Understanding MQ Managed.NET Exits
Prateek Kulkarni
Published on 18/06/2019 / Updated on 18/06/2019
In this blog we will go through how managed .Net Exits can be written and used.
To implement managed .Net exits, you must define a new class that implements the appropriate interfaces. The three interfaces are:
1. MQSendExit
2 .MQReceiveExit
3. MQSecurityExit
Example 1:
class MySendExit : MQSendExit{ //This Method comes from the send exit public byte[] SendExit(MQChannelExit channelExitParms, MQChannelDefinition channelDefinition, byte[] dataBuffer, ref int dataOffset, ref int dataLength, ref int dataMaxLength) { Console.WriteLine("Send Exit"); return dataBuffer; }}
Example 2:
class MyReceiveExit : MQReceiveExit{ // This method comes from the receive exit public byte[] ReceiveExit(MQChannelExit channelExitParms, MQChannelDefinition channelDefinition, byte[] dataBuffer, ref int dataOffset, ref int dataLength, ref int dataMaxLength) { Console.WriteLine("Receive Exit"); return dataBuffer; }}
Example 3:
class MySecurityExit : MQSecurityExit{ // This method comes from the security exit public byte[] SecurityExit(MQChannelExit channelExitParms, MQChannelDefinition channelDefParms, byte[] dataBuffer, ref int dataOffset, ref int dataLength, ref int dataMaxLength) { Console.WriteLine("Security Exit"); return dataBuffer; }}
Steps to compile:
1. Create a dll project from Visual studio.
2. Add the above program or write your own program as above in the project.
3. Add the appropriate reference for the project.
4. Build the project to create a dll.
For example, the above sample program would be build as MySendExit.dll, MyReceiveExit.dll and MySecurityExit.dll .
Each exit is passed with MQChannelExit and MQChannelDefinition object instance. These represent MQCXP and MQCD structures.
Each exit must return dataBuffer or byte array.
After implementing a class with following interfaces, now we have to invoke the exits.
Exits can be invoked in the following ways:
1. Passing hashtable properties MQC.SECURITY_EXIT_PROPERTY, MQC.SEND_EXIT_PROPERTY or MQC.RECEIVE_EXIT_PROPERTY on the MQQueueManager constructor.
- Setting the MQEnvironment SecurityExit, SendExit or ReceiveExit properties.
- Setting SENDEXIT, RCVEXIT and SCYEXIT of CLNTCONN and using CCDT.
In all the above-mentioned ways, the specification takes the form of a string in the following format:
Assembly-name(Class_name)
Class_name is the fully qualified name, including namespace specification, of a .NET class that implements the IBM.WMQ.MQSecurityExit, IBM.WMQ.MQSendExit or IBM.WMQ.MQReceiveExit interface (as appropriate). Assembly_name is the fully qualified location, including file extension, of the assembly that houses the class.
Example:
C:\ProgramData\IBM\MQ\channelExit\DotnetExits.dll (DotnetExits.MyExits)
Passing Hashtable
Example :
class Putmsg{ static void main(String[] args) { // mq properties properties = new Hashtable(); String queueName = args[0]; String hostName = args[1]; int port = Convert.ToInt32(args[2]); String channelName = args[3]; String queueManager = “QM”; properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED); properties.Add(MQC.HOST_NAME_PROPERTY, hostName); properties.Add(MQC.PORT_PROPERTY, port); properties.Add(MQC.CHANNEL_PROPERTY, channelName); properties.Add(MQC.SECURITY_EXIT_PROPERTY, " C:\\ProgramData\\IBM\\MQ\\channelExit\\MySecurityExit.dll(SecurityExit.MySecurityExits)"); properties.Add(MQC.RECEIVE_EXIT_PROPERTY, " C:\\ProgramData\\IBM\\MQ\\channelExit\\ MyReceiveExit.dll(ReceiveExit.MyReceiveExit)"); properties.Add(MQC.SEND_EXIT_PROPERTY, " C:\\ProgramData\\IBM\\MQ\\channelExit\\MySendExit.dll(SendExit.MyExits)"); queueManager = new MQQueueManager(queueManagerName, properties); }}
Setting MQEnvironment properties
Example:
class Putmsg{ static void main(String[] args) { // mq properties properties = new Hashtable(); String queueName = args[0]; String hostName = args[1]; int port = Convert.ToInt32(args[2]); String channelName = args[3]; String queueManager = “QM”; properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED); properties.Add(MQC.HOST_NAME_PROPERTY, hostName); properties.Add(MQC.PORT_PROPERTY, port); properties.Add(MQC.CHANNEL_PROPERTY, channelName); MQEnvironment.SecurityExit = "C:\\ProgramData\\IBM\\MQ\\channelExit\\MySecurityExit.dll(SecurityExit.MySecurityExits"; MQEnvironment.SendExit = "C:\\ProgramData\\IBM\\MQ\\channelExit\\MySendExit.dll(SendExit.MyExits)"; MQEnvironment.ReceiveExit = "C:\\ProgramData\\IBM\\MQ\\channelExit\\ MyReceiveExit.dll(ReceiveExit.MyReceiveExit)"; queueManager = new MQQueueManager(queueManagerName, properties); }}
Using CCDT
To use .Net exits using one must set these attributes of CLNTCONN channel definition: SCYEXIT, RCVEXIT and SENDEXIT.
Example:
runmqsc DISPLAY CHANNEL(SVR) CHLTYPE(CLNTCONN) 1 : DISPLAY CHANNEL(SVR) CHLTYPE(CLNTCONN)AMQ8414: Display Channel details. CHANNEL(SVR) CHLTYPE(CLNTCONN) AFFINITY(PREFERRED) ALTDATE(2019-05-17) ALTTIME(12.23.24) CERTLABL( ) CLNTWGHT(0) COMPHDR(NONE) COMPMSG(NONE) CONNAME(localhost(1432)) DEFRECON(NO) DESCR( ) HBINT(3) KAINT(AUTO) LOCLADDR( ) MAXMSGL(4194304) MODENAME( ) PASSWORD( ) QMNAME(QM) RCVDATA( ) RCVEXIT( ) SCYDATA( ) SCYEXIT( ) SENDDATA( ) SENDEXIT( ) SHARECNV(10) SSLCIPH( ) SSLPEER( ) TPNAME( ) TRPTYPE(TCP) USERID( ) ALTER CHANNEL(SVR) CHLTYPE(CLNTCONN) SCYEXIT('C:\ProgramData\IBM\\MQ\channelExit\MySecurityExit.dll(SecurityExit.MySecurityExit)') ALTER CHANNEL(SVR) CHLTYPE(CLNTCONN) RCVEXIT('C:\ProgramData\IBM\\MQ\channelExit\MySendExit.dll(SendExit.MySendExit)') ALTER CHANNEL(SVR) CHLTYPE(CLNTCONN) SENDEXIT('C:\ProgramData\IBM\\MQ\channelExit\ MyReceiveExit.dll(ReceiveExit.MyReceiveExit)')
After setting these attributes of CLNTCONN channel definition then, run any of the .Net application(put or get).
by Prateek Kulkarni