始める前に
WebSphere Business Integration Message Broker では、SwitchNode および TransformNode という名前の 2 つのサンプル・ユーザー定義ノードのソースが準備されています。 これらのノードは現行の状態で使用することもできますし、変更を加えてもかまいません。
分散プラットフォーム上でブローカーをデプロイする予定の z/OS で、 Java ノードを開発しないでください。 これは、z/OS 上の Java のレベルが、分散プラットフォーム上で Java のレベルと互換性のある コードを作成しない可能性があるためです。
入力ノードは、ノードからの出力が正しい形式になっている限り、 どんなタイプの外部ソース (ファイル・システム、キュー、またはデータベースなど) からでも、 他の Java プログラムと同じようにデータを受信することができます。
ユーザーは入力データを格納する入力バッファー (またはビット・ストリーム) を準備し、 これをメッセージ・オブジェクトと関連付けます。 MbInputNode クラスの createMessage メソッドを使用してバイト・アレイからメッセージを作成し、 このメッセージから有効なメッセージ・アセンブリーを生成します (これらのメソッドの詳細については、Javadoc を参照してください)。 たとえば、ファイルから入力データを読み取るには、次のようにします。
FileInputStream inputStream = new FileInputStream("myfile.msg");
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
inputStream.close();
MbMessage msg = createMessage(buffer);
msg.finalizeMessage(MbMessage.FINALIZE_VALIDATE); MbMessageAssembly newAssembly = new MbMessageAssembly(assembly, msg);
メッセージ・アセンブリーを作成したら、それをノードのターミナルの 1 つに伝搬することができます。
MbOutputTerminal out = getOutputTerminal("out"); out.propagate(newAssembly);
ブローカー・インフラストラクチャーは、 メッセージ処理の完了時の WebSphere MQ やデータベースの作業単位のコミットの制御などのトランザクション問題を処理します。 しかし、ユーザー定義のノードが使用されている場合、 ブローカーはリソースの更新を自動的にコミットすることはできません。
各メッセージ・フロー・スレッドは、 各メッセージ・フローごとに維持されているスレッドのプールから割り振られ、 run メソッドで実行を開始します。
ユーザー定義ノードが戻り値を使用して、トランザクションが正常かどうかを示し、 トランザクションをコミットするかロールバックするか、 また、いつスレッドをプールに戻すかを制御します。 ブローカーのインフラストラクチャーが処理されない例外を検出した場合、 トランザクションはロールバックされます。
トランザクションとスレッド化の動作は、以下の適切な戻り値を使用して判断します。
public int run( MbMessageAssembly assembly ) throws MbException { byte[] data = getDataWithTimeout(); // user supplied method // returns null if timeout if( data == null ) return TIMEOUT; MbMessage msg = createMessage( data ); msg.finalizeMessage( MbMessage.FINALIZE_VALIDATE ); MbMessageAssembly newAssembly = new MbMessageAssembly( assembly, msg ); dispatchThread(); getOutputTerminal( "out" ).propagate( newAssembly ); return SUCCESS_RETURN; }
mbException クラスを使用して、 例外をキャッチして例外に接続します。 mbException クラスは、 ブローカー例外リスト内の例外の子を表す例外オブジェクトの配列を戻します。 戻される各エレメントは、その例外タイプを指定します。 例外に子が存在しない場合には、空の配列が戻されます。 次のコード・サンプルは、MbException クラスの使用法の例を示しています。
public void evaluate(MbMessageAssembly assembly, MbInputTerminal inTerm) throws MbException { try { // plug-in functionality } catch(MbException ex) { traverse(ex, 0); throw ex; // if re-throwing, it must be the original exception that was caught } } void traverse(MbException ex, int level) { if(ex != null) { // Do whatever action here System.out.println("Level: " + level); System.out.println(ex.toString()); System.out.println("traceText: " + ex.getTraceText()); // traverse the hierarchy MbException e[] = ex.getNestedExceptions(); int size = e.length; for(int i = 0; i < size; i++) { traverse(e[i], level + 1); } } }
mbException クラスの使用法の詳細については、javadoc を参照してください。
こうした方法で、すべての現行の例外にアクセスできるユーザー定義メッセージ処理ノードまたは出力ノードを開発できます。 たとえば、 データベース例外をキャッチするには MbSQLStatement クラスを使用できます。 このクラスは「throwExceptionOnDatabaseError」属性の値を設定します。 この属性はデータベース・エラーの発生時のブローカー動作を決定します。 true に設定すると、 例外が送出される場合、ユーザー定義拡張機能がキャッチして処理できます。
次のコード・サンプルは、 MbSQLStatement クラスの使用法の例を示しています。
public void evaluate(MbMessageAssembly assembly, MbInputTerminal inTerm) throws MbException { MbMessage newMsg = new MbMessage(assembly.getMessage()); MbMessageAssembly newAssembly = new MbMessageAssembly(assembly, newMsg); String table = assembly.getMessage().getRootElement().getLastChild().getFirstChild().getName(); MbSQLStatement state = createSQLStatement( "dbName", "SET OutputRoot.XML.integer[] = PASSTHRU('SELECT * FROM " + table + "');" ); state.setThrowExceptionOnDatabaseError(false); state.setTreatWarningsAsErrors(true); state.select( assembly, newAssembly ); int sqlCode = state.getSQLCode(); if(sqlCode != 0) { // Do error handling here System.out.println("sqlCode = " + sqlCode); System.out.println("sqlNativeError = " + state.getSQLNativeError()); System.out.println("sqlState = " + state.getSQLState()); System.out.println("sqlErrorText = " + state.getSQLErrorText()); } getOutputTerminal("out").propagate(assembly); }
「Java 設定 (Java Settings)」パネルが表示されます。
MbInputNodeInterface をインプリメントし、 ブローカーのクラスパス (または LIL パス) に含められるすべてのクラスは、 入力ノードとしてブローカーに登録されます。 MbInputNodeInterface をインプリメントする場合は、 このクラスの run メソッドもインプリメントしなければなりません。 run メソッドは、 メッセージ・フローの開始を表し、 メッセージを公式化するデータを含んでいて、これをフローに伝搬します。 ブローカーは、スレッドが使用可能になると、 指定されたスレッド化モデルに従って run メソッドを呼び出します。
入力ノード・クラスを宣言するには、たとえば次のようにします。
package com.ibm.jplugins; import com.ibm.broker.plugin.*; public class BasicInputNode extends MbInputNode implements MbInputNodeInterface { ...
ノードがインスタンス化されるときは、 ユーザーのノード・クラスのコンストラクターが呼び出されます。 これは、ノードのターミナルを作成し、属性のデフォルト値を初期設定する場所です。
入力ノードには、いくつかの出力ターミナルが関連付けられますが、 通常は入力ターミナルはありません。 ノードに出力ターミナルを追加するには、 ノードをインスタンス化するときに createOutputTerminal メソッドを使用します。 たとえば、3 つの出力ターミナルを持つノードを作成するには、 次のようにします。
public BasicInputNode() throws MbException { createOutputTerminal ("out"); createOutputTerminal ("failure"); createOutputTerminal ("catch"); setAttribute ("firstParserClassName","myParser"); attributeVariable = new String ("none"); }
ノードの名前を宣言して、ノードがワークベンチに識別されるようにする必要があります。 すべてのノード名は末尾が "Node" でなければなりません。 名前は以下のメソッドを使用して宣言します。
public static String getNodeName() { return "BasicInputNode"; }
package com.ibm.pluginsamples; public class BasicInputNode extends MbInputNode implements MbInputNodeInterface { ...
ノード属性は、Java Bean プロパティーと同じ方法で宣言します。 属性の getter メソッドおよび setter メソッドはユーザーが作成しなければなりません。 API フレームワークは、Java Bean 内視規則を使用して属性名を推測します。 たとえば、以下の 2 つのメソッドを宣言するには、次のようにします。
private String attributeVariable; public String getFirstAttribute() { return attributeVariable; } publc void setFirstAttribute(String value) { attributeVariable = value; }
ブローカーは、このノードが firstAttribute という属性を持つことを推測します。 この名前は、内部クラス・メンバー変数名ではなく、get または set メソッドの名前に由来します。 属性はストリングとしてしか公開できないので、 get または set メソッドで、数値タイプとストリングの変換を行う必要があります。 たとえば、次のメソッドは timeInSeconds という属性を定義します。
int seconds; public String getTimeInSeconds() { return Integer.toString(seconds); } public void setTimeInSeconds(String value) { seconds = Integer.parseInt(value); }
先に述べたとおり、ブローカーは run メソッドを呼び出して入力メッセージを作成します。 このメソッドは、入力ノードのためのすべてのアプリケーション処理機能を備えている必要があります。
入力ノードは通常、 最初に入力メッセージを構文解析するメッセージ・パーサーを判別します。 たとえば、プリミティブ MQInput ノードは、 MQMD ヘッダーを構文解析するために MQMD パーサーが必要であることを指示します。 ユーザー定義入力ノードは、 デフォルトとして組み込まれる、オーバーライドも可能な以下の属性を使用することによって、 適切なヘッダーかメッセージ・パーサー、および構文解析の制御のモードを選択することができます。
onDelete メソッドは次のようにしてインプリメントします。
public void onDelete() { // perform node cleanup if necessary }
注意 |
商標 |
ダウンロード |
ライブラリー |
技術サポート |
フィードバック
![]() ![]() |
as09950_ |