Creating the XML_Reservation message flow

Use the following instructions to create the XML_Reservation message flow. For more detailed instructions, click the links provided at the end of each step.

To create and configure the XML_Reservation message flow:

  1. Create a new message flow called XML_Reservation.
    For instructions, see Creating a message flow.
  2. In the Message Flow editor, add and rename the nodes listed in the following table.
    For instructions, see Adding a node.
    Palette drawers Node type Node name
    WebSphere MQ MQInput XML_RESERVATION_IN
    WebSphere MQ MQOutput XML_RESERVATION_OUT
    WebSphere MQ MQOutput XML_RESERVATION_FAIL
    Transformation Compute UpdatePassengerTable
    Transformation Compute BuildSingleMessage
    Transformation Compute PropagateMultipleMessages
    Database Database UpdateFlightTable
    Routing Filter MultipleOrSingleMessage
    Construction Throw InvalidRequest
    Construction Trace LogException
  3. Connect the nodes together as shown in the following table.
    For instructions, see Connecting nodes.
    To check that you have connected the nodes together correctly, see the figure in About the XML_Reservation message flow.
    Node name Terminal Connect to this node
    XML_RESERVATION_IN Out UpdateFlightTable
    Catch XML_RESERVATION_FAIL
    UpdateFlightTable Out UpdatePassengerTable
    UpdatePassengerTable Out MultipleOrSingleMessage
    MultipleOrSingleMessage Unknown InvalidRequest
    False BuildSingleMessage
    True PropagateMultipleMessages
    BuildSingleMessage Out XML_RESERVATION_OUT
    PropagateMultipleMessages Out XML_RESERVATION_OUT
    XML_RESERVATION_FAIL Out LogException
  4. Configure the node properties as shown in the following table.
    Accept the default values for all properties unless an alternative value is shown in the table.
    For instructions, see Configuring a node.
    Node name Page Property Value
    XML_RESERVATION_IN Basic Queue name XML_RESERVATION_IN
    (This is the local queue from which the message flow takes the message.)
    Input Message Parsing Message domain XML : For XML messages
    (This tells the broker to use the generic XML parser.)
    UpdateFlightTable Basic Data source RESERVDB
    (This is the database used by this node.)
    Basic Statement

    UpdateFlightTable
    (Replace the default value)
    (This is the name of the ESQL module used by this node during processing. The name must match the name in the CREATE DATABASE MODULE statement in the ESQL file.)

    UpdatePassengerTable Basic Data source

    RESERVDB
    (This is the database used by this node.)

    Basic ESQL module UpdatePassengerTable
    (Replace the default value)
    (This is the name of the ESQL module used by this node during processing. The name must match the name in the CREATE COMPUTE MODULE statement in the ESQL file.)
    XML_RESERVATION_OUT Basic Queue name
    (You do not need to specify the name of the queue manager because the queue is defined on the same queue manager as the broker.)
    XML_RESERVATION_OUT
    (This is the local queue on which the message flow puts the message.)
    LogException Basic Destination Local Error Log
    (This instructs the node to write the trace information the local error log. On Windows, the local error log is Event Viewer; on Linux, the local error log is syslog.)
    Basic Pattern Date is:
    ${EXTRACT (MONTH FROM CURRENT_DATE)}/
    ${EXTRACT (DAY FROM CURRENT_DATE)}/
    ${EXTRACT (YEAR FROM CURRENT_DATE)}
    Time is: ${EXTRACT (HOUR FROM CURRENT_TIMESTAMP)}:
    ${EXTRACT(MINUTE FROM CURRENT_TIMESTAMP)}

    Environment is:
    ${Environment}

    Exception List is:
    ${ExceptionList}

    (This extracts the date and time information, and information about the error from the Exception List.)
    Basic Message number 3052
    XML_RESERVATION_FAIL Basic Queue name
    (You do not need to specify the name of the queue manager because the queue is defined on the same queue manager as the broker.)
    XML_RESERVATION_FAIL
    (This is where the message flow puts the message if the processing fails.)
  5. In the XML Airline Message Flows project, double-click the ESQL file to open it in the ESQL editor. Copy and paste the following ESQL code modules to the ESQL file, then save the file. For more information, see Developing ESQL.
    -- ************************************************
    -- * ESQL for the XML_Reservation message flow
    -- ************************************************
    
    CREATE DATABASE MODULE UpdateFlightTable
    	CREATE FUNCTION Main() RETURNS BOOLEAN
    	BEGIN
    		-- populate the environment with flight info from the database		
    		SET Environment.Variables =
    			THE (SELECT T.* FROM Database.XMLFLIGHTTB AS T
    				WHERE T.FLIGHTDATE = Root.XML.Reservation.FlightDetails.FlightDate
    				AND T.FLIGHTNO = Root.XML.Reservation.FlightDetails.FlightNumber);
    		DECLARE ref REFERENCE TO Root.XML.Reservation.ListOfPassengers.PassengerDetails[1];
    		-- track the remaining number of seats
    		SET Environment.Variables.EconomyClassRemain = CAST(Environment.Variables.TOTALECONOMIC AS INTEGER);
    		SET Environment.Variables.FirstClassRemain = CAST(Environment.Variables.TOTALFIRST AS INTEGER);
    
    		-- loop through the request, counting the passengers and checking capacity
    		SET Environment.Variables.NoPassengers = 0;
    		WHILE LASTMOVE(ref) DO -- check that the REFERENCE is still valid
    			IF ref.Class = 'F' THEN
    				IF Environment.Variables.FirstClassRemain >= 1 THEN
    					SET Environment.Variables.FirstClassRemain = Environment.Variables.FirstClassRemain - 1;
    					SET Environment.Variables.FIRSTCLASS = Environment.Variables.FIRSTCLASS + 1;
    					SET Environment.Variables.NoPassengers = Environment.Variables.NoPassengers + 1;
    				ELSE
    					THROW USER EXCEPTION MESSAGE 2949 VALUES('Number of passengers exceeds capacity');
    				END IF;
    			END IF;
    			IF ref.Class = 'Y' THEN
    				IF Environment.Variables.EconomyClassRemain >= 1 THEN
    					SET Environment.Variables.EconomyClassRemain = Environment.Variables.EconomyClassRemain - 1;
    					SET Environment.Variables.ECONOMICCLASS = Environment.Variables.ECONOMICCLASS + 1;
    					SET Environment.Variables.NoPassengers = Environment.Variables.NoPassengers + 1;
    				ELSE
    					THROW USER EXCEPTION MESSAGE 2949 VALUES('Number of passengers exceeds capacity');
    				END IF;
    			END IF;
    			MOVE ref NEXTSIBLING REPEAT NAME; -- increment the loop condition
    		END WHILE;
    		
    		-- update the database with the decreased seat availability for the flight
    		UPDATE Database.XMLFLIGHTTB AS T
    			SET ECONOMICCLASS = Environment.Variables.ECONOMICCLASS,
    				TOTALECONOMIC = Environment.Variables.EconomyClassRemain,
    				FIRSTCLASS = Environment.Variables.FIRSTCLASS,
    				TOTALFIRST = Environment.Variables.FirstClassRemain
    				WHERE T.FLIGHTDATE = Root.XML.Reservation.FlightDetails.FlightDate
    				AND T.FLIGHTNO = Root.XML.Reservation.FlightDetails.FlightNumber;
    		RETURN TRUE;
    	END;
    END MODULE;
    
    CREATE COMPUTE MODULE UpdatePassengerTable
    	CREATE FUNCTION Main() RETURNS BOOLEAN
    	BEGIN		
    		SET OutputRoot = InputRoot;		
    		DECLARE I INTEGER 1;
    		DECLARE J INTEGER Environment.Variables.NoPassengers;
    		DECLARE resno CHARACTER;
    		WHILE I <= J DO -- loop through the passengers
    			SET Environment.Variables.RESERVATIONSEQNO = Environment.Variables.RESERVATIONSEQNO + 1;
    			-- generate the reservation number (unique)
    			SET resno = (InputRoot.XML.Reservation.FlightDetails.FlightNumber ||
    						 InputRoot.XML.Reservation.FlightDetails.FlightDate ||
    						 CAST (Environment.Variables.RESERVATIONSEQNO AS CHAR));
    			-- insert a row into the database to track this reservation
    			INSERT INTO Database.XMLPASSENGERTB (LASTNAME, FIRSTNAME, FLIGHTNO, FLIGHTDATE, CLASSTYPE, RESERVATIONNO)
    				VALUES(InputRoot.XML.Reservation.ListOfPassengers.PassengerDetails[I].LastName,
    					   InputRoot.XML.Reservation.ListOfPassengers.PassengerDetails[I].FirstName,
    					   InputRoot.XML.Reservation.FlightDetails.FlightNumber,
    					   InputRoot.XML.Reservation.FlightDetails.FlightDate,
    					   InputRoot.XML.Reservation.ListOfPassengers.PassengerDetails[I].Class,
    					   resno);
    			-- report the reservation number in the output message
    			SET OutputRoot.XML.Reservation.ListOfPassengers.PassengerDetails[I].ReservationNumber = resno;
    			SET I = I + 1;
    		END WHILE;
    
    		-- update the sequence number in the database
    		UPDATE Database.XMLFLIGHTTB AS T
    			SET RESERVATIONSEQNO = Environment.Variables.RESERVATIONSEQNO; 
    		RETURN TRUE;
    	END;
    END MODULE;
    
    CREATE FILTER MODULE MultipleOrSingleMessage
    	CREATE FUNCTION Main() RETURNS BOOLEAN
    	BEGIN
    		IF Root.XML.Reservation.Request = 'M' THEN
    			RETURN TRUE;
    		END IF;
    		IF Root.XML.Reservation.Request = 'S' THEN
    			RETURN FALSE;
    		END IF;
    		RETURN UNKNOWN;
    	END;
    END MODULE;
    
    CREATE COMPUTE MODULE BuildSingleMessage
    	CREATE FUNCTION Main() RETURNS BOOLEAN
    	BEGIN
    		SET OutputRoot = InputRoot;
    		SET OutputRoot.XML.Reservation = NULL;
    		SET OutputRoot.XML.PassengerReservationResponse.ListOfConfirmations.ClassF.Confirmation[] =
    			(SELECT X.FirstName, X.LastName AS Surname, X.ReservationNumber
    				FROM InputRoot.XML.Reservation.ListOfPassengers.PassengerDetails[] AS X
    				WHERE UPPER(X.Class) = 'F');
    		SET OutputRoot.XML.PassengerReservationResponse.ListOfConfirmations.ClassY.Confirmation[] =
    			(SELECT X.FirstName, X.LastName AS Surname, X.ReservationNumber
    				FROM InputRoot.XML.Reservation.ListOfPassengers.PassengerDetails[] AS X
    				WHERE UPPER(X.Class) = 'Y');
    		RETURN TRUE;
    	END;
    END MODULE;
    
    CREATE COMPUTE MODULE PropagateMultipleMessages
    	CREATE FUNCTION Main() RETURNS BOOLEAN
    	BEGIN
    		DECLARE I INTEGER 1;
    		DECLARE J INTEGER Environment.Variables.NoPassengers;
    		WHILE I <= J DO
    			SET OutputRoot = InputRoot;
    			SET OutputRoot.XML.Reservation = NULL;
    			SET OutputRoot.XML.PassengerReservationResponse.ListOfConfirmations.Confirmation = 
    				InputRoot.XML.Reservation.ListOfPassengers.PassengerDetails[I];
    			PROPAGATE;
    			SET I = I + 1;
    		END WHILE;
    		RETURN FALSE; -- returning false stops automatic propagation
    	END;
    END MODULE;

     

  6. The ESQL uses the Environment tree to carry data. The second SET statement in the UpdateFlightTable ESQL module populates the Environment.Variables folder with the elements (data) extracted from the flight table (XMLFLIGHTTB). The names of the elements in the folder are inherited from the column names of the flight table (XMLFLIGHTTB). The statement generates the following Environment tree. For more information, see Environment tree.
    (
       (0x1000000)Variables = (
          (0x3000000)FLIGHTDATE         = '20020220'
          (0x3000000)FLIGHTNO           = 'CA937'
          (0x3000000)ECONOMICCLASS      = 18
          (0x3000000)FIRSTCLASS         = 9
          (0x3000000)TOTALECONOMIC      = 200
          (0x3000000)TOTALFIRST         = 50
          (0x3000000)ECONOMICPRICE      = 200
          (0x3000000)FIRSTPRICE         = 300
          (0x3000000)STARTPOINT         = 'BEIJING       '
          (0x3000000)ENDPOINT           = 'LONDON        '
          (0x3000000)EconomyClassRemain = 182
          (0x3000000)FirstClassRemain   = 41
          (0x3000000)NoPassengers       = 3
       )
    )
    

    The UpdateFlightTable module uses the REFERENCE field dynamic reference and the MOVE statement (see the statements that begin DECLARE ref REFERENCE TO and While LASTMOVE(ref)) rather than the CARDINALITY statement to access repeating structures in the Message tree. Field reference variables are more efficient when accessing repeating structures.

    If CARDINALITY is used within a WHILE loop, it reduces the efficiency of the message flow's performance. The overhead of using CARDINALITY in a loop increases because every time the CARDINALITY statement is executed, it counts the number of instances in the array.

    This ESQL uses the Environment tree to carry data for purposes of the Airline Reservations sample. This is not necessarily how you would achieve the result in a real business situation.

  7. Save the message flow.

You have now created the XML_Reservation message flow, which reserves seats on a flight and builds reply messages to confirm that the reservations have been made.

Main Page icon   Back to Building the Airline Reservations sample.