Requirement :- A JMS Connector with a Oracle AQ as inbound endpoint.
Problem statement :- How to reconnect a JMS connector after a regular interval so that when it reconnect it consumes the new messages in queue.
I have tried the below reconnect strategy
-- JMS Connector defined
<jms:connector name="AQJMS" validateConnections="true"
maxRedelivery="-1" numberOfConsumers="1" durable="true" doc:name="JMS"
username="X" password="X" connectionFactory-ref="OAQTopicConnectionFactoryBean">
-- reconnect at 5 sec
<reconnect-forever frequency="5000"/>
</jms:connector>
-- flow
<flow name="sendmessagetoqFlow">
-- jms inbound endpoint as oracle AQ
<jms:inbound-endpoint queue="QUEUE"
connector-ref="AQJMS" doc:name="AQJMS">
<jms:client-ack-transaction action="BEGIN_OR_JOIN"/>
</jms:inbound-endpoint>
<logger message="Log 1 - #[message.inboundProperties]" level="INFO" doc:name="Logger 1"/>
</flow>
But its not reconnecting after 5 seconds.
Could you please help me solve the problem.
Thanks in Advance.
Configuring Transactional Polling (Enterprise)
This works for me
<jms:connector ...cut...>
<service-overrides transactedMessageReceiver="com.mulesoft.mule.transport.jms.TransactedPollingJmsMessageReceiver" />
</jms:connector>
<jms:inbound-endpoint queue="my.queue">
<ee:multi-transaction action="ALWAYS_BEGIN" timeout="30000"/>
<properties>
<spring:entry key="pollingFrequency" value="5000" />
</properties>
</jms:inbound-endpoint>
Related
I have a request-response flow that starts with VM. Is there a way to restrict a number of the requests that could be processed in parallel by the flow? I'm on 3.7. Thanks.
Ps. I've tried using maxThreadsActive in VM connector but it still runs in the "source" thread. This is how the VM connector in defined:
<vm:connector name="myvm" validateConnections="true" doc:name="VM">
<receiver-threading-profile maxThreadsActive="1"/>
<vm:queue-profile>
<default-in-memory-queue-store/>
</vm:queue-profile>
</vm:connector>
and then in the flow:
<vm:inbound-endpoint exchange-pattern="request-response" path="myqueue" connector-ref="myvm" doc:name="getevent">
<vm:transaction action="NONE"/>
</vm:inbound-endpoint>
This is how it's called from the "source" flow:
<vm:outbound-endpoint exchange-pattern="request-response" path="myqueue" connector-ref="myvm" doc:name="VM">
<vm:transaction action="NONE"/>
</vm:outbound-endpoint>
You can configure the number of receiver threads for the connector or your inbound-endpoint to one:
<vm:connector name="VM" validateConnections="true">
<receiver-threading-profile maxThreadsActive="1"/>
</vm:connector>
<flow name="testFlow1">
<vm:inbound-endpoint path="in" connector-ref="VM"/>
<echo-component/>
</flow>
You can control this with the threading profiles. For example:
<configuration >
<default-threading-profile maxBufferSize="100" maxThreadsActive="20" maxThreadsIdle="10" threadTTL="60000" poolExhaustedAction="RUN" />
</configuration>
You can read more here: https://docs.mulesoft.com/mule-user-guide/v/3.7/tuning-performance
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.
I have 2 separate Amazon SQS queues; Queue and ResponseQueue.
SQS configurations:
<sqs:config name="Amazon_SQS_Consumer" accessKey="XXX" secretKey="XXX" queueName="Queue" doc:name="Amazon SQS">
<sqs:connection-pooling-profile maxActive="10" maxIdle="10" exhaustedAction="WHEN_EXHAUSTED_GROW" maxWait="12000" minEvictionMillis="60000" evictionCheckIntervalMillis="30000" initialisationPolicy="INITIALISE_ONE"/>
<reconnect count="5" frequency="1000"/>
</sqs:config>
<sqs:config name="Amazon_SQS_Response" accessKey="XXX" secretKey="XXX" queueName="ResponseQueue" doc:name="Amazon SQS">
<sqs:connection-pooling-profile maxActive="100" maxIdle="10" exhaustedAction="WHEN_EXHAUSTED_GROW" maxWait="12000" minEvictionMillis="60000" evictionCheckIntervalMillis="30000" initialisationPolicy="INITIALISE_ONE"/>
<reconnect count="5" frequency="1000"/>
</sqs:config>
I have no problem receiving messages from the first queue (Queue) via:
<flow name="consumer" doc:name="consumer">
<sqs:receive-messages config-ref="Amazon_SQS_Consumer" preserveMessages="true" doc:name="Amazon SQS (Streaming)" visibilityTimeout="300" />
<logger level="INFO" message="#[payload]" />
</flow>
I need to also receive messages from the second queue (ResponseQueue):
<flow name="response" doc:name="response">
<sqs:receive-messages config-ref="Amazon_SQS_Response" preserveMessages="true" doc:name="Amazon SQS (Streaming)" visibilityTimeout="300" />
<logger level="INFO" message="#[payload]" />
</flow>
However, whenever the second sqs:receive-messages is added, I get the following error:
Exception in thread "Receiving Thread" java.lang.LinkageError: loader (instance of org/mule/module/launcher/plugin/MulePluginsClassLoader): attempted duplicate class definition for name: "com/amazonaws/services/sqs/QueueUrlHandler"
Is it possible to read messages from 2 different queues in the same project?
I'm using 3.4.0 CE Mule Server Runtime and 2.4.4 Amazon SQS Connector. I need to stay at these versions. If I switch to 3.5.0 EE Mule Server Runtime, there is no problem in having multiple sqs:receive-messages; it works just as expected. However, it leads to another issue.
Are you using the same credentials in both sqs:config elements? If yes, then you only need one config element and then specify the queue name on the sqs:receive-messages elements.
<sqs:receive-messages queueName="Queue"
preserveMessages="true"
visibilityTimeout="300" />
Refer to the user guide: http://mulesoft.github.io/sqs-connector/2.5.0/mule/sqs-config.html#receive-messages
I have a jms connector, i am receiving message from a queue processing the message in a flow, calling db to get the data based on some ids in the message and writing response output to files, i am using dynamic outbound endpoints to decide output location.
<jms:connector name="tibco" numberOfConsumers="20" ..... >
.....
</jms:connector>
<flow name="realtime" doc:name="ServiceId-8">
<jms:inbound-endpoint queue="${some.queue}" connector-ref="tibco" doc:name="JMS">
<jms:transaction action="ALWAYS_BEGIN"/>
</jms:inbound-endpoint>
<processor ref="proc1"></processor>
<processor ref="proc2"></processor>
<component doc:name="Java">
<spring-object bean="comp1"/>
</component>
<processor ref="proc3"></processor>
<collection-splitter doc:name="Collection Splitter"/>
<processor ref="endpointprocessor"></processor>
<foreach collection="#[message.payload.consumerEndpoints]" counterVariableName="endpoints" doc:name="Foreach">
<when expression="#[consumerEndpoint.getOutputType().equals('txt') and consumerEndpoint.getChannel().equals('file')]">
<processor-chain>
<file:outbound-endpoint path="#[consumerEndpoint.getPath()]" outputPattern="#[consumerEndpoint.getClientId()]-#[attributes['eventId']]%#[consumerEndpoint.getTicSeedCount()]-#[attributes['dateTime']].tic" responseTimeout="10000" doc:name="File"/>
</processor-chain>
</when>
<when expression="#[consumerEndpoint.getOutputType().equals('txt') and consumerEndpoint.getChannel().equals('ftp')]">
<processor-chain>
<ftp:outbound-endpoint path="#[consumerEndpoint.getPath()]" outputPattern="#[consumerEndpoint.getClientId()]-#[attributes['eventId']]%#[consumerEndpoint.getTicSeedCount()]-#[attributes['dateTime']].tic" host="#[consumerEndpoint.getHost()]" port="#[consumerEndpoint.getPort()]" user="#[consumerEndpoint.getChannelUser()]" password="#[consumerEndpoint.getChannelPass()]" responseTimeout="10000" doc:name="FTP"/>
</processor-chain>
</when>
</choice>
</foreach>
<rollback-exception-strategy doc:name="Rollback Exception Strategy">
<processor ref="catchExceptionCustomHandling"></processor>
</rollback-exception-strategy>
</flow>
Above is not complete flow. i pasted the important parts to understand.
Question 1. As i have not defined any thread strategy at any level, and connector has numberOfConsumers="20", if i drop 20 messages in queue how many threads will start.
prefetch size in the jms queue is set to 20.
Question 2: Do i need to configure threading strategy at receiver end and/or at flow level.
some time when the load is very high(let say 15k msgs in queue in a minute) i see message processing gets slow and thread dump shows some thing like below:
"TIBCO EMS Session Dispatcher (7905958)" prio=10 tid=0x00002aaadd4cf000 nid=0x3714 waiting for monitor entry [0x000000004af1e000]
java.lang.Thread.State: BLOCKED (on object monitor)
at org.mule.endpoint.DynamicOutboundEndpoint.createStaticEndpoint(DynamicOutboundEndpoint.java:153)
- waiting to lock <0x00002aaab711c0e0> (a org.mule.endpoint.DynamicOutboundEndpoint)
Any help and pointers will be appreciated.
Thanks-
Message processing is getting slow because of dynamic endpoint, I see thread congestion when dynamic outbound endpoint is created and used. I was using mule 3.3.x and after looking at mule 3.4.x code i realized that dynamic outbound endpoint creation is handled more appropriately. upgraded to 3.4 and the issue is almost gone.
How do I create a delayed JMS message processor in Mule 3.3.1? My goal is to process messages from a queue in certain interval...some listener that wakes up every minute to process messages.
I have the following configuration, but the delay is not honored. When a message is rolled back, it is immediately picked for processing.
<spring:bean id="MQConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<spring:property name="transportType" value="1"/>
<spring:property name="hostName" value="myHost"/>
<spring:property name="port" value="1414"/>
<spring:property name="queueManager" value="myQmgr"/>
</spring:bean>
<jms:connector name="queueConnector" connectionFactory-ref="MQConnectionFactory"
specification="1.1" username="xxx" password="yyy"
disableTemporaryReplyToDestinations="true"
numberOfConcurrentTransactedReceivers="3" maxRedelivery="5">
<service-overrides transactedMessageReceiver="com.mulesoft.mule.transport.jms.TransactedPollingJmsMessageReceiver"/>
</jms:connector>
<jms:endpoint name="someQueue" queue="osmQueue" connector-ref="queueConnector">
<jms:transaction action="ALWAYS_BEGIN"/>
<property key="pollingFrequency" value="60000"/>
</jms:endpoint>
I did a lot of search but am unable to indentify a proper solution. If there is a better option, I'm open. Appreciate any help. 2 days and no response? Did I phrase the question wrong?
Have you tried using Quartz?
This config fires up your JMS inbound every minute
<flow name="ftpFlow2" doc:name="ftpFlow2">
<quartz:inbound-endpoint jobName="job1" repeatInterval="60000" responseTimeout="10000" doc:name="Quartz">
<quartz:endpoint-polling-job>
<quartz:job-endpoint ref="someQueue"/>
</quartz:endpoint-polling-job>
</quartz:inbound-endpoint>
</flow>