This has to be a common scenario yet I only came across the following link so far addressing it - I have a bunch of Data Mapper elements doing Pojo to Pojo transformation and need a way to reliably capture the exceptions - right now an exception happens but there is no indication of which mapper the exception occurred in.
http://www.mulesoft.org/documentation/display/current/DataMapper+Input+Error+Policy+for+Bad+Input+Data
Can someone please point to a link which describes how to capture these errors in the mapper
Thanks
The easiest way is probably to put each data mapper transformer in a private flow with their own local exception strategies:
<flow name="main">
<flow-ref name="transform1" />
<flow-ref name="transform2" />
</flow>
<flow name="transform1">
<data-mapper:transform config-ref="grf1" />
<catch-exception-strategy>
<!-- do something -->
</catch-exception-strategy>
</flow>
<flow name="transform2">
<data-mapper:transform config-ref="grf2" />
<catch-exception-strategy>
<!-- do something -->
</catch-exception-strategy>
</flow>
Related
I am facing problem in batch processing mule esb. If I set any payload in process record face and try to get that payload in oncomplete face then not getting that payload. same problem with variable and property.
If I set any property in process record phase and try to get in on complete phase then always get null value.
how to get those value in oncomplete phase?
below is flow..
<batch:job name="TestBatch" max-failed-records="-1">
<batch:input>
<component class="com.test.RecordTest"
doc:name="Java" />
<json:object-to-json-transformer
doc:name="Object to JSON" />
<custom-transformer class="com.test.CustomTr"
doc:name="Java" />
</batch:input>
<batch:process-records>
<batch:step name="Batch_Step1" accept-policy="ALL">
<batch:commit size="5" doc:name="Batch Commit">
<!-- Insert record in Salesforce -->
</batch:commit>
</batch:step>
<batch:step name="Batch_Step2" accept-policy="ONLY_FAILURES">
<logger message="STEPP #[getStepExceptions()]" level="INFO" doc:name="Logger"/>
<set-property propertyName="error" value="STEPP #[getStepExceptions()]" doc:name="Property"/>
<set-payload value="#[getStepExceptions()]" doc:name="Set Payload"/>
</batch:step>
</batch:process-records>
<batch:on-complete>
<logger level="INFO" doc:name="Logger" message="--> #[payload.failedRecords] --> #[message.payload] "/>
<logger message="error--- #[message.outboundProperties['error']] " level="INFO" doc:name="Logger"/>
</batch:on-complete>
</batch:job>
I got null in property logger
How can I solve this?
I got some bad news from you :-).
Batch processing by design will not old any of the value you may try to set in steps, especially payload.
When I started working with it I was also expecting to have session variable on complete phase in a correct status but this is not the case, they are completely wiped at each step.
Now I don't think this is a bug, but it is really a design feature that I can understend even if I don't really love it.
I solved the same problem by using the object store connector.
It will allow you to access the mule Object Store API via nice XML configuration block, in this way you can store in memory variables that you can recover after in your on-complete without them being affected by flow logic.
Hope this helps
I have 2 flows, A.flow and B.flow, eventually both flows execute the same java class.
A & B read from a separate Queue.
I want to synchronize the flows so that if both flows get input simultaneously then one flow at a time process and after it finishes, the other flow will start processing.
Any ideas?
thanks
Use a pooled component and configure it to use one thread at a time:
<flow name="A">
<jms:inbound-endpoint...>
...
<vm:outbound-endpoint path="process"/>
...
</flow>
<flow name="B">
<jms:inbound-endpoint...>
...
<vm:outbound-endpoint path="process"/>
...
</flow>
<flow name="process">
<vm:inbound-endpoint path="process"/>
<pooled-component class="org.my.PrototypeObject">
<pooling-profile exhaustedAction="WHEN_EXHAUSTED_WAIT" initialisationPolicy="INITIALISE_ALL" maxActive="1" maxIdle="1" maxWait="1000" /> </pooled-component>
</pooled-component>
</flow>
Source: http://www.mulesoft.org/documentation/display/current/Configuring+Java+Components#ConfiguringJavaComponents-ConfiguringaPooledJavaComponent
I get a list of files on amazon S3 and iterate over the list of files and process one file at a time. The corresponding flow is as follows --
<flow name="process-from-s3" doc:name="process-from-s3"
processingStrategy="synchronous">
<poll doc:name="Poll" frequency="${s3-poll-interval}">
<s3:list-objects config-ref="Amazon_S3" doc:name="Get List of files"
accessKey="${s3-access-key}" secretKey="${s3-secret-key}"
bucketName="${s3-read-bucket}" />
</poll>
<choice doc:name="Choice">
<foreach doc:name="For Each">
<set-session-variable variableName="s3_file_name" value="#[payload.getKey()]" doc:name="Session Variable"/>
<logger message="From bucket ( ${s3-read-bucket} ), received the file #[s3_file_name]" level="INFO" doc:name="Logger"/>
<flow-ref name="process_s3_file" doc:name="Flow Reference"/>
</foreach>
</choice>
</flow>
The flow works well, however it keeps on spitting the following log statements if there are no files found.
[03-06 21:52:05] WARN Foreach$CollectionMapSplitter
[[myapp].connector.polling.mule.default.receiver.01]: Splitter returned no results.
If this is not expected, please check your split expression
How can I avoid this annoying log message. Should I wrap the foreach within a choice router that processes the foreach if there is atleast one element in the list. Any suggestions are welcome.
I would rather set the log level for org.mule.routing.Foreach$CollectionMapSplitter to ERROR than configure any additional logic for this warning. See Mule docs for configuring logger/log4j if you need to.
I have a flow in which I have inserted a flow reference component. The reference component flow will obviously send a message to my first flow with a result "xxx". I want this result to be put in the header of the message sent.
<flow name="CreateAccountFlow1" doc:name="CreateAccountFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP" path="bank"/>
<cxf:jaxws-service doc:name="SOAP" serviceClass="com.essai2.AccountService"/>
<component class="com.essai2.AccountRequest" doc:name="Java"/>
<flow-ref name="Projet2Flow1" doc:name="Flow Reference"/>
<component class="com.essai2.AccountResponse" doc:name="Java"/>
<logger level="INFO" doc:name="Logger"/>
</flow>
Flow-references do not "send messages" per se, so it's hard to understand what you're after. It seems you want the result of the execution of the flow-ref to be placed in a message property. If that's the case, you can do:
<set-variable variableName="result" value="#[message.payload]" />
This assumes that the result of the flow-ref is in the message payload and that having the result property in the invocation scope (aka flow variable) is OK for you. With the little information you provided, that's the most I can tell you.
In trying to restore the original payload in a message, I ran into this issue that confused me regarding the scope of a mule message. Given the mule config below, I initially assumed that the payload received at the test.Name vm endpoint was going to be restored at the end of the flow (see 1. and 2. in the config):
<mule ...>
<vm:endpoint name="replacePayloadWithFoo.Name"
path="replacePayloadWithFoo.Path" />
<flow name="test">
<vm:inbound-endpoint name="test.Name" path="test.Path"
exchange-pattern="request-response" />
<!-- 1. Down below, I wanted to restore the payload at this point -->
<expression-transformer evaluator="string"
expression="bar" />
<outbound-endpoint ref="replacePayloadWithFoo.Name"
exchange-pattern="request-response" />
<!-- 2. The transformer below does not restore the payload at 1. -->
<expression-transformer evaluator="groovy"
expression="message.originalPayload" />
</flow>
<flow name="replacePayloadWithFoo">
<inbound-endpoint ref="replacePayloadWithFoo.Name"
exchange-pattern="request-response" />
<expression-transformer evaluator="string"
expression="foo" />
</flow>
</mule>
However, it seemed as though the message that entered the test flow ended at the replacePayloadWithFoo outbound endpoint. The transformer at 2. leaves "foo" as the payload.
What's the scope of the mule message?
In passing, the scripting reference documentation indicates that there is a binding for originalPayload in groovy scripts. However, if the transformer at 2. is replaced with
<expression-transformer evaluator="groovy" expression="originalPayload" />
I get an exception:
org.mule.api.expression.RequiredValueException: Expression Evaluator "groovy"
with expression "originalPayload" returned null but a value was required.
What could be the issue?
Thanks
Any outbound interaction, unless performed through an enricher, will affect the current in-flight message. This is why the call to replacePayloadWithFoo replaces the original message with the result of the outbound interaction.
This said, I can not explain the discrepancy between:
<expression-transformer evaluator="groovy" expression="message.originalPayload" />
and:
<expression-transformer evaluator="groovy" expression="originalPayload" />
because they both rely on:
event.getMessage().getPayload()