Click here to Skip to main content
11,702,939 members (60,279 online)
Click here to Skip to main content

.NET IBM MQ Series Adapter

, 2 Apr 2009 CPOL 44.2K 1.3K 16
Rate this:
Please Sign up or sign in to vote.
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.

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.

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).

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:

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)

Share

About the Author

Wael Al Wirr
Program Manager INVESTBANK
Jordan Jordan
Wael Al Wirr’s Specialties:
•Microsoft BizTalk Server 2004, 2006, 2010
•ASP.Net, C#, ADO.Net and .Net Framework (1.1, 2.0, 3.0, 3.5, 4.0)
•Windows Communication Foundation
•Windows Workflow Foundation
•Windows AppFabric
•ADO.NET Entity Framework
•Microsoft Line Of Business Adapter Framework
•SQL Server 2000, 2005
•Web development
•HTML, XML, XSD, XSLT
•JavaScript
•Database design
•Web Services
•Build, deployment script
•Microsoft Source Safe, Microsoft Team Foundation Server

You may also be interested in...

Comments and Discussions

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

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150819.1 | Last Updated 2 Apr 2009
Article Copyright 2009 by Wael Al Wirr
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid