Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Websphere MQ Queue Depth with XMS.Net

Tags:

c#

.net

ibm-mq

Since we are experiencing some trouble with IBM's Websphere MQ using XMS.net (Windows service that sometimes seems to give up listening for messages on a queue) we would like to create a simple application to monitor the depths of some queues (or number of messages on the queue) to be able to alert someone when the queue depth exceeds a certain threshold. This application would be launched by the task scheduler on a specific interval and would "read out" for X queues their queue depth (and maybe some other statistics).

Our windows service is using the following code and I was hoping I could reuse that same "knowledge" for our "monitoring" application.

    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    //Read config values
    string QueueManager = ConfigurationManager.AppSettings["queuemanager"];
    string Channel = ConfigurationManager.AppSettings["channel"];
    string Queue = ConfigurationManager.AppSettings["queue"];
    string HostIP = ConfigurationManager.AppSettings["host"];
    int Port = int.Parse(ConfigurationManager.AppSettings["port"]);

    //Create connection
    var factoryfactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
    var connectionfactory = factoryfactory.CreateConnectionFactory();

    connectionfactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, QueueManager);
    connectionfactory.SetStringProperty(XMSC.WMQ_HOST_NAME, HostIP);
    connectionfactory.SetIntProperty(XMSC.WMQ_PORT, Port);
    connectionfactory.SetStringProperty(XMSC.WMQ_CHANNEL, Channel);
    connectionfactory.SetIntProperty(XMSC.WMQ_BROKER_VERSION, XMSC.WMQ_BROKER_V2);
    connectionfactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT_UNMANAGED);

    Console.WriteLine("Creating connection");
    var connection = connectionfactory.CreateConnection();
    connection.ExceptionListener = new ExceptionListener(OnXMSExceptionReceived);

    //Create a_session
    Console.WriteLine("Creating sessions");
    var session = connection.CreateSession(false, AcknowledgeMode.ClientAcknowledge);

    //Create queue
    Console.WriteLine("Creating queue");
    var queue = session.CreateQueue(string.Format("queue://{0}/{1}", QueueManager, Queue));

I have browsed through the properties of session, queue etc. but, ofcourse, there are no "current queue depth" properties. I could use GetIntProperty() or GetLongProperty() on these objects but I don't know which constant to use for that (I have seen IBM.XMS.MQC.MQIA_CURRENT_Q_DEPTH but that contains an int and Get...Property() expects a string as parameter).

Long story short: how would I go about retrieving a queues depth with the above code as a starting-point? Is it at all possible using XMS.Net?

like image 658
RobIII Avatar asked Feb 20 '23 20:02

RobIII


1 Answers

I was able to solve it using, as Shashi suggested, the MQ API. For this you need to reference amqmdnet.dll (C:\Program Files (x86)\IBM\WebSphere MQ\bin\amqmdnet.dll) and use the following (example) code. Please note that this is a simple example, no exception handling etc. is included.

using System;
using System.Collections;
using System.Configuration;
using IBM.WMQ;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            //Connection properties
            var properties = new Hashtable();
            properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
            properties.Add(MQC.CHANNEL_PROPERTY, "SOME.CHANNEL.TCP");
            properties.Add(MQC.HOST_NAME_PROPERTY, "12.34.56.78");
            properties.Add(MQC.PORT_PROPERTY, 1416);

            var qmgr = new MQQueueManager("MYQMGR", properties);

            Console.WriteLine("Local  : {0}", GetQueueDepth(qmgr, "FOO.LOCALQ"));
            Console.WriteLine("Report : {0}", GetQueueDepth(qmgr, "FOO.REPORTQ"));
        }

        public static int GetQueueDepth(MQQueueManager queuemgr, string queue)
        {
            return queuemgr.AccessQueue(queue,
                MQC.MQOO_INPUT_AS_Q_DEF + 
                MQC.MQOO_FAIL_IF_QUIESCING + 
                MQC.MQOO_INQUIRE).CurrentDepth;
        }
    }
}

This performs way better than my initial "workaround".

like image 179
RobIII Avatar answered Feb 22 '23 11:02

RobIII