Communication with IBM MQ in .Net Core 3.0

  • .Net Core
  • IBM MQ
  • Message Queue
  • Mehdi Mohseni
  • September 7, 2020
  • Home
  • Blog
  • Communication with IBM MQ in .Net Core 3.0

Introduction

Using message queues is one of the most effective ways to communicate with different modules in a micro-service solution. In this method, the communication has no dependence on the recipient, and even the recipient can be offline when the message is published, and after the message is published by the sender, when it comes online and get the message from the message queue.

Message queuing systems also allow multiple recipients to listen to one sender and vice versa. Such a feature is very difficult and complex in ordinary sync communication. These are just some of the features that the messaging system provides for us.

Background

For a long time, our team used RabbitMQ for the Message Queueing system. Although RabbitMq is a system with many benefits, our current client uses a Warehouse Management System that connects to other systems via IBM MQ . Although the basics of using the Message Queue systems were the same, but there were many challenges to using the IBM MQ.

The IBM MQ system is an Enterprise system. The vast majority of related documents are written primarily for Java, which makes it difficult for a .NET developer to work with this system.

Installation

The first challenge with working with IBM MQ is installing it on a Windows operating system, which poses a huge challenge about system security. Especially if the system you are working with runs under an Active Directory, it makes the task of setting up this system many times more difficult.

My suggestion is to use and install IBM MQ on Docker for the development and the test. The installation guide provided by IBM is very efficient and complete. You can find this installation guide here (Get an IBM MQ queue for development in a container).

After installing the IBM MQ on Docker, there is some useful information that may be difficult to find in IBM documents.

  • Host name: localhost(1414)
  • Queue manager: QM1
  • Queue: DEV.QUEUE.1
  • Channel: DEV.APP.SVRCONN
  • Port: 1414
  • Integration UserId: app
  • Integration Password: passw0rd
  • Management Console: https://localhost:9443/ibmmq/console/
  • User: admin
  • Password: passw0rd

Connection Structure

As I mentioned, working with the IBM MQ is not so easy. Although IBM MQ provides a very efficient NuGet for developing applications under .Net, working with this library is not easy and requires deep knowledge and familiarity with IBM MQ.

In short, you are able to connect to the Topic or the Queue in IBM MQ via the Channel. You connect to Queue Manager via Channel. Queue Manager is actually a specific instance in IBM MQ. This means that you can have several Queue Managers. Each Queue Manager can have a number of Channels through which communication with the Queue Manager is established.

Code Guide

Initialize the connection properties

The library I designed makes this connection easier. This is done through the IbmMqProxyConnectionConfiguration class.

In the next step we need to create an example of the IbmMqProxy class. This class facilitates communication with IBM MQ. Of course, I want to make you more familiar with how to use the NuGet provided by IBM. But for simple communication, using this proxy is also recommended.

Listening to a Queue/Topic (MQDestination)

In the next step, you need to create an instance of the MQQueueManager class. To create this instance, you need to have the QueueManger's name as well as the basic connection properties stored in the HashTable.

The QueueManager class has two methods called AccessQueue and AccessTopic. The first method returns an instance of the MQQueue class and the second method returns an instance of the MQTopic class. Both MQQueue and MQTopic classes inherit from a class called MQDestination. When you want to access either of these, you need to specify why you are opening this connection. You specify this access through MQC.MQTOPIC_OPEN_AS_SUBSCRIPTION. MQC is one of the static classes of the IBM.WMQ class that has a lot of constant used to work with IBM MQ.

This connection opens for one of the following two reasons:

  • MQTOPIC_OPEN_AS_SUBSCRIPTION = 1
  • MQTOPIC_OPEN_AS_PUBLICATION = 2

Once this connection is opened, you can use the Get() method to read any new message that comes in Queue or Topic. Here you should get acquainted with MQException. This Exception is part of IBM.WMQ which covers errors related to working with IBM MQ. These are errors returned by IBM MQ command line. Each error has a specific Reason and a Code that identifies it for you.

A very common error occurs when you try to get a new message from a MQDestination that has no message. In such a case, Reason will be equal to MQC.MQRC_NO_MSG_AVAILABLE, which is again one of the constants of the MQC class.

This error must be resolved at the time of reading (Get) from any MQDestination. But other errors at the connect, read, or write time mean there was a problem with the connection process. As you can see in the code above, when a proxy reads a new message, it calls a CallBack method called messageHandler and returns the message. Also, when another error occurs, the connection to the IBM MQ is disconnected. The proxy calls the CallBack method called connectionStatusChangedHandler.

Writing to a Queue/Topic (MQDestination)

Writing in an MQDestination is much easier. Basically, like the read method, you have to open an MQDestination via the Access method and then put your message in the Destination with the Put method.

Related Post