2017-08-10 164 views
1

我有一個問題與騾Dataweave變壓器得到騾JSON到對象的變壓器和變壓器Dataweaver例​​外

INFO 2017-08-10 15:05:52,787 [amqpReceiver.02] org.mule.api.processor.LoggerMessageProcessor: Authorisation Changed Event received. authorisation id: 1 
INFO 2017-08-10 15:05:57,844 [amqpReceiver.02] org.mule.api.processor.LoggerMessageProcessor: type before class com.mulesoft.weave.reader.ByteArraySeekableStream 
INFO 2017-08-10 15:06:02,058 [amqpReceiver.02] org.mule.api.processor.LoggerMessageProcessor: type after: class com.mulesoft.weave.reader.ByteArraySeekableStream 
INFO 2017-08-10 15:06:13,309 [amqpReceiver.02] org.mule.api.processor.LoggerMessageProcessor: Org Name :- Id:- Org Name 3 
ERROR 2017-08-10 15:06:15,520 [amqpReceiver.02] org.mule.exception.RollbackMessagingExceptionStrategy: 
******************************************************************************** 
Message    : Exception while executing: 
{ 
^ 
Unexpected end-of-input at index 0 (line 1, position 1), expected JSON Value 
Payload    : [email protected] 
Element    : /subscribe-to-changeFlow/processors/8 @ voa-009-mule-authorisation-search-api:test.xml:60 (Final Transform Message) 
Element XML   : <dw:transform-message doc:name="Final Transform Message" metadata:id="fa7e7663-50bb-4675-a8c8-e8cb311946a9"> 
         <dw:input-payload mimeType="application/json"></dw:input-payload> 
         <dw:set-payload resource="classpath:dwl/owner-authorisation-enrichment.dwl"></dw:set-payload> 
         </dw:transform-message> 
-------------------------------------------------------------------------------- 
Root Exception stack trace: 
com.mulesoft.weave.reader.json.JsonReaderException: Unexpected end-of-input at index 0 (line 1, position 1), expected JSON Value 
    at com.mulesoft.weave.reader.json.JsonTokenizer.fail(JsonTokenizer.scala:193) 
    at com.mulesoft.weave.reader.json.JsonTokenizer.readValue(JsonTokenizer.scala:49) 
    at com.mulesoft.weave.reader.json.JsonTokenizer.tokens(JsonTokenizer.scala:16) 
    at com.mulesoft.weave.reader.json.JsonReader.root(JsonReader.scala:17) 
    at com.mulesoft.weave.mule.reader.ReusableReader.root(ReusableReader.scala:12) 
    at com.mulesoft.weave.engine.EvaluationContext$InternalExecutionContext$$anonfun$3.apply(EvaluationContext.scala:106) 
  • 流接收ID作爲消息有效載荷
  • 使一個HTTP調用獲取一些JSON ID
  • 做一個初始Dataweave轉換將JSON轉換爲新的JSON模式
  • 爲了從JSON中提取一些值JSON:JSON到對象的變壓器,但我已經把這個在富集靶向flowVar允許轉換爲地圖,並保持原有的有效載荷不變

    <enricher target="#[flowVars.ownerAuthorisationJsonMap]" doc:name="Copy to JSON map"> 
         <json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/> 
        </enricher> 
    
  • 我然後調用一個子流程來獲得一些進一步的日期以後再補充。該子流程僅存儲另一個流量變量的濃縮結果

  • 第二個Dataweave變換器(獲取異常)從第一個Dataweave變換器獲取JSON模式輸出並使用子流查找的數據豐富了一些缺失值(示例顯示一但地圖上會有很多)。這會得到例外。

但是如果我註釋掉濃縮塔嵌套JSON到對象的變壓器

  <enricher target="#[flowVars.ownerAuthorisationJsonMap]" doc:name="Copy to JSON map"> 
      <json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/> 
     </enricher> 

第二dataweave工作正常(但我不能訪問數據在JSON中)。看來json-to-object-transformer會讓事情變得很糟糕,但是如果我調試有效載荷類型並且Java對象id始終保持不變。

我只使用json-to-object-transformer來允許MEL訪問JSON,因爲似乎被建議爲JSON-path已被棄用。

<?xml version="1.0" encoding="UTF-8"?> 

<amqp:endpoint name="authorisationChangeQueueDef" 
    queueName="authorisation-change-queue" queueDurable="true" 
    exchangeName="authorisation-exchange" exchangeType="direct" exchangeDurable="true" 
    connector-ref="AMQP_Connector" 
    routingKey="authorisation-change-queue-routing-key" doc:name="authorisationChangeQueueDef"> 
     <properties> 
      <spring:entry key="amqp-queue.x-dead-letter-exchange" value="authorisation-exchange" /> 
      <spring:entry key="amqp-queue.x-dead-letter-routing-key" value="authorisation-change-queue-dead-routing-key" /> 
     </properties> 
</amqp:endpoint> 


<flow name="subscribe-to-changeFlow" processingStrategy="synchronous"> 

    <amqp:inbound-endpoint ref="authorisationChangeQueueDef" responseTimeout="10000" doc:name="authorisation-change-consumer" /> 

    <set-variable variableName="authorisationId" value="#[message.payloadAs(java.lang.String)]" doc:name="set authorisation id"/> 

    <logger message="#['Authorisation Changed Event received. authorisation id: ' + flowVars.authorisationId]" level="INFO" doc:name="Logger"/> 

    <http:request config-ref="Mule_Authorisation_Management_API_HTTP_Request_Configuration" path="#['/authorisation/' + flowVars.authorisationId]" method="GET" doc:name="HTTP REST call to Authorisation API"/> 

    <dw:transform-message doc:name="Transform to basic owner-authorisation" metadata:id="1bdd6f7e-6b4b-415b-819d-e88b9ff7f92b"> 
     <dw:input-payload mimeType="application/json"/> 
     <dw:set-payload resource="dwl/owner-authorisation-skeleton.dwl"/> 
    </dw:transform-message> 

     <logger message="#['type before ' + message.dataType.type]" level="INFO" doc:name="Logger"/> 

    <!-- Enricher targeting flowVar to keep original payload type intact -->    
    <enricher target="#[flowVars.ownerAuthorisationJsonMap]" doc:name="Copy to JSON map"> 
     <json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/> 
    </enricher> 

     <logger message="#['type after: ' + message.dataType.type]" level="INFO" doc:name="Logger"/> 

    <!-- subflow that uses flowVars.ownerAuthorisationJsonMap and MEL --> 
    <flow-ref name="enrich-Sub_Flow" doc:name="enrich-Sub_Flow"/> 


    <dw:transform-message doc:name="Final Transform Message" metadata:id="fa7e7663-50bb-4675-a8c8-e8cb311946a9"> 
     <dw:input-payload mimeType="application/json"/> 
     <dw:set-payload resource="classpath:dwl/owner-authorisation-enrichment.dwl"/> 
    </dw:transform-message> 


    <logger level="INFO" doc:name="Logger all "/> 


    <!-- Does a manual ACK to RabbitMQ, only do once we know all the processing is complete --> 
    <amqp:acknowledge-message doc:name="AMQP-0-9 Acknowledge Message"/> 


    <rollback-exception-strategy maxRedeliveryAttempts="3" doc:name="Rollback Exception Strategy"> 
     <logger message="#['REQUESTING RETRY OF REQUEST... delivery-tag : ' + message.inboundProperties['delivery-tag']]" level="INFO" doc:name="Logger"/> 
     <!-- re-queue message for re-tries --> 
     <amqp:reject-message requeue="true" doc:name="AMQP-0-9 Reject Message" /> 

     <on-redelivery-attempts-exceeded> 
      <logger message="REDELIVERY EXHAUSTED" level="ERROR" doc:name="Logger"/> 
      <amqp:reject-message doc:name="AMQP-0-9 Reject Message" /> 
     </on-redelivery-attempts-exceeded>   
    </rollback-exception-strategy> 

</flow> 

<sub-flow name="enrich-Sub_Flow"> 
    <set-variable variableName="organisationId" value="#[ownerAuthorisationJsonMap.organisationId]" doc:name="Extract Organisation Id" encoding="UTF-8" mimeType="application/json"/> 

    <enricher target="#[flowVars.organisationName]" source="#[payload.organisationLatestDetail.organisationName]" doc:name="Message Enricher"> 
     <processor-chain doc:name="Processor Chain"> 
      <flow-ref name="get-organisation-details-SubFlow" doc:name="get-organisation-details-Sub_Flow" /> 
      <json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/> 
      <logger level="INFO" message="Org Name :- Id:- #[payload.organisationLatestDetail.organisationName]" doc:name="Logger"/> 
     </processor-chain> 
    </enricher> 
</sub-flow> 

<sub-flow name="get-organisation-details-SubFlow"> 
    <http:request config-ref="VOA_Mule_Customer_Management_API_HTTP_Request_Configuration" path="#['/organisation?organisationId='+ flowVars.organisationId]" method="GET" 
     doc:name="HTTP - Get Customer details"> 
    </http:request> 
</sub-flow> 

Dataweave 1

%dw 1.0 
%output application/json 
--- 
{ 
    authorisationId: payload.id, 
    uarn: payload.uarn, 
    authorisedParties: payload.parties map ((party , indexOfParty) -> { 
     organisationId: party.authorisedPartyOrganisationId, 
     status: party.authorisedPartyStatus, 
     startDate: party.startDate 
    }), 
    endDate: payload.endDate, 
    organisationId: payload.authorisationOwnerOrganisationId, 
    propertyLinkSubmissionId: payload.submissionId, 
    startDate: payload.startDate, 
    status: payload.authorisationStatus 
} 

Dataweave 2(這將有進一步的映射,從一個Java地圖太)

%dw 1.0 
%output application/json 
--- 
{ 
    authorisationId: payload.authorisationId, 
    authorisedParties: payload.authorisedParties map ((authorisedParty , indexOfAuthorisedParty) -> { 
     organisationId: authorisedParty.organisationId, 
     startDate: authorisedParty.startDate, 
     status: authorisedParty.status 
    }), 
    endDate: payload.endDate, 
    organisationId: payload.organisationId, 
    organisationName: flowVars.organisationName, 
    propertyLinkSubmissionId: payload.propertyLinkSubmissionId, 
    startDate: payload.startDate, 
    status: payload.status, 
    uarn: payload.uarn 
} 

日誌

INFO 2017-08-10 15:05:52,787 [amqpReceiver.02] org.mule.api.processor.LoggerMessageProcessor: Authorisation Changed Event received. authorisation id: 1 
INFO 2017-08-10 15:05:57,844 [amqpReceiver.02] org.mule.api.processor.LoggerMessageProcessor: type before class com.mulesoft.weave.reader.ByteArraySeekableStream 
INFO 2017-08-10 15:06:02,058 [amqpReceiver.02] org.mule.api.processor.LoggerMessageProcessor: type after: class com.mulesoft.weave.reader.ByteArraySeekableStream 
INFO 2017-08-10 15:06:13,309 [amqpReceiver.02] org.mule.api.processor.LoggerMessageProcessor: Org Name :- Id:- Org Name 3 

回答

1

這個問題是由JSON負載流被json-to-object-transformer消耗而引起的,並且沒有被重置,儘管它在消息中更豐富。 看到這個問題 - https://www.mulesoft.org/jira/browse/MULE-10623

最簡單的解決方案是消息富集後到流復位:

... 
<enricher target="#[flowVars.myMar]" doc:name="Message Enricher"> 
    <json:json-to-object-transformer doc:name="JSON to Object"/> 
</enricher> 
<expression-component doc:name="Expression"> 
    <![CDATA[payload.seek(0);]]> 
</expression-component> 
... 

或使用消息富集之前打開有效載荷爲字符串:

... 
<object-to-string-transformer doc:name="Object to String"/> 
<enricher target="#[flowVars.myMar]" doc:name="Message Enricher"> 
... 

只是爲了參考我複製的問題與這個更簡單的流程:

<flow name="flow"> 

    <dw:transform-message doc:name="Transform Message"> 
     <dw:set-payload> 
<![CDATA[%dw 1.0 
%output application/json 
--- 
{ 
    foo:0 
}]]> 
     </dw:set-payload> 
    </dw:transform-message> 
    <enricher target="#[flowVars.myVar]" doc:name="Message Enricher"> 
     <json:json-to-object-transformer doc:name="JSON to Object"/> 
    </enricher> 
    <dw:transform-message doc:name="Transform Message"> 
     <dw:set-payload> 
<![CDATA[%dw 1.0 
%output application/json 
--- 
payload 
]]> 
     </dw:set-payload> 
    </dw:transform-message> 
</flow> 
+0

感謝您的及時答案,我會重置流。 BTW是最好避免使用json:path?因爲我通過避免使用json到object變換器並使用JSON路徑來實現它。 – Pete

+0

JSON路徑已棄用,並將在Mule 4中刪除,因此最好避免它。 https://forums.mulesoft.com/questions/26717/correct-way-of-accessing-json-payload-in-mule-37.html –

+0

感謝您的答案,但是我現在發現了一個進一步的問題,如果一個flowVar我們在第二次Dataweave變壓器使用,然後有效載荷轉換爲一個地圖看到我的問題https://stackoverflow.com/questions/45689371/mule-if-flowvar-used-in-dataweave-transformer-payload-converted-to -地圖 – Pete