How to manage JMS Request / Reply scenarios in BusinessWorks and BusinessWorks Container Edition
While the use of an HTTP transport is nowadays the most common way to manage synchronous Request / Reply interactions it is still possible in BusinessWorks to use a JMS transport for this. This bring some advantages like the ability to finely control message exchange scenarios and avoid data losses, the ability to manage volume spikes smoothly and the ability to secure access to the JMS destinations.
There are two approaches to manage JMS Request / Reply interactions in BusinessWorks:
. Use of a temporary reply queue
. Use of a fixed reply queue with a Correlation ID
This article is to explain how the activities used to implement such scenarios work and how to use them to implement both approaches.
# JMS Request / Reply activity
This activity is to be used by client processes, it is doing the following:
. Set the ‘Reply to’ queue to a fixed queue if specified or otherwise to a temporary queue
. Set a Correlation ID to the request message if specified in the Input mapping
. Send the request message to the defined request queue
. It will then wait for a response until it receives a message matching the following criterias or the defined time out expires:
- If using a temporary reply queue : a message is received on the queue
- If using a fixed reply queue : a message is received on the queue and the message Correlation ID matches the request message Correlation ID (if present) or the message Correlation ID matches the request message Message ID
Important note : the above behavior is applicable while using BusinessWorks 6.11 or above, for releases between 6.7 and 6.10 the Correlation ID is managed with both temporary and fixed queues which is not valid. In older releases the Correlation ID was not managed and only the approach of using temporary queues was working.
If no time out is defined the default synchronous activity time-out defined by the appnode configuration property bw.engine.activity.async.waitTime will apply (its default value is 3 minutes).
# The JMS ReplyToJMSMessage activity
This activity is to be used by server processes, it is doing the following:
. Set the Correlation ID of the response to the Correlation ID of the request message, if present, or otherwise to the Message ID of the request message
. Send the reply to the ‘Reply To’ queue defined in request message (fixed or temporary queue)
It is also possible to use the ‘JMS Send’ activity to send a reply, in this approach you have a little bit more configuration to do.
# JMS Request / Reply using a temporary reply queue
In this approach temporary queues ensure that each request gets its own dedicated reply queue, preventing potential interference or message mix-up between concurrent requests. This approach is easy to implement but it generates an overhead on the messaging server.
This approach is recommended for simple short-lived request / reply interactions where resource overhead is not a primary concern and loss of replies is acceptable.
Configuration of the JMS Request / Reply activity
. General tab
There is nothing specific here.
. Advanced tab
This is where the ‘Reply to’ queue is specified, here we leave this field empty because we want to use a temporary queue.
For performance reasons it is better to set the Delivery Mode to Non_persistent (this doesn’t really make sense to use persistent messages while the activity may time out).
. Input tab
There is no need to set anything apart from the Body of the request. I still recommend to apply the following good practices:
. Define a requestTimeout (the value is in milli-seconds), if not defined the appnode configuration property bw.engine.activity.async.waitTime defining the default synchronous activity time out will apply (its default value is 3 minutes)
. Define a time to live (JMS Expiration) for the request (the value is in milli-seconds), it is good to set it to the same duration as the request time out
Configuration of the JMS ReplyToJMSMessage activity
. General tab
Just set ‘Reply for Event’ to the JMS Receive Message activity used to handle the request message (in a context where a temporary reply queue is used the JMS Receive Message activity can be configured with the ‘Auto’ acknowledgement mode).
. Advanced tab
Set the Delivery Mode to Non_persistent (this is not useful to use persistent messages with a temporary reply queue and performances will be better).
. Input tab
There is no need to set anything apart from the Body of the reply. There is no need to define a time to live (JMS Expiration) for the message while the temporary queue will be deleted once the client will have consumed the reply or will have timed out or terminated.
# JMS Request / Reply using a fixed reply queue
This approach can be used to manage scenarios where the reply queue needs to have a specific configuration, for example it needs to be routed, or if the loss of reply messages should be avoided, or in cases where using temporary queues won’t be effective (for example in high throughput scenarios).
Use of fixed queues with Correlation ID is generally a more robust and scalable option. However, the correlation logic must be carefully manage.
Configuration of the JMS Request / Reply activity
. General tab
There is nothing specific here.
. Advanced tab
This is where the ‘Reply to’ queue is specified, here we set this field to the name of the queue used to manage the reply messages.
For performance reasons it is better to set the Delivery Mode to Non_persistent (this doesn’t really make sense to use persistent messages while the activity may time out).
. Input tab
There is no need to set anything apart from the Body of the request, but you may set the Correlation ID to a given value depending on what you want to achieve.
I also recommend applying the following good practices:
. Define a requestTimeout (the value is in milli-seconds), if not defined the appnode configuration property bw.engine.activity.async.waitTime defining the default synchronous activity time out will apply (its default value is 3 minutes)
. Define a time to live (JMS Expiration) for the request (the value is in milli-seconds), it is good to set it to the same duration as the request time out
Configuration of the JMS ReplyToJMSMessage activity
. General tab
Just set ‘Reply for Event’ to the JMS Receive Message activity used to handle the request message (the JMS Receive Message activity acknowledgement mode must be configured according to your requirements).
. Advanced tab
For performance reasons it is generally better to set the Delivery Mode to Non_persistent but depending on how the reply message is managed it may make sense to use the persistent mode (for example in the case replies would be managed asynchronously).
. Input tab
There is no need to set anything apart from the Body of the reply. The activity will automatically set the CorrelationID with the Correlation ID of the request message if it exists, otherwise it will set the CorrelationID with the Message ID of the request message. You may also set the Correlation ID with a specific value depending on what you are trying to achieve.
When using a fixed queue this is a good practice to define a time to live (JMS Expiration) for the message while the message may otherwise stay in the fixed queue for a long time. The value is in milli-seconds.
# Additional elements
It is also possible to manage JMS Request Reply interactions in an asynchronous way using JMS Send and JMS Receive Message activities.
In this approach correlation between requests and replies have to managed in the BusinessWorks application logic.
# Summary
There are two approaches to manage JMS Request / Reply interactions in BusinessWorks:
. Use of a temporary reply queue
. Use of a fixed reply queue with a Correlation ID
Use of a temporary reply queue is recommended for simple short-lived request / reply interactions where resource overhead is not a primary concern and loss of replies is acceptable.
Use of fixed queues with Correlation ID is generally a more robust and scalable option. However, the correlation logic must be carefully manage.