.NET and MQ admin via ADSI

We have previously discussed connecting to MQSeries from .NET applications

That post dealt specifically with connecting to MQSeries to perform queue operations: Puts and Gets. MQSeries also exposes an administrative interface. What are the possibilities for connecting from a .NET app into the MQ Administrative function? At first glance, there seems to be a number of viable options for administratively querying MQSeries from .NET:

  1. PCF
2. Using System.DirectoryServices to connect with the MQ ADSI provider
3. COM interop with IBM's MQ ADSI COM library
4. COM interop with IBM's MQAI

But each of these obvious options falls short in one way or another.

PCF stands for, I think, Programmable Command Facility - basically it is a mechanism for sending administrative commands directly over the MQ transport. The use of PCF from .NET involves explicitly formatting messages and placing them on command queues. MQ reads the messages and responds. Using PCF from .NET is possible and has been demonstrated elsewhere. It works, but the programming model is not facile.

The use of System.DirectoryServices namespace is problematic. Apparently the MQ ADSI provider does not fully implement all of the required interfaces, and so using System.DirectoryServices on the MQ provider generates exceptions, timeouts, and etc. This option appears to be not very popular. I couldn't find anyone doing it, and I could find no help on IBM's website. 

The MQ-ADSI COM library shipped with MQSeries, found at <MQDIR>\bin\amqmadsi.dll , is intriguing, but there is effectively no documentation on this library from IBM, and no examples to go on, that I could find. 

MQAI is a separate option, a facade over top of MQAX and PCF. Again, not facile. 

This example uses a fifth option: interaction with MQ's ADSI provider via COM interop with the Active Directory Services library. Don't be confused by the name - I am not saying that MQ stores its administrative data in Active Directory; only that MQ Administrative data can be accessed via the programmatic interface known as ADSI. The most well known subsystem that exposes an ADSI interface is, of course, Active Directory itself. But MQ is another system that does so. In this usage, We are not utilizing the amqmadsi.dll directly; instead, we use the ActiveDs COM library, and specify a binding string (really a COM moniker) like IBMMQSeries://MQHost/hostname to get to MQ. This connects to the MQ ADSI provider. 

For the programming model, rather than explicitly putting and getting messages as with PCF, MQ objects are accessed through COM monikers. You can query the queue managers on a machine, the local queues managed by those QMs, the various attributes on those queues, and so on. 

Screen shot:  

This example is packaged as a Visual Studio solution, but it can also be compiled using just the .NET SDK. Download it here. It queries the properties of MQ objects like Queues, Channels, Queue Managers, and so on. Theoretically, you should also be able to use the MQ ADSI provider to write those properties, but this code does not try that. If anyone cares to take this code and extend it to also update MQ, I'd like to hear about it. 

To get this to work, you need to reference the Active Directory Services COM library. To do this in Visual Studio .NET, you need to right click on the project in the Solution Explorer, Add Reference..., select the COM tab, and then select the "Active DS Type Library". This has already been done on the projects included here. Using the .NET SDK, you need to run tlbimp.exe on c:\windows\system32\activeds.tlb to generate the interop assembly, then reference the assembly when compiling this file, eg,

   tlbimp c:\windows\system32\activeds.tlb
csc /debug+ /t:exe /r:ActiveDs.dll /out:MQ-via-ADSI.exe MQ-via-ADSI.cs
 

References:
ADSI Reference from Microsoft:
https://msdn.microsoft.com/library/en-us/netdir/adsi/adsi_reference.asp
Programming MQ using the COM interface (from IBM):
https://publibfp.boulder.ibm.com/epubs/html/amqtan02/amqtan02tfrm.htm

-Dino