メッセージ・フローにメッセージを受信するためのユーザー定義入力ノードを C で作成します。
ロード可能インプリメンテーション・ライブラリー、または LIL は C ノードのインプリメンテーション・モジュールです。 LIL は共用ライブラリーまたはダイナミック・リンク・ライブラリー (DLL) としてインプリメントされますが、ファイル拡張子は .dll ではなく .lil です。
ノード用に作成するインプリメンテーション関数のリストは、C ノード・インプリメンテーション関数にあります。 ランタイム・ブローカーにインプリメントされたユーティリティー関数を呼び出して、ノード操作に役立てることもできます。これらの関数のリストは C ノード・ユーティリティー関数 にあります。
WebSphere® Message Broker では、SwitchNode および TransformNode という名前の 2 つのサンプル・ユーザー定義ノードのソースが準備されています。 これらのノードは現行の状態で使用することもできますし、変更を加えてもかまいません。
ブローカーに対してユーザー定義ノードを宣言して定義するには、初期化関数 bipGetMessageflowNodeFactory を LIL に含めます。 以下のステップは、ブローカーが初期化関数をどのようにして呼び出し、初期化関数がユーザー定義ノードをどのようにして宣言および定義するかについての概要です。
ノードをインスタンス化するには、次のようにします。
属性は、ブローカーを開始するとき、 あるいは新しい値を持つメッセージ・フローを再デプロイするときに設定します。
{
const CciChar* ucsAttr = CciString("nodeTraceSetting", BIP_DEF_COMP_CCSID) ;
insAttrTblEntry(p, (CciChar*)ucsAttr, CNI_TYPE_INTEGER);
_setAttribute(p, (CciChar*)ucsAttr, (CciChar*)constZero);
free((void *)ucsAttr) ;
}
{
const CciChar* ucsAttr = CciString("nodeTraceOutfile", BIP_DEF_COMP_CCSID) ;
insAttrTblEntry(p, (CciChar*)ucsAttr, CNI_TYPE_STRING);
_setAttribute(p, (CciChar*)ucsAttr, (CciChar*)constSwitchTraceLocation);
free((void *)ucsAttr) ;
}
入力ノードがあることをブローカーが認識している場合、 ブローカーは定期的にこのノードの cniRun 関数を呼び出します。 cniRun 関数は、実行すべきアクションを判断しなければなりません。 処理に使用できるデータがあれば、cniRun 関数はメッセージを伝搬できます。 処理に使用できるデータがなければ、cniRun 関数は CCI_TIMEOUT とともに制御を戻して、ブローカーが構成変更を続行できるようにします。
If ( anything to do )
CniDispatchThread;
/* do the work */
If ( work done O.K.)
Return CCI_SUCCESS_CONTINUE;
Else
Return CCI_FAILURE_CONTINUE;
Else
Return CCI_TIMEOUT;
入力ノードは通常、 最初に入力メッセージを構文解析するメッセージ・パーサーを判別します。 例えば、MQInput ノードは、MQMD ヘッダーを構文解析するために MQMD パーサーが必要であることを指示します。 ユーザー定義入力ノードは、デフォルトとして組み込まれる、以下の属性を使用またはオーバーライドすることによって、適切なヘッダーかメッセージ・パーサー、および構文解析の制御のモードを選択することができます。
CciFactory LilFactoryExportPrefix * LilFactoryExportSuffix bipGetMessageflowNodeFactory()
{
....
CciFactory* factoryObject;
....
factoryObject = cniCreateNodeFactory(0, (unsigned short *)constPluginNodeFactory);
...
vftable.iFpCreateNodeContext = _createNodeContext;
vftable.iFpSetAttribute = _setAttribute;
vftable.iFpGetAttribute = _getAttribute;
...
cniDefineNodeClass(&rc, factoryObject, (CciChar*)constSwitchNode, &vftable);
...
return(factoryObject);
}
CciContext* _createNodeContext(
CciFactory* factoryObject,
CciChar* nodeName,
CciNode* nodeObject
){
NODE_CONTEXT_ST* p;
...
/* Allocate a pointer to the local context */
p = (NODE_CONTEXT_ST *)malloc(sizeof(NODE_CONTEXT_ST));
/* Create attributes and set default values */
{
const CciChar* ucsAttrName = CciString("firstParserClassName", BIP_DEF_COMP_CCSID);
const CciChar* ucsAttrValue = CciString("MYPARSER", BIP_DEF_COMP_CCSID) ;
insAttrTblEntry(p, (CciChar*)ucsAttrName, CNI_TYPE_INTEGER);
/*see sample BipSampPluginNode.c for implementation of insAttrTblEntry*/
_setAttribute(p, (CciChar*)ucsAttrName, (CciChar*)ucsAttrValue);
free((void *)ucsAttrName) ;
free((void *)ucsAttrValue) ;
}
上記のコード例では、insAttrTblEntry メソッドが呼び出されます。 このメソッドは、サンプル・ユーザー定義ノード SwitchNode および TransformNode で宣言されます。メッセージ・フローが再デプロイされたり、 実行グループの処理が (mqsistop コマンドを使用して) 停止されたりすると、 ノードは破棄されます。 ノードが破棄されるとき、cniDeleteNodeContext 関数を呼び出して、使用されていたすべてのメモリーおよび保持されていたすべてのリソースを解放する必要があります。 以下に例を示します。
void _deleteNodeContext(
CciContext* context
){
static char* functionName = (char *)"_deleteNodeContext()";
return;
}