Advanced WebSphere MQ connectivity in .NET apps, JMS without JVM

Using WebSphere MQ (still MQSeries for most of us) and the related products abbreviated WPM and alike from Microsoft .NET applications can be painstaking.

While there are enterprise application integration solutions and BizTalk Server can help quite a bit with connecting to the IBM MQ world, you are up to different tasks, when you really need native .NET code to deal with MQ directly.

Damir posted a small introduction to connecting to Websphere MQ in .NET a couple of days ago.

However, advanced WebSphere MQ scenarios will very often involve doing it the JMS way. We stumbled over this the first time when we were supposed to "only" connect to MQSeries and not to need any JMS-related things. But then we found out "oh, yes, we write our messages to topics". Topics however, are very JMSish and WebSphere MQ provides a "broker" that handles this for you. JMS was there again.
Until relatively recently, when you wanted to deal with topics, you only had options that either involved handling all the topic-logic yourself and putting together the appropriate messages manually, or you had to connect to a Java virtual machine somewhere (or even host the JVM yourself in your .NET app) and use code there. So, basically: "bummer".

IBM released the XMS.NET SupportPac in an updated version just very recently. Since links to that section change frequently it seems, I recommend using your favourite search engine for "XMS.NET" and a combination of the following terms "IBM - IA9H: IBM Message Service Client for .NET". We are dealing with a supported SupportPAC here, so as a paying customer of one of the applicable products, you can actually expect that someone cares.

The SupportPac wraps some of the built-in features of JMS for you.

Beware, the documentation is huge and there is a lot to consider.

What do you need besides of your favorite .NET tools: WebSphere MQ with at least patch-level version 6.0.1.1 (but with this you need additional hotfixes).

For the basic connectivity you have to consider the same things that Damir already talked in his post about. There are more things in regards to security, group memberships and so on, you might have to consider, but this post would explode if I would talk about that here. If you look through the API, you will find an example, but that is not very straightforward in my humble opinion. So below you find a simplified spaghetti-code version of connecting to a "topic" and consuming messages for the topic synchronously.

Beware: There are many, many options and properties that change the connection behavior completely. So, this simple example is really just one simple example for many possible scenarios that you might have.

   

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using IBM.XMS;
 
namespace XMSTest
{
    class Program
    {
        static void Main(string[] args)
        {
            XMSFactoryFactory factoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
 
            Console.WriteLine("Before create connectionfactory");
            // Use the connection factories factory to create a connection factory
            IBM.XMS.IConnectionFactory connfactory = factoryFactory.CreateConnectionFactory();
            Console.WriteLine("created connectionfactory");
            // Set the properties
            connfactory.SetStringProperty(XMSC.WMQ_HOST_NAME, "MyHostNameOrIPAddressHere");
            connfactory.SetIntProperty(XMSC.WMQ_PORT, 1414);
            connfactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT);//managed
            connfactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "MainQM");
            connfactory.SetIntProperty(XMSC.WMQ_BROKER_VERSION, XMSC.WMQ_BROKER_V1);
 
            Console.WriteLine("Before create connection");
            using (IBM.XMS.IConnection conn = connfactory.CreateConnection())
            {
                Console.WriteLine("created connection");
 
                using (IBM.XMS.ISession session = conn.CreateSession(false, AcknowledgeMode.AutoAcknowledge))
                {
                    Console.WriteLine("Before create session with topic");
                    using (IBM.XMS.IDestination dest = session.CreateTopic("topic://MyOwn.TopicHere")) // Create a topic
                    {
                        Console.WriteLine("created session with topic");
                        dest.SetIntProperty(XMSC.DELIVERY_MODE, XMSC.DELIVERY_NOT_PERSISTENT);
                        Console.WriteLine("before create consumer");
                        using (IBM.XMS.IMessageConsumer consumer = session.CreateConsumer(dest))
                        {
                            Console.WriteLine("created consumer");
 
                            // Start the connection
                            conn.Start();
                            IMessage recvMsg = null;
                            int messagesReceived = 0;
                            // Receive specified number of messages 
 
                            while (
                                   messagesReceived < Convert.ToInt32(10))
                            {
                                recvMsg = null;
 
                                // Receive the message                                    
                                try
                                {
                                    recvMsg = consumer.Receive();
                                }
                                catch (System.Xml.XmlException xmlException)
                                {
                                    // we had cases where XMS.NET throws this
                                    // exception because the received message
                                    // had a tag-name put in an encoding that
                                    // resulted in invalid XML
                                    Console.WriteLine(xmlException.ToString());
                                }
                                catch (Exception otherException)
                                {
                                    Console.WriteLine(otherException.ToString());
                                }
                                // Increment the counter
                                messagesReceived++;
 
                                if (recvMsg != null)
                                {
                                    // Display that message was received.
                                    Console.WriteLine("Received message "+messagesReceived.ToString());
                                }
                                else
                                {
                                    Console.WriteLine("Message received was null or an error occurred.");
                                }
 
                            } // end of while
                        }
                    }
                }
            }
            Console.WriteLine("End. Press Enter");
            Console.ReadLine();
        }
    }
}

   

Note that this example does not set a username. This means that the username your code is running under will be sent to WebSphere MQ. In my case I had to add an account with my Windows accountname to at least the mqm group on a Linux machine like this:

adduser –g mqm myusername

followed by

passwd myusername

to set a proper password to make sure that nobody does funny things with my account that will be created on the Linux box.

  


Posted Apr 15 2007, 04:40 AM by Andreas Erben

Comments

Damir Dobric Posts wrote Receiving of JMS Messages in .NET apps
on 04-21-2007 19:08

Few days ago Andreas described how to build interop between JMS and .NET applications based on XMS (IBM

developers.de is a .Net Community Blog powered by daenet GmbH.