IBM websphere scripting with jmeter - jmeter

Need to create an automate script with jmeter for sending xml to queue.
We are using IBM websphere mq to put xml to queues.
We have received hostname,port,queue manager and queue name info from application team along with the xml contents.
Found blogs on Google that we can get it done using jms point to point sampler in jmeter.
Since it's a new concept for me so not sure what are the mandatory details that we have to enter in that sampler.
Inputs for jms resources- who will provide that.
2.JNDI properties-initial context factory value.
Any pre-requisite jar or something that we have to install.
Any help on this will be appreciated.
Thanks
I have added jms p2p sampler and provided connection details under jndi properties .
Not sure what value to be put for initial context factory ,jndi name request queue ,receive queue and under queue connection factory parameters.
Is this the right way of handling IBM websphere mqs using jmeter.Using jmeter 5.1 version for testing.

Any pre-requisite jar or something that we have to install - yes, as per documentation
JMeter includes the JMS API jar, but does not include a JMS client implementation. If you want to run JMS tests, you will need to download the appropriate jars from the JMS provider.
for IBMMQ it would be com.ibm.mq.allclient.jar which needs to be put into JMeter Classpath
With regards to sending the message I believe you should consider using JSR223 Sampler and writing the code to connect to the queue manager and send the message in Groovy, something like:
import com.ibm.msg.client.jms.JmsFactoryFactory
import com.ibm.msg.client.wmq.WMQConstants
import javax.jms.Session
def hostName = "your IBMMQ Host"
def hostPort = 1414
def channelName = "DEV.APP.SVRCONN"
def queueManagerName = "QM1"
def queueName = "DEV.QUEUE.1"
def ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER)
def cf = ff.createConnectionFactory()
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, hostName)
cf.setIntProperty(WMQConstants.WMQ_PORT, hostPort)
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channelName)
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT)
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManagerName)
def conn = cf.createConnection("app", "test")
def sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE)
def destination = sess.createQueue(queueName)
conn.start()
def producer = sess.createProducer(destination)
def rnd = new Random(System.currentTimeMillis())
def payload = String.format("JMeter...IBM MQ...test message no. %09d!", rnd.nextInt(Integer.MAX_VALUE))
def msg = sess.createTextMessage(payload)
producer.send(msg)
producer.close()
More information: IBM MQ testing with JMeter - Learn How

Related

Unable to establish connection using jms jndi

I am very new to JMS & JNDI, and I'm trying to receive message from a queue programatically, but I am not sure how I can connect to the server. I have Websphere console UI where I login to manage all my queues. This console UI is hosted at linux-server:7276. Below is the UI link
https://my-server:9043/ibm/console
I have referred to the sample classes from IBM MQ JmsJndiConsumer:
String contextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
String initialContextUrl = "ldap://my-server:9043"
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
environment.put(Context.PROVIDER_URL, initialContextUrl);
environment.put(Context.SECURITY_PRINCIPAL, userName);
environment.put(Context.SECURITY_CREDENTIALS, password);
InitialContext context = new InitialContext(environment);
It always throws an error in the context Connection or outbound has closed.
The queue I am trying to connect to has these details:
Connection factories : jms/atConnectionFactory
queue-manager : appit-node.Sit-TBus
Bus name : TBus
queue name : jms/appitone-event
Bootstrap Member : linux-server:7276
You're using my-server:9043 for both your HTTPS and LDAP server. Both of these can't be using the same port on the same machine so one of them must be wrong which is almost certainly why it's failing.

How can JMS Point-to-Point Sampler be used in Jmeter to send messages to an IBM MQ queue

I have a local IBM MQ instance set up with some default queues.
Using JMeter 5.4.1, I first want to send messages to one of these queues to test that the connection works.
1. Is it possible with IBM MQ or does it only work with Active MQ?
The test scenario I wish to achieve is this:
JMeter sends some message with ID1 to a queue named "DEV.QUEUE.1"
The System under test takes the message from "DEV.QUEUE.1", does some processing and places the response on "DEV.QUEUE.2"
JMeter checks and asserts that a response has been received for the message with ID1 on the queue named "DEV.QUEUE.2" within X seconds
View results in Aggregate Report
2. Is this achievable with JMS Point-to-Point Sampler?
I've checked the official JMeter documentation, but I don't understand what connection details I need to place in each of the sampler's configuration fields.
JMS Resources
QueueConnection Factory:
JNDI name Request queue:
JNDI name Receive queue:
Number of samples to aggregate
JMS Selector
....
etc...
I was able to connect to one queue and send messages using custom code in a JSR223 Sampler.
These are the connection details I have used to create the connection:
def hostName = "127.0.0.1"
def hostPort = 1414
def channelName = "DEV.APP.SVRCONN"
def queueManagerName = "QM1"
def queueName = "DEV.QUEUE.1"
def ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER)
def cf = ff.createConnectionFactory()
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, hostName)
cf.setIntProperty(WMQConstants.WMQ_PORT, hostPort)
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channelName)
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT)
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManagerName)
def connInboundQueue = cf.createConnection("mquser", "secretpassword")
def sessInboundQueue = connInboundQueue.createSession(false, Session.AUTO_ACKNOWLEDGE)
def destinationInboundQueue = sessInboundQueue.createQueue(queueName)
connInboundQueue.start()
I'm guessing that I can map these connection credentials to this JMS Point-to-Point Sampler so that I can achieve the same connection, I just don't know how.
So to sum up:
1a. How can I achieve connection to my two queues using the JMS Point-to-Point Sampler?
2a. How can the JMS Point-to-Point Sampler be configured for the scenario I have described above?
I would appreciate any help.
I don't think it's currently possible, the options are in:
Use mqmeter - MQ JMeter Extension, it will provide a custom Java Request sampler
Continue with JSR223 Test Elements, example producer and consumer code snippets can be found in IBM MQ testing with JMeter - Learn How article

How to connect to IBM MQ from JMS publisher without JNDI properties?

I have been trying to connect to IBM MQ from JMeter JMS publisher. Unable to find corrert "Initial context factory" and "connection factory" values to use without JNDI properties. I have all MQ jars present in LIB folder.
I have the following information-host name - Venus, Port - 21717, Destination Queue name - request.queue,Queue manager - venus.QMGR,channel - venus.server.chl
(no authorization required).
My requirement - To connect to IBM MQ using JMS publisher with above details. But I am not able to sort out on what to give for Provider URL, Initial context factory and connection factory. Can you please help as this has been bugging me for past two weeks and couldn't find a solution yet?
It would be great if you can tell me on where to populate the above values in JMS publisher as well for connecting to IBM MQ.
I have tried with user.classpath=/folder/with/mq/jars as well but it is not working and all jars are in place with JMeter restart still no luck.
Note: I have gone through all sites in these two weeks but couldn't get any luck.
Example configuration steps would be something like:
Add javax.jms-api.-x.x.x jar to JMeter Classpath
Add mq-allclient-x.x.x.x.jar to JMeter Classpath
Add JSR223 Sampler to your Test Plan
Put the following code into "Script" area:
import com.ibm.jms.JMSTextMessage;
import com.ibm.mq.jms.*;
import com.ibm.msg.client.wmq.WMQConstants;
import javax.jms.JMSException;
import javax.jms.Session;
MQQueueConnectionFactory cf = new MQQueueConnectionFactory();
cf.setHostName("your_IBMMQ_host");
cf.setPort(1414); // or other port
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setQueueManager("your_IBMMQ_queue_manager");
cf.setChannel("your_IBMMQ_channel");
cf.setStringProperty(WMQConstants.USERID, "your_IBMMQ_username");
cf.setStringProperty(WMQConstants.PASSWORD, "your_IBMMQ_password");
connection = (MQQueueConnection) cf.createQueueConnection();
MQQueueSession session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
MQQueue queue = (MQQueue) session.createQueue("queue:///your_IBMMQ_queue");
MQQueueSender sender = (MQQueueSender) session.createSender(queue);
JMSTextMessage message = (JMSTextMessage) session.createTextMessage("your_message_body");
connection.start();
sender.send(message);
More information:
What is installed for IBM MQ classes for Java
Apache Groovy - Why and How You Should Use It
Simplest sample applications using WebSphere MQ JMS
Depending on your exact requirements, you may be interested by JMSToolBox and its possibility to define scriptsthat will read the payload from csv files stored in a directiory, then create and post them in a MQ Q
as a JMS Message from a message template

Spring JMS + IBM MQ: How to set message buffer size or wait timeout?

I'm unable to process large messages from IBM MQ and get the below error:
JMSCMQ0001: WebSphere MQ call failed with compcode '1' ('MQCC_WARNING') reason '2080' ('MQRC_TRUNCATED_MSG_FAILED')
I'm using the DefaultListenerContainer and not consuming via a MessageConsumer using IBM MQ Java API classes directly. I believe by using IBM MQ JMS API you can specific options before retrieving the message from the queue. But how do I do that with DefaultListenerContainer, is there a system property I can set for these?
If using IBM MQ JMS API(I'm not consuming message like this, pasted just for reference):
MQGetMessageOptions mqGetMessageOptions = new MQGetMessageOptions();
mqGetMessageOptions.waitInterval = ipreoProperties.getMqReceiveWaitTime();
mqGetMessageOptions.options = MQC.MQGMO_WAIT | MQC.MQPMO_SYNCPOINT | MQC.MQGMO_ACCEPT_TRUNCATED_MSG;
Below is my Java Config for the IBM MQ Connection:
#Bean
public CachingConnectionFactory ipreoMQCachingConnectionFactory() {
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
//Not defining MQQueueConnectionFactory as separate bean as Spring boot's auto-configuration finds two instances
//of ConnectionFactory and throws ambiguous implementation exception
//One implementation is CachingConnectionFactory and other one would be MQQueueConnectionFactory if defined separately
MQQueueConnectionFactory mqConnectionFactory = new MQQueueConnectionFactory();
try {
mqConnectionFactory.setHostName(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_HOSTNAME));
mqConnectionFactory.setQueueManager(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_QUEUE_MGR));
mqConnectionFactory.setPort(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_PORT, Integer.class));
mqConnectionFactory.setChannel(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_CHANNEL));
//mqConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
//Setting connection mode as Client so it doesn't complain for native IBM MQ libraries
mqConnectionFactory.setIntProperty(CommonConstants.WMQ_CONNECTION_MODE, CommonConstants.WMQ_CM_CLIENT);
} catch (JMSException exception) {
exception.printStackTrace();
}
cachingConnectionFactory.setTargetConnectionFactory(mqConnectionFactory);
//Setting session caching size as 10, don't think we need more
cachingConnectionFactory.setSessionCacheSize(10);
cachingConnectionFactory.setReconnectOnException(true);
return cachingConnectionFactory;
}
public DefaultMessageListenerContainer ipreoDealActivityListenerContainer() {
DefaultMessageListenerContainer factory = new DefaultMessageListenerContainer();
factory.setConnectionFactory(ipreoMQCachingConnectionFactory());
factory.setDestinationName(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_DEAL_QUEUE_NAME));
factory.setMessageListener(ipreoDealActivityListener());
factory.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
return factory;
}
#Bean
public MessageListener ipreoDealActivityListener() {
return new IpreoDealActivityListener();
}
Appreciate your help, thanks.
Adding a late response as it might be useful to someone.
In my case, when the java client had this exception, we noticed the actual message size was larger than the default 4 MB buffer size.
The Java API does not provide a hook to change buffer size. Hence, the buffer size has to be updated at the MQ server level.
First, we increased the message size in queue properties - It did not work.
Then, we increased the message size property at the MQ channel level as well, which finally resolved the issue.
To summarise, increase the buffer size at the MQ server for queue & the channel both.
On a client connection to a queue manager you can limit the size of messages on both the server and client side. I've seen this error before when the client side limit was smaller then the size of the message.
I don't know how you can set the message size limit directly in the JMS client, but you could use a Client Channel Definition Table. It's a file containing the details for connecting to queue managers, created on a queue manager and then copied to the client host. You need to reference the file by issuing setCCDTURL on the connection factory (setting the host, port and channel is not required when using a CCDT, the CCDT will specify those).
When the CCDT is created on the queue manager the appropriate message size limit needs to be set on the client channel.
The server side limit is set on the server connection channel.
Within the JMS client code handling of the receive buffer us handled automatically; the theory is that specific error should never be received by a JMS Application.
The first snippet of code is the Java Classes API and this could get that error.
How big actually are these messages? What level of the JMS client code are you using - make sure that it is the latest version. And certainly one of the 7.5 or 8 releases.
This answer also has some more information on this.

Send message to MQ using Jmeter

I want to send message to a remote IBM MQ using Jmeter for performance testing. I went through this link. But it requires the JNDI specific details like, QueueConnection Factory, JNDI Name Request queue, Initial Context Factory & Provider URL. Whereas the queu details i have are Qmanager, Qname, hostname, channel, port as given in the code shared in this link. Do these properties have any relation? Can i configure the Jmeter JMS test using the queue details i have?
Thanks in advance.
The first link you gave has a description using Java JMS/MQ and the second shows Java MQ (non-JMS).
JMS is just an abstraction layer. In simple terms, JMS is like giving everything a nick-name. A QCF (QueueConnectionFactory) is simply an object that has all of the information to connect to a queue manager.
i.e.
DEFINE QCF(myQCF) QMANAGER(MQWT1) CHANNEL(TEST.CHL) HOSTNAME(127.0.0.1) PORT(1415) TRANSPORT(CLIENT) FAILIFQUIESCE(YES)
A JMS queue is just a nick-name to an MQ queue.
DEFINE Q(test.q) QUEUE(TEST.Q1) QMANAGER(MQWT1) TARGCLIENT(JMS) FAILIFQUIESCE(YES)
Therefore, in your JMS code you simply reference your QCF (i.e. myQCF) and the JMS queue (i.e. test.q) and you are good to go.
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, ""file:/C:/JNDI-Directory");
try
{
Context ctx = new InitialContext(env);
QueueConnectionFactory cf = (QueueConnectionFactory) ctx.lookup("myQCF");
Queue q = (Queue) ctx.lookup("test.q");
}
catch (NamingException e)
{
System.err.println(e.getLocalizedMessage());
e.printStackTrace();
}
It can be done via the beanshell as well. You can directly access the queue manager via the api, or via exposing the queue via a jms binding. The first is more simple and does not require the MQ client installation.

Resources