IBM WebSphere MQThere are a couple of options for testing a WebSphere MQ-based system using LoadRunner, but this blog post shows my preferred approach: write some simple Java code to put a message on a queue (and get a message from a queue).

Note that this approach requires that you have a Java-based LoadRunner license such as the Java Tempate vuser or the Java Record-Replay vuser. You are not likely to need many virtual users, even if you want to generate a lot of messages.

If you need to test a message-based system, you might also be interested in reading about testing JMS with LoadRunner.

/*
 * Example WebSphere MQ LoadRunner script (written in Java)
 * 
 * Script Description: 
 *     This script puts a message on a queue, then gets a response message from 
 *     another queue.
 *
 * You will probably need to add the following jar files to your classpath
 *   - com.ibm.mq.jar
 *   - connector.jar
 *   - com.ibm.mq.jmqi.jar
 *   - com.ibm.mq.headers.jar
 *   - com.ibm.mq.commonservices.jar
 */
 
import lrapi.lr;
import com.ibm.mq.*;

public class Actions
{
    // Variables used by more than one method
    String queueMgrName = "TESTQMGR";
    String putQueueName = "TEST.INBOUND.QUEUE";
    String getQueueName = "TEST.REPLY.QUEUE";
    
    MQQueueManager queueMgr = null;
    MQQueue getQueue = null;
    MQQueue putQueue = null;
    MQPutMessageOptions pmo = new MQPutMessageOptions();
    MQGetMessageOptions gmo = new MQGetMessageOptions();
    MQMessage requestMsg = new MQMessage();
    MQMessage responseMsg = new MQMessage();
    String msgBody = null;

    public int init() throws Throwable {
        // Open a connection to the queue manager and the put/get queues
        try {
            // As values set in the MQEnvironment class take effect when the 
            // MQQueueManager constructor is called, you must set the values 
            // in the MQEnvironment class before you construct an MQQueueManager object.
            MQEnvironment.hostname="mqsvr.myloadtest.com";
            MQEnvironment.port=1414;
            MQEnvironment.channel = "WMQTOOL.ADMIN.CLIENT";
            queueMgr = new MQQueueManager(queueMgrName);
            
            // Access the put/get queues. Note the open options used.
            putQueue = queueMgr.accessQueue(putQueueName, MQC.MQOO_BIND_NOT_FIXED | MQC.MQOO_OUTPUT);
            getQueue= queueMgr.accessQueue(getQueueName, MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_OUTPUT);
        } catch(Exception e) {
            lr.error_message("Error connecting to queue manager or accessing queues.");
            lr.exit(lr.EXIT_VUSER, lr.FAIL);
        }
        
        return 0;
    }//end of init
 
    public int action() throws Throwable {
        // This is an XML message that will be put on the queue. Could do some fancy 
        // things with XML classes here if necessary.
        // The message string can contain {parameters} if lr.eval_string() is used.
        msgBody = lr.eval_string("{OrderNum}"); 
    	
        // Clear the message objects on each iteration.
        requestMsg.clearMessage();
        responseMsg.clearMessage();
        
        // Create a message object and put it on the request queue
        lr.start_transaction("test_message");
        try {
            pmo.options = MQC.MQPMO_NEW_MSG_ID; // The queue manager replaces the contents of the MsgId field in MQMD with a new message identifier.
            requestMsg.replyToQueueName = getQueueName; // the response should be put on this queue
            requestMsg.report=MQC.MQRO_PASS_MSG_ID; //If a report or reply is generated as a result of this message, the MsgId of this message is copied to the MsgId of the report or reply message.
            requestMsg.format = MQC.MQFMT_STRING; // Set message format. The application message data can be either an SBCS string (single-byte character set), or a DBCS string (double-byte character set). 
            requestMsg.messageType=MQC.MQMT_REQUEST; // The message is one that requires a reply.
            requestMsg.writeString(msgBody); // message payload
            putQueue.put(requestMsg, pmo);
        } catch(Exception e) {
        	lr.error_message("Error sending message.");
        	lr.exit(lr.EXIT_VUSER, lr.FAIL);
        }
        
        // Get the response message object from the response queue
        try {
            responseMsg.correlationId = requestMsg.messageId; // The Id to be matched against when getting a message from a queue
            gmo.matchOptions=MQC.MQMO_MATCH_CORREL_ID; // The message to be retrieved must have a correlation identifier that matches the value of the CorrelId field in the MsgDesc parameter of the MQGET call.
            gmo.options=MQC.MQGMO_WAIT; // The application waits until a suitable message arrives.
            gmo.waitInterval=60000; // timeout in ms
            getQueue.get(responseMsg, gmo);

            // Check the message content
            byte[] responseMsgData = responseMsg.readStringOfByteLength(responseMsg.getTotalMessageLength()).getBytes();
            String msg = new String(responseMsgData);
            lr.output_message(msg); // for debugging. Disable this for a load test.
            // TODO: add your own message checking here using string functions.
            // I have found that extracting XML fields and comparing them (rather than 
            // comparing the whole message body or substrings) is more resistant to change.
            // If no match is found, then lr.error_message() and lr.exit().
        } catch() {
            lr.error_message("Error receiving message.");
            lr.exit(lr.EXIT_VUSER, lr.FAIL);
        }
        lr.end_transaction("test_message", lr.AUTO);
        
        return 0;
    }//end of action
 
    public int end() throws Throwable {
        // 	Close all the connections
        try {
            putQueue.close();
            getQueue.close();
            queueMgr.close();
        } catch(Exception e) {
            lr.error_message("Exception in closing the connections");
            lr.exit(lr.EXIT_VUSER, lr.FAIL);
        }

        return 0;
    }//end of end
}

Please leave a comment if you find any errors in the code above, as I no longer have access to a WebSphere MQ environment to test this with.

 

Published On: August 7, 2008Tags: ,

21 Comments

  1. Stuart Moncrieff August 8, 2013 at 2:55 pm - Reply

    Note: IBM WebSphere MQ 7.5 is available for download with a 90-day trial/evaluation license. The trial version has all features enabled.

    • Haneesh December 14, 2015 at 7:21 pm - Reply

      Hi Stuart…while using this code in LR 12.5 with jdk 7 i m getting an error “Can’t create script object.Exception was raised when calling abort-cleanup function in extension java_int.dll: System Exceptions: EXCEPTION_ACCESS_VIOLATION” on the line of code “MQPutMessageOptions pmo = new MQPutMessageOptions();”. The script is getting compiled successfuly. i have added the class path in runtime settings. Please help.

      • Haneesh December 14, 2015 at 7:27 pm - Reply

        Also, the first error in output log is “Error: at com.ibm.mq.MQPutMessageOptions” so the “MQPutMessageOptions.class” file inside the “com.ibm.mq.jar” jar file is the root cause i believe. I m using this jar file which has been given by my MQ developer who used this for Jmeter scripting of MQ message.

  2. srinivas September 17, 2013 at 2:21 am - Reply

    Hi Stuart , Thanks , It is an excellent example . There is a small error in the code on line 98 it is catch(), it should be catch(Exception e) , please check , Thank you once again for an excellent post .

    • Hans September 26, 2013 at 6:41 am - Reply

      Hi, Have you used this script on WMQ ? I need to do a load test for which i need to push messages to WMQ with specified bandwidth (300/minute), all the messages should have a unique Order number, could you please help me with that.

      Get message is not required.

  3. Pradip October 26, 2013 at 12:40 am - Reply

    Hi Stuart, very informative post. thanks. One quick question- i want to test MQ where message consumer application at the other end of MQ is not available in environment. Looking for some approach to simulate consumer application. Any suggestion on this? Thanks.

  4. perftest July 9, 2014 at 5:47 am - Reply

    Hi Stuart,

    Are they details need from mq team to run the script?
    hostname
    port
    channel
    queuemanager name

  5. perftest July 9, 2014 at 5:58 am - Reply

    what are the prerequisites to test code? (ex : jre version, mq details)

  6. perftest July 24, 2014 at 3:00 am - Reply

    Stuart , i am able to connect queue manager but not getting response message.

  7. Sarah October 15, 2014 at 6:16 pm - Reply

    I wonder how can we transfer/pass images over an MQ. Can someone help with that?

  8. shagi December 15, 2014 at 10:32 pm - Reply

    Hi Stuart, how can we pass big xml having many parameters by using same code?

    • carlos February 13, 2015 at 10:40 am - Reply

      Shagi, you can create a parameter file, you can use the same code, and concatenate the request with “+” signals

  9. Oleg August 10, 2015 at 7:19 pm - Reply

    Supper, it’s working perfect

  10. Mandar October 2, 2015 at 6:07 am - Reply

    Is there way that we can send Binary message from LR via MQ..instead of text message i need to send binary message

  11. Fasha December 8, 2015 at 12:07 am - Reply

    Yes , we can pass

  12. PrabhuKumar CHN_CTS January 29, 2016 at 12:08 am - Reply

    Stuart,

    Can we pass any username or password for accessing queue manager(if any)?.

    If answer is yes then please tell me how to pass the creentials.

    I tried the below but no luck,
    MQEnvironment.un= “uname”;
    MQEnvironment.pw= “pword123”;

  13. Raju May 16, 2016 at 8:46 pm - Reply

    Hi Stuart, Nice post
    I think code runs like, first it puts a message into MQ Input queue from first try block and reads a message based on the request message id/correlation id from second try block.
    My question is that after we put a message onto the queue then it reads a message from getQueue name until correlation ID matches. So, its waits there till the that message gets processed. Looks like sequential (Send + Read and Send so on). In such case, we wont find any lag in the queue as queue will always be empty at any point of time as its processing only one message at any time.

  14. chandrashekar July 12, 2016 at 8:13 pm - Reply

    Hi Stuart,
    I am using LR version 12.01. For using Java record and replay feature which is the version of JDK I should get installed?

  15. Sriharsha July 14, 2016 at 9:42 pm - Reply

    Can anybody please let me know from where i can above mentioned JAR Files? If you already have those files could you please share with me…

    Thanks a lot in advance….

  16. Tushar August 17, 2016 at 9:14 pm - Reply

    Hi ,I am able to push the message into the queue ,but it failing while receiving giving ” Error While receiving” message.
    Can someone help me

  17. Vin October 10, 2016 at 5:59 pm - Reply

    Hi Stuart, thanks a lot.

    Can you please let us know, where do i get the below as we are new to MQ loadtesting.

    * – com.ibm.mq.jar
    * – connector.jar
    * – com.ibm.mq.jmqi.jar
    * – com.ibm.mq.headers.jar
    * – com.ibm.mq.commonservices.jar

Leave A Comment