Mule processing strategies - call async private flow from synchronous flow - mule

I am trying to call an async private flow from a main synchronous flow like so:
<flow name="main" doc:name="main" processingStrategy="synchronous">
<poll frequency="10000">
<set-payload value="main"></set-payload>
</poll>
<flow-ref name="async-private" />
<flow-ref name="private" />
</flow>
<flow name="private" processingStrategy="synchronous">
<logger level="ERROR" message="sync" />
</flow>
<flow name="async-private" processingStrategy="asynchronous">
<logger level="ERROR" message="async" />
</flow>
But it does not work and results in the following exception:
Unable to process a synchronous event asynchronously. Message payload is of type: String (org.mule.api.MessagingException)
What is going on here?
UPDATE
It works if I wrap the async flow-ref in <async> tags. But why do I need to do this? Is it a bug?

This is a feature.
You are in an explicit synchronous flow and try to call an explicit asynchronous one. The response from the asynchronous flow will never make it back to the caller flow. Thus there is a potential for losing messages. Thus Mule forces you to be explicit and wrap with <async> tags.

Related

How to use Mule Expression in JMS:selector

I checked several previous discussions but couldnt find the answer.
I am trying to achieve synchronous communicaiton using JMS back-channel (http://www.whishworks.com/blog/synchronous-communication-using-jms-back-channel). Apart from the things mentioned in that site, I need to filter out the message from the inbound queue based on a dynamic Id.
Following are my mule flows:
<flow name="serverFlow" >
<jms:inbound-endpoint doc:name="REQUEST" queue="REQUEST.QUEUE" connector-ref="jmsConnector">
<jms:selector expression="MULE_CORRELATION_ID='#[sessionVars.myCorrelationId]'"/>
</jms:inbound-endpoint>
<set-payload value="#[payload] + Hello World from Receiver" doc:name="Set Payload" />
<jms:outbound-endpoint doc:name="REPLY" queue="REPLY.QUEUE" connector-ref="jmsConnector" />
</flow>
<flow name="mainFlow" >
<http:listener config-ref="HTTP_Listener_Configuration" path="/jms" allowedMethods="GET" doc:name="HTTP"/>
<set-session-variable variableName="myCorrelationId" value="#[System.currentTimeMillis().toString()]" doc:name="Set Correlation ID"/>
<set-payload value="New message sent from Mule - mainFlow at #[new Date()]" doc:name="Set Message"/>
<set-property propertyName="MULE_CORRELATION_ID" value="#[sessionVars.myCorrelationId]" doc:name="Property"/>
<request-reply doc:name="Request-Reply">
<jms:outbound-endpoint doc:name="REQUEST" connector-ref="jmsConnector" queue="REQUEST.QUEUE"/>
<jms:inbound-endpoint doc:name="REPLY" connector-ref="jmsConnector" queue="REPLY.QUEUE"/>
</request-reply>
<logger message="Reply to sender: #[message]" level="WARN" doc:name="Logger" />
</flow>
If I try a static value like "<jms:selector expression="MULE_CORRELATION_ID='12345'"/>", it works. But if I try a dynamic ID using MEL, its not working. The MEL inside the jms selector expression is not working. The message stays at the queue as Unread. I used logs to see what the MULE_CORRELATION_ID is while being set at mainFlow and found the same value is set in the message that is UNREAD in the queue. So, I guess nothing is wrong in the way the MULE_CORRELATION_ID is set. The only problem is that MEL is not working within jms:selector.
Could you please help how to get MEL working within JMS selector?
Thank you very much.
MEL is working fine in the selector but its usage is very limited. When the JMS selector is created, there's no in-flight event available to Mule so none of the event-bound data (including session) is available.
To select a very particular message, you need to use a JMS message requester, constructed with the desired selector, like:
jms://REQUEST.QUEUE?selector=MULE_CORRELATION_ID%3D'#[sessionVars.myCorrelationId]'
Here is the working solution based on David's suggestion. I am using wmq here (not jms).
<mulerequester:config name="Mule_Requester" doc:name="Mule Requester"/>
<flow name="mainFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" allowedMethods="GET" doc:name="HTTP"/>
<set-payload value="My Message" doc:name="Set Message"/>
<set-property propertyName="JMSCorrelationID" value="12345" doc:name="Property"/>
<set-session-variable variableName="myCorrelationId" value="ID:313233343500000000000000000000000000000000000000" doc:name="Set Correlation ID"/>
<!--313233343500000000000000000000000000000000000000 is the MQMD CorrelationId for 12345. This is set by IBM MQ -->
<logger message="The Message to REQUEST QUEUE: #[message]" level="WARN" doc:name="Logger"/>
<wmq:outbound-endpoint queue="REQUEST.QUEUE" connector-ref="wmqConnector" doc:name="OUT"/>
<mulerequester:request config-ref="Mule_Requester" resource="wmq://REPLY.QUEUE?selector=JMSCorrelationID%3D'#[sessionVars.myCorrelationId]'" doc:name="Mule Requester" timeout="120000"/>
<logger message="Final Response: #[message]" level="WARN" doc:name="Logger"/>
</flow>
Please note, I manually moved the message from Request queue to Reply queue using MQVE for my testing. In real time, it will be done by another program.

I want to Scatter the requests but not Gather results into single payload unlike how scatter-gather does in Mule

I have a flow like:
<flow name="Flow1">
<set-payload value="Important Message" />
<scatter-gather>
<choice doc:name="A">
<when expression="true">
//TODO
</when>
<otherwise>
//TODO
</otherwise>
</choice>
<flow-ref name="B" />
</scatter-gather>
<logger message="from flow-ref B: #[payload]" level="INFO" doc:name="response from B only"/>
</flow>
Right now the payload that comes out is an array of Payload;But I need only payload from response of B. I don't want to append java class to iterate over the payload to find B response.
I don't want the response from choice component but only from flow-ref B.
How to achieve this? Is this possible in an easy way using only mule components?
If I understand correctly, you want the payload "Important Message" to reach the flow-ref to B, and you also want the choice to occur?
Try getting rid of the scatter-gather and wrapping the choice router in an Async Scope instead.

How to capture an exception using the regex-filter filter in Mule ESB

Currently I have a flow that exposes a REST service with a string as input parameter . I am using a regex -filter to ensure the format parameter as follows :
<http:inbound-endpoint doc:name="HTTP"
connector-ref="ciuServiceHTTPConnector" ref="ciuServiceHTTPEndpoint"
exchange-pattern="request-response" />
<logger level="INFO" doc:name="Logger" message="epale1 #[payload]"/>
<regex-filter pattern="^/api/person/(V|E)[0-9]{8}$"
doc:name="Regex" />
<logger message="epale2 #[payload]" level="INFO" doc:name="Logger"/>
<jersey:resources doc:name="REST" >
<component class="...resource.CiudadanoResource"/>
</jersey:resources>
I need to send the customer a message "Invalid or missing parameter" . For this I use a choice-exception-strategy and catch-exception-strategy and then call a Subflow and perform http:response-builder.
How can I throw an exception(type) when the regex-filter do not match?. It is possible to incorporate this behavior or should I change my flow?
Thanks for your help;
Wrap it in a message-filter, like this:
<message-filter throwOnUnaccepted="true">
<regex-filter pattern="^/api/person/(V|E)[0-9]{8}$"
doc:name="Regex" />
</message-filter>
See the official documentation for further details:
Check the Throw On Unaccepted box to throw an exception if a message
or event is not handled. The default when not checked is to not throw
an exception.

Seeing ConcurrentModificationException in Mule 3.3.0

I am fairly new to Mule ,using 3.3.0, but I am trying what I think should be a fairly stock example.
I have a mule config which will read a csv file and attempt to process the lines and columns of in different flows async. However, we are seeing ConcurrentModificationException when the message is being "handed off" to one of the async flows. I was wondering if anyone else has seen this issue and what they may have done to work around the problem.
java.util.ConcurrentModificationException
at org.apache.commons.collections.map.AbstractHashedMap$HashIterator.nextEntry(AbstractHashedMap.java:1113)
at org.apache.commons.collections.map.AbstractHashedMap$KeySetIterator.next(AbstractHashedMap.java:938)
at org.mule.DefaultMuleEvent.setMessage(DefaultMuleEvent.java:933)
at org.mule.DefaultMuleEvent.(DefaultMuleEvent.java:318)
at org.mule.DefaultMuleEvent.(DefaultMuleEvent.java:290)
at org.mule.DefaultMuleEvent.copy(DefaultMuleEvent.java:948)
<queued-asynchronous-processing-strategy poolExhaustedAction="RUN" name="commonProcessingStrategy" maxQueueSize="1000" doc:name="Queued Asynchronous Processing Strategy"/>
<file:connector name="inboundFileConnector" fileAge="1000" autoDelete="true" pollingFrequency="1000" workDirectory="C:/mule/orca/dataprovider/work"/>
<file:endpoint name="dataProviderInbound" path="C:\mule\orca\dataprovider\inbound" moveToPattern="#[function:datestamp]-#[header:originalFilename]" moveToDirectory="C:\mule\orca\dataprovider\history" connector-ref="inboundFileConnector" doc:name="Data Feed File" doc:description="new files are processed in 'work' folder, then moved to 'archive' folder"/>
<flow name="dataProviderFeedFlow">
<inbound-endpoint ref="dataProviderInbound"/>
<file:file-to-string-transformer />
<flow-ref name="dataSub"/>
</flow>
<sub-flow name="dataSub" >
<splitter expression="#[rows=org.mule.util.StringUtils.split(message.payload, '\n\r')]" />
<expression-transformer expression="#[org.mule.util.StringUtils.split(message.payload, ',')]" />
<foreach>
<flow-ref name="storageFlow" />
<flow-ref name="id" />
</foreach>
</sub-flow>
<flow name="storageFlow" processingStrategy="commonProcessingStrategy">
<logger level="INFO" message="calling the 'storageFlow' sub flow."/>
</flow>
<flow name="id" processingStrategy="commonProcessingStrategy">
<logger level="INFO" message="calling the 'id' sub flow."/>
</flow>
Here is a fixed version of the dataSub sub-flow that works fine:
<sub-flow name="dataSub">
<splitter expression="#[org.mule.util.StringUtils.split(message.payload, '\n\r')]" />
<splitter expression="#[org.mule.util.StringUtils.split(message.payload, ',')]" />
<flow-ref name="storageFlow" />
<all>
<async>
<flow-ref name="storageFlow" />
</async>
<async>
<flow-ref name="id" />
</async>
</all>
</sub-flow>
Notice that:
I use two splitter expressions,
I use an all message processor to ensure the same payload is sent to both private flows,
I have to wrap the flow-refs with an async message processor otherwise the invocation fails because the private flows are asynchronous but all forces synchronous.

mule weird flow behavior

I'm using mule 3.2.0 and
I'm invoking muleclient.send method in java-class which sends soap-request to a mule flow(not present here), which sends it to the http endpoint which receives request, logs it to my db with proxy pattern and propagates it to "ServiceFlow" which has Dispatcher transformer - java class, which uses invocation of MuleClient.send(String url, Object payload, Map messageProperties) method to dispatch one object of the payload array to an endpoint.
Then it gets processed by cxf:jax-ws-client, logged to a db once again and transferred to another instance of Dispatcher (where incoming payload is again of type Object[]). There I have http endpoint which does the service invocation. This part works okay.
But trouble appears at the receiving of the response. I've put Test1(2,3,4) transformers to print the invocation chain in my flows (They just do the System.out.println()), and saw that they're invoked in a weird sequence: I have it like 1,3 then TestTransformer (which is also the sysouter) then I get the error "NullPayload" in the caller of the main flow "Service flow" and then I receive the Test 4 and Test 2 outs. The responseTransformer-refs in patterns "1Proxy" are ignored, so as in "ServiceProxy". I've been looking for the solution for like a week now, and can't find it. In debugging, I can see that transformer called "TestTransformer" in has expected payload (Object[]) but when I receive it in my class caller, it appears as "NullPayload". I can see now that one of my endpoints has the path element instead of ref, not sure if this cause any impact on flow, but will check it. Also tried to use the "response" block to ensure my flow runs as expected. Any suggestions appreciated. Thanks
Here is what my config looks like:
<http:endpoint name="httpService" address="${service.soap}" exchange-pattern="request-response" responseTimeout="${timeout}" />
<vm:endpoint name="vmService" path="vmService" exchange-pattern="request-response"/>
<pattern:web-service-proxy
name="ServiceProxy"
inboundEndpoint-ref="httpService"
transformer-refs="to-string logging"
responseTransformer-refs="to-string logging"
outboundEndpoint-ref="vmService" />
<flow name="ServiceFlow" >
<inbound-endpoint ref="vmService"/>
<cxf:jaxws-service serviceClass="pkg.ServiceImpl" wsdlLocation="${service.wsdl}" enableMuleSoapHeaders="false" validationEnabled="true"/>
<custom-transformer class="pkg.Dispatcher">
<spring:property name="vmFlowPath" value="vm.logService"/>
</custom-transformer>
<custom-transformer name="TestTransformer" class="pkg.TestTransformer"/>
</flow>
<vm:endpoint name="vm1In" path="vm1In" exchange-pattern="request-response"/>
<vm:endpoint name="vm1Out" path="vm1Out" exchange-pattern="request-response"/>
<custom-transformer name="arrayGenerator" class="pkg.ArrayGenerator"/>
<custom-transformer name="objectExtractor" class="pkg.ObjectExtractor"/>
<custom-transformer name="faultChecker" class="pkg.FaultChecker"/>
<custom-transformer name="objectLogging" class="pkg.ObjectLogger">
<pattern:web-service-proxy
name="1Proxy"
inboundEndpoint-ref="vm1In"
transformer-refs="arrayGenerator objectLogging"
responseTransformer-refs="objectLogging objectExtractor faultChecker"
outboundEndpoint-ref="vm1Out" />
<flow name="logService">
<vm:inbound-endpoint path="vm.logService exchange-pattern="request-response"/>
<custom-transformer class="Test1"/>
<vm:outbound-endpoint ref="vm1In">
<cxf:jaxws-client
serviceClass="pkg.ServiceImpl"
operation="import"
enableMuleSoapHeaders="false"/>
<object-to-string-transformer/>
</vm:outbound-endpoint>
<object-to-xml-transformer>
<xm:xml-to-object-transformer returnClass="pkg.WSResponseClass"/>
<custom-transformer class="Test2"/>
</flow>
<flow name="DispatcherToServiceFlow">
<custom-transformer class="Test3"/>
<vm:inbound-endpoint path="vm1.Out"/>
<custom-transformer class="pkg.Dispatcher">
<spring:property name="vmFlowPath" value="vm.import"/>
</custom-transformer>
</flow>
<flow name="import">
<vm:inbound-endpoint path="vm.import" exchange-pattern="request-response"/>
<http:outbound-endpoint address="${importService}" responseTimeout="${timeout}" exchange-pattern="request-response" />
<object-to-string-transformer/>
<custom-transformer class="Test4"/>
</flow>
well, my problem really was the "path" element instead of referring to an existing vm endpoint with "ref" element like
<inbound-endpoint ref="vm1Out"/>