始める前に
入力ノードは、ノードからの出力が正しい形式になっている限り、 ファイル・システムや FTP 接続などのどんなタイプの外部ソースからでも、データを受信することができます。 キューやデータベースへの接続には、 提供されている IBM プリミティブ・ノードと API 呼び出しを使用する必要があります。 その主な理由は、プリミティブ・ノードにはエラー処理のためのセットアップがすでになされているためです。 WebSphere MQ キューへの直接アクセスのための mqget や mqput コマンドは使用しないでください。
{ static char* functionName = (char *)"_Input_run()"; void* buffer; CciTerminal* terminalObject; int buflen = 4096; int rc = CCI_SUCCESS; int rcDispatch = CCI_SUCCESS; buffer = readFromDevice(&buflen); cniSetInputBuffer(&rc, message, buffer, buflen);} /*propagate etc*/
入力ノードの役割は、メッセージ・フローでメッセージが伝搬されたときに、 メッセージの処理を適切に終了することです。 特に、入力ノードはすべてのトランザクションをコミットまたはロールバックし、 スレッドをスレッド・プールに戻す必要があります。
各メッセージ・フロー・スレッドは、 各メッセージ・フローごとに維持されているスレッドのプールから割り振られ、 cniRun 関数で実行を開始します。 スレッドの動作は、cniDispatchThread ユーティリティー関数と適切な戻り値を使用して判断します。
cniRun 関数から、cniDispatchThread ユーティリティー関数を呼び出すと、別のスレッドが cniRun 関数の実行を開始することができるようになります。 別のスレッドを実行する最適のタイミングは、関数が新しいスレッドでデータを処理することが可能であると設定した直後です。
本書では、一般にトランザクション という用語を、 グローバルな整合トランザクションまたはブローカー制御トランザクションのどちらかを言い表すために使用しています。 グローバルな整合トランザクションは、 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(&rcDispatch, ((NODE_CONTEXT_ST *)context)->nodeObject); ... if (rcDispatch == CCI_NO_THREADS_AVAILABLE) return CCI_SUCCESS_CONTINUE; else return CCI_SUCCESS_RETURN; }
メッセージを伝搬する前に、何のメッセージ・フロー・データを伝搬するか、 また、どのターミナルでデータを受信するかを決定する必要があります。
terminalObject は、ユーザー定義ノード自体が保守しているリストに由来します。
if (terminalObject) { if (cniIsTerminalAttached(&rc, terminalObject)) { if (rc == CCI_SUCCESS) { cniPropagate(&rc, terminalObject, destinationList, exceptionList, message); } }
上記の例で、 cniIsTerminalAttached 関数は、 メッセージを指定されたターミナルに伝搬できるか検査するために使用されています。 cniIsTerminalAttached 関数が使用されず、 ターミナルがコネクターによって他のノードに付加されていない場合、 メッセージは伝搬されず、警告メッセージは戻されません。 cniIsTerminalAttached 関数を使用して、それが起こらないようにしてください。