C 入力ノードの機能の拡張

始める前に

以下のトピックを読み、理解していることを確認してください。
ユーザー定義ノードを作成した後、以下のオプションが使用可能になります。
  1. 外部データのバッファーへの受信
  2. スレッド化とトランザクションの制御
  3. メッセージの伝搬

外部データのバッファーへの受信

入力ノードは、ノードからの出力が正しい形式になっている限り、 ファイル・システムや FTP 接続などのどんなタイプの外部ソースからでも、データを受信することができます。 キューやデータベースへの接続には、 提供されている IBM プリミティブ・ノードと API 呼び出しを使用する必要があります。 その主な理由は、プリミティブ・ノードにはエラー処理のためのセットアップがすでになされているためです。 データベース表への直接アクセスのための mqgetmqput コマンドは使用しないでください。

ユーザーは入力データを格納する入力バッファー (またはビット・ストリーム) を準備し、 これをメッセージ・オブジェクトと関連付ける必要があります。 C API では、cniSetInputBuffer ユーティリティー関数を使用することによって、 入力メッセージを表す CciMessage オブジェクトにバッファーが割り当てられます。 以下に例を示します。
{
  static char* functionName = (char *)"_Input_run()";
  void*        buffer;
  CciTerminal* terminalObject;
  int          buflen = 4096;
  int          rc = CCI_SUCCESS;
  int          rcDispatch = CCI_SUCCESS;
  char         xmlData[] = "<A>data</A>";

  buffer = malloc(buflen);
  memcpy(buffer, &xmlData, sizeof(xmlData));
  cniSetInputBuffer(&rc, message, buffer, buflen);
}
/*propagate etc*/

free(buffer);
上記の例は、割り振られているメモリーの領域を示しています (buffer = malloc(buflen);)。 C でプログラミングしているとき、 メモリーを割り振る場合には、それが不要になったら開放しなければなりません。 メッセージがフローに伝搬されている間はいつでも、 ブローカーがこのメモリーにアクセスしようとする可能性があるので、 メモリーの解放は、同じ CciMessage に対して cniPropagate を呼び出した後にだけ行う必要があります。

スレッド化とトランザクションの制御

入力ノードの役割は、メッセージ・フローでメッセージが伝搬されたときに、 メッセージの処理を適切に終了することです。 特に、入力ノードはすべてのトランザクションをコミットまたはロールバックし、 スレッドをスレッド・プールに戻す必要があります。

各メッセージ・フロー・スレッドは、 各メッセージ・フローごとに維持されているスレッドのプールから割り振られ、 cniRun 関数で実行を開始します。 スレッドの動作は、cniDispatchThread ユーティリティー関数と適切な戻り値を使用して判断します。

本書では、一般にトランザクション という用語を、 グローバルな整合トランザクションまたはブローカー制御トランザクションのどちらかを言い表すために使用しています。 グローバルな整合トランザクションは、 XA 準拠の Transaction Manager としての WebSphere MQ か、 z/OS でのリソース・リカバリー・サービス (RRS) のどちらかによって 整合がとられます。 WebSphere Message Broker は、データベース・リソースをコミット (またはロールバック) してから、WebSphere MQ 作業単位をコミットすることによってトランザクションを制御しますが、ユーザー定義ノードが使用されている場合、ブローカーはリソースの更新を自動的にコミットすることはできません。 ユーザー定義ノードが、戻り値を使用して、トランザクションが正常かどうかを示し、 トランザクションをコミットするかロールバックするかを制御します。 ブローカーのインフラストラクチャーが処理されない例外を検出した場合、 トランザクションはロールバックされます。

以下の表では、サポートされている各戻り値と、 それぞれがトランザクションに及ぼす影響、 および現行スレッドに対してブローカーが行う処理について説明しています。

戻り値 トランザクションへの影響 スレッドに対するブローカーの処置
CCI_SUCCESS_CONTINUE コミットされます。 cniRun 関数で同じスレッドを再度呼び出します。
CCI_SUCCESS_RETURN コミットされます。 スレッド・プールにスレッドを戻します。
CCI_FAILURE_CONTINUE ロールバックされます。 cniRun 関数で同じスレッドを再度呼び出します。
CCI_FAILURE_RETURN ロールバックされます。 スレッド・プールにスレッドを戻します。
CCI_TIMEOUT 適用外。 関数が、入力メッセージを待っている間に、定期的にタイムアウトします。 cniRun 関数で同じスレッドを再度呼び出します。
以下は、 cniDispatchThread 関数での SUCCESS_RETURN 戻りコードの使用例です。
{
  ...
    cniDispatchThread(&rcDispatch, ((NODE_CONTEXT_ST *)context)->nodeObject);
  ...
    if (rcDispatch == CCI_NO_THREADS_AVAILABLE) return CCI_SUCCESS_CONTINUE;
    else return CCI_SUCCESS_RETURN;
}     

メッセージの伝搬

メッセージを伝搬する前に、何のメッセージ・フロー・データを伝搬するか、 また、どのターミナルでデータを受信するかを決定する必要があります。

terminalObject は、ユーザー定義ノード自体が保守しているリストに由来します。

たとえば、出力ターミナルにメッセージを伝搬するには、 次のように、cniPropagate 関数を使用します。
  if (terminalObject) {
    if (cniIsTerminalAttached(&rc, terminalObject)) {
            if (rc == CCI_SUCCESS) {
                cniPropagate(&rc, terminalObject, destinationList, exceptionList, message);
      }
    }

上記の例で、 cniIsTerminalAttached 関数は、 メッセージを指定されたターミナルに伝搬できるか検査するために使用されています。 cniIsTerminalAttached 関数が使用されず、 ターミナルがコネクターによって他のノードに付加されていない場合、 メッセージは伝搬されません。 この関数を使用するならば、 ターミナルが接続されていない場合でも、 ノードの動作を変更することができます。

特記事項 | 商標 | ダウンロード | ライブラリー | サポート | フィードバック
Copyright IBM Corporation 1999, 2005 Last updated: 11/07/2005
as24988_