Using Zato, it is easy to make IBM MQ queues available to Python applications - this article will lead you step-by-step through the process of setting up the Python integration platform to listen for MQ messages and to send them to MQ queue managers.
Further steps will assume that Zato and MQ Client are installed.
Now, we need to enable IBM MQ connections in your Zato server - this needs to be done in a file called server.conf, e.g. assuming that your server is in the /opt/zato/env/dev/server1 directory, the file will be in /opt/zato/env/dev/server1/config/repo/server.conf
Open the file and locate the [component_enabled] stanza
Make sure that there is an entry reading "ibm_mq=True" in the stanza (by default it is False)
Save and close the file
If the server was running while you were editing the file, use 'zato stop' to stop it
Start the server with 'zato start'
If you have more than one Zato server, all the steps need to be repeated for each one
Most Zato connection types, including IBM MQ ones, are divided into two broad classes:
Moreover, certain connection types - including IBM MQ - make use of connection definitions which are reusable pieces of configuration that can be applied to other parts of the configuration.
For instance, IBM MQ credentials are used by both channels and outgoing connections so they can be defined once, in a definition, and reused in many other places.
Note that, if you are familiar with IBM MQ, you may already know what an MQ channel is - the term is the same but the concept does not map 1:1, because in Zato a channel always relates to incoming messages, never to outgoing.
Let's configure Zato using its web-admin dashboard. We shall assume that your queue manager's configuration is the following:
But first, we will need some Python code.
Let's deploy this module with two sample Zato services that will handle messages from and to IBM MQ.
You will note two aspects:
A Zato channel service is invoked each time a new message arrives in the queue the channel listens for - there is no MQ programming involved. Note that you can mount the same service on multiple Zato channels - it means that the service is reusable and a single one can wait for messages from multiple queues simultaneously.
The other service is a producer - it uses an outgoing connection to put messages on MQ queues. Again, you just invoke a method and Zato sends your message, there is no low-level MQ programming here. Just like with channels, it can be used for communication with multiple queues at a time.
# -*- coding: utf-8 -*-
from zato.server.service import Service
""" Receives messages from IBM MQ queues.
name = 'api.mq.channel'
# Our handle method is invoked for each message taken off a queue
# and we can access the message as below.
# Here is the business data received
data = self.request.ibm_mq.data
# Here is how you can access lower-level details,
# such as MQMD or CorrelId.
mqmd = self.request.ibm_mq.mqmd
correl_id = self.request.ibm_mq.correlation_id
# Let's log the message and some of its details
self.logger.info('Data: %s', data)
self.logger.info('Sent by: %s', mqmd.PutApplName)
self.logger.info('CorrelId: %s', correl_id)
""" Sends messages to IBM MQ queues.
name = 'api.mq.producer'
# Message to send as received on input,
# without any transformations or deserialization,
# hence it is considered 'raw'.
msg = self.request.raw_request
# Outgoing connection to use
conn = 'My MQ Connection'
# Queue to send the message to
queue = 'DEV.QUEUE.2'
# Send the message
self.outgoing.ibm_mq.send(msg, conn, queue)
# And that's it, the message is already sent!
In web-admin, go to Connections -> Definitions -> IBM MQ and fill out the form as below. Afterwards, make sure to change your user's password by clicking Change password for the connection definition you have just created.
Let's create a new Zato channel to receive message sent from IBM MQ. In web-admin, create it via Connections -> Channels -> IBM MQ. In the Service field, use the channel service deployed earlier.
We have configured everything as far as Zato goes and we can try it out now - let's start with channels. We can use IBM's MQ Explorer to put a message on a queue:
As expected, here is an entry from the Zato server log confirming that it received the message:
The next step is to send a message from Zato to IBM MQ. We already have our producer deployed and we need a way to invoke it.
This means that the producer service itself needs a channel - for instance, if you want to make it available to REST clients, head over to these articles for more information about using REST channels in Zato.
For the purposes of this guide, though, it will suffice if we invoke our service from web-admin. To that end, navigate to Services -> Find "api.mq.producer" -> Click its name -> Invoker, and a form will show.
Enter any test data and click Submit - data format and transport can be left empty.
The message will go to your service and Zato will deliver it to the queue manager that "My MQ Connection" uses. We confirm it using MQ Explorer again:
At this point, everything is already configured but we can still go one better. It is often useful to be able to send test messages to queue managers directly from servers, without any service, which is exactly what can be done from an outgoing connection's definition page, as in these screenshots:
Note that the message is sent from a Zato server, not from the dashboard - the latter is just a GUI that delivers your message to the server. This means that it is a genuine test of connectivity from your servers to remote queue managers.
Finally, it is worth to keep in mind that there are two server log files with details pertaining to communication with IBM MQ:
With that, we conclude this blog post - everything is set up, tested and you are ready to integrate with IBM MQ in your Python projects now!