Hi I am working with Mule Any Point Studio. I want to define one queue name and from that queue i want to read the data using AMQP.
Its not polling the data from the Queue which i mentioned.
My Mule Flow:
<amqp:connector name="amqpConnector" doc:name="AMQP Connector" host="localhost" port="5672" username="admin" password="admin" validateConnections="true" ></amqp:connector>
<flow name="mule-ampq" doc:name="mule-ampq">
<amqp:inbound-endpoint exchangeName="AMQP.DEFAULT.EXCHANGE" queueName="newx" queueAutoDelete="true" connector-ref="amqpConnector" doc:name="AMQP" exchangeType="fanout" responseTimeout="10000"/>
<logger message="#[message.payload]" level="INFO" doc:name="Logger"/>
</flow>
I am getting the following Error:
ERROR 2014-10-16 15:54:44,452 [main] org.mule.module.launcher.DefaultArchiveDeployer:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Failed to deploy artifact 'mule-ampq', see below +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
org.mule.module.launcher.DeploymentStartException: EOFException:
at org.mule.module.launcher.application.DefaultMuleApplication.start(DefaultMuleApplication.java:143)
at org.mule.module.launcher.artifact.ArtifactWrapper$4.execute(ArtifactWrapper.java:98)
at org.mule.module.launcher.artifact.ArtifactWrapper.executeWithinArtifactClassLoader(ArtifactWrapper.java:129)
at org.mule.module.launcher.artifact.ArtifactWrapper.start(ArtifactWrapper.java:93)
at org.mule.module.launcher.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:26)
at org.mule.module.launcher.DefaultArchiveDeployer.guardedDeploy(DefaultArchiveDeployer.java:274)
at org.mule.module.launcher.DefaultArchiveDeployer.deployArtifact(DefaultArchiveDeployer.java:294)
at org.mule.module.launcher.DefaultArchiveDeployer.deployExplodedApp(DefaultArchiveDeployer.java:261)
at org.mule.module.launcher.DefaultArchiveDeployer.deployExplodedArtifact(DefaultArchiveDeployer.java:110)
at org.mule.module.launcher.DeploymentDirectoryWatcher.deployExplodedApps(DeploymentDirectoryWatcher.java:287)
at org.mule.module.launcher.DeploymentDirectoryWatcher.start(DeploymentDirectoryWatcher.java:148)
at org.mule.tooling.server.application.ApplicationDeployer.main(ApplicationDeployer.java:130)
Caused by: org.mule.retry.RetryPolicyExhaustedException: null
at org.mule.retry.policies.AbstractPolicyTemplate.execute(AbstractPolicyTemplate.java:101)
at org.mule.transport.AbstractConnector.connect(AbstractConnector.java:1621)
at org.mule.transport.AbstractConnector.start(AbstractConnector.java:424)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.mule.lifecycle.phases.DefaultLifecyclePhase.applyLifecycle(DefaultLifecyclePhase.java:237)
at org.mule.lifecycle.RegistryLifecycleManager$RegistryLifecycleCallback.onTransition(RegistryLifecycleManager.java:273)
at org.mule.lifecycle.RegistryLifecycleManager.invokePhase(RegistryLifecycleManager.java:152)
at org.mule.lifecycle.RegistryLifecycleManager.fireLifecycle(RegistryLifecycleManager.java:123)
at org.mule.registry.AbstractRegistryBroker.fireLifecycle(AbstractRegistryBroker.java:76)
at org.mule.registry.MuleRegistryHelper.fireLifecycle(MuleRegistryHelper.java:136)
at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:91)
at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:87)
at org.mule.lifecycle.MuleContextLifecycleManager.invokePhase(MuleContextLifecycleManager.java:69)
at org.mule.lifecycle.MuleContextLifecycleManager.fireLifecycle(MuleContextLifecycleManager.java:61)
at org.mule.DefaultMuleContext.start(DefaultMuleContext.java:278)
at org.mule.module.launcher.application.DefaultMuleApplication.start(DefaultMuleApplication.java:123)
... 11 more
Caused by: java.io.IOException
at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:107)
at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:259)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:383)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:403)
at org.mule.transport.amqp.AmqpConnector.connectToFirstResponsiveBroker(AmqpConnector.java:443)
at org.mule.transport.amqp.AmqpConnector.doConnect(AmqpConnector.java:365)
at org.mule.transport.AbstractConnector$5.doWork(AbstractConnector.java:1561)
at org.mule.retry.policies.AbstractPolicyTemplate.execute(AbstractPolicyTemplate.java:63)
... 29 more
Caused by: com.rabbitmq.client.ShutdownSignalException: connection error; reason: java.io.EOFException
at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:67)
at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:33)
at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:328)
at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:244)
... 35 more
Caused by: java.io.EOFException
at java.io.DataInputStream.readUnsignedByte(DataInputStream.java:290)
at com.rabbitmq.client.impl.Frame.readFrom(Frame.java:104)
at com.rabbitmq.client.impl.SocketFrameHandler.readFrame(SocketFrameHandler.java:141)
at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:402)
at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:430)
INFO 2014-10-16 15:54:44,455 [main] org.mule.module.launcher.DeploymentDirectoryWatcher:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Mule is up and kicking (every 5000ms) +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Try this example ... It contains different different exchange type used by AMQP .. For Direct Messaging you don't need to create the queue explicitly in the RabitMQ.. it will automatically created :-
<http:connector name="HttpConnector" doc:name="HTTP\HTTPS"/>
<amqp:connector name="amqpConnector" activeDeclarationsOnly="true" ackMode="MULE_AUTO" doc:name="AMQP Connector"/>
<amqp:connector name="amqpConnectorManualAck" prefetchCount="1" ackMode="MANUAL" doc:name="AMQP Connector"/>
<amqp:connector name="mandatoryAmqpConnector" mandatory="true" immediate="true" doc:name="AMQP Connector"/>
<!-- Direct Messaging -->
<amqp:connector name="amqp_config" validateConnections="true" virtualHost="/" username="guest" password="guest" doc:name="AMQP Connector"/>
<amqp:endpoint exchangeName="directEx" queueName="directQ" routingKey="routing.key" exchangeType="direct" queueDurable="true" name="amqp_direct_endpoint" responseTimeout="10000" doc:name="AMQP"/>
<!-- Direct Messaging -->
<jbossts:transaction-manager doc:name="Transaction Manager">
<property key="com.arjuna.ats.arjuna.coordinator.defaultTimeout" value="600"></property>
<property key="com.arjuna.ats.arjuna.coordinator.txReaperTimeout" value="1000000"></property>
</jbossts:transaction-manager>
<flow name="DefaultSender" doc:name="DefaultSender" >
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="1080" path="orders" doc:name="/orders" doc:description="Process HTTP reqests or responses." connector-ref="HttpConnector"/>
<set-payload value="New Message for Flow1" doc:name="Set Payload"/>
<logger message="Sending Message to Queue inhouseOrder .. Payload is #[message.payload]" level="INFO" category="DefaultSender" doc:name="Payload Logger" />
<amqp:outbound-endpoint exchange-pattern="request-response" exchangeName="directEx" exchangeType="direct" queueDurable="true" queueName="inhouseOrder" connector-ref="amqpConnector" doc:name="Dispatch to inhouseOrder" />
<byte-array-to-object-transformer doc:name="Byte Array to Object"/>
</flow>
<flow name="DefaultReceiver" doc:name="inhouseOrder" processingStrategy="synchronous" >
<amqp:inbound-endpoint queueName="inhouseOrder" connector-ref="amqpConnector" exchangeName="directEx" exchangeType="direct" queueDurable="true" doc:name="inhouseOrder" >
<amqp:transaction action="ALWAYS_BEGIN" recoverStrategy="REQUEUE" />
</amqp:inbound-endpoint>
<byte-array-to-object-transformer doc:name="Byte Array to Object"/>
<logger message="Receiving Message to Queue inhouseOrder .. Payload is #[message.payload]" level="INFO" category="DefaultReceiver" doc:name="Payload Logger" />
</flow>
<flow name="FanoutSenderExample2" doc:name="FanoutSenderExample2">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="1080" path="orders3" doc:name="/orders" doc:description="Process HTTP reqests or responses." connector-ref="HttpConnector"/>
<set-payload value="Fanout Message for Queue accounting" doc:name="Set Payload"/>
<logger message="Sending Payload in FanoutSenderExample2 #[message.payload]" level="INFO" category="FanoutSenderExample2" doc:name="Payload Logger" />
<amqp:outbound-endpoint exchangeName="back-end-processing" exchangeType="fanout" exchangeAutoDelete="false" exchangeDurable="true" queueDurable="true" queueExclusive="false" queueAutoDelete="false" exchange-pattern="one-way" connector-ref="amqpConnector" doc:name="Dispatch to back-end-processing" />
<byte-array-to-object-transformer doc:name="Byte Array to Object"/>
</flow>
<flow name="FanoutReceiverExample2" doc:name="FanoutReceiverExample2">
<amqp:inbound-endpoint exchangeName="back-end-processing" queueName="accounting" exchangeType="fanout" exchangeAutoDelete="false" exchangeDurable="true" queueDurable="true" queueExclusive="false" queueAutoDelete="false" connector-ref="amqpConnector" doc:name="back-end-processing fullfilment queue" />
<byte-array-to-object-transformer doc:name="Byte Array to Object"/>
<logger message="Payload received in FanoutReceiverExample2 is: #[payload]" level="INFO" category="FanoutReceiverExample2" doc:name="Payload Logger" />
</flow>
<!-- Direct Messaging -->
<flow name="Send_Message_Direct" doc:name="Send_Message_Direct">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="1080" doc:name="HTTP" path="orders5"/>
<set-payload value="#['im a Direct message'.getBytes()]" doc:name="Set payload for amqp message as ByteArray"/>
<amqp:outbound-endpoint responseTimeout="10000" doc:name="Send Direct Message" connector-ref="amqp_config" ref="amqp_direct_endpoint"/>
<set-payload value="#['Message Sended']" doc:name="Set payload as String"/>
<logger message="Direct message sended" level="INFO" doc:name="Logger"/>
</flow>
<flow name="Recive_Message_Direct" doc:name="Recive_Message_Direct">
<amqp:inbound-endpoint responseTimeout="10000" doc:name="Recive Direct Message" connector-ref="amqp_config" ref="amqp_direct_endpoint"/>
<byte-array-to-string-transformer doc:name="Transform bytearray message to String"/>
<logger message="I recived a direct message from AMQP: #[payload]" level="INFO" doc:name="Logger"/>
</flow>
<sub-flow name="defaultErrorHandler" doc:name="defaultErrorHandler">
<logger message="Error occurred: #[payload]" level="INFO" doc:name="Log Error"/>
<smtp:outbound-endpoint host="localhost" responseTimeout="10000" doc:name="Send Email to Operations"/>
</sub-flow>
</mule>
Reference :- Reference :- https://github.com/mulesoft/mule-transport-amqp/blob/master/GUIDE.md#mule-amqp-transport---user-guide
Related
SFTP connector does not delete the ssource file after reading in batch processing, while run as normal flow the file gets deleted
I am setting autoDelete="true" condition in the SFTP connector. Can anyone please suggest how to handle this scenario
<context:property-placeholder location="dev.properties"/>
<encryption:config name="Encryption" defaultEncrypter="PGP_ENCRYPTER" doc:name="Encryption">
<encryption:pgp-encrypter-config publicKeyRingFileName="keys/dev_pgp_wd_ecc_public.key.gpg" secretKeyRingFileName="keys/dev_pgp_wd_ecc_private.key.gpg" secretAliasId="${key.AliasId}" secretPassphrase="${key.Passphrase}" principal="${key.principal}"/>
</encryption:config>
<amqp:connector name="AMQP_Connector" validateConnections="true" host="${amqp.host}" doc:name="AMQP Connector" virtualHost="${amqp.virtualhost}" password="${amqp.password}" port="${amqp.port}" username="${amqp.user}"/>
<http:request-config name="HTTP_Request_PI" host="${pi.endpoint}" port="${pi.port}" doc:name="HTTP Request Configuration" basePath="${pi.path}" responseTimeout="30000">
<http:basic-authentication username="${pi.username}" password="${pi.password}"/>
</http:request-config>
<smtp:connector name="SMTP_Alert" contentType="text/html" validateConnections="true" doc:name="SMTP"/>
<sftp:connector name="SFTP_Inbound_Connector" validateConnections="true" autoDelete="true" pollingFrequency="120000" doc:name="SFTP"/>
<batch:job name="TestBatch" max-failed-records="-1">
<batch:input>
<sftp:inbound-endpoint connector-ref="SFTP_Inbound_Connector" host="${sftp.host}" port="${sftp.port}" path="/test/incoming/lt" user="${sftp.user}" password="${sftp.password}" responseTimeout="10000" doc:name="SFTP"/>
<encryption:decrypt config-ref="Encryption" using="PGP_ENCRYPTER" doc:name="Encryption"/>
<object-to-string-transformer doc:name="Object to String"/>
<logger message="Decrypted" level="INFO" doc:name="Logger"/>
<splitter expression="#[xpath3('/wd:Report_Data/wd:Report_Entry', payload, 'NODESET')]" doc:name="Splitter"/>
<mulexml:dom-to-xml-transformer doc:name="DOM to XML"/>
<dw:transform-message doc:name="Transform Message" metadata:id="b7cbbbbb-d58b-439b-8684-5a6d0345d48c">
<dw:input-payload doc:sample="empty.xml"/>
<dw:set-payload></dw:set-payload>
</dw:transform-message>
</batch:input>
<batch:process-records>
<batch:step name="Batch_Step1">
<json:object-to-json-transformer doc:name="Object to JSON"/>
<batch:commit size="5" doc:name="Batch Commit">
<amqp:outbound-endpoint exchangeName="${amqp.exchangeName}" queueName="${amqp.queueName}" responseTimeout="10000" encoding="UTF-8" mimeType="application/xml" connector-ref="AMQP_Connector" doc:name="AMQP"/>
</batch:commit>
</batch:step>
</batch:process-records>
<batch:on-complete>
<logger message="#[flowVars.totalRecords.totalRecords]" level="INFO" doc:name="Logger"/>
<logger message="#[flowVars.failedReocrds.failedReocrds]" level="INFO" doc:name="Logger"/>
<set-payload value="${mail.html}" doc:name="Set Payload" mimeType="text/html"/>
<smtp:outbound-endpoint host="${mail.host}" port="${mail.port}" user="${mail.user}" password="${mail.password}" connector-ref="SMTP_Alert" to="${mail.receiver}" from="${mail.from}" subject="${IntegrationName}" responseTimeout="10000" doc:name="SMTP"/>
</batch:on-complete>
</batch:job>
There seemed to be bugs around autoDelete and SFTP:
https://www.mulesoft.org/jira/browse/MULE-9144
So maybe this is the issue you are running into however in your normal flow you say it works.
So an option is to try a normal flow together with the batch execute component, so your FTP inbound endpoint and collection creation is part of a flow and from that flow you execute the batch processing. The input section of your batch element will be empty.
https://docs.mulesoft.com/mule-user-guide/v/3.7/batch-processing#triggering-batch-jobs
I'm trying same host, port, mailid from java program , it send mail successfully.
below is my mule smtp flow
<smtp:connector name="smtpConnector" doc:name="SMTP"/>
<flow name="sendmail" >
<http:inbound-endpoint exchange-pattern="request-response" host="0.0.0.0" port="8089" doc:name="HTTP" path="sendMail"/>
<smtp:outbound-endpoint host="15.456.128.61" port="587" user="test"
password="test123" to="xxxxx#xxx.com" from="xxxxx#xxx.com" subject="test mule"
responseTimeout="10000" connector-ref="smtpConnector" doc:name="Smtp"/>
<logger message="send mail suceesfully........ " level="INFO" doc:name="mailsend"/>
</flow>
http://localhost:8089/sendMail
using mule smtp i got below execption
Root Exception stack trace: javax.mail.AuthenticationFailedException:
535 5.7.3 Authentication unsuccessful
i tested smtp connector and it is working fine in mule flow , below is my code.
but here i used SMTPS
<http:listener-config name="HTTP_Listener_Configuration"
host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration" />
<flow name="yahooemailFlow">
<http:listener config-ref="HTTP_Listener_Configuration"
path="/" doc:name="HTTP" />
<set-payload value="#['Test Message ']" doc:name="Set Payload" />
<smtps:outbound-endpoint host="${smtp_host_ip}"
responseTimeout="10000" doc:name="SMTP" from="fromemail#yahoo.com"
mimeType="text/html" password="password" subject="subject"
to="toemail#yahoo.com" user="fromemail%40yahoo.com" />
<logger message="Mail Sent #[payload]" level="INFO" doc:name="Logger" />
</flow>
<flow name="listobjects">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="listobjects" contentType="text/plain" doc:name="HTTP"/>
<s3:list-objects config-ref="Amazon_S3" bucketName="demo" doc:name="Amazon S3" maxKeys="5" />
<!-- <payload-type-filter expectedType="java.util.List" doc:name="Payload"/> -->
<foreach collection="#[payload]" doc:name="For Each">
<!-- <foreach doc:name="For Each file"> -->
<logger message=" inside foreach...... #[payload.getKey()] ...." level="INFO" doc:name="Logger" />
<s3:get-object-content config-ref="Amazon_S3" bucketName="demo" key="#[payload.getKey()]" doc:name="Amazon S3"/>
<object-to-byte-array-transformer/>
<file:outbound-endpoint path="C:\output" responseTimeout="10000" doc:name="File" outputPattern="#[payload.getKey()] "></file:outbound-endpoint>
</foreach>
</flow>
I have bucket name called demo.
In that bucket I have 3 pdf files. I want to download all files and put it in c:\output folder.
I hit my url like http://localhost:8081/listobjects.
But I got the error:
Could not find a transformer to transform "CollectionDataType{type=org.mule.module.s3.simpleapi.SimpleAmazonS3AmazonDevKitImpl$S3ObjectSummaryIterable, itemType=com.amazonaws.services.s3.model.S3ObjectSummary, mimeType='/'}" to "SimpleDataType{type=org.mule.api.transport.OutputHandler, mimeType='/'}". (org.mule.api.transformer.TransformerException) (org.mule.api.transformer.TransformerException). Message payload is of type: SimpleAmazonS3AmazonDevKitImpl$S3ObjectSummaryIterable
The error occurs because after the foreach processor the payload is an instance of an S3 class, and you haven't specified any Content-Type to return. So Mule tries to transform the S3 instance to the default SimpleDataType and fails.
One way to solve it is simply to add something like
<set-property propertyName="Content-Type" value="application/json" doc:name="Content-Type" />
<set-payload value="{'result': 'ok'}"/>
at the end to make it explicit.
Also note that in your flow after running:
<object-to-byte-array-transformer/>
the S3 payload is gone, so #[payload.getKey()] will fail in the next processor:
<file:outbound-endpoint path="C:\output" responseTimeout="10000" doc:name="File" outputPattern="#[payload.getKey()] "></file:outbound-endpoint>
I've run this without problems:
<flow name="listobjects">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8083" path="listobjects" contentType="text/plain" doc:name="HTTP"/>
<s3:list-objects config-ref="Amazon_S3" bucketName="mule_test" doc:name="Amazon S3" maxKeys="5" />
<foreach collection="#[payload]" doc:name="For Each">
<logger message=" inside foreach...... #[payload.getKey()] ...." level="INFO" doc:name="Logger" />
<set-variable variableName="fileKey" value="#[payload.getKey()]" doc:name="Variable" />
<s3:get-object-content config-ref="Amazon_S3" bucketName="#[payload.getBucketName()]" key="#[payload.getKey()]" doc:name="Amazon S3"/>
<object-to-byte-array-transformer/>
<file:outbound-endpoint path="/tmp" responseTimeout="10000" doc:name="File" outputPattern="#[flowVars.fileKey] "></file:outbound-endpoint>
</foreach>
<set-property propertyName="Content-Type" value="application/json" doc:name="Content-Type" />
<set-payload value="{'result': 'ok'}"/>
</flow>
I was exploring Mule scatter-gather for parallel processing of flows in Mule fork and join pattern. My Mule config is as follows:
<flow name="fork" doc:name="fork">
<http:inbound-endpoint host="localhost" port="8090" path="mainPath" exchange-pattern="request-response" doc:name="HTTP"/>
<set-property propertyName="MULE_CORRELATION_GROUP_SIZE" value="2" doc:name="Property"/>
<!-- <all enableCorrelation="IF_NOT_SET" doc:name="All"> -->
<scatter-gather timeout="6000">
<processor-chain>
<async doc:name="Async">
<set-property propertyName="MULE_CORRELATION_SEQUENCE" value="1" doc:name="Property"/>
<flow-ref name="Flow1" doc:name="Flow Reference"/>
</async>
</processor-chain>
<async doc:name="Async">
<set-property propertyName="MULE_CORRELATION_SEQUENCE" value="2" doc:name="Property"/>
<flow-ref name="Flow2" doc:name="Flow Reference"/>
</async>
<!-- </all> -->
</scatter-gather>
<logger message="Main Flow" level="INFO" doc:name="Logger"/>
</flow>
<sub-flow name="Flow1" doc:name="Flow1">
<logger level="INFO" message="Flow1: processing started" doc:name="Logger"/>
<set-payload value="Flow1 Payload" doc:name="Set Payload"/>
<!-- Transformation payload -->
<logger level="INFO" message="Flow1: processing finished" doc:name="Logger"/>
<flow-ref name="Join-Flow" doc:name="Flow Reference"/>
</sub-flow>
<sub-flow name="Flow2" doc:name="Flow2">
<logger level="INFO" message="Flow2: processing started" doc:name="Logger"/>
<set-payload value="Flow2 Payload" doc:name="Set Payload"/>
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[sleep(2000); return message.payload;]]></scripting:script>
</scripting:component>
<!-- Transformation payload -->
<logger level="INFO" message="Flow2: processing finished" doc:name="Logger"/>
<flow-ref name="Join-Flow" doc:name="Flow Reference"/>
</sub-flow>
<sub-flow name="Join-Flow" doc:name="Join-Flow">
<collection-aggregator timeout="6000" failOnTimeout="true" doc:name="Collection Aggregator"/>
<combine-collections-transformer doc:name="Combine Collections"/>
<logger level="INFO" message="Combined Payload: #[message.payload]" doc:name="Logger"/>
<set-payload value="Soap XML Response" doc:name="Set Payload"/>
</sub-flow>
The scatter and gather is throwing following exception though I am getting the aggregated Payload in Logger:
Exception stack is:
1. null (java.lang.UnsupportedOperationException)
org.mule.VoidMuleEvent:50 (null)
2. null (java.lang.UnsupportedOperationException). Message payload is of type: String (org.mule.api.MessagingException)
org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:32 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.lang.UnsupportedOperationException
at org.mule.VoidMuleEvent.getMessage(VoidMuleEvent.java:50)
at org.mule.api.routing.AggregationContext$1.evaluate(AggregationContext.java:41)
at org.apache.commons.collections.CollectionUtils.select(CollectionUtils.java:517)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
INFO 2014-08-17 18:04:52,008 [[try1].fork.2.02] org.mule.api.processor.LoggerMessageProcessor: Flow2: processing started
INFO 2014-08-17 18:04:52,016 [[try1].fork.1.02] org.mule.api.processor.LoggerMessageProcessor: Flow1: processing started
INFO 2014-08-17 18:04:52,017 [[try1].fork.1.02] org.mule.api.processor.LoggerMessageProcessor: Flow1: processing finished
INFO 2014-08-17 18:04:54,309 [[try1].fork.2.02] org.mule.api.processor.LoggerMessageProcessor: Flow2: processing finished
INFO 2014-08-17 18:04:54,347 [[try1].fork.2.02] org.mule.api.processor.LoggerMessageProcessor: Combined Payload: [Flow1 Payload, Flow2 Payload]
One interesting fact is that if I use <all> router instead of scatter-gather, I don't get this exception. but I guess <all> router process the flows sequentially and not in parallel as per Mule documentation. So for that reason I tried to choose scatter-gather over all router. But I am not sure how to handle the above exception thrown by the scatter-gather. Is there any way out?
UPDATED FLOW :-
<flow name="fork" doc:name="fork">
<http:inbound-endpoint host="localhost" port="8090" path="mainPath" exchange-pattern="request-response" doc:name="HTTP"/>
<scatter-gather timeout="6000">
<processor-chain>
<flow-ref name="Flow1" doc:name="Flow Reference"/>
</processor-chain>
<flow-ref name="Flow2" doc:name="Flow Reference"/>
</scatter-gather>
<logger message="Main Flow" level="INFO" doc:name="Logger"/>
</flow>
<sub-flow name="Flow1" doc:name="Flow1">
<logger level="INFO" message="Flow1: processing started" doc:name="Logger"/>
<set-payload value="Flow1 Payload" doc:name="Set Payload"/>
<!-- Transformation payload -->
<logger level="INFO" message="Flow1: processing finished" doc:name="Logger"/>
<flow-ref name="Join-Flow" doc:name="Flow Reference"/>
</sub-flow>
<sub-flow name="Flow2" doc:name="Flow2">
<logger level="INFO" message="Flow2: processing started" doc:name="Logger"/>
<set-payload value="Flow2 Payload" doc:name="Set Payload"/>
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[sleep(2000); return message.payload;]]>
</scripting:script>
</scripting:component>
<!-- Transformation payload -->
<logger level="INFO" message="Flow2: processing finished" doc:name="Logger"/>
<flow-ref name="Join-Flow" doc:name="Flow Reference"/>
</sub-flow>
<sub-flow name="Join-Flow" doc:name="Join-Flow">
<collection-aggregator timeout="6000" failOnTimeout="true" doc:name="Collection Aggregator"/>
<combine-collections-transformer doc:name="Combine Collections"/>
<logger level="INFO" message="Combined Payload: #[message.payload]" doc:name="Logger"/>
<set-payload value="Soap XML Response" doc:name="Set Payload"/>
</sub-flow>
EXCEPTION :-
[try1].ScatterGatherWorkManager.02] org.mule.api.processor.LoggerMessageProcessor: Flow2: processing started
INFO 2014-08-18 13:34:24,361 [[try1].ScatterGatherWorkManager.01] org.mule.api.processor.LoggerMessageProcessor: Flow1: processing started
INFO 2014-08-18 13:34:24,364 [[try1].ScatterGatherWorkManager.01] org.mule.api.processor.LoggerMessageProcessor: Flow1: processing finished
WARN 2014-08-18 13:34:24,366 [[try1].ScatterGatherWorkManager.01] org.mule.routing.correlation.CollectionCorrelatorCallback: Correlation Group Size not set, but correlation aggregator is being used. Message is being forwarded as is
INFO 2014-08-18 13:34:24,401 [[try1].ScatterGatherWorkManager.01] org.mule.api.processor.LoggerMessageProcessor: Combined Payload: [Flow1 Payload]
INFO 2014-08-18 13:34:26,615 [[try1].ScatterGatherWorkManager.02] org.mule.api.processor.LoggerMessageProcessor: Flow2: processing finished
ERROR 2014-08-18 13:34:26,625 [[try1].connector.http.mule.default.receiver.03] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : null (java.lang.NullPointerException). Message payload is of type: String
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. null (java.lang.NullPointerException)
org.mule.api.routing.AggregationContext$1:41 (null)
2. null (java.lang.NullPointerException). Message payload is of type: String (org.mule.api.MessagingException)
org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:32 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.lang.NullPointerException
at org.mule.api.routing.AggregationContext$1.evaluate(AggregationContext.java:41)
at org.apache.commons.collections.CollectionUtils.select(CollectionUtils.java:517)
at org.apache.commons.collections.CollectionUtils.select(CollectionUtils.java:498)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
Now as you can see it's not combining the both payload of both flow after removing the set-property ..... It is getting only payload of first flow :- Combined Payload: [Flow1 Payload] ..
Remove the async scope around the message processors in the scatter-gather, which indeed does the parallelization for you so you don't have to.
EDIT: Also remove the set-property message processors that deal with the MULE_CORRELATION properties. The scatter-gather is supposed to do that for you.
EDIT2: You can remove the processor-chain around the single flow-ref: it's useless.
Also, there seem to be a deep misunderstanding about what scatter-gather does: you forcefully make its sub-flow responses converge to a single Join-Flow where you aggregate stuff, effectively by-passing and re-implementing all what the scatter-gather proposes to do for you.
Remove the flow-refs towards Join-Flow, remove Join-Flow and just put its processing logic (not the aggregator) after the scatter-gather.
So as per David's suggestion the final working solution is :-
<flow name="fork" doc:name="fork">
<http:inbound-endpoint host="localhost" port="8090" path="scattergather" exchange-pattern="request-response" doc:name="HTTP"/>
<scatter-gather timeout="6000">
<!-- Calling Flow1 -->
<flow-ref name="Flow1" doc:name="Flow Reference"/>
<!-- Calling Flow2 -->
<flow-ref name="Flow2" doc:name="Flow Reference"/>
</scatter-gather>
<!-- <collection-aggregator timeout="6000" failOnTimeout="true" doc:name="Collection Aggregator"/>
<combine-collections-transformer doc:name="Combine Collections"/> -->
<logger level="INFO" message="Combined Payload: #[message.payload]" doc:name="Logger"/>
<logger level="INFO" message="Payload1: #[message.payload[0]] and Payload2: #[message.payload[1]] " doc:name="Logger"/>
<set-payload value="Done Merging ...!!!" doc:name="Set Payload"/>
<logger message="Back to Main Flow" level="INFO" doc:name="Logger"/>
</flow>
<sub-flow name="Flow1" doc:name="Flow1">
<logger level="INFO" message="Flow1: processing started" doc:name="Logger"/>
<set-payload value="Flow1 Payload" doc:name="Set Payload"/>
<logger level="INFO" message="Flow1: processing finished" doc:name="Logger"/>
</sub-flow>
<sub-flow name="Flow2" doc:name="Flow2">
<logger level="INFO" message="Flow2: processing started" doc:name="Logger"/>
<!-- Sleep function to delay the flow2 payload -->
<set-payload value="Flow2 Payload" doc:name="Set Payload"/>
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[sleep(3000); return message.payload;]]></scripting:script>
</scripting:component>
<logger level="INFO" message="Flow2: processing finished" doc:name="Logger"/>
</sub-flow>
</mule>
I am using the following fork and join pattern in my flow.Parallel processing works just fine. However, I have issues with exception handling. I want to implement an exception strategy for the processing happening on VM response inbound endpoint of the router. However, it seems my nothing happens when I am trying to write to response, from within the catch exception strategy block. When there is an exception, I am able to see the log statement from the catch block, but the response on browser just hangs.
Please suggest.
<flow name="forkAndJoinFlow" doc:name="forkAndJoinFlow">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="81" path="lowestprice" doc:name="HTTP"/>
<not-filter doc:name="Not">
<wildcard-filter pattern="*favicon*" caseSensitive="true"/>
</not-filter>
<request-reply>
<all>
<vm:outbound-endpoint path="shop1"/>
<vm:outbound-endpoint path="shop2"/>
</all>
<vm:inbound-endpoint path="response">
<message-properties-transformer>
<add-message-property key="MULE_CORRELATION_GROUP_SIZE" value="2" />
</message-properties-transformer>
<collection-aggregator />
</vm:inbound-endpoint>
</request-reply>
<expression-transformer evaluator="groovy" expression="java.util.Collections.min(payload)" doc:name="Expression"/>
<object-to-string-transformer doc:name="Object to String"/>
<logger level="WARN" message="#[string:Lowest price: #[payload]]" doc:name="Logger"/>
<catch-exception-strategy doc:name="Catch Exception Strategy">
<logger message="EXCEPTION:#[payload]" level="INFO" doc:name="Logger"></logger>
<!--Nothing happens after this-->
<object-to-string-transformer doc:name="Object to String"></object-to-string-transformer></catch-exception-strategy>
</flow>
<flow name="shop1Flow" doc:name="shop1Flow">
<vm:inbound-endpoint path="shop1" doc:name="VM"/>
<logger level="INFO" message="SHOP1 Flow..." doc:name="Logger"/>
<expression-transformer evaluator="groovy" expression="new java.lang.Double(1000.0 * Math.random()).intValue()" doc:name="Expression"/>
<logger level="WARN" message="#[string:Price from shop 1: #[payload]]" doc:name="Logger"/>
</flow>
<flow name="shop2Flow" doc:name="shop2Flow">
<vm:inbound-endpoint path="shop2" doc:name="VM"/>
<logger level="INFO" message="SHOP2 Flow..." doc:name="Logger"/>
<expression-transformer evaluator="groovy" expression="new java.lang.Double(1000.0 * Math.random()).intValue()" doc:name="Expression"/>
<logger level="WARN" message="#[string:Price from shop 2: #[payload]]" doc:name="Logger"/>`enter code here`
</flow>
</mule>