Connecting an IBM MQ to WSO2 ESB

In this article I will be discussing on how to configure WSO2 ESB 4.8.1 to both read and write from/to JMS queues on IBM WebSphere MQ. Following is the scenario.



Prerequisites:

You need to have IBM MQ installed in you machine (or to access remotely). Reference [1] contains detailed information on how to install and setup IBM MQ.

Once IBM MQ is installed, create two queues: InputQueue and OutputQueue.

Configuring WSO2 ESB

Copy jta.jar and jms.jar to repository/components/lib directory, and com.ibm.mq_2.0.0.jar and fscontext_1.0.0.jar to repository/components/dropins directory. (.jars can be found in the article [1] )

Next, We need to enable JMS transport details in the ESB side. For that, add the following to <ESB_HOME>/repository/conf/axis2/axis2.xml file.

<transportReceiver class="org.apache.axis2.transport.jms.JMSListener" name="jms">
    <parameter locked="false" name="default">
        <parameter locked="false" name="java.naming.factory.initial">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
        <parameter locked="false" name="java.naming.provider.url">file:///home/supun/Supun/JNDIDirectory</parameter>
        <parameter locked="false" name="transport.jms.ConnectionFactoryJNDIName">MyQueueConnFactory</parameter>
        <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
        <parameter locked="false" name="transport.jms.UserName">Supun</parameter>
        <parameter locked="false" name="transport.jms.Password">supun</parameter>
    </parameter>
    <parameter locked="false" name="myQueueConnectionFactory1">
        <parameter locked="false" name="java.naming.factory.initial">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
        <parameter locked="false" name="java.naming.provider.url">file:///home/supun/Supun/JNDIDirectory</parameter>
        <parameter locked="false" name="transport.jms.ConnectionFactoryJNDIName">MyQueueConnFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
        <parameter locked="false" name="transport.jms.UserName">Supun</parameter>
        <parameter locked="false" name="transport.jms.Password">supun</parameter>
    </parameter>
</transportReceiver>

Here, java.naming.provider.url is the location where IBM MQ's binding file is located. "transport.jms.UserName" and "transport.jms.Password" refers to the username and the password of the login account of the machine in which IBM MQ is installed. Similarly, add the following jms sender details too, to the same axis2.xml file.

<transportSender class="org.apache.axis2.transport.jms.JMSSender" name="jms">
    <parameter locked="false" name="default">
        <parameter locked="false" name="java.naming.factory.initial">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
        <parameter locked="false" name="java.naming.provider.url">file:///home/supun/Supun/JNDIDirectory</parameter>
        <parameter locked="false" name="transport.jms.ConnectionFactoryJNDIName">MyQueueConnFactory</parameter>
        <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
        <parameter locked="false" name="transport.jms.UserName">Supun</parameter>
        <parameter locked="false" name="transport.jms.Password">supun</parameter>
    </parameter>
    <parameter locked="false" name="ConnectionFactory1">
        <parameter locked="false" name="java.naming.factory.initial">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
        <parameter locked="false" name="java.naming.provider.url">file:///home/supun/Supun/JNDIDirectory</parameter>
        <parameter locked="false" name="transport.jms.ConnectionFactoryJNDIName">MyQueueConnFactory</parameter>
        <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
        <parameter locked="false" name="transport.jms.UserName">Supun</parameter>
        <parameter locked="false" name="transport.jms.Password">supun</parameter>
    </parameter>
</transportSender>


Deploying Proxy to Read/Write from/to JMS Queue

Save the above configurations and start the ESB server. Create a new custom proxy as follows.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="JMSProducerProxy" transports="jms" startOnLoad="true" trace="disable">
   <description/>
   <target>
      <inSequence>
         <property name="OUT_ONLY" value="true"/>
         <property name="startTime" expression="get-property('SYSTEM_TIME')" scope="default" type="STRING"/>
         <property name="messagId" expression="//senderInfo/common:messageId" scope="axis2" type="STRING"/>
         <property name="messageType" value="application/sampleFormatReceive" scope="axis2"/>
         <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
         <property name="JMS_IBM_PutApplType" value="2" scope="transport" type="INTEGER"/>
         <property name="JMS_IBM_Encoding" value="785" scope="transport" type="INTEGER"/>
         <property name="JMS_IBM_Character_Set" value="37" scope="transport" type="INTEGER"/>
         <property name="JMS_IBM_MsgType" value="8" scope="transport" type="INTEGER"/>
         <property name="Accept-Encoding" scope="transport" action="remove"/>
         <property name="Content-Length" scope="transport" action="remove"/>
         <property name="User-Agent" scope="transport" action="remove"/>
         <property name="JMS_REDELIVERED" scope="transport" action="remove"/>
         <property name="JMS_DESTINATION" scope="transport" action="remove"/>
         <property name="JMS_TYPE" scope="transport" action="remove"/>
         <property name="JMS_REPLY_TO" scope="transport" action="remove"/>
         <property name="Content-Type" scope="transport" action="remove"/>
         <send>
            <endpoint>
               <address uri="jms:/OutputQueue?transport.jms.ConnectionFactoryJNDIName=MyQueueConnFactory&amp;java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory&amp;java.naming.provider.url=file:///home/supun/Supun/JNDIDirectory&amp;transport.jms.DestinationType=queue&amp;transport.jms.ConnectionFactoryType=queue&amp;transport.jms.Destination=OutputQueue"/>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </target>
   <parameter name="transport.jms.Destination">InputQueue</parameter>
</proxy>

This proxy service will read messages from "InputQueue", and will write them out to the "OutputQueue". As you can see, here I have set some custom properties and removed some other properties from the JMS message. This is done as IBM MQ expect only certain properties, and if those are not available or if there are unexpected properties, it will throw an error.

If you need to change the priority of a message using the proxy, add the following property to the insequence.
      <property name="JMS_PRIORITY" value="2" scope="axis2"/>
Here "value" is the priority you want to set to the message.

References:

[1] http://nandikajayawardana.blogspot.com/2015/03/configuring-ibm-mq-with-wso2-esb.html

Share:

1 comments