Wednesday, January 22, 2014

HowTo: One ESB - Two isolated ActiveMQ instances


There is sometimes a need to point WSO2 ESB to two separate ActiveMQ instances which are independent from each other. So, there will be different queues in these ActiveMQ instances. And, in the proxy configuration we can specify which ActiveMQ instance to use. Following samples explain how to do this. While this blog post focus on ActiveMQ, you follow quite the same steps for other message brokers like WSO2 MB, IBM MQ etc.


jms transportReceiver section of axis2.xml would look like below.

<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
  <parameter name="myTopicConnectionFactory" locked="false">
    <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
    <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
    <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">TopicConnectionFactory</parameter>
    <parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>
  </parameter>
  
  <parameter name="myQueueConnectionFactory" locked="false">
    <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
    <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
    <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
    <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
   </parameter>
  
   <parameter name="default" locked="false">
     <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
     <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
     <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
     <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
   </parameter>
   </transportReceiver>

  • Note the parameter names that's been set - for queues, there is configurations under 'myQueueConnectionFactory' and under 'default'
  • Now, let's go ahead and add the configurations for the other ActiveMQ instance. For that, add another <parameter> under the jms <transportReceiver> and set the java.naming.provider.url to point to the new ActiveMQ instance. Also note the parameter name you have set. Now, the <transportReceiver> section of axis2.xml would look like the following.
 <transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
       <parameter name="myTopicConnectionFactory" locked="false">
            <parameter name="java.naming.factory.initial"  locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
           <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
            <parameter name="transport.jms.ConnectionFactoryJNDIName"  locked="false">TopicConnectionFactory</parameter>
            <parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>
       </parameter>
  
       <parameter name="myQueueConnectionFactory" locked="false">
            <parameter name="java.naming.factory.initial"  locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
           <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
            <parameter name="transport.jms.ConnectionFactoryJNDIName"  locked="false">QueueConnectionFactory</parameter>
            <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
       </parameter>


       <parameter name="secondQueueConnectionFactory" locked="false">
            <parameter name="java.naming.factory.initial"  locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
           <parameter name="java.naming.provider.url" locked="false">tcp://mq2.example.com:61616</parameter>
            <parameter name="transport.jms.ConnectionFactoryJNDIName"  locked="false">QueueConnectionFactory</parameter>
            <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
       </parameter>
  
       <parameter name="default" locked="false">
            <parameter name="java.naming.factory.initial"  locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
           <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
            <parameter name="transport.jms.ConnectionFactoryJNDIName"  locked="false">QueueConnectionFactory</parameter>
            <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
       </parameter>
   </transportReceiver>

 Now, the ESB configuration is complete. What's left is to instruct a JMS proxy service to which jms connection factory to use. We use the service level parameter, transport.jms.ConnectionFactory, to specify the connection factory name. If you did not specify any name, ESB will use the connection factory configuration under 'default'.

A sample proxy service that uses the newly defined activemq instance would look like the following. Note the value set for the transport.jms.ConnectionFactory.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="remoteJMSProxy" transports="jms" startOnLoad="true" trace="disable">
  <target>
    <inSequence>
      <property name="OUT_ONLY" value="true" scope="default"/>
        <send>
          <endpoint>
            <address uri="http://localhost:9763/services/echo" format="soap11"/>
          </endpoint>
        </send>
    </inSequence>
    <outSequence/>
  </target>

  <parameter name="transport.jms.ContentType">
    <rules>
      <jmsProperty>contentType</jmsProperty>
        <default>text/xml</default>
    </rules>
  </parameter>

  <parameter name="transport.jms.ConnectionFactory">remoteQueueConnectionFactory</parameter>

</proxy>