XML_Reservation メッセージ・フローの作成

XML_Reservation メッセージ・フローを作成するには、以下の手順に従ってください。 詳細な指示については、各ステップの終わりにあるリンクをクリックしてください。

XML_Reservation メッセージ・フローを作成および構成するには、次のようにします。

  1. XML_Reservation という新規メッセージ・フローを作成します。
    その方法については、メッセージ・フローの作成を参照してください。
  2. メッセージ・フロー・エディターで、次の表にリストされているノードを追加して名前変更します。
    その方法については、ノードの追加を参照してください。
    ノード・タイプ ノード名
    MQInput XML_RESERVATION_IN
    MQOutput XML_RESERVATION_OUT
    MQOutput XML_RESERVATION_FAIL
    Compute UpdatePassengerTable
    Compute BuildSingleMessage
    Compute PropagateMultipleMessages
    Database UpdateFlightTable
    Filter MultipleOrSingleMessage
    Throw InvalidRequest
    Trace LogException
  3. 次の表に示されているように、ノードを接続します。
    その方法については、ノードの接続を参照してください。
    ノードが正しく接続されたかどうかを確認する には、『XML_Reservation メッセージ・フローについて』の図を参照してください。
    ノード名 ターミナル 接続先のノード
    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. 次の表に示されているように、ノードのプロパティーを構成します。 この表に代替値が示されていなければ、すべてのプロパティーに関してデフォルト値を受け入れます。
    その方法については、ノードの構成を参照してください。
    ノード名 ページ プロパティー
    XML_RESERVATION_IN 基本 キュー名 XML_RESERVATION_IN
    (これは、メッセージ・フローがメッセージを取り出すローカル・キューです。)
    デフォルト メッセージ・ドメイン XML
    (これは、汎用 XML パーサーを使用するようにブローカーに指示します。)
    UpdateFlightTable 基本 データ・ソース RESERVDB
    (これは、このノードで使用されるデータベースです。)
    基本 ステートメント (Statement) UpdateFlightTable
    (これは、処理中にこのノードによって使用される ESQL モジュールの名前です。 この名前は、ESQL ファイル中の CREATE DATABASE MODULE ステートメント中の名前と一致していなければなりません。)
    UpdatePassengerTable 基本 データ・ソース RESERVDB
    (これは、このノードで使用されるデータベースです。)
    基本 ESQL モジュール UpdatePassengerTable
    (これは、処理中にこのノードによって使用される ESQL モジュールの名前です。 この名前は、ESQL ファイル中の CREATE COMPUTE MODULE ステートメント中の名前と一致していなければなりません。)
    XML_RESERVATION_OUT 基本 キュー名
    (キューはブローカーと同じキュー・マネージャーで定義されるので、キュー・マネージャーの名前を指定する必要はありません。)
    XML_RESERVATION_OUT
    (これは、メッセージ・フローがメッセージを書き込むローカル・キューです。)
    LogException 基本 宛先 (Destination) ローカル・エラー・ログ
    (これは、トレース情報をローカル・エラー・ログに書き込むように、ノードに指示します。 Windows 上では、ローカル・エラー・ログはイベント・ビューアーです。Linux 上では、ローカル・エラー・ログは syslog です。)
    基本 パターン (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}

    (これは、日時情報と、例外リスト中のエラーに関する情報を抽出します。)
    基本 メッセージ番号 3052
    XML_RESERVATION_FAIL 基本 キュー名
    (キューはブローカーと同じキュー・マネージャーで定義されるので、キュー・マネージャーの名前を指定する必要はありません。)
    XML_RESERVATION_FAIL
    (これは、処理が失敗した場合にメッセージ・フローがメッセージを書き込む場所です。)
  5. XML Airline メッセージ・フローのプロジェクトで、ESQL ファイル・プロジェクトをダブルクリックして ESQL エディターで開き、以下の ESQL コード・モジュールを ESQL ファイルにコピーして貼り付けます。 詳しくは、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. Compute、Database、および Filter の各ノードで、ノードを右マウス・ボタン・クリックし、「プロパティー」をクリックして、「プロパティー」ダイアログを開きます。 「ESQL モジュール」フィールドで、そのノードと関連付ける ESQL ファイルのモジュールの名前を入力します。 たとえば、Propagate Multiple Messages ノードの場合、PropagateMultipleMessages と入力しますが、これは ESQL ファイル内に貼り付けた ESQL のモジュールの名前です。 「OK」をクリックしてダイアログを閉じます。

ESQL は、Environment ツリーを使用してデータを運びます。ただし、実際のビジネス状況では、同じ結果を達成するのに必ずしもこの方法が使用されるとは限りません。 UpdateFlightTable ESQL モジュール内の 2 番目の SET ステートメントは、「Environment.Variables」フォルダーに、フライト表 (XMLFLIGHTTB) から抽出されたエレメント (データ) を取り込みます。 このフォルダー内のエレメントの名前は、フライト表 (XMLFLIGHTTB) の列名から継承されます。 このステートメントによって、以下の Environment ツリーが生成されます。 Environment についての詳細は、論理メッセージ・ツリーを参照してください。

(
   (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
   )
)

UpdateFlightTable モジュールは、CARDINALITY ステートメントではなく REFERENCE フィールド動的参照および MOVE ステートメント (DECLARE ref REFERENCE TO および While LASTMOVE(ref) で始まるステートメントを参照) を使用して、Message ツリー内の反復構造にアクセスします。 反復構造にアクセスする場合、フィールド参照変数の方が効率的です。

CARDINALITY を WHILE ループ内で使用すると、メッセージ・フローのパフォーマンスの効率が低下します。 CARDINALITY ステートメントが実行されるたびに配列内のインスタンスの数を数えるため、ループ内で CARDINALITY の使用のオーバーヘッドが増大します。

この ESQL は、Environment ツリーを使用して、Airline Reservations サンプル用のデータを実行します。 ただしこれは、実際のビジネス状況で結果をアーカイブする方法とは異なる場合もあります。

これで、XML_Reservation メッセージ・フローの作成が終わりました。このメッセージ・フローはフライトの座席を予約し、予約されたことを確認する応答メッセージを作成します。

メインページのアイコン   『Airline Reservations サンプルのビルド』に戻る