How to publish-consume a message from IBM MQ using Message id or Correlation id in Mule4 - mule

I need to correlate request and reply messages. I have a requirement to publish a message to MQ(REQUEST.QUEUE) and consume the reply message from the reply queue(REPLY.QUEUE). I am using MuleSoft IBM MQ publish-consume operation to publish the message. I am also specifying a reply queue in the publish-consume configurations because the reply comes into the reply queue. I also set the "request-reply-pattern" but it does not seem to be consuming the correct message.
My requirements are to publish a message with a unique id(message_id or correlation_Id) so I can consume the reply of that particular message using the same message_id or correlation_Id. I could use any custom Id but I need to make sure when I consume it, I am not consuming any random message off the reply queue. It has to be the reply message which was the result of my publish message. This is a sync process so I will need to send and receive the message that is associated with a particular transaction
Below are my configurations of the publish-consume operator. I am able to publish the message but the consumer is reading any random message that is already sitting in the reply queue.
<ibm-mq:publish-consume doc:name="Publish consume" doc:id="86294ec7-6559-427f-8c80-eafa4b458a50" requestReplyPattern="CORRELATION_ID" config-ref="IBM_MQ_Config" destination="REQUEST.QUEUE">
<ibm-mq:message>
<ibm-mq:reply-to destination="REPLY.QUEUE" />
</ibm-mq:message>
<ibm-mq:consume-configuration maximumWait="10" ackMode="IMMEDIATE" maximumWaitUnit="SECONDS" /></ibm-mq:publish-consume>
Image of publish-consume configs

I do not think you can have consume node in the same flow and pick the messages based on the correlationID.
<flow name="publish-consume-correlation-id">
<ibm-mq:publish-consume config-ref="config"
destination="targetDestination"
requestReplyPattern="CORRELATION_ID">
<ibm-mq:message >
<ibm-mq:reply-to destination="replyToDestination" />
</ibm-mq:message>
</ibm-mq:publish-consume>
</flow>
<flow name="ibm-mq-listener-correlation-id" >
<ibm-mq:listener config-ref="config" destination="replyToDestination">
<ibm-mq:reply-to-response requestReplyPattern="CORRELATION_ID" />
</ibm-mq:listener>
</flow>

Related

How can I subscribe to a message being sent to the _skipped queue in rabbit mq

Question one: Can I subscribe to the event of a message being sent to the _skipped queue?
I am using masstransit together with rabbit mq. Some messages sometimes are sent to the _skipped queue for unclear reasons. The message type has a consumer, the ttl (time to life) is not small. It should not happen, and I am getting a log entry from masstransit, but I want to do more at the moment. Maybe log an error, in test maybe pop-up a window. Is there a way to achieve this? I am only getting these log messages below.
MassTransit.ReceiveTransport|SKIP rabbitmq://localhost/services_admin db270000-1fd6-00ff-3b83-08d9000ef97c
MassTransit.ReceiveTransport|Declare queue: name: services_admin_skipped, durable, consumer-count: 0 message-count: 3
Question two: What exactly happens to messages in the _skipped queue? Can they be resent?
Skipped messages either don't match the type (namespace included), don't have a consumer on the endpoint, or were a response to a request client that is no longer waiting for it. Since it's a receive endpoint queue, it's likely one of the first two reasons. Look at the message body/details in the RabbitMQ Management Console, that should give you some ideas.
You can use a shovel in RabbitMQ to move the messages back into the queue once you've resolved the issue.

RabbitMQ creates a temporary queue but don't know how or when

I'm using Mule ESB with two apps (one publishes status to the other through rabbitMQ). ONLY in my production environment, I get these amqp.gen- queues popping up but they're locked and I can't see what's inside of them. They're bound to my exchange (the publisher).
Customer is pointing at it as the problem for random assets being lost. I'm trying to eliminate them from happening but haven't got a clue. According to the rabbitMQ tutorial, these are created when you declare a queue but don't provide a name. However, I'm not doing that.
More info: The two apps use different logins to rabbitMQ and the queues are created by my app (the publisher), not the consumer app. I don't have a queue name and my queue declaration looks like this:
<amqp:connector name="amqpConnector"
host="${myApp.status_reporting.host}"
port="${myApp.status_reporting.port}"
username="${myApp.status_reporting.username}"
password="${myApp.status_reporting.password}"
requestedHeartbeat="${myApp.status_reporting.requestedHeartbeat}"
doc:name="AMQP Connector for Status Messages"/>
<flow name="cwm_send" doc:name="cwm_send">
<amqp:outbound-endpoint
exchangeName="${myApp.status_reporting.exchange_name}"
exchangeType="topic"
exchangeDurable="${myApp.status_reporting.exchange_is_durable}"
routingKey="${myApp.status_reporting.routing_key}"
connector-ref="amqpConnector"
doc:name="AMQP Out"
queueDurable="true"
responseTimeout="10000"
/>
</flow>
As you can see, there's no queue name. just a routing key.
My question is this: If there's no queue's bound to this exchange that match this routing key, is this why these temporary queues getting created?
How can my app retrieve the messages that are locked in them?
Am I doing something wrong architecturally?
Sorry for the open ended questions, but I gotta start somewhere.
The outbound-endpoint has no exchange-pattern configured. IIRC it defaults to request-response.
Given that there is no REPLY_TO header, the endpoint decides to create a temporary queue, send the message to the exchange and subscribe for an answer in the temporary queue.
If you don't want this behaviour just add exchange-pattern="one-way" to the outbound endpoint.

RabbitMQ: check if message has been delivered?

With a simple work queue, is is possible to ask the RabbitMQ server if a specific message has already been delivered to a consumer (worker) or if it is still in the queue?
You can't query RabbitMQ about a specific message has been delivered, but if you you need to know if a message has been processed by a consumer you could use an RPC implementation to get a response sent back to the sender once your message has been processed.
You can find an example on how to implement a RPC solution on RabbitMQ's official tutorials here.

How to Listen data from particular Correlation Id and Queue in Mule

Hi I am working with mule and i am using JMS inbound to listen particular queue. I want to configure my JMS in such a way that if i am pushing data from Active MQ with particular correlation id and that correlation id is already configured in Mule JMS Inbound. It will listen and poll only that. Please share some JMS XML configuration for better understanding.
There is a filter called jms:selector in JMS inbound to select a particular type of message based on it's properties
Now, as you said you are pushing a message from ActiveMQ with a particular corelation id so, you can select the message to consume in your Mule based on that particular corelation id as follows :-
<jms:inbound-endpoint queue="reply"
connector-ref="Active_MQ" exchange-pattern="one-way"
doc:name="JMS-REPLY"/ >
<jms:selector expression="JMSCorrelationID='your corelation id'"/>
</jms:inbound-endpoint>
You can see, the example here :- Mule request-reply consuming all the messages in the JMS reply queue
But, again, I would suggest you not to filter a message based corelation id, if that corelation id is not defined in your message you are pushing or you are not setting as static id, it may unable to consume if the corelation id differs.
So, rather I would suggest you to filter the message based on message priority,which is the best way to filter JMS messages.
Here is how, you can set a message priority in Mule flow itself on JMS messages and consume it based on that priority property :-
Mule: JMS reply queue consumes all the messages. I want to process messages that coming to reply queue

not able to push message to sonic JMS queue in mule

I have a scenario where I am reading the JMS message from queue and based on that I am firing SOAP call to retrieve corresponding document. However if SOAP service is not available or if its down, then I don't want to lose the JMS message that I read from queue. In this case, I am pushing this message to retry queue so that when SOAP service is up again, I can read the original message from retry queue and fire the SOAP call again.
Now the issue is that I am not able to push the original message to retry queue if SOAP service is down. Its going into the code block where I am checking for failure message and trying to push the original message to retry queue but its not actually pushing the message. This behavior is not consistent. Sometimes, it successfully pushes the messages but some times it not.
<when expression="#[xpath('//soapenv:Fault') != null ]">
<set-payload value="#[flowVars['abc']]" />
<jms:outbound-endpoint queue="${RETRY_QUEUE}" />
</when>
Any help is appreciated.