3 Replies Latest reply on May 22, 2009 12:36 PM by Tom Fennelly

    Websphere MQ with XA connections

    Tom Fennelly Master

      I'm currently working on trying to establish what needs to be done to make the ESB work more smoothly with Websphere MQ (WMQ), specifically in relation to working with XA based connections.

      There's a known issue with WMQ on the ESB when using XA based JMS sessions/connections. With WMQ, you are only allowed have a 1:1 xasession:xaconnection relationship i.e. you're not allowed create more than one XA session/connection. No such restriction exists for non-XA based connections.

      Our current JmsConnectionPooling code is not able to handle this restriction properly as it assumes the provider supports a 1:n xaconnection:xasession relationship.

      Now to my first problem... before even trying to address a possible solution for the JmsConnectionPool.... I simply can not get my WMQ setup to produce XA based JMS resources (ConnectionFactory, Connection etc). Not if I kissed it up the *** :)

      I have tried a number of options at this stage, using both the JBoss and WMQ JMS adapters. I can get them to create non-XA resources no problem, but I cannot get them to create XA based resource.

      Using the WMQ Adapter
      Here's the config I tried for the WMQ adapter connection factory (note xa-transaction is set on the factory):

      <?xml version="1.0" encoding="UTF-8"?>
      <connection-factories>
      
       <tx-connection-factory>
       <jndi-name>WMQConnectionFactory</jndi-name>
       <xa-transaction></xa-transaction>
       <rar-name>wmq.jmsra.rar</rar-name>
       <connection-definition>javax.jms.ConnectionFactory</connection-definition>
       <config-property name="channel" type="java.lang.String">SYSTEM.DEF.SVRCONN</config-property>
       <config-property name="hostName" type="java.lang.String">localhost</config-property>
       <config-property name="port" type="java.lang.String">1414</config-property>
       <config-property name="queueManager" type="java.lang.String">ConnectionFactory</config-property>
       <config-property name="transportType" type="java.lang.String">BINDING</config-property>
       <security-domain-and-application>JmsXARealm</security-domain-and-application>
       </tx-connection-factory>
      
       <mbean code="org.jboss.resource.deployment.AdminObject" name="jca.wmq:name=WMQGATEWAY">
       <attribute name="JNDIName">WMQGATEWAY</attribute>
       <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='wmq.jmsra.rar'</depends>
       <attribute name="Type">javax.jms.Queue</attribute>
       <attribute name="Properties">
       baseQueueManagerName=ConnectionFactory
       baseQueueName=WMQGATEWAY
       </attribute>
       </mbean>
      
      </connection-factories>
      


      And here's the ESB config I'm using with that WMQ Adapter config:
      <?xml version = "1.0" encoding = "UTF-8"?>
      <jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd"
       parameterReloadSecs="5">
      
       <providers>
      
       <jms-jca-provider name="WMQ-via-JCA" connection-factory="WMQConnectionFactory" adapter="wmq.jmsra.rar">
      
       <jms-bus busid="quickstartGwChannel">
       <jms-message-filter dest-type="QUEUE" dest-name="WMQGATEWAY" transacted="true"/>
       </jms-bus>
      
       <activation-config>
       <property name="queueManager" value="ConnectionFactory"/>
       <property name="transportType" value="BINDINGS"/>
       <property name="useJNDI" value="true"/>
       </activation-config>
      
       </jms-jca-provider>
      
       <jms-provider name="IBMMQ" jndi-URL="localhost:1414/SYSTEM.DEF.SVRCONN"
       jndi-context-factory="com.ibm.mq.jms.context.WMQInitialContextFactory"
       jndi-pkg-prefix=""
       connection-factory="ConnectionFactory">
      
       <jms-bus busid="quickstartEsbChannel1">
       <jms-message-filter dest-type="QUEUE" dest-name="WMQESBAWARE1" transacted="true"/>
       </jms-bus>
      
       </jms-provider>
      
       </providers>
      
       <services>
       <service category="IBMESB" name="IBMListener" description="Consume IBM MQ ibmGwChannel Message">
      
       <listeners>
       <jms-listener name="JMS-Gateway" busidref="quickstartGwChannel" is-gateway="true"/>
       <jms-listener name="JMS-ESBListener" busidref="quickstartEsbChannel1" maxThreads="1"/>
       </listeners>
      
       <actions mep="OneWay">
       <action name="print" class="org.jboss.soa.esb.actions.SystemPrintln">
       <property name="message" value="Message from JMS-ESBListener"/>
       </action>
       </actions>
      
       </service>
      
       </services>
      </jbossesb>
      


      Using the JBoss Adapter

      And here's the config I tried for the JBoss adapter connection factory (again, note xa-transaction is set on the factory):

      <connection-factories>
      
       <mbean code="org.jboss.jms.jndi.JMSProviderLoader" name=":service=JMSProviderLoader,name=WSMQJmsProvider">
       <attribute name="ProviderName">WSMQProvider</attribute>
       <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
       <attribute name="QueueFactoryRef">ConnectionFactory</attribute>
       <attribute name="TopicFactoryRef">ConnectionFactory</attribute>
       <attribute name="FactoryRef">ConnectionFactory</attribute>
       <attribute name="Properties">
       java.naming.factory.initial=com.ibm.mq.jms.context.WMQInitialContextFactory
       java.naming.provider.url=localhost:1414/SYSTEM.DEF.SVRCONN
       </attribute>
       </mbean>
      
       <tx-connection-factory>
       <jndi-name>WSMQJmsXA</jndi-name>
       <xa-transaction/>
       <rar-name>jms-ra.rar</rar-name>
       <connection-definition>org.jboss.resource.adapter.jms.JmsConnectionFactory</connection-definition>
       <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Queue</config-property>
       <config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/WSMQProvider</config-property>
       <max-pool-size>20</max-pool-size>
       <security-domain-and-application>JmsXARealm</security-domain-and-application>
       </tx-connection-factory>
      
      </connection-factories>
      


      And then the ESB config used against this...

      <?xml version = "1.0" encoding = "UTF-8"?>
      <jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd"
       parameterReloadSecs="5">
      
       <providers>
      
       <jms-jca-provider name="WMQ-via-JCA" providerAdapterJNDI="java:/WSMQProvider" connection-factory="ConnectionFactory">
      
       <jms-bus busid="quickstartGwChannel">
       <jms-message-filter dest-type="QUEUE" dest-name="WMQGATEWAY" transacted="true"/>
       </jms-bus>
      
       </jms-jca-provider>
      
       <jms-provider name="IBMMQ" jndi-URL="localhost:1414/SYSTEM.DEF.SVRCONN"
       jndi-context-factory="com.ibm.mq.jms.context.WMQInitialContextFactory"
       jndi-pkg-prefix=""
       connection-factory="ConnectionFactory">
      
       <jms-bus busid="quickstartEsbChannel1">
       <jms-message-filter dest-type="QUEUE" dest-name="WMQESBAWARE1" transacted="true"/>
       </jms-bus>
      
       </jms-provider>
      
       </providers>
      
       <services>
       <service category="IBMESB" name="IBMListener" description="Consume IBM MQ ibmGwChannel Message">
      
       <listeners>
       <jms-listener name="JMS-Gateway" busidref="quickstartGwChannel" is-gateway="true"/>
       <jms-listener name="JMS-ESBListener" busidref="quickstartEsbChannel1" maxThreads="1"/>
       </listeners>
      
       <actions mep="OneWay">
       <action name="print" class="org.jboss.soa.esb.actions.SystemPrintln">
       <property name="message" value="Message from JMS-ESBListener"/>
       </action>
       </actions>
      
       </service>
      
       </services>
      </jbossesb>
      


      I also tried numerous other options, but I think I've given enough here to let people see where I'm at (I hope :)).

      Here are the notes I took re how I installed WMQ and configured my JBoss AS instance.

      So... has anyone any idea where I'm going wrong here and why I'm not getting XA based connections out of the WMQ connection factory???


        • 1. Re: Websphere MQ with XA connections
          Tom Fennelly Master

          Sorry... I was wrong on something there (at least one thing ;) )....

          I am getting an XAResource enlisted into a new transaction (org.jboss.soa.esb.listeners.jca.EndpointProxy:326:branches/JBESB_4_4_GA_CP) when I use the WMQ Adapter config (option #1 above).

          So what's the magic for getting the com.ibm.mq.jms.context.WMQInitialContextFactory class to create an XA Connection Factory (com.ibm.mq.jms.MQXAQueueConnectionFactory I assume) using direct JNDI??

          As you can see from my config above, my non-JCA listener config is:

          <jms-provider name="IBMMQ" jndi-URL="localhost:1414/SYSTEM.DEF.SVRCONN"
           jndi-context-factory="com.ibm.mq.jms.context.WMQInitialContextFactory"
           jndi-pkg-prefix=""
           connection-factory="ConnectionFactory">
          
          
           <jms-bus busid="quickstartEsbChannel1">
           <jms-message-filter dest-type="QUEUE" dest-name="WMQESBAWARE1" transacted="true"/>
           </jms-bus>
          
          </jms-provider>
          


          Any ideas?

          • 2. Re: Websphere MQ with XA connections
            Tom Fennelly Master

            OK... so it sounds like it's not possible to create XA Connections without the Extended Client lib over the WMQ JNDI Provider, but it should be possible use the Filesystem JNDI Provider. Will have a look at that now.

            • 3. Re: Websphere MQ with XA connections
              Tom Fennelly Master

              After getting a copy of the Extended Client Config, I was at last able to reproduce this issue and verify that the mods made to the JmsConnectionPool (http://www.jboss.org/index.html?module=bb&op=viewtopic&t=155230) solved it.