5 Replies Latest reply on Oct 22, 2015 10:06 AM by mrswenso

    Issues connecting to remote Websphere MQ

    mrswenso

      Hello,

       

      I am having an issue where I cannot get a connection to a remote Websphere MQ instance to work. I am using the generic JMS connector with a connection factory configured in the source of the blueprint.xml.

       

      Here is a link to my stackoverflow question on it http://stackoverflow.com/q/32594275/5339497. I was hoping maybe someone here would be able to help and provide insight. I cannot find a good tutorial that walks through setting this up. (At least not one that isn't 5 years old)

       

      Feel free to comment here or on Stack Overflow, Thank you very much for the help.

        • 1. Re: Issues connecting to remote Websphere MQ
          mrswenso

          After many different possible solutions I have found what works:

          First - I did not have the correct version of the .jar files. The .jars must be the same version as the MQ you are using. (in my case I should have been using 8.0.0.2)

          Second - The jars must be imported through Maven. The .jars cannot be added to the classpath as Fuse does not know to look here.

          Finally - The bean looked like this:

          <bean id="websphere" class="org.apache.camel.component.jms.JmsComponent"> <property name="connectionFactory"> <bean class="com.ibm.mq.jms.MQConnectionFactory"> <property name="transportType" value="1" /> <property name="hostName" value="IPAddress"/> <property name="port" value="1414"/> <property name="queueManager" value="WQM"/> <property name="channel" value="SYSTEM.ADMIN.SVRCONN"/> </bean> </property> </bean>
          • 2. Re: Issues connecting to remote Websphere MQ
            sbrandt

            Your solution doesn't use connection pooling and cannot be used in XA transactions.

            To give another example how a possible setup can look like: We've defined WMQ connection factories in a separate bundle and export the pools (one for local JMS transactions and one for XA transactions) through OSGi-services.

            This works very well and you can reuse your JMS pools in multiple bundles.

             

            connection factory/pool-bundle:

            <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
              <reference id="jtaRecoverableTransactionManager" interface="org.apache.geronimo.transaction.manager.RecoverableTransactionManager" availability="mandatory" />
            
              <!-- ***************************************************************** -->
            
              <bean id="wmqXACF" class="com.ibm.mq.jms.MQXAConnectionFactory">
                   <property name="hostName" value="WMQ-Hostname" />
                   <property name="port" value="WMQ-Port" />
                   <property name="queueManager" value="WMQ-Queuemanager-Name" />
                   <property name="channel" value="WMQ-Channel-Name" />
                   <property name="transportType" value="1" />
              </bean>
            
              <bean id="wmqLocalTxCF" class="com.ibm.mq.jms.MQConnectionFactory">
                   <property name="hostName" value="WMQ-Hostname" />
                   <property name="port" value="WMQ-Port" />
                   <property name="queueManager" value="WMQ-Queuemanager-Name" />
                   <property name="channel" value="WMQ-Channel-Name" />
                   <property name="transportType" value="1" />
              </bean>
            
              <!-- ***************************************************************** -->
            
              <bean id="wmqXAPooledCF" class="org.apache.activemq.jms.pool.JcaPooledConnectionFactory" init-method="start" destroy-method="stop">
                   <property name="connectionFactory" ref="wmqXACF"/>
                   <property name="transactionManager" ref="jtaRecoverableTransactionManager"/>
                   <property name="maxConnections" value="WMQ-XAConnection-Poolsize"/>
                   <property name="maximumActiveSessionPerConnection" value="WMQ-Sessions-per-XAConnection-Poolsize"/>
                   <!-- note we set a unique name for the XA resource, should contain "MQSeries_XA_RMI" -->
                   <property name="name" value="MQSeries_XA_RMI-SomeUniqueName" />
                   <!-- Idle and expiry timeouts for XA pool should be larger than Aries transaction timeouts (default 10 mins, see ect/org.apache.aries.transaction.cfg:aries.transaction.timeout property)! -->
                   <property name="expiryTimeout" value="WMQ-XAConnection-Expiry-Timeout"/>
                   <property name="idleTimeout" value="WMQ-XAConnection-Idle-Timeout"/>
                    <property name="blockIfSessionPoolIsFull" value="false"/>
              </bean>
            
            
              <bean id="wmqLocalTxPooledCF" class="org.apache.activemq.jms.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
                   <property name="connectionFactory" ref="wmqLocalTxCF"/>
                   <property name="maxConnections" value="WMQ-LocalTxConnection-Poolsize"/>
                   <property name="maximumActiveSessionPerConnection" value="WMQ-Sessions-per-LocalConnection-Poolsize"/>
                   <property name="expiryTimeout" value="WMQ-LocalTxConnection-Expiry-Timeout"/>
                   <property name="idleTimeout" value="WMQ-LocalTxConnection-Idle-Timeout"/>
                    <property name="blockIfSessionPoolIsFull" value="false"/>
              </bean>
            
              <!-- ***************************************************************** -->
            
              <bean id="resourceManager" class="org.apache.activemq.jms.pool.GenericResourceManager" init-method="recoverResource">
                   <property name="connectionFactory" ref="wmqXACF" />
                   <property name="transactionManager" ref="jtaRecoverableTransactionManager" />
                   <property name="resourceName" value="MQSeries_XA_RMI-SomeUniqueName" />
              </bean>
            
              <!-- ***************************************************************** -->
            
                <service ref="wmqXAPooledCF" interface="javax.jms.ConnectionFactory">
                    <service-properties>
                        <entry key="name" value="WMQ_XA_Name"/>
                    </service-properties>
                </service>
              
                <service ref="wmqLocalTxPooledCF" interface="javax.jms.ConnectionFactory">
                    <service-properties>
                        <entry key="name" value="WMQ_LocalTx_Name"/>
                    </service-properties>
                </service>
            
            </blueprint>
            
            
            

             

            bundle containing Camel context, using pooled JMS connection factory (not XA-enabled) with Camel JMS-Component:

            <?xml version="1.0" encoding="UTF-8"?>
            <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
              xmlns:camel="http://camel.apache.org/schema/blueprint"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="
                    http://camel.apache.org/schema/blueprint 
                    http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
            
              <!-- Setup Camel JMS Component for use with local JMS transactions -->
            
              <reference id="wmqLocalTxPooledCF" interface="javax.jms.ConnectionFactory" filter="(name=WMQ_LocalTx_Name)" />
            
              <bean id="localTxJmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
                   <property name="connectionFactory" ref="wmqLocalTxPooledCF" />
              </bean>
            
              <bean id="wmq" class="org.apache.camel.component.jms.JmsComponent">
                   <property name="connectionFactory" ref="wmqLocalTxPooledCF" />
                   <property name="transactionManager" ref="localTxJmsTransactionManager" />
                   <property name="transacted" value="true" />
                  <!-- Must be CACHE_NONE, pooling happens on the connecion factory -->
                   <property name="cacheLevelName" value="CACHE_NONE" />
              </bean>
            
              <!-- ... -->
            
            </blueprint>
            
            
            

             

            bundle containing Camel context, using pooled JMS connection factory (XA-enabled) with Camel JMS-Component:

            <?xml version="1.0" encoding="UTF-8"?>
            <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
              xmlns:camel="http://camel.apache.org/schema/blueprint"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="
                    http://camel.apache.org/schema/blueprint 
                    http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
            
              <!-- Setup Camel JMS Component for use with XA transactions -->
            
              <reference id="platformTxManager" interface="org.springframework.transaction.PlatformTransactionManager" availability="mandatory"/>
            
              <reference id="wmqXAPooledCF" interface="javax.jms.ConnectionFactory" filter="(name=WMQ_XA_Name)" />
            
              <bean id="wmqXA" class="org.apache.camel.component.jms.JmsComponent">
                   <property name="connectionFactory" ref="wmqXAPooledCF" />
                   <property name="transactionManager" ref="platformTxManager" />
                  <!-- Must be false for XA transactions, XA transaction is initiated by JTA -->
                   <property name="transacted" value="false" />
                  <!-- Must be CACHE_NONE, pooling happens on the connecion factory -->
                   <property name="cacheLevelName" value="CACHE_NONE" />
              </bean>
            
              <!-- ... -->
            
            </blueprint>
            
            
            
            • 3. Re: Issues connecting to remote Websphere MQ
              mrswenso

              Any idea on which would be theoretically faster? I understand that the original would not support XA but would that in turn be slightly faster for non-XA?

              • 4. Re: Issues connecting to remote Websphere MQ
                sbrandt

                Using connection pooling will always be faster than no pooling independently of transaction strategy (local-JMS vs. XA).

                 

                Local transactions are generally faster than XA transactions. But the choice of transaction strategy should depend on your requirements. If you need to modify more than one transactional resource in a transaction, say consume a message from JMS-broker/queuemanager #1 and in the same transaction produce a message to another JMS-broker/queuemanager #2, or consume a message from a JMS-broker/queuemanager and write to a database, then you should consider using XA or you might have duplicates in case of a crash, maybe even lost messages depending on your setup. If you can deal with duplicates, you might use local transactions for performance reasons. If you can afford message loss, you might even consider not using transactions at all and/or using non-persistent messages, which is even faster.

                 

                With more than one transactional resource involved, I generally opt for XA and only investigate alternatives if the performance goal can't be achieved. XA-transactions also can be sped up by storing the fuse transaction log on a very fast media (such as battery buffered server RAID-SSDs). XA infrastrucure is somewhat more difficult to setup, e.g. in Oracle-DB the technical user needs more grants. You might want to have Redhat support help you with that, but once it's set up, my experience is that it works very reliably.

                 

                With only one tx resource involved, local JMS-transaction are just fine

                 

                Hope that helps...

                • 5. Re: Issues connecting to remote Websphere MQ
                  mrswenso

                  We are using non-persistent messaging. I will attempt to use connection pooling to increase performance.