PyMQI Examples

The purpose of this chapter is to gather code showing PyMQI in action or code that is related to common IBM MQ-related tasks in general.

All the samples are self-contained and ready to use in your own PyMQI applications.

Connecting to a queue manager

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
conn_info = '%s(%s)' % (host, port)

qmgr = pymqi.connect(queue_manager, channel, conn_info)
qmgr.disconnect()

Connecting with username/password credentials

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
conn_info = '%s(%s)' % (host, port)

user = 'app'
password = 'mypassword'

qmgr = pymqi.connect(queue_manager, channel, conn_info, user, password)
qmgr.disconnect()

Notes:

  • Credentials need to be provided to PyMQI as regular Python variables - PyMQI will not look them up in any user database or similar.

Connecting in bindings mode (without TCP)

import pymqi

queue_manager = 'QM1'
qmgr = pymqi.connect(queue_manager)

qmgr.disconnect()

How to put the message on a queue

import pymqi

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

qmgr = pymqi.connect(queue_manager, channel, conn_info)

queue = pymqi.Queue(qmgr, queue_name)
queue.put(message)
queue.close()

qmgr.disconnect()

How to get the message off a queue

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
queue_name = 'TEST.1'
conn_info = '%s(%s)' % (host, port)

qmgr = pymqi.connect(queue_manager, channel, conn_info)

queue = pymqi.Queue(qmgr, queue_name)
message = queue.get()
queue.close()

qmgr.disconnect()

Notes:

  • By default Queue.get will not use any timeout, if messages are not available immediately a pymqi.MQMIError will be raised with MQ reason code set to 2033 MQRC_NO_MSG_AVAILABLE.

Sending Unicode data vs. bytes

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
queue_name = 'TEST.1'
message = u'My Unicode data'
conn_info = '%s(%s)' % (host, port)

bytes_encoding = 'iso-8859-1'
default_ccsid = 819

qmgr = pymqi.connect(
    queue_manager, channel, conn_info,
    bytes_encoding=bytes_encoding,
    default_ccsid=default_ccsid
)

queue = pymqi.Queue(qmgr, queue_name)
queue.put(message)
queue.close()

qmgr.disconnect()

Notes:

  • Unicode and bytes handling is unified in PyMQI regardless of whether one uses Python 2 or 3, i.e. everything above applies to both Python lines.
  • PyMQI does not process in any way bytes objects used in queue.put calls - this means that if you encode your data as bytes before handling it to queue.put, the data will be sent as-is.
  • If you give queue.put Unicode objects on input, though, they will be automatically converted to bytes, using UTF-8 by default - this should suffice in most cases.
  • It is possible to change the default encoding used for conversion from Unicode to bytes by providing two parameters when calling pymqi.connect or when constructing QueueManager objects.
  • The parameters are called bytes_encoding and default_ccsid and their default values are utf8 and 1208, respectively.
  • Parameter bytes_encoding is used for conversion of Python Unicode objects to bytes objects.
  • Parameter default_ccsid is used to specify a CCSID in the underlying call's MQMD structure.
  • Both parameters will be used in all put calls related to a single MQ connection - that is, they are specified once only on the level of the connection to a queue manager, rather than individually for each put call.
  • If not using the defaults, it is the user's responsibility to make sure that the two parameters match - for instance, encoding UTF-8 is represented by CCSID 1208, but a different CCSID may be required with other encodings.
  • It is also the user's responsibility to ensure that default_ccsid matches the queue manager's CCSID.
  • Again, the conversion from Unicode to bytes as well as the application of bytes_encoding and default_ccsid take place only if Unicode objects are given on input to queue.put - if data is already bytes, there is no conversion.
  • In the example below, message is a Unicode object and it will be converted to ISO-8859-1 by PyMQI because this is the encoding explicitly specified. Also, that encoding's corresponding CCSID - 819 - is given on input to pymqi.connect.

How to get a message without JMS (MQRFH2) headers

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
queue_name = 'TEST.1'
conn_info = '%s(%s)' % (host, port)

qmgr = pymqi.connect(queue_manager, channel, conn_info)

queue = pymqi.Queue(qmgr, queue_name)

# Get the message but discard any JMS headers
message = queue.get_no_jms()

# Works exactly as above: get_no_rfh2 is an alias to get_no_jms
message = queue.get_no_rfh2()

# Close queue and disconnect from queue manager
queue.close()
qmgr.disconnect()

Notes:

  • Depending on how they are configured, JMS-based applications may send a series of headers that are at times not required by Python recipients - use .get_no_jms to receive only business payload without any JMS headers.
  • For completeness, .get_no_rfh2 was added as an alias to .get_no_jms - it works exactly the same.

How to wait for a single message

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
queue_name = 'TEST.1'
conn_info = '%s(%s)' % (host, port)

# Message Descriptor
md = pymqi.MD()

# Get Message Options
gmo = pymqi.GMO()
gmo.Options = pymqi.CMQC.MQGMO_WAIT | pymqi.CMQC.MQGMO_FAIL_IF_QUIESCING
gmo.WaitInterval = 5000 # 5 seconds

qmgr = pymqi.connect(queue_manager, channel, conn_info)

queue = pymqi.Queue(qmgr, queue_name)
message = queue.get(None, md, gmo)
queue.close()

qmgr.disconnect()

Notes:

  • If not told otherwise, Queue.get builds up a default Message Descriptor (MD) and Get Message Options (GMO), however in this case one needs to specify custom GMO in order to tell MQ to wait for messages for a given time. A default MD still needs to be passed to Queue.get.
  • It is a recommended MQ programming practice to always use MQGMO_FAIL_IF_QUIESCING - PyMQI uses it by default unless it is overridden.

How to wait for multiple messages

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
queue_name = 'TEST.1'
conn_info = '%s(%s)' % (host, port)

# Message Descriptor
md = pymqi.MD()

# Get Message Options
gmo = pymqi.GMO()
gmo.Options = pymqi.CMQC.MQGMO_WAIT | pymqi.CMQC.MQGMO_FAIL_IF_QUIESCING
gmo.WaitInterval = 5000 # 5 seconds

qmgr = pymqi.connect(queue_manager, channel, conn_info)
queue = pymqi.Queue(qmgr, queue_name)

keep_running = True

while keep_running:
    try:
        # Wait up to to gmo.WaitInterval for a new message.
        message = queue.get(None, md, gmo)

        # Process the message here..

        # Reset the MsgId, CorrelId & GroupId so that we can reuse
        # the same 'md' object again.
        md.MsgId = pymqi.CMQC.MQMI_NONE
        md.CorrelId = pymqi.CMQC.MQCI_NONE
        md.GroupId = pymqi.CMQC.MQGI_NONE

    except pymqi.MQMIError as e:
        if e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_NO_MSG_AVAILABLE:
            # No messages, that is OK, we can ignore it.
            pass
        else:
            # Some other error condition.
            raise

queue.close()
qmgr.disconnect()

Notes:

  • The key part is a GIL-releasing non-busy loop which consumes almost no CPU and runs very close to raw C speed. On modern-day hardware, such a programming pattern can be used to easily achieve a throughput of thousands of messages a second.
  • Again, using pymqi.CMQC.MQGMO_FAIL_IF_QUIESCING is a recommended programming practice.

How to specify dynamic reply-to queues

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
conn_info = '%s(%s)' % (host, port)
message = 'Please reply to a dynamic queue, thanks.'
dynamic_queue_prefix = 'MY.REPLIES.*'
request_queue = 'TEST.1'

qmgr = pymqi.connect(queue_manager, channel, conn_info)

# Dynamic queue's object descriptor.
dyn_od = pymqi.OD()
dyn_od.ObjectName = 'SYSTEM.DEFAULT.MODEL.QUEUE'
dyn_od.DynamicQName = dynamic_queue_prefix

# Open the dynamic queue.
dyn_input_open_options = pymqi.CMQC.MQOO_INPUT_EXCLUSIVE
dyn_queue = pymqi.Queue(qmgr, dyn_od, dyn_input_open_options)
dyn_queue_name = dyn_od.ObjectName.strip()

# Prepare a Message Descriptor for the request message.
md = pymqi.MD()
md.ReplyToQ = dyn_queue_name

# Send the message.
queue = pymqi.Queue(qmgr, request_queue)
queue.put(message, md)

# Get and process the response here..

dyn_queue.close()
queue.close()
qmgr.disconnect()

Notes:

  • To specify a dynamic reply-to queue, one needs to first create an appropriate Object Descriptor and then open the queue, the descriptor's DynamicQName attribute will be filled in by MQ to the name of a queue created.
  • Queue.put accepts a message descriptor on input, its ReplyToQ attribute is responsible for storing information about where the responding side should send the messages to.

How to send responses to reply-to queues

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
queue_name = 'TEST.1'
message = 'Here's a reply'
conn_info = '%s(%s)' % (host, port)

qmgr = pymqi.connect(queue_manager, channel, conn_info)

md = pymqi.MD()

queue = pymqi.Queue(qmgr, queue_name)
message = queue.get(None, md)

reply_to_queue_name = md.ReplyToQ.strip()
reply_to_queue = pymqi.Queue(qmgr, reply_to_queue_name)
reply_to_queue.put(message)

queue.close()
qmgr.disconnect()

Notes:

  • Queue.get accepts an input message descriptor parameter, its ReplyToQ attribute is responsible for storing information about where the responding side should send the messages to. The attribute's value is filled in by IBM MQ.

How to publish messages on topics

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
topic_string = '/currency/rate/EUR/USD'
msg = '1.3961'
conn_info = '%s(%s)' % (host, port)

qmgr = pymqi.QueueManager(None)
qmgr.connect_tcp_client(queue_manager, pymqi.CD(), channel, conn_info)

topic = pymqi.Topic(qmgr, topic_string=topic_string)
topic.open(open_opts=pymqi.CMQC.MQOO_OUTPUT)
topic.pub(msg)
topic.close()

qmgr.disconnect()

Notes:

  • pymqi.Topic is a class through which all operations related to MQ topics are made.
  • A Topic object may be open just like if it were a regular queue.
  • Once a topic is open, its .pub method may be used for publishing the messages.

How to subscribe to topics

# stdlib
import logging

# PyMQI
import pymqi

logging.basicConfig(level=logging.INFO)

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
topic_string = '/currency/rate/EUR/USD'
msg = '1.3961'
conn_info = '%s(%s)' % (host, port)

qmgr = pymqi.QueueManager(None)
qmgr.connect_tcp_client(queue_manager, pymqi.CD(), channel, conn_info)

sub_desc = pymqi.SD()
sub_desc['Options'] = pymqi.CMQC.MQSO_CREATE + pymqi.CMQC.MQSO_RESUME + \
    pymqi.CMQC.MQSO_DURABLE + pymqi.CMQC.MQSO_MANAGED
sub_desc.set_vs('SubName', 'MySub')
sub_desc.set_vs('ObjectString', topic_string)

sub = pymqi.Subscription(qmgr)
sub.sub(sub_desc=sub_desc)

get_opts = pymqi.GMO(
    Options=pymqi.CMQC.MQGMO_NO_SYNCPOINT + pymqi.CMQC.MQGMO_FAIL_IF_QUIESCING + pymqi.CMQC.MQGMO_WAIT)
get_opts['WaitInterval'] = 15000

data = sub.get(None, pymqi.md(), get_opts)
logging.info('Here is the received data: [%s]' % data)

sub.close(sub_close_options=pymqi.CMQC.MQCO_KEEP_SUB, close_sub_queue=True)
qmgr.disconnect()

Notes:

  • A pymqi.Subscription and its companion class pymqi.SD (a Subscription Descriptor) are needed for subscribing to a topic.
  • A proper pymqi.SD needs to be created first; note the usage of its .set_vs method for setting some of the object's properties. It's needed here because parts of the pymqi.SD's implementation depend on ctypes <http://docs.python.org/library/ctypes.html>_ and cannot be set directly through the regular dictionary assignment like the 'Options' have been set.
  • Note well that among other options we're using pymqi.CMQC.MQSO_CREATE + pymqi.CMQC.MQSO_RESUME, in plain words in means create a new subscription of the name set in the 'SubName' key ('MySub' in the example) but if the subscription already exists then just resume it, this basically means we will not meet the MQRC_SUB_ALREADY_EXISTS error code.
  • Once the pymqi.SD has been created, it can be used for subscribing to a particular topic with invoking the pymqi.Subscription's .sub method.
  • Once subscribed to the topic, you can use the subscription's .get method for receiving the messages. Note that the .get method uses regular Get Message Options (pymqi.GMO), just like if the subscription was an ordinary queue.
  • Before disconnecting from the queue manager, a subscription should be closed; note passing of the information regarding what MQ should do with the related objects.

How to use SSL and TLS

# stdlib
import logging

# PyMQI
import pymqi

logging.basicConfig(level=logging.INFO)

queue_manager = 'QM1'
channel = 'SSL.SVRCONN.1'
host = '127.0.0.1'
port = '1414'
queue_name = 'TEST.1'
conn_info = '%s(%s)' % (host, port)
ssl_cipher_spec = 'TLS_RSA_WITH_AES_256_CBC_SHA'
key_repo_location = '/var/mqm/ssl-db/client/KeyringClient'
message = 'Hello from Python!'

cd = pymqi.CD()
cd.ChannelName = channel
cd.ConnectionName = conn_info
cd.ChannelType = pymqi.CMQC.MQCHT_CLNTCONN
cd.TransportType = pymqi.CMQC.MQXPT_TCP
cd.SSLCipherSpec = ssl_cipher_spec

sco = pymqi.SCO()
sco.KeyRepository = key_repo_location

qmgr = pymqi.QueueManager(None)
qmgr.connect_with_options(queue_manager, cd, sco)

put_queue = pymqi.Queue(qmgr, queue_name)
put_queue.put(message)

get_queue = pymqi.Queue(qmgr, queue_name)
logging.info('Here is the message again: [%s]' % get_queue.get())

put_queue.close()
get_queue.close()
qmgr.disconnect()

How to set and get the message priority

# stdlib
import logging

# PyMQI
import pymqi

logging.basicConfig(level=logging.INFO)

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

put_md = pymqi.MD()
put_md.Priority = priority

qmgr = pymqi.connect(queue_manager, channel, conn_info)

put_queue = pymqi.Queue(qmgr, queue_name)
put_queue.put(message, put_md)

get_md = pymqi.MD()
get_queue = pymqi.Queue(qmgr, queue_name)
message_body = get_queue.get(None, get_md)

logging.info('Received a message, priority `%s`.' % get_md.Priority)

put_queue.close()
get_queue.close()
qmgr.disconnect()

Notes:

  • Use custom pymqi.MD instances for both setting and reading the message priority.

How to use channel compression

import pymqi
import CMQXC

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

cd = pymqi.CD()
cd.MsgCompList[1] = CMQXC.MQCOMPRESS_ZLIBHIGH

qmgr = pymqi.connect(queue_manager, channel, conn_info)

queue = pymqi.Queue(qmgr, queue_name)
queue.put(message)
queue.close()

qmgr.disconnect()

Notes:

  • Note that the compression level to use is the second element of the cd.MsgCompList list, not the first one,
  • The above assumes the channel has been configured using the following MQSC command: ALTER CHANNEL(SVRCONN.1) CHLTYPE(SVRCONN) COMPMSG(ZLIBHIGH)

How to check completion- and reason codes

# stdlib
import logging

# PyMQI
import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = 'localhost.invalid' # Note the invalid hostname here
port = '1414'
conn_info = '%s(%s)' % (host, port)

try:
    qmgr = pymqi.connect(queue_manager, channel, conn_info)
except pymqi.MQMIError as e:
    if e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_HOST_NOT_AVAILABLE:
        logging.error('Such a host `%s` does not exist.' % host)

Notes:

  • When IBM MQ raises an exception, it is wrapped in a pymqi.MQMIError object which exposes 2 useful attributes: .comp is a completion code and .reason is the reason code assigned by MQ. All the completion- and reason codes can be looked up in the pymqi.CMQC module.

How to check the versions of IBM MQ packages installed (Linux)

import logging
import rpm

logging.basicConfig(level=logging.INFO)

package_name = 'MQSeriesClient'

ts = rpm.TransactionSet()
mi = ts.dbMatch('name', package_name)

if not mi.count():
    logging.info('Did not find package [%s] in RPM database.' % package_name)
else:
    for header in mi:
        version = header['version']
        msg = 'Found package `%s`, version `%s`.' % (package_name, version)
        logging.info(msg)

Notes:

  • IBM MQ packages for Linux are distributed as RPMs and we can query the RPM database for information about what has been installed.
  • PyMQI hasn't been used in the example, however the task is related to MQ administration and that is why it has been shown here.

How to check the versions of IBM MQ packages installed (Windows)

import logging
import _winreg

logging.basicConfig(level=logging.INFO)

key_name = 'Software\\IBM\\MQSeries\\CurrentVersion'

try:
    key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key_name)
except WindowsError:
    logging.info('Could not find IBM MQ-related information in Windows registry.')
else:
    version = _winreg.QueryValueEx(key, 'VRMF')[0]
    logging.info('IBM MQ version is `%s`.' % version)

Notes:

  • Versions of IBM MQ packages installed under Windows can be extracted by querying the Windows registry.
  • Again, PyMQI hasn't been used in the example, however the task is related to MQ administration and that is why it has been shown here.

How to use an alternative user ID

import pymqi

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

qmgr = pymqi.connect(queue_manager, channel, conn_info)

od = pymqi.OD()
od.ObjectName = queue_name
od.AlternateUserId = alternative_user_id

queue = pymqi.Queue(qmgr)
queue.open(od, pymqi.CMQC.MQOO_OUTPUT | pymqi.CMQC.MQOO_ALTERNATE_USER_AUTHORITY)
queue.put(message)

queue.close()
qmgr.disconnect()

Notes:

  • Queue.open accepts an object descriptor (an instance of pymqi.OD class) and queue open options, both of which are used here to specify the alternative user ID.

How to avoid MQRC_ALREADY_CONNECTED

import pymqi

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

cd = pymqi.CD()

cd.ChannelName = channel
cd.ConnectionName = conn_info
cd.ChannelType = pymqi.CMQC.MQCHT_CLNTCONN
cd.TransportType = pymqi.CMQC.MQXPT_TCP

connect_options = pymqi.CMQC.MQCNO_HANDLE_SHARE_BLOCK

qmgr = pymqi.QueueManager(None)

for x in range(10):
    qmgr.connect_with_options(queue_manager, cd=cd, opts=connect_options)
    qmgr.connect_with_options(queue_manager, cd=cd, opts=connect_options)

queue = pymqi.Queue(qmgr, queue_name)
queue.put(message)
queue.close()

qmgr.disconnect()
import pymqi

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

qmgr = pymqi.QueueManager(None)
qmgr.connect_tcp_client(queue_manager, pymqi.CD(), channel, conn_info)

try:
    qmgr.connect_tcp_client(queue_manager, pymqi.CD(), channel, conn_info)
except pymqi.MQMIError as e:
    if e.comp == pymqi.CMQC.MQCC_WARNING and e.reason == pymqi.CMQC.MQRC_ALREADY_CONNECTED:
        # Move along, nothing to see here..
        pass

queue = pymqi.Queue(qmgr, queue_name)
queue.put(message)
queue.close()

qmgr.disconnect()

Notes:

  • The first example is the recommended way, it tells MQ to reuse a single connection regardless of how many times the application will be issuing a request for establishing a new connection. That is also a pattern to use when your application is multi-threaded, without using MQCNO_HANDLE_SHARE_BLOCK MQ would not allow the threads to reuse the same connection.
  • The second one shows how to ignore the particular exception indicating that an application has been already connected.

How to define a channel

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
conn_info = '%s(%s)' % (host, port)

channel_name = 'MYCHANNEL.1'
channel_type = pymqi.CMQXC.MQCHT_SVRCONN

args = {pymqi.CMQCFC.MQCACH_CHANNEL_NAME: channel_name,
        pymqi.CMQCFC.MQIACH_CHANNEL_TYPE: channel_type}

qmgr = pymqi.connect(queue_manager, channel, conn_info)

pcf = pymqi.PCFExecute(qmgr)
pcf.MQCMD_CREATE_CHANNEL(args)

qmgr.disconnect()

Notes:

  • Instances of pymqi.PCFExecute class have direct access to all PCF administrative MQ commands. The commands expect a dictionary of parameters describing the properties of MQ objects which need to be manipulated. All commands and appropriate parameters may be looked up in modules pymqi.CMQC, pymqi.CMQXC and pymqi.CMQCFC.
  • The code above is equivalent to following MQSC command: DEFINE CHANNEL(MYCHANNEL.1) CHLTYPE(SVRCONN).

How to define a queue

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
conn_info = '%s(%s)' % (host, port)

queue_name = 'MYQUEUE.1'
queue_type = pymqi.CMQC.MQQT_LOCAL
max_depth = 123456

args = {pymqi.CMQC.MQCA_Q_NAME: queue_name,
        pymqi.CMQC.MQIA_Q_TYPE: queue_type,
        pymqi.CMQC.MQIA_MAX_Q_DEPTH: max_depth}

qmgr = pymqi.connect(queue_manager, channel, conn_info)

pcf = pymqi.PCFExecute(qmgr)
pcf.MQCMD_CREATE_Q(args)

qmgr.disconnect()

Notes:

  • Instances of pymqi.PCFExecute class have direct access to all PCF administrative MQ commands. The commands expect a dictionary of parameters describing the properties of MQ objects which need to be manipulated. All commands and appropriate parameters may be looked up in modules pymqi.CMQC, pymqi.CMQXC and pymqi.CMQCFC.
  • The code above is equivalent to following MQSC command: DEFINE QLOCAL(MYQUEUE.1) MAXDEPTH(123456).

How to display channels

import logging

import pymqi

logging.basicConfig(level=logging.INFO)

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
conn_info = '%s(%s)' % (host, port)

prefix = 'SYSTEM.*'

args = {pymqi.CMQCFC.MQCACH_CHANNEL_NAME: prefix}

qmgr = pymqi.connect(queue_manager, channel, conn_info)
pcf = pymqi.PCFExecute(qmgr)

try:
    response = pcf.MQCMD_INQUIRE_CHANNEL(args)
except pymqi.MQMIError as e:
    if e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_UNKNOWN_OBJECT_NAME:
        logging.info('No channels matched prefix `%s`' % prefix)
    else:
        raise
else:
    for channel_info in response:
        channel_name = channel_info[CMQCFC.MQCACH_CHANNEL_NAME]
        logging.info('Found channel `%s`' % channel_name)

qmgr.disconnect()

Notes:

  • PCF calls that read MQ objects' definition or status, and MQCMD_INQUIRE_CHANNEL among them, return a list of dictionaries, items of which describe the particular objects queried for.
  • The code above is equivalent to following MQSC command: DIS CHANNEL(SYSTEM.*).

How to display queues

import logging

import pymqi

logging.basicConfig(level=logging.INFO)

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
conn_info = '%s(%s)' % (host, port)

prefix = 'SYSTEM.*'
queue_type = pymqi.CMQC.MQQT_MODEL

args = {pymqi.CMQC.MQCA_Q_NAME: prefix,
        pymqi.CMQC.MQIA_Q_TYPE: queue_type}

qmgr = pymqi.connect(queue_manager, channel, conn_info)
pcf = pymqi.PCFExecute(qmgr)

try:
    response = pcf.MQCMD_INQUIRE_Q(args)
except pymqi.MQMIError as e:
    if e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_UNKNOWN_OBJECT_NAME:
        logging.info('No queues matched given arguments.')
    else:
        raise
else:
    for queue_info in response:
        queue_name = queue_info[pymqi.CMQC.MQCA_Q_NAME]
        logging.info('Found queue `%s`' % queue_name)

qmgr.disconnect()

Notes:

  • PCF inquiries, MQCMD_INQUIRE_Q including, return a list of dictionaries, items of which describe the particular objects queried for.
  • The code above is equivalent to following MQSC command: DIS QMODEL(SYSTEM.*).

How to use query filters

import logging

import pymqi

logging.basicConfig(level=logging.INFO)

qmgr = pymqi.connect(queue_manager, channel, conn_info)
pcf = pymqi.PCFExecute(qmgr)

attrs = {
    CMQC.MQCA_Q_NAME :'*',
    CMQC.MQIA_Q_TYPE : CMQC.MQQT_LOCAL,
    CMQCFC.MQIACF_Q_ATTRS : CMQC.MQCA_Q_NAME
}

filter1 = pymqi.Filter(CMQC.MQCA_Q_DESC).like('IBM MQ *')
filter2 = pymqi.Filter(CMQC.MQIA_CURRENT_Q_DEPTH).greater(2)

result = pcf.MQCMD_INQUIRE_Q(attrs, [filter1, filter2])

logging.info('Result is %s', result)

Notes:

  • String and integer filters can be applied when looking up MQ objects.
  • Filters are AND-joined.
  • In the example above, only queues whose description starts with 'IBM MQ' and whose depth is greater than 2 will be returned.

How to ping the queue manager

import pymqi

queue_manager = 'QM1'
channel = 'DEV.APP.SVRCONN'
host = '127.0.0.1'
port = '1414'
conn_info = '%s(%s)' % (host, port)

qmgr = pymqi.connect(queue_manager, channel, conn_info)

pcf = pymqi.PCFExecute(qmgr)
pcf.MQCMD_PING_Q_MGR()

qmgr.disconnect()

Notes:

  • Not all PCF commands require input parameters, MQCMD_PING_Q_MGR is one such an argument-less command.