Mqseries Ibmtutorial
Mqseries Ibmtutorial
MQSeries Publish/Subscribe:
A Tutorial
Notices
The following paragraph does not apply in any country where such provisions are
inconsistent with local law
INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS
PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Some states do not allow disclaimer of express or implied warranties in certain
transactions, therefore this statement may not apply to you.
References in this publication to IBM products, programs, or services do not imply that
IBM intends to make these available in all countries in which IBM operates.
Any reference to an IBM licensed program or other IBM product in this publication is not
intended to state or imply that only IBMs program or other product may be used. Any
functionally equivalent program that does not infringe any of the intellectual property
rights may be used instead of the IBM product. Evaluation and verification of operation
in conjunction with other products, except those expressly designated by IBM, is the
users responsibility.
The information contained in this document has not be submitted to any formal IBM test
and is distributed AS IS. The use of the information or the implementation of any of
these techniques is a customer responsibility and depends on the customers ability to
evaluate and integrate them into the customers operational environment. While each
item has been reviewed by IBM for accuracy in a specific situation, there is no
guarantee that the same or similar results will be obtained elsewhere. Customers
attempting to adapt these techniques to their own environments do so at their own risk.
The following terms are trademarks of the International Business Machines Corporation
in the United States and/or other countries:
IBM
MQSeries
Windows NT is a trademark of Microsoft Corporation .
Introduction
This tutorial guides you from your first steps of creating your first MQSeries
Publish/Subscribe broker to writing your own Publish/Subscribe applications.
Following this tutorial will teach you how to :
Requirements
To complete this tutorial you will require a working knowledge of MQSeries along with
an understanding of the programming language C and experience in writing and
compiling MQSeries applications. One of the exercises requires MQSeries channels to
be defined, though this exercise can be omitted if necessary.
Before you start the tutorial check that you have the necessary level of MQSeries which
supports the publish/subscribe function. You will also need to have downloaded the
MQSeries Publish/Subscribe SupportPac for your platform. This can be found at
http://www.software.ibm.com/ts/mqseries/txppacs/ma0c.html, as can the
MQSeries Publish/Subscribe Users manual which will also need to be consulted.
When you perform the tutorial you must be logged on as a user which is authorized to
run MQSeries commands (a member of the mqm group). A C compiler will also be
required.
It is assumed that the accompanying C source files with this document have been
downloaded into a suitable place on the machine that you will be using for this tutorial,
you will need to be able to modify these files. The directory structure of these files
should be maintained, from now on we will refer to these files by there relative directory
(e.g. Tutorial/Exer3/amqssub).
All supplied Publish/Subscribe samples used in this tutorial can be found under the
standard directories for MQSeries samples for your installation of MQSeries (e.g. on
Windows NT the executable samples can be found in mqmtop\tools\c\samples\bin), all
non-executable Publish/Subscribe sample files will be found in or below the pubsub
subdirectory in the C sample directory.
-1-
-2-
strmqm QMgrName
Now we can start the broker
strmqbrk -m QMgrName
To display the status of the broker we can use the dspmqbrk command
dspmqbrk -m QMgrName
You should have seen the following message:
MQSeries message broker for queue manager QMgrName running.
The broker is now ready to receive commands and publications from MQSeries
Publish/Subscribe applications.
The first time we start the broker all the necessary default queues required by the
broker are created on the queue manager, we can display these by using runmqsc
runmqsc QMgrName
display qlocal(*)
end
All the SYSTEM.BROKER.* queues are those used by the broker, queue names
starting with SYSTEM.BROKER are reserved for use by the broker. See the MQSeries
Publish/Subscribe Users Guide for more details on the individual use of these queues.
To end the broker, without ending the queue manager, the endmqbrk command is
used, end the broker now.
endmqbrk -m QMgrName
-3-
Once this has completed the broker has been ended, this can be verified by running
dspmqbrk again.
dspmqbrk -m QMgrName
This time we should see the following message.
MQSeries message broker for queue manager QMgrName not active.
For the next exercises we will be using the broker we just created, to restart the broker
rerun the strmqbrk command.
strmqbrk -m QMgrName
We are now ready to continue with the next exercise.
-4-
amqsres QMgrName
The match simulator publishes event publications, so that the results server does not
miss any publications the results server has to of registered its subscription before any
match simulators are started. Once a message is displayed by the results server,
indicating it is okay to start the match simulator (it has successfully registered its
subscription) we can start a soccer match. From another command line, think of two
soccer teams (no spaces or double quotes () allowed in either name) and start the
match using these names as the first two parameters, if the results server, amqsres,
has already finished restart it from its command line first. Now, from another command
line in the same sample directory start the match simulator.
-5-
amqsmany QMgrName
The other main feature of this sample is that it maintains a current state of all the
matches being played, which allows the results server to be restarted after a possible
failure. The results server does this by publishing a retained message to the broker with
the latest score of each match every time the score changes. On startup of the results
server it subscribes to all these retained publications and when they are received the
current match state is restored as to how it was the last time the results server was
running.
To exercise this feature restart the script amqsmany (anqsmany.bat for Windows NT)
that we used above. Once it is running and a couple of goals have been scored you can
change to the window running the results server, amqsres, and prematurely kill that
process (using Ctrl-C). The results service can then be restarted at any time and you
will see that the matches being played will be restored to their last known score and
then updated by any remaining match changes that have occurred whilst the results
service was stopped. If, when restarting the results service, the sample fails to open the
subscriber queue for reason 2042 (MQRC_OBJECT_IN_USE) it is because we have
-6-
-7-
runmqsc QMgrName
define qlocal(SUBSCRIBER_QUEUE)
define qlocal(PUBLISHER_QUEUE)
end
The incomplete C source files have been supplied in the tutorial directories, you are
required to modify these files and compile them into executables, as with standard
MQSeries samples, when linking into an executable MQSeries library(s) must be linked,
see the MQSeries Application Programming Guide manual for details on your particular
platform. Each of the following samples consist of a single source file per executable
and should be compiled into an executable of the same name as the directory that the
source can be found in.
Publisher Project
The first sample we will complete is the publisher sample amqspub. The incomplete
source of this sample, amqspuba.c, can be found in the tutorial directory
Tutorial\Exer3\amqspub.
There are eight steps within the sample that are to be completed, work your way
through the code, understanding what is being done, when you reach an incomplete
step follow the instructions to add the correct lines of code. There is more help in the
source file in the comments preceding each step, use this in conjunction with the help
given below.
-8-
Step 1.
To be able to put publications to the brokers stream queue we must open it first,
complete the configuration of the MQOPEN command for putting messages.
Step 2.
When we publish to a broker the publication must normally start with an MQRFH
structure (the definition can be found in the MQSeries Publish/Subscribe manual). All
fields in this structure must have a defined value, a default definition of the MQRFH
structure is supplied with MQSeries, use this to initialize the fields of the MQRFH within
the message block. Some values of the MQRFH will have to be changed from their
default values before we can publish the message, we will change those later, when we
know what they will be.
Step 3.
Immediately after the defined MQRFH structure in the message block a
NameValueString must follow, this is a character string. Point the pNameValueString
pointer to the starting position of the NameValueString in the message block.
Step 4.
The contents of the NameValueString is what is used by the broker to distinguish
between different Publish/Subscribe commands and how it is to be processed. The
NameValueString of this message must contain all the required information for the
broker to recognize it as a publication and how to process it. The Publish/Subscribe
manual has information on all the recognized command messages and what
name/value pairs are required/optional, use this to help in forming a continuous
character string valid for our publications.
Step 5.
The StrucLength field of the MQRFH structure holds the length of the MQRFH structure
and its accompanying NameValueString, this tells the broker how long the
NameValueString length in this message is as the MQRFH structure is fixed in size and
the NameValueString is a variable length field. It also allows any application receiving
this message to identify where the NameValueString ends and the next structure (if
any) starts.
Alter the StrucLength field of the MQRFH to represent the size of the structure. The
broker does not require a null terminator on the end of the NameValueString but it can
make it easier for any other application that should need to read the string (if a null
terminator is present it is possible to perform string operations against it, e.g. strlen),
-9-
Step 6.
In this sample we are publishing a character string as user data in each publication, this
is a recognized MQSeries format that can be chained from the MQRFH and
NameValueString structure. The MQRFH structure must indicate that the data following
this structure is a string and also what character set it is in, alter the appropriate MQRFH
fields to show this.
Step 7.
The user data (in this case the string data) must be positioned directly after the MQFRH
and NameValueString structure, point the pUserData pointer to the starting position of
any string data we will be adding.
Step 8.
Now that a line of string data has been read from standard input we can copy it into the
publication message block. Once this has been done the publication message is
complete and is ready to be put to the brokers stream queue.
Once all the above steps have been completed the sample is ready to be compiled. If
compilation errors are displayed at this point you may have made a mistake in one or
more of your code changes, use the information in the compilation errors to try and
correct any mistakes. Once the sample compiles with no errors it is ready to be run.
At this point we do not have a subscriber sample to receive your publications but we
can still try running the sample to see if the broker accepts the publications that you
have generated. To run the publisher sample:
Subscriber Project
Now that we have a publishing sample we need a subscribing sample to subscribe to
the publishers topic and receive the publications. The sample we will complete is
amqssub and, like before, the source, amqssuba.c, can be found in directory
Tutorial\Exer3\amqssub.
There are five steps within the sample that are to be completed, work your way through
the code, understanding what has been done, when you reach an incomplete step
follow the instructions to add the correct lines of code. There is more help in the source
file preceding each step, use this in conjunction with the help given below.
The five steps to complete in the code are listed below
Step 1.
To be able to put the command messages to the broker we must first open the
appropriate queue, complete the configuration of the MQOPEN command for putting
messages to this queue.
Step 2.
In this sample we must first register our interest in a topic, so we must send a
subscription registration to the broker. Because we will be sending different commands
to the broker in this sample the function for generating a command message and
sending it to the broker has been taken out of the main line of code and put into the
function SendBrokerCommand , One of the arguments of this function is the command
string to put into the NameValueString of the command message, add the appropriate
command string for a subscription registration. (The function SendBrokerCommand
should be similar to the section of code in amqspuba.c that builds the publication
message).
Step 3.
Once we have registered as a subscriber we can wait for publications to arrive on our
subscriber queue, as they arrive we read them in using MQGET. When we have a
message we need to check that it is in the format we were expecting, not a message
put to this queue from a different sort of application. So the first thing we must to do is
check that the message is an MQRFH format message.
- 11 -
Step 4.
Now that we recognize the message as an MQRFH message we can locate the portion
of the message that we, as a subscribing application, are interested in. In our sample
we do not need to look at the NameValueString of the message, all we are interested in
is the user data that follows it, the character string. Point the character string pointer
pUserData to the start of the character string that follows the NameValueString and
print it to the screen, if the null terminator was included by the publisher the printf
function can be used.
Step 5.
We have now finished running the sample so we need to deregister our subscription
that we made earlier, as in Step 2 the command string has been left out of the call to
SendBrokerCommand, add the appropriate string for a subscription deregistration.
Once all the above steps have been completed the sample is ready to be compiled. If
compilation errors are displayed at this point you may have made a mistake in one or
more of your code changes, use the information in the compilation errors to try and
correct any mistakes. Once the sample compiles with no errors it is ready to be run.
To run this subscriber sample:
- 13 -
endmqbrk -m QMgrName
endmqm QMgrName
Now we will create a two broker hierarchy on our machine, for this we will create two
new queue managers to host the brokers. A two broker hierarchy has a parent/child
relationship, we will name the two queue managers parent and child.
As in section 1, to create and start the queue managers from the command line type
Once we have the parent and child queue managers communicating with each other we
can start the brokers. The broker on child will naturally be the child of the broker on
parent. As in Exercise 1, to start the brokers type the following commands. It is
recommended that you allow a delay of a few seconds between starting related brokers
for the first time as this allows the parent broker to be running before the child registers
with it.
strmqbrk -m parent
strmqbrk -m child - p parent
The -p option tells the child broker that parent is its parent.
We now have a broker hierarchy.
At this point we will introduce another sample that is supplied with MQSeries
Publish/Subscribe, this sample, amqspsd, is a sample system management tool. It
makes use of the administration and metatopic messages that each broker itself
publishes to provide information on the current configuration and use of a broker.
The system management sample requires a subscriber queue for it to be defined
before it is run. The MQSC script for this queue can be found in the pubsub\admin
directory under the MQSeries C sample directory. The script file is amqspsda.tst.
Run this script for each queue manager :
amqspsd -m parent
You should see output like the one below, note how the child broker should be listed
under the brokers children heading, if it is not the broker does not recognize the
second broker, there could be a problem with the channels, look for messages in the
MQSeries error logs.
- 15 -
Run the sample again, this time against the child queue manager. This time you should
see the name of the parent queue manager under the parent heading, if you do not see
this the broker does not recognize the parent broker as its parent, then again look for
messages in the MQSeries error logs.
As you can see, other information is also displayed under the subscriber heading. The
subscriptions we can see to MQ/... topics are those subscriptions currently registered
- 16 -
- 17 -
- 19 -
- 21 -
Step 1.
Build the topic string that we will be publishing on, this is unique to each match being
played, it is of the form:
Sport/Soccer/State/FinalScore/Team1 Team2
Step 2.
We call the function BuildMQRFHeader() to build the MQRFH structure and
NameValueString for the publication, two of the arguments required have been left out
of your source, the command string needed for a publication message and the
publication options for this publication (in decimal form (using the defined MQPUBO_
- 22 -
Step 3.
Finally we must add the user data to the publication, for this publication we generate a
string that will be displayed by the final score sample, the string must contain all the
details of the matches final score.
Final Score Project, amqsfin
To create the final score sample modify the source file in Tutorial\Exer5\amqsfin. This is
basically a slightly modified version of the subscriber sample from Exercise 3, this time
the source file is called amqsfina.c but it is very similar to amqssuba.c, follow the next
step to complete the final score sample. The only differences to the simple subscriber
sample is that the topic we subscribe to is defined (not a user argument) and we are not
using the default stream.
Step 1.
In the function SendBrokerCommand() build the NameValueString of the command
messages sent to the brokers control queue. This is a similar NameValueString
between the subscriber registration and deregister, the only difference being the
command string which is passed into the function as an argument. The
NameValueString must contain all the name/value pairs required for a
register/deregister of a subscriber, see the Publish/Subscribe manual for details of
these commands, remember that we are not subscribing to a topic on the default
stream so the stream name is required.
Once both of the above projects compile cleanly we can run the new samples. We will
use the single broker which we created in Exercise 1. If this has been ended then
restart it.
To run the final score sample, amqsfin, we require another queue in addition to the two
previously defined in the MQSC script amqsresa.tst, define
FINAL.SCORE.SAMPLE.QUEUE as a local queue on QMgrName, this will be the
subscriber queue used by amqsfin
runmqsc QMgrName
define qlocal(FINAL.SCORE.SAMPLE.QUEUE)
Unlike the results service it is not important when the final score sample is started as it
will receive any existing FinalScore retained publications when it is started. This time we
will start the final result sample, amqsfin, first. From the command line in the tutorial
directory Tutorial\Exer5\amqsfin, run this at the QMgrName broker.
- 23 -
amqsfin QMgrName
Now start the new results service from another command line in
Tutorial\Exer5\amqsres2, run this also at the QMgrName broker.
amqsres2 QMgrName
Finally start up one or more of the original match simulators, amqsgam, or use the
multiple match script file amqsmany (from Exercise 2) to start three at once.
The match simulator(s) and results service should perform exactly as before, once a
match ends you should see the final match score being displayed by the final score
sample.
- 24 -
endmqbrk -m child
When a broker is deleted the queues defined when the broker is first started are
removed, it is possible that some of these may be held open by the parent broker via a
channel, whilst this is true the queue cannot be deleted and thus, the broker cannot
complete the deletion. The parents hold on these queues will eventually time-out and
the child broker can then be deleted, to speed this process up we can break the
parents hold by stopping and starting the parent-to-child channel, this can be done
from runmqsc.
runmqsc parent
stop channel(parent.to.child)
start channel(parent.to.child)
end
Once this has been done we can delete the child broker.
dltmqbrk -m child
If you now use the system management sample amqspsd to display the configuration of
the parent broker you will see that the parent has no children registered.
amqspsd -m parent
To delete the parent broker we follow the same method as used for the child,
remembering to stop and start the childs channel to the parent.
End the broker running on parent.
endmqbrk -m parent
Stop and start the channel from child to parent.
- 25 -
runmqsc child
stop channel(child.to.parent)
start channel(child.to.parent)
end
Delete the broker on parent.
dltmqbrk -m parent
We have now removed both brokers from the child and parent queue managers.
- 26 -