Overview
Java Messaging Service is often used for asynchronous communication between client and server. Mule ESB allows JMS for synchronous communication wherein the client and server can be be completely decoupled. The JMS synchronous communication is also referred to as “JMS Back-channel”. The JMS back-channel is usually not provided by the JMS protocol or any JMS brokers and has to be implemented by the applications. In this blog, a simple use case of the synchronous JMS communication using Mule ESB and Active MQ is described.
Implementation Details
In the below example, a string message is sent and received in order to demonstrate JMS back-channel. The Active MQ is used as a message broker for the demo. The JMS back-channel can be implemented by Mule ESB in two ways which are described in the following sections.
- Active MQ Connector Configuration
<jms:activemq-connector name="Active_MQ"
username="username" password="password"
brokerURL="tcp://localhost:63636"
validateConnections="true" doc:name="Active MQ" />
Approach 1: using request-response JMS endpoints
- Client Flow
- XML Code for the flow
<flow name="jmsmessagepublisher" doc:name="jmsmessagepublisher">
<http:inbound-endpoint exchange-pattern="request-response"
host="localhost" port="1111" path="backchannel" doc:name="HTTP" />
<set-payload value="Hello World from Sender" doc:name="Set Payload" />
<response>
<logger message="Final Response: #[payload]" level="INFO" doc:name="Logger" />
</response>
<logger message="Sending Message: #[payload]" level="INFO" doc:name="Logger" />
<jms:outbound-endpoint exchange-pattern="request-response"
queue="myQueue" connector-ref="Active_MQ" doc:name="JMS" />
</flow>
- Server Flow
- XML Code for the flow
<flow name="jmsmessagereceiver" doc:name="jmsmessagereceiver">
<jms:inbound-endpoint queue="myQueue" connector-ref="Active_MQ" doc:name="JMS"
exchange-pattern="request-response"/>
<logger message="Received Message: #[payload]" level="INFO" doc:name="Logger"/>
<set-payload value="Hello World from Receiver" doc:name="Set Payload"/>
<logger message="New Message Back to Sender: #[payload]" level="INFO" doc:name="Logger"/>
</flow>
- How it works
- A temporary response queue for JMS backchannel is created internally using Request-response JMS endpoints.
- Response is sent to the client via a temporary queue.
- The response queue is anonymous and Mule automatically sets the JMS_REPLY_TO property. This property instructs Mule on where the reply message needs to be sent.
- The response queue is created for every message exchange and is destroyed immediately after the client receives the response.
- JMSCorrelationId ensures proper sequencing.
Approach 2: using request-reply message processor
- Client Flow
- XML Code for the flow
<flow name="jmsmessagepublisher" doc:name="jmsmessagepublisher">
<http:inbound-endpoint exchange-pattern="request-response"
host="localhost" port="1111" path="backchannel" doc:name="HTTP" />
<set-payload value="Hello World from Sender" doc:name="Set Payload"/>
<logger message="Sending Message: #[payload]" level="INFO" doc:name="Logger"/>
<request-reply doc:name="Request-Reply">
<jms:outbound-endpoint queue="reqQueue" connector-ref="Active_MQ" doc:name="JMS"/>
<jms:inbound-endpoint queue="replyQueue" connector-ref="Active_MQ" doc:name="JMS"/>
</request-reply>
<logger message="Final Response: #[payload]" level="INFO" doc:name="Logger"/>
</flow>
- Server Flow
- XML Code for the flow
<flow name="jmsmessagereceiver" doc:name="jmsmessagereceiver">
<jms:inbound-endpoint queue="reqQueue" connector-ref="Active_MQ" doc:name="JMS"/>
<logger message="Received Message: #[payload]" level="INFO" doc:name="Logger"/>
<set-payload value="Hello World from Receiver" doc:name="Set Payload"/>
<logger message="New Message Back to Sender: #[payload]" level="INFO" doc:name="Logger"/>
<jms:outbound-endpoint queue="replyQueue" connector-ref="Active_MQ" doc:name="JMS"/>
</flow>
How it works
- JMS outbound and inbound endpoints are nested in the request-reply message processor.
- Requests are sent to target queue through JMS outbound-endpoint.
- Responses are received through the JMS inbound-endpoint.
- Both request and response queues are explicitly specified and are named queues.
- JMSCorrelationId ensures proper sequencing.
Testing and observation
- Open a browser and type the below URL
http://localhost:1111/backchannel
- This will invoke the “jmsmessagepublisher” flow and will send a message to request queue.
- “Jmsmessagereceiver” queue will log the request message received and return a new message.
- “Jmsmessagepublisher” flow will receive the message returned from the “Jmsmessagereceiver” queue and will log the final response.
- The final response will be printed on the browser.
- If using approach 1 and running in INFO mode, the temporary queue and correlation id are saved in logs.
Approach 1 vs Approach 2
- Approach 1 is useful, if message has to be sent and received on the same queue whereas Approach 2 is useful if there are two different queues for sending and receiving messages.
- Approach 1 creates a temporary queue for synchronous communication between client and server whereas approach 2 uses two named queues.
- Approach 1 creates and destroys the temporary queue for every message exchange and hence consumes additional CPU cycles and memory compared to approach 2.
- Approach 1 can raise a concern on performance and resource utilization.
Conclusion
JMS synchronous communication has an advantage of complete decoupling between the client and service. As described in this blog, the above mentioned approaches for JMS synchronous messaging using Mule ESB has their own set of advantages and disadvantages.
The implementation approach can be chosen on the basis of use case for the project.
If you would like to find out more about how Systems Integration could help you make the most out of your current infrastructure while enabling you to open your digital horizons, do give us a call at +44 (0)203 475 7980 or email us at Salesforce@coforge.com
Other useful links:
Related reads.
About Coforge.
We are a global digital services and solutions provider, who leverage emerging technologies and deep domain expertise to deliver real-world business impact for our clients. A focus on very select industries, a detailed understanding of the underlying processes of those industries, and partnerships with leading platforms provide us with a distinct perspective. We lead with our product engineering approach and leverage Cloud, Data, Integration, and Automation technologies to transform client businesses into intelligent, high-growth enterprises. Our proprietary platforms power critical business processes across our core verticals. We are located in 23 countries with 30 delivery centers across nine countries.