0

Below is a summary of the AMQP client we have trying to build to evaluate request / response message pattern with IBM MQ.

Current IBM Queue Manager version = 9.1.0.6

AMQP channel setup with the below properties, and is available at <<host_name>>:5672. Properties of the channel are below.

Attributes for COMET.AMQP_SECCLNT
name    COMET.AMQP_SECCLNT
type    AMQP
alteration_date 2021-09-06
alteration_time 08.48.37
no_external_participants    
description COMET Secure SSL Client for AMQP
disc_interval   
hb_interval 
keep_alive_interval 
max_instances   999999999
max_instances_per_client    
max_message_length  4194304
mca_user    
sharing_conversations   
ssl_client_auth REQUIRED
ssl_cipher_spec ECDHE_RSA_AES_256_CBC_SHA384
ssl_peer_name   
cert-label  
status  INACTIVE
canStart    false
canStop false

To access an existing queue via the channel, a subscription was setup - /comet/interim/claim. The subscription was mapped to queue endpoint – COMET.INTERIM_CLAIMQ. The below client is configured to

  1. Send a message and pickup the message using jms correlation id from the same queue endpoint.
  2. Set the JMS Message Type to MQSTR instead of MQHRF2
  3. Set reply to end point as /comet/interim/claim – subscription created to access COMET.INTERIM_CLAIMQ.

Client code is below

package com.ibm.mq.samples.jms.qpid;

import javax.jms.JMSContext;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueReceiver;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
import org.apache.qpid.jms.JmsConnectionFactory;

public class TestMessageSender {
       public static void main(String[] args) {

              System.setProperty("javax.net.ssl.keyStore", "cometdesktopmq.jks");
              System.setProperty("javax.net.ssl.trustStore", "cometdesktopmq.jks");
              System.setProperty("javax.net.ssl.keyStorePassword", "<<password>>");
              System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false");
              try {
                     String requsetUri = "amqps://host_name:5672";
                     String userName = "tgusr";
                     String password = "<<password>>";
                     JmsConnectionFactory factory = new JmsConnectionFactory(userName, password, requsetUri);
                     QueueConnection conn = factory.createQueueConnection();
                     conn.start();
                     System.out.println("conn started");
                     QueueSession sess = conn.createQueueSession(false, 1);
                     System.out.println("queue session created");
                     JMSContext context = factory.createContext(userName, password);
                     System.out.println("context created");
                     Queue q = context.createQueue("/comet/interim/claim");
                     QueueSender qs = sess.createSender(q);
                     System.out.println("queue sender created");
                     TextMessage message = context.createTextMessage("Text content");
                     message.setJMSType("MQSTR");
                     String msgId = message.getJMSMessageID();
                     message.setJMSCorrelationID(msgId);
                     Queue rq = context.createQueue("/comet/interim/claim");
                     message.setJMSReplyTo(rq);
                     qs.send(message);  // Send the message
                     System.out.println("message sent");
                     QueueReceiver reciever = sess.createReceiver(rq, "JMSCorrelationID ='" + msgId + "'");
                     Message reply = reciever.receive(10*1000); // Pickup the message using the id set in correlation id field, timeout = 10 secs
                     Inspector ins = new Inspector(reply);
                     ins.showMessageType();
                     ins.showProperties();
                     ins.showMessageHeaders();
                     ins.showMessageBody();
                     conn.close();
              } catch (Exception e) {
                     e.printStackTrace();
              }
       }
}

The message that was received at queue COMET.INTERIM_CLAIMQ is a below

RFH [1]\[1] ¸
________________________________________
MQSTR 
MQMD
StrucId:    MD  Version:    1
MsgType:    8   Expiry: -1
Encoding:   546 CodedCharSetId: 1208
Format: MQHRF2  Priority:   0
Report: 0   Feedback:   0
MsgId:  414d5120574d51543532352020202020e4c44561003c722a
CorrelId:   414d5120574d51543532352020202020b6273861033d162d
BackoutCount:   0
AccountingToken:    0531353938370000000000000000000000000000000000000000000000000006
ApplIdentityData:       ApplOriginData: 
ReplyToQ:       ReplyToQMgr:    WMQT525
Persistence:    1   UserIdentifier: mqm
PutApplType:    26  PutApplName:    WMQT525
PutDate:    09/19/2021 22:14:20
GroupId:    000000000000000000000000000000000000000000000000
MsgSeqNumber:   1   Offset: 0
MsgFlags:   0   OriginalLength: -1
Message     
RFH [1]\[1] ¸
________________________________________
MQSTR ¸
________________________________________
ü<mq_amqp><Lis>p910-006-200703</Lis><Ver>1.0</Ver><Hdr><Dur dt='boolean'>1</Dur><Pri dt='i2'>4</Pri><Ttl dt='i8'>0</Ttl><Fac xsi:nil='true'></Fac></Hdr><Prp><Mid>ID:ce297c87-f1f4-46af-8ecb-6f6eb4d97d70:1:1:1-1</Mid><To>/comet/interim/claim</To><Sub>MQSTR</Sub><Rto>/comet/interim/claim</Rto><Aet dt='i8'>0</Aet><Crt dt='i8'>1632107660940</Crt><Gsq dt='i8'>0</Gsq></Prp><Man><x-opt-jms-reply-to>0</x-opt-jms-reply-to><x-opt-jms-dest>0</x-opt-jms-dest><x-opt-jms-msg-type>5</x-opt-jms-msg-type></Man></mq_amqp> 4<jms><Rto>topic:///comet/interim/claim</Rto></jms> Text content

Concerns –

  1. Format still shows MQHRF2 instead of MQSTR.
  2. ReplyToQ property shows blank. [First to concerns are high priority]
  3. The message body contains tag To as - /comet/interim/claim , What does this indicate ?
  4. It also contains tag topic:///comet/interim/claim. The relyTo destination we are setting in the code is a Queue, Why does it get translated into a topic:///?
JoshMc
  • 10,239
  • 2
  • 19
  • 38

1 Answers1

2

Below is a summary of the AMQP client we have trying to build to evaluate request / response message pattern with IBM MQ.

Current IBM Queue Manager version = 9.1.0.6

If you want to create a client application to connect to IBM MQ queue manager, then why don't you just write it using the MQ Java or Java/JMS Client Library? Why add all this extra stuff? You are giving yourself more headaches than it is worth.

IBM has been incrementally adding AMQP features to IBM MQ over the last 6 years since IBM added AMQP channel support in IBM MQ v8.0.0.2.

You are using IBM MQ v9.1, I believe it only supports Pub/Sub and not point-to-point messages. For Pub/Sub, all messages will be in the JMS message format (aka MQRFH2 format). You should read this page.

If you upgrade your queue manager to IBM MQ v9.2 then you will get more AMQP features. For IBM MQ v9.2 AMQP features, you should read this page.

Roger
  • 7,062
  • 13
  • 20
  • Hi Roger Ty for reply. The end goal is to be able to create a native-image using graalvm. and the ibm.mq.allclient jar initiates a JMX Bean during initialization, which is currently not supported for native images . and hence the alternative of being able to do the exact same thing by using a AMQP channel and a compatible client like apache qpid. I will definitely consider upgrading the broker to 9.2 – Chandan Mishra Sep 22 '21 at 17:46