この章では、Oracle Mediatorルーティング・ルール、およびMediatorサービス・コンポーネントに対してルーティング・ルールを指定する方法について説明します。ルーティング・ルールには、トランスフォーメーション、フィルタリング、検証、マッピングおよびルーティング・ロジックが含まれます。
この章では、次の項目について説明します。
次の章で、特定のシナリオのためのルーティング・ルールの定義に関する追加情報を説明しています。
ルーティング・ルールは、必要な仲介を実行するために定義する仲介ロジックまたは実行ロジックです。メディエータを使用すると、サービス・コンシューマとサービス・プロバイダの間でデータをルーティングできます。データはサービス間をフローするため、トランスフォーメーションが必要です。ルーティングとトランスフォーメーションの2つのタスクは、メディエータの中核となる処理内容です。ルーティング・ルールにより、メディエータで処理されたメッセージを次の宛先にどのように送信するかを指定できます。ルーティング・ルールは、メディエータによるメッセージの送信先、メッセージの送信方法、およびターゲット・サービスへの送信前にメッセージ構造に加える必要がある変更の内容を指定します。
ルーティング・ルールは、サービス操作またはイベント・サブスクリプションのいずれかでトリガーできます。サービス操作は、同期、非同期または一方向のいずれかです。ルーティング・ルールには、次の2つのタイプがあります。
静的ルーティング・ルール
起動コンテキストによって変更されることのない一貫して適用される静的ルールです。
動的ルーティング・ルール
Oracle Rules Dictionaryへのルーティング・ロジックの外部化を可能にする動的ルールです。Oracle Rules Dictionaryは、ルーティング・ロジックの動的変更を可能にします。
ルーティング・ルールの作成の詳細は、第20.3.2項「静的ルーティング・ルールの作成方法」および第20.3.3項「動的ルーティング・ルールの作成方法」を参照してください。標準のメッセージ交換パターンの詳細とそれらのメディエータでの処理方法は、第24章「Oracle Mediatorのメッセージ交換パターンの理解」を参照してください。
起動コンテキストによって変更されることのない静的ルーティング・ルールです。この場合のルーティングは、エコー、別のサービスへのルーティングまたはイベントの公開のいずれかです。
静的ルールを定義するときは、次のタイプの情報を指定できます。
ターゲット・サービス
メディエータにより、指定するターゲット・サービスにメッセージが送信されます。このサービスは、WSDLインタフェースまたはJavaインタフェースとして定義できます。ターゲット・サービスの起動の詳細は、第20.3.2.1項「メディエータ・サービスまたはイベントの指定方法」を参照してください。
実行タイプ
メディエータは、ルーティング・ルールを順次(同じスレッド内で実行)またはパラレル(異なるスレッドで実行)のいずれかで実行します。実行タイプの指定方法の詳細は、第20.3.2.3項「順次実行またはパラレル実行の指定方法」を参照してください。
注意: 同期サービス起動の場合、ルーティング・ルールは必ず順次にする必要があります。 |
リプライ、コールバックおよびフォルト・ハンドラ
同期リプライ、コールバックおよびフォルト・メッセージをメディエータで処理する方法を定義できます。ハンドラの詳細は、第20.3.2.4項「レスポンス・メッセージの構成方法」、第20.3.2.7項「フォルトの処理方法」および第20.1.1.2項「静的ルーティング・ルール・コンポーネント」を参照してください。
次のタイプのメディエータの静的ルールを定義できます。
フィルタ式
メッセージのコンテンツ(ペイロードまたはヘッダー)に適用するフィルタ式を定義できます。フィルタを定義する場合、コンテンツはサービスの起動前に分析されます。たとえば、メッセージに顧客IDが含まれている場合、またはその顧客IDの値が特定のパターンと一致する場合のみサービスを起動することを指定する、フィルタ式を適用できます。フィルタ式の指定方法の詳細は、第20.3.2.8「メッセージをフィルタリングする式の指定方法」を参照してください。
トランスフォーメーション
メディエータでは、メッセージをサービスに転送する前にメッセージ・データを変換できます。データのマッピングまたは値の割当てにより、ターゲット・ペイロードで値を設定するようトランスフォーメーションを定義できます。
XSLTマッパーを使用すると、XMLスキーマ間でメッセージを変換するために、メッセージ本文全体に適用するトランスフォーメーションを定義できます。値の割当て機能では個々のフィールドを処理します。このダイアログを使用すると、メッセージ(ペイロード、ヘッダーなど)、定数または様々なシステム・プロパティ(データ・パスに存在するアダプタのプロパティなど)から値を割り当てることができます。トランスフォーメーションの定義方法の詳細は、第20.3.2.9項「トランスフォーメーションの作成方法」および第20.3.2.10項「値の割当て方法」を参照してください。
式にあるヘッダー変数へのアクセス
メディエータは、現在のルーティング・ルール操作用の式の作成に使用したSOAPヘッダーを検出できます。ヘッダー・アクセス方法の詳細は、第20.3.2.12項「フィルタおよび割当てのためのヘッダー・アクセス方法」および第20.3.2.12.2項「フィルタおよび割当てのためのプロパティ・アクセスに使用する式の手動作成」を参照してください。
Schematronベースの検証
インバウンド・メッセージの様々な部分を検証するためにメディエータが使用する必要のあるSchematronファイルを指定できます。Schematronをベースにした検証の実行方法の詳細は、第20.3.2.13項「セマンティク検証の使用方法」を参照してください。
Javaコールアウト
カスタムJavaクラス・コールアウトにより、正規表現のみでは十分でないときに、その正規表現をJavaコードと併用できるようにします。Javaコールアウトの使用方法の詳細は、第20.3.2.15「Javaコールアウトの使用方法」を参照してください。
ユーザー定義拡張関数
XSLTマッパーで使用可能な独自の関数セットです。ユーザー定義拡張関数の使用方法の詳細は、「ユーザー定義拡張関数を追加する手順」を参照してください。
静的ルーティング・ルールでは、次のコンポーネントを定義します。
リクエスト・ハンドラ: メディエータでの受信リクエストの処理方法を定義します。
リプライ・ハンドラ: コールしたサービスからの同期レスポンスをメディエータが処理する方法を定義します。
フォルト・ハンドラ: コールしたサービスからの名前付きフォルトまたは宣言済フォルトをメディエータが処理する方法を定義します。
コールバック・ハンドラ: コールしたサービスからの非同期レスポンスとコールバックをメディエータが処理する方法を定義します。
コールバックのタイムアウト・ハンドラ: 特定の非同期リクエストに対するタイムアウト処理を実行するまでに、メディエータが、非同期レスポンスとコールバックを待機する時間を定義します。
イベントの公開およびサービスの起動: ハンドラの構成に応じて、他のサービスのコールまたはイベントの公開を実行します。
Oracle Rules Dictionaryへのルーティング・ロジックの外部化を可能にする動的ルーティング・ルールです。Oracle Rules Dictionaryは、ルーティング・ルール内のルーティング・ロジックの動的変更を可能にします。この機能は、デシジョン・サービスおよびOracle Rulesを使用して、実行時にルーティング・ロジックを取得します。
動的ルーティングは、プロセスが経由するパスを決定する制御ロジックをプロセスの実行から分離します。動的ルーティングのシナリオでは、デシジョン・マトリックスによって各ルーティングに対して選択されるレベル2タイプのサービスが決定されます。レベル2タイプのサービスのデシジョンに影響を与える要因は、チャネル、顧客タイプなどです。このソリューションによって、ビジネス・アナリストはルーティングを変更せずに、このデシジョン・マトリックスを外部から変更できます。アウトバウンド・サービスを決定するためには、デシジョン・マトリックスを評価する必要があります。
動的ルーティング・ルールについては、項20.3.3項「動的ルーティング・ルールの作成方法」で詳しく説明します。
ルーティング・ルールは、順次またはパラレルで実行できます。この項では、両方の実行タイプの基本原則について説明します。操作またはイベントに順次およびパラレルの両方のルーティング・ルールがある場合は、最初に順次ルーティング・ルールが評価されてアクションが実行され、次にパラレルのルーティングがパラレル実行のためにキューに入れられます。
注意: リクエスト/レスポンス・インタフェースを使用するメディエータ・サービス・コンポーネントにパラレルのルーティング・ルールのみが設定されている場合、そのメディエータ・サービス・コンポーネントはコール元にレスポンスを返信しません。このタイプのメディエータ・サービス・コンポーネントは作成できますが、メディエータ・サービス・コンポーネントのコール元が、実行時にレスポンスを受信することはありません。 |
メディエータは、次の原則に基づいて順次ルーティング・ルールを処理します。
メディエータは、ルーティングを評価し、結果の処理を順次実行します。順次ルーティングは、コール元と同じスレッドとトランザクションで評価されます。
メディエータは常に、受信メッセージを処理しているスレッドを介して伝播されたグローバル・トランザクションにメディエータ自体を登録します。たとえば、インバウンドJCAアダプタがメディエータを起動すると、そのメディエータは、JCAアダプタが開始したトランザクションにメディエータ自体を登録します。
メディエータは、順次ルーティング・ルールの実行中に、ターゲット・コンポーネントと同じスレッドを介してトランザクションを伝播します。
外部エンティティによって伝播されたトランザクションを、メディエータがコミットまたはロールバックすることはありません。
メディエータがトランザクションを管理するのは、スレッド起動メディエータにアクティブなトランザクションが存在していない場合のみです。たとえば、メディエータがインバウンドSOAPサービスから起動された場合、そのメディエータはトランザクションを開始し、成功および失敗に応じてトランザクションをコミットまたはロールバックします。
メディエータは、次の原則に基づいてルーティング・ルールをパラレルで処理します。
メディエータは、ルーティングをキューに入れ、別々のスレッドでパラレルに評価します。
各メディエータ・サービス・コンポーネントのメッセージは、重み付けラウンド・ロビン方式で取得され、すべてのメディエータ・サービス・コンポーネントで確実にパラレル処理サイクルが受け入れられます。これは、1つ以上のメディエータ・サービス・コンポーネントで、他のコンポーネントよりも多くのメッセージが生成される場合でも同様です。使用される重み付けは、メディエータ・サービス・コンポーネントの設計時に設定されたメッセージ優先度です。メッセージ優先度の高いコンポーネントほど、多数のパラレル処理サイクルが割り当てられます。
メディエータ・サービス・コンポーネントの優先度を指定するには、メディエータ・エディタで「優先度」フィールドを設定します。優先度は0から9までの範囲で、9が最高優先度です。デフォルトの優先度は4です。
注意: 「優先度」プロパティの適用対象は、パラレルのルーティング・ルールのみです。 |
メディエータは、各パラレル・ルールを処理するための新規トランザクションを開始します。開始されたトランザクションは、メディエータのパラレル・メッセージ・デハイドレーション・ストアへのエンキューで終了します。
たとえば、メディエータ・サービス・コンポーネントにパラレルのルーティング・ルールが1つある場合は、1つのメッセージがメディエータのパラレル・メッセージ・デハイドレーション・ストアにエンキューされます。次に、ストアに対するパラレル・メッセージ・ディスパッチャがトランザクションを開始し、データベース・ストアからメッセージを読み取り、このルーティング・ルールのターゲット・コンポーネントまたはサービスを起動します。リスナー・スレッドによって開始されるトランザクションは、完全に新規のトランザクションであり、ターゲット・コンポーネントに伝播されます。
注意: メッセージのデハイドレーションでは、パラレル・ルーティング・ルール対象の受信メッセージがデータベースに格納されるため、ワーカー・スレッドはそれらのメッセージを後で処理できます。 |
メディエータはトランザクションのイニシエータであるため、これらのトランザクションをコミットまたはロールバックします。
メディエータには再シーケンサが含まれており、これは、関連がありながらも順序が正しくないメッセージを、使用されている再シーケンサのタイプと定義されているルールに基づいて適切な順序に並べ替えます。受信メッセージがランダムな順番で着信した場合、再シーケンサは、メッセージを順次または時系列の情報に基づいて並べ替え、再順序付けの構成に基づいた正しい順序でメッセージをターゲット・サービスに送信します。
メッセージの再順序付けの詳細は、第23章「Oracle Mediatorにおける再順序付け」を参照してください。
ルーティング・ルールは、インタフェースが定義されているメディエータにのみ定義できます。インタフェースの定義方法の詳細は、第19.6.1項「メディエータのインタフェースの定義方法」を参照してください。
メディエータ・エディタの「ルーティング・ルール」セクションで、ルーティング・ルールを定義します。
「ルーティング・ルール」セクションにアクセスする手順は、次のとおりです。
次のいずれかの方法を使用して、メディエータ・エディタの「ルーティング・ルール」セクションにアクセスできます。
SOAコンポジット・エディタからアクセスする方法
ルーティング・ルールを指定するメディエータを示すアイコンをダブルクリックします。
「ルーティング・ルール」セクションが表示されない場合は、「ルーティング・ルール」セクションの横のプラス(+)アイコンをクリックします。
アプリケーション・ナビゲータからアクセスする方法
「アプリケーション・ナビゲータ」からSOAプロジェクトを開き、次に「SOAコンテンツ」フォルダを開きます。
「SOAコンテンツ」フォルダで、ルーティング・ルールを指定するメディエータ・ファイルの名前をダブルクリックします。
メディエータ・ファイルには、MPLAN
拡張子が付きます。
「ルーティング・ルール」セクションが表示されない場合は、「ルーティング・ルール」セクションの横のプラス(+)アイコンをクリックします。
図20-1に、メディエータ・エディタの「ルーティング・ルール」セクションを示します。
図20-2では、「ルーティング・ルール」セクションのアイコンをリストして説明します。
この後の各項では、メディエータの静的ルーティング・ルールの定義(サービスおよびイベントの指定、ハンドラ、トランスフォーメーション、式、フィルタなどの定義)に関する情報および手順について説明します。
メディエータ・コンポーネントを作成した後は、そのメディエータをインバウンド・サービス操作またはイベント・サブスクリプション、およびアウトバウンド・ターゲットに関連付けます。ターゲットは、アウトバウンド・サービス操作またはイベントの公開です。ターゲットはメディエータがメッセージを送信する次のサービスまたはイベントを指定し、起動するサービス操作も指定します。サービスまたはイベントをターゲット・タイプとして指定できます。
ソース・メッセージは、トランスフォーメーション、検証、割当てまたは順序操作の実行後に、初期のコール元にエコーして戻すこともできます。エコーは、メディエータ・コンポーネントに同期または非同期のインタフェースがある場合にのみ指定できます。エコーが同期、非同期のいずれで行われるかは、コール元のWSDLファイルによって決まります。エコー・オプションは、インバウンド・サービス操作に対してのみ使用可能で、イベント・サブスクリプションには使用できません。
エコー・オプションの目的は、メディエータのすべての機能をコール可能なサービスとして公開することによって、他のサービスへのルーティングの必要性をなくすことです。たとえば、メディエータをコールしてトランスフォーメーション、検証または割当てを実行した後、別の場所にルーティングすることなくアプリケーションにメディエータをエコーして戻すことができます。
1つのインバウンド操作またはイベントに複数のルーティングを指定できます。各ルーティングは、1つのターゲット・サービス起動またはイベントにマップされます。したがって、特定のターゲット・サービスに対して複数のサービス起動を指定したり、複数イベントを発生させるには、各ターゲットに1つのルーティング・ルールを指定する必要があります。たとえば、メッセージ・ペイロードに基づいて、サービスに定義された次の操作から、ある操作を起動できます。
insert
update
updateid
delete
このアクションを実行するため、各操作に1つずつ、4つのルーティング・ルールを作成する必要があります。その後、各ルールにフィルタ式を指定する場合は、図20-3に示すように、メッセージ・ペイロードに基づいて各メッセージ・インスタンスに適用するターゲットおよび操作を指定できます。
サービスを起動する手順は、次のとおりです。
この手順を実行するには、WSDLドキュメントまたはJavaインタフェースでターゲット・サービスを定義する必要があります。
「ルーティング・ルール」セクションで、ルーティング・ルールを定義中の操作の横にある「追加」をクリックし、次に「静的ルーティング・ルール」を選択します。
図20-4に示すように、「ターゲット・タイプ」ダイアログが表示されます。
「サービス」をクリックします。
図20-5に示すように、「ターゲット・サービス」ダイアログが表示されます。
「ターゲット・サービス」ダイアログで、サービスが提供する操作に移動し、選択します。
「OK」をクリックします。
Javaインタフェースで定義されたターゲット・サービスを選択した場合、「必要なインタフェース」ダイアログが表示されます。「はい」をクリックして必要なWSDLファイルを作成し、次に確認ダイアログで「OK」をクリックします。
ルーティング・ルールを定義できる新規の「静的ルーティング」セクションが表示されます。
この章の後続の項の説明に従って、ルーティング・ルールを構成します。
イベントをトリガーする手順は、次のとおりです。
「ルーティング・ルール」セクションで、ルーティング・ルールを定義中の操作の横にある「追加」をクリックし、次に「静的ルーティング・ルール」を選択します。
図20-4に示すように、「ターゲット・タイプ」ダイアログが表示されます。
「イベント」をクリックします。
「イベント・チューザ」ダイアログが表示されます。
「イベント定義」フィールドの右側にある「検索」をクリックします。
「SOAリソース・ブラウザ」ダイアログが表示されます。
イベント(.edl
)・ファイルを選択し、「OK」をクリックします。
図20-6に示すように、選択したファイルに定義されているイベントが「イベント」フィールドに移入されます。
注意: 既存のイベント定義ファイルを参照するかわりに、「新規イベント定義(edl)ファイルを作成します。」をクリックし、「イベント定義ファイルの作成」ダイアログのフィールドを完了して、新規ファイルを作成できます。 |
イベントを選択します。
「OK」をクリックします。
ルーティング・ルールを定義できる新規の「静的ルーティング」セクションが表示されます。
この章の後続の項の説明に従って、ルーティング・ルールを構成します。
サービスをエコーする手順は、次のとおりです。
エコー・オプションには次の制限があります。
サービスのエコーは、メディエータのインタフェースが、次のタイプのWSDLファイルの場合のみサポートされます。
リクエスト/リプライ
リクエスト/リプライ/フォルト
リクエスト/コールバック
注意: エコー・オプションは、メディエータのインタフェースがリクエスト/リプライ/フォルト/コールバックのWSDLファイル、または一方向WSDLファイルの場合には使用できません。 |
エコー・オプションは、リクエスト/リプライおよびリクエスト/リプライ/フォルトのような同期操作で使用できます。
注意: 同期操作のメディエータでは、パラレルのルーティング・ルールはサポートされないため、エコー・オプションを同期操作で使用できるのは、ルーティング・ルールが順次実行の場合のみです。 |
条件フィルタ付きの同期操作の場合は、フィルタ条件をfalse
に設定していると、エコー・オプションではレスポンスがコール元に返されません。かわりに、null
レスポンスが返されます。
エコー・オプションを非同期操作で使用できるのは、メディエータのインタフェースにコールバック操作が指定されている場合のみです。この場合、エコーは別のスレッドで実行されます。
注意: 非同期のエコー・オプションを使用できるのは、ルーティング・ルールがパラレル実行の場合のみです。エコー・オプションを使用する場合、非同期操作のメディエータでは、順次実行のルーティング・ルールはサポートされません。 |
ルーティング・ルールは、パラレルまたは順次のいずれかで実行できます。ルーティング・ルールの実行タイプを指定するには、「ルーティング・ルール」セクションで、「順次」または「パラレル」実行タイプを選択します。
メディエータ・ルーティング・ルールでは、レスポンス・メッセージを同期および非同期の相互作用内で処理する方法を指定できます。同期相互作用の場合は、レスポンスとフォルト・メッセージのトランスフォーメーションと割当てを指定できます。レスポンスとフォルト・メッセージを別のサービスまたはイベントに転送するか、または初期のコール元にレスポンスおよびフォルトを受信する用意がある場合は、それらを初期のコール元に戻すことができます。
非同期相互作用の場合は、トランスフォーメーションと割当て、およびレスポンスを受信するまでのタイムアウト時間を指定できます。タイムアウト時間は、秒、時、日、月または年で指定できます。タイムアウト時間のデフォルト値は無限です。コールバック・レスポンスが指定したタイムアウト時間内に返されない場合、タイムアウトしたレスポンスは別のサービス、別のイベントに転送されるか、初期のコール元に戻されます。
メディエータのレスポンスを双方向サービスにルーティングすることはできません。レスポンスを双方向サービスにルーティングする場合は、最初のメディエータと双方向サービスの間に一方向のメディエータを使用する必要があります。レスポンスを最初に一方向のメディエータに転送し、その一方向のメディエータが双方向サービスをコールする必要があります。
注意:
|
非同期処理のタイムアウト時間を指定する手順は、次のとおりです。
メディエータ・エディタの「ルーティング・ルール」セクションで、次の手順を実行します。
「コールバック」セクションで、「タイムアウト期間」フィールド側の「<<ターゲット操作>>」フィールドの横にある「ターゲット・サービス操作を参照します。」アイコンをクリックします。
「ターゲット・タイプ」ダイアログが表示されます。
「サービス」、「イベント」または「初期コール元」を選択します。
「サービス」または「イベント」を選択した場合は、選択した内容によって「ターゲット・サービス」または「イベント・チューザ」が表示されます。
サービスまたはイベントを選択します。
「OK」をクリックします。
「タイムアウト期間」フィールドで、タイムアウト期間の単位数を入力し、ドロップダウン・リストから時間の単位を選択します。
タイムアウトしたレスポンスが、指定したサービスまたはイベントに転送されます。
注意: ルーティング・ルールの数が多く、ルーティング・ルールの実行に要する時間がトランザクション・タイムアウトを超える場合は、トランザクション・タイムアウトの値を、すべてのルーティング・ルールの実行に要する時間より長い時間に設定する必要があります。 |
コールバック・メッセージは、トランザクションの開始が完了する前に着信する場合があります。この場合、メディエータでの相関は失敗します。早すぎるコールバックの問題がある場合は、oracle.tip.mediator.callback.correlationWaitDuratino_in_seconds
プロパティを使用して、コールバックを再試行する前にコールバック・スレッドが待機する期間(秒単位)を設定できます。
このプロパティは、composite.xml
ファイル内のMediatorコンポーネントを定義するcomponent
要素で定義します。次に示す例では、再試行前の待機時間は15秒です。
<component name="Mediator1"> <implementation.mediator src="Mediator1.mplan"/> <property name="oracle.tip.mediator.callback.correlationWaitDuration_in_ seconds">15</property> </component>
1つのメディエータで複数のコールバックを処理することはできません。複数のコールバックを受信するメディエータが含まれているコンポジット・アプリケーションがある場合、そのコンポジット・アプリケーションの動作は不明です。たとえば、図20-9に示したシナリオでは、AsyncMediatorがAsyncEchoMediator1およびAsyncEchoMediator2からのコールバック・レスポンスをFileInMediatorに転送します。このようなフローでは、AsyncMediatorは、AsyncEchoMediator1とAsyncEchoMediator2の両方からのコールバックを返すか、またはいずれか一方のコールバックを返す可能性があります。正確な動作はランダムであり、予測できません。
ターゲット・サービスの操作に1つ以上のフォルトがある新規ルーティング・ルールを作成する場合でも、メディエータ・エディタには、単一フォルトのルーティング・セクションが表示されます。ソース・メディエータ・サービス・コンポーネントが1つ以上のフォルトをサポートしている場合、デフォルトでは、フォルトはコール元に戻されます。ただし、ルーティングするソース・フォルト名およびターゲット・フォルト名を指定できます。サービス・ブラウザを使用して、フォルトを別のターゲットにルーティングすることもできます。
追加のフォルト・ルーティングを定義する手順は、次のとおりです。
メディエータ・エディタの「ルーティング・ルール」セクションで、次の手順を実行します。
図20-10に示すように、「フォルト」セクションで、「別のフォルト・ルーティングを追加します。」ボタンをクリックします。
別のフォルト・セクションがルーティング・ルール・ボックスに表示されます。
新規フォルトに対して、ターゲット・サービス、トランスフォーメーションおよび値の割当てを構成します。
図20-11に、ファイル・アダプタ・サービスにルーティングされている2番目のフォルトを示します。
注意: 異なるトランスフォーメーションを使用して、複数のターゲットに同じフォルトをルーティングできます。 |
フォルト・ルーティング・セクションを削除する手順は、次のとおりです。
メディエータ・エディタの「ルーティング・ルール」セクションで、次の手順を実行します。
図20-12に示すように、ターゲット・サービス・フィールドをクリックして削除するフォルト・ルーティングをハイライト表示し、「選択したフォルト・ルーティングを削除します。」をクリックします。
フィルタ式ルーティング・ルールを使用すると、ペイロードに基づいてメッセージをフィルタリングできます。特定のメッセージ・インスタンスに対してフィルタ式がtrueと評価されると、そのメッセージはルーティング・ルールに指定されているターゲット・サービスまたはイベントに送信されます。
たとえば、アメリカとカナダのような異なる2国にいる顧客にデータをルーティングする場合、アメリカの顧客には携帯の製品系列に関する通知のみを、カナダの顧客には固定電話の製品系列の通知のみを送信するとします。このルーティングのためには、メッセージをターゲット顧客に送信するコンポーネントと操作の各組合せについてルーティング・ルールを定義する必要があります。さらに、アメリカまたはカナダの顧客にメッセージを送信するルーティング・ルールには、フィルタ式を指定します。
フィルタ式のメッセージ・プロパティまたはメッセージ・ヘッダーを定義することもできます。
フィルタ式のメッセージ・プロパティ
例20-1に、フィルタ式のメッセージ・プロパティの2つ例を示します。
フィルタ式のメッセージ・ヘッダー
例20-2に、フィルタ式のメッセージ・ヘッダーの2つ例を示します。
例20-2 フィルタ式のメッセージ・ヘッダー
$in.header.wsse_Security/wsse:Security/Priority = '234' $in.header.wsse_Security/wsse:Security/Priority = '234'
このフィルタ式のメッセージ・ヘッダーが機能するには、.mplan
ファイルのルート要素に例20-3に示す属性を追加する必要があります。
例20-3 追加する属性
wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity- secext-1.0.xsd"
メッセージをフィルタリングする式を指定する手順は、次のとおりです。
式ビルダーを使用すると、フィルタ式をグラフィカルに作成できます。「式ビルダー」ダイアログには、フィルタ式の設計を支援するコンポーネントやコントロールが含まれています。
「ルーティング・ルール」セクションの「フィルタ式」フィールドの右側にある「式ビルダーの起動」アイコンをクリックします。
図20-13に示すように、「式ビルダー」ダイアログが表示されます。
「式」フィールドに値を追加するには、「変数」フィールドまたは「関数」パレットで、必要な値をダブルクリックします。変数要素、関数および手動で入力したテキストの組合せを使用して、このウィンドウで、特定のルーティング・ルールに対してメッセージ・ペイロードをフィルタリングする式を作成できます。
表20-1で、「式ビルダー」ダイアログの各フィールドについて説明します。
表20-1 「式ビルダー」フィールド
フィールド | 説明 |
---|---|
式 |
このフィールドには、メッセージのフィルタに使用される実際の式が含まれます。フィルタ式は手動、または「変数」フィールドおよび「関数」パレットを使用して入力できます。 このフィールドの右上部に表示されている各アイコンを使用すると、最後に行った編集の取消し、最後に行った編集の再実行、または「式」フィールド全体の消去を実行できます。 |
変数 |
このフィールドには、メディエータ・コンポーネントに対して定義されたメッセージが含まれます。Oracle JDeveloperはメディエータのWSDLファイルを解析し、メッセージ定義を「変数」フィールドに表示します。入力メッセージは 入力メッセージが複数のパートで構成されている場合は、 |
「関数」パレット |
このリストには、式に挿入できる関数のリストが表示されます。関数を選択すると、その関数が「式」フィールドに追加されたときにどのように表示されるかを示すプレビューが「コンテンツのプレビュー」フィールドに表示され、その関数の説明が「説明」フィールドに表示されます。 |
コンテンツのプレビュー |
このフィールドには、「変数」フィールドまたは「関数」パレットで選択した値が「式」フィールドに挿入されたときの表示状態で示されます。 |
説明 |
このフィールドには、「変数」フィールドまたは「関数」パレットで選択した値の説明が表示されます。 |
メッセージ・ペイロードのフィルタ式を指定する手順は、次のとおりです。
「ルーティング・ルール」セクションの「フィルタ式」フィールドの右側にある「式ビルダーの起動」アイコンをクリックします。
「式ビルダー」ダイアログが表示されます。
「変数」フィールドで、メッセージ定義を開き、式の基になるメッセージ要素を選択します。
たとえば、図20-14で選択されたCustomerId要素が表示されます。
「式に挿入」をクリックします。
図20-15に示すように、式が「式」フィールドに追加されます。
「関数」リストから、メッセージ・ペイロードに適用する関数を選択します。たとえば、equalsを選択します。
関数は、「関数」リストの下矢印をクリックすると表示されるカテゴリ別にグループ化されます。たとえば、下矢印をクリックして「Logical Functions」を選択すると、図20-15に示すようにリストが表示されます。
「式に挿入」をクリックします。
選択した関数のXPath式が「式」フィールドに挿入されます。
式を完成します。
この例では、図20-16に示すように、顧客IDがtrueと評価されるには1001
である必要があります。
エラーが検出された場合、式は手動で編集するか、式の編集アイコンを使用できます。図20-17には、これらのアイコンがまとめられています。
「OK」をクリックします。
式が「ルーティング・ルール」セクションに追加されます。
フィルタ式の変更または削除は、「フィルタ式の追加」アイコンをダブルクリックし、「式ビルダー」の「式」フィールドで実行します。
Oracle JDeveloperには、XSLTマッパーが用意されています。XSLTマッパーを使用すると、データをXMLスキーマ(XSDファイルで表されます)間で変換するためのマッパー・ファイル(XSLファイル)を指定できます。XSLTマッパーを使用することで、異なるスキーマを使用しているアプリケーション間でのデータ交換が可能になります。たとえば、受信した注文書スキーマを、送信する請求書スキーマにマップできます。XSLファイルを定義した後は、そのファイルを複数のルーティング・ルール仕様で再利用できます。
トランスフォーメーションを作成する手順は、次のとおりです。
「ルーティング・ルール」セクションで、「次を使用して変換」フィールドの右側にある「既存のマッパー・ファイルを選択するか、新規マッパー・ファイルを作成します。」アイコンをクリックします。
「リクエスト・トランスフォーメーション・マップ」ダイアログが表示されます。既存のXSLファイルを選択するか、XSLTマッパーを使用して必要なトランスフォーメーションを実行する新規XSLファイルを作成できます。
次のいずれかを実行します:
マッピング・ファイルが存在する場合は、「既存のマッパー・ファイルの使用」を選択し、次に「参照」をクリックして、使用するマッパー・ファイルを検索および選択します。
マッパー・ファイルを作成するには、「新規マッパー・ファイルの作成」を選択し、次に入力情報を入力します。
同期リプライ、コールバック・レスポンスまたはフォルト・メッセージに対して、前述の手順を繰り返します。
図20-18に示すように、同期リプライまたはフォルト・メッセージの場合、「リプライ・トランスフォーメーション・マップ」ダイアログまたは「フォルト・トランスフォーメーション・マップ」ダイアログには、「リクエストをリプライ・ペイロードに含める」オプションがあります。
同期相互作用の元のメッセージを含む$initial
変数を作成するには、「リクエストをリプライ・ペイロードに含める」オプションを選択します。
図20-19に示すように、変数が作成されます。
注意: 初期メッセージも複数のパートで構成されます。 |
XSLTマッパーの詳細は、第40章「XSLTマッパーを使用したトランスフォーメーションの作成」を参照してください。
ユーザー定義拡張関数を追加する手順は、次のとおりです。
式ビルダーを使用すると、ユーザー定義拡張関数を含めることができます。
XPath関数を作成します。
Jaxen XPath関数を、サーバーのxpath-function.xml
ファイルのメディエータ・サービス・コンポーネントに登録します。
Oracle JDeveloperを起動します。
式ビルダーで式をカスタマイズします。
Oracle JDeveloperプロジェクトをOracle WebLogic Serverにデプロイします。
ユーザー定義拡張関数を格納したJARファイルを$BEAHOME/user_projects/domains/soainfra/autodeploy/soa-infra/APP-INF/lib
ディレクトリにコピーします。
プロジェクトの.mplan
ファイルを、次のように変更します。
拡張関数用に定義した関数ネームスペースをMediator
要素の下に追加します。
関数名をExpression
要素に追加します。
図20-20に、この変更操作を示します。
図20-20 プロジェクトの.mplanファイル – ユーザー定義拡張関数を使用するように変更済
適切なペイロードでテスト・ページを起動します。
メッセージのヘッダー、ペイロードおよびプロパティは、「値の割当て」フィールドを使用してソースからターゲットに伝播できます。図20-21に、「値の割当て」ダイアログを示します。このダイアログは、「ルーティング・ルール」セクションの「値の割当て」アイコンをクリックすると表示されます。
ターゲット・メッセージのプロパティを設定する手順は、次のとおりです。
「値の割当て」ダイアログの「追加」をクリックします。
図20-22に示すように、「値の割当て」ダイアログが表示されます。
「From」セクションで、「タイプ」ボックスから次のオプションのいずれかを選択します。
プロパティ: ターゲット・メッセージにプロパティの値を割り当てる場合に選択します。「プロパティ」リストには、事前に定義されたプロパティのリストが表示されます。任意のユーザー定義プロパティ名を入力することもできます。
式: ターゲット・メッセージに式の値を割り当てる場合に選択します。「式」フィールドの右側にある「式ビルダーの起動」アイコンをクリックすると、図20-13に示すような「式ビルダー」ダイアログが表示されます。
「式ビルダー」ダイアログの詳細は、第20.3.2.8項「メッセージをフィルタリングする式の指定方法」を参照してください。
定数: ターゲット・メッセージに定数値を割り当てる場合に選択します。
「To」セクションで、次のオプションのいずれかを選択します。
プロパティ: メッセージ・プロパティに値をコピーする場合に選択します。「式ビルダー」ダイアログの「変数」フィールドには、出力メッセージを格納する$out変数が表示されます。$out.propertyを使用すると、出力メッセージのプロパティにアクセスできます。
式: 式に値をコピーする場合に選択します。「式」フィールドの右側にある「式ビルダーの起動」アイコンをクリックすると、「式ビルダー」ダイアログが表示されます。「式ビルダー」ダイアログの「変数」フィールドには、出力メッセージを格納する$out変数が表示されます。$out.partnameを使用すると、出力メッセージ全体または出力メッセージのパートにアクセスできます。
図20-23に、定数値が式として指定されている、サンプルの「値の割当て」ダイアログを示します。
「値の割当て」ダイアログの「OK」をクリックします。
「OK」をクリックします。「ルーティング・ルール」セクションの「値の割当て」フィールドに式が追加されます。
注意:
|
表20-2から表20-4に、メッセージの定数とプロパティ、ペイロードおよびヘッダーに関するソースからターゲットへの考えられる様々な割当てを示します。
表20-2 定数とプロパティの場合の考えられる割当て
ソース | ターゲット | 例 |
---|---|---|
プロパティ |
プロパティ |
|
定数 |
プロパティ |
|
表20-3 ペイロードの場合の考えられる割当て
ソース | ターゲット | 例 |
---|---|---|
XPath式 |
プロパティ |
|
XPath式(パート・レベルより下) |
プロパティ |
|
プロパティ |
XPath式(パート・レベルより下) |
|
定数 |
XPath式(パート・レベルより下) |
|
XPath式 |
XPath式 |
|
XPath式(パート・レベルより下) |
XPath式(パート・レベルより下) |
|
表20-4 ヘッダーの場合の考えられる割当て
ソース | ターゲット | 例 |
---|---|---|
XPath式(パート・レベルより下) |
プロパティ |
|
プロパティ |
XPath式(パート・レベルより下) |
|
定数 |
XPath式(パート・レベルより下) |
|
定数 |
XPath式(パート・レベルより下) |
|
XPath式 |
XPath式 |
|
XPath式(パート・レベルより下) |
XPath式(パート・レベルより下) |
|
assignアクティビティについては、次の点に注意してください。
assignアクティビティは、メディエータの<copy>
要素に記述されている順序で実行されます。
ソースがターゲットのプロパティに割り当てられている場合でも、そのソースのXPath式は常にリーフ・ノードを参照する必要があります。そうでない場合、ソースの子ノードの値はすべて連結されて、ターゲットのプロパティに割り当てられます。例20-4に詳細を示します。
例20-4 リーフ・ノードを参照するXPath式
<copy target="$out.property.jca.file.FileName" expression="$in.body/imp1:request/ProductReq/Make" xmlns:imp1="http://xmlns.oracle.com/psft"/>
注意: リーフ・ノードとは、子ノードのないノードです。 |
定数またはプロパティがターゲットのXPath式に割り当てられる場合でも、そのターゲットのXPath式は常にリーフ・ノードを指し示す必要があります。そうでない場合、リーフ以外のノードには文字列値のみが含まれ、.xsd
ファイルに従って無効なXMLが生成される可能性があります。例20-5に詳細を示します。
例20-5 リーフ・ノードを指し示すターゲットのXPath式
<copy target="$out.request/inp1:request/ProductReq/Make" value="NewMakeValue" xmlns:inp1="http://xmlns.oracle.com/psft"/>
この例では、$out.request/inp1:request/ProductReq/Make
がリーフ・ノードを参照しています。
トランスフォーメーションが使用可能な場合は、ソース・パートをターゲット・パートに割り当てても、そのターゲットは上書きされます。これは、トランスフォーメーションの最初にassignアクティビティが発生するためです。トランスフォーメーションが使用不可の場合は、assignアクティビティによってターゲットが作成されます。例20-6に詳細を示します。
ターゲット・ペイロードのいずれかの子ノードを変更する必要がある場合は、次のような2つのユースケースがあります。
ソースの子ノードの1つのみをターゲットに伝播する必要がある場合は、最初にトランスフォーメーションが起動されていないことを確認します。次に、必要な子ノードを指し示すソースのXPath式を割り当てます。例20-9に詳細を示します。
例20-9 ソースの1つの子ノードがターゲットに伝播される場合
<copy target="$out.request/imp1:ProductReq" expression="$in.body/imp1:request/ProductReq" xmlns:imp1="http://xmlns.oracle.com/psft"/>
このケースで、$in.body/imp1:request/ProductReq
から評価されるソース要素には、子ノードのみが含まれ、ルート要素から始まる完全なツリー構造は含まれていません。例20-10に詳細を示します。
メディエータに複数のassignアクティビティがあり、各ソースのXPath式が別々の子ノードを指し示している場合は、次のような2つのユースケースがあります。
トランスフォーメーションが使用可能な場合は、ターゲットの対応する子ノードが更新されます。
トランスフォーメーションが使用不可の場合、ターゲットは複数パートのターゲットであり、各パートがソースの子ノードを参照している必要があります。
ヘッダーの場合、passThroughHeader
プロパティが設定されている場合は、次のようになります。
トランスフォーメーションのヘッダー操作は、ターゲットのヘッダーで更新されます。
パート・レベルのassignアクティビティによって、ターゲットのヘッダー・パートが上書きされます。
パート・レベルより下のノードのassignアクティビティによって、ターゲットの対応するノードが更新されます。
(パート・レベルより下の)複数のソース・ノードが(パート・レベルより下の)同じターゲット・ノードに割り当てられている場合、そのターゲット・ノードには、assignアクティビティの最後のcopy
要素の値が含まれます。例20-11に詳細を示します。
例20-11 同じターゲット・ノードに複数のソース・ノードが割り当てられる場合
<copy target="$out.request/imp1:request/ProductReq/Make" expression="$in.body/imp1:request/ProductReq/Model" xmlns:imp1="http://xmlns.oracle.com/psft"/> <copy target="$out.request/imp1:request/ProductReq/Make" expression="$in.body/imp1:request/Description" xmlns:imp1="http://xmlns.oracle.com/psft"/>
例20-11で、最初のcopy
要素は、2番目のcopy
要素によって上書きされるため何も効果がありません。
XPath式の結果がリスト(複数発生)になる場合は、次の2つのユースケースがあります。
リストに単一の要素が含まれる場合は、XPath式が伝播されます。
リストに複数の要素が含まれる場合、XPath式はサポートされません。
ソースの子ノードをターゲットの子ノードに割り当てると、次のアクティビティが発生します。
ソースの子ノードの名前とネームスペースが、ターゲットのノード名とネームスペースによってそれぞれ上書きされます。
ターゲットの子ノードは、ターゲット・ノードの親ノードにあるソースの子ノードによって置換されます。
フィルタを定義するため、または割当てソースや割当てターゲットを定義するためにメディエータから式ビルダーを起動すると、WSDLファイルが解析されます。その際に、図20-24に示すように、現在のルーティング・ルール操作のSOAPヘッダーが自動的に検出され、このSOAPヘッダーが変数として、in
フォルダまたはout
フォルダにheader./ns_elementName/
のように表示されます。ここで、ns
はネームスペース接頭辞、elementName
はヘッダー・スキーマのルート要素名です。
次のシナリオで詳細を説明します。
シナリオ1: ネームスペース接頭辞wsseおよびns1がすでに定義されている場合
ネームスペース接頭辞wsse
およびns1
がWSDLファイルまたは.mplan
ファイルにすでに定義されているとします。この場合、XPath式は次のように記述できます。
$in.header.wsse_Security/wsse:Security/ns1:Foo/Priority
シナリオ2: WSDLファイルにネームスペースが事前定義されていないスキーマの場合
WSDLファイルにネームスペースが事前定義されていないスキーマを使用するとします。この場合、式ビルダーでは、接頭辞のかわりに{full_namespace}
を入力できる機能が提供されます。さらに、式ビルダーによって一意の接頭辞が生成され、接頭辞の定義が.mplan
ファイルに追加されます。
たとえば、式ビルダーに例20-12に示す式を入力するとします。
例20-12 式
$in.header.{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-sec ext-1.0.xsd}_Security/ {"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xs d"}: Security/{"http://www.globalcompany.com/ns/OrderBooking"}:Foo/Priority
.mplan
ファイルには、例20-13に示すコンテンツが含まれています。
例20-13 .mplanファイルのコンテンツ
xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity- secext-1.0.xsd" xmlns:ns2="http://www.globalcompany.com/ns/OrderBooking" ... expression="$in.header.ns1_Security/ns1:Security/ns2:Foo/Priority"
デフォルトでは、SOAPヘッダーはメディエータを介して渡されません。passThroughHeader
エンドポイント・プロパティを、対応するメディエータ・ルーティング・サービスに追加する必要があります。
<property name="passThroughHeader">true</property>
たとえば、このプロパティを追加するには、composite.xml
ファイルを例20-14に示すように変更できます。
例20-14 passThroughHeaderプロパティ
<component name="Mediator1"> <implementation.mediator src="Mediator1.mplan"/> <property name="passThroughHeader">true</property> </component>
ヘッダーを渡すには、ソースとターゲットのQName(名前とネームスペース)が同じである必要があります。ソースとターゲットのQNameが異なる場合は、トランスフォーメーションまたはパートレベルの割当てのいずれかを実行する必要があります。
(トランスフォーメーションまたはassignを使用しない)passthrough
メディエータの場合、ソースとターゲットのパートQNameが同じでない場合は、メディエータがメッセージ・ペイロードをターゲット・サービスに渡す際にエラーが発生していない点に注意する必要があります。ただし、この処理はターゲット・サービスでエラーになる場合があります。これは、メッセージ・ペイロードはターゲット・サービスのメッセージ構造に従って再構築されていないためです。
注意:
|
ユースケースによっては、WSDLファイルからヘッダー・スキーマを識別できない場合があります。たとえば、メッセージに付加されたセキュリティ・ヘッダーや、抽象的なWSDLファイルを使用して作成されるメディエータのヘッダーなどです。そのようなヘッダーにアクセスするには、式ビルダーにXPath式を手動で入力する必要があります。
例20-15に、ヘッダー式の構文を示します。
例20-15 ヘッダー式の構文
$in.header.<header root element namespace prefix>_<header root element name>/<xpath>
例20-16に示すヘッダーがあるとします。
例20-16 ヘッダーの構文
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-sec ext-1.0.xsd"> <Priority>234</Priority> </wsse:Security>
フィルタ式は次のようになります。
$in.header.wsse_Security/wsse:Security/Priority = '234'
割当て式は例20-17に示すようになります。
例20-17 割当て式
<copy target="$out.property.jca.jms.priority" expression="$in.header.wsse_Security/wsse:Security/Priority"/>
これらの式が機能するには、.mplan
ファイルのルート要素に例20-18に示す属性を追加する必要があります。
フィルタ式の例は、次のとおりです。
$in.property.tracking.ecid = '2'
割当て式の例は、次のとおりです。
<copy target="$out.property.tracking.ecid" value="$in.property.tracking.ecid"/>
インバウンド・メッセージとその様々なパートは、Schematronファイルを指定して検証できます。Schematronバージョン1.5がサポートされているバージョンです。
Schematronスキーマを指定して、インバウンド・メッセージとその様々なパートを検証する手順は、次のとおりです。
セマンティク検証を使用する手順は、次のとおりです。
「セマンティックの検証」フィールドの右側にある「検証ファイルの選択」アイコンをクリックします。
「検証」ダイアログが表示されます。
「追加」をクリックします。
「検証の追加」ダイアログが表示されます。
「パート」リストから、メッセージ・パートを選択します。
「ファイル」フィールドの右側にある「検索」をクリックします。
「SOAリソース・ブラウザ」ダイアログが表示されます。
Schematronファイルを選択し、「OK」をクリックします。
注意:
|
図20-25に示すように、「検証の追加」ダイアログが更新されます。
「OK」をクリックします。
図20-26に示すように、「検証」ダイアログが更新されます。
「追加」をクリックして別のメッセージ・パートのSchematronファイルを指定するか、「OK」をクリックします。
Schematronスキーマの作成方法の詳細は、次の場所から入手できるリソースを参照してください。
注意: セマンティク検証では、各要素名の長さをチェックした場合、異なる入力セットに対して要素名が変わる場合があります。これは、パーサーが空白をテスト・ノードとして処理するため、ノード間に空白がある場合に発生します。 |
プロジェクトのcomposite.xml
ファイルにプロパティを追加することによって、メディエータが添付ファイルを処理する方法を構成できます。添付ファイルの処理の詳細は、「アタッチメント・ストリームの送信」および「Oracle Mediatorでの添付ファイルのパス・スルー設定のオーバーライド」を参照してください。
Javaコールアウトを使用すると、メディエータを介してフローするメッセージの操作に外部のJavaクラスを使用できます。操作またはイベント・サブスクリプションごとに、Javaコールアウトは1つのみサポートされます。コールアウト・クラスは、oracle.tip.mediator.common.api.IjavaCallout
インタフェースを実装する必要があります。コールアウトは、静的ルーティングおよび動的ルーティングの両方に使用できます。図20-27に、2つの操作が指定されたメディエータのサンプルを示します。2つの操作には、それぞれルーティング・ルールが1つあり、最初の操作にはコールアウト・クラスが指定されています。
Javaコールアウト・クラスを使用できるようにする手順は、次のとおりです。
サーバーでJavaコールアウト・クラスが使用できることが必要です。このためには、次のいずれかの方法を使用します。
JavaクラスをSCA-INF/classes
フォルダにコピーします。
Javaクラスが含まれているJARファイルをSCA-INF/lib
フォルダにコピーします。
Javaクラスが含まれているJARファイルを$DOMAIN_HOME/lib
フォルダにコピーします。
Javaコールアウト・クラスを複数のメディエータで使用できるようにするには、Javaクラスが含まれているJARファイルを$DOMAIN_HOME/lib
フォルダにコピーします。
コールアウトのJavaクラスを入力する手順は、次のとおりです。
Javaクラスを手動で入力するか、「クラス・ブラウザ」からクラスを選択できます。
図20-28に示すように、Javaコールアウト・クラスの名前を手動で入力するには、「コールアウト先」フィールドにクラス名を入力し始めます。Oracle JDeveloperのオートコンプリート機能によって、現在のプロジェクトのアドレスとクラスが挿入されます。
使用可能なクラスをリストから選択するには、「Javaコールアウト・クラスを選択します。」アイコンをクリックします。
図20-29に示すように、標準のOracle JDeveloperクラス・ブラウザが表示されます。
クラス・ブラウザは、oracle.tip.mediator.common.api.IjavaCallout
インタフェースを実装するクラスのみが表示されるようにフィルタリングされます。
ペイロードのルート要素を設定する手順(フィルタ式を使用している場合)は、次のとおりです。
メディエータにJavaコールアウトがあり、同じメディエータでフィルタ式を使用している場合は、ペイロードのルート要素を例20-19に示すように設定する必要があります。
例20-19 ペイロードのルート要素の設定
changexmldoc = XmlUtils.getXmlDocument(ChangedDoc); String mykey = "request"; message.addPayload(mykey,changexmldoc.getDocumentElement());
ドメイン値マップと相互参照関数を有効にする手順は、次のとおりです。
Javaコールアウトでドメイン値マップ関数または相互参照関数を使用するには、soa-xpath-exts.jar
ファイルをプロジェクトに追加し、コードに必要なJavaクラスをインポートする必要があります。
Oracle JDeveloperプロジェクト・エクスプローラで、Javaコールアウトを含むプロジェクトの名前を右クリックします。
「プロジェクト・プロパティ」を選択します。
「プロジェクト・プロパティ」ダイアログが表示されます。
図20-30に示すように、左側のパネルで、「ライブラリとクラスパス」を選択します。
「JAR/ディレクトリの追加」をクリックします。
図20-31に示すように、「アーカイブまたはディレクトリの追加」が表示されます。
エクスプローラ・ツリーで、ディレクトリを展開して<JDEV_HOME>/jdeveloper/soa/modules/oracle.soa.fabric_11.1.1/soa-xpath-exts.jar
を選択し、次に「選択」をクリックします。
JARファイルが「クラスパス・エントリ」リストに表示されます。
「OK」をクリックします。
注意: ドメイン値マップ関数を使用する場合は、Javaクラスに次をインポートします。
相互参照(xref)関数を使用する場合は、Javaクラスに次をインポートします。
|
メディエータのJavaコールアウトAPI
JavaコールアウトAPIでは、oracle.tip.mediator.common.api.IjavaCallout
およびoracle.tip.mediator.common.api.CalloutMediatorMessage
という2つのインタフェースを定義します。
表20-5では、oracle.tip.mediator.common.api.IjavaCallout
インタフェースのメソッドをリストして説明します。
表20-5 IjavaCalloutインタフェースのメソッドの説明
メソッド | 説明 |
---|---|
|
コールアウト実装クラスが初めてインスタンス化されるときに起動されます。 |
|
メディエータがケースの実行を開始する前にコールされます。このメソッドをカスタマイズすると、検証および拡張機能を組み込むことができます。 |
|
メディエータが特定のケースの実行を開始する前にコールされます。このメソッドをカスタマイズすると、ケース固有の検証および拡張機能を組み込むことができます。 |
|
メディエータがコールバック処理の実行を終了する前にコールされます。このメソッドをカスタマイズすると、コールバックの監査およびカスタムのフォルト・トラッキングを実行できます。 |
|
メディエータがケースの実行を終了した後にコールされます。このメソッドをカスタマイズすると、レスポンスの監査およびカスタムのフォルト・トラッキングを実行できます。 後処理メソッドは、すべての順次ルーティングが実行された後にコールされますが、パラレルのルーティング・ルールの完了は待機しません。 |
|
メディエータがケースの実行を開始した後にコールされます。このメソッドをカスタマイズすると、レスポンスの監査およびカスタムのフォルト・トラッキングを実行できます。 |
|
メディエータがコールバック処理の実行を終了した後にコールされます。このメソッドをカスタマイズすると、コールバックの監査およびカスタムのフォルト・トラッキングを実行できます。 |
注意:
<assign> <copy target="$out.property.jca.file.FileName" expression="$in.property.jca.file.FileName"/> </assign> |
表20-6で、CalloutMediatorMessage
インタフェースのメソッドについて説明します。
表20-6 CalloutMediatorMessageインタフェースのメソッドの説明
メソッド | 説明 |
---|---|
|
メディエータ・メッセージのペイロードを設定します。 |
|
メディエータ・メッセージにプロパティを追加します。 |
|
メディエータ・メッセージにヘッダーを追加します。 |
|
プロパティ名を指定してメディエータ・メッセージのプロパティを取得します。 |
|
メディエータ・メッセージのプロパティを取得します。 |
|
メディエータ・メッセージのインスタンスIDを取得します。このインスタンスIDは、該当する特定のメッセージに対して作成されたメディエータ・インスタンスIDです。 |
|
メディエータ・メッセージのペイロードを取得します。 |
|
メディエータ・メッセージのヘッダーを取得します。 |
|
メディエータ・サービス・コンポーネントのcomponentDNを取得します。 |
注意:
|
Javaコールアウト・クラスのサンプル
例20-20は、Javaコールアウト・クラスのサンプルを示しています。
例20-20 Javaコールアウト・クラスのサンプル
package qa.as11tests.javacallout; import com.collaxa.cube.persistence.dto.XmlDocument; import com.oracle.bpel.client.NormalizedMessage; import java.util.logging.Logger; import java.util.Map; import java.util.Iterator; import oracle.tip.mediator.common.api.CalloutMediatorMessage; import oracle.tip.mediator.common.api.ExternalMediatorMessage; import oracle.tip.mediator.common.api.IJavaCallout; import oracle.tip.mediator.common.api.MediatorCalloutException; import oracle.tip.mediator.metadata.CaseType; import oracle.tip.mediator.utils.XmlUtils; import oracle.tip.pc.services.functions.ExtFunc; import oracle.xml.parser.v2.XMLDocument; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; public class JavaCalloutSanity implements IJavaCallout { Logger logger = Logger.getLogger("Callout"); public JavaCalloutSanity() { } public void initialize(Logger logger) throws MediatorCalloutException { this.logger = logger; this.logger.info("Initializing..."); } public boolean preRouting(CalloutMediatorMessage calloutMediatorMessage) { System.out.println("Pre routing..."); String sPayload = "null"; String sPayload_org = "null"; for (Iterator msgIt = calloutMediatorMessage.getPayload().entrySet().iterator(); msgIt.hasNext(); ) { Map.Entry msgEntry = (Map.Entry)msgIt.next(); Object msgKey = msgEntry.getKey(); Object msgValue = msgEntry.getValue(); if (msgKey.equals("request")) sPayload = XmlUtils.convertDomNodeToString((Node)msgValue); } sPayload_org = sPayload; String tobeReplaced = "CHANGE_THIS"; String replaceWith = "JAVA_CALLOUT_||_PRE_ROUTING"; int start = sPayload.indexOf(tobeReplaced); StringBuffer sb = new StringBuffer(); sb.append(sPayload.substring(0, start)); sb.append(replaceWith); sb.append(sPayload.substring(start + tobeReplaced.length())); String changedPayload = sb.toString(); String uid; try { uid = ExtFunc.generateGuid(); } catch (Exception e) { } XMLDocument changedoc; try { changedoc = XmlUtils.getXmlDocument(changedPayload); String mykey = "request"; calloutMediatorMessage.addPayload(mykey, changedoc.getDocumentElement()); //calloutMediatorMessage.getPayload().put(mykey, changedoc); } catch (Exception e) { } System.out.println("Changed from : \n"+sPayload_org+"\nTo\n"+changedPayload); System.out.println("End Pre routing...\n\n"); return false; } public boolean postRouting(CalloutMediatorMessage calloutMediatorMessage, CalloutMediatorMessage calloutMediatorMessage1, Throwable throwable) throws MediatorCalloutException { System.out.println("Start Post routing..."); String sPayload = "null"; String sPayload_org = "null"; for (Iterator msgIt = calloutMediatorMessage1.getPayload().entrySet().iterator(); msgIt.hasNext(); ) { Map.Entry msgEntry = (Map.Entry)msgIt.next(); Object msgKey = msgEntry.getKey(); Object msgValue = msgEntry.getValue(); if(msgKey.equals("reply")) sPayload = XmlUtils.convertDomNodeToString((Node)msgValue); } sPayload_org = sPayload; String tobeReplaced = "POST_ROUTING_RULE_REQUEST_REPLY"; String replaceWith = "POST_ROUTING_RULE_REQUEST_REPLY_||_POSTROUTING_||_JAVA_CALLOUT_WORKING"; int start = sPayload.indexOf(tobeReplaced); StringBuffer sb = new StringBuffer(); sb.append(sPayload.substring(0, start)); sb.append(replaceWith); sb.append(sPayload.substring(start + tobeReplaced.length())); String changedPayload = sb.toString(); XMLDocument changedoc; try { changedoc = XmlUtils.getXmlDocument(changedPayload); String mykey = "reply"; calloutMediatorMessage1.addPayload(mykey,changedoc.getDocumentElement()); // calloutMediatorMessage1.getPayload().put(mykey, changedoc.getDocumentElement()); } catch (Exception f) { } System.out.println("Changed from : \n"+sPayload_org+"\nTo\n"+ changedPayload); System.out.println("End Post routing...\n\n"); return false; } public boolean preRoutingRule(CaseType caseType, CalloutMediatorMessage calloutMediatorMessage) { System.out.println("\nStart PreRoutingRule.\n"); String sPayload = "null"; String sPayload_org = "null"; for (Iterator msgIt = calloutMediatorMessage.getPayload().entrySet().iterator(); msgIt.hasNext(); ) { Map.Entry msgEntry = (Map.Entry)msgIt.next(); Object msgKey = msgEntry.getKey(); Object msgValue = msgEntry.getValue(); if(msgKey.equals("request")) sPayload = XmlUtils.convertDomNodeToString((Node)msgValue); } sPayload_org = sPayload; String tobeReplaced = "PRE_ROUTING"; String replaceWith = "PRE_ROUTING_||_PRE_ROUTING_RULE"; int start = sPayload.indexOf(tobeReplaced); StringBuffer sb = new StringBuffer(); sb.append(sPayload.substring(0, start)); sb.append(replaceWith); sb.append(sPayload.substring(start + tobeReplaced.length())); String changedPayload = sb.toString(); XMLDocument changedoc; try { changedoc = XmlUtils.getXmlDocument(changedPayload); String mykey = "request"; calloutMediatorMessage.addPayload(mykey, changedoc.getDocumentElement()); // calloutMediatorMessage.getPayload().put(mykey, changedoc); } catch (Exception e) { } System.out.println("Changed from : \n"+sPayload_org+"\nTo\n"+changedPayload); System.out.println("End PreRoutingRule.\n\n"); return true; } public boolean postRoutingRule(CaseType caseType, CalloutMediatorMessage calloutMediatorMessage, CalloutMediatorMessage calloutMediatorMessage1, Throwable throwable) { System.out.println("Start PostRoutingRule."); String req_sPayload = "null"; String req_sPayload_org = "null"; String rep_sPayload = "null"; String rep_sPayload_org = "null"; for (Iterator msgIt = calloutMediatorMessage.getPayload().entrySet().iterator(); msgIt.hasNext(); ) { Map.Entry msgEntry = (Map.Entry)msgIt.next(); Object msgKey = msgEntry.getKey(); Object msgValue = msgEntry.getValue(); if(msgKey.equals("request")) req_sPayload = XmlUtils.convertDomNodeToString((Node)msgValue); } req_sPayload_org = req_sPayload; String tobeReplaced = "PRE_ROUTING_RULE"; String replaceWith = "PRE_ROUTING_RULE_||_POST_ROUTING_RULE_REQUEST"; int start = req_sPayload.indexOf(tobeReplaced); StringBuffer sb = new StringBuffer(); sb.append(req_sPayload.substring(0, start)); sb.append(replaceWith); sb.append(req_sPayload.substring(start + tobeReplaced.length())); String changedPayload = sb.toString(); XMLDocument changedoc; try { changedoc = XmlUtils.getXmlDocument(changedPayload); String mykey = "request"; calloutMediatorMessage.addPayload(mykey, changedoc.getDocumentElement()); // calloutMediatorMessage.getPayload().put(mykey, changedoc); } catch (Exception e) { } for (Iterator msgIt = calloutMediatorMessage1.getPayload().entrySet().iterator(); msgIt.hasNext(); ) { Map.Entry msgEntry = (Map.Entry)msgIt.next(); Object msgKey = msgEntry.getKey(); Object msgValue = msgEntry.getValue(); if(msgKey.equals("reply")) rep_sPayload = XmlUtils.convertDomNodeToString((Node)msgValue); } rep_sPayload_org = rep_sPayload; tobeReplaced = "PRE_ROUTING_RULE"; replaceWith = "PRE_ROUTING_RULE_||_POST_ROUTING_RULE_REQUEST_REPLY"; start = rep_sPayload.indexOf(tobeReplaced); sb = new StringBuffer(); sb.append(rep_sPayload.substring(0, start)); sb.append(replaceWith); sb.append(rep_sPayload.substring(start + tobeReplaced.length())); changedPayload = sb.toString(); try { changedoc = XmlUtils.getXmlDocument(changedPayload); String mykey = "reply"; calloutMediatorMessage1.addPayload(mykey,changedoc.getDocumentElement()); // calloutMediatorMessage1.getPayload().put(mykey, changedoc.getDocumentElement()); } catch (Exception e) { } System.out.println("Changed from : \n"+req_sPayload_org+"\nTo\n"+changedPayload); System.out.println("End postRoutingRule\n\n"); return true; } }
動的ルーティングの基本的な考え方は、プロセスが経由するパスを決定する制御ロジックを、そのプロセスの実行から分離することです。動的ルーティングのシナリオでは、デシジョン・マトリックスによって各ルーティングに対して選択されるレベル2タイプのサービスが決定されます。レベル2タイプのサービスのデシジョンに影響を与える要因は、チャネル、顧客タイプなどです。このソリューションによって、ビジネス・アナリストはルーティングを変更せずに、このデシジョン・マトリックスを外部から変更できます。アウトバウンド・サービスを決定するためには、デシジョン・マトリックスを評価する必要があります。
動的ルーティング・ルールを作成する手順は、次のとおりです。
図20-32に示すように、メディエータ・エディタの動的ルーティング・ルールのオプションを使用します。
このウィンドウで、新しいビジネス・ルール・サービス・コンポーネントが作成され、メディエータ・サービス・コンポーネントのSOAコンポジット内のメディエータ・サービス・コンポーネントに接続されます。ビジネス・ルール・サービス・コンポーネントとメディエータ・サービス・コンポーネント間のワイヤ・リンクは、実装の詳細とみなされ、図20-33に示すように、SOAコンポジット・エディタでは点線で表示されます。
図20-33 ビジネス・ルール・サービス・コンポーネントとメディエータ・サービス・コンポーネント間のワイヤ・リンクが表示されたSOAコンポジット・エディタ
ビジネス・ルール・サービス・コンポーネントには、ルール・ディクショナリが含まれています。ルール・ディクショナリは、ファクト・タイプ、ルールセット、ルール、デシジョン表など、ルール・エンジン・アーティファクトに対するメタデータ・コンテナです。ルール・ディクショナリは、ビジネス・ルール・サービス・コンポーネントの作成過程で、次のデータを使用して事前に初期化されます。
ファクト・タイプ・モデル
ファクト・タイプ・モデルは、ルールのモデル化に使用できるデータ・モデルです。ルール・ディクショナリには、BPELプロセスのphaseアクティビティの入力に対応するファクト・タイプ・モデルと、メディエータ・サービス・コンポーネントとビジネス・ルール・サービス・コンポーネント間の規定の一部として必要な固定データ・モデルの一部が移入されます。
ルールセット
ルールセットは、ルールのグループ化メカニズムとして使用されるルールのコンテナです。ルールセットはサービスとして公開できます。ビジネス・ルール・サービス・コンポーネントの作成過程で、1つのルールセットがルール・ディクショナリ内に作成されます。
デシジョン表(またはマトリックス)
ルール・エンジンから見ると、デシジョン表は、ルールの条件およびアクション部分のファクト・タイプ・モデルの要素が同じであるルールの集合です。デシジョン表を使用すると、ルールを表形式で表示できます。ビジネス・ルール・サービス・コンポーネントの作成過程で、ルールセット内に新規デシジョン表が作成されます。
デシジョン・サービス
デシジョン・サービスは、ビジネス・ルール・サービス・コンポーネントの作成過程で作成され、ルールセットをビジネス・ルール・サービス・コンポーネントのサービスとして公開します。メディエータ・サービス・コンポーネントでは、サービス・インタフェースを使用してデシジョン表を評価します。
phaseアクティビティの必要なアーティファクトがすべて作成されると、ウィザードでは、フェーズ・デシジョン・マトリックス(PDM)のモデル化が開始されます。Oracle JDeveloperのビジネス・ルール・デザイナが起動され、フェーズ・デシジョン・マトリックスを編集できるようになります。図20-34に、ビジネス・ルール・デザイナ内のデシジョン表のサンプルを示します。
動的ルーティングを作成した後は、「動的ルールの編集」をクリックして、関連デシジョン・マトリックスを変更できます。ビジネス・ルール・デザイナが起動され、ビジネス・ルール・サービス・コンポーネントの関連デシジョン表の変更が可能になります。メディエータ・サービス・コンポーネントに対して動的ルーティングを作成した後は、その動的ルーティングを削除しないかぎり、静的ルーティングに戻すことはできません。現在、これら2つのタイプのルーティングを組み合せて使用するオプションはありません。
動的ルーティング・オプションを選択した後のメディエータ・エディタは、図20-35のようになります。
ソース・ビューは次のように変更されます。
<Mediator name="Shipment" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/sca/1.0/mediator"> <operation name="execute" deliveryPolicy="AllOrNothing" priority="0"> <switch decisionServiceRef="Phase1DecisionService" decisionServiceOperation="executeFunction"></switch> </operation> </Mediator>
switch
要素には、デシジョン・サービス参照および操作の詳細が含まれています。これによって、メディエータ・サービス・コンポーネントは、動的ルーティング・デシジョンを取得するためのデシジョン・サービスを実行時に起動できます。動的デシジョンは、実行時のビジネス・ルール・サービス・エンジン・ユーザー構成によって返されます。
外部サービスの起動には、bindingInfoという特別な属性が含まれます。この属性には、起動を動的にするためのバインディング情報が含まれています。
メディエータで動的ルーティング・ルールを使用する場合は、次の制限に注意してください。
現在は、SOAPバインディングのみがサポートされています。composite.xml
ファイルには、ダミーのSOAPバインディングが作成されます。このエンドポイントは、NMプロパティを介して実行時にメディエータによってオーバーライドされます。このため、アウトバウンド・サービスはSOAPを介してのみコールできます。
動的ルーティング・ルールによってペイロード操作が制限されます。割当て、トランスフォーメーションまたは検証は実行できません。
参照WSDLファイル(レイヤー2またはコールした参照)には、自動的に作成されるフェーズ参照と同じ抽象的なWSDLファイルが必要です。
動的ルーティングは、同期インタフェースまたは一方向インタフェースを使用するメディエータには使用できません。
メディエータでは、ルーティング・ルールで指定された条件に従ってメッセージが処理されます。ルーティング・ルールで指定されたいずれの条件も満たさないために、受信メッセージが処理されない場合もあります。このようなメッセージに使用するデフォルト・ルーティング・ルールを定義できます。デフォルト・ルーティング・ルールは、他のルーティング・ルールの条件がいずれも満たされない場合に実行されます。
デフォルト・ルーティング・ルールは、第20.3.2項「静的ルーティング・ルールの作成方法」で説明したルーティング・ルールと同じです。デフォルト・ルーティング・ルールが他のルーティング・ルールと異なる唯一の点は、デフォルト・ルーティング・ルールには関連付けられた条件がないことです。それ以外は、ターゲット・サービス、レスポンス処理、フォルト処理などすべてにおいて、デフォルト・ルーティング・ルールは他のルーティング・ルールと同じです。
注意:
|
デフォルト・ルーティング・ルールは、順次ルールまたはパラレル・ルールのいずれかに設定できます。順次またはパラレルに関係なく、デフォルト・ルーティング・ルールは、他のルーティング・ルールの条件が満たされない場合に実行されることが保証されています。デフォルト・ルールが実行された場合、メディエータの監査証跡には、すべてのルーティング・ルールのフィルタ条件が満たされず、デフォルト・ルーティング・ルールのフィルタ条件が満たされて実行されたことが示されます。例20-21に詳細を示します。
例20-21 デフォルト・ルールのシナリオ
ActivityJan 7, 2010 4:35:15 PM Message onCase "fileout2.Write" Jan 7, 2010 4:35:15 PM Message Evaluation of xpath condition " No Filter (DEFAULT CASE) " resulted true
デフォルト・ルーティング・ルールも含めて、すべてのルーティング・ルールは順次またはパラレルのルーティング・ルールとして定義できるため、想定されるルーティング・ルールの動作は多数あります。次の各項では、各組合せと想定される動作について説明します。
順次のデフォルト・ルーティング・ルール
順次のデフォルト・ルーティング・ルールでは、次のシナリオが考えられます。
メディエータの他のルーティング・ルールがすべて順次の場合: これは、デフォルト・ルーティング・ルールも含めて、すべてのルーティング・ルールのタイプが順次である最も単純なケースです。すべてのルーティング・ルールのフィルタ条件が実行時に評価され、いずれのフィルタ条件も一致しない場合は、順次のデフォルト・ルーティング・ルールが実行されます。順次のデフォルト・ルーティング・ルールは、受信メッセージと同じトランザクションで実行されます。デフォルト・ルールの実行後に、事後Javaコールアウトが発生します。
メディエータのルーティング・ルールの少なくとも1つがパラレルである場合: これは、デフォルト・ルーティング・ルールが順次であり、他のルーティング・ルールの少なくとも1つがパラレルである複雑なケースです。実行時のデフォルトの動作では、最初に順次ルーティング・ルールがすべて実行された後で、パラレルのルーティング・ルールが実行されます。したがって、デフォルト・ルールは、他のすべてのルーティング・ルールがfalseであると評価された後でのみ実行する必要があるため注意が必要です。
この場合、サーバーでは、最初にパラレル・ルールのフィルタ条件が評価された後でデフォルト・ルーティング・ルールのフィルタ条件が評価されます。他のいずれのフィルタ条件も一致しない場合は、順次のデフォルト・ルーティング・ルールが実行されます。
パラレルのデフォルト・ルーティング・ルール
パラレルのデフォルト・ルーティング・ルールでは、次のシナリオが考えられます。
メディエータの他のルーティング・ルールがすべてパラレルの場合: これは簡単なケースです。デフォルト・ルーティング・ルールは、他のルーティング・ルールで指定されたいずれかのフィルタ条件が一致する場合は実行されません。フィルタ条件がいずれも一致しない場合は、デフォルト・ルーティング・ルールが非同期で実行されます。
メディエータの他のルーティング・ルールが順次またはパラレルである場合: これは複雑ですが一般的なユースケースです。使用可能な他の順次またはパラレルのルーティング・ルールがあり、デフォルト・ルーティング・ルールがパラレルの場合です。デフォルト・ルーティング・ルールは、他の順次またはパラレルのルーティング・ルール基準のいずれかが一致した場合は実行されません。条件がいずれも一致しない場合は、デフォルト・ルーティング・ルールが非同期で実行されます。
注意: デフォルト・ルーティング・ルールが自動的に実行されるということは、デフォルト・ルーティング・ルールが、特定のメディエータ・サービス・コンポーネントに対して実行された唯一のケースであることを意味します。同様に、メディエータ・サービス・コンポーネントに、フィルタ条件が指定されていない1つのルーティング・ルールがあり、デフォルト・ルーティング・ルールもある場合、そのデフォルト・ルーティング・ルールが実行されることはありません。 |
デフォルト・ルーティング・ルールのターゲットは、他の既存ルーティング・ルールのサポートされているターゲットと同じです。つまり、ターゲットにはサービス、イベントまたはエコーを設定できます。同様に、デフォルト・ルーティング・ルールのターゲット・サービスからのレスポンスは、コール元に転送するか、返すことができます。ターゲット・サービスからフォルトが返された場合は、他のルーティング・ルールで処理される場合と同様に処理されます。
注意: 他のルーティング・ルールの評価または実行時に例外が発生した場合、デフォルト・ルーティング・ルールは実行されません。 |
デフォルト・ルーティング・ルールのSchematron検証、トランスフォーメーションおよび割当機能は、他のルーティング・ルールと同様に動作します。
事前Javaコールアウトまたは事後Javaコールアウトの現在の動作は、他のルーティング・ルールの場合と同様です。Javaコールアウト場合は、デフォルト・ルーティング・ルールは別のルーティング・ルールとみなされます。したがって、デフォルト・ルーティング・ルールが実行されるシナリオの場合、postRouting()
コールバック・メソッドは、デフォルト・ルーティング・ルールが実行された後でのみ発生します。
注意: 事後Javaコールアウトは、順次ルールの実行後に発生し、パラレル・ルールの実行の完了は待機しません。したがって、デフォルト・ルーティング・ルールが順次の場合、 |
2つのチュートリアルが入手可能であり、それらでは、Oracle SOA Suiteサンプル・ページ
で提供されているメディエータ・サンプル・プロジェクトのうちの2つを作成する手順を示しています。作成したメディエータにルーティング・ルールを定義する方法を説明しています。それらのチュートリアルは、http://java.net/projects/oraclesoasuite11g/downloads/download/Mediator/Tutorials/med_rr_tutorial.pdf
からダウンロードできます。