Click here to Skip to main content
15,880,891 members
Articles / Programming Languages / C#

.NET IBM MQ Series Adapter

Rate me:
Please Sign up or sign in to vote.
3.83/5 (12 votes)
2 Apr 2009CPOL2 min read 87.9K   1.7K   16   18
A custom component to help connect to the IBM MQ series server.

Introduction

As part of integration between systems and legacy systems, you may have to deal with different platforms. The point of business integration is to connect different computer systems, diverse geographical locations, and dissimilar IT infrastructures so that a seamless operation can be run. A spread wide platform is IBM MQ series. IBM MQ Series supplies communication between applications, or between users and a set of applications on dissimilar systems. It has grown in popularity as applications are made available over the Internet because of its support of over 35 platforms and its ability to integrate disparate automation systems. For more details, check the IBM website: http://www-01.ibm.com/software/integration/wmq/.

Background

To start with this article, you have to be familiar with asynchronous communication, messaging platform basics, the Microsoft .NET framework, and Microsoft C#.NET.

Using the code

This IBM MQ series example works as follows: we have two main components, MQAdapter and Utilities. MQAdapter contains all the classes responsible for defining MQ Series Queue managers, channels properties, opening and closing connections, and executing Push and Pop functionalities. Also, we have our custom exception handling responsible for wrapping the MQ errors into readable errors for logging and auditing.

MQAdapter class: Contains a constructor to instantiate a new instance from the MQ adapter which takes multiple parameters.

C#
public MQAdapter(string mqManager,string channel, string ipAddress,string putQueue, 
                 string getQueue,int timeout, int charSet, int port)
{
    try
    {
        // IBM MQ Series server address
        MQEnvironment.Hostname = ipAddress;
        // server channel name
        MQEnvironment.Channel = channel;
        MQEnvironment.Port = 1000;
        mqQueueManagerName = mqManager;
        mqRequestQueueName = putQueue;
        mqResponseQueueName = getQueue;
        characterSet = charSet;
        pollingTimeout = timeout;
        // Connect to an MQ Manager, and share the connection handle with other threads
        mqQueueManager = new MQQueueManager(mqManager,channel, ipAddress);
        // Open Queue for Inquiry, Put Message in, and fail if Queue Manager is stopping
        mqPutQueue = mqQueueManager.AccessQueue(putQueue, MQC.MQOO_INQUIRE | 
        MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING|MQC.MQOO_SET_IDENTITY_CONTEXT);
        mqGetQueue = mqQueueManager.AccessQueue(getQueue,MQC.MQOO_INPUT_AS_Q_DEF + 
                                                MQC.MQOO_FAIL_IF_QUIESCING);
    }
    catch (MQException mqe)
    {
        throw new MQAdapterException("Error Code: " + 
              MQAdapterErrorReasons.GetMQFailureReasonErrorCode(mqe.Reason));
    }
}

Push MQ Message: This function is responsible for connecting to the MQ Server and pushing messages into the supplied put queue.

C#
public string PushMQRequestMessage(string message)
{
    try
    {
        MQMessage requestMessage = new MQMessage();

        requestMessage.Persistence = 0;

        requestMessage.ReplyToQueueName = mqResponseQueueName;
        requestMessage.ReplyToQueueManagerName = mqQueueManagerName;

        requestMessage.Format = MQC.MQFMT_STRING;
        requestMessage.CharacterSet = characterSet;
        requestMessage.MessageType = MQC.MQMT_REQUEST;
        requestMessage.MessageId = HexaDecimalUtility.ConvertToBinary(GenerateMQMsgId());
        requestMessage.CorrelationId = requestMessage.MessageId;

        MQPutMessageOptions pmo = new MQPutMessageOptions();
        pmo.Options = MQC.MQPMO_SET_IDENTITY_CONTEXT;

        requestMessage.WriteString(message);

        mqPutQueue.Put(requestMessage, pmo);
        string _msgId = BinaryUtility.ConvertToHexaDecimal(requestMessage.MessageId);

        return _msgId;

    }
    catch (MQException mqe)
    {
        // Close request Queue if still opened
        if(mqPutQueue.OpenStatus)
            mqPutQueue.Close();
        // Close Queue manager if still opened
        if(mqQueueManager.OpenStatus)
            mqQueueManager.Close();

        throw new MQAdapterException("Error Code: " + 
                    MQAdapterErrorReasons.GetMQFailureReasonErrorCode(mqe.Reason));
    }
}

POP MQ Message: This function is responsible for connecting to the MQ Server and to pop a MQ Message (FIFO).

C#
public string GetMQResponseMessage(string correlationId)
{
    MQMessage rsMsg = new MQMessage();
    rsMsg.CorrelationId = HexaDecimalUtility.ConvertToBinary(correlationId);
            
    MQGetMessageOptions gmo = new MQGetMessageOptions();
    gmo.Options = MQC.MQGMO_WAIT;
    gmo.MatchOptions = MQC.MQMO_MATCH_CORREL_ID;
    gmo.WaitInterval = pollingTimeout;

    try
    {
        mqGetQueue.Get(rsMsg,gmo);
        return rsMsg.ReadString(rsMsg.DataLength);
    }
    catch(MQException mqe)
    {
        // Close Reponse Queue if still opened
        if(mqGetQueue.OpenStatus)
            mqGetQueue.Close();
        // Close Queue manager if still opened
        if(mqQueueManager.OpenStatus)
            mqQueueManager.Close();
                
        // Check if it a timeout exception
        if(MQAdapterErrorReasons.GetMQFailureReasonErrorCode(mqe.Reason) == 
                      "MQRC_NO_MSG_AVAILABLE")
            throw new MQAdapterTimeoutException("Message with correlation Id " + 
                      correlationId + " Timed out");

        // MQ Exception
        throw new MQAdapterException("Error Code: " + 
             MQAdapterErrorReasons.GetMQFailureReasonErrorCode(mqe.Reason));
    }
}

To correlate the request and response, and since we are using an asynchronous communication approach, you have to provide a unique key so the MQ Series can correlate the request with the response. (MQ Series supports correlation). To apply synchronous support, a SendMQRequestSync function was implemented to wait on the reply queue for a specific time to get the response.

To use the component, do as follows:

C#
MQAdapter adapter = new MQAdapter("MqmanagerName",
           "RequestChannelName","Queue.RequestName",
"Queue.ResponseName",timeout,characterset, port);
adapater.SendMQRequestSync(strMessage);

The execution flow will be:

  1. Open a connection to the MQ Server.
  2. Push the MQ request into the request queue.
  3. Pop the MQ response from the response queue.
  4. Wait for the timeout to expire and throw an exception.

P.S.: All MQ series exceptions will be wrapped.

History

Version 1.0.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Program Manager
Jordan Jordan
Self-motivated, creative and results-driven technology executive who is well versed and experienced in leveraging an end-to-end, holistic vision of business objectives to drive full technology / business alignment.

Skilled in grasping business needs and sudden market demand’s shifts by diving into latest business / technology trends, selecting the best fit business model / technology to create a positive reflection on revenue. His multifaceted approach has enabled him to deliver key solutions across a wide range of disciplines including design, development, UX / UI, Business Intelligence.

Technical Specialties are in .Net, Java, Spring Boot, Maven, MS SQL, Oracle, Postgesql, Redis, Javascript, Bootstrap, Angular 2.

Comments and Discussions

 
QuestionPassing parameters Pin
joey mosleh15-Jun-15 23:11
joey mosleh15-Jun-15 23:11 
QuestionERROR "IBM.WMQ.MQTrace" Pin
raffaelearduino13-Feb-12 4:34
raffaelearduino13-Feb-12 4:34 
Questionhow to write MQ contineous listner [modified] Pin
Member 297937818-Jul-11 21:21
Member 297937818-Jul-11 21:21 
GeneralCharacterSet value Pin
abdul-kader El-Husseini28-Jan-11 8:01
abdul-kader El-Husseini28-Jan-11 8:01 
GeneralRe: CharacterSet value Pin
Wael Al Wirr7-Feb-11 21:47
Wael Al Wirr7-Feb-11 21:47 
GeneralMQEnvironment.Port not working Pin
ArvindChavan17-Nov-10 19:36
ArvindChavan17-Nov-10 19:36 
GeneralRe: MQEnvironment.Port not working Pin
Wael Al Wirr7-Feb-11 22:11
Wael Al Wirr7-Feb-11 22:11 
GeneralAsynchronous messages Pin
BrunoLopes30-Aug-10 3:35
BrunoLopes30-Aug-10 3:35 
GeneralRe: Asynchronous messages Pin
Wael Al Wirr30-Aug-10 20:11
Wael Al Wirr30-Aug-10 20:11 
Questionhow to detect the connection status MQQueueManager Pin
vineet1378013-Dec-09 3:54
vineet1378013-Dec-09 3:54 
AnswerRe: how to detect the connection status MQQueueManager Pin
Wael Al Wirr13-Dec-09 4:39
Wael Al Wirr13-Dec-09 4:39 
GeneralExtra care with options Pin
mlhmlh20-Oct-09 2:32
mlhmlh20-Oct-09 2:32 
GeneralRe: Extra care with options Pin
Wael Al Wirr20-Oct-09 2:40
Wael Al Wirr20-Oct-09 2:40 
GeneralFor me an error occour... Pin
Bruno Renato31-Jul-09 4:16
Bruno Renato31-Jul-09 4:16 
GeneralRe: For me an error occour... Pin
Wael Al Wirr1-Aug-09 22:54
Wael Al Wirr1-Aug-09 22:54 
GeneralRe: For me an error occour... Pin
Bruno Renato4-Aug-09 2:28
Bruno Renato4-Aug-09 2:28 
GeneralRe: For me an error occour... Pin
Wael Al Wirr5-Aug-09 2:30
Wael Al Wirr5-Aug-09 2:30 
GeneralNice Article Pin
Mario_F15-Apr-09 15:32
Mario_F15-Apr-09 15:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.