Monday 28 August 2017

Send Custom Values in MQ Message Header

Scenario

You want to send custom name-value data with your IBM MQ message. This will allow you to pass application state information. This is useful when you want to change the behaviour of your application without affecting other domain-specific data  for example can be picked up by another for application or another flow in your application.

Solution 


You can use the MQRFH2 header to send your information. In this example, I've added the variable SAPInterface which has the value 'STCKORDERS'.

 SET OutputRoot.MQRFH2.usr.SAPInterface='STCKORDERS';   

NB: The order in which you build your messages is important!

 The XMLNSC value can only be added after the MQMD Header and the MQRFH2 Header part. Getting the order wrong will cause your flow to throw exceptions (sample shown at the bottom of this post).

Below is some sample code where I create test messages that belong to a message group, and the MQRFH2, and MQMD headers are in the correct order.

 CREATE COMPUTE MODULE CreateMessages_Create_Message  
      CREATE FUNCTION Main() RETURNS BOOLEAN  
      BEGIN  
           DECLARE MSGNUM INT 0;  
           DECLARE MSGTOTAL INT 1;  
           WHILE MSGNUM < MSGTOTAL DO  
                SET MSGNUM = MSGNUM + 1;  
                CALL CopyMessageHeaders();  
                -- Manually set the groupId since we cant ask the queue manager to generate one.  
                -- the UUIDASBLOB function could be used here to generate one, but this must be done  
                -- outside the loop to keep the same groupId throughout!  
                     SET OutputRoot.MQRFH2.usr.SAPInterface='STCKEVCH';  
                SET OutputRoot.MQMD.GroupId = X'000000000000000000000000000000000000000000000001';  
                SET OutputRoot.MQMD.MsgSeqNumber = MSGNUM;  
                SET OutputRoot.MQMD.MsgFlags = MQMF_MSG_IN_GROUP;  
                IF (MSGNUM = MSGTOTAL) THEN  
                     SET OutputRoot.MQMD.MsgFlags = MQMF_LAST_MSG_IN_GROUP;  
                END IF;  
                     -- SET OutputRoot.XML.TestCase = MSGNUM;  
                SET OutputRoot.XMLNSC.value='**Message ' || CAST( MSGNUM AS CHARACTER);  
                LOG USER TRACE VALUES(2950,OutputRoot.XMLNSC.value );  
                PROPAGATE;  
           END WHILE;  
           RETURN FALSE;  
      END;  


Observed Preferred Order


The Order of the elements in your message should be

  1. MQMD
  2. MQRFH2
  3. XMLNSC
 (there are other segments that aren't shown, I'm just jotting down what I have. Please comment and I will improve this list.

Incorrect Order Exception 


You will see and error like below if you build your messages in the incorrect order.

"Exception. BIP2230E: Error detected whilst processing a message in node 'test.CreateMessages.Create Message'. : /build/S1000_slot1/S1000_P/src/DataFlowEngine/SQLNodeLibrary/ImbComputeNode.cpp: 515: ImbComputeNode::evaluate: ComIbmComputeNode: test/CreateMessages#FCMComposite_1_2 BIP2488E: ('test.CreateMessages_Create_Message.Main', '30.4') Error detected whilst executing the SQL statement ''PROPAGATE FINALIZE DEFAULT DELETE DEFAULT;''. : /build/S1000_slot1/S1000_P/src/DataFlowEngine/ImbRdl/ImbRdlStatementGroup.cpp: 792: SqlStatementGroup::execute: : BIP2230E: Error detected whilst processing a message in node 'test.CreateMessages.Send to Queue'. : /build/S1000_slot1/S1000_P/src/DataFlowEngine/TemplateNodes/ImbOutputTemplateNode.cpp: 303: ImbOutputTemplateNode::processMessageAssemblyToFailure: ComIbmMQOutputNode: test/CreateMessages#FCMComposite_1_4 BIP4694E: The message received at output node 'test.CreateMessages.Send to Queue' contains an MQMD at index '2' which is the wrong position; the MQMD should be at index '1'. : /build/S1000_slot1/S1000_P/src/DataFlowEngine/Connectors/lib/ImbOutputNode.cpp: 941: ImbOutputNode::checkForMQMDinHeaderChain: ComIbmMQOutputNode: test/CreateMessages#FCMComposite_1_4 "

No comments:

Post a Comment