Search code examples
ibm-mqgatlingscala-gatling

JMS-Loadtest using Gatling: unable to initialize ContextFactory of IBM MQ


I'm implementing a load test scenario against a IBM MQ with Gatling. The setup is basically the same as mentioned here

Problem: I'm not able to initialize the required ContextFactory with IBM MQ - which should be com.ibm.mq.jms.context.WMQInitialContextFactory. The WMQInitialContextFactory cannot be found.

But my build.sbt is containing the IBM MQ dependency correctly (being successfully retrieved by our internal Nexus :

"com.ibm.mq" % "com.ibm.mq" % "8.0.0.3"  

My gatling scenario:

package com.myawesomecompany.loadtest

import com.ibm.mq._
import com.ibm.mq.jms.MQConnectionFactory
import com.ibm.mq.jms.JMSMQ_Messages
import com.ibm.msg.client.wmq.common.CommonConstants
import io.gatling.core.Predef._
import io.gatling.core.scenario.Simulation
import io.gatling.jms.Predef._
import javax.jms._

import scala.concurrent.duration._

class JMSLoadTest extends Simulation {

  val jmsConfiguration = jms
    .connectionFactoryName("ConnectionFactory")
    .url("devmq01.company.dmz")
    .credentials("mqm", "mqm")

  .contextFactory(classOf[com.ibm.mq.jms.context.WMQInitialContrextFactory].getName) 
  .listenerCount(1)
  .usePersistentDeliveryMode  

 val scn = scenario("Load testing GPRSForwarder").repeat(1) {
exec(jms("testing GPRSForwarder...").reqreply
  .queue("COMPANY.TEST.QUEUE")
  .textMessage("00001404020611100E033102C20EBB51CC1C036EFFFF00010002323802000200FE05001400000000FFFFFFFFFFFFFFFFFF040010038B0D6912EB10CE070206110F37298C")
  .jmsType("test_jms_type")
    )
  }  

 setUp(scn.inject(rampUsersPerSec(10) to 1000 during (2 minutes)))
    .protocols(jmsConfiguration)


}  

The setup is equivalent to this one - but instead of using ActiveMQInitalContextFactory, I'm forced to use the "counterpart" of IBM MQ.

According to official docks the WMQInitialContextFactory should be in com.ibm.mq.jms.context but it is not. Ore is there some constant in CommonConstants which I can use to initialize a ContextFactory ?

Thanks a lot in advance.


Solution

  • Problem: I'm not able to initialize the required ContextFactory with IBM MQ - which should be com.ibm.mq.jms.context.WMQInitialContextFactory. The WMQInitialContextFactory cannot be found.

    Do not use WMQInitialContextFactory. It was an MQ SupportPac someone created where they wanted to use MQ as the JNDI repository. It is not a good idea plus the SupportPac does not support any form of security (i.e. SSL/TLS or security exit).

    You should use a file based MQ JNDI. Here's a basic example:

    import java.util.Hashtable;
    import javax.jms.JMSException;
    import javax.jms.Queue;
    import javax.jms.QueueConnection;
    import javax.jms.QueueConnectionFactory;
    import javax.jms.QueueSender;
    import javax.jms.QueueSession;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    import com.ibm.mq.MQException;
    
    /**
     * Program Name
     *  TestJMS01
     *
     * Description
     *  This java JMS class will connect to a remote queue manager
     *  using JNDI and put a message to a queue.
     *
     * Sample Command Line Parameters
     *  -x myQCF -q dev.test.q -f C:\JNDI-Directory\roger\mqjndi
     *
     *  Sample MQ JNDI Commands:
     *    DEFINE QCF(myQCF) QMANAGER(MQA1) CHANNEL(TEST.CHL) HOSTNAME(127.0.0.1) PORT(1415) TRANSPORT(CLIENT) FAILIFQUIESCE(YES)
     *    DEFINE Q(dev.test.q) QUEUE(TEST1) QMANAGER(MQA1) TARGCLIENT(JMS) FAILIFQUIESCE(YES)
     *
     * @author Roger Lacroix, Capitalware Inc.
     */
    public class TestJMS01
    {
       private static final String JNDI_CONTEXT = "com.sun.jndi.fscontext.RefFSContextFactory";
    
       private QueueConnectionFactory cf;
       private Queue q;
       private Hashtable<String,String> params = null;
       private String userID = "tester";
       private String password = "mypwd";
    
       public TestJMS01() throws NamingException
       {
          super();
       }
    
       /**
        * Make sure the required parameters are present.
        * @return true/false
        */
       private boolean allParamsPresent()
       {
          return (params.containsKey("-x") && params.containsKey("-q") && params.containsKey("-f"));
       }
    
       /**
        * Extract the command-line parameters and initialize the MQ variables.
        * @param args
        * @throws IllegalArgumentException
        */
       private void init(String[] args) throws IllegalArgumentException
       {
          params = new Hashtable<String,String>(10);
          if (args.length > 0 && (args.length % 2) == 0)
          {
             for (int i = 0; i < args.length; i += 2)
             {
                params.put(args[i], args[i + 1]);
             }
          }
          else
          {
             throw new IllegalArgumentException();
          }
    
          if (allParamsPresent())
          {
             Hashtable<String,Object> env = new Hashtable<String,Object>();
             env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_CONTEXT);
             env.put(Context.PROVIDER_URL, "file:/"+(String) params.get("-f"));
    
             try
             {
                Context ctx = new InitialContext(env);
    
                cf = (QueueConnectionFactory) ctx.lookup((String) params.get("-x"));
                q = (Queue) ctx.lookup((String) params.get("-q"));
             }
             catch (NamingException e)
             {
                System.err.println(e.getLocalizedMessage());
                e.printStackTrace();
                throw new IllegalArgumentException();
             }
          }
          else
          {
             throw new IllegalArgumentException();
          }
       }
    
       /**
        * Test the connection to the queue manager.
        * @throws MQException
        */
       private void testConn() throws JMSException
       {
          QueueConnection connection = null;
          QueueSession session = null;
    
          try
          {
             connection = cf.createQueueConnection(userID, password);
             connection.start();
    
             session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    
             sendMsg(session);
          }
          catch (JMSException e)
          {
             System.err.println("getLinkedException()=" + e.getLinkedException());
             System.err.println(e.getLocalizedMessage());
             e.printStackTrace();
          }
          finally
          {
             try
             {
                session.close();
             }
             catch (Exception ex)
             {
                System.err.println("session.close() : " + ex.getLocalizedMessage());
             }
    
             try
             {
                connection.stop();
             }
             catch (Exception ex)
             {
                System.err.println("connection.stop() : " + ex.getLocalizedMessage());
             }
    
             try
             {
                connection.close();
             }
             catch (Exception ex)
             {
                System.err.println("connection.close() : " + ex.getLocalizedMessage());
             }
          }
       }
    
       /**
        * Send a message to a queue.
        * @throws MQException
        */
       private void sendMsg(QueueSession session) throws JMSException
       {
          QueueSender sender = null;
    
          try
          {
             TextMessage msg = session.createTextMessage();
             msg.setText("Nice simple test. Time in 'ms' is  -> " + System.currentTimeMillis());
             // msg.setJMSReplyTo(tq);
             // msg.setJMSDeliveryMode( DeliveryMode.NON_PERSISTENT);
    
             System.out.println("Sending request to " + q.getQueueName());
             System.out.println();
    
             sender = session.createSender(q);
             sender.send(msg);
          }
          catch (JMSException e)
          {
             System.err.println("getLinkedException()=" + e.getLinkedException());
             System.err.println(e.getLocalizedMessage());
             e.printStackTrace();
          }
          finally
          {
             try
             {
                sender.close();
             }
             catch (Exception ex)
             {
                System.err.println("sender.close() : " + ex.getLocalizedMessage());
             }
          }
       }
    
       /**
        * main line
        * @param args
        */
       public static void main(String[] args)
       {
          try
          {
             TestJMS01 tj = new TestJMS01();
             tj.init(args);
             tj.testConn();
          }
          catch (IllegalArgumentException e)
          {
             System.err.println("Usage: java TestJMS01 -x QueueConnectionFactoryName -q JMS_Queue_Name -f path_to_MQ_JNDI");
             System.exit(1);
          }
          catch (NamingException ex)
          {
             System.err.println(ex.getLocalizedMessage());
             ex.printStackTrace();
          }
          catch (JMSException e)
          {
             System.err.println("getLinkedException()=" + e.getLinkedException());
             System.err.println(e.getLocalizedMessage());
             e.printStackTrace();
          }
          catch (Exception ex)
          {
             System.err.println(ex.getLocalizedMessage());
             ex.printStackTrace();
          }
       }
    }