This article is designed to provide a basic understanding of messaging from IBM perspective through the explanation of some basic functionalities of WebSphere MQ. The document is divided into three main parts:

a. Introduction to messaging: this is covered in sections 3 - 4.5. You can skip this part if you have a past experience with MSMQ.

b. Interacting with WebSphere MQ: this is covered in sections 4.6 - 8, and will provide you with sufficient knowledge that will allow you to interact with WebSphere MQ (IBM MQSeries).

c. Appendixes: this is covered in section 9, and to be used as a reference for part two.

Message queuing has been used in data processing for many years. It is most commonly used today in electronic mail. Without queuing, sending an electronic message over long distances requires every node on the route to be available for forwarding messages, and aware of the fact that you are trying to send them a message. In a queuing system, messages are stored at intermediate nodes until the system is ready to forward them or process them.

Even so, many complex business transactions are processed today without queuing. If this is the case; then why do we need queuing? Think about a system consisting of multiple nodes, where those nodes need to communicate with each other. If one node of the system suffers a problem, many nodes could become unusable.

In a message queuing environment, each program from the set that makes up the system is designed to perform a well-defined, self-contained function in response to a specific request. To communicate with another program, a program must put a message on a predefined queue. The other program retrieves the message from the queue, and processes the message. So message queuing is a style of program-to-program communication.

Queuing is the mechanism by which messages are held until an application is ready to process them. Queuing allows you to:

Communicate between programs (which may each be running in different environments) without having to write the communication code.

Select the order in which a program processes messages.

Balance loads on a system by arranging for more than one program to service a queue when the number of messages exceeds a threshold.

Increase the availability of your applications by arranging for an alternative system to service the queues if your primary system is unavailable.

A message queue, referred to as a queue, is a named destination to which messages can be sent. Messages accumulate on queues until they are retrieved by programs that service those queues. Queues reside in, and are managed by, a queue manager. A queue can either be a volatile buffer area in the memory of a computer, or a data set on a permanent storage device, such as a disk. The physical management of queues is the responsibility of the queue manager and is not made apparent to the participating application programs.

Programs access queues only through queue manager. They can open a queue, put messages, get messages, and they can close the queue. They can also set, and inquire about, the attributes of queues.

A queue manageris a system program that provides queuing services to applications. It exposes an API that would allow programs to put, and get messages from queues. A queue manager provides additional functions that would provide administrators with the ability to create new queues, alter the properties of existing ones, and control the operation of the queue manager.

For the queuing services to be available on a system; there must be a queue manager running On OS/400, z/OS, OS/2, Windows systems, UNIX, or some other supported operating system. You can have more than one queue manager running on a single system (for example, to separate the testing environment from the production one). To an application, each queue manager is identified by a connection handle(Hconn).

Many different applications can make use of the queue manager’s services at the same time and these applications can be entirely unrelated. For a program to use the services of a queue manager, it must establish a connection to that queue manager. For applications to be able to send messages to applications that are connected to other queue managers, queue managers must be able to communicate among themselves. WebSphere achieved this by implementing a store-and-forwardprotocol to ensure the safe delivery of messages between such applications.

Applications can use the first three types of messages to pass information between themselves. The fourth type, report, is for applications and queue managers to report information about events such as the occurrence of an error.

You should use a datagramwhen you do not require a reply from the application that receives the message. An example of an application that could use datagrams is one that displays flight information on the airport screens periodically.

You should use a request messagewhen you expect a reply from the application that receives the message. An example of an application that could use request messages is one that displays the balance of an account. The request message could contain the number of the account, and the reply message would contain the account balance. If you want to link your reply message with your request message, there are two options:

You can give the application that handles the request message the responsibility of ensuring that it puts information into the reply message that relates to the request message.

You can use the report field in the message descriptor of your request message to specify the content of the MsgId and CorrelId fields of the reply message:

You can request that either the MsgId or the CorrelId of the original message is to be copied into the CorrelId field of the reply message (the default action is to copy MsgId).

You can request that either a new MsgId is generated for the reply message, or that the MsgId of the original message is to be copied into the MsgId field of the reply message (the default action is to generate a new message identifier).

You should use a reply messagewhen you reply to another message. When you create a reply message, you should respect any options that were set in the message descriptor of the message to which you are replying. Report options specify the content of the message identifier (MsgId) and correlation identifier (CorrelId) fields. These fields allow the application that receives the reply to correlate the reply with its original request.

In WebSphere MQ applications, when a program receives a message that asks it to do some work, the program usually sends one or more reply messages to the requester. To help the requester to associate these replies with its original request, an application can set a correlation identifierfield in the descriptor of each message. Programs should copy the message identifier of the request message into the correlation identifier field of their reply messages.

A channelis a communication link used by queue managers. There are two categories of channel in WebSphere MQ, and we can describe them as control channels and data channels:

Messagechannels, which are unidirectional, and transfer messages from one queue manager to another.

Message Queue Interface (MQI)channels, which are bidirectional, and transfer control calls from a WebSphere MQ client to a queue manager, and responses from a queue manager to a WebSphere MQ client. We will not spend more time on this part since it is out of the scope of this article.

Classesrepresenting MQ concepts such as queue managers, queues, and messages.

Methodson each class corresponding to MQI calls.

Propertieson each class corresponding to attributes of MQ objects.

And provides the following set of classes:

Class Name

Description

MQQueueManager

An object of the MQQueueManager class represents a connection to a queue manager. It has methods to Connect(), Disconnect(), Commit(), and Backout() or what we call “rollback” . It has properties corresponding to the attributes of a queue manager. Note that accessing a queue manager attribute property implicitly connects to the queue manager if not already connected.

MQQueue

An object of the MQQueue class represents a queue. It has methods to Put() and Get() messages to and from the queue. It has properties corresponding to the attributes of a queue. Note that accessing a queue attribute property, or issuing a Put() or Get() method call, implicitly opens the queue.

MQMessage

An object of the MQMessage class represents a message to be placed on a queue or to be retrieved from a queue. It encapsulates both application data and MQMD, along with having properties corresponding to MQMD fields, and methods that allow you to write and read user data of different types (for example, strings, long integers, short integers, byte).

MQPutMessageOptions

An object of the MQPutMessageOptions class represents the MQPMO structure. It has properties corresponding to MQPMO fields.

MQGetMessageOptions

An object of the MQGetMessageOptions class represents the MQGMO structure. It has properties corresponding to MQGMO fields.

A WebSphere MQ client is part of the WebSphere MQ product that can be installed on a separate machine from the base product and server and acts as a proxy between that machine and the server. You can run a WebSphere MQ application on a WebSphere MQ client and it can interact with one or more WebSphere MQ servers and connect to their queue managers by means of a communications protocol.

The MQI is available to applications running on the client platform; the queues and other WebSphere MQ objects are held on a queue manager that you have installed on a server machine. An application that you want to run in the WebSphere MQ client environment must first be linked with the relevant client library. When the application issues an MQI call, the WebSphere MQ client directs the request to a queue manager, where it is processed and from where a reply is sent back to the WebSphere MQ client.

An application running in the WebSphere MQ client environment runs in synchronous mode because there must be an active connection between the client and the server machines. The connection is made by an application issuing an MQCONN or MQCONNX calls. Clients and servers communicate through MQI channels. When the call succeeds, the MQI channel remains connected until the application issues a MQDISC call. This is the case for every queue manager that an application needs to connect to.

After installing the software you need to go and configure the MQ client. There are multiple ways of performing the configurations; the easiest and most straight forward one is by adding a system wide environment variable called MQSERVER and assigning to it the channel name, protocol used, server address and port in the following format:

MQSERVER=ChannelName/Protocol/server_address(port)

For example:

MQSERVER=GI_HUB_SVCON/TCP/172.21.106.14(1414).

To perform this on windows-XP right-click on my computer and select properties, then click over the Advanced tab.

<!--

-->

Then click on the Environment Variables button.

<!--

-->

Under system variables, click on the New button; a screen will popup asking you to provide the variable name and its value.

<!--

-->

Then click over the OK button. Remember to restart the machine or the system will not be able to catch the variable you’ve just added.

Below you will find a ready-to-use class with comments showing you how to drop and receive messages from WebSphere MQ. All what you have to do is to add a reference to IBM.WMQ namespace which exists in amqmdnet.dll, if you install MQ client on the default directory; you will find amqmdnet.dll under C:\Program Files\MQSeries Client\bin.

One of the annoying things about the .NET implementation is that whenever the system raise an exception and you examined the “CompCode” (stands for completion code), and “Reason” properties of the MQException object, they will always provide you with a number that you have to lookup to know exactly what went wrong.

CompCode can have one of three values:

0 : Successful completion.

1 : Warning (partial completion).

2 : Call failed

When the value of CompCode is not equal to 0 you need to go and examine the Reason property which will give you another number that you can lookup in Appendix B for a basic explanation of the code, for more details you can refer to IBM WebSphere Messages Document.

This code can be used whenever a need arise to interface with WebSphere MQ from a .NET client code. Those clients include but not limited to BizTalk 2004, CMS 2002, SPS 2003, or any custom .NET application. It has been tested with Windows-XP and Windows 2003 and in both cases it was working without problems.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

I started working with .NET since it was Beta 1. I then joined Microsoft and had the chance to work with multiple technologies including BI, Portals, and Integration. I am working now at Microsoft as a Senior Development Consultant focusing on portals, and hopefully I will go back to my old love, Integration

I loved your solution. However in your solution the GET function needs a messageid which means that you can only GET those messages from the MQ , which you have created or put into the queue, however how can we establish connection and GET ANY MESSAGES that arrive at our QUEUE ?

I realize this article is quite old, but I have been having trouble finding more current examples of using IBM's .NET assembly. In the C# example, it defines a class:

publicclass MQAdapter

In that class there are private member variables:

// The name of the queue where you will be dropping your messages.privatestring InQueName;
// The name of the queue where you will be getting your messages.privatestring OutQueName;

However, there are no public properties or other code that ASSIGNS them, even though they are used in some places (I did a "Find all references" search to be sure.) I cannot see how this code could function as a valid, working example for MQ. As I said, I know the article is old, but I have had trouble finding anything more up-to-date, and IBM's web site is of little help.

Anyone know why this code is written the way it is, or if there are some more current, valid examples somewhere?

As per our current set up we are not passing any user id to connect but due to security concerns now we need to pass user id to connect to queue manager.Code is written in VB6.I have set MQSERVER variable with manager name and port name. Rest all the details are passing through code.

Actually application is running under "uprabc" but "bagabc" is the user id which authorised to connect.
SO i passed "bagabc" as alternate user id but i am getting 2035 error and as per logs uprabc id is getting passed. Please help in understanding where i am making a mistake or any step i missed.

I'm working on the migration of a VB6.0 application to VB.net.
The application talks to an MQSeries queue and in doing so makes heavy use of MQAI calls like mqAddInquiry, mqAddInteger, mqAddString, mqBagToBuffer etc.

Can you please let me know what is the .net equivalent of these calls?

I have a windows service which gets messages from an MQ queue and updates a db. The code is in C#. When the queue manager fails over to a standby server the client is not reconnecting automatically.

It seems like it is listening to the old location for messages. The error logs gives an error code of 2009. I am not using the physical server name while connection rather i am giving the queuemanager name.

The version of MQ that i am using is 6. I came to know that in MQ version 7 there is an option to reconnect if the queuemanager failsover.

I found that in V6 and V7 of the MQ Messaging Library for .NET, the readme file states:

(WMQ) User authentication for WMQ is performed by using the details of the
logged on user and not the information provided in the XMSC.USERID and
XMSC.PASSWORD fields. This is the current design intention for consistency
with WMQ. Please see the WMQ user documentation for further details of
authentication.

I found that if you "impersonate" a windows user at runtime that is the same username of the MQ server before creating the MQQueueManager, it works!

By adjusting this sample code from MS (http://support.microsoft.com/kb/306158) you can easily accomplish the impersonation.

I am replying to your response since it is the most recent. I have little or no knowledge of MQ.

Is it OK to assume that this can only handle a request/response if .Net is the consumer of the message?

Can this code be utilized for a fire and forget scenario from IBM MF MQ to the .Net solution.

More importantly, how do I use this code?

1) Assuming I instanciate this class, how do I establish connection to acquire data
2) When do I make the public function calls and in what order if necessary.
3) At what stage do I do the impersonation

Hi,
I am IBM Websphere Newbie. I have set up MQ 7.01. I would like to try this example but what MQ objects should I create? And why use a channel instead of connection to a queue? Can I just connect to a queue with the code in this example? Or what channels do I need to create?

Hi,
Wondering if its possible to use this approach to place messages on the que to send to a was server. Bassically instead of using http to transfer the soap message i need to place it on the que instead and have another program at the other end take it of and use it.

My problem is i'm not to sure how to get eh entire soap message on to the Que.

Hi all,
I am trying to make a C# application which can talk to MQseries.
As per a IBM document, there are two ways of doing it,one using client connection and other is using server binding.
Teh article says that server binding is faster compared to client connection.
i couldn't understand why it is so in reality(is it bypassing TCP channel and creating its own native channel and port for itself).
I understand that in this article, we are using server binding.

So for server binding, do we need to configure something inside the MQclient like queue manager, or only the code will take care of everything.
Please help me in understanding these two things.

Thanks for the excellent article! We are trying to use MQSeries to connect to Mainframe from our custom developed .NET applications (to be developed in Windows XP SP2 and deployed on a Windows Server 2003) and I have a few basic questions on the same. This is the first article I referenced on MQSERIES and some of these questions may sound ridiculous (Sorry!).

1) As part of the installation, can we have just the WebSphere MQ Client at the Windows end (that hosts our .NET application) and have the MQ Product installed on the Z/OS (Mainframe) or do we have to install the full product on both ends? Reading thru u r article, I get the impression that the environment variable (MQSERVER) on windows has the necessary information to connect to Mainframe.

2) Do we need to define separate Queue Managers on both Mainframe and Windows? Or is it that we could programmatically (using .NET) connect to the Queue Manager on the Mainframe?

3) We have a situation where the request could be initiated from either the Mainframe or at the Windows end? I suppose, that would mean, we may have to maintain separate Queue Managers (please clarify this as I am not sure) at both ends. For instance, if the request is to be initiated on the windows end, can we still do it with just the Websphere MQ Client on the windows?

4) Our requirement mandates that if we have a request/message sent over from Windows (our .NET code) into Mainframe, we need to wait for sometime (some processing is being done in Mainframe before the results are sent back) before we initiate the REPLY for that request (may take uptil a MINUTE or so). Can we do that or do we need to initiate a separate DataGram message (we don't need a reply to this one - equivalent of a request/reply) to achieve this?

In this scenario, you are using the Websphere MQ Series Client software to connect to the mainframe. A good reference manual in a scenario where you connect to an iSeries can be found here: http://publib.boulder.ibm.com/iseries/v5r2/ic2924/books/csqzaf05.pdf

Have a look also at this
http://www-1.ibm.com/support/docview.wss?rs=171&uid=swg24011756&loc=en_US&cs=utf-8&lang=en and this
http://www-1.ibm.com/support/docview.wss?rs=171&uid=swg24006105&loc=en_US&cs=utf-8&lang=en

As an answer on your 1st question, yes, you only need to install the MQ Client on the client side, and properly configure your environment variables to connect to the MQ Server on your mainframe.

2. Generally speaking if you only have one mainframe, entreprises have one production queue manager, one for development and one for QAT testing. As usual, it depends on the purpose and infrastructure you are currently using. If you are using multiple mainframes which does have each there own queue managers, then it is obvious that you have multiple queue managers. The best practice here is to put them in the same cluster.

3. The principle in the client/server design is that the client is connecting to the queue manager using the MQCONN call, it's opening a queue using the MQOPEN call, get message(s) from the queue with the MQGET call (you can wait infinitely for a message if you set the Delay parameter in the MQGET call), once you retrieved all your messages you close from the queue using MQCLOSE and finally disconnect from the queue manager using MQDISC

The server cannot initiate a connection to the client, it is the client that need to wait until a message appears on the queue, which can be initiated by the server.

4. If you want to wait for a reply, you need to to a MQCONN-MQOPEN-MQPUT-MQGET-MQCLOSE-MQDISC. When you do the MQGET on the client side aftee you have put the message to the queue using the MQPUT, you need to use the value of the Message Id field, which is populated after you did the MQPUT. The value from the MessageId you use in the Correlation Id parameter to use during the MQGET call, and set the delay parameter for example to 30 seconds. On the server side, you have to ensure that you put the message id in the correlation id.

If there is no response from the server within the selected 30 seconds, the MQGET call will return with 'No Message' that you need to handle appropriate in your .NET code.

Hopes this helps, there is plenty of information on the Internet or IBM site