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 have following Code for my Mule FLOW and seems like something is wrong with my code which is not allowing to invoke Catch Exception Strategy, What are the corrections required here ?
<flow name="Mule_Common_FTP_EDI_FilesProcessing_Inbound" doc:name="Mule_Common_FTP_EDI_FilesProcessing_Inbound"
processingStrategy="synchronous">
<quartz:inbound-endpoint cronExpression="${ftp.edi.inbound.cronExpression}" responseTimeout="${ftp.edi.inbound.root.responseTimeout}" jobName="pollingFTPFiles" doc:name="Quartz" connector-ref="pollingFTPFilesConnector">
<quartz:event-generator-job/>
</quartz:inbound-endpoint>
<set-payload value="#[[${ftp.edi.inbound.carriers.path}]]" doc:name="Set Payload"/>
<foreach doc:name="For Each">
<flow-ref name="Initialise-logging-variables" doc:name="Flow Reference"/>
<set-variable value="#[payload]" variableName="processing_folder_path" doc:name="Variable processing_folder_path" />
<mulerequester:request config-ref="FTP_Requester" resource="ftp://${ftp.edi.inbound.root.user}:${ftp.edi.inbound.root.password}#${ftp.edi.inbound.root.host}:${ftp.edi.inbound.root.port}${ftp.edi.inbound.root.path}#[payload]" timeout="${ftp.edi.inbound.root.responseTimeout}" doc:name="Mule Requester"/>
<choice doc:name="Choice">
<when expression="#[message.payload != null]">
<set-variable variableName="careerName" value="#[groovy:String s = flowVars.processing_folder_path; s.substring(0,s.indexOf('-'))]" doc:name="Variable careerName"/>
<set-variable variableName="filename" value="#[variable:careerName]-_#[message.outboundProperties['originalFilename']]" doc:name="Variable filename"/>
<file:file-to-string-transformer doc:name="File to String"/>
<set-variable variableName="InputPayload" value="#[payload:]" doc:name="Variable InputPayload"/>
<choice doc:name="Choice">
<when expression="#[regex(app.registry.configProperties[careerName])]">
<scripting:component doc:name="Script">
<scripting:script engine="Groovy" file="generateWSRequest.groovy"/>
</scripting:component>
<message-properties-transformer doc:name="Message Properties">
<add-message-property key="SOAPAction" value="/ProcessService/PDoc"/>
</message-properties-transformer>
<http:outbound-endpoint exchange-pattern="request-response" host="${http.host}" port="${http.port}" path="yourservices/service.svc" responseTimeout="${http.timeout.sync}" contentType="text/xml" connector-ref="httpConnector" doc:name="HTTP"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<set-variable value="#[message.payload.toString()]" variableName="OutputPayload" doc:name="Variable"/>
<choice doc:name="Choice">
<when expression="message.getInboundProperty('http.status') == '200'" evaluator="groovy">
<set-payload value="#[variable:InputPayload]" doc:name="Set Payload"/>
<file:outbound-endpoint path="${ftp.edi.outbound.root.success.path}" outputPattern="#[variable:filename]" responseTimeout="10000" doc:name="File"/>
<set-payload value="#[variable:InputPayload]" doc:name="Set Payload"/>
<ftp:outbound-endpoint host="${ftp.edi.inbound.root.host}" port="${ftp.edi.inbound.root.port}" path="${ftp.edi.elementum.copy.path}" user="${ftp.edi.inbound.root.user}" password="${ftp.edi.inbound.root.password}" outputPattern="#[message.outboundProperties['originalFilename']]" mimeType="text/plain" doc:name="FTP"/>
</when>
<otherwise>
<set-payload value="#[variable:InputPayload]" doc:name="Set Payload"/>
<set-variable variableName="original_message" value="#[groovy:message.toString()]" doc:name="original_message" />
<set-attachment attachmentName="#[message.outboundProperties['originalFilename']]" value="#[payload]" contentType="text/xml" doc:name="originalFileAttachment"/>
<set-variable variableName="content" value="${smtp.service.failure.body}, Splunk txId=#[sessionVars.logTxid] #[System.getProperty('line.separator')] #[System.getProperty('line.separator')] #[variable:logErrmsg] #[System.getProperty('line.separator')] #[System.getProperty('line.separator')] #[variable:original_message] #[System.getProperty('line.separator')]" doc:name="EmailBodyContent" />
<set-payload value="#[variable:content]" doc:name="Set Payload"/>
<set-variable variableName="subjectEmail" value="${smtp.service.failure.subject}filename=#[message.outboundProperties['originalFilename']]" doc:name="Variable"/>
<smtp:outbound-endpoint host="${smtp.host}" port="${smtp.port}" to="${smtp.to}" from="${smtp.from}" subject="#[variable:subjectEmail]" responseTimeout="10000" doc:name="HTTP_EMAIL_ALERT" mimeType="text/plain"/>
<set-payload value="#[variable:InputPayload]" doc:name="Set Payload"/>
<file:outbound-endpoint path="${ftp.edi.outbound.root.reprocesspath}" outputPattern="#[variable:filename]" responseTimeout="10000" doc:name="File"/>
<set-payload value="#[variable:InputPayload]" doc:name="Set Payload"/>
<ftp:outbound-endpoint host="${ftp.edi.inbound.root.host}" port="${ftp.edi.inbound.root.port}" path="${ftp.edi.elementum.copy.path}" user="${ftp.edi.inbound.root.user}" password="${ftp.edi.inbound.root.password}" outputPattern="#[message.outboundProperties['originalFilename']]" mimeType="text/plain" doc:name="FTP"/>
</otherwise>
</choice>
</when>
<otherwise>
<set-variable variableName="original_message" value="#[groovy:message.toString()]" doc:name="original_message" />
<set-attachment attachmentName="#[message.outboundProperties['originalFilename']]" value="#[payload]" contentType="text/xml" doc:name="OriginalFileAttachment"/>
<set-variable variableName="content" value="${smtp.file.not.supported.body}, Splunk txId=#[sessionVars.logTxid] #[System.getProperty('line.separator')] #[System.getProperty('line.separator')] #[variable:logErrmsg] #[System.getProperty('line.separator')] #[System.getProperty('line.separator')] #[variable:original_message] #[System.getProperty('line.separator')]" doc:name="EmailBodyContent" />
<set-payload value="#[variable:content]" doc:name="Set Payload"/>
<set-variable variableName="subjectEmail" value="${smtp.file.not.supported.subject}filename=#[message.outboundProperties['originalFilename']]" doc:name="Variable"/>
<smtp:outbound-endpoint host="${smtp.host}" port="${smtp.port}" to="${smtp.to}" from="${smtp.from}" subject="#[variable:subjectEmail]" responseTimeout="10000" doc:name="REGEX_NOT_FOUND_EMAIL_ALERT" mimeType="text/plain"/>
<logger message="{message = Email Sent to ${smtp.to}}" level="ERROR" doc:name="Logger"/>
<file:outbound-endpoint path="${ftp.edi.outbound.root.failedpath}" outputPattern="#[variable:filename]" responseTimeout="10000" doc:name="File"/>
</otherwise>
</choice>
</when>
<otherwise>
<logger message="{InboundPath=#[processing_folder_path], Message= REQUEST NOT PROCESSED NO MATCHING TEXT FOUND}" level="DEBUG" doc:name="Logger"/>
</otherwise>
</choice>
</foreach>
<choice-exception-strategy doc:name="Choice Exception Strategy">
<rollback-exception-strategy when="exception.causedBy(java.net.ConnectException) || exception.causedBy(java.net.SocketTimeoutException) || exception.causedBy(java.net.SocketException) || exception.causedBy(java.lang.Throwable)" maxRedeliveryAttempts="4" doc:name="Rollback Exception Strategy">
<on-redelivery-attempts-exceeded doc:name="Redelivery exhausted">
<set-variable variableName="errorMessage" value="{InboundPath=#[processing_folder_path], Ref= #[message.outboundProperties['originalFilename']], Content= #[groovy:payload.toString().replaceAll('\n', '')], Flow= #[variable:careerName], Message= MAXIMUM RETRIES REACHED}" doc:name="Variable"/>
<logger message="#[variable:errorMessage]" level="ERROR" doc:name="Logger"/>
<set-variable variableName="original_message" value="#[groovy:message.toString()]" doc:name="original_message" />
<set-attachment attachmentName="#[message.outboundProperties['originalFilename']]" value="#[payload]" contentType="text/xml" doc:name="OriginalFileAttachment"/>
<set-variable variableName="content" value="${smtp.rollback.body}, Splunk txId=#[sessionVars.logTxid] #[System.getProperty('line.separator')] #[System.getProperty('line.separator')] #[variable:logErrmsg] #[System.getProperty('line.separator')] #[System.getProperty('line.separator')] #[variable:original_message] #[System.getProperty('line.separator')]" doc:name="EmailBodyContent" />
<set-payload value="#[variable:content]" doc:name="Set Payload"/>
<set-variable variableName="subjectEmail" value="${smtp.rollback.subject}filename=#[message.outboundProperties['originalFilename']]" doc:name="Variable"/>
<smtp:outbound-endpoint host="${smtp.host}" port="${smtp.port}" to="${smtp.to}" from="${smtp.from}" subject="#[variable:subjectEmail]" responseTimeout="10000" doc:name="RETRY_FAILURE_EMAIL_ALERT" mimeType="text/plain"/>
<logger message="{message = Email Sent to ${smtp.to}}" level="ERROR" doc:name="Logger"/>
<file:file-to-string-transformer doc:name="File to String"/>
<file:outbound-endpoint path="${ftp.edi.outbound.root.failedpath}" responseTimeout="10000" outputPattern="#[message.outboundProperties['originalFilename']]" doc:name="File"/>
</on-redelivery-attempts-exceeded>
</rollback-exception-strategy>
<catch-exception-strategy when="exception.causeMatches(java.*)" doc:name="Data Errors Catch Exception Strategy">
<set-variable variableName="errorMessage" value="{InboundPath=#[processing_folder_path], Ref= #[message.outboundProperties['originalFilename']], Content= #[groovy:payload.toString().replaceAll('\n', '')], Flow= #[variable:careerName], Message=Common Exception Occured look at exception stackTrace for more details}" doc:name="Variable"/>
<logger message="#[variable:errorMessage]" level="ERROR" doc:name="Logger"/>
<set-variable variableName="original_message" value="#[groovy:message.toString()]" doc:name="original_message" />
<set-attachment attachmentName="#[message.outboundProperties['originalFilename']]" value="#[payload]" contentType="text/xml" doc:name="OriginalFileAttachment"/>
<set-variable variableName="content" value="${smtp.catch.exception.body}, Splunk txId=#[sessionVars.logTxid] #[System.getProperty('line.separator')] #[System.getProperty('line.separator')] #[variable:logErrmsg] #[System.getProperty('line.separator')] #[System.getProperty('line.separator')] #[variable:original_message] #[System.getProperty('line.separator')]" doc:name="EmailBodyContent" />
<set-payload value="#[variable:content]" doc:name="Set Payload"/>
<set-variable variableName="subjectEmail" value="${smtp.catch.exception.subject}filename=#[message.outboundProperties['originalFilename']]" doc:name="Variable"/>
<smtp:outbound-endpoint host="${smtp.host}" port="${smtp.port}" to="${smtp.to}" from="${smtp.from}" subject="#[variable:subjectEmail]" responseTimeout="10000" doc:name="CATCH_EXCEPTION_EMAIL_ALERT" mimeType="text/plain"/>
<logger message="{message = Email Sent to ${smtp.to}}" level="ERROR" doc:name="Logger"/>
<file:file-to-string-transformer doc:name="File to String"/>
<file:outbound-endpoint path="${ftp.edi.outbound.root.failedpath}" responseTimeout="10000" outputPattern="#[message.outboundProperties['originalFilename']]" doc:name="File"/>
</catch-exception-strategy>
</choice-exception-strategy>
</flow>
I am trying to put invalid WEBSERVICE URL here which is causing this error and i want to catch those kind of errors and send out emails if service is down or configuration is wrong and not able to process the files :
What i need to change here in my code which will allow me to receive email notification about this error ? Can you please advice me what's wrong with Exception Strategy here?
INFO 2015-04-29 11:31:40,105 [scheduler-edi-ftp-file-processing-1.0.0-SNAPSHOT-v20150427-19+32_Worker-1] org.mule.transport.http.transformers.ObjectToHttpClientMethodRequest: Content-Type not set on outgoing request, defaulting to: text/plain
ERROR 2015-04-29 11:31:40,123 [scheduler-edi-ftp-file-processing-1.0.0-SNAPSHOT-v20150427-19+32_Worker-1] org.mule.exception.DefaultSystemExceptionStrategy:
********************************************************************************
Message : Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=http://myservice.company.com:80/services/service.svc, connector=HttpConnector
{
name=httpConnector
lifecycle=start
this=4d81bcef
numberOfConcurrentTransactedReceivers=4
createMultipleTransactedReceivers=true
connected=true
supportedProtocols=[http]
serviceOverrides=
session.handler=org.mule.session.NullSessionHandler
}
, name='endpoint.http.myservice.company.com.80.services.service.svc', mep=REQUEST_RESPONSE, properties={Content-Type=text/xml}, transactionConfig=Transaction{factory=null, action=INDIFFERENT, timeout=0}, deleteUnacceptedMessages=false, initialState=started, responseTimeout=120000, endpointEncoding=UTF-8, disableTransportTransformer=false}. Message payload is of type: PostMethod
Code : MULE_ERROR-42999
--------------------------------------------------------------------------------
Exception stack is:
1. myservice.company.com (java.net.UnknownHostException)
java.net.AbstractPlainSocketImpl:175 (null)
2. Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=http://myservice.mycompany.com:80/services/service.svc, connector=HttpConnector
{
name=httpConnector
lifecycle=start
this=4d81bcef
numberOfConcurrentTransactedReceivers=4
createMultipleTransactedReceivers=true
connected=true
supportedProtocols=[http]
serviceOverrides=
session.handler=org.mule.session.NullSessionHandler
}
, name='endpoint.http.myservice.company.com.80.services.service.svc', mep=REQUEST_RESPONSE, properties={Content-Type=text/xml}, transactionConfig=Transaction{factory=null, action=INDIFFERENT, timeout=0}, deleteUnacceptedMessages=false, initialState=started, responseTimeout=120000, endpointEncoding=UTF-8, disableTransportTransformer=false}. Message payload is of type: PostMethod (org.mule.api.transport.DispatchException)
org.mule.transport.http.HttpClientMessageDispatcher:155 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/DispatchException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.net.UnknownHostException: myservice.company.com
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:175)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
at java.net.Socket.connect(Socket.java:546)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
Either one of the following:
Add "|| exception.causedBy(java.net.UnknownHostException)" to your first exception strategy to catch only unknown hosts exception.
Change your second catch exception strategy into exception.causeMatches('java.net.*') to catch all network exceptions (notice the quotes).
Change your second catch exception strategy into exception.causeMatches('java.*') to catch all java exceptions (notice the quotes).
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
How can I get Mule to download just attachments using pop3? I tried following the example at http://www.mulesoft.org/documentation/display/current/POP3+Transport+Reference as closely as possible, but I keep getting two files: one with the e-mail body and one with the actual attachment. Here's the flow I'm using:
<pop3:connector name="pop3Connector" checkFrequency="5000" doc:name="POP3"/>
<expression-transformer name="returnAttachments" doc:name="Expression">
<return-argument evaluator="attachments-list" expression="*" />
</expression-transformer>
<file:connector name="fileName" doc:name="File">
<file:expression-filename-parser/>
</file:connector>
<flow name="incoming-orders" doc:name="incoming-orders">
<pop3s:inbound-endpoint host="pop.gmail.com" port="995" user="myuser%40mydomain" password="mypassword" responseTimeout="10000" doc:name="POP3" transformer-refs="returnAttachments" />
<collection-splitter doc:name="Collection Splitter"/>
<file:outbound-endpoint path="C:/popthreetest" outputPattern="#[function:datestamp].dat" doc:name="File">
<expression-transformer>
<return-argument expression="payload.inputStream" evaluator="groovy" />
</expression-transformer>
</file:outbound-endpoint>
</flow>
Thanks!
edit:
Here's the final flow based on #David Dossot's answer. I have an added complexity in that I'm reading in a JSON file that specifies attachment names and an arbitrary destinations for the attachment. I included the replaceAll because I was getting an error about an invalid character in the path file:///C:\.
<pop3:connector name="pop3Connector" checkFrequency="5000" doc:name="POP3"/>
<expression-transformer name="returnAttachments" doc:name="Expression">
<return-argument evaluator="attachments-list" expression="*" />
</expression-transformer>
<file:connector name="DestinationsFileConnector" doc:name="File" autoDelete="false" streaming="true" validateConnections="true">
<file:expression-filename-parser/>
</file:connector>
<file:endpoint path="C:/popthreetest/" name="DestinationsFileEndpoint" responseTimeout="10000" doc:name="File" connector-ref="DestinationsFileConnector">
<file:filename-regex-filter pattern="destinations\.json" caseSensitive="true"/>
</file:endpoint>
<mulerequester:config name="DestinationsMuleRequestorConnector" doc:name="Mule Requester"/>
<flow name="incoming-orders" doc:name="incoming-orders">
<pop3s:inbound-endpoint host="pop.gmail.com" port="995" user="myusername%40mydomain" password="mypassword" responseTimeout="10000" doc:name="POP3" transformer-refs="returnAttachments" />
<collection-splitter doc:name="Collection Splitter"/>
<set-variable variableName="MessagePart" value="#[message.payload]" doc:name="MessagePart"/>
<logger message="Got #[message.payload.dataSource.name]." level="INFO" doc:name="Logger"/>
<mulerequester:request config-ref="DestinationsMuleRequestorConnector" resource="DestinationsFileEndpoint" doc:name="GetDestinations"/>
<json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/>
<choice doc:name="Choice">
<when expression="#[message.payload.get(MessagePart.dataSource.name) != null]">
<set-payload value="#[message.payload.get(MessagePart.dataSource.name)]" doc:name="Destination List"/>
<foreach doc:name="For Each">
<logger message="Saving to #[message.payload]." level="INFO" doc:name="Logger"/>
<set-variable variableName="DestinationPath" value="#[java.nio.file.Paths.get(message.payload).getParent().toString().replaceAll('\\\\', '/')]" doc:name="DestinationPath"/>
<set-variable variableName="DestinationPattern" value="#[java.nio.file.Paths.get(message.payload).getFileName()]" doc:name="DestinationPattern"/>
<logger message="Saving to #[DestinationPattern] in #[DestinationPath]." level="INFO" doc:name="Logger"/>
<set-payload value="#[MessagePart]" doc:name="MessagePart"/>
<file:outbound-endpoint path="#[DestinationPath]" outputPattern="#[DestinationPattern]" doc:name="File">
<expression-transformer>
<return-argument expression="payload.inputStream" evaluator="groovy"/>
</expression-transformer>
</file:outbound-endpoint>
</foreach>
</when>
<otherwise>
<logger message="Did not find destination(s) for #[MessagePart.dataSource.name]." level="INFO" doc:name="Logger"/>
</otherwise>
</choice>
</flow>
For completeness, here's the JSON file:
{
"attachment-name.txt": [
"C:/popthreetest/firstDestination.txt"
, "C:/path/to/secondDestination.txt"
, "C:\\popthreetest\\destination\\using-backslashes.txt"
]
}
An email with attachment is a multi-part email into which attachments are parts but also the body. Hence Mule can only download "the whole package" and give the different parts to you.
You should be able to filter the body part after the collection-splitter based on the name of the part.
Alternatively, you could use a MEL expression to drop the first element of the collection, which is typically the body (Mule uses this technique internally to set the message payload: https://github.com/mulesoft/mule/blob/mule-3.x/transports/email/src/main/java/org/mule/transport/email/transformers/EmailMessageToString.java#L50 )
I am having the following problem concerning asynchronous (or one-way) vm inbound endpoints. In the tests below, it seems that the number of one-way inbound endpoints is limited to 20 per vmconnector. My question is: Is there a setting on the vmconnector or a way programmatically to configure the vmconnector to remove this limitation?
I am using Mule 3.3.1 CE.
Thanks.
test1 (will fail to reach secondFlow unless the 21nd endpoint uses vmConn2):
<mule ..>
<stdio:connector name="stdioConn" messageDelayTime="1000" promptMessage="prompt >"/>
<vm:connector name="vmConn"/>
<vm:connector name="vmConn2"/>
<flow name="FirstFlow">
<stdio:inbound-endpoint system="IN" connector-ref="stdioConn"/>
<vm:outbound-endpoint exchange-pattern="one-way" path="path21" connector-ref="vmConn"/>
</flow>
<flow name="SecondFlow">
<composite-source doc:name="Composite Source">
<vm:inbound-endpoint exchange-pattern="one-way" path="path1" connector-ref="vmConn"/>
<vm:inbound-endpoint exchange-pattern="one-way" path="path2" connector-ref="vmConn"/>
<vm:inbound-endpoint exchange-pattern="one-way" path="path3" connector-ref="vmConn"/>
....
<vm:inbound-endpoint exchange-pattern="one-way" path="path20" connector-ref="vmConn"/>
<vm:inbound-endpoint exchange-pattern="one-way" path="path21" connector-ref="vmConn"/>
</composite-source>
<logger message="MESSAGE RECEIVED!" level="INFO" doc:name="Logger"/>
</flow>
test2 (same test with 21 flows):
<flow name="Flow1" >
<stdio:inbound-endpoint system="IN" connector-ref="stdioConn"/>
<vm:outbound-endpoint exchange-pattern="one-way" path="path21" connector-ref="vmConn" />
</flow>
<flow name="Flow2">
<vm:inbound-endpoint exchange-pattern="one-way" path="path1" connector-ref="vmConn" doc:name="VM" />
<logger message="MESSAGE RECEIVED!" level="INFO" doc:name="Logger" />
</flow>
<flow name="Flow3">
<vm:inbound-endpoint exchange-pattern="one-way" path="path2" connector-ref="vmConn" doc:name="VM" />
<logger message="MESSAGE RECEIVED!" level="INFO" doc:name="Logger" />
</flow>
...
<flow name="Flow21">
<vm:inbound-endpoint exchange-pattern="one-way" path="path20" connector-ref="vmConn" doc:name="VM" />
<logger message="MESSAGE RECEIVED!" level="INFO" doc:name="Logger" />
</flow>
<flow name="Flow22">
<vm:inbound-endpoint exchange-pattern="one-way" path="path21" connector-ref="vmConn" doc:name="VM" />
<logger message="MESSAGE RECEIVED!" level="INFO" doc:name="Logger" />
</flow>
Any vm connector has a thread pool of message receivers. Once the receiver are exhausted new vm inbound endpoint want be able to process messages.
To address it you should increase the number of message receivers configuring threading profiles properly