3

I have a requirement to get just a specific message from a queue based on its correlation ID.

Is there a way where we can get a message for the corresponding correlation ID and remove only that message from the queue without deleting the others.

The options which I have tried they retrieve the message but removing the other messages from the queue as well while finding my message

I have used the following openOptions in accessQueue method while browsing the queue

MQC.MQOQ_INPUT_SHARED | MQC.MQOO_FAIL_IF_QUIESCING | MQC_MQOO_INQUIRE | MQC.MQOOBROWSE

And the following options to get the message

    String correlation ID = <correlationID>

    MQMessage respMessage = new MQMessage();

    respMessage.correlationId = correlation ID.getBytes();

    MQGetMessageOptions msg = new MqGetMessageOptions();    
    msg.options = MQC.MQGMO_NO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING + MQC.MQGMO_CONVERT + MQC.MQGMO_BROWSE_NEXT

        msg.matchOptions = MQC.MQMO_MATCH_MSG_ID

msg.waitInterval = 2000;

queue.get(respMessage, msg);
  • You appear to have MQGMO_BROWSE_NEXT in your set of Get Options. Your question suggests you want to remove the message, not browse it? – Morag Hughson Jul 09 '19 at 08:47
  • You are setting correlationID but match options your set is MQMO_MATCH_MSG_ID. You need to set MQMO_MATCH_CORREL_ID if you want to get messages matching correlation id. – Shashi Jul 09 '19 at 08:53
  • @morag hughson Getting MQJE001: Completion Code '2', Reason '2033' .... with the mentioned options of msg.options = MQC.MQGMO_WAIT + MQC.MQGMO_SYNCPOINT + MQC.MQGMO_FAIL_IF_QUIESCING + MQC.MQGMO_CONVERT – Johnny Bravo Jul 09 '19 at 10:07
  • @Shashi ... Thanks for pointing it out have made the changes but stuck with MQ error '2033' – Johnny Bravo Jul 09 '19 at 10:17
  • How sure are you that the correlation ID you are asking for is on the queue. Have you tried printing out the hex bytes of the correlation ID you are filling into `respMessage.correlationId` and comparing it to what is shown if you run the `amqsbcg` sample to browse the contents of your queue. 2033 means that no matching message was found. Your question doesn't show us your processing of the correlation ID so we cannot easily comment on what you have done. – Morag Hughson Jul 09 '19 at 10:47
  • @morag hughson I am able to verify the CORRELATION ID in the hermesJMS tool.... Can you please direct me to any example for this ? – Johnny Bravo Jul 09 '19 at 14:50
  • The answer from @Roger shows examples of hex correlation IDs. Does your correlation ID have a similar format? – Morag Hughson Jul 10 '19 at 03:32

1 Answers1

3

You have many issues with your code.

(1) As Morag said, remove the MQGMO_BROWSE_NEXT option if you want to remove the message from the queue (i.e. destructive get).

respMessage.correlationId = correlation ID.getBytes();
msg.matchOptions = MQC.MQMO_MATCH_MSG_ID

(2) You are setting the CorrelId but then requesting to match on MsgId. That won't work. You will get reason code of MQRC_NO_MSG_AVAILABLE (2033).

(3) MsgIds and/or CorrelIds should never be converted to a string or start as a string. MsgIds and/or CorrelIds will contain binary data. Hence, MsgIds and CorrelIds should always be a byte array. i.e. byte[]

Here is a screenshot of a message's MsgId and CorrelId:

MQ Visual Edit showing a messages MQMD fields

(4) You have MQGMO_NO_WAIT option but you set waitInterval to 2000. If you want to wait for up to 2 seconds for a message to arrive then you need to use the MQGMO_WAIT option.

MQGetMessageOptions msg = new MqGetMessageOptions();

(5) "msg" is a terrible variable name. It will only confuse people because they will think it references a message. i.e. MQMessage class. It is far better to call the variable "gmo".

i.e.

MQGetMessageOptions gmo = new MqGetMessageOptions();
gmo.options = CMQC.MQGMO_WAIT + CMQC.MQGMO_FAIL_IF_QUIESCING + CMQC.MQGMO_CONVERT;
gmo.waitInterval = 2000;
gmo.matchOptions = CMQC.MQMO_MATCH_CORREL_ID;
Roger
  • 7,062
  • 13
  • 20