Connect to WebSphere MQ through JMS API (JMS Adapter) - Forum - OpenEdge Development - Progress Community

Connect to WebSphere MQ through JMS API (JMS Adapter)

 Forum

Connect to WebSphere MQ through JMS API (JMS Adapter)

This question is answered

Hello, everybody! 

I'm trying to open, get, put, close WebSphere MQ queuе through JMS API. 

I want to connect to the queue manager, open a specific queue, put in her message, get the message and then close and disconnect. Earlier I connected to the MQ through MQ API

With the help of colleagues from this forum, I was able to write a program with the help of which I got the opportunity to put messages in the queue and pick them up. This program is very cumbersome. I made it in the OpenEdge 10.1B, using installed the WebSphere MQ client 7.5 and downloaded the manual "MQSeries Application Programming Interface". It was a test and this solution is not used in our product.

Now I'm using version 11.6.3. Having learned that since version 11.5.1 I can interact with WebSphere MQ without using the SonicMQ (I do not have licenses for this product), I became interested and decided to figure it out.

My task of interacting with WebSphere MQ queues is complicated by the fact that I have to access the queue from the server (not from the client, as in the program I wrote earlier). For these purposes, I plan to use purchased and installed on the database server PAS for OE. In any case, this is how I call the web services: the program on the client calls the application server on which the service call programs run.

So, I started to study the documentation "Messaging and ESB". I made the necessary changes in jmsProvider.properties and AdminServerPlugins.properties in In the %DLC%\properties path:

[PluginPolicy.Progress.SonicMQ]
    pluginclasspath=C:\Program Files\Progress\OpenEdge_11_6/sonic/MQ8.5/lib/sonic_Client.jar,C:\Program Files\Progress\OpenEdge_11_6/sonic/MQ8.5/lib/mgmt_client.jar,C:\Program Files\Progress\OpenEdge_11_6/java/progress.jar,C:\PROGRA~1\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
    classpath=C:\Program Files\Progress\OpenEdge_11_6/sonic/MQ8.5/lib/sonic_Client.jar,C:\Program Files\Progress\OpenEdge_11_6/java/progress.jar,C:\PROGRA~1\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
    jvmargs=-DsonicMQExtensions=false -DjmsProvider=WebSphereMQ

After that, I began to doubt: there is a WebSphere client on my workstation. But our users work with software using the Client Networking, hosted on a network resource. Probably I should install the WebSphere client on the network? After all, I must somehow run the SonicMQ adapter? On the server in Progress OpenEdge Management I chose the SonicMQ Adapter Resource. But nothing can be created here. Here I am stuck. Do I need to configure something on the server or just make changes to the properties files? Maybe I missed something (did not install it) during the installation of OpenEdge RDBMS?

Can anyone help me? Thanks.

Andrew.

Verified Answer
  • pcode.zip
    Hi Fuelfire,
     
    Following are the two ways to connect IBM WebSphere MQ.
    • Local Queue Manager
    • Remote Queue Manager (using JNDI approach)
     
    Procedure to setup Local Queue Manager:
     
    Step 1: Need to update the WebSphereMQ connection factory class names in $DLC/properties/jmsProvider.propeties as shown below:
     
    [WebsphereMQ]
    javax.jms.ConnectionFactory=com.ibm.mq.jms.MQConnectionFactory
    javax.jms.QueueConnectionFactory=com.ibm.mq.jms.MQQueueConnectionFactory
    javax.jms.TopicConnectionFactory=com.ibm.mq.jms.MQTopicConnectionFactory
     
    Step 2: Update $DLC/properties/AdminServerPlugins.propertes file with WebSphereMQ libraries under [PluginPolicy.Progress.SonicMQ] section as shown below.
     
    [PluginPolicy.Progress.SonicMQ]
    pluginclasspath=C:\Progress115\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
    classpath=C:\Progress115\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
    jvmargs=-DsonicMQExtensions=false -DjmsProvider=WebSphereMQ
     
    Step 3: We need to start SonicMQ adapter with following command from proenv section.
                   proenv>adaptman -i sonicMQ1 -start
    Step 4: Provide the quque manager name as a value in Broker-URL in pcode and run it.
     
    Procedure to setup Remote Queue Manager:
     
    We need to follow below one extra step to connect WebSphere MQ remotely.
     
    Develop AdminObjectFinder.java by specifying PROVIDER_URL and generate jar out of it and place it in pluginclasspath and classpath under [PluginPolicy.Progress.SonicMQ].
     
    Please find the attached sample pcode.
     
    Thanks,
    Anand.
     
All Replies
  • There are such lines in admserv.log:

    [2017/03/17@13:17:48.680+0300] [2] [AdminServer]           Installing plugin: Plugin.SonicMQAdapter (7432)
    [2017/03/17@13:17:48.681+0300] [0] [AdminServer]         * Licence check status: Plugin not licensed. (ADMMsg037) (7438)
    [2017/03/17@13:17:48.681+0300] [0] [AdminServer]         * Plugin.SonicMQAdapter not installed: Plugin not licensed. (ADMMsg037) (7439)
    [2017/03/17@13:17:48.681+0300] [0] [AdminServer]         * Failed to install plugin Plugin.SonicMQAdapter. (7433)

    Can I use JMS API to communicate with WebSphere MQ in this configuration? Thanks.

  • pcode.zip
    Hi Fuelfire,
     
    Following are the two ways to connect IBM WebSphere MQ.
    • Local Queue Manager
    • Remote Queue Manager (using JNDI approach)
     
    Procedure to setup Local Queue Manager:
     
    Step 1: Need to update the WebSphereMQ connection factory class names in $DLC/properties/jmsProvider.propeties as shown below:
     
    [WebsphereMQ]
    javax.jms.ConnectionFactory=com.ibm.mq.jms.MQConnectionFactory
    javax.jms.QueueConnectionFactory=com.ibm.mq.jms.MQQueueConnectionFactory
    javax.jms.TopicConnectionFactory=com.ibm.mq.jms.MQTopicConnectionFactory
     
    Step 2: Update $DLC/properties/AdminServerPlugins.propertes file with WebSphereMQ libraries under [PluginPolicy.Progress.SonicMQ] section as shown below.
     
    [PluginPolicy.Progress.SonicMQ]
    pluginclasspath=C:\Progress115\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
    classpath=C:\Progress115\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar
    jvmargs=-DsonicMQExtensions=false -DjmsProvider=WebSphereMQ
     
    Step 3: We need to start SonicMQ adapter with following command from proenv section.
                   proenv>adaptman -i sonicMQ1 -start
    Step 4: Provide the quque manager name as a value in Broker-URL in pcode and run it.
     
    Procedure to setup Remote Queue Manager:
     
    We need to follow below one extra step to connect WebSphere MQ remotely.
     
    Develop AdminObjectFinder.java by specifying PROVIDER_URL and generate jar out of it and place it in pluginclasspath and classpath under [PluginPolicy.Progress.SonicMQ].
     
    Please find the attached sample pcode.
     
    Thanks,
    Anand.
     
  • Anand, great thanks! Now I have time to continue. I must communicate with remote WebSphereMQ server. And I must develop AdminObjectFinder class. I'm not very good in Java. As I understand, this file allows me to configure the connection settings to the WebSphereMQ server.

    Do I understand correctly that  I don't need to install  SonicMQ adapter on the server for working with WebSphere MQ? You write that I must start SonicMQ adapter and specify sonicMQ1 in command. But in my OEM I don't see any sonicMQ adapters. Moreover, I did not install Sonic ESB adapter on the database server. Is it necessary?

    I'm looking at an example file in the documentation:

    package jmsfromABL;
    import javax.jms.ConnectionFactory;
    import javax.jms.Destination;
    import javax.jms.TopicConnectionFactory;
    import javax.jms.QueueConnectionFactory;
    import javax.jms.Topic;
    import javax.jms.Queue;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NameNotFoundException;
    import javax.naming.NamingException;
    import java.util.Hashtable;
    public class AdminObjectFinder{
    public Context context = null;
    
    public AdminObjectFinder() throws Exception{
    Hashtable<String, String> env = new Hashtable<>();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
    "com.sun.jndi.fscontext.RefFSContextFactory");
    env.put(Context.PROVIDER_URL, "file:/C:/JNDI");
    env.put(Context.SECURITY_PRINCIPAL, "username");
    env.put(Context.SECURITY_CREDENTIALS, "password");
    context = new InitialContext(env);
    }
    public TopicConnectionFactory getTopicConnectionFactory(String name)
    throws Exception {
    TopicConnectionFactory factory = null;
    factory = (javax.jms.TopicConnectionFactory)context.lookup(name);
    return factory;
    }
    public QueueConnectionFactory getQueueConnectionFactory(String name)
    throws Exception {
    QueueConnectionFactory factory = null;
    factory = (javax.jms.QueueConnectionFactory)context.lookup(name);
    return factory;
    }
    public ConnectionFactory getConnectionFactory(String name)
    throws NamingException {
    return (ConnectionFactory) context.lookup(name);
    }
    public Topic getTopic(String name) throws Exception {
    Topic topic = null;
    Object object = null;
    object = context.lookup(name);
    if (object != null) {
    topic = (javax.jms.Topic) object;
    }
    return topic;
    }
    public Queue getQueue(String name) throws Exception {
    Queue queue = null;
    Object object = null;
    object = context.lookup(name);
    if (object != null) {
    queue = (javax.jms.Queue) object;
    }
    return queue;
    }
    public Destination getDestination(String name)
    throws NamingException {
    return (Destination) context.lookup(name);
    }
    }

    As I understand I must specify in this text URL of MQ Server (PROVIDER_URL), login (SECURITY_PRINCIPAL) and password (SECURITY_CREDENTIALS). Then I must create class with javac and after that pack it in jar. Then I place it in pluginclass and classpath under [PluginPolicy.Progress.SonicMQ].

    Is that enough? Or Websphere admin must tell me also INITIAL_CONTEXT_FACTORY ?

  • Hi Fuelfire,

    AFAIK, we need [PluginPolicy.Progress.SonicMQ] policy plug-in under $DLC/properties/AdminServerPlugins.properties file and Sonic ESB adapter may not be need as we are using MQ system.

    In Order to make remote connection with WebSpherMQ follow the below steps:
    1) Create Connection factory in WebSphereMQ server
    2) Create Client-connection Channel from Channels under Queue Manager
    3) Create Client Channel Definition Table (CCDT) and it will be located at <WebSphereMQInstallation>\Qmgrs\RemoteQM\@ipcc\AMQCLCHL.TAB
    4) Now, install the WebSphereMQ client on client machine and create .bindings file by providing the location of .TAB file.

    Create AdminObjectFinder.java file and specify the location of .bindings file as value to PROVIDER_URL property along with username and password. We can use the INITIAL_CONTEXT_FACTORY value as "com.sun.jndi.fscontext.RefFSContextFactory". Generate the class file from java and packet that class in jar and provide the generated jar file in pluginclasspath and classpath under [PluginPolicy.Progress.SonicMQ].

    Hope this helps!!

    Thanks,
    Anand.

  • Sorry, Anand... I'm new in MQ. I don't understand how will I get .bindings file?

    I can not follow the steps you proposed - MQ Server is out of my administrative jurisdiction. It's not mine. Perhaps the MQ administrator should give it to me? I do not know what the .bindings file is?

    When I wrote a program with structures (I cited the topic above), the MQ admin gave me the following line:

    EXTMQUSER.SVRCONN.CH/TCP/vprwmq(1422) and I used it to create an environment variable MQServer. Here, in JNDI approach I've handle another parameters.

    At the moment I asked for access to the test queue manager and clarify for myself the unclear points.

    Thanks again for the help!

    Andrew.

  • Hi Fuelfire,

    Ask MQ Administrator to provide the Client Channel Definition Table(CCDT) file and use that file to create the .bindings in client machine using the following command.

    Syntax:
    InitCtx> DEF CF(<connection_factory_name>) + QMGR(<queue_manager_name>) + TRAN(CLIENT) + CHAN(SYSTEM.DEF.SVRCONN) + HOST(<ServerName>) + PORT(<ServerPort>) + CCDTURL(<location of TAB file>)

    Example:

    InitCtx> DEF CF(RemoteCF) + QMGR(RemoteQM) + TRAN(CLIENT) + CHAN(SYSTEM.DEF.SVRCONN) + HOST(<ServerName>) + PORT(<ServerPort>) + CCDTURL(file:C:/workspace/WMQClient/AMQCLCHL.TAB)

    Once .bindings generated, specify the location of .bindings in AdminObjectFinder.java and create jar out of it and use it in classpath and pluginsclasspath.

    Hope this helps!!

    Thanks,
    Anand.

  • Anand, I correctly understood that the .bindings file I received from the MQ admin should be copied to the bin directory of the WebSphere MQ Client Installation? I plan to install the MQ client on a network drive for using by clients. They also use client networking from network drive (network Progress installation). If the network drive with the client networking and WebSphere MQ Client is named K, then the path to the binding file will be:

    env.put(Context.PROVIDER_URL, "file:/K:/WebSphere MQ/BIN");

    Is it right?

    Thanks.

    Andrew.

  • MQ admin sent me a tab file. So, I did the following (I hope this will help the same newbies in the MQ like me):

    1. If the MQ client is not installed - you must install it (I have MQ client 7.5 already been installed on the workstation).

    2. Open MQ_INSTALLATION_PATH/java/bin/JMSAdmin.config file with text editor and make sure that the directory specified in the PROVIDER_URL exists (in my case the directory C:/JNDI-Directory did not exist and I created it)

    3. Run JMSAdmin tool MQ_INSTALLATION_PATH/java/bin/JMSAdmin

    4. Run following commands in JMSAdmin tool. Replace <connection_factory_name>, <queue_manager_name>, SYSTEM.DEF.SVRCONN, <ServerName>, <ServerPort> and tab file path with the actual values:

    DEF CF(<connection_factory_name>) + QMGR(<queue_manager_name>) + TRAN(CLIENT) + CHAN(SYSTEM.DEF.SVRCONN) + HOST(<ServerName>) + PORT(<ServerPort>) + CCDTURL(<location of TAB file>)

    InitCtx> DEF CF(RemoteCF) + QMGR(UNIQM) + TRAN(CLIENT) + CHAN(SWIFTMQ.SVRCONN) + HOST(vplmq12) + PORT(1422) + CCDTURL(file:C:/JNDI-Directory/AMQCLCHL.TAB)

    As I understand, I myself define the connection_factory_name. I set it RemoteCF.

    5. A file named .bindings has been generated under the directory specified for the PROVIDER_URL parameter (in my case in C:\JNDI-Directory).

    Voila, .bindings file is created.

    Does the location of .bindings file affect the creation of the class? In other words, should I put this file on a network share or it's only needed to create a class and is not used anywhere else? Thanks.

  • We can copy the .bindings file in any location at client machine, but we need to provide the location of .bindings file in AdminObjectFinder.java file. For example, if .bindings file located at C:\remote\ directory then we need to provide the PROVIDER_URL as env.put(Context.PROVIDER_URL, "file://C://remote");

    Hope this helps!!

    Thanks,
    Anand.

  • Ok, Anand! You helped me a lot.

    Above I wrote the text of the class. Change the line with PROVIDER_URL from

    env.put(Context.PROVIDER_URL, "file:/C:/JNDI");

    to

    env.put(Context.PROVIDER_URL, "file:/C:/JNDI-Directory");

    So, we must create AdminObjectFinder.jar. Doing it.

    1. Compile AdminObjectFinder.java (command create AdminObjectFinder.class):

    %DLC%\jdk\bin\javac AdminObjectFinder.java

    2. Pack AdminObjectFinder.class in jar:

    %DLC%\jdk\bin\jar cf AdminObjectFinder.jar AdminObjectFinder.class

    AdminObjectFinder.jar is created. You must copy it and set the file path in the [PluginPolicy.Progress.SonicMQ] of %DLC%\properties\AdminServerPlugins.properties file (I change it on the server):

    [PluginPolicy.Progress.SonicMQ]
        pluginclasspath=C:\Program Files\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar,D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.jar
        classpath=C:\Program Files\OpenEdge/java/progress.jar,C:\PROGRA~2\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar,D:\Depo101\DPRO_31_10\MQ\AdminObjectFinder.jar
        jvmargs=-DsonicMQExtensions=false -DjmsProvider=WebSphereMQ
  • Hello, everybody!

    I wish everyone a good mood and a productive day :-)

    Now I have to write programs for working with queues. Do I need to know what kind of queue model we use? It depends on which of the approaches and procedures should I use? Or it's not important? I assume that our queue server uses the PTP model (but I'll clarify).

    Anand, there are a few questions:

    1) I see that you use "RUN jms/jmssession.p ". The documentation suggests using "RUN jms/pubsubsession.p" for Publisher/Subscribe and "RUN jms/ptpsession.p" for PTP. How to initialize the session properly?

    2) I'm stuck on your example (Producer.p). Where the variable cdate is initialized? Or it's not working example?

    3) I see the remark "Set user credentials". Can you show simple code - how I can set user credentials? I thought that the login and password of the user we specify in the class AdminObjectFinder. Later in the documentation I found a description of SetUser and SetPassword. Is this the right procedure?

    Thanks!

  • Hi Fuelfire,

    We should know which model we are going to use before start writing the programs. In any MQ we can send messages using either PTP or Pub-Sub model.

    jms/ptpsession.p - will work only with PTP domain
    jms/pubsubsession.p - will work only with Pub-Sub domain.
    jms/jmssession.p - will work for both PTP and Pub-Sub domains.

    2) I'm stuck on your example (Producer.p). Where the variable cdate is initialized? Or it's not working example?
    [Anand] - cdate variable is defined in the begin of variable definition section and Producer.p is working sample procedrue to send messages using PTP domain.

    Below is example to set the credentials in the procedure.

    /* Creates a session object. */
    RUN jms/jmssession.p PERSISTENT SET ptpsession ("-H localhost -S 5162 -AppService AD.sonicMQ1").

    /* Set user credentials. */
    RUN setBrokerURL IN ptpsession (INPUT "TestQueueManager").
    RUN setUser IN ptpsession (INPUT "admin" ).
    RUN setPassword IN ptpsession (INPUT "admin" ).

    Hope this helps!!

    Thanks,
    Anand.

  • Anand, good day! I started sonicMQ1.

    How can I determine on which port sonicMQ1 started? I see sonicMQ1.broker.log and sonicMQ1.server.log, but there is no indormation about port number in it. There is no information in admserv.log too.

    I run netstat -ao and see that port 5162 is used by java process. But in fact somewhere this information should be logged explicitly?

    Thank you.

  • The only thing I found in NS1.ns.log:

    [17/03/24@10:09:26.718+0300] P-005336 T-main 2 NS NSPlumbing Starting NameServer NS1 rmi://depotest2:20931/NS1 Port = 5162 TimeOut = 35. (8196)
    
  • Hi Fuelfire,

    3620 is the default port for sonicMQ1, if you modify it in ubroker.properties file, you can find it in sonicMQ1.broker.log as shown below:

    Started listener thread: L-3620 (8043)

    It logs in NS1.log file as shown below:

    T-NS1 2 NS NSPlumbing Registering Broker 932.99.999.XXX:1ee77e:cf3bbe3d33:-8030 AD.sonicMQ1 XXXXXX.bedford.progress.com/xxx.xx.xx.xx 3620. (8205)

    If it is not listing, can you please check whether SonicMQ1 got registered with NS1 or not

    Or you can query the SonicMQ1 and find it out as shown below:

    Broker Port                    : 3620

    Hope, this helps.

    Thanks,

    Srinivas Munigala