I am trying to capture error status from one API & and send it to the calling API. In my downstream API I have the following catch exception strategy:
<catch-exception-strategy>
<set-payload value= "500" />
<logger message="***BACKEND API: #[payload]" level="INFO" doc:name="Logger"/>
</catch-exception-strategy>
In my calling API I have the following:
<http:request config-ref="downstream API " path="/downstream/{id}" method="POST " doc:name="Generate "/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
<logger message="PAYLOAD: #[payload]" level="INFO" doc:name="Logger"/>
However I am able to print the payload in the downstream API but not in the calling API. Am I missing something?
If your API throw http.status == 500, it should trigger this condition
<choice-exception-strategy doc:name="Choice Exception Strategy">
<catch-exception-strategy when="#[message.inboundProperties.'http.status' == 500]" doc:name="Error 500">
<set-payload value= "500" />
<logger message="***BACKEND API: #[payload]" level="INFO" doc:name="Logger"/>
</catch-exception-strategy>
</choice-exception-strategy>
I you didn't add any condition, it should be the default catch exception
everything should work properly.
Related
Scenario - I have to iterate over this payload, and for those listings with error I would need to increment count. But how to check if error property exists?
{
"jobGuid": "123",
"status": "COMPLETED",
"listings": [
{
"exteralListingId": 7654320
},
{
"exteralListingId": 7654321,
"error": {
"code": "inventory.listings.sellerCreditCardNotfound",
"description": "Seller credit card not found"
}
}
]
}
Option1 - Check using json syntax
Option2 - Iterating in a for-each loop over listings, checked for #[payload.error !=null]. But it gave error - Message payload is of type: LinkedHashMap
You can use jsonPath something like xpath but for JSON
I attached my example with the json provided. As you can see there are #[json:listings] which return array, this array will be iterated by foreach and then validate if contains error tag using #[json:error]. errorCount variable store the number of errors and it will be printed in the console.
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="demoFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<set-payload value="{"jobGuid":"123","status":"COMPLETED","listings":[{"exteralListingId":7654320},{"exteralListingId":7654321,"error":{"code":"inventory.listings.sellerCreditCardNotfound","description":"Seller credit card not found"}},{"exteralListingId":7654321,"error":{"code":"inventory.listings.sellerCreditCardNotfound","description":"Seller credit card not found"}},{"exteralListingId":7654321,"error":{"code":"inventory.listings.sellerCreditCardNotfound","description":"Seller credit card not found"}}]}" doc:name="Set Payload"/>
<expression-transformer expression="#[json:listings]" doc:name="Expression"/>
<set-variable variableName="errorCount" value="#[0]" doc:name="Variable"/>
<foreach collection="#[message.payload]" doc:name="For Each">
<expression-filter expression="#[json:error]" doc:name="Expression"/>
<set-variable variableName="errorCount" value="#[flowVars.errorCount + 1 ]" doc:name="Variable"/>
<logger message="counter: #[errorCount]" level="INFO" doc:name="Logger"/>
</foreach>
</flow>
For more information check the official documentation at mule .
http://www.mulesoft.org/documentation/display/current/JSON+Module+Reference
I have a simple csv-to-pojo datamapper, which gets sent to two synchronous flow through an "All" flow control component. The first flow runs the payload through a Foreach, then once it is done, the second flow attempts to run the payload from the datamapper again through a different foreach, but instead I'm getting this warning message:
Splitter returned no results. If this is not expected, please check your split expression.
Furthermore, it seems that Mule only allows me to run the payload through either flow one or flow two, but not both. Again, running it trough more than one Foreach component will result in the Splitter warning.
Any help will be appreciated. Thanks in advance. Here's the setup:
<flow name="main_flow" doc:name="main_flow" initialState="started" processingStrategy="synchronous">
<data-mapper:transform config-ref="csv_to_pojo" doc:name="CSV To Pojo" stream="true"/>
<all doc:name="All">
<flow-ref name="flow1" doc:name="Flow Reference"/>
<flow-ref name="flow2" doc:name="Flow Reference"/>
</all>
</flow>
<flow name="flow1" doc:name="flow1" processingStrategy="synchronous">
<logger message="Entering flow 1" level="INFO" doc:name="Logger"/>
<foreach doc:name="For Each">
<logger message="Inside foreach of flow1 " level="INFO" doc:name="Logger"/>
</foreach>
</flow>
<flow name="flow2" doc:name="flow2" processingStrategy="synchronous">
<logger message="Entering flow2" level="INFO" doc:name="Logger"/>
<foreach doc:name="For Each">
<logger message="Inside foreach of flow2" level="INFO" doc:name="Logger"/>
</foreach>
</flow>
In my Mule app, I've configured some of the flows to use a catch exception strategy in order to do some special processing. For these cases, I want to pop the error and the original payload into an object store. Everywhere else, the default exception strategy is fine.
<flow name="saveLookup">
<vm:inbound-endpoint exchange-pattern="one-way" ref="Lookup_Save_VM" />
<component>
<spring-object bean="insertLookupMDCvalues"/>
</component>
<set-variable variableName="originalPayload" value="#[payload]"/>
<json:json-to-object-transformer returnClass="com.company.LookupData"/>
<set-variable variableName="transactionId" value="#[payload.transactionId]"/>
<transactional action="ALWAYS_BEGIN">
<logger message="${lookup.SQL}" level="INFO"/>
<jdbc:outbound-endpoint exchange-pattern="request-response" queryKey="saveLookup" queryTimeout="-1" connector-ref="JdbcConnector" />
<foreach collection="#[payload.transactional.lookupItems.items]">
<logger message="${lookup.item.SQL}" level="INFO" />
<jdbc:outbound-endpoint exchange-pattern="request-response" queryKey="saveLookupItem" queryTimeout="-1" connector-ref="JdbcConnector"/>
</foreach>
</transactional>
<component>
<spring-object bean="clearLookupMDCvalues"/>
</component>
<catch-exception-strategy>
<message-properties-transformer scope="invocation">
<add-message-property key="errorMap" value="#[['id' : transactionId, 'body' : originalPayload, 'error' : exception.summaryMessage]]"/>
</message-properties-transformer>
<choice>
<when expression="#[message.inboundProperties['resubmit']]">
<logger message="Resubmission of lookup data failed, saving to Dead Letter object store. ID=#[transactionId]" level="INFO"/>
<objectstore:store config-ref="lookupDeadLetterOS" key="#[transactionId]" overwrite="true" value-ref="#[errorMap]"/>
</when>
<otherwise>
<logger message="Saving lookup data failed, saving to Error object store. ID=#[transactionId]" level="INFO"/>
<objectstore:store config-ref="lookupErrorOS" key="#[transactionId]" overwrite="true" value-ref="#[errorMap]"/>
</otherwise>
</choice>
<set-payload value="Error: #[exception.summaryMessage]"/>
<component>
<spring-object bean="clearLookupMDCvalues"/>
</component>
</catch-exception-strategy>
</flow>
My problem is that when an error is encountered, let's say a Null Pointer Exception in the foreach component, I'm seeing four ERROR log statements for each event:
Exception stack is: 1. null (java.lang.NullPointerException) ...and so on. This is logged twice.
CatchMessagingExceptionStrategy - Message : Execution of the expression "payload.transactional.lookupItems.items" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: LookupData
DefaultMessagingExceptionStrategy - Message : Execution of the expression "payload.transactional.lookupItems.items" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: LookupData
I thought that a flow-specific exception strategy should override the default strategy. Why the duplicate log messages, and is there a way to shush them? I'd like to avoid having to configure the default exception strategy, as it's perfectly acceptable behavior in the majority of the flows.
The issue is that the built in exception strategies inherit from AbstractExceptionListener, and they all use the logException template method. The base implementation always logs at ERROR level, which is sometimes not appropriate for your application.
You can create a simple subclass of CatchMessagingExceptionStrategy that overrides the logException method, and logs however you want. Then, use it in your flow in place of the <catch-exception-strategy> like so:
<custom-exception-strategy class="com.mycompany.mule.QuietCatchExceptionStrategy">
<!-- your message processors here -->
</custom-exception-strategy>
Below is my Json
{"caseType":"CashLess","claimNo":9.0}
how to get caseType value in logger.
below my config XML
<json:json-to-object-transformer doc:name="JSON to Object"/>
<logger message="#['\n JSON::\n'+ message.payload.caseType+'\n']" level="INFO" doc:name="Logger"/>
but it is giving error.
Thanks.
need to add returnClass="java.util.HashMap" in json:json-to-object-transformer
<json:json-to-object-transformer doc:name="JSON to Object" returnClass="java.util.HashMap"/>
I have a quartz scheduler configured as shown below.
<quartz:inbound-endpoint jobName="retryJob" repeatInterval="5000" cronExpression="0 0/1 * * * ?">
<quartz:endpoint-polling-job>
<quartz:job-endpoint ref="retryQueue"/>
</quartz:endpoint-polling-job>
</quartz:inbound-endpoint>
<flow-ref name="callMySubFlow" />
<choice-exception-strategy>
<catch-exception-strategy when="groovy:message.getInvocationProperty('next') == 'DONE'">
<logger level="INFO" message="DONE"/>
</catch-exception-strategy>
<rollback-exception-strategy>
<on-redelivery-attempts-exceeded>
<logger level="INFO" message="Redelivery Exceeded. Done with retries."/>
</on-redelivery-attempts-exceeded>
</rollback-exception-strategy>
</choice-exception-strategy>
<jms:connector name="queueConnectorU" connectionFactory-ref="MQConnectionFactoryU" specification="1.1" username="me" password="p" numberOfConsumers="5" maxRedelivery="3"/>
<jms:endpoint name="retryQueue" queue="retryQ" connector-ref="queueConnectorU">
<ee:multi-transaction action="ALWAYS_BEGIN" />
</jms:endpoint>
I have an intentional service not found exception in subflow and expect the message to be retried 3 times and commited, but the message is never removed from the queue...infinite loop.
Is there anything wrong with the configuration?