fb
WSO2 Enterprise Integrator 5 min

Synchronous Invocations over JMS queues on WSO2 EI / WSO2 ESB

Wouter van Wijngaarden
Wouter van Wijngaarden
Integration Consultant
Synchronous scaled
Scroll

SynchronousOne of our clients wanted an Enterprise Service Bus setup where the message flows worked synchronously but still used JMS queues to ensure no message were lost. In this blog, I will explain to you how to set this up.

First things first. You first need to configure the product to work with JMS. I’m not going to cover this specifically in this blog but it can be done fairly easily by adding some JAR files and uncommenting lines in the axis2.xml configuration. A how to is described inside the WSO2 documentation here

In this case we developed for one of our clients the origin system wants to send a message to the back-end while using the ESB to perform transformations midway. After the back-end has received the message the response will be sent back through JMS queues synchronously to finish the cycle.

Instead of using separate endpoints for these responses we can use the “transport.jms.ReplyDestination” parameter which automatically routes the responses to a designated “Reply” queue.

Inside the ESB we have two possible setups depending on whether the origin and back-end systems are able to or want to write and read from a queue or use the ESB as an API/Webservice.

Setup 1:

Setup 1 Synchronous Invocations

In this setup, the client communicates with either a SOAP Webservice or REST API on the ESB, which then sends the message to a JMS endpoint (Including reply parameter!). Once the message is on the queue it will be taken off by the sending proxy which will handle message transformation and communication with the back-end system. The reply can be transformed by the proxy and then sent back to the reply queue after which the original receiving proxy or API will get the response and sent it back to the client, completing the synchronous flow.

If our entry point is a webservice before sending it to the queue the receiving proxy would look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<proxy name="ReceivingProxy" startOnLoad="true" transports="https http" xmlns="http://ws.apache.org/ns/synapse">
    <target>
     <inSequence>
       <send>
        <endpoint key="gov:/blogproject/endpoint/requestQueueEP.xml"/>
       </send>
     </inSequence
      <outSequence>
       <!--  Sends to the correct place due to the replyDestination parameter -->
            <send/>
        </outSequence>
        <faultSequence>
            <!--  Write your fault sequence here  -->
        </faultSequence>
    </target>
    </target>
</proxy>

To facilitate sending to the queue the requestQueueEP.xml looks like the example below. In this JMS Endpoint there are 3 main parts to look out for:
jms:/<Destination queue name>?transport.jmsConnectionFactory=<Relevant connection factory from axis2.xml>&amp;transport.jms.ReplyDestination=<Response queue name> “transport.jms.ReplyDestination=responseQueue” this decides which queue the response message will be sent to on the way back from the second proxy.

<endpoint name="requestQueueEP" xmlns="http://ws.apache.org/ns/synapse">
<address uri="jms:/requestQueue?transport.jms.ConnectionFactory=myQueueConnectionFactory&amp;transport.jms.ReplyDestination=responseQueue"/>
</endpoint>

On the other side the basic proxy looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<proxy name="SendingProxy" startOnLoad="true" transports="jms" xmlns="http://ws.apache.org/ns/synapse">
    <target>
<inSequence>
  <property action="set" name="transport.jms.ContentTypeProperty"
         value="Content-Type" scope="axis2"/>

       <send>
   <xslt key="gov:/blogproject/transformRequest.xsl"/>
         <endpoint key="gov:/blogproject/endpoint/backEndEP.xml "/>
        </send>
       </inSequence>
       <outSequence>
       <!-- Transform the response to required format -->
        <xslt key="gov:/blogproject/transformResponse.xsl"/>
<!--  Send goes towards the replyQueue due to the replyDestination parameter. -->
        <send/>
       </outSequence>
       <faultSequence>
         <!--  Write your fault sequence here  -->
       </faultSequence>
    </target>
    <parameter name="transport.jms.DestinationType">queue</parameter>

<!--  Queue name to designate where to retrieve messages from  --> 
   <parameter name="transport.jms.Destination">
      requestQueue
    </parameter>

<!--  Make sure the message coming off the queue stays in the wanted format -->
    <parameter name="transport.jms.ContentType">
     <rules>
       <jmsProperty>contentType</jmsProperty>
       <default>text/xml</default>
     </rules>
    </parameter>
    <parameter name="transport.jms.ConnectionFactory">
      myQueueConnectionFactory
    </parameter>
</proxy>

Setup 2:

Setup 2 - Synchronous Invocations

Setup 2 can be used if the origin and back-end system are able to interact with JMS queues themselves instead of relying on the WSO2 ESB to manage these connections.
In the above diagram, you can see that the origin system (client) drops a message on the request queue, it gets processed inside the ESB and put on the Back-End request queue.
The back-end system then takes it off the Request queue and sends it into the Back-end response queue. Meanwhile the ESB is polling this queue for a response and picks it up to process it back to the client through the Response queue defined as ReplyDestination during the original request coming from the client.

This single proxy at its most basic form would look like this:

<?xml version="1.0" encoding="UTF-8"?>
<proxy name="TransformationProxy " transports="jms" xmlns="http://ws.apache.org/ns/synapse">
      <target>
          <inSequence>
<property action="set" name="transport.jms.ContentTypeProperty"  value="Content-Type" scope="axis2"/>
              <send>
                  <endpoint>
                      <address uri="jms:/BackEndRequestQueue? transport.jms.ConnectionFactory=myQueueConnectionFactory&amp;transport.jms.DestinationType=queue&amp;transport.jms.ReplyDestination=BackEndResponseQueue"/>
                  </endpoint>
              </send>
          </inSequence>
          <outSequence>
              <send/>
          </outSequence>
      </target>
      <parameter name="transport.jms.ContentType">
          <rules>
              <jmsProperty>contentType</jmsProperty>
              <default>text/xml</default>
          </rules>
      </parameter>
     <parameter name="transport.jms.Destination">BackEndResponseQueue </parameter>
</proxy>

I recommend everyone to experiment with these setups and see how they can help you solve queueing for your projects. If there are any questions don’t hesitate to contact us!

Full API lifecycle Management Selection Guide

WHITEPAPER

smartmockups l0qqucke