<jms:publish-consume
doc:name="Publish consume"
doc:id="facb4f6a-5796-4d62-9052-64258dfd8639"
config-ref="config"
destination="targetDestination">
<jms:consume-configuration maximumWait="20" maximumWaitUnit="SECONDS" />
</jms:publish-consume>
Publish Messages and Listen for Replies
Request and reply is a very common pattern between applications, thus the JMS
connector provides the publish-consume
operation specifically for that.
The publish-consume
operation lets you publish a message to any destination,
and then wait for a reply on a different destination.
When using this operation, the JMSReplyTo header of the outgoing message contains the ID of the destination on which your application waits for a response. This destination may be a well-known destination, or it may be a temporary destination created on the fly with the purpose of receiving a single response message.
Finally, the result of the operation is the message received as a response,
with the same structure as if a consume
operation was invoked.
Wait For a Reply On a Temporary Queue
Using a temporary queue to wait for a response is very simple, just configure the message being sent and the operation automatically waits for a response in a temporary queue:
In this example, the operation publishes a message with the current
payload
as its body and the JMSReplyTo header
configured to a temporary
destination, to the targetDestination
.
Then, it automatically tries to consume the response from that temporary
queue until a message is consumed or the maximumWait
is reached, in which case
it fails with a JMS:TIMEOUT
error).
Receive the Reply On a Known Queue
In many cases you don’t want to reply to queues to be created on a per-request basis, but
instead a well-known queue is used for replies. For this cases, all you have to
do is to configure the reply-to
parameter on the outgoing message:
<jms:publish-consume config-ref="config" destination="targetDestination">
<jms:message>
<jms:reply-to destination="replyToDestination"/>
</jms:message>
</jms:publish-consume>
Now the operation publishes a message to the targetDestination
with the
current payload
as its body and the JMSReplyTo
header configured with
the replyToDestination
.
Then, it automatically tries to consume the response from the
replyToDestination
queue until a message is consumed or the maximumWait
is
reached, in which case it fails with a JMS:TIMEOUT
error.
Request Reply Patterns
As of JMS Connector 1.6.0:
In JMS, there exists two well know Request-Reply patterns for how request and reply messages are correlated. This ensures that an incoming message is the proper reply of an outgoing message.
Correlation ID Pattern
This pattern is the default one in the Publish Consume operation, the usage of this pattern implies that the operation after publishing a message to the destination queue, consumes a message using a selector that expects a message with the same Correlation ID to be used to publish the request message.
<flow name="publish-consume-correlation-id">
<jms:publish-consume config-ref="config" destination="targetDestination" requestReplyPattern="CORRELATION_ID">
<jms:message >
<jms:reply-to destination="replyToDestination" />
</jms:message>
</jms:publish-consume>
<logger message="Received message from 'replyToDestination' with Correlation ID: #[attributes.headers.correlationId]"/>
</flow>
<flow name="jms-listener-correlation-id" >
<jms:listener config-ref="config" destination="targetDestination">
<jms:response requestReplyPattern="CORRELATION_ID" />
</jms:listener>
<logger level="INFO" message="About to reply to 'targetDestination' with Correlation ID: #[attributes.headers.correlationId]"/>
</flow>
Message ID Pattern
Different from the Correlation ID Pattern is the Message ID pattern that implies that an operation after publishing a message to the destination queue, will consume a message using a selector that expects a message with a Correlation ID of the same value as the Message ID of the request message.
<flow name="publish-consume-message-id">
<jms:publish-consume config-ref="config"
destination="targetDestination"
requestReplyPattern="MESSAGE_ID">
<jms:message >
<jms:reply-to destination="replyToDestination" />
</jms:message>
</jms:publish-consume>
<logger message="Received message from 'replyToDestination' with Correlation ID: #[attributes.headers.correlationId]"/>
</flow>
<flow name="jms-listener-message-id" >
<jms:listener config-ref="config" destination="targetDestination">
<jms:response requestReplyPattern="MESSAGE_ID" />
</jms:listener>
<logger level="INFO" message="About to reply to 'targetDestination' with Correlation ID: #[attributes.headers.messageId]"/>
</flow>