Search code examples
pythonibm-mqpymqi

How to browse the message based on MsgId or CorrelId from queue in pymqi


import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
queue_name = 'TEST.1'
message = 'Hello from Python 2!'
conn_info = '%s(%s)' % (host, port)

First I did the PUT operation like the below code and I worked fine. I put for more 2000 messages

qmgr = pymqi.connect(queue_manager, channel, conn_info)
queue = pymqi.Queue(qmgr, queue_name)
queue.put(message)
queue.close()
qmgr.disconnect()

I tried the below code to get the first message It also worked fine. It gives me the first message. I don't know is the correct approach to get the first message.

queue = pymqi.Queue(qmgr, queue_name, pymqi.CMQC.MQOO_BROWSE)    
gmo = pymqi.GMO()
gmo.Options = pymqi.CMQC.MQGMO_WAIT | pymqi.CMQC.MQGMO_BROWSE_NEXT | pymqi.CMQC.MQGMO_NO_PROPERTIES
gmo.WaitInterval = 5000
md = pymqi.MD()
md.Format = pymqi.CMQC.MQFMT_STRING
message = queue.get(None, md, gmo)
print(message)   # b'Hello from Python 2!'
print(md.MsgId.hex())  #'414d51204e41544d333030202020202817d9ff650a742f22'
queue.close()
qmgr.disconnect()

but when I tried below code it gives me correct message but I this is not the best solution because if I have 2000 messages then it will iterate until the msgId matches.

queue = pymqi.Queue(qmgr, queue_name, pymqi.CMQC.MQOO_BROWSE)
gmo = pymqi.GMO()
gmo.Options = pymqi.CMQC.MQGMO_WAIT | pymqi.CMQC.MQGMO_BROWSE_NEXT | pymqi.CMQC.MQGMO_NO_PROPERTIES
gmo.WaitInterval = 5000
user_MsgId = '414d51204e41544d333030202020202817d9ff650a742f22'
overall_message = []
keep_running = True
while keep_running:
    md = pymqi.MD()
    md.Format = pymqi.CMQC.MQFMT_STRING
    message = queue.get(None, md, gmo)
    print(md.MsgId.hex())
    if md.MsgId.hex() != user_MsgId:
        continue:
    else:
        overall_message.append(message)
        break
queue.close()
qmgr.disconnect()

The above solution gives me correct message but when messages are more performance goes down. Can anyone please suggest better approach to browse the message by MsgId or CorrelId?

I tried below code as per suggestion I edited here but it is not working:

queue = pymqi.Queue(qmgr, queue_name, pymqi.CMQC.MQOO_BROWSE)    
gmo = pymqi.GMO()
gmo.MatchOptions = pymqi.CMQC.MQMO_MATCH_MSG_ID
gmo.Version = pymqi.CMQC.MQMO_VERSION_2
gmo.Options = pymqi.CMQC.MQGMO_WAIT | pymqi.CMQC.MQGMO_BROWSE_NEXT | pymqi.CMQC.MQGMO_NO_PROPERTIES
gmo.WaitInterval = 5000
md = pymqi.MD()
md.Version = pymqi.CMQC.MQMO_VERSION_2
md.Format = pymqi.CMQC.MQFMT_STRING
md.MsgId = b'414d51204e41544d333030202020202817d9ff650a742f22' # this is the same output which I get from above 
message = queue.get(None, md, gmo)
print(message)
print(md.MsgId.hex())
queue.close()
qmgr.disconnect()

Solution

  • You certainly can, and should, be using Get by Message Id.

    I ran your example code and discovered that you were setting the MsgId as a string. The MsgId is a bytes field, so you want to change the line where you are setting the MsgId to something like the following:-

    md.MsgId = bytes.fromhex('414D51204D51473120202020202020200110A66537AC0040')
    

    You also had a couple of minor errors that I'm sure you'd notice soon enough. The constant MQMO_VERSION_2 does not exist. You need to correct the lines setting the gmo.Version and the md.Version thus:-

    gmo.Version = pymqi.CMQC.MQGMO_VERSION_2
    md.Version = pymqi.CMQC.MQMD_VERSION_2
    

    And finally there is no need to set the md.Format on input to a queue.get. It is an output only field in that case.