BLOB ドメインでのメッセージの操作

このトピックでは、BLOB ドメインに属し、 BLOB パーサーによって構文解析されるメッセージを処理する場合の情報が提供されます。

BLOB メッセージには事前定義された構造がないため、BLOB メッセージの内容を操作することはできません。 ただし、その内容を、ビット・ストリーム内の既知の位置を使用して参照すること、 またそのメッセージをその内容に関する最小の知識で処理することは可能です。

BLOB メッセージ本文パーサーがツリー構造を作成する方法は、他のメッセージ本文パーサーとは違います。 このツリー構造にはルート・エレメント BLOB があり、 データを含む子エレメントがあります (これも BLOB と呼ばれる)。

BLOB データ内の情報の特定の部分の位置がわかっている場合、サブストリングを使用してメッセージの内容を参照できます。 たとえば、以下の式は、メッセージ本文の 10 番目のバイトを識別します。

InputBody.BLOB.BLOB[10]

以下の式は、オフセット 10 から始まる 10 バイトのメッセージ・データを参照します。

SUBSTRING(InputBody.BLOB.BLOB from 10 for 10)

BLOB メッセージ操作の例

この例は、可変長 BLOB メッセージの操作方法を示すものです。 この例は、可変長 BLOB メッセージを受信するメッセージ・フローを構成しており、 MRM パーサーの起動によってフィールドのいくつかを構文解析し、 解析された情報に基づいて正しい出力キューに出力メッセージを経路指定することを前提としています。

入力メッセージは BLOB 形式であり、組み込み NULL ('x00') が含まれていることが前提です。したがって、 そのメッセージをヌル終了ストリングとして定義することはできません。

この例では、次のような ESQL を示します。

  • BLOB メッセージ長を計算する
  • それを 16 進形式に変換する
  • それを、BLOB メッセージの先頭に付加する

これにより、BLOB メッセージの前に整数の長さフィールドを付けたメッセージ・モデルとして定義できるようになります。

さらにこの例では、この BLOB メッセージを CWF に変換し、 メッセージを処理して、付加された長さフィールドを除去する方法も示されています。

この例の入力レコードの形式は、次のとおりです。

  • バージョン番号: ストリング、11 文字
  • 店舗番号: ストリング、10 文字

    このフィールドは、ユーザー定義の基準に基づいて異なる複数のキューにメッセージを送るための整数値として使用されます。

  • 店舗データ: 可変長のバイナリー・データ

新しいメッセージの定義

以下のエレメントおよびタイプを組み込んだ、新規メッセージ BLOB_Example の定義

  • B_LEN, xsd:integer
  • VERSION_NUM, xsd:string, 長さ 11
  • STORE_NUM, xsd:string, 長さ 10
  • BIN_BLOB, xsd:binary, 長さ B_LEN

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

ここでは、メッセージ・フローの特性について説明します。 この例のフローをインプリメントしたい場合には、メッセージ・フローの定義を完了し (たとえば、3 つのサブフローを作成して、 偽の、不明な、および障害のケースを扱うために ここで使用されている出力ノードと取り替えることにより)、 またそのメッセージ・フローのデプロイメントおよび実行に必要なサポートを提供する (たとえば、 そのフローをデプロイするブローカーのためのキュー・マネージャーに インバウンドおよびアウトバウンド・キューを作成する) 必要があります。

  1. サブフロー LESS_THAN を作成します。このタスクについては、LESS_THAN サブフローの作成で説明しています。
  2. 新しいメッセージ・フローを作成します。 「メッセージ・フロー・エディター」ビューに次のノードを追加します。1 つの MQInput ノード、1 つの Compute ノード、1 つの ResetContentDescriptor ノード、1 つの Filter ノード、3 つの MQOutput ノード、および LESS_THAN サブフロー。
  3. MQInput ノードの名前を INQUEUE に変更し、その 「キュー名」プロパティーを INQUEUE に設定します。
  4. 出力ターミナルを Compute ノードに接続します。
  5. デフォルト値の Compute ノード名を Add_length に変更します。 Compute ノードを構成して、BIN_BLOB の長さを計算し、 それをフィールド B_LEN の BLOB_Example メッセージの先頭に付加します。
    1. ノードを右クリックして、「ESQL のオープン」をクリックします。
    2. このノードに対して、モジュールの以下の ESQL をコーディングします。
      -- Declare local variables
      DECLARE I INTEGER 1;
      DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
      DECLARE MSGLEN CHARACTER;
      DECLARE NUMBER INTEGER;
      DECLARE RESULT INTEGER;
      DECLARE REM    INTEGER;
      
      -- Copy message headers
      WHILE I < J DO
        SET OutputRoot.*[I] = InputRoot.*[I];
        SET I = I + 1;
      END WHILE;
      -- 
      -- Set MSGLEN to non NULL to avoid errors when concatenating the first time --
      SET MSGLEN = 'X';
      -- 
      -- Get the length of the BLOB and substract the length of VERSION_NUM and STORE_NUM (11+10)
      SET NUMBER = LENGTH("InputRoot"."BLOB"."BLOB")-21; 
      -- 
      -- Convert NUMBER to hexadecimal. The remainder of dividing by 16 is calculated recursively. -- 
      WHILE NUMBER > 15 DO
         SET RESULT = NUMBER/16;      
         SET REM    = NUMBER - RESULT*16;      
         SET MSGLEN = 
          CASE
            WHEN REM < 10  THEN CAST(REM AS CHARACTER) || MSGLEN               
            WHEN REM = 10  THEN 'A' || MSGLEN              
            WHEN REM = 11  THEN 'B' || MSGLEN              
            WHEN REM = 12  THEN 'C' || MSGLEN              
            WHEN REM = 13  THEN 'D' || MSGLEN               
            WHEN REM = 14  THEN 'E' || MSGLEN              
            ELSE                'F' || MSGLEN          
          END;      
         SET NUMBER = RESULT; 
      END WHILE;
      SET REM = NUMBER;
      SET MSGLEN =
         CASE                
           WHEN REM < 10  THEN CAST(REM AS CHARACTER) || MSGLEN               
           WHEN REM = 10  THEN 'A' || MSGLEN              
           WHEN REM = 11  THEN 'B' || MSGLEN              
           WHEN REM = 12  THEN 'C' || MSGLEN              
           WHEN REM = 13  THEN 'D' || MSGLEN               
           WHEN REM = 14  THEN 'E' || MSGLEN              
           ELSE                'F' || MSGLEN          
         END; 
      -- 
      -- Add leading '0's up to a length of 9 to be able to cast as BLOB.
      -- Remember it started with MSGLEN set to X (length 1)
      WHILE LENGTH(MSGLEN) < 9 DO
         SET MSGLEN = '0' || MSGLEN; END WHILE; 
      -- 
      -- Change to appropriate endian (PLATFORM DEPENDENT) 
      -- If no endian swapping needed then remember to get rid of the last character as below --
      SET MSGLEN = SUBSTRING(MSGLEN FROM 1 FOR 8); 
      -- 
      SET MSGLEN = SUBSTRING(MSGLEN FROM 7 FOR 2) || SUBSTRING(MSGLEN FROM 5 FOR 2) ||
                   SUBSTRING(MSGLEN FROM 3 FOR 2) || SUBSTRING(MSGLEN FROM 1 FOR 2);
      SET "OutputRoot"."BLOB"."BLOB" = CAST(MSGLEN AS BLOB) || "InputRoot"."BLOB"."BLOB"; 
      
  6. Compute ノードの Out ターミナルを ResetContentDescriptor ノードに接続します。
  7. ResetContentDescriptor ノード名を ResetContent_2_MRM に変更します。 以下のように、ノードを構成します。
    1. 「メッセージ・ドメイン」MRM に設定します。
    2. 「メッセージ・ドメインのリセット」チェック・ボックスを選択します。
    3. 「メッセージ・セット」を BLOB_Example メッセージを定義したメッセージ・セットの ID に設定します。
    4. 「メッセージ・セットのリセット」チェック・ボックスを選択します。
    5. 「メッセージ・タイプ」BLOB_Example に設定します。
    6. 「メッセージ・タイプのリセット」チェック・ボックスを選択します。
    7. を定義した CWF 物理フォーマットの名前に設定します (たとえば、デフォルト値 CWF1)。
    8. 「メッセージ形式のリセット」チェック・ボックスを選択します。
  8. ResetContentDescriptor ノードの Out ターミナルを Filter ノードに接続します。
  9. Filter ノードの名前を Route_2_QUEUE に変更します。以下のように、ノードを構成します。
    1. ノードを右クリックして、「ESQL のオープン」をクリックします。
    2. このノードに対して、ESQL モジュールの以下の ESQL ステートメントをコーディングします。
      CAST("Body"."e_STORE_NUM" AS INTEGER) < 151    

      このステートメントは、「店舗番号」からの入力メッセージが 151 未満であり、 特定のキューにルーティングされるという前提に基づいています。 他のどんな適切なテストをもコーディングすることができます。

  10. Filter の出力ターミナルを次のように接続します。
    1. True ターミナルを LESS_THAN という名前のサブフロー・ノード (下を参照) へ。
    2. False ターミナルを、「キュー名」 のプロパティー・セットが GREATER_THAN で、GREATER_THAN という名前の MQOutput ノードへ。
    3. Unknown ターミナルを、「キュー名」 プロパティー・セットが INVALID で、INVALID という名前の MQOutput ノードへ。
    4. Failure を、「キュー名」 のプロパティー・セットが ERROR で、ERROR という名前の MQOutput ノードへ。

LESS_THAN サブフローの作成

このサブフローは期待される形式 (Filter ノードで実行されたテストが true を戻した) を持つメッセージを扱います。障害のないメッセージは、出力キューにその元の形式で 書き込まれます。メッセージは MRM から変換されて BLOB に戻り、 付加した 4 バイト (フィールド B_LEN) が除去されます。

このサブフローについて、

  1. LESS_THAN という名前の新規メッセージ・フローを作成します。
  2. 「エディター」ビューで、Input ノード、ResetContentDescriptor ノード、 Compute ノード、および MQOutput ノードを追加します。
  3. その Input ノードの名前を InputTerminal1 に変更し、 その Out ターミナルをその ResetContentDescriptor ノードに接続します。
  4. ResetContentDescriptor の名前を ResetContent_2_BLOB に 変更し、以下のノードを構成します。
    1. 「メッセージ・ドメイン」BLOB に設定します。
    2. 「メッセージ・ドメインのリセット」チェック・ボックスを選択します。
  5. ResetContentDescriptor ノードを Compute ノードに接続します。
  6. Compute ノードの名前を Remove_length に変更し、以下のノードを構成します。
    1. ノードを右クリックして、「ESQL のオープン」をクリックします。
    2. このノードに対して、モジュールの以下の ESQL をコーディングします。
      -- Copy message headers
      DECLARE I INTEGER 1;
      DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
      
      WHILE I < J DO
        SET OutputRoot.*[I] = InputRoot.*[I];
        SET I = I + 1;
      END WHILE;
      -- 
      -- Remove the 4 bytes length field added previously --
      SET "OutputRoot"."BLOB"."BLOB" = SUBSTRING("InputRoot"."BLOB"."BLOB" FROM 5);

      BLOB メッセージの操作をサポートするため、その先頭に付加した 4 バイトが この Compute ノードにより除去されます。

      メッセージの既存ヘッダーの基数値に初期設定されている、変数 J の使用に注意してください。これは、以下の WHILE 文をコーディングする場合に起こる、ループのそれぞれの反復上での基数の計算より効率的です。

      WHILE I < CARDINALITY(InputRoot.*[]) DO
  7. Compute ノードの Out ターミナルを MQOutput ノードに接続します。
  8. MQOutput ノードの名前を Output_success に変更し、「キュー・マネージャー名」および 「キュー名」を設定してノードを構成します。 これらの MQOutput ノードのプロパティーをプロモートして、 それらのプロパティーをメッセージ・フローのレベルで指定できるようにすると便利でしょう。
特記事項 | 商標 | ダウンロード | ライブラリー | サポート | フィードバック
Copyright IBM Corporation 1999, 2005 Last updated: 11/07/2005
ac11640_