Below is my mule configuration, i want to acknowledge using client acknoledge , how can i do it?
<mule>
<jms:activemq-connector name="Active_MQ" brokerURL="tcp://localhost:61616" validateConnections="true" doc:name="Active MQ" maxRedelivery="2" persistentDelivery="true"/>
<flow name="activemqFlow">
<file:inbound-endpoint path="D:\mule\input" responseTimeout="10000" doc:name="File"/>
<object-to-string-transformer doc:name="Object to String"/>
<set-property propertyName="fileName" value="#[message.inboundProperties.originalFilename]" doc:name="Property"/>
<jms:outbound-endpoint queue="logfilequeue" connector-ref="Active_MQ" doc:name="JMS">
<jms:transaction action="NONE"/>
</jms:outbound-endpoint>
</flow>
<flow name="JmsInboundFlow">
<jms:inbound-endpoint queue="logfilequeue" connector-ref="Active_MQ" doc:name="JMS">
<jms:client-ack-transaction action="ALWAYS_BEGIN"/>
</jms:inbound-endpoint>
<logger message="#[payload.toString()]" level="INFO" doc:name="Logger"/>
<file:outbound-endpoint path="D:\mule\output" responseTimeout="10000" doc:name="File" outputPattern="#[message.inboundProperties.fileName]"/>
</flow>
</mule>
Note: Be REALLY sure you want to use CLIENT_ACKNOWLEDGE it doesn't work like most people think. It ack's the current message AND all previous within the session. If you have parallel/threaded consumers this setting will inadvertently ack messages that aren't ready to be ack'd yet. ActiveMQ has a INDIVIDUAL_ACKNOWLEDGE which ack's just the single message.
JMS Spec 2.0 has feat requests to make this add'l ack mode a standard.
Try adding acknowledgementMode="CLIENT_ACKNOWLEDGE" in your JMS connector.
You can refer this question for more details
Mule jms with CLIENT_ACKNOWLEDGE mode? Message automatically consumed even though I didn't acknoeledge it
Related
I am using Mule ESB to design a process whereby one can post a message to a topic. Subscribers will listen to the topic and receive messages. Each subscriber will act on the messages differently. The goal here is to have the ability to post a test message to the topic from HTTP for testing subscribers.
Here is how I have the JMS connection configured:
<!-- JMS Topic connector -->
<jms:activemq-connector name="jmsTopicConnection" specification="1.1" brokerURL="tcp://localhost:61616" validateConnections="true" doc:name="Active MQ2" durable="true" numberOfConcurrentTransactedReceivers="2"/>
This is the flow:
<flow name="auditJMSServiceFlow">
<http:listener config-ref="HTTP" path="/Audit/Activity" responseStreamingMode="ALWAYS" doc:name="HTTP"/>
<set-variable variableName="#['id']" value="#[message.inboundProperties['id']]" doc:name="set dynamic id"/>
<set-payload value="===TOPIC===" doc:name="Set Payload" />
<request-reply storePrefix="mainFlow">
<jms:inbound-endpoint topic="Audit.Activity" connector-ref="jmsTopicConnection" doc:name="JMS Topic Audit.Activity" exchange-pattern="request-response" durableName="audit_activity">
<jms:transaction action="ALWAYS_BEGIN" />
<!-- Not required to explicitly have this element. Mule will put this in implicitly. -->
<!-- <jms:jmsmessage-to-object-transformer displayName="JmsMsg to Object"/> -->
</jms:inbound-endpoint>
</request-reply>
<json:object-to-json-transformer doc:name="transform JMS message to JSON"/>
<json:validate-schema schemaLocation="resource://AuditMsgSchema.json" doc:name="Validate Json Schema"/>
<component class="com.baml.panther.audit.service.impl.AuditServiceImpl" doc:name="Java"/>
<default-exception-strategy>
<commit-transaction exception-pattern="com.foo.ExpectedExceptionType"/>
<jms:outbound-endpoint queue="dead.letter" connector-ref="jmsConnection">
<jms:transaction action="JOIN_IF_POSSIBLE" />
</jms:outbound-endpoint>
</default-exception-strategy>
<logger message="=== #[message.payload] received #[org.mule.util.DateUtiles.getTimeStamp('dd-MM-yyyy_HH-mm-ss.SSS')]" level="INFO" doc:name="Logger"/>
When I am running through the test I get the following error:
Any suggestions would be greatly appreciated.
Russ
For the error: Your request-reply scope is missing an outbound endpoint. You only have the inbound-endpoint (jms:inbound-endpoint). You need to provide the outbound-endpoint as well.
<request-reply storePrefix="mainFlow">
<jms:inbound-endpoint topic="Audit.Activity" connector-ref="jmsTopicConnection" doc:name="JMS Topic Audit.Activity" exchange-pattern="request-response" durableName="audit_activity">
<jms:transaction action="ALWAYS_BEGIN" />
<!-- Not required to explicitly have this element. Mule will put this in implicitly. -->
<!-- <jms:jmsmessage-to-object-transformer displayName="JmsMsg to Object"/> -->
</jms:inbound-endpoint>
</request-reply>
Not sure what your aim there but if you put just a jms:outbound-enpoint (instead of the whole request-reply block), you can send a message to the JMS topic.
The problem is that you cannot put a message source as the first message processor in a request-reply. The request reply allows you a kind of synchronous call for async protocols like JMS.
If you want to send a message to the message broker at the point where you put the request-reply just put a JMS outbound-endpoint.
If what you want to do is consume a message from the JMS topic you have to put a JMS inbound endpoint as the first message processor in a flow.
My flow is:
<flow name="activemqFlow3" doc:name="activemqFlow3">
<http:inbound-endpoint exchange-pattern="request-response" host="${hostname}" port="${port}" path="producetopic" doc:name="HTTP"/>
<set-payload value="===TOPIC===" doc:name="Set Payload"/>
<jms:outbound-endpoint topic="sfdc" connector-ref="Active_MQ" doc:name="JMS" />
</flow>
<flow name="activemqFlow4" doc:name="activemqFlow4">
<jms:inbound-endpoint doc:name="JMS" connector-ref="Active_MQ" topic="sfdc"/>
<logger message="===#[message.payload]" level="INFO" doc:name="Logger"/>
</flow>
AcitveMQ console shows one consumer under topic section, but I dont receive immediate response in the anypoint studio console once hit the http://localhost:9001/producetopic url. When I go to AcitveMQ console http://localhost:8161/admin/topics.jsp and selecting sfdc topic, send button will get the response in the Anypoint studio console.
Why immediate response/subscribe not displaying when I publish topic?
EDIT
Global element:
<jms:activemq-connector name="Active_MQ" brokerURL="tcp://localhost:61616" validateConnections="true" doc:name="Active MQ"/>
Console:
INFO 2015-05-15 07:56:21,820 [main] org.mule.module.launcher.DeploymentDirectoryWatcher:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Mule is up and kicking (every 5000ms) +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
INFO 2015-05-15 07:56:29,081 [[sfdc].activemqFlow4.stage1.02] org.mule.api.processor.LoggerMessageProcessor: ======TOPIC===
It was my mistake, server was displaying the data in the console. To understand better I have modified the subscriber logger to differentiate data from publisher.
<logger message="==Subscriber=#[message.payload]====" level="INFO" doc:name="Logger"/>
Now the console displays:
==Subscriber====TOPIC=======
<mulerequester:request config-ref="Mule_Requester1" resource="file:///#[flowVars.filename]" doc:name="Mule Requester"/>
<object-to-byte-array-transformer/>
<file:outbound-endpoint path="C:\OUTPUT" responseTimeout="10000" doc:name="Filewrite" outputPattern="#[flowVars.inpfilename]"/>
Please note below points
the above flow will create files (pdf,ppt,image ) with corrupted format in C:\OUTPUT folder
the file i want to move like pdf,ppt,image etc.
anyone suggest solution for that
If your requirement is to just move the files with some particular extenstions, this can be done by using File inbound and file outbound endpoints. Your flow should look like as follows
<flow name="testFlow1" doc:name="testFlow1">
<file:inbound-endpoint path="C:\Input" responseTimeout="10000" doc:name="File">
<file:filename-regex-filter pattern="*.pdf" caseSensitive="true"/>
</file:inbound-endpoint>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
<file:outbound-endpoint path="C:\Output" responseTimeout="10000" doc:name="File"/>
</flow>
I'm not sure how to apply logic to handle this issue.
I have a simple flow, Where I'm consuming the service in between the flow. I have tried until successful, but it required Max retries field( but I dont want to limit my retry by giving any number). To my scenario, I'm not sure when my consuming service is up, But need to retry until the service up and running ( not required retry exhausted). Could anyone suggest to handle the scenario.
<flow name="newFlow1" doc:name="newFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="ttt" doc:name="HTTP"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<logger message="**********test****#[payload]" level="INFO" doc:name="Logger"/>
<until-successful doc:name="Until Successful">
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8089" path="new" method="POST" doc:name="HTTP"/>
</until-successful>
<set-payload value="'Return Response'" doc:name="Set Payload"/>
</flow>
Also tried Max Retries in until successful as '-1'( to make as unlimited retry) but it is not accepting the negative value.
Tried using HTTP connector retry connection strategy(but it seems to be work for JMS or JDBC).
Could you please anyone suggest to handle this issue.
Thanks in advance.
Edited:
<http:connector name="HttpConnector" doc:name="HTTP-HTTPS">
<reconnect-forever />
</http:connector>
<flow name="new1Flow1" doc:name="new1Flow1">
<http:inbound-endpoint exchange-pattern="request-response" doc:name="HTTP" path="ttt" responseTimeout="30000" host="localhost" port="8081" />
<logger message="***entered***" level="INFO" doc:name="Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8089" path="new" connector-ref="HttpConnector" method="POST" doc:name="HTTP"/>
<logger message="**Http StatusCode***#[message.inboundProperties['http.status']]" level="INFO" doc:name="Logger"/>
</flow>
It is not doing retry, since the service is down I could see the following error message in console for one time only.( But we should get multiple times the error message in console until service up)
Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=http://localhost:8089/new, connector=HttpConnector
Please suggest.
You can first define a http Connector which will have a property of reconnecting forever
<http:connector name="HttpConnector" >
<reconnect-forever frequency="2000" />
</http:connector>
then you can have your inbound-or outbound endpoint use that connector reference
like this
<http:inbound-endpoint connector-ref="HttpConnector" .../>
or
<http:outbound-endpoint connector-ref="HttpConnector" .../>
Hope this helps!
Good luck!
I have a mule flow as under
<flow name="flow1" doc:name="f1">
<file:inbound-endpoint path="C:\input" responseTimeout="10000"
doc:name="File" />
</flow>
<flow name="flow2" doc:name="f2">
<http:inbound-endpoint address="http://localhost:8080"
doc:name="HTTP" exchange-pattern="request-response" />
<flow-ref name="flow1" doc:name="Flow Reference" />
<file:outbound-endpoint path="C:\outputfile"
responseTimeout="10000" doc:name="File" />
</flow>
I am trying to move/upload multiple files from source to destination (can be anything e.g. FTP or File outbound etc..) by using the flow.
The reason for doing in this way is that I want to invoke the job from CLI(Command Line Interface) using CURL.
But it is not working....
Edited
I need to pick up some files(multiple files) from a particular folder located in my hard drive. And then move those to some outbound process which can be FTP site or some other hard drive location.
But this flow needs to be invoked from CLI.
Edited (Based on David's answer)
I now have the flow as under
<flow name="filePickupFlow" doc:name="flow1" initialState="stopped">
<file:inbound-endpoint path="C:\Input" responseTimeout="10000" doc:name="File"/>
<logger message="#[message.payloadAs(java.lang.String)]" level="ERROR" />
</flow>
<flow name="flow2" doc:name="flow2">
<http:inbound-endpoint address="http://localhost:8080/file-pickup/start" doc:name="HTTP" exchange-pattern="request-response"/>
<expression-component>
app.registry.filePickupFlow.start();
</expression-component>
<file:outbound-endpoint path="C:\outputfile" responseTimeout="10000" doc:name="File"/>
</flow>
I am getting couple of problems
a) I am getting an error that - Attribute initialState is not defined as a valid property of flow
However, if I remove that attribute, the flow continues without waiting for "http://localhost:8080/file-pickup/start" to fire up.
b) The files are not moved to the destination folder
So how can I do so?
You can't reference a flow that has an inbound endpoint in it because such a flow is already active and consuming events from its inbound endpoint so you can't invoke it on demand.
The following, tested on Mule 3.3.1, shows how to start a "file pickup flow" on demand from an HTTP request.
<flow name="filePickupFlow" initialState="stopped">
<file:inbound-endpoint path="///tmp/mule/input" />
<!-- Do something with the file: here we just log its content -->
<logger message="#[message.payloadAs(java.lang.String)]" level="ERROR" />
</flow>
<flow name="filePickupStarterFlow">
<http:inbound-endpoint address="http://localhost:8080/file-pickup/start"
exchange-pattern="request-response" />
<expression-component>
app.registry.filePickupFlow.start();
</expression-component>
<set-payload value="File Pickup successfully started" />
</flow>
HTTP GETting http://localhost:8080/file-pickup/start would then start the filePickupFlow, which in turn will process the files in /tmp/mule/input.
Note that it is up to you to configure the file:connector for what behavior it must have for files it processes, either deleting them or moving them to another directory are two main options.
I guess in this case a File inbound to read a file on demand will not be helpful.
Please try if the follwoing way.
<flow name="flow1" doc:name="f2">
<http:inbound-endpoint address="http://localhost:8080"
doc:name="HTTP" exchange-pattern="request-response" />
<component>
<spring-object bean="fileLoader"></spring-object>
</component>
<file:outbound-endpoint path="C:\outputfile"
responseTimeout="10000" doc:name="File" />
</flow>
So the Custom component will be a Class which reads the file from your specified location.
Hope this helps.
You can use Mule Requester for a clean solution. See the details in the blog entry Introducing the Mule Requester.