Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not able to get response from IBM MQ using JMS application

We communicate with the third party using IBM MQ in request/reply fashion. We send them request and they give us reply. Current we both have a simple java based native IBM MQ application. We are planning to rewrite our code using spring jms. But we are not getting any response back within given time when spring jms is used. We are using JMSTemplate to send or receive messages. I am sharing my code snippet. Am I doing anything wrong here? Any other properties should I set here?

  // Request Part (we are sending request)

  String request // this is the request string
  byte[] reqData = request.getBytes(); // converting it into byte array to send

  TextMessage txtMsg = session.createTextMessage(String.valueOf(reqData));

  Destination replyToQName = jmsTemplate.getDestinationResolver().resolveDestinationName(session, responseQueueName, false);

  txtMsg.setJMSReplyTo(replyToQName);

  Destination requestQ = jmsTemplate.getDestinationResolver().resolveDestinationName(session, requestQueueName, false);

  ((JmsDestination) requestQ).setBooleanProperty( WMQConstants.WMQ_MQMD_WRITE_ENABLED, true );

  ((MQQueue) requestQ).setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ); // setting this because third party application is native websphere mq java application 

  jmsTemplate.convertAndSend(requestQ, txtMsg);

  // saved msgId of request for late use
  String messageId =  txtMsg.getJMSMessageID();


  // Response fetching part

  Destination responseQ = jmsTemplate.getDestinationResolver().resolveDestinationName(session, responseQueueName, false);

  ((JmsDestination) responseQ).setBooleanProperty(WMQConstants.WMQ_MQMD_READ_ENABLED, true);

  ((JmsDestination) responseQ).setObjectProperty( WMQConstants.JMS_IBM_MQMD_CORRELID, msgIdText);

  jmsTemplate.setReceiveTimeout(30000L);

  String filter = "JMSCorrelationID='" + messageId + "'"; // to match request message's messageId with response message's correlationId

  TextMessage respMsg = (TextMessage) jmsTemplate.receiveSelected(responseQ, filter);

Below is my connectionFactory code:

 MQConnectionFactory factory = new MQQueueConnectionFactory();
 factory.setHostName("hostname");
 factory.setPort(1420);
 factory.setQueueManager("QM1");
 factory.setChannel("TEST.CHANNEL");
 factory.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
like image 329
Dev Shenoy Avatar asked Mar 06 '18 21:03

Dev Shenoy


1 Answers

The main issue here is that basic diagnostics have not been performed, or if they have then the results not presented in the question. I don't know Spring but I do know basic MQ debugging. I also lived in Missouri, the "Show Me" state, long enough to adopt the state motto as my own. Show me how all the assumptions were verified. As an MQ Admin I'd work with the developer to confirm all the assumptions by visual inspection. Here's how I'd approach it:

Inspect the outbound message

  1. Stop the outbound channel
  2. PUT a request message
  3. GET(ENABLE) the XMitQ and browse the message
    a) Does the message appear?
    b) Does the message have the right format and values?
    c) Are the Reply-To fields correctly populated?
    d) Does the message expire and if so is the expiry sufficiently long?

Inspect the return message

  1. Stop the application
  2. Restart the outbound channel
  3. Browse the reply-to queue
    a) Does a message arrive?
    b) Is it correctly formatted and populated?

Summary
In the end there are only two likely scenarios where this can go wrong and both are easy to check.

First, it is possible the new program is not putting any message at all. This is actually quite common when refactoring code to use a new framework. Trying to debug without positively verifying a message gets PUT (and explicitly stating in the question how this was done and the result) is making an awfully big assumption. Don't assume. Verify a message is produced and tell us the details when asking so we can eliminate that as a root cause.

Second, working backward from the application taking the requests, it doesn't care which app sends the message if they are the same. Assuming the requestor app is actually PUTting a message, it can't be the same as the old one since it gets a different reaction from the remote server app. Compare messages for the same transaction from the old and the new app versions. Print them out in hex and compare byte for byte if necessary.

After performing this kind of differential diagnosis it would be possible narrow the focus and get to root cause. The list of things to check if no message is produced is quite different from the list of items to check if a message is actually produced. It might be possible to resolve this without doing basic diagnostics but that would be the exception. So my non-answer answer is: start by doing the basic diagnostics.

like image 55
T.Rob Avatar answered Nov 16 '22 12:11

T.Rob