Archive

Posts Tagged ‘WebSphere MQ’

PCF/MQAI filters with WebSphere MQ and Python

April 16th, 2011 Dariusz Suchojad 2 comments

I’ve just pushed a new feature to the lp:~pymqi-dev/pymqi/string-filter branch that makes it possible to use WebSphere MQ PCF/MQAI filters with Python. That should be a nice addition if anyone’s thinking of creating cross-platform open-source equivalents of various Windows-only freeware support packs there are already available. Or just for anyone writing slightly more advanced code for administering MQ objects.

So how does it work?

You sure remember how to use PCFExecute, right? Well, the class has just been extended and now accepts a new parameter, a list of filters to use when querying MQ objects. The API has been more or less inspired by how Django’s QuerySets look like which basically means it’s a higher level one then what you’d be normally using with plain MQ verbs. See for yourself, the code below fetches all the queues that have a description starting with a ‘WebSphere MQ Selection*’ pattern and the current depth of 10 and greater:

import pymqi, CMQC, CMQCFC
 
queue_manager = 'QM01'
channel = 'SVRCONN.1'
host = '192.168.1.139'
port = '1434'
conn_info = '%s(%s)' % (host, port)
 
qmgr = pymqi.connect(queue_manager, channel, conn_info)
pcf = pymqi.PCFExecute(qmgr)
 
attrs = {CMQC.MQCA_Q_NAME :'*', CMQC.MQIA_Q_TYPE : CMQC.MQQT_LOCAL}
 
desc_filter = pymqi.Filter(CMQC.MQCA_Q_DESC).like('WebSphere MQ Selection*')
depth_filter = pymqi.Filter(CMQC.MQIA_CURRENT_Q_DEPTH).greater(10)
 
res = pcf.MQCMD_INQUIRE_Q(attrs, [desc_filter, depth_filter])
print(res)

It’s still a feature branch not trunk, and even if it were trunk it still hasn’t been released in PyMQI 1.3, and even then, there still would be PyMQI 1.4, so if you feel like anything should be changed or rather work differently, please speak up! Cheers!

Share

PyMQI 1.2 has been released!

March 15th, 2011 Dariusz Suchojad 3 comments

Woo hoo! PyMQI 1.2 – Python interface to WebSphere MQ – has been released and here’s an excerpt on new features taken from the release announcement:

  • Added support for MQ 7.0-style publish/subscribe
  • Added support for creating and parsing of MQRFH2 headers
  • Added new constants in the CMQZC.py module
  • Added new structures – MQSRO, MQSD, MQTM, MQTMC2
  • PyMQI now supports byte strings
  • New MQ verb – MQSUB
  • Simplified establishing connections to queue managers
  • Added means for checking whether a client application is connected to a queue manager

Special thanks to Hannes Wagener for his excellent contributions!

Links

Project’s homepage: http://packages.python.org/pymqi/
Download URL: https://launchpad.net/pymqi/+download
Usage examples: http://packages.python.org/pymqi/examples.html
Twitter: https://twitter.com/fourthrealm
Blog: http://www.gefira.pl/blog
LinkedIn: http://www.linkedin.com/groups?gid=3726448
IRC: #pymqi channel on Freenode network

Share

WebSphere MQ Administration with Python. Part I – introducing PCFExecute

March 10th, 2011 Dariusz Suchojad 4 comments

Hi and welcome to the first installment in the WebSphere MQ Administration with Python series. The goal is to introduce readers to the topic of performing admin tasks with Python and encourage those who still waver over whether to migrate all those Visual Basic or Java tools to actually start using Python, a modern, fast and cross-platform programming language.

The Python interface to MQ is called PyMQI and among many goodies it provides there’s also a very useful pymqi.PCFExecute class. PCF is, as you surely remember, a short for Programmable Command Formats, which basically means it’s an API for writing programs that are meant to automate tasks MQ admins usually do.

How does it work in Python? Well, you just need to open the appropriate MQ manual and pick any PCF command, say an MQCMD_PING_Q_MGR. The name you’ve chosen is always available as an attribute of the PCFExecute class instances, like below:

import pymqi
 
queue_manager = "QM01"
channel = "SVRCONN.1"
host = "192.168.1.139"
port = "1434"
conn_info = "%s(%s)" % (host, port)
 
qmgr = pymqi.QueueManager(None)
qmgr.connectTCPClient(queue_manager, pymqi.cd(), channel, conn_info)
pcf = pymqi.PCFExecute(qmgr)
 
# Woohoo, we've just executed our first PCF command!
pcf.MQCMD_PING_Q_MGR()
 
qmgr.disconnect()

So you just need to connect to a queue manager, create an instance of the pymqi.PCFExecute class and then you can directly invoke anything that’s listed in MQ manuals.

OK, that was easy as pinging a queue manager doesn’t require any parameters nor does it return anything. How about something less trivial, like creating a new queue with MQCMD_CREATE_Q?

import CMQC
import pymqi
 
queue_manager = "QM01"
channel = "SVRCONN.1"
host = "192.168.1.139"
port = "1434"
conn_info = "%s(%s)" % (host, port)
 
qmgr = pymqi.QueueManager(None)
qmgr.connectTCPClient(queue_manager, pymqi.cd(), channel, conn_info)
pcf = pymqi.PCFExecute(qmgr)
 
queue_name = "PYMQI.1"
queue_type = CMQC.MQQT_LOCAL
 
args = {CMQC.MQCA_Q_NAME: queue_name, CMQC.MQIA_Q_TYPE: queue_type}
 
pcf.MQCMD_CREATE_Q(args)
 
qmgr.disconnect()

MQCMD_CREATE_Q obviously needs some arguments and these are passed in wrapped in a dictionary whose keys are the same as the manual says there should be. For instance, it says that MQCA_Q_NAME and MQIA_Q_TYPE are required identifiers so I knew I could use the PyMQI’s CMQC module for looking them up. Likewise, the manual lists all the supported queue types and they also can be found in CMQC and that’s how I knew I could use CMQC.MQQT_LOCAL for the queue type. So to recap, the arguments – required and optional – are explained in the MQ documentation and you need to use PyMQI constants to form a dictionary and pass it in to the PCF command of your choice. What other modules are there in addition to CMQC? Well, there’s also CMQXC and CMQCFC and PyMQI 1.2 will introduce CMQZC – they all may be used for constructing the arguments to PCF calls.

So here it is, an introduction to PCFExecute. I plan on writing more about manipulating MQ objects, queues, channels, queue managers, aliases and so on and if you’d like to have anything covered you just need to drop me an e-mail. Thanks!

Share

Looking for a clear example of using MQSUBRQ in C?

March 9th, 2011 Dariusz Suchojad No comments

Some time ago I was in a middle of resolving an interesting issue in PyMQI while I found myself in a need of a clear example of how to use WebSphere MQ’s MQSUBRQ in C. Yea, in C this time, not in Python. I needed something that wouldn’t have been obscured by stuff like parsing of command line options or you know, anything that painfully reminds you how low-level C really is.

So I wrote the code and thought I shouldn’t be really keeping it for myself, maybe someone else will need it some day as well. Hence I’ve uploaded it all to my bitbucket repo, and if you need the sample code for MQCONNX, MQPUT, MQSUB, MQSUBRQ and then, finally, an MQGET :-) then here it is, enjoy!

And while I have your attention – you do know there’s PyMQI, the Python interface to WebSphere MQ, don’t you? So if one shiny beautiful day you find yourself weary of C then you are more than welcome to give PyMQI and Python a try!

Share
Categories: Software Tags: , , ,

Message browsing with WebSphere MQ and PyMQI

February 21st, 2011 Dariusz Suchojad No comments

I’ve noticed quite a few people hitting this blog and looking for keywords along the lines of “pymqi read a message and leave on queue” so I thought it should be explained. The thing you’re looking for is called message browsing and this post will show it in action.

Before I get into details though, I’d like to ask you for contacting me if there’s anything I can do regarding the documentation and usage examples. Really, it’s open-source so both the code and docs should shine but I’ll never know what to improve next if you don’t tell me it first :-) Checking the referrers is of course important but it won’t help much if you shun sending me your suggestions. Thanks!

So, the code is below.  The trick is composed of two parts that sort of resemble using cursors in SQL databases:

  • The queue needs to be open for browsing using the CMQC.MQOO_BROWSE option,
  • When calling queue.get, you need to pass it a proper CMQC.MQGMO_BROWSE_* option, in our simple case, there’s only one message on the queue and it just so happens that right after opening the queue for browsing, the logical cursor used for browsing is placed before the first message so we can use CMQC.MQGMO_BROWSE_NEXT and it will browse the next message which happens to be the first and the only one on the queue.

The code has been written in a form of a test case in the hope that it will make it clear that msg1 and msg2 are really equal to self.expected_msg, which is a UUID4 so we know it’s a different message on each test invocation.

I think that would be it as far as explaining the concept goes and again, don’t hesitate to contact me if you’d like me to expand on it or maybe cover something entirely else.

# stdlib
import unittest, uuid
 
# PyMQI
import CMQC, pymqi
 
queue_manager = "QM01"
channel = "SVRCONN.1"
host = "192.168.1.139"
port = "1434"
queue_name = "TEST.1"
conn_info = "%s(%s)" % (host, port)
 
class BrowsingTestCase(unittest.TestCase):
    def setUp(self):
        self.expected_msg = uuid.uuid4().hex
        self.qmgr = pymqi.QueueManager(None)
        self.qmgr.connectTCPClient(queue_manager, pymqi.cd(), channel, conn_info)
 
        self.put_queue = pymqi.Queue(self.qmgr, queue_name)
        self.put_queue.put(self.expected_msg)
        self.put_queue.close()
 
        browse_options = CMQC.MQOO_BROWSE
        self.browse_queue = pymqi.Queue(self.qmgr, queue_name,  browse_options)
        self.get_queue = pymqi.Queue(self.qmgr, queue_name)
 
    def tearDown(self):
        # Clear the queue and close all objects.
        try:
            while True:
                self.get_queue.get()
        except pymqi.MQMIError, e:
            if e.comp != CMQC.MQCC_FAILED and e.reason != CMQC.MQRC_NO_MSG_AVAILABLE:
                raise
 
        self.browse_queue.close()
        self.get_queue.close()
        self.qmgr.disconnect()
 
    def test_message_browsing(self):
 
        md = pymqi.md()
        gmo = pymqi.gmo()
        gmo.Options = CMQC.MQGMO_BROWSE_NEXT
 
        msg1 = self.browse_queue.get(None, md, gmo)
        self.assertEquals(msg1, self.expected_msg)
 
        msg2 = self.get_queue.get()
        self.assertEquals(msg2, self.expected_msg)
Share

A quick intro to WebSphere MQ & Python programming

January 31st, 2011 Dariusz Suchojad Comments off

This post will show you the basic concepts pertaining to programming asynchronous applications with WebSphere MQ (‘MQ’ from now on) and Python. MQ, in case you didn’t know it,  is a proprietary piece of software by IBM which lets you easily design and create distributed applications utilising the popular messaging patterns – queues and topics. If you’ve ever heard of RabbitMQ, ZeroMQ or similar projects then you’ll find yourself comfortable with MQ right away. Only MQ is much older and proprietary though there’s a 90-day trial version you can download from IBM’s site. I don’t know about you but I stick to the opinion that one should usually know main opensource as well as closed applications in their domain so if you’re into asynchronous programming in general, you’ll most likely find MQ an interesting subject to learn. Python isn’t (yet?) an officially IBM-blessed language for MQ programming but PyMQI, the Python bindings, has been around for about a decade and it’s extremely well field-tested, so that’s what we’ll be using.

Let’s say we have a CRM and a pair of surrounding applications, an IVR system and a self-service portal. When a customer account’s data is being changed we need to notify the other systems and we’re to use MQ for the task. Note that in reality I’d likely use a middleware construct – such as an ESB – in the middle of it all to avoid the tight coupling between the apps but the post’s about MQ so let’s turn a blind eye to it for now. There are apps and queues, each client application – one to be notified – has its dedicated queue on which it listens for messages from the CRM.

The figure below depicts the communication paths; note that even though we can say that MQ notifies the IVR and a portal about the changes, it’s actually the case that both apps need to initiate a connection to MQ and listen for incoming messages hence the arrows point towards MQ, not the other way around.

Example MQ communication. CRM sends messages to IVR.1 and PORTAL.1 queues off which the messages are being read by the IVR and a portal, respectively.

Each particular arrow represents a connection through a channel. A channel is sort of a link and a gate through which messages are being sent. There’s one channel for each application but a single channel may be reused for sending messages to more than one queue as it’s the case with CRM which puts messages onto both client applications’ queues. It’s even more than that, a single channel may be used by more that one application and that’s what the code below does – not that it’s particularly safe or sound to do it but it’s there in case that’s how you’d like things be set up – and how channels can be secured with or without Python around is a topic for one of the next posts.

For the sake of the post let’s say our environment is comprised of the following MQ objects:

  • an MQ queue manager (that is, an MQ server) named QM01, running on host 192.168.1.139, listening for connections on port 1434
  • a channel for the CRM, called CRM.SVRCONN.1,
  • a channel for the IVR, called IVR.SVRCONN.1,
  • a channel for the portal, called PORTAL.SVRCONN.1,
  • a queue for the IVR, called IVR.1,
  • a queue for the portal, called PORTAL.1

The first thing we’ll do is to connect the CRM to the queue manager over its dedicated channel and put some messages onto queues:

# stdlib
import time
 
# PyMQI
import pymqi
 
queue_manager = 'QM01'
channel = 'SVRCONN.1'
host = '192.168.1.139'
port = '1434'
message = 'New data!'
queue_names = ['CRM.1', 'IVR.1']
conn_info = '%s(%s)' % (host, port)
 
qmgr = pymqi.QueueManager(None)
qmgr.connectTCPClient(queue_manager, pymqi.cd(), channel, conn_info)
 
queues = [pymqi.Queue(qmgr, name) for name in queue_names]
 
try:
    while True:
        for queue in queues:
            queue.put(message)
            time.sleep(1)
finally:
    for queue in queues:
        queue.close()
    qmgr.disconnect()

What we’ve just achieved is obtaining a connection to MQ through a TCP channel and adding a loop which makes sure messages are trickling into each of the client queues. Note the finally block which closes any objects used in the example. Always clean up after yourself :-)

OK, let’s add the receiving part now. That’s the same code for both IVR and a portal so the name of a queue to get messages off is read from the command line.

# stdlib
import sys, optparse # (I know there's argparse but I'm stuck with 2.6)
 
# PyMQI
import pymqi, CMQC
 
queue_manager = 'QM01'
channel = 'SVRCONN.1'
host = '192.168.1.139'
port = '1434'
conn_info = '%s(%s)' % (host, port)
 
# Read the queue name from the command line
parser = optparse.OptionParser()
parser.add_option("-q", dest="queue", help="Queue to get the messages off")
(options, args) = parser.parse_args()
 
if not options.queue:
    print("Forgot to specify the queue?")
    parser.print_help()
    sys.exit(1)
 
qmgr = pymqi.QueueManager(None)
qmgr.connectTCPClient(queue_manager, pymqi.cd(), channel, conn_info)
 
queue = pymqi.Queue(qmgr, options.queue)
 
# Message Descriptor
md = pymqi.md()
 
# Get Message Options
gmo = pymqi.gmo()
gmo.Options = CMQC.MQGMO_WAIT | CMQC.MQGMO_FAIL_IF_QUIESCING
gmo.WaitInterval = 5000 # 5 seconds
 
try:
    while True:
        try:
            # Wait up to to gmo.WaitInterval for a new message.
            message = queue.get(None, md, gmo)
 
            print(message)
 
            # Reset the MsgId, CorrelId & GroupId so that we can reuse
            # the same 'md' object again.
            md.MsgId = CMQC.MQMI_NONE
            md.CorrelId = CMQC.MQCI_NONE
            md.GroupId = CMQC.MQGI_NONE
 
        except pymqi.MQMIError, e:
            if e.comp == CMQC.MQCC_FAILED and e.reason == CMQC.MQRC_NO_MSG_AVAILABLE:
                # No messages, that's OK, we can ignore it.
                pass
            else:
                # Some other error condition.
                raise
finally:
    queue.close()
    qmgr.disconnect()

I now feel the urge to mention that the client code above could’ve been written in a shorter – and  much a sloppier – way but I instead opted for showing you all the correct MQ programming patterns that make the code run with a speed close to that of a C MQ program with a minimal amount of RAM needed. That’s why the code may seem a little bit verbose but then again, even though I’m about as lazy as most Python programmers are, I don’t really have any problems with writing 3 lines of code instead of a single one if only the API doesn’t feel too contrived and baroque.

So what’s new in the client code anyway?

A Message Descriptor (MD) and Get Message Options (GMO) are one of the structures used by PyMQI to pass the relevant options to MQ layers below. That’s how you do programming with PyMQI  – and with MQ generally speaking – there are few concepts and verbs, like a queue, putting a message onto queue or getting it from it, but there are literally hundreds of customization options it all can be wrapped with. This particular GMO says that we don’t want to bail out immediately if there aren’t any messages on the queue (MQGMO_WAIT) and that we’re good MQ citizens and when the queue manager’s shutting down we will be disconnecting from it instead of leaving dangling half-open connections that prevent a queue manager from shutting down – and believe me that MQ admins will start loving you for using that option (MQGMO_FAIL_IF_QUIESCING). Then there’s gmo.WaitInterval which says how many milliseconds we intend to wait for a message before giving up and raising an exception as an indication that there has been none (for the curious one, PyMQI’s releasing GIL while waiting for messages or indeed, when calling any MQ API function).

Note there’s an inner try/except block now. What it does is catching any MQ exceptions and checking whether the exception raised isn’t trying to tell us that there have been no messages on a queue – that’s how it’s signalled to layers above, by raising an exception. The exception object, ‘e’, has two interesting properties – one is a completion code ‘.comp’, the latter one’s a reason code ‘.reason’. Basically, the completion code says if there was an error, a warning condition or if everything went fine. If there indeed was an error or a warning situation, the reason code is set to some meaningful value, such as MQRC_NO_MSG_AVAILABLE above which makes it obvious for us that well, no messages were found on a queue during that interval, and if so, we may safely ignore the exception and let it try getting the message again. In this example any other error condition is being re-raised though so that we know something went wrong. All the constants – and their meaning – can be looked up in IBM’s documentation, PyMQI is simply passing it on from MQ to our code.

As for resetting the IDs (MsgId, CorrelId and GroupId), the thing is that most options are passed to PyMQI and MQ by reference. In this context it means that some of the MD object’s attributes will be overwritten by MQ and it just so happens that

  • on a successful call to a .get, MQ sets .MsgId, .CorrelId and .GroupId values to those found in the message read,
  • we’re using the same MD object over and over in the loop,
  • if a call to a .get specifies an MD whose .MsgId, .CorrelId and .GroupId attributes are set to anything but their equivalent of None (MQMI_NONE, MQCI_NONE and MQGI_NONE respectively), MQ will be trying to get a message from a queue but only if that message’s attributes have values matching those set in the MD.

See where it takes us to? Hadn’t we been resetting the IDs, the first successful call to .get would’ve set the MD’s IDs for good and any subsequent call would’ve been trying to get new messages by those IDs, which – unless you’re trying hard, but what for – is guaranteed to never succeed, IDs are unique by default.

So that would be it as far as an introduction goes :-) I’m not even saying I haven’t covered everything about PyMQI because I’ve rather only mentioned a tiny little bit of what’s available to Python programmers. And there’s more, there’s Jython, Spring, Spring Python, JMS programming, MQ administration – PCF and MQAI, publish/subscribe and even more. Be sure to leave a comment or drop me an e-mail if there’s anything in particular you’d like to see covered!

Share

WebSphere MQ and Ubuntu HOWTO

July 3rd, 2010 Dariusz Suchojad 6 comments

(Update Jan 22, 2011 – I’ve just reproduced all the steps below on a fresh Ubuntu 10.10 install)

Until IBM finally recognizes that Ubuntu is the most popular Linux distribution and starts offering WebSphere MQ DEBs to install, here’s a small HOWTO which will guide you through the installation process. I’m using Ubuntu 9.10 and MQ 7.0.1 (CZ4VEML), both 64-bits, but it’s something I’ve been using since at least Ubuntu 7.04  I think, so it will work reliably with other versions of Ubuntu and MQ as well.

Installation

First untar the CZ4VEML.tar.gz archive and then install rpm and sharutils packages:

dsuch$ sudo apt-get install rpm sharutils

Next try executing the ./mqlicense.sh script which will most probably fail horribly but that’s OK, we’ll work around it

dsuch$ sudo ./mqlicense.sh

Accept the license if it doesn’t end with an error such as the one below ..

Exception in thread "main" java.lang.UnsatisfiedLinkError: fontmanager
(libstdc++.so.5: cannot open shared object file: No such file or directory)

.. but if it does, just read the license carefully

dsuch$ less ./licenses/LA_en

I’m assuming the script has failed but if you take a look at it closely you’ll notice that all it does in the end is to create a /tmp/mq_license/license/status.dat file, so we’ll do the same ourselves a couple of times.

Now comes the runtime, preceded by the manual creation of the file which ./mqlicense.sh failed to create.

dsuch$ sudo mkdir -p /tmp/mq_license/license/
dsuch$ sudo touch /tmp/mq_license/license/status.dat
dsuch$ sudo rpm -iavh --nodeps --force-debian
./MQSeriesRuntime-7.0.1-0.x86_64.rpm

.. more RPMs to install ..

dsuch$ sudo mkdir -p /tmp/mq_license/license/
dsuch$ sudo touch /tmp/mq_license/license/status.dat
dsuch$ sudo rpm -iavh --nodeps --force-debian ./MQSeriesJava-7.0.1-0.x86_64.rpm
./MQSeriesClient-7.0.1-0.x86_64.rpm ./MQSeriesServer-7.0.1-0.x86_64.rpm
./MQSeriesSDK-7.0.1-0.x86_64.rpm ./MQSeriesSamples-7.0.1-0.x86_64.rpm
./MQSeriesTXClient-7.0.1-0.x86_64.rpm
 

.. and the last batch of RPMs ..

dsuch$ sudo mkdir -p /tmp/mq_license/license/
dsuch$ sudo touch /tmp/mq_license/license/status.dat
dsuch$ sudo rpm -iavh --nodeps --force-debian  ./MQSeriesMan-7.0.1-0.x86_64.rpm
./MQSeriesKeyMan-7.0.1-0.x86_64.rpm 

The newly created mqm user would sure like to use Bash by default ;-)

dsuch$ sudo usermod -s /bin/bash mqm

That’s all there is to installing, let’s send some messages now.

Verifying the installation

First change the user to mqm ..

dsuch$ sudo su - mqm

.. and create & start a QM01 queue manager:

mqm$ crtmqm QM01
mqm$ strmqm QM01

Let’s define a Q1 local queue for testing

mqm$ runmqsc QM01

Now cd to /opt/mqm/samp/bin/ which holds various precompiled utilities among which are amqsput and amqsget. By the way, the source code is in /opt/mqm/samp.

Send two messages to the Q1 queue on the QM01 queue manager and quit amsqput with Ctrl-C:

mqm$ ./amqsput Q1 QM01
Sample AMQSPUT0 start
target queue is Q1
123
zxc
^C

Now let’s use amqsget to get the messages off Q1 queue and quit with Ctrl-C again, as you can see, there are 2 messages sent there in the previous step:

mqm$ ./amqsget Q1 QM01
Sample AMQSGET0 start
message <123>
message <zxc>
^C

Removing WebSphere MQ

Use those three commands if for some reason you need to remove MQ from your system.

dsuch$ sudo rpm -qa | grep "MQSeries" | xargs sudo rpm -e --force-debian --noscripts
dsuch$ sudo rm -rf /var/mqm
dsuch$ sudo userdel mqm

That’s all folks, the rest is in the MQ documentation, using MQ on Ubuntu is in no way different to what RHEL has to offer, it’s simply Linux and everything works just fine. Except for the installer :-)

Share
Categories: Software Tags: ,

PyMQI 1.0 – Python i WebSphere MQ

December 5th, 2009 Dariusz Suchojad No comments

Zreleasowałem PyMQI 1.0, czyli interfejs do WebSphere MQ dla Pythona. Nowości w wersji 1.0 to

  • Support dla WebSphere MQ 7.0,
  • Możliwość podłączania do 64-bitowych queue managerów,
  • Domyślne buildowanie PyMQI w trybie klienckim MQ, nie w trybie bindingów,
  • Nowe stałe MQ dodane do modułu pymqi.CMQXC.

PyMQI jest dostępne na licencji Pythona, czyli krótko mówiąc może być używane do jakichkolwiek zastosowań, opensource’owych lub zamkniętych. Download wersji 1.0 jest tutaj https://launchpad.net/pymqi/+download.

Jest też nowa strona PyMQI pod adresem http://packages.python.org/pymqi/, jest tam sporo dokumentacji.

Z kolei pod adresem https://launchpad.net/pymqi jest cały kod oraz bug- i answer tracker. Zdecydowałem się przenieść kod z SVN-a do bzr w nadziei na to, że pozwoli to na łatwiejszy rozwój kodu wspólnie z innymi developerami – PyMQI to kolejny projekt, w którym bzr spisuje się bardzo dobrze i po paru miesiącach mogę powiedzieć, że jestem zadowolony z przeniesienia kodu.

Opcje supportu, zarówno darmowego jak i płatnego, a także informacja o tym, w jaki sposób zgłaszać security bugi, opisane są tutaj.

Poniżej jest przykład pokazujący jak proste jest używanie PyMQI do komunikacji z queue managerami:

# -*- coding: utf-8 -*-

import pymqi

# Namiary na MQ
qm_name = "QM.1"
queue_name = "TEST.QUEUE.1"
channel = "SVRCONN.CHANNEL.1"
conn_info = "192.168.1.121(1434)"

# Utwórzmy obiekt łączący się z MQ
qmgr = pymqi.QueueManager(None)
qmgr.connectTCPClient(qm_name, pymqi.cd(), channel, conn_info)

# Zdefiniujmy sobie obiekty łączące się z kolejkami
put_queue = pymqi.Queue(qmgr, queue_name)
get_queue = pymqi.Queue(qmgr, queue_name)

# Teraz umieśćmy komunikat w kolejce i od razu pobierzmy go
put_queue.put("Hello world")
print get_queue.get()

# Zamknijmy kolejki
put_queue.close()
get_queue.close()

Na wersję 1.1 jest przewiduję kilka nowych rzeczy, jeśli ktoś ma ochotę to zapraszam do branchowania i podsyłania patchów :-)

Share
Categories: Software Tags: ,

Prosty przykład nieklarownego procesu developmentu

September 12th, 2009 Dariusz Suchojad No comments

Spędziłem sobie właśnie kilka godzin na szukaniu błędu w kodzie, po czym okazało się, że błąd był w kodzie biblioteki, z której korzystałem, i błąd ten występuje tylko w trunku SVN-owym tejże biblioteki. Oczywiście są dwie szkoły, “kod w trunku może nie kompilować się/nie działać, stabilne są branche” i “cały rozwój jest w branchach, a trunk musi się kompilować/działać”. Osobiście jestem z tej drugiej szkoły, ale to nie ma znaczenia, ważne jest to, żeby dokumentować to, co się wybrało, proces musi być jasny. Wystarczy krótka informacja na stronie projektu w sekcji “For developers” i zaoszczędzi się innym sporo czasu. Jeśli ktoś ma ochotę na inne dobre rady na temat prowadzenia projektów i community, w szczególności opensource’owych, to zachęcam do przeczytania książki The Art of Community, napisanej przez community managera Ubuntu, bardzo pouczająca lektura.

W trakcie szukania błędu przeczytałem przy okazji release notes dla WebSphere MQ 7.0 i rozbawiła mnie informacja na temat JMS-owych bundli OSGi WMQ “The OSGi bundles shipped with WebSphere MQ classes for JMS client are not working.” Krótko i na temat. Nie mamy Pańskiego płaszcza i co nam Pan zrobi. ;-)

Share
Categories: Software Tags: , ,

MO72, czyli zdalne runmqsc

August 9th, 2009 Dariusz Suchojad No comments

Wszyscy wiedzą, że przy hurtowym tworzeniu obiektów WebSphere MQ najlepiej posługiwać się poleceniem runmqsc, raczej nikomu nie przychodzi do głowy, żeby tworzyć 300 kolejek korzystając z WebSphere MQ Explorera lub – skądinąd całkiem niezłego – support packa MO71. Co jednak zrobić gdy queue manager znajduje się w systemie z/OS? Korzystanie z paneli ISPF do utworzenia kilkuset obiektów także nie należy do ciekawych zajęć. Co prawda można zestawić połączenia proxy pomiędzy queue managerami, i np. polecenia wysyłane do queue managera na Linuksie będą forwardowane do innego queue managera uruchomionego w systemie z/OS, ale jednak wymaga to dodatkowych zabiegów administracyjnych i jest kolejną rzeczą, o której trzeba pamiętać przy konfiguracji środowisk.

Na ratunek przychodzi freeware’owy support pack MO72, udostępniający polecenie mqsc, które najłatwiej można określić jako zdalne runmqsc. Dzięki MO72 możemy wywoływać polecenia MQSC na zdalnych queue managerach, w tym także na queue managerach zainstalowanych w systemie z/OS.

Przykładowe wywołanie MO72, sprawdzające przez kanał CRM.TO.EAI.1 głębokość kolejki S/CRM.TO.EAI.1 queue managera EAI.QM.1 uruchomionego na hoście 192.168.1.79, z listenerem uruchomionym na porcie 1424  wygląda tak

C:\>mqsc -m EAI.QM.1 -l -c CRM.TO.EAI.1 -h 192.168.1.79(1424) -C “DIS QLOCAL(S/CRM.TO.EAI.1) CURDEPTH”

Powyższe polecenie zadziała jednak tylko na systemach innych niż z/OS – dla queue managerów uruchomionych na z/OS-ach wymagane jest podanie switcha -z w wywołaniu polecenia. Zakładając więc, że mamy plik “zos-objects.mqsc”, w którym znajdują się polecenia CREATE QLOCAL tworzące kilkaset obiektów, w taki oto sposób można je szybko utworzyć na z/OS-ach:

C:\>mqsc -m EAI.QM.1 -l -z -c CRM.TO.EAI.1 -h 192.168.1.79(1424) < ./zos-objects.mqsc

Prawda, że jest to wygodniejsze niż panele? ;-)

Share
Categories: Software Tags: ,