Mule consuming JMS topic message - mule

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=======

Related

How to acknowledge the activemq message in mule using client acknowledge?

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

Mule avoid downloading file after db select statement

<flow name="testFlow1" doc:name="testFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="${hostname}" port="${port}" path="dbtest" doc:name="HTTP"/>
<db:select config-ref="PostgreSQL" doc:name="Database">
<db:parameterized-query><![CDATA[SELECT id, name, int_status FROM test]]></db:parameterized-query>
</db:select>
<!--line 6 --> <!-- <set-payload value="==no downlaod=#[payload]" doc:name="Set Payload"/>-->
</flow>
when I run the application with url: host:port/dbtest, I am getting file downloaded. How can I avoid downloading file? If i enable line 6, I don't get file downloaded, instead it displays in browser.
Since you have used HTTP inbound 'exchange-pattern' as request-response. When you enable setpayload(line 6) it is returning to brower. If you dont want that, make HTTP exchange-pattern as one- way.
I tried the flow by adding an 'Object-to-String' transformer. It is working for me. The file is not downloading. Here is the flow.
<flow name="sampleflow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/"doc:name="HTTP></http:listener>
<db:select config-ref="MySQL_Configuration" doc:name="Database">
<db:parameterized-query><![CDATA[select id,name,designation,address from myrest]]></db:parameterized-query>
</db:select>
<object-to-string-transformer doc:name="Object to String"/>
</flow>
</mule>

Mule ESB: How to achieve unlimited Retry till the consuming Service is up and running

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!

Mule - mixing exchange patterns

I am trying to understand what is going one when i mix exchange patterns.
If i call a vm request-response inbound endpoint with a ones-way outbound endpoint, there is no error but it appears as though the flow is never run for example:
<flow name="main" doc:name="main" processingStrategy="asynchronous">
<poll frequency="60000">
<set-payload value="main"></set-payload>
</poll>
<set-variable value="xxx" variableName="var1"></set-variable>
<logger level="ERROR" message="MAIN1 #[flowVars.var1]" />
<vm:outbound-endpoint address="vm://vm" />
<logger level="ERROR" message="MAIN2 #[flowVars.var1]" />
</flow>
<flow name="p1">
<vm:inbound-endpoint address="vm://vm" exchange-pattern="request-response" />
<logger level="ERROR" message="PRIVATE #[flowVars.var1]" />
</flow>
</mule>
This configuration logs the following, but never prints 'PRIVATE xxx'.
ERROR 2014-03-26 13:22:35,794 [[test].main.stage1.01] org.mule.api.processor.LoggerMessageProcessor: MAIN1 xxx
ERROR 2014-03-26 13:22:35,812 [[test].main.stage1.01] org.mule.api.processor.LoggerMessageProcessor: MAIN2 xxx
INFO 2014-03-26 13:22:35,816 [[test].connector.VM.mule.default.dispatcher.01] org.mule.lifecycle.AbstractLifecycleManager: Initialising: 'connector.VM.mule.default.dispatcher.784920740'. Object is: VMMessageDispatcher
INFO 2014-03-26 13:22:35,817 [[test].connector.VM.mule.default.dispatcher.01] org.mule.lifecycle.AbstractLifecycleManager: Starting: 'connector.VM.mule.default.dispatcher.784920740'. Object is: VMMessageDispatcher
And if I mix them the other way around MAIN2 xxx never prints. Can someone explain what actually is going on here?
Mule docs state the following:
request-response:
When using request-response endpoints, messages are
delivered directly from an outbound vm endpoint to the inbound vm
endpoint that is listening on the same path. This delivery is blocking
and occurs in the same thread. If there is no inbound request-response
vm endpoint in the same Mule application listening on this path, then
dispatching of the message from the outbound endpoint will fail.
one-way:
When using one-way endpoints, messages are delivered to the
corresponding inbound endpoint via a queue. This delivery is
non-blocking. If there is no inbound one-way endpoint in the same Mule
application listening on this path, then, although dispatching of the
message will succeed, the message will remain in the queue. By
default, this queue is in memory, but it is also possible to configure
a persistent queue that will use the file system as its persistence
mechanism.
http://www.mulesoft.org/documentation/display/current/VM+Transport+Reference
I would guess the case with request-response outbound just remains waiting for a response, as the message gets dispatched and received contrary to the docs.
I don't mean to be rude, but It doesn't make sense to mix echange patterns this way. I believe one should never do something like this. In fact it's better to configure your exchange pattern on the vm endpoint globally, so that you have have consistent endpoints and you can't make mistakes.
<vm:endpoint name="vm-endp" path="vm-endp" exchange-pattern="request-response" />
<flow name="main" doc:name="main" processingStrategy="asynchronous">
<http:inbound-endpoint exchange-pattern="one-way" name="http-endpoint" host="localhost" port="2003" path="mule" doc:name="HTTP"/>
<set-variable variableName="var1" value="xxx" doc:name="XXX" />
<logger level="INFO" message="MAIN1 #[flowVars.var1]" />
<set-payload value="#[flowVars.var1]" />
<vm:outbound-endpoint ref="vm-endp" />
<logger level="INFO" message="MAIN2 #[flowVars.var1]" />
<logger level="INFO" message="PAYLOAD #[message.payloadAs(java.lang.String)]" />
</flow>
<!-- flowVars are FLOW VARIABLES, hence they're not accessible from multiple flows -->
<flow name="flow">
<vm:inbound-endpoint ref="vm-endp" />
<logger level="INFO" message="PRIVATE #[flowVars.var1]" />
<append-string-transformer message=" added to the payload" />
</flow>
It should output:
INFO [[VMtest].main.stage1.01] org.mule.api.processor.LoggerMessageProcessor: MAIN1 xxx
INFO [[VMtest].main.stage1.01] org.mule.lifecycle.AbstractLifecycleManager: Initialising: 'connector.VM.mule.default.dispatcher.1221995064'. Object is: VMMessageDispatcher
INFO [[VMtest].main.stage1.01] org.mule.lifecycle.AbstractLifecycleManager: Starting: 'connector.VM.mule.default.dispatcher.1221995064'. Object is: VMMessageDispatcher
INFO [[VMtest].main.stage1.01] org.mule.api.processor.LoggerMessageProcessor: PRIVATE null
INFO [[VMtest].main.stage1.01] org.mule.api.processor.LoggerMessageProcessor: MAIN2 xxx
INFO [[VMtest].main.stage1.01] org.mule.api.processor.LoggerMessageProcessor: PAYLOAD xxx added to the payload

How to rectify the issue with the below flow?

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.