[SOA] Fanning Out Events on the Oracle SOA Suite 11g Event Delivery Network

原文はこちら。
http://www.oracle.com/technetwork/articles/soa/jellema-events-soasuite-1902429.html

著者について
Lucas Jellemaは、1994年以来(Oracleと共に)ITで活躍してきました。 Oracle Fusion MiddlewareのOracle ACE DirectorであるLucasは、Oracle Database(SQL、PL/SQL)、サービス指向アーキテクチャ、ADF、およびJavaを含む多様な分野でのコンサルタント、トレーナー、およびインストラクターです。彼はOracle SOA Suite 11g Handbookの著者であり、JavaOne、Oracle Open World、ODTUG Kaleidoscope、Devoxx、その他のコンファレンスでたくさんの発表を行っています。
Oracle SOA Suite 11g Handbook / By Lucas Jellema (Oracle Bookstore)
http://astore.amazon.com/oraclebooks-20/detail/0071608974

サンプルはこちら。
Sample code for this article (zip, 54kb)
http://www.oracle.com/technetwork/articles/soa/fanoutevent-sources-1903159.zip

Overview

この記事ではOracle SOA Suite 11gでイベントを使い、最大限分断しつつ、意味のある形で相互にビジネスプロセスが影響を与える方法をご説明します。具体的には、この記事ではEvent Delivery Network (EDN)イベントをよりきめ細かいレベルに広げるためのソリューションです。これを使うと、一つのイベントが複数の実行中のBusiness Process Execution Language (BPEL)プロセスのインスタンスに影響を及ぼすことができます。この記事では以下のOracle SOA Suite 11gコンポーネントを利用します。
  • BPEL
  • Mediator
  • Event Delivery Network
  • Spring
  • Locator API
  • Composite Sensors

Introduction

イベントとはメッセージですが、特定のコンシューマをターゲットにしていません。SOA環境においては、コンポーネント間の依存性を減らし、再利用性や柔軟性を増すためにdecoupling(分断)が主要な目的の一つであるため、イベントは極限まで分断して情報を共有するための価値ある方法です。

イベントのパブリッシャーは潜在的に他のコンポーネントが関心を持っているビジネスの状況を知るコンポーネントです。コンポーネントが責任をもって、関連する詳細情報と共に汎用的なイベントハンドラ基盤に対しイベントを渡します。パブリッシャーはイベントのサブスクライバーのことは認識していません。パブリッシャーはイベントで何が起こり、誰がイベントを消費するのか知っている必要はありません。

特定のビジネス·イベントに関心を持つすべてのコンポーネントが、イベントハンドラインフラストラクチャを使い、これらのイベントのリスナーとして登録できます。特定のビジネスイベントタイプのイベントがイベントハンドラに渡されるたびに、サブスクライブしているすべてのリスナーにイベントが発行されます。イベントのコンシューマーは、どこでイベントが発生し、どのように配信されるのかを知る必要はありません。
図1
イベントパブリッシャーやイベントコンシューマー間のつながりが完全に切れていることが、イベントとイベント駆動型アーキテクチャパターンを利用する上で大きな魅力的です。依存関係のないコラボレーションはアーキテクトの至高の目標と言ってもいいでしょう。

Events in the Oracle SOA Suite: EDN and BPEL

Oracle SOA Suite 11gはイベントハンドラ基盤を備えており、この基盤はビジネスイベントのパブリッシャーにとって仲介者であるとともに、こうしたイベントのコンシューマーでもあります。この基盤をEvent Delivery Network (EDN)と呼んでいます。
(注意)SCAコンポジットアプリケーションでイベントと共にJMSやAQを利用できます。

EDNで特定のイベントをサブスクライブ可能なコンポーネントの一つにBPELがあります。MediatorやBPMNもEDNイベントをサブスクライブできます。BPELプロセスはEDNイベントを次の2方法のうち1方法で受け取ることができます。
  • イベントで新しいBPELプロセスインスタンスを生成する
  • イベントが実行中のBPELプロセスインスタンスに消費される
最初のオプションは有用ですが、この記事ではもう一つの状況について取り上げます。イベントが実行中のイベントに消費されると、イベントは明らかにそのインスタンスや進行する向きに影響を与える可能性があります。このパターンを、ビジネスイベントが実行中のビジネスプロセスに影響を与える可能性のある状況で使います。このようなイベントの例としては、特定の国や会社との貿易の禁止、倉庫での火災、クライアントの死亡、または特定の製品またはサービスの即時撤退というように、かなり劇的な可能性があります。それほど劇的でない例では、(マーケティングキャンペーンに応答した)新しいクライアント、一般的な割引期間の開始や終了、病気で呼び出されるスタッフ、特定の製品の在庫枯渇があります。

ビジネスの条件が事前に定義されたビジネスイベントに対応するものと認識されているならば、イベントを発行します。イベントに反応して何が起こるか、どこで誰によって起こるかは目に見えないし、イベントのパブリッシャーにとっては無関係です。

この記事では、Termination of Customer(顧客の終了)というイベントを検討します。このイベントは、会社が顧客とのすべての取引を中止するべきであることを意味します。任意のセールスサイクルが中止され、全く出荷が行われず、保留中の注文がキャンセルされます。この影響力のあるイベントは、例えば顧客が破産を申請したとか、特定の連邦政府の調査対象であるような場合にパブリッシュされます。先ほど述べたように、イベントの発生元とその原因はイベントコンシューマーにとっては無関係です。終了対象の顧客のIDというシンプルなペイロードでイベントを流す必要があります。
図2
こうしたイベントコンシューマーの一つに、BPELプロセスのProcessOrderがあります。このプロセスは顧客からの注文を処理し、受注から出荷、そして後続の請求プロセスの起動までを取り扱います。下図はプロセスの概要を示しています。

図3
顧客資格が停止されると、すべての実行中のProcessOrderプロセスインスタンスが中断されます。この目的のため、BPELプロセス中のDoAllTheWorkというスコープにはイベントハンドラーがあり(図4参照)、終了イベントを消費してプロセスを正常に終了することができます。
図4
相関に基づいて実行中のBPELプロセスインスタンスでイベントを消費することができます。BPELの相関の本質は、すべてのプロセスインスタンスが一意のキーを持つ、ということです。これは相関識別子という、着信メッセージやプロセス内で確立された派生したもので、これを使い、インスタンスと着信メッセージやイベントを関連付けます。相関関係を成功するためには、この着信メッセージやイベントはこの一意のキーを含む必要があります。

The challenge at hand

すでにこの記事で直面している課題に目星がついていることでしょう。一つのTerminateCustomerイベントが多くのProcessOrderというBPELインスタンスに影響を与える可能性がある、ということです。しかし、これらのインスタンスは、その一意の識別子に基づいて着信イベントと相関させることができます。それゆえ、EDNの任意のイベントをせいぜい一つのBPELプロセスのインスタンスが消費できるのです。

同じ顧客に対して同時に処理されている複数のオーダーが存在し得るので、ProcessOrderインスタンスをCustomerIDで一意に識別することができません。その代わりに、ProcessOrderインスタンスはそのOrderIDで識別されています。

イベントを発行し、現在その取引を停止する顧客のために処理されているすべての注文のために、一つのTerminateCustomerイベントを複数のAbortOrderForCustomerイベントに変換する解決策を見つける必要があります。 AbortOrderForCustomerイベントのペイロードには、OrderIDが含まれており、これを使ってProcessOrderというBPELプロセスの1つのインスタンスに正確に関連付けることができます。
図5

Addressing the challenge

やるべきことは明確で、ビジネスイベントと紐付けるきめ細かい詳細情報を見つけ出し、その各々の詳細情報に対し、適切なイベントを発行する、ということです。この場合、ビジネス·オブジェクトのCustomerに詳細Orderオブジェクトが関連付けられています。TerminateCustomerイベントの場合、当該顧客の実行中の受注を検索し、その後、各注文に対しAbortOrderForCustomerイベントを発行する必要があります。イベントの発行は簡単です。Oracle SOA SuiteでMediatorが完璧にうまくやってくれます。

本当の問題は、実行中のProcessOrderインスタンスを検索する方法です。ここでは、Oracle SOA SuiteのAPIを利用して、プログラムでインスタンスを問い合わせることができます。APIを使うと、Composite Sensorの値でインスタンスをフィルタリングすることができます。ProcessOrderコンポジットがComposite SensorとしてCustomerIDが公開されている場合、特定のCustomerIDに紐付くインスタンスだけをAPIで取得することができます。このような各インスタンスのために、OrderIDが必要です。APIを使って簡単にインスタンスのセンサー値を取得できるため、OrderIDを含む2個目のComposite Sensorが役に立ちます。

これを念頭に置いて、この課題に対する解決策の案を図6に作ってみました。最初の1枚は、Oracle OpenWorld期間中に開催されたOracle SOA Suite Customer Advisory Boardでナプキンに走り書きしたものです。明らかに思いつきですね。この案は以下の手順を含んでいます。
  1. 様々な顧客に対応する一つ以上のProcessOrderのBPELプロセス·インスタンスを開始する。このBPELプロセスを含むSOAコンポジット·アプリケーションには、2つのComposite Sensor(CustomerIDとOrderID)がある。
  2. TerminateCustomerイベントをEvent Delivery Network(EDN)発行する。ペイロードにはCustomerIDを含む。
  3. (不可能な手順):取引停止の顧客に対し実行しているすべてのProcessOrderインスタンスに、単一のイベントを渡す。
  4. 手順3のかわりに、Mediatorコンポーネントを使ってTerminateCustomerイベントを消費し、イベントからCustomerIDを抽出する。
図6
  1. (CustomerIDを渡して)Spring Contextコンポーネントを呼びだす…
  2. このSpring Contextコンポーネントは、Oracle SOA SuiteのJava APIを使ってComposite Sensorを使ってCustomerIDと紐付くProcessOrderのすべての実行中インスタンスを識別し、第2のComposite Sensorの値からこれらのインスタンスのOrderIDを収集する。
  3. 各OrderIDに対しMediatorを呼び出す
  4. MediatorはOrderIDをペイロードとして持つAbortOrderForCustomerイベントをEDNに対し発行する。
  5. 各AbortOrderForCustomerイベントはOrderIDと相関を持つProcessOrder BPELプロセスの一つの実行中インスタンスが消費する。BPELプロセスインスタンスは事前に定義されているロジックに従い終了する。
図7は、SOAコンポジットアプリケーションで実装が必要なコンポーネントを示しながら、走り書きから技術的な設計に落とし込んだものです。
図7

Implementation Steps

この記事の残りの部分では、上述のSOAコンポジットアプリケーションを実装するための手順を詳細に説明しますが、ここには、ProcessOrderビジネスプロセスを実行するためのBPELプロセスが含まれています。また、顧客に関連付けられた各注文のイベントにTerminateCustomerイベントを発行するMediatorとSpringコンポーネントが含まれています。EDNのイベントを定義し、最後に、アプリケーションを実際に動かしてご覧にいれましょう。

もちろん、この記事で説明したBPELプロセスは実際の運用環境で使うプロセスよりもずっとシンプルになっていますが、主要な要素とイベント発行メカニズムの価値を損なうわけではありません。

Implementing the ProcessOrder BPEL process

作業は新しいSOAコンポジットアプリケーションを(SOA Extensionインストール済みの)JDeveloper 11gで作成するところから始まります。このアプリケーションをFanoutEventと呼びます。現在のところ、プロジェクトにはSOAコンポジットが含まれています。これ以後記載のソースや成果物はこの記事からダウンロード可能なソースからご利用いただけます。
サンプルコード
http://www.oracle.com/technetwork/articles/soa/fanoutevent-sources-1903159.zip

Develop BPEL Process component ProcessOrder

ProcessOrder.wsdlファイルには、ProcessOrderというBPELプロセスが公開するWebサービスが記述されています。このサービスにはProcessOrderというportTypeがあり、一つの非同期オペレーションプロセスがあります。このオペレーションはProcessOrderRequestMessageという、一つのメッセージパートを持つ入力メッセージを取ります。このメッセージパートはProcessOrder.xsdファイルのOrder要素に定義されています。
図8
Order要素は非常にシンプルです。CustomerIdentifierとOrderIdentifierが製品名、品目個数、配達の詳細と共に渡されます。

サービスは非同期であるため、Callbackポートタイプが定義されています。このポートタイプには一つのオペレーション(processResponse)があり、ProcessOrderResponse要素を基にしたシンプルなシングルパートのメッセージを取ります。ところで、この記事の説明上、このレスポンスメッセージは全く無関係です。
図9
WSDLとXSDドキュメントに基づいて、BPELプロセスコンポーネントをコンポジットに追加します(図10)。
図10
このプロセスにはDoAllTheWorkという一つのスコープが含まれています。このスコープでは、すべての注文処理を実装することができますが、この記事では、そのような処理は必要ではありません。このスコープに含むものは、Waitアクティビティだけです。

Add Composite Sensors for CustomerIdentifier and OrderIdentifier

以前、イベントレベルの不一致に対する解決策を議論した際に、2個のComposite Sensorを導入しました。これらのセンサーを使うと管理者はOracle Enterprise Manager Fusion Middleware Controlのコンソールでコンポジットインスタンスを検索し抽出することができます。また、Java APIを使ってプログラムでインスタンスを検索することも可能です。

センサーアイコンを使うComposite Editorで、Composite Sensor Editorを使って最初のComposite Sensorを定義します。これをCustomerIdentifierと呼び、BPELが公開するSCA Serviceに接続しています。このセンサー値はリクエストメッセージ中のOrder要素のCustomerIdentifier要素から導出されます。言い換えると、このセンサー値はCustomerIdentifierに一致します。Process Orderインスタンスを作成するインスタンスのCustomerIdentifierに等しい、ということです(図11)。
図11
2個目のComposite Sensorを作成します。これもOrderIdentifierを出力します。Java APIを使ってこの値を保持し、送出するAbortOrderForCustomerイベントのペイロードとして使う必要があります(図12)
図12

Create AbortOrderForCustomer Event

XMLスキーマ定義ファイルのevents.xsdには AbortOrderForCustomerEventタイプがあり、ここでAbortOrderForCustomerというEDNイベントのペイロードを説明しています(図13)。
図13
AbortOrderForCustomerEventには子要素としてOrderIdentifierとCustomerIdentifier、motivationが含まれています。

このAbortOrderForCustomerEvent定義を基にして、AbortOrderForCustomerイベントをCustomerEvents.edlファイルで定義します。次の図はこのイベント定義を説明しています(図14)。
図14

Subscribe the ProcessOrder BPEL process to the AbortOrderForCustomer Event

この時点での状況は以下のようになっています。
非同期Webサービスと2個のコンポジットセンサーを公開するコンポジット。
さらに、コンポジット(もしくはコンポジットが包含するBPELコンポーネント)はEDNイベントAbortOrderForCustomerにサブスクライブされています。
図15

Setup Correlation

イベントをProcessOrderの実行中インスタンスに取り込むため、イベントの消費に対する相関を設定する必要があります。つまり、(OrderIDを使って)どのようにProcessOrderインスタンスを識別しすべきか、いつ、どのように一意のキーをインスタンスに割り当てるべきか、いつ、どのようにインバウンドメッセージやイベントをこの一意のキーと照合するか、を指定します。

まず、OrderIdentifierと呼ばれるプロパティに基づいて、相関セットOrderIdentifierCorrelationSetを作成します。
図16
これは単一の値を基にした一意のキーの定義を意味します。

次は、インバウンドメッセージやイベントと相関セット内のプロパティをマッピングするためのプロパティエイリアスを定義します。図17では、プロパティOrderIdentifierをインバウンドメッセージのProcessOrderRequestMessageのOrder要素に含まれるOrderIdentifierという子要素とマッピングしています。このプロパティをAbortOrderForCustomerEventペイロードのOrderIdentifier要素ともマッピングします。これにより、ProcessOrderRequestMessageとAbortOrderForCustomerEventの両方がProcessOrderインスタンスを一意に識別するために必要な情報を含んでおり、それらが相関の関係にある、ということをBPELエンジンに指示しています。
図17

Associate Receive and Message Handler with CorrelationSet

まだBPELプロセスから欠けているものが一つあります。我々は、一意のキーがインスタンスに設定されている場合、そしてその一意のキーを使って既存のインスタンスに着信イベントまたはメッセージを供給する場合、BPELエンジンに指示する必要があります。

ProcessOrderRequestMessage(および第作成されたインスタンス)を受信した場合、このプロセスで、相関セットを初期化します。ProcessOrderRequestMessageを受信し(インスタンスが最初に作成され)た際に、相関セットを開始します。最初のReceiveアクティビティで、相関セットOrderIdentifierCorrelationSetは[相関]タブに表示され、開始プロパティが[はい]に設定されています。

相関セットを使って着信するAbortOrderForCustomerイベントを既存のProcessOrderインスタンスに取り込みます。これはDoAllTheWorkスコープで定義されたonMessageイベントリスナーで起こります。OnMessageアクティビティもまた同じOrderIdentifierCorrelationSetを使って相関が構成されています。こんどは、インスタンスIDに割り当てたくなく、この値を使ってイベントを実行中のインスタンスにマッピングしたいため、開始プロパティが[いいえ]に設定されています。

図18ではReceiveアクティビティとOnMessageアクティビティの両方で相関を設定する方法を説目いしています。
図18

Implement the Event Fan Out machinery

TerminateCustomerイベントをCustomerevents.edlファイルに定義します。Fan-out mediatorがこのイベントをインターセプトする必要があります。このMediatorはTerminateCustomerイベントをEvent Delivery Networkを使ってサブスクライブします。イベントが到着すると、Mediatorがアクティブになり、Springコンポーネントを呼び出します。


SpringコンポーネントはTerminateCustomerイベントのペイロードに含まれる顧客IDを使って、正しい値を持つコンポジットセンサーCustomerIdentifierを出力する、すべての実行中のProcessOrderインスタンスを(SOA SuiteやJava APIを使って)検索します。Springコンポーネントは各インスタンスのコンポジットセンサーOrderIdentifierの値を抽出し、各インスタンスについてもう一つのMediatorを呼びだし、その特定のOrderIDの値について、AbortOrderForCustomerイベントをEDNにパブリッシュします。

Definition of the TerminateCustomer event

XMLスキーマ定義ファイルのEvents.xsdには、TerminateCustomerイベントのペイロードを定義するために使用される、TerminateCustomerタイプが含まれています。このペイロードは、少なくともcustomerIdentifierを含める必要があります。子要素motivationはおまけとして追加されています。
図20
TerminateCustomerイベントをCustomerEvents.edlファイルで定義します。このペイロードはXSDファイル内のTerminateCustomerタイプに基づいています。図21では、このコンポジットアプリケーションで認識されている2個のビジネスイベントを使ってedlファイルを紹介しています。
図21
TerminatorCustomerイベントを消費するMediatorを作成しましょう。
「イベントのサブスクライブ」テンプレートを基に、ConsumeTerminateCustomerというMediatorコンポーネントを作成します。イベント定義ファイルCustomerEvents.edlからこのコンポーネントがサブスクライブするイベントとして、TerminateCustomerイベントを選択します。
図22
イベントをサブスクライブするMediatorをコンポジットに追加します。
図23

Create the event publishing Mediator for AbortOrderForCustomer

次に追加するコンポーネントは、AbortOrderForCustomerイベントをパブリッシュするMediatorコンポーネントです。このMediatorのインターフェースを定義する簡単なWSDLドキュメントを設定しました。AbortOrderForCustomerイベントのペイロード定義を基にした入力要素を持つ、一方向のオペレーション(publishAbortOrderEvent)を含んでいます。
図24
AbortOrderForCustomerイベントを発行するため、ルーティングルールをMediatorに追加します。トランスフォーメーションはリクエストメッセージのペイロードパートからイベントペイロードへ、1対1のマッピングをします。
図25

Create and wire the Spring Component

SpringコンポーネントTerminateCustomerToAbortOrderEventTranslatorをコンポジット中に作成します。

MediatorコンポーネントPublishAbortOrderEventをSpringコンポーネントとつなぎます。このMediatorはSpringコンポーネントが要求するイベントを発行します。
図26

これはSpring bean定義ファイルで作成された任意のbeanに後で注入できるSpringコンポーネントでsca.referenceを作成します。
図27
この参照はPublishAbortOrderEventInterfaceというJava Interfaceを基にしており、これはMediatorのインターフェースを表現するWSDL用にJDeveloperが生成します。
図28
Springコンポーネントが提供するサービスを説明するCustomerToOrderEventProcessor Javaインターフェイスを作成します。このインタフェースは、TerminateCustomerイベントを処理でき、2個の文字列を入力値とするメソッドを定義しています。インタフェースで定義された2個目のメソッドは、前段で導入したPublishAbortOrderEventInterfaceの実装を注入するために使用されるセッターです。このJavaインターフェース由来のメディエータPublishAbortOrderEventは、既に作成済みのsca:referenceを通じてこの実装を提供します。
図29
Springコンポーネントが提供するsca:serviceを、現在Spring Bean定義ファイルで定義することができます。公開されている名前はCustomerToOrderEventProcessorで、サービスインターフェースは、Javaインターフェースによって指定されます。
図30
このsca:serviceのWSDLベースのインターフェース記述(CustomerToOrderEventProcessor.wsdl)は、Springコンポーネントのサービスをコンシューマと接続した際(この場合ComsumeTerminateCustomerというMediatorです。図31参照)に、は、JDeveloperが生成します。
図31
ソリューションの外殻を作成し、すべての結線が適切に配置されています。欠けているのは、Javaインターフェースを実装し、Springコンポーネントのsca:serviceが約束した実際の作業を実施するJava Spring Beanです。この実装は、次で説明します。

Implementing the Spring Bean

JavaクラスCustomerToOrderEventProcessorImplはCustomerToOrderEventProcessorインタフェースの実装で、processTerminateCustomerEventとsetPublishAbortOrderEventInterfaceの両メソッドを実装しています。

このクラスに基づくSpring Beanを次のように設定できます。
図32
CustomerToOrderEventProcessorBeanと呼ばれるBeanは、sca:serviceの実装を提供しており、このリンクはターゲット属性を介して確立されます。 (AbortOrderForCustomerイベントを発行するメディエータを通して注入される)sca:referenceはBeanのpublishAbortOrderEventInterfaceプロパティに設定されています。

クラスそのものは非常に簡単です。AbortOrderForCustomerEventオブジェクト、いわゆる"ペイロード"をメディエータに渡しイベントを発行する準備をします。このクラスは、customerIdentifierに対応する現在実行中のProcessOrderインスタンスからすべてorderIdentifierの一覧を取得します。その後、これらのorderIdentifierを反復処理し、それぞれに対応したMediatorを呼び出します。
図33
最も難しい作業は、collectOrderIdentifiersというプライベートメソッドで行われます。このメソッドは、Oracle SOA SuiteのJava APIと接続し、customerIdentifierに値を設定されたCustomerIdentifier Composite Sensorを使ってすべてのProcessOrderインスタンスをクエリします。
図34
このAPIによるクエリは、CustomerIdentifierという名前のComposite Sensorとセンサー値が設定されているSensorFilterを使っています。このAPIが返す各インスタンスから、OrderIdentifier Sensorの値は2つのステップで取得されます。まず、getSensorData()でインスタンス用のComposite Sensorのコレクションを取得します。続いて、このコレクションに対してOrderIdentifier Sensorのエントリを発見するという単純な繰り返し処理を実施します。値があればその値を読み取ります。こうして決定された値を、このメソッドが返すそのorderIdentifierのコレクションに追加します。
図35

Reviewing the work

これまで説明したすべての最終結果を図36に示します。通常のビジネスフローはBPELプロセスProcessOrderをアクティベートするProcessOrder_epサービスへの呼び出しです。このインスタンスは、その存続期間中いつでもAbortOrderForCustomerイベントを消費するような状態になっています。そのイベントは、Order IDに基づいてインスタンスに関連付けることができます。.

例外的なフローは、TerminateCustomerイベントを消費するMediatorから始まります。 Mediatorは、イベントのペイロードからCustomer IDを取得し、そのCustomer IDを渡してSpringコンポーネントTerminateCustomerToAbortOrderEventTranslatorを呼び出します。このコンポーネントは、Oracle SOA Suite Java APIを使い、Composite Sensorで設定されたCustomer IDを持つすべてのコンポジットインスタンスを見つけようとします。すべてのこれらのインスタンスのOrder IDは対応するセンサから取得され、各インスタンスについて、Order IDを渡してメディエータPublishAbortOrderEventを呼びだします。このMediatorはAbortOrderForCustomerイベントを発行します。

このイベントは、Order IDに基づいて、イベントと相関を持つBPELプロセスProcessOrderのインスタンスが消費します。その後、インスタンスが終了します。

図36はCompositeでイベント転送を可視化しています。ただし、イベントを発行するメディエータとイベントを消費するBPELプロセスの間には直接のリンクが存在しないことにご注意下さい。:この相互作用は完全にコンシューマからパブリッシャを分離するイベント配信ネットワークを介して実施されています。
図36

And... action!

SOAコンポジットアプリケーションは完全に自己完結しています。アプリケーションをOracle SOA Suiteランタイム環境に通常の方法でデプロイできます。
図37
JDeveloperアプリケーションをご覧頂くことができますし、図37のように、ご自身のOracle SOA Suite環境にデプロイすることもできます。

Run ProcessOrder instances

デプロイが終了したら、ProcessOrderプロセスのインスタンスを起動します。FanoutEventコンポジットをOracle Enterprise Manager Fusion Middleware Controlで選択し、[テスト]ボタンを押します(図38)。
図38
ProcessOrder_epサービスのリクエストメッセージの要素に対応するフィールドを持つWebサービスのテストページが現れます。Only the customerIdentifierとorderIdentifierのみが今回の目的に関係がありますので、それぞれABCと123Aを指定し、[Webサービスのテスト]ボタンを押してリクエストを発行します(図39)。
図39
以下のリストに従い、CustomerIDがABC、XYZ、PQRのProcessOrderインスタンスを複数起動します。

図40
この時点で、Oracle Enterprise Manager Fusion Middleware Controlをチェックしてインスタンスのリストを確認します。3個のインスタンスのComposite SensorがCustomer IDとOrder IDを出力しています(図41)
図41

Publish the TerminateCustomer event

シナリオ:顧客XYZは、もはや信頼できるビジネスパートナーではなく、すべての関係をすぐに切断するべきです。 TerminateCustomerイベントをこの顧客のために発行するべきです。このイベント発行の間接的な結果として、現在、顧客XYZのために実行しているProcessOrderのすべての5インスタンスを終了させたいと考えています。

テスト目的で、Enterprise Manager FMW ControlからEDNイベントを発行できます。soa-infraノードのコンテキストメニューから、[ビジネスイベント]を選択します。
図42
ビジネス·イベントのページの[テスト]ボタンを押すと、ポップアップウィンドウが開き、どのイベントを発行するか尋ねてきますので、図43のように、このイベントのXMLペイロードをテキストフィールドに入力し、[発行]ボタンを押します。
図43
TerminateCustomerイベントはcustomerIdentifierにXYZを持つイベントとして、Event Delivery Networkに発行されています。

このイベントを発行することによって生じる効果を見る前に、CustomerIdentifier Composite Sensorからの値をXYZでフィルタリングした実行中のインスタンスの概要を見てみましょう(図44)。これにより、何が起こるか予想がつくと思います。記載されているこの5個のインスタンスは、終了しているはずです。
図44

Inspecting the event consequences

EDNにはTerminateCustomerイベントの一つのサブスクライバがあります。それがFanoutEventコンポジットのメディエータConsumeTerminateCustomerです。このMediatorは、顧客XYZのイベントを消費し、SpringコンポーネントのTerminateCustomerToAbortOrderEventTransformerを起動します。このコンポーネントは、顧客XYZに対応する、実行中のすべてのProcessOrderインスタンスを見つけ(図44から少なくとも5個あることがわかります)、特定のOrder IDのために、EDNに対しAbortOrderForCustomerEventを発行するPublishAbortOrderEventメディエータを呼び出します。

メッセージフロートレースの検査時に、いったい何が起こったのかが明確になります。5個の呼び出しはメディエータPublishAbortOrderEventに対してなされました。この結果、5つ実行中の注文に対応するAbortOrderForCustomerイベントになりました。メッセージフロートレースから、これらのイベントのいずれかが、ProcessOrderインスタンスをどのように終了させているかがわかります(図45)。
図45
終了したProcessOrderインスタンスのいずれかをドリルダウンし、BPELの監査証跡を調べると、何が起こったか明確な図を確認できます(図46)。
図46
顧客XYZ(終了したもの)と注文345X(BPELインスタンスが処理した注文)のAbortOrderForCustomerイベントを、orderIdentifierを基にした相関を通じて、このインスタンスが消費しました。このイベントを捕捉するonMessageハンドラは、AbortThisOrderアクティビティを実行し、意図したとおりにBPELインスタンスを中止しました。

当然ながら、他の顧客のためのすべてのProcessOrderインスタンスは、この時点では実行されています。顧客XYZを扱うものだけが終了しました。

Conclusion

ビジネスイベントを使用すると、組織は、新しいいレベルの疎結合を導入することができます。潜在的に興味深いものと認識されている状況にある任意のパーティー(システム、サービス、アプリケーション、プロセス)は、汎用的なイベントハンドラーに対してイベントを発行することで世間に伝える必要があります。これらの認識されているビジネスイベントの一つ以上に関心を持つ当事者は、イベント発生時に、通知するイベントハンドラを購読することができます。イベントのコンシューマやパブリッシャがお互いについて何も知らないにもかかわらず、曲がりなりにもまだ協力しています。

Oracle SOA SuiteのEvent Delivery Networkはイベントハンドラの一例です。その他もご利用いただけますし、JMSやAQを含めて、比較的単純な手段を使って作成することができます。

ビジネスイベントは、例えば、BPMやBPELといった実行中のプロセスに影響を与える必要がある場合、こうしたイベントを特定のコンポジットインスタンスと相関を持たせる必要があります。しかし、ビジネスイベントが意図された効果とは異なるレベルにあるとき、例えば顧客のすべての注文を停止するような場合、私たちは課題に直面します。通常は、実行中の一つのプロセスインスタンスと相関を構成します。

この記事では、イベントをより高いレベルで捕捉し、期待するレベルの実行中のインスタンスにイベントを発行できることをご説明しました。Composite Sensor、Springコンポーネント、相関を持つインスタンスを発見するためのOracle SOA SuiteのJava API、そして、2番目のタイプの適切なレベルに調整したイベントを使って実施しています。

Resources

0 件のコメント:

コメントを投稿