C メッセージ処理または出力ノードの機能の拡張

始める前に

以下のトピックを読み、理解していることを確認してください。

メッセージ・データへのアクセス

多くの場合、ユーザー定義ノードは、入力ターミナルで受け取ったメッセージの内容にアクセスする必要があります。 メッセージは、構文エレメントのツリーとして表されます。 ユーティリティー関数のグループが、メッセージ管理、メッセージ・バッファー・アクセス、 構文エレメント・ナビゲーション、および構文エレメント・アクセス用に提供されます。 (ユーティリティー関数の詳細については、C ノード・ユーティリティー関数を参照してください。)

実行する可能性の高い照会のタイプには、次のようなものがあります。
  • 必要なメッセージ・オブジェクトのルート・エレメントを取得する。
  • エレメント・ツリーのビット・ストリーム表現にアクセスする。
  • 名前によって子エレメントや兄弟エレメントを要求することにより、ツリーをナビゲートまたは照会する。
  • エレメントのタイプを取得する。
  • エレメントの値を取得する。

例えば、本体の最初の子の名前とタイプを照会するには、次のようにします。

void cniEvaluate( ...
){                                    
  ...
/* Navigate to the target element */
  rootElement = cniRootElement(&rc, message);
  bodyElement = cniLastChild(&rc, rootElement);
  bodyFirstChild = cniFirstChild(&rc, bodyElement);

/* Query the name and value of the target element */
  cniElementName(&rc, bodyFirstChild, (CciChar*)&elementname, sizeof(elementName));
  bytes = cniElementCharacterValue(
&rc, bodyfirstChild, (CciChar*)&eValue, sizeof(eValue));
  ...    
}

エレメント・ツリーのビット・ストリーム表現にアクセスするには、cniElementAsBitstream 関数を使用することができます。この関数を使用すると、メッセージ内の任意のエレメントのビット・ストリーム表現を取得できます。 この関数およびサンプル・コードの使用方法の詳細については、cniElementAsBitstreamを参照してください。

メッセージ・オブジェクトの変換

受信した入力メッセージは読み取り専用です。 したがって、メッセージを変換するには、まず cniCreateMessage 関数を使用して、それを新しい出力メッセージに書き込む必要があります。 入力メッセージからエレメントをコピーするか、 あるいは、新しいエレメントを作成してそれらをメッセージに付加することができます。 新しいエレメントは通常はパーサーのドメインに入ります。

以下に例を示します。
  1. 着信メッセージを新しいメッセージに書き込むには、次のようにします。
    {
      ...
      context = cniGetMessageContext(&rc, message));
      outMsg = cniCreateMessage(&rc, context));
      ...
    }
  2. 新しいメッセージのコピーを作成するには、以下のようにします。
    cniCopyElementTree(&rc, sourceElement, targetElement);
  3. ターゲット・エレメントの値を変更するには、次のようにします。
      cniSetElementIntegerValue(&rc, targetElement, L"newValue", 8); 
  4. メッセージをファイナライズして伝搬したら、 次のように、cniDeleteMessage 関数を使用して、出力メッセージを削除する必要があります。
     cniDeleteMessage(&rc, outMsg);
変換の一部として、新規メッセージ本体を作成する必要があるかもしれません。 新規メッセージ本体を作成するために、以下の関数が使用可能です。
cniCreateElementAsFirstChildUsingParser
cniCreateElementAsLastChildUsingParser
cniCreateElementAfterUsingParser
cniCreateElementBeforeUsingParser
これらの関数は、パーサーをメッセージ・ツリー・フォルダーに割り当てるための固有のものであるため、使用する必要があります。
以下の関数は、所有パーサーをフォルダーに関連付けないため、メッセージ本体を作成する時、これらを使用しないでください。
cniCreateElementAsFirstChild
cniCreateElementAsLastChild
cniCreateElementAfter
cniCreateElementBefore

ESQL へのアクセス

ノードは、Compute ノードの ESQL 構文を使用して ESQL 式を呼び出すことができます。 ユーザーは、ESQL 式を使用してメッセージのコンポーネントを作成および変更し、 cniSqlCreateStatementcniSqlSelectcniSqlDeleteStatement 、および cniSqlExecute 関数を使用して、 入力メッセージと外部データベースのデータの両方を参照できます。

例えば、 データベース表内の列の内容から Result エレメントを取り込むには、 次のようにします。

{
  ...
  sqlExpr = cniSqlCreateStatement(&rc,
   (NODE_CONTEXT_ST *)context->nodeObject,
   L"DB", CCI_SQL_TRANSACTION_AUTO,
   L"SET OutputRoot.XML.Result[] = (SELECT T.C1 AS Col1 FROM Database.TABLE AS T;");
  ...
  cniSqlSelect(&rc, sqlExpr, destinationList, exceptionList, message, outMsg);
  cniSqlDeleteStatement(&rc, sqlExpr);
  ...                                                               
}

ESQL の詳細については、ESQL の概要を参照してください。

ユーザー定義ノードが主として ESQL を使用する場合は、compute ノードの使用を検討してください (Compute ノードを参照してください)。

メッセージの伝搬

メッセージを伝搬する前に、何のメッセージ・フロー・データを伝搬するか、 また、どのターミナルでデータを受信するかを決定する必要があります。
  1. メッセージが変更されている場合は、 そのメッセージを伝搬する前に、cniFinalize 関数を使用してファイナライズする必要があります。 以下に例を示します。
          cniFinalize(&rc, outMsg, CCI_FINALIZE_NONE);
  2. terminalObject は、ユーザー定義ノード自体が保守しているリストに由来します。 出力ターミナルにメッセージを伝搬するため、 次のように、cniPropagate 関数を使用します。
      if (terminalObject) {
        if (cniIsTerminalAttached(&rc, terminalObject)) {
          if (rc == CCI_SUCCESS) {
            cniPropagate(&rc, terminalObject, destinationList, exceptionList, outMsg);
          }
        }

    上記の例で、 cniIsTerminalAttached 関数は、 メッセージを指定されたターミナルに伝搬できるか検査するために使用されています。 cniIsTerminalAttached 関数が使用されず、 ターミナルがコネクターによって他のノードに付加されていない場合、 メッセージは伝搬されず、警告メッセージは戻されません。 cniIsTerminalAttached 関数を使用して、それが起こらないようにしてください。

  3. cniCreateMessage を使用して新しい出力メッセージを作成した場合は、 メッセージを伝搬した後で、次のようにして cniDeleteMessage 関数を使用して出力メッセージを削除する必要があります。
     cniDeleteMessage(&rc, outMsg);

出力装置への書き込み

変換されたメッセージは、逐次化してビット・ストリームにする必要があります。 その後、そのビット・ストリームにアクセスして、それを出力装置に書き込むことができます。メッセージは、 cniWriteBuffer 関数を使用してビット・ストリームに書き込みます。 例を以下に示します。
{
  ...
  cniWriteBuffer(&rc, message);
  writeToDevice(cniBufferPointer(&rc, message), cniBufferSize(&rc, message));
  ...                                                               
}
この例では、メソッド writeToDevice は、 出力装置にビット・ストリームを書き込むユーザー作成メソッドです。

メッセージが逐次化できるのは、一度だけであることに注意してください。

注: WebSphere MQ キューに書き込むときは、提供されている MQOutput ノードを使用しなければなりません。 これは、ブローカーが、スレッド単位で、内部的に WebSphere MQ 接続およびオープン・キュー・ハンドルを保守し、 それらはパフォーマンスを最適化するためにキャッシュに入れられるからです。 さらに、ブローカーは特定の WebSphere MQ イベントの発生時に リカバリー・シナリオを処理しますが、 WebSphere MQ MQI 呼び出しが ユーザー定義出力ノードで使用された場合、これは不利な影響を受けます。
特記事項 | 商標 | ダウンロード | ライブラリー | サポート | フィードバック
Copyright IBM Corporation 1999, 2006 最終更新: 08/21/2006
as24989_