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:
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 |
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 |
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 |
|
UpdatePassengerTable | Basic | Data source | RESERVDB |
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.) |
-- ************************************************ -- * 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;
( (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.
Save the message flow.