Closed mehrdad2000 closed 6 months ago
Hi @mehrdad2000
You have to write your own Channel Class that wraps the JMS objects.
It would have to implement ISOChannel to be able to connect, send, receive etc. via JMS queue.
It should implement Configurable so you can pass in required properties via the test plan, for example:
Below is an example of how you would access those properties.
You would also have to convert the ISOMsg
that the ISO8583 Sampler generates into an appropriate JMS message, see below for an example.
public class JMSChannel implements ISOChannel, Configurable {
MQQueueConnectionFactory cf;
// etc., your other JMS objects
public void setConfiguration(Configuration cfg) throws ConfigurationException {
// From common "Channel Settings":
cf.setHostName(cfg.get("host"));
cf.setPort(cfg.getInt("port"));
// From "Advanced Configuration":
cf.setQueueManager(cfg.get("queueManager"));
cf.setChannel(cfg.get("channel"));
// etc., your other config properties
}
public void send(ISOMsg isoMsg) throws IOException, ISOException {
// Assuming your messages are sent as bytes rather than text:
BytesMessage jmsMsg = session.createBytesMessage();
jmsMsg.writeBytes(isoMsg.pack());
sender.send(jmsMsg);
}
// etc., other methods
}
Most other ISOChannels extend BaseChannel for sending messages via all sorts of network/TCP connections, so you may want to have a look at how that is done.
I hope this gives you some ideas and a starting point.
@tilln Thank you for answer, would you please consider this as feature request and add channel for “jms channel”? it would be useful feature for anyone who need send jms message.
Thanks
@mehrdad2000 I'm happy to consider pull requests that add useful features.
@tilln should i do anything?
@mehrdad2000 how about implementing that channel class? Or do you expect me to write your code for you?
Ok, I'm newbie in this case. if you guide me step by step I'll write it and create merge request.
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.
@tilln instead of write class from scratch, is it possible to generate message with iso8583 plugin then pass to "jms publisher" or "java request" and send to mq?
@mehrdad2000 Theoretically, it is possible, and you could re-use some functionality of this plugin, however, you would end up writing quite a bit of code too. The challenge is that the ISO8583 Sampler builds the ISOMsg and expects to send it over the Channel. If you don't want to send but only generate the message, you would have to avoid the Sampler altogether and re-write all the message generation. So I suppose you're better off just creating that Channel class.
@tilln ok i’ll try to write below java code use base-channel as you mentioned, after compile this code it generates class file. What should i do next? Should i put class file in lib/ext directory of jmeter? Or it should be add into the iso8583.jar file to jmeter detect it?
Here is the code:
package org.jpos.iso.channel;
import com.ibm.jms.JMSTextMessage;
import com.ibm.mq.jms.*;
import com.ibm.msg.client.wmq.WMQConstants;
import org.jpos.iso.ISOChannel;
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOMsg;
import org.jpos.iso.BaseChannel;
import org.jpos.core.Configuration;
import org.jpos.core.Configurable;
import org.jpos.core.ConfigurationException;
import javax.jms.*;
public class JMSChannel extends BaseChannel implements ISOChannel, Configurable {
private MQQueueConnectionFactory cf;
private MQQueueConnection connection;
private MQQueueSession session;
private MQQueueSender sender;
public void setConfiguration(Configuration cfg) throws ConfigurationException {
try {
cf = new MQQueueConnectionFactory();
cf.setHostName(cfg.get("host"));
cf.setPort(cfg.getInt("port"));
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setQueueManager(cfg.get("queueManager"));
cf.setChannel(cfg.get("channel"));
cf.setStringProperty(WMQConstants.USERID, cfg.get("user"));
cf.setStringProperty(WMQConstants.PASSWORD, cfg.get("pass"));
connection = (MQQueueConnection) cf.createQueueConnection();
session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
MQQueue queue = (MQQueue) session.createQueue(cfg.get("qname"));
sender = (MQQueueSender) session.createSender(queue);
JMSTextMessage message = (JMSTextMessage) session.createTextMessage("MYMESSAGE");
connection.start();
sender.send(message);
} catch (JMSException e) {
throw new ConfigurationException(e);
}
}
}
@mehrdad2000 You may want to look at the JMeter documentation.
@tilln already read that page, the question is which is better? 1-create single jar file that contain this JMSChannel.class 2-add JMSChannel.class to jpos-2.1.8.jar file that exist in lib directory of Jmeter in this path "org.jpos.iso.channel.JMSChannel.class"
FYI: also try number2 got below error, when i start test:
2024-03-30 13:28:17,387 ERROR n.c.b.j.i.Q2: (org.jpos.q2.iso.ChannelAdaptor) error starting service
2024-03-30 13:28:17,387 ERROR n.c.b.j.i.Q2: (org.jpos.q2.iso.ChannelAdaptor) JMSChannel
org.jpos.core.ConfigurationException: JMSChannel
at org.jpos.q2.QFactory.newInstance(QFactory.java:307) ~[jpos-2.1.8.jar:2.1.8]
at org.jpos.q2.iso.ChannelAdaptor.newChannel(ChannelAdaptor.java:197) ~[jpos-2.1.8.jar:2.1.8]
at org.jpos.q2.iso.ChannelAdaptor.initChannel(ChannelAdaptor.java:253) ~[jpos-2.1.8.jar:2.1.8]
at org.jpos.q2.iso.ChannelAdaptor.startService(ChannelAdaptor.java:76) [jpos-2.1.8.jar:2.1.8]
at org.jpos.q2.QBeanSupport.start(QBeanSupport.java:137) [jpos-2.1.8.jar:2.1.8]
at jdk.internal.reflect.GeneratedMethodAccessor37.invoke(Unknown Source) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) [?:?]
at jdk.internal.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:260) [?:?]
at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:112) [?:?]
at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:46) [?:?]
at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:237) [?:?]
at com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138) [?:?]
at com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:252) [?:?]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:809) [?:?]
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) [?:?]
at org.jpos.q2.QFactory.startQBean(QFactory.java:176) [jpos-2.1.8.jar:2.1.8]
at nz.co.breakpoint.jmeter.iso8583.ISO8583Config.deployAndStart(ISO8583Config.java:364) [jmeter-iso8583-1.4-SNAPSHOT.jar:?]
at nz.co.breakpoint.jmeter.iso8583.ISO8583Config.startChannelAdaptor(ISO8583Config.java:283) [jmeter-iso8583-1.4-SNAPSHOT.jar:?]
at nz.co.breakpoint.jmeter.iso8583.ISO8583Config.testStarted(ISO8583Config.java:467) [jmeter-iso8583-1.4-SNAPSHOT.jar:?]
at org.apache.jmeter.engine.StandardJMeterEngine.notifyTestListenersOfStart(StandardJMeterEngine.java:246) [ApacheJMeter_core.jar:5.6.2]
at org.apache.jmeter.engine.StandardJMeterEngine.run(StandardJMeterEngine.java:424) [ApacheJMeter_core.jar:5.6.2]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
at java.lang.Thread.run(Thread.java:829) [?:?]
Any idea? Thanks
@mehrdad2000
the question is which is better?
I cannot answer that without knowing your quality criteria. Both should work though.
org.jpos.core.ConfigurationException: JMSChannel
Instead of JMSChannel
you have to use the fully qualified class name in you JMeter script, e.g. org.jpos.iso.channel.JMSChannel
.
@tilln try it too
Your source file is missing the package declaration.
@tilln declare package name and return exception error: package org.jpos.iso.channel.JMSChannel1;
FYI: filled host, port, from “Channel Settings”, And queueManager, channel from “Advanced Configuration”
@mehrdad2000
Your package name must not include the class name:
package org.jpos.iso.channel;
@tilln ok, now modified code and pass that exception, now I'll able to send "MYMESSAGE" to destination successfully.
now need to put iso8583 message that generate by sampler instead of "MYMESSAGE".
any idea? Thanks
@tilln instead of this line that you mentioned create new message: BytesMessage jmsMsg = session.createBytesMessage(); need to get iso8583 sampler output to replace with "MYMESSAGE".
I’ll try to enable debug code but can’t find any error or log that let me inspect issue deeply. I try to send bytes, and didn’t return any error and run but mq didn’t receive message, and not show any error:
public void send(ISOMsg isoMsg) throws IOException, ISOException {
try {
// Create a BytesMessage
BytesMessage jmsMsg = session.createBytesMessage();
// Pack the ISO message and write its bytes to the JMS message
jmsMsg.writeBytes(isoMsg.pack());
// Send the JMS message
sender.send(jmsMsg);
} catch (JMSException e) {
throw new ISOException("Error sending JMS message", e);
}
}
Also try to sent as text, instead of BytesMessage, same result:
public void send(ISOMsg isoMsg) throws ISOException {
try {
// Create a TextMessage
TextMessage jmsMsg = session.createTextMessage();
// Set the text content of the JMS message
jmsMsg.setText(new String(isoMsg.pack(), "ISO-8859-1")); // Assuming ISO-8859-1 encoding
// Send the JMS message
sender.send(jmsMsg);
} catch (JMSException | UnsupportedEncodingException e) {
throw new ISOException("Error sending JMS message", e);
}
}
Any Idea? Thanks
I try to send message from jmeter-iso8583 to mq, but it’s not work.
here is the my current JSR223 sampler that work correctly and send “mymessage“ to mq, now question is how can i send output of iso8583 plugin to mq server? Is it possible to add “queue manager, channel, user, pass, queue name,…) in connection manager of jmeter-iso8583?
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("192.168.1.1"); cf.setPort(1443); // or other port cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT); cf.setQueueManager("qm"); cf.setChannel("my.SVRCONN"); cf.setStringProperty(WMQConstants.USERID, "user"); cf.setStringProperty(WMQConstants.PASSWORD, "pass"); connection = (MQQueueConnection) cf.createQueueConnection(); MQQueueSession session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); MQQueue queue = (MQQueue) session.createQueue("queue:///my.queue"); MQQueueSender sender = (MQQueueSender) session.createSender(queue); JMSTextMessage message = (JMSTextMessage) session.createTextMessage("mymessage"); connection.start(); sender.send(message);