C# .NET MQ Code to Subscribe to a Topic

The other day I answered a question on StackOverflow about subscribing to a topic using C# .NET code. I figured I should also post the code here for everyone to read & use.

You can download the source code from here.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using IBM.WMQ;

/// <summary> Program Name
/// MQTest82
///
/// Description
/// This C# class will connect to a remote queue manager
/// and get messages from a topic using a managed .NET environment.
///
/// Sample Command Line Parameters
/// -h 127.0.0.1 -p 1414 -c TEST.CHL -m MQA1 -t abc/xyz -u tester -x mypwd
/// </summary>
/// <author>  Roger Lacroix
/// </author>
namespace MQTest82
{
   public class MQTest82
   {
      private Hashtable inParms = null;
      private Hashtable qMgrProp = null;
      private System.String qManager;
      private System.String topicString;

      /*
      * The constructor
      */
      public MQTest82()
          : base()
      {
      }

      /// <summary> Make sure the required parameters are present.</summary>
      /// <returns> true/false
      /// </returns>
      private bool allParamsPresent()
      {
         bool b = inParms.ContainsKey("-h") && inParms.ContainsKey("-p") &&
                  inParms.ContainsKey("-c") && inParms.ContainsKey("-m") &&
                  inParms.ContainsKey("-t");
         if (b)
         {
            try
            {
               System.Int32.Parse((System.String)inParms["-p"]);
            }
            catch (System.FormatException e)
            {
               b = false;
            }
         }

         return b;
      }

      /// <summary> Extract the command-line parameters and initialize the MQ variables.</summary>
      /// <param name="args">
      /// </param>
      /// <throws>  IllegalArgumentException </throws>
      private void init(System.String[] args)
      {
         inParms = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable(14));
         if (args.Length > 0 && (args.Length % 2) == 0)
         {
            for (int i = 0; i < args.Length; i += 2)
            {
               inParms[args[i]] = args[i + 1];
            }
         }
         else
         {
            throw new System.ArgumentException();
         }

         if (allParamsPresent())
         {
            qManager = ((System.String)inParms["-m"]);
            topicString = ((System.String)inParms["-t"]);

            qMgrProp = new Hashtable();
            qMgrProp.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);

            qMgrProp.Add(MQC.HOST_NAME_PROPERTY, ((System.String)inParms["-h"]));
            qMgrProp.Add(MQC.CHANNEL_PROPERTY, ((System.String)inParms["-c"]));

            try
            {
               qMgrProp.Add(MQC.PORT_PROPERTY, System.Int32.Parse((System.String)inParms["-p"]));
            }
            catch (System.FormatException e)
            {
               qMgrProp.Add(MQC.PORT_PROPERTY, 1414);
            }

            if (inParms.ContainsKey("-u"))
               qMgrProp.Add(MQC.USER_ID_PROPERTY, ((System.String)inParms["-u"]));

            if (inParms.ContainsKey("-x"))
               qMgrProp.Add(MQC.PASSWORD_PROPERTY, ((System.String)inParms["-x"]));

            logger("Parameters:");
            logger("  QMgrName ='" + qManager + "'");
            logger("  Topic String ='" + topicString + "'");

            logger("Connection values:");
            foreach (DictionaryEntry de in qMgrProp)
            {
               logger("  " + de.Key + " = '" + de.Value + "'");
            }
         }
         else
         {
            throw new System.ArgumentException();
         }
      }

      /// <summary> Connect, open topic, get messages, close topic and disconnect. </summary>
      ///
      private void testReceive()
      {
         MQQueueManager qMgr = null;
         MQTopic inTopic = null;
         int openOptionsForGet = MQC.MQSO_CREATE | MQC.MQSO_FAIL_IF_QUIESCING | MQC.MQSO_MANAGED | MQC.MQSO_NON_DURABLE;

         try
         {
            qMgr = new MQQueueManager(qManager, qMgrProp);
            logger("successfully connected to " + qManager);

            inTopic = qMgr.AccessTopic(topicString, null, MQC.MQTOPIC_OPEN_AS_SUBSCRIPTION, openOptionsForGet);
            logger("successfully opened " + topicString);

            testLoop(inTopic);
         }
         catch (MQException mqex)
         {
            logger("CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
         }
         catch (System.IO.IOException ioex)
         {
            logger("ioex=" + ioex);
         }
         finally
         {
            try
            {
               if (inTopic != null)
                  inTopic.Close();
               logger("closed: " + topicString);
            }
            catch (MQException mqex)
            {
               logger("CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
            }

            try
            {
               if (qMgr != null)
                  qMgr.Disconnect();
               logger("disconnected from " + qManager);
            }
            catch (MQException mqex)
            {
               logger("CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
            }
         }
      }

      private void testLoop(MQTopic inTopic)
      {
         bool flag = true;
         MQGetMessageOptions gmo = new MQGetMessageOptions();
         gmo.Options |= MQC.MQGMO_NO_WAIT | MQC.MQGMO_FAIL_IF_QUIESCING;
         MQMessage msg = null;

         while (flag)
         {
            try
            {
               msg = new MQMessage();
               inTopic.Get(msg, gmo);
               if (msg.Feedback == MQC.MQFB_QUIT)
               {
                  flag = false;
                  logger("received quit message - exiting loop");
               }
               else
                  logger("Message Data: " + msg.ReadString(msg.MessageLength));
            }
            catch (MQException mqex)
            {
               logger("CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
               if (mqex.Reason == MQC.MQRC_NO_MSG_AVAILABLE)
               {
                  // no meesage - life is good - loop again
                  logger("sleeping");
                  Thread.Sleep(60*1000);  // sleep for 60 seconds
               }
               else
               {
                  flag = false;  // severe error - time to exit
               }
            }
            catch (System.IO.IOException ioex)
            {
               logger("ioex=" + ioex);
            }
         }
      }

      private void logger(String data)
      {
         DateTime myDateTime = DateTime.Now;
         System.Console.Out.WriteLine(myDateTime.ToString("yyyy/MM/dd HH:mm:ss.fff") + " " + this.GetType().Name + ": " + data);
      }

      /// <summary> main line</summary>
      /// <param name="args">
      /// </param>
      //        [STAThread]
      public static void Main(System.String[] args)
      {
         MQTest82 write = new MQTest82();

         try
         {
            write.init(args);
            write.testReceive();
         }
         catch (System.ArgumentException e)
         {
            System.Console.Out.WriteLine("Usage: MQTest82 -h host -p port -c channel -m QueueManagerName -t topicString [-u userID] [-x passwd]");
            System.Environment.Exit(1);
         }
         catch (MQException e)
         {
            System.Console.Out.WriteLine(e);
            System.Environment.Exit(1);
         }

         System.Environment.Exit(0);
      }
   }
}

Regards,
Roger Lacroix
Capitalware Inc.

.NET, C#, IBM MQ, Linux, Open Source, Programming, Windows Comments Off on C# .NET MQ Code to Subscribe to a Topic

Capitalware Products Minimum MQ Level Changed

The minimum IBM MQ level for the following Capitalware products (distributed platforms) is now IBM MQ v7.1 (or higher):

  • MQ Auditor
  • MQ Authenticate User Security Exit
  • MQ Message Encryption
  • MQ Message Replication
  • MQ Standard Security Exit
  • Regards,
    Roger Lacroix
    Capitalware Inc.

    Capitalware, IBM i (OS/400), IBM MQ, Linux, MQ Auditor, MQ Authenticate User Security Exit, MQ Enterprise Security Suite, MQ Message Encryption, MQ Message Replication, MQ Standard Security Exit, Unix, Windows Comments Off on Capitalware Products Minimum MQ Level Changed

    Capitalware Products 2019 Release Train

    Here is a summary of all the recent releases that Capitalware Inc. has published:

      Updated ‘License as Free’ products:

    • MQ Channel Auto Creation Manager v1.0.5
    • MQ Channel Auto Creation Manager for z/OS v1.0.5
    • MQ Set UserID v1.0.4
    • MQ Set UserID for z/OS v1.0.4
    • Client-side Security Exit for Depository Trust Clearing Corporation v1.0.4
    • Client-side Security Exit for Depository Trust Clearing Corporation for z/OS v1.0.4

    Regards,
    Roger Lacroix
    Capitalware Inc.

    Capitalware, IBM i (OS/400), IBM MQ, Linux, MQ Auditor, MQ Authenticate User Security Exit, MQ Channel Connection Inspector, MQ Channel Encryption, MQ Channel Throttler, MQ Enterprise Security Suite, MQ Message Encryption, MQ Message Replication, MQ Standard Security Exit, Unix, Windows, z/OS Comments Off on Capitalware Products 2019 Release Train

    New: MQ Standard Security Exit v2.5.0

    Capitalware Inc. would like to announce the official release of MQ Standard Security Exit v2.5.0. This is a FREE upgrade for ALL licensed users of MQ Standard Security Exit. MQ Standard Security Exit is a solution that allows a MQAdmin to control and restrict who is accessing an IBM MQ resource.

    For more information about MQ Standard Security Exit go to:
    https://www.capitalware.com/mqssx_overview.html

      Changes for MQ Standard Security Exit v2.5.0:

    • Tuned the code that is called on entry
    • Tuned the logging code

    Regards,
    Roger Lacroix
    Capitalware Inc.

    Capitalware, IBM i (OS/400), IBM MQ, Linux, MQ Standard Security Exit, Unix, Windows Comments Off on New: MQ Standard Security Exit v2.5.0

    New: MQ Standard Security Exit for z/OS v2.5.0

    Capitalware Inc. would like to announce the official release of MQ Standard Security Exit for z/OS v2.5.0. This is a FREE upgrade for ALL licensed users of MQ Standard Security Exit for z/OS. MQ Standard Security Exit for z/OS is a solution that allows a MQAdmin to control and restrict who is accessing an IBM MQ resource.

    For more information about MQ Standard Security Exit for z/OS go to:
    https://www.capitalware.com/mqssx_zos_overview.html

      Changes for MQ Standard Security Exit for z/OS v2.5.0:

    • Tuned the code that is called on entry
    • Tuned the logging code

    Regards,
    Roger Lacroix
    Capitalware Inc.

    Capitalware, IBM MQ, MQ Standard Security Exit, z/OS Comments Off on New: MQ Standard Security Exit for z/OS v2.5.0

    New: MQ Message Replication v2.1.0

    Capitalware Inc. would like to announce the official release of MQ Message Replication v2.1.0. This is a FREE upgrade for ALL licensed users of MQ Message Replication. MQ Message Replication (MQMR) will clone messages being written (via MQPUT or MQPUT1 API calls) to an application’s output queue and MQMR will write the exact same messages to ‘n’ target queues (‘n’ can be up to 100). When MQMR replicates a message both the message data and the message’s MQMD structure will be cloned.

    For more information about MQMR, please go to:
    https://www.capitalware.com/mqmr_overview.html

      Changes for MQ Message Replication v2.1.0:

    • Erase ExitUserArea field on exiting.
    • Added code to append trailing slash for ExitPath if it is missing.
    • Fixed issue with UserIDFormatting
    • Tuned the logging code

    Regards,
    Roger Lacroix
    Capitalware Inc.

    Capitalware, IBM i (OS/400), IBM MQ, Linux, MQ Message Replication, Unix, Windows Comments Off on New: MQ Message Replication v2.1.0

    New: MQ Message Encryption v4.1.0

    Capitalware Inc. would like to announce the official release of MQ Message Encryption v4.1.0. This is a FREE upgrade for ALL licensed users of MQ Message Encryption. MQME provides encryption for MQ message data while it resides in a queue and in the MQ logs (i.e. all data at rest).

    For more information about MQME, please go to:
    https://www.capitalware.com/mqme_overview.html

      Changes for MQ Message Encryption v4.1.0:

    • Because of APAR IT22258, added code to set the ReturnedLength of MQGMO for MQGET and MQCALLBACK.
    • Erase ExitUserArea field on exiting.
    • Added code to append trailing slash for ExitPath if it is missing.
    • Fixed issue with UserIDFormatting
    • Tuned the logging code

    Regards,
    Roger Lacroix
    Capitalware Inc.

    Capitalware, IBM i (OS/400), IBM MQ, Linux, MQ Message Encryption, Unix, Windows Comments Off on New: MQ Message Encryption v4.1.0

    New: MQ Channel Encryption v3.3.0

    Capitalware Inc. would like to announce the official release of MQ Channel Encryption (MQCE) v3.3.0. This is a FREE upgrade for ALL licensed users of MQCE. MQCE provides encryption for message data over IBM MQ channels.

    MQCE operates with Sender, Receiver, Server, Requester, Cluster-Sender, Cluster-Receiver, Server Connection and Client Connection channels of the WMQ queue managers. MQCE uses Advanced Encryption Standard (AES) to encrypt the data and SHA-2 to create a digital signature.

    For more information about MQCE go to:
    https://www.capitalware.com/mqce_overview.html

      Changes for MQ Channel Encryption v3.3.0:

    • Tuned the code that is called on entry
    • Tuned the logging code

    Regards,
    Roger Lacroix
    Capitalware Inc.

    Capitalware, IBM i (OS/400), IBM MQ, Linux, MQ Channel Encryption, Unix, Windows Comments Off on New: MQ Channel Encryption v3.3.0

    New: MQ Channel Encryption for z/OS v3.3.0

    Capitalware Inc. would like to announce the official release of MQ Channel Encryption for z/OS (z/MQCE) v3.3.0. This is a FREE upgrade for ALL licensed users of z/MQCE. z/MQCE provides encryption for message data over IBM MQ channels.

    z/MQCE operates with Sender, Receiver, Server, Requester, Cluster-Sender, Cluster-Receiver, Server Connection and Client Connection channels of the WMQ queue managers. z/MQCE uses Advanced Encryption Standard (AES) to encrypt the data and SHA-2 to create a digital signature.

    For more information about z/MQCE go to:
    https://www.capitalware.com/mqce_zos_overview.html

      Changes for MQ Channel Encryption for z/OS v3.3.0:

    • Tuned the code that is called on entry
    • Tuned the logging code

    Regards,
    Roger Lacroix
    Capitalware Inc.

    Capitalware, IBM MQ, MQ Channel Encryption, z/OS Comments Off on New: MQ Channel Encryption for z/OS v3.3.0

    New: MQ Channel Throttler v1.2.0

    Capitalware Inc. would like to announce the official release of MQ Channel Throttler v1.2.0. This is a FREE upgrade for ALL licensed users of MQ Channel Throttler (MQCT). MQCT provides the ability to control/throttle the number of messages or bytes that flow over a channel.

    For more information about MQCT, please go to:
    https://www.capitalware.com/mqct_overview.html

    • Tuned the code that is called on entry
    • Tuned the logging code

    Regards,
    Roger Lacroix
    Capitalware Inc.

    Capitalware, IBM i (OS/400), IBM MQ, Linux, MQ Channel Throttler, Unix, Windows Comments Off on New: MQ Channel Throttler v1.2.0