Receive an MQ request message, pass the message to MQ, and then pass the response from MQ to the requesting client

Receive a WebSphere® MQ request message, pass the message to WebSphere MQ, and then send the WebSphere MQ response to the requesting client.

Before you begin

For this scenario, server bindings are used on the MQ nodes to connect to WebSphere MQ. WebSphere MQ therefore must be installed on the same computer as the integration node. Alternatively, you can configure the MQ nodes for remote connections, but these steps are not described within the scenario. For more information, see Configuring connections to WebSphere MQ.

About this task

A request-response message flow is a specialized form of a point-to-point application. For a general description of these applications, see Nodes for connectivity.

This scenario is used for connecting client applications.

Scenario:

Two applications with different message formats communicate with each other by using WebSphere MQ in a request-reply message processing solution. For the applications to communicate successfully, the message formats must be transformed in IBM Integration Bus on both the request and reply messages. The backend application is represented in this scenario by a third message flow, to demonstrate the successful processing of a message.

Two message flows are required for request-reply, because WebSphere MQ processes messages asynchronously. Messages that are processed asynchronously in IBM Integration Bus do not wait for a response, and WebSphere MQ does not send a reply message. To process a reply, a store queue takes the original message's ReplyToQ property so that a second message flow can process a reply from an application.

This scenario demonstrates how to create Request and Reply message flows, and how to store message state information by using a store queue. The message flow that represents the backend application modifies a "Completion Time" value in the message.

Instructions:

The following steps show how to create the message flows and a store state queue so that a reply message from WebSphere MQ can be processed.

Procedure

  1. Create a message flow that is named MQ_Task2_Request with the following nodes, and name them on the Description tab Node name property:
    • An MQInput node, named Receive Message.
    • Four Compute nodes, named Transform Request Message, Save MQMD Headers to LocalEnvironment, Set New ReplyToQ, and Build State Message.
    • Two MQOutput nodes, named Output Request Message and Store State Message.

    For more information, see Creating a message flow.

  2. Connect the Out terminal of the Receive Message MQInput node to the In terminal of the Transform Request Message Compute node.
  3. Connect the Out terminal of the Transform Request Message Compute node to the In terminal of the Save MQMD Headers to LocalEnvironment Compute node.
    Note: You can add your own transformation node, or a subflow, for the message processing that you require between the Receive Message MQInput node and Save MQMD Headers to LocalEnvironment Compute node. The Transform Request Message Compute node is a placeholder in this scenario that does not transform the message.
  4. Connect the Out terminal of the Save MQMD Headers to LocalEnvironment Compute node to the In terminal of the Set New ReplyToQ Compute node.
  5. Connect the Out terminal of the Set New ReplyToQ Compute node to the In terminal of the Output Request Message MQOutput node.
  6. Connect the Out terminal of the Output Request Message MQOutput node to the In terminal of the Build State Message Compute node.
  7. Connect the Out terminal of the Build State Message Compute node to the In terminal of the Store State Message MQOutput node.
    Image of the message flow with nodes that are connected as described in the steps.

You must now configure the message flow nodes for the Request behavior of the message flow.

  1. Set the following properties of the Receive Message MQInput node:
    1. On the Basic tab, set the Queue name property to MQ.TASK2.IN1.
    2. On the MQ Connection tab, set the Connection property to Local queue manager, and then the Destination queue manager property to TASK2_QUEUE_MANAGER.
    3. On the Input Message Parsing tab, set the Message domain property to XMLNSC.
  2. Set the following properties of the Transform Request Message Compute node:
    1. An ESQL module, MQ_Task2_Request_Transform_Reply_Message, is automatically created. In the Application Development view, open ESQLs, and then the MQ_Task2_Request_Transform_Reply_Message module.
    2. Copy the following ESQL into the module:
      CREATE COMPUTE MODULE MQ_Task2_Request_Transform_Reply_Message
      	CREATE FUNCTION Main() RETURNS BOOLEAN
      	BEGIN
      		SET OutputRoot = InputRoot;
      		RETURN TRUE;
      	END;
      END MODULE;

      The Transform Request Message Compute does not transform the message, and acts as a placeholder for this scenario.

  3. Set the following properties of the Save MQMD Headers to LocalEnvironment Compute node:
    1. On the Basic tab, set the Compute mode property to LocalEnvironment.
    2. An ESQL module, MQ_Task2_Request_Save_MQMD_Headers_to_LocalEnvironment, is automatically created. In the Application Development view, open ESQLs, and then the MQ_Task2_Request_Save_MQMD_Headers_to_LocalEnvironment module.
    3. Copy the following ESQL into the module:
      CREATE COMPUTE MODULE MQ_Task2_Request_Save_MQMD_Headers_to_LocalEnvironment
      	CREATE FUNCTION Main() RETURNS BOOLEAN
      	BEGIN
      		SET OutputLocalEnvironment.Variables.OriginalMQMD = InputRoot.MQMD;
      		RETURN TRUE;
      	END;
      END MODULE;

      The Save MQMD Headers to LocalEnvironment Compute node saves the MQMD of the original message to a local environment variable, which is then retrieved later in the message flow by the Build State Message Compute node.

  4. Set the following properties of the Set New ReplyToQ Compute node:
    1. An ESQL module, MQ_Task2_Request_Set_New_ReplyToQ, is automatically created. In the Application Development view, open ESQLs, and then the MQ_Task2_Request_Set_New_ReplyToQ module.
    2. Copy the following ESQL into the module:
      CREATE COMPUTE MODULE MQ_Task2_Request_Set_New_ReplyToQ
      	CREATE FUNCTION Main() RETURNS BOOLEAN
      	BEGIN
      		SET OutputRoot = InputRoot;
      		SET OutputRoot.MQMD.ReplyToQ = 'MQ.TASK2.BACKEND.RESP1';
      		SET OutputRoot.MQMD.ReplyToQMgr = 'TASK2_QUEUE_MANAGER';
      		RETURN TRUE;
      	END;
      END MODULE;

      The Set New ReplyToQ Compute node sets a new value for ReplytoQ so that the Reply message flow queue is used.

  5. Set the following properties of the Output Request Message MQOutput node:
    1. On the Basic tab, set the Queue name property to MQ.TASK2.BACKEND.REQ1.
    2. On the Advanced tab, select the New message ID property.
  6. Set the following properties of the Build State Message Compute node:
    1. An ESQL module, MQ_Task2_Request_Build_State_Message, is automatically created. In the Application Development view, open ESQLs, and then the MQ_Task2_Request_Build_State_Message module.
    2. Copy the following ESQL into the module:
      CREATE COMPUTE MODULE MQ_Task2_Request_Build_State_Message
      	CREATE FUNCTION Main() RETURNS BOOLEAN
      	BEGIN
      		CALL CopyMessageHeaders();
      		SET OutputRoot.MQMD.CorrelId = InputLocalEnvironment.WrittenDestination.MQ.DestinationData.msgId;
      		SET OutputRoot.MQMD.ReplyToQ = InputLocalEnvironment.Variables.OriginalMQMD.ReplyToQ;
      		SET OutputRoot.MQMD.ReplyToQMgr = InputLocalEnvironment.Variables.OriginalMQMD.ReplyToQMgr;
      		SET OutputRoot.BLOB.BLOB = InputLocalEnvironment.Variables.OriginalMQMD.MsgId;
      		RETURN TRUE;
      	END;
      	
      	CREATE PROCEDURE CopyMessageHeaders() BEGIN
      		DECLARE I INTEGER 1;
      		DECLARE J INTEGER;
      		SET J = CARDINALITY(InputRoot.*[]);
      		WHILE I < J DO
      			SET OutputRoot.*[I] = InputRoot.*[I];
      			SET I = I + 1;
      		END WHILE;
      	END;
      END MODULE;
      The Build State Message Compute node:
      1. Extracts the Message ID of the message that is written to MQ.TASK2.BACKEND.REQ1.
      2. Extracts the original ReplyToQ and ReplyToQMgr values from the LocalEnvironment, and these values are saved in the state message MQMD.
      3. Extracts the original MessageId value from the LocalEnvironment, and saves this value to the body of the state message.
      4. Uses the BLOB parser to read and write the body of the state message, because the MessageId is binary data.
  7. Set the following properties of the Store State Queue MQOutput node:
    1. On the Basic tab, set the Queue name property to MQ.TASK2.STATE1.
    2. On the Advanced tab, select the New message ID property.

You must now create the Reply message flow.

  1. Create a message flow that is named MQ_Task2_Reply with the following nodes, and name them on the Description tab Node name property:
    • An MQInput node, named Receive Backend Application Reply.
    • An MQGet node, named Get Original MQMD.
    • An MQOutput node, named Send Reply.
    • Two Compute nodes, named Transform Reply Message and Set CorrelID And RTQ.
    • Two Throw nodes, named Handle MQGet Warning and Handle Error No Store Message.
  2. Connect the Out terminal of the Receive Backend Application Reply MQInput node to the In terminal of the Transform Reply Message Compute node.
  3. Connect the Out terminal of the Transform Reply Message Compute node to the In terminal of the Get Original MQMD MQGet node.
  4. Connect the Warning terminal of the Get Original MQMD MQGet node to the Handle MQGet Warning Throw node.
  5. Connect the Failure terminal of the Get Original MQMD MQGet node to the Handle Error Not Stored Message Throw node.
  6. Connect the Out terminal of the Get Original MQMD MQGet node to the Set CorrelID And RTQ Compute node.
  7. Connect the Out terminal of the Set CorrelID And RTQ Compute node to the Send Reply MQOutput node.
    Image of the message flow and nodes, which are connected as described in the steps.

You must now configure the message flow nodes for the Reply behavior of the message flow.

  1. Set the following properties of the Receive Backend Application Reply MQInput node:
    1. On the Basic tab, set the Queue name property to MQ.TASK2.BACKEND.RESP1.
    2. On the Input Message Parsing tab, set the Message domain property to XMLNSC.
  2. Set the following properties of the Transform Reply Message Compute node:
    1. An ESQL module, MQ_Task2_Reply_Transform_Reply_Message, is automatically created. In the Application Development view, open ESQLs, and then the MQ_Task2_Reply_Transform_Reply_Message module.
    2. Copy the following ESQL into the module:
      CREATE COMPUTE MODULE MQ_Task2_Reply_Transform_Reply_Message
      	CREATE FUNCTION Main() RETURNS BOOLEAN
      	BEGIN
      		SET OutputRoot = InputRoot;
      		RETURN TRUE;
      	END;
      END MODULE;

      The Compute does not transform the message. The Compute node is a placeholder for the solution transformation in this scenario.

  3. Set the following properties of the Get Original MQMD MQGet node:
    1. On the Basic tab, set the Queue name property to MQ.TASK2.STATE1.
    2. On the MQ Connection tab, set the Connection property to Local queue manager, and then the Destination queue manager property to TASK2_QUEUE_MANAGER.
    3. On the Input Message Parsing tab, set the Message domain property to BLOB.
    4. On the Advanced tab:
      • Set the Copy message property to Copy Entire Message.
      • Set the Copy local environment property to Copy Entire LocalEnvironment.
    5. On the Request tab:
      • Set the Input MQMD location property to InputRoot.MQMD.
      • Select the Get by correlation ID property.
    6. On the Result tab:
      • Set the Output data location property to OutputLocalEnvironment.ResultRoot,
      • Set the Result data location to ResultRoot.
  4. Set the following properties of the Set CorrelId And RTQ Compute node:
    1. On the Basic tab, set the Compute mode property to MQ.TASK2.STATE1.
    2. An ESQL module, MQ_Task2_Reply_Set_CorrelId_And_RTQ, is automatically created. In the Application Development view, open ESQLs, and then the MQ_Task2_Reply_Set_CorrelId_And_RTQ module.
    3. Copy the following ESQL into the module:
      CREATE COMPUTE MODULE MQ_Task2_Reply_Set_CorrelId_And_RTQ
      	CREATE FUNCTION Main() RETURNS BOOLEAN
      	BEGIN
      		SET OutputRoot = InputRoot;
      		SET OutputRoot.MQMD.CorrelId = InputLocalEnvironment.Variables.ResultRoot.BLOB.BLOB;
      		SET OutputLocalEnvironment.Destination.MQ.DestinationData[1].queueName = InputLocalEnvironment.Variables.ResultRoot.MQMD.ReplyToQ;
      		SET OutputLocalEnvironment.Destination.MQ.DestinationData[1].queueManagername = InputLocalEnvironment.Variables.REResultRoot.MQMD.ReplyToQMgr;
      		RETURN TRUE;
      	END;
      END MODULE;
      The Set CorrelId And RTQ Compute node:
      1. Extracts the ReplyToQ and ReplyToQMgr from the MQMD of the state message.
      2. Sets a CorrelId that is the value of the MessageId in the body of the original state message. The CorrelId is used for the Reply message flow.
  5. Set the following properties of the Send Reply MQOutput node:
    1. On the Advanced tab, set the Destination mode property to Destination list

      By setting the MQOutput node in Destination List mode, the output queue can be set dynamically.

  6. Set the following properties of the Handle MQGet Warning Throw node:
    1. On the Basic tab, enter error message text into the Message text field.
      For example, "MQGet returned a warning."

      If a warning occurs in the message from the MQGet node, the Handle_MQGet_Warning Throw node returns an error message about this warning. The message tree contains the MQMD and any message content that was received.

  7. Set the following properties of the Handle Error Not Stored Message Throw node:
    1. On the Basic tab, enter error message text into the Message text field.
      For example, "MQGet error, no store message queue received."

    If an error occurs because the MQGet node failed to get the message from the store queue, the Handle_Error_Not_Stored_Message Compute node returns an error message. The message is not processed.

    You cannot return the message from the Reply message flow back to the Request message flow. Therefore, you must consider error handling at a higher level in your messaging architecture than the error handling options that are provided by message flow nodes.

The message flow can now communicate with a backend application. For this scenario, create a third message flow to represent this application.

A backend application, by default, copies the MessageId of the message to its CorrelId, and this value is then sent in the reply message. However, as a real application is not used in this scenario, this action was taken by the Save MQMD Headers to LocalEnvironment Compute node in step 10 for the Request message flow.

To demonstrate that the backend application is successfully processed in the Reply message flow, a Compute node modifies the Completion Time value that is in the message.

  1. Create a message flow that is named MQ_Task2_BackendApp with the following nodes, and name them on the Description tab Node name property:
    • An MQInput node, named Get Request Message.
    • A Compute node, named Modify Completion Time.
    • An MQReply node, named Put Reply Message.
  2. Connect the Out terminal of the Get Request Message MQInput node to the In terminal of the Modify Completion Time Compute node.
  3. Connect the Out terminal of the Modify Completion Time Compute node to the In terminal of the Put Reply Message MQReply node.
    Image of the message flow and nodes, which are connected as described in the steps.
  4. Set the following properties of the Get Request Message MQInput node:
    1. On the Basic tab, set the Queue name property to MQ.TASK2.BACKEND.REQ1.
    2. On the MQ Connection tab, set the Connection property to Local queue manager, and then the Destination queue manager property to TASK2_QUEUE_MANAGER.
    3. On the Input Message Parsing tab, set the Message domain property to XMLNSC.
  5. Set the following properties of the Modify Completion Time Compute node:
    1. An ESQL module, MQ_Task2_BackendApp_Modify_Completion_Time, is automatically created. In the Application Development view, open ESQLs, and then the MQ_Task2_BackendApp_Modify_Completion_Time module.
    2. Copy the following ESQL into the module:
      CREATE COMPUTE MODULE MQ_Task2_BackendApp_Modify_Completion_Time
      	CREATE FUNCTION Main() RETURNS BOOLEAN
      	BEGIN
      		SET OutputRoot = InputRoot;
      		SET OutputRoot.XMLNSC.SaleEnvelope.TimeStamp = CURRENT_GMTTIMESTAMP;
      		RETURN TRUE;
      	END;
      END MODULE;
      
      The Modify Completion Time Compute node represents the solution transformation in this scenario. The Compute node adds a time stamp value to the message, which shows the time that it was processed.
  6. Set the following properties of the Get Request Message MQReply node:
    1. On the Basic tab, set the Queue name property to MQ.TASK2.BACKEND.REQ1.
    2. On the MQ Connection tab, set the Connection property to Local queue manager, and then the Destination queue manager property to TASK2_QUEUE_MANAGER.
  7. Save the message flow.

Results

  • When the Request message flow is run, the following actions occur:
    1. The MQInput node reads a WebSphere MQ request message.
    2. The original message is transformed into an equivalent format for the backend application.
    3. The ReplyToQ and ReplyToQMgr details are set for the input message to the Reply message flow.
    4. A WebSphere MQ message is created that contains the transformed message. This message is sent to the backend message flow.
    5. The original MessageId, ReplyToQ, ReplyToQMgr details are saved in a separate WebSphere MQ message for subsequent retrieval by the Reply message flow.
  • When the Reply message flow is run, the following actions occur:

    1. The MQInput reads the WebSphere MQ message that contains a message in the data format from the backend application.
    2. The message is transformed into the equivalent format for the requester application.
    3. The MQGet node obtains the CorrelId, ReplyToQ, and ReplyToQMgr details of the original request message, by reading theWebSphere MQ message that was used to store this information in the Request message flow.
    4. A WebSphere MQ message that contains the transformed message and the retrieved CorrelId, ReplyToQ, and ReplyToQMgr values is created.