ESB Muleの多くの機能はエンタープライズ統合パターン(EIP)に記述されています。この本は、ESB Muleが解決しようとしている問題を取り上げて、ESB Muleフレームワークで利用されている多くのパターンの説明があります。ESB Muleの資料ではEIPへの参照は以下のように記述されています:
| EIP - (パターン名) (本のパターン番号) (EIPサイトのパターンへのURL) |
| (パターン図) (説明) |
| Webサイト又は本からの説明 |
はじめに
このドキュメントはESB Muleのアーキテクチャに付いて説明します。ESB Muleの最終的な目標は、プログラマーがデータ送受信の詳細や通信プロトコールに依存なく、複数のデータ資源を統一した方法で利用できるようにすることです。その結果は、高スケラブル、軽量、高性能、簡単に利用できるESB(企業サービス・バス)サーバであります。ESB MuleはESBモデルを意識して設計され、分散サービスネットワークを簡単かつ短時間で開発できるようにすることを一つの目的としています。ただし、名前からも分かるように、ESBモデルは異なる多くのエンタープライズ・アプリケーションを含む大規模な統合プロジェクトと関連付けられることが多くあります。ESB Muleはエンタープライズ・レベル・サービス・アーキテクチャを資源、開発費、商品の市場投入までに要する期間を最低限にする必要がある小規模プロジェクトで使うことを可能にします。
アーキテクチャの概要
ESB Muleの主要目的は標準、オープン・プロトコール、明示的なパターンを利用してアプリケーション統合を行えるようにすることです。この目的を達成するために、ESB Muleはアプリケーション及びサービスを連携するための基本コンポーネントを提供します。
上の図は、簡単なエンド・ツ・エンド構成の場合にESB Muleコンポーネントの関係を示します。
アプリケーション
アプリケーションは特に特性されていません。Webアプリケーション、バックオフィス・アプリケーション、アプリケーション・サーバ又は他ESB Muleインスタンスも可能です。
チャネル(channel)
2点間でデータ通信を行う任意の方法です。
ESB MuleでチャネルはUMOコンポーネントを繋げるのと、異なるESB Muleノードをローカル及びインターネットを介して繋げるのに使われます。
| EIP - Message Channel (60) http://www.eaipatterns.com/MessageChannel.html |
ESB Muleはチャネルを実装したり、チャネルを特定したりしません。ただし、ESB Muleはトランスポート・プロバイダと言う多くのチャネルの選択を提供します。 |
| "When an application has information to communicate, it doesn't just fling the information into the messaging system, it adds the information to a particular Message Channel. An application receiving information doesn't just pick it up at random from the messaging system; it retrieves the information from a particular Message Channel." |
メッセージ・レシーバー(message receiver)
メッセージ・レシーバーはアプリケーション・データの読書きを行います。ESB Muleでは、レシーバーは トランスポート・プロバイダの一要素です。ESB MuleはJMS, SOAP, HTTP, TCP, XMPP,SMTP,ファイル等と豊富なトランスポートを提供します。
ESB Muleの特徴は、ビジネス・ロジック(UMOコンポーネント)がシステムの場所、データ形式、転送方法、プロトコルを知らなくても多くの異なるシステムと通信することができることです。同じく、UMOコンポーネントが処理を行った後に、どのようなデータ形式でデータが何処に転送されるのかを知らなくてもよいのです。
| EIP - Message Endpoint (95) http://www.eaipatterns.com/TransactionalClient.html |
ESB Muleは透過的にエンドポイントからエンドポイントにデータを運びます。 |
| "Message Endpoint code is custom to both the application and the messaging system's client API. The rest of the application knows little about message formats, messaging channels, or any of the other details of communicating with other applications via messaging. It just knows that it has a request or piece of data to send to another application, or is expecting those from another application. It is the messaging endpoint code that takes that command or data, makes it into a message, and sends it on a particular messaging channel. It is the endpoint that receives a message, extracts the contents, and gives them to the application in a meaningful way." |
受信ルータ(inbound router)
受信ルータはチャネルに購買しれいるコンポーネントがどのイベントをどのように受信するかを制御します。受信ルータはイベントがUMOコンポーネントが受信する前にフィルタ, 分割, 組直しすることができます。
メッセージ・ルータに付いては、このページのここを参照してください。
コネクター
コネクタは、特定チャネルに対してデータの送受信を行います。
メッセージ・レシーバーはコネクタと関連付けられて、コネクタが扱えるリソースからのデータを受信するように登録します。
コネクタに付いては、このページのここを参照してください。
トランスフォーマ
トランスフォーマはメッセージやイベント・ペイロードのデータ変換を行います。ESB Muleは標準メッセージ形式を定義していません(ただし、ESB Muleは将来に標準ビジネス・プロセス定義メッセージ・タイプをサポートするかもしれません)。
ESB Muleが標準で提供している変換は、データ型の変換(例:JMSメッセージをObjectに変換する)とXMLトランスフォーマです。データ変換はアプリケーションに依存するところが多いのですが、ESB Muleは簡単かつ強力な変換フレームワークを提供します。
トランスフォーマに付いては、このページのここを参照してください。
エンドポイント
エンドポイントはコネクタ,エンドポイントURI,トランスフォーマ,フィルタ,トランザクション情報を繋いでチャネル・アダプタを提供する構成ラッパーです。プロバイダはプロバイダ・インスタンスのためにトランザクション情報を保存します。エンドポイントの詳細に付いてはESB Muleエンドポイントを参照してください。
| EIP - Channel Adapter (127) http://www.eaipatterns.com/ChannelAdapter.html |
プロバイダはチャネル・アダプタと同等です。 |
| "The adapter acts as a messaging client to the messaging system and invokes application functions via an application-supplied interface. Likewise, the Channel Adapter can listen to Application-internal events and invoke the messaging system in response to these events." |
送信ルータ(outbound router)
送信ルータはイベントの属性又は設定で定義されているルールによって、別のプロバイダにメッセージ/イベントを送信します。
送信ルータに付いては、このページのここを参照してください。
ESB Muleマネージャー
ESB Muleの中刻はMuleManagerです。MuleManagerはモデルの全ての基本サービスの設定とそのコンポーネントを管理します。下はMuleManagerを構成する基本コンポーネントの概要です。
以下の節はESB Muleのこれらの要素に付いてもうすこし詳しく説明します。
モデル
モデルはESB Muleサーバ・インスタンスの実行中の振舞いを管理し、カプセル化します。UMOのインスタンスとその設定を管理します。モデルは、ESB MuleがどのようにUMOコンポーネントと対話するかを決定するために3つの制御の仕掛けをもちます。
エントリ・ポイント・リゾーバー
エントリ・ポイント・リゾーバーはorg.mule.umo.model.UMOEntryPointResolverで定義されています。エントリ・ポイント・リゾーバーは、UMOコンポーネントがイベントを受信した場合に呼び出すメソッドを特定します。モデルにエントリ・ポイント・リゾーバーが設定されていない場合はDynamicEntryPointResolver が使われます(詳細に付いては設定・ガイドを参照してください。)。
DynamicEntryPointResolverは一般的なエントリ・ポイントの解決を提供します。以下の手順で処理を行います:
- コンポーネントがCallableライフサイクル・インターフェースを実装しているか確認します。実装している場合はonCall(UMOEventContext)メソッドを使ってイベントを受信します。
- コンポーネントにトランスフォーマが設定されているか確認します。トランスフォーマの戻り値の型をコンポーネントのメソッドの型を比較され、トランスフォーマの戻り値の型に対応したメソッドがあるか検索します。ある場合はこのイベントは使われます。一つより多くのメソッドと一致した場合は、例外が投げられます。
- コンポーネントにorg.mule.umo.UMOEventContextを受けるメソッドがあるか確認します。ある場合は、このイベントは使われます。一つより多くのメソッドと一致した場合は、例外が投げられます。
- 最後に、コンポーネントにjava.util.Eventを受けるメソッドがあるか確認します。ある場合は、このイベントは使われます。一つより多くのメソッドと一致した場合は、例外が投げられます。
- 上のどの条件にも一致しない場合は例外が投げられて、コンポーネントの登録は失敗します。
もちろん、DynamicEntryPointResolverが適切な場合も多くあります。例えば、1つのフレームワークから別のフレームワークへ移行する場合に、エントリ・ポイントがどのように解析されるかを制限(例えば、org.mule.umo.lifecycle.Callableを継承したコンポーネントのみをorg.mule.model.CallableEntryPointResolverする)又は変更したくなりかもしれません。カスタムなエントリー・ポイント・リゾーバーを作成するには、 org.mule.model.EntryPointResolver を実装します。
ライフサイクル・アダプタ
org.mule.umo.lifecycle.UMOLifecycleAdapterインターフェースで定義され、ライフサイクル・アダプタはESB Muleコンポーネント・ライフサイトを下層コンポーネントに対応付けます。DefaultLifecycleAdapterはライフサイクル・イベントを0以上のUMOライフサイクル・インターフェースを実装したコンポーネントに委任します。
明らかにこれはESB Muleに管理させたい既存コンポーネントには適切ではありません。なぜなら、既存コンポーネントはESB Muleフレームワークと関係をしなければならない独自のライフサイクル・メソッドがあるからです。運良くorg.mule.umo.lifecycle.LifecycleAdapterは簡単に実装することができます。
ライフサイクル・アダプタは org.mule.umo.lifecycle.UMOLifecycleAdapterFactory の実装を使って設定されます。ファクトリはモデルの設定で宣言されます。デフォルトは提供さらえているDefaultLifecycleAdapterFactoryです。
コンポーネント・ファクトリ
モデルのコンポーネント・プール・ファクトリ・プロパティは、指定されたUMOコンポーネントのコンポーネント・プールを作成するファクトリを定義します。プールはUMOComponentをプールします。この拡張ポイントは、開発者が必要に応じて自前のプールの仕組みを開発ことを可能にします。
ESB Muleは2つのプールの実装を同梱しています:
- commons-pool - Jakarta commons-poolを使ってUMOComponentプールの管理を行います。
- pico-pool - picoContainerを使ってオブジェクト・プーリングをするPico追加コンポーネントです。
自前のプールの開発する場合は、 org.mule.umo.model.UMOPoolFactory, org.mule.until.ObjectPool と org.mule.util.ObjectFactory を実装します。
トランスポート・プロバイダ
トランスポート・プロバイダとは、ESB Muleコンポーネントが特定のプロトコル, リポジトリ・メッセ-ジング又はその他の技術を使って情報の送受信をできるようにするESB Muleプラグインです。
下の図はトランスポート・プロバイダのアーキテクチャです:
コネクター
コネクタは、外部システムと接続するための実装を提供します。コネクタは外部レシーバへデータを送信する事と、外部システムからデータを受信するコネクタのリスナーを管理します。例えば、HTTPコネクタはHttpConnectorを生成し、ペイロードをコネクタを介して送信し、戻り値のUMOEventを取得します(同期で実行されば場合)。HTTPコネクタのレシーバーは、HTTPサーバから何かを受信した場合に通知するオブジェクトです。
コネクタにはイベントの送受信のために2つのオブジェクトがあります:
- MessageReceiver -
下層技術へのエンドポイントをレッスンする。多くのレシーバにはただスレッドを受信メッセージの有無を監視し、設定の多くはコネクタで行われます。
- MessageDispatcher - 下層技術へイベントを送信します。メッセージ・ディスパッチャーはプール可能なスレッドであり、イベントを送信したり、下層技術から利用できるイベントを「receive」(受取り)します。UMOMessageDespatcherインターフェースは次の3つの重要なメソッドを定義します:
- dispatch() - 外部システムに非同期でデータを送信する
- send() - 外部システムに同期でデータを送信し、外部システムからの回答をUMOEventで返す
- recieve() - 利用している下層技術へイベントを送り、結果を返す。このメソッドにはタイムアウト・パラメータを設定することができます。
コネクタは下層技術のために、セッション管理を行います。例えば、JmsConnectorはコネクタのメッセージ・レシーバーとJMSを介してイベントを送信するためのメッセージ・ディスパッチャーにJMSセッションを提供します。
エンドポイント・アドレス
エンドポイント・アドレスは宛先又はデータの資源を定義し、URI形式で記述されます。以下はエンドポイントの例です:
エンドポイント・アドレスはコネクタのプロトコルと資源を特定する情報を含む正式なURIです。
ESB Muleトランスポート・プロバイダは、開発者がESB Muleでエンドポイントの読み方を修正できるプラグ・インできるエンドポイント・ビルダを提供しています。
エンドポイント解決
この節は、ESB MuleがどのようにしてエンドポイントURIを解決するかを説明します。この例では次のURIを使います:「jms://topic:myTopic?durable=true」。 このJMS URIは持続トピックスです。
- ConnectorFactoryはURIから呼び出されます。
- サービス・ディスクリプタ(service descriptor)が「jms」の項目をMETA-INF/services/org/mule/providersで検索します。
- それからConnectorServiceDescriptorオブジェクトが生成されます。
- エンドポイントURIに、URI用に新しいコネクタ(Connector)を生成するか、既存の接続(connection)を利用を使うかの指定ができます。指定が無い場合は、既存のプロトコルによる接続が探します。
- ConnectorServiceDescriptorは使うエンドポイント・ビルダ(Endpoint builder)を持ち、エンドポイントはエンドポイント・ビルダに渡されます。
- エンドポイント・ビルダは、URI仕様に基づいてURIをコンポーネントに分解します。
メッセージ・レシーバー(Message receiver)
メッセージ・レシーバー又はメッセージ・リスナーは、外部システムからデータを受信します。コネクタはレシーバーを登録・解除します。メッセージ・レシバーの複雑さは使う外部システムに依存します。例えば、JMSプロバイダ用のメッセージ・レシーバーはただjavax.jms.MessageListenerを実装しています。JMSコネクタはレスナーをJMS接続(connection)に登録します。しかし、HTTPメッセージ・レシーバーは受信リクエストを特定のポートを監視するHTTPサーバを実装します。
メッセージ・アダプタ(Message Adapter)
メッセージ・アダプタは外部アプリケーションから送られた異なる形式のオブジェクトを共通の方法で読み取ります。UMOMessageAdapterは、どのJavaオブジェクトからのペイロードとプロパティを読むための少数のメソッドを定義したインターフェースです。メッセージ・アダプタはコネクタに特有しています。コネクタにメッセージが書き込まれる場合は、メッセージ・アダプタは特定のデータ形式のデータを読み込み、バイト配列又は文字列(String)に変換します。
トランザクション
トランザクションはプロバイダで管理されます。トランザクションはメッセージ・レシーバーがメッセージを受信した時及びメッセージ・ディスパッチャがメッセージを送信した時にに開始又はコミットされます。ESB Muleトランザクション管理の中核はTransactionCoordinatorです。TransactionCoordinatorはトランザクションの状態を管理します。トランザクションの詳細に付いてはユーザ・ガイドのトランザクション管理を参照してください。
全てのトランザクションを同じように処理するために、トランザクションに対応したプロバイダは少数のAPIを定義する必要があります:
- org.mule.umo.UMOTransaction - 下層のトランザクションのラッパー。システムによっては、明示的にトランザクション・オブジェクトを定義しません。代わりに、トランザクションの区分はコネクション又はセッションのメソッドを呼びます。UMOTransaction APIはトランザクションのリソースから情報を取得するメソッドを定義しています。
- org.mule.umo.UMOTransactionFactory - UMOTransactionの実装を生成するファクトリ。
コンテナ・コンテキスト(Container Context)
コンポーネント・リゾーバーはUMOコンポーネント及び関連するオブジェクトの初期化・設定を管理する外部コンテナ・フレームワークを使うためのゲートウエアです。第三者から実績のある良いIoCコンテナが提供されているために、ESB Muleは独自のコンポーネント・コンテナを提供していません。その代わりにESB Muleは以下のような多く利用されているコンテナ用のコンポーネント・リゾーバー(Component Resolver)を提供しています。
外部コンテナからのコンポーネントをUMOコンポーネントとして使う場合は、使いたいComponentResolverをモデルに設定し、設定ファイルのmule-descriptorのimplementation属性をコンテナのコンポーネント・キー(Picocontainerの場合はクラス)に設定します。
設定でコンポーネント・リゾーバー(Component Resolver)が指定されて無い場合は、MuleComponentResolverが使われます。この実装は、コンポーネントを解析するために、コンポーネント・キーの代わりにクラス名を要求します。コンテナのコンポーネントを検索する機能が未サポートの他は、実際の実装と同じように動作します
自前のComponentResolverを実装するには、次の2つのインターフェースを実装します:
- org.mule.umo.model.UMOComponentResolver - コンテナのコンポーネントを解析します。
- org.mule.umo.model.UMOContainerContext - コンテナを生成・初期化します。コンポーネント・リゾーバーはこのコンテキストを使って外部フレームワークを問い合わせます。
UMOコンポーネント
ESB Muleアーキテクチャの中心は、独立して資源, トランスポート,データ転送の仕組みに非依存なコンポーネントです。これらのコンポーネントはUMOコンポーネントと呼ばれ、多数な方法で相互と関係会うように動きます。UMOコンポーネントは、複数の異なる資源からデータを受け取ったり、送り返したりするように設定することができます。
上の図の「UMO Impl」はObjectです。ObjectはJavaBean, 違うフレームワークのコンポーネント, その他の何にでも設定することができます。イベントを受信した時に実際に実行する処理です。ESB Muleはオブジェクトに次の2点以外の制限を掛けません:①ESB Muleが直接オブジェクトを構成できること、②デフォルト・コンストラクタを持ちます(SpringやPicoのようなコンテナで構成されている場合は、ESB Muleは管理方法を問いません)。
勿論、これだけの柔軟性を持たせるためんは、ESB Muleはオブジェクトから情報を取得できる仕組みが必要です。オブジェクトがどのようにイベントを使うか管理する仕事は上の図外の2レイヤが行います。
コンポーネント・ライフサイクル(Lifecycle adapter)
ライフサイクル・アダプタは、オブジェクト(ある場合)のライフサイクル・メソッドを起動するのにモデル(Model)が使います。モデル毎に自前のライフサイクルを設定することができます。即ち、各モデルが管理しているコンポーネントのライフサイクルを変えることができます。
ESB Muleは管理するコンポーネント用に、デフォルトのライフサイクルを定義しています。コンポーネントは、それぞれに必要なライフサイクル・インターフェースを実装することで、0以上のライフサイクル・イベントに参加することができます。ライフサイクルは以下の通りです:
ESB Muleが管理するコンポーネントはESB Muleが定義するライフサイクルに従事する必要はありません。DefaultLifecycleAdapterを使って、コンポーネントは任意のライフサイクル・インターフェースを実装することができます:
- org.mule.umo.lifecycle.Initialisable - コンポーネントにinitialise()メソッドを追加します。
- org.mule.umo.lifecycle.Startable - コンポーネントにstart()メソッドを追加します。コンポーネントはイベントを受信できる状態になるためにどのコードでも実行できるとします。
- org.mule.umo.lifecycle.Callable - コンポーネントにonCall(UMOEventContext eventContext)メソッドを追加します。コンポーネントのイベントを受信した場合にこのメソッドは呼ばれます。
- org.mule.umo.lifecycle.Stoppable - コンポーネントが停止状態になるためのstop()メソッドをコンポーネントに追加します。コンポーネントが再生できる状態にします。
- org.mule.umo.lifecycle.Disposable - コンポーネントが解放される前に処理するdispose()メソッドをコンポーネントに追加します。
このライフサイクル・インターフェースはConnectors, AgentsとInterceptorsにも適用されます。例えば、LifecycleInterceptorはライフサイクルを管理するために、Startable, StoppableとDisposableインターフェースを実装します。
トランスフォーマー(transformer)
トランスフォーマは、元データの形式をUMOコンポーネントが処理できるオブジェクト形式に変換します。トランスフォーマは、UMOコンポーネントが期待するオブジェクト形式のデータを受取ることができるようにするために、データを受信するエンドポイントに設定することができます。送信エンドポイントに設定されたトランスフォーマは、ポイントがメッセージを送信する前に正しい形式のオブジェクトを受けるようにします。複数のトランスフォーマを連鎖させて、再利用ができる細かい変換を行うようにすることが可能です。エンドポイントに1つよりも多くのトランスフォーマを設定する場合は、設定ファイル([設定ガイド]を参照してください)にトランスファーマをコンマ「,」で区切って指定するか、プログラムからsetTransformer()メソッドを使って連鎖することができます。。
以下は受信(inbound)トランスフォーマの例です:
以下は送信(outbound)トランスフォーマの例です:
全てのESB Muleトランスフォーマは
org.mule.transformer.UMOTransformer を実装します。このトランスフォーマが対応してオブジェクト・タイプを制御するメソッドを定義し、返却値の型を検証する抽象トランスフォーマが用意されています。開発者はただ1つのメソッド
doTransform() を実装するだけです。
エントリーポイント・リゾーバー(Entry Point Resolver)
EntryPointResolver(図には含まれていません)は、UMOComponentがモデルに登録される時に、イベントを受信した場合に呼び出すメソッドを探すのにつかわれます。メソッドが見つからなかった場合は例外が投げられます。エントリーポイント・リゾーバーに関する詳細はここを参照してください。
イベント(event)
ESB Muleのアーキテクチャはイベントに基づいています。即ち、ESB Muleネットワーク上の動作はESB Mule及び外部システムからのイベントが起動します。イベントには必ずデータ(ペイロード)があります。ペイロードはイベントの処理と関連する1つ以上のコンポーネントとプロパティで使われます。このプロパティは不特定であり、イベントが生成された時点から何時にでも設定されます。イベントのデータは、元の形式及び変換後の形式で参照することができます。イベントを受信したエンドポイントは、イベントのペイロードを設定されたトランスフォーマを適用してイベントを受け取るコンポーネントが受け取れる形式に変換します。イベント・ライフサイクルの詳細に付いては下のメッセージ・フローの節を参照してください。
イベント処理
ESB Muleは、イベントの送受信を3つの処理モデルで行うことができます:
- 非同期- 複数のイベントを1つのコンポーネントで同時に複数のスレッドで処理することができます。ESB Muleサーバが非同期で実行している場合は、コンポーネントのインスタンスは別々のスレッドで実行され、各インスタンスがイベントを受信します。ただし、イベントは一つのコンポーネントのインスタンスで受信されて処理されます。
- 同期 - UMOコンポーネントが同期モードでイベントを受信すると、リクエストの全てが1つのスレッドで処理されます。
- リクエスト-レスポンス - UMOコンポーネントが特定したイベントのリクエストを要求し、指定した時間まで返事を待ちます。
イベント処理の同期はエンドポイントの synchronous プロパティで(又はプログラムからイベントに)設定することができます。利用されるトランスポートが返信チャネルをサポートしている場合は、同期の設定はネットワークに伝播することができます。例えば、同期JMSリクエストはリクエストを受けると、一時的な返信キューを作成して、レスポンスがそのキューをされるのを待ちます。ソケットを使ってトランスポートも同じような動作をします。実際のイベント・フローは同期(synchronous)プロパティ, インドポイントが受信(inbound)か送信(outbound)であるか, トランザクションが既に実行されているかによって変わります。以下のルールが適用されます:
非同期イベント処理
受信(inbound)エンドポイントの同期(synchronous)フラグがfalseに設定されている場合は非同期でイベントが処理されます。
イベントの感知と発生

このシナリオでは、メッセージはキューに送られ、プールのワーカー・スレッドが受け取ります。ワーカー・スレッドはUMOComponentの実際の処理を実行します。送信(outbound)エンドポイントも非同期であり、結果メッセージはディスパッチャー・スレッドで送信されます。
非同期感知、同期発生

このシナリオでは、メッセージはキューに送られ、UMOComponentの実作業を行うプールのワーカ・スレッドがを受け取ります。送信(outbound)エンドポイントは同期に設定されているために、送信はコンポーネントが実行されている同じスレッドでされます。この処理は自動的にESB Muleで行われます。
同期処理
同期受信のみ

同じスレッドでUMOComponentがイベントを受信・処理して、UMOComponentが結果を戻す必要がある場合は、レスポンス・チャネルのあるレシーバに渡されます。 i.e Socket outputstream a result will be sent.
同期送受信

イベントの受信と処理は同じスレッドで処理されます。ディスパッチの送信も受信のスレッドで処理されます。ここで、送信(outbound)エンドポイントのトランスポートがソケットやJMSのように返信チャネルをサポートしている場合は、送信イベントはインターセプト(又はタイムアウトします)され、レスポンスはレスポンス・チャネルで戻されます。
同期送受信トランザクション

(現在では)トランザクションは同期エンドポイントのみに対応しています。エンドポイントがトランザクション用に設定された場合は、自動的に同期に設定されます。トランザクション中にイベントをディスパッチすると、そのディスパッチはトランザクションのスレッドで処理されます。
メッセージ・ルータ(message router)
メッセージ・ルータは、システム内のコンポーネントがどのようにイベントを送受信するかを制御します。ESB Muleは受信したイベントに適用される受信ルータ(inbound router)とイベントを送信する前に適用する送信ルータ(outbound router)を定義しています。
受信ルータ(inbound router)
受信ルータはコンポーネントで受信したイベントを制御及び操作します。一般的には、受信(inbound)ルータは受信イベントのフィルタと 受信イベントの集約及び並べ替えを行います。受信ルータを連鎖させることもできます。その場合は、イベントはESB Muleコンポーネントに送られる前に、各ルータで処理されます。受信(inbound)ルータは送信(outbound)ルータと異なり、プロバイダが特定されているために、プロバイダを介してどのようにメッセージが送信されるかを制御することができます。イベントが指定されているルータで受け取られない場合に処理を行うcatch-all処理を設定することもできます。
受信ルータ(inbound-router)はmule-config.xmlファイルのmule-descriptorタグ内で設定されます:
<inbound-router>
<catch-all-strategy
className="org.mule.tck.testmodels.mule.TestCatchAllStrategy"/>
<router className="org.mule.routing.inbound.SelectiveConsumer">
<filter expectedType="java.lang.String"
className="org.mule.routing.filters.PayloadTypeFilter"/>
</router>
<router className="org.mule.routing.inbound.Aggregator">
</router>
</inbound-router>
コンポーネントが受信したメッセージに特別な処理を行う必要が無い場合は、受信ルータを設定する必要はなりません。
送信ルータ(outbound router)
送信(outbound)ルータは、UMOコンポーネントが処理したイベントをどのプロバイダを使って送信するかを制御します。メッセージ・ルータはUMOComponentで構成され、イベントに対して複数のルーティング制約を定義することができます。どの定義されたルートでもイベントを処理できない場合に処理を受けるcatch-all処理を設定することもできます。
下は送信メッセージ・ルータ(outbound-router)定義の例です:
<outbound-router>
<catch-all-strategy className="org.mulerouting.ForwardingCatchAllStrategy"
provider="catchAll"/>
<router providers="TestApple-Out"
className="org.mule.routing.outbound.FilteringOutboundRouter">
<filter expectedType="java.lang.String"
className="org.mule.routing.filters.PayloadTypeFilter"/>
</router>
<router providers="waterMelonProvider"
className="org.mule.routing.outbound.FilteringOutboundRouter">
<filter className="org.mule.routing.filters.logic.AndFilter">
<left-filter pattern="the quick brown (.*)"
className="org.mule.routing.filters.RegExFilter"/>
<right-filter pattern="(.*) brown (.*)"
className="org.mule.routing.filters.RegExFilter"/>
</filter>
</router>
</outbound-router>
キャッチ・オール処理(catch-all strategy)
定義されているルータがイベントを処理できない場合に、イベントを引き受けるキャッチ・オール処理を定義することができます。キャッチ・オール処理は次のメソッドを定義する org.mule.umo.routing.UMORoutingCatchAllStrategy を実装します:
public void catchMessage(UMOMessage message, UMOSession session,
boolean synchronous) throws RoutingException;
このメソッドはvoidです。即ち、戻り値を返すことができません。同期で処理を行っている場合は処理の流れが中断されます。catch-all処理が実行された場合はエラーと見なします。
ルータ
例は2つのルータを定義しています。送信ルータ(outbound-router)要素が親に設定されています。このような場合は、イベントをルーティングできるか記述順に各ルータが確認されます。
ルータ設定にトランザクションい対応したプロバイダの利用は推奨されていません。イベントのルーティングが動的的に決められるために、非トランザクション・プロバイダにイベントがルータされる可能性もあり、トランザクションでタイムアウト・エラーになる場合もあります。トランザクションを利用する場合は、イベント用にトランザクションに対応した受信(inbound)ルータを1つと送信(outbound)ルータを1つ設定することを推奨します。
UMOコンポーネントに送信ルータが1つしか無い場合は、メッセージ・ルータの定義は不要です。
ESB Muleに同梱されているルータの詳細に付いては、 ユーザ・ガイドのメッセージ・ルータを参照してください。
インターセプタ(Interceptor)
ESB Muleインターセプタは共通した振る舞いを複数のUMOを設定する場合に便利な機能です。インターセプタ及びコマンド・パタンは、多くの場合は、AOP(アスペクト指向プログラム)と呼ばれます。インターセプタは、オブジェクト処理を介入し、処理及び結果に変更することができます。インターセプタはESB Muleコンポーネントにプロファイリング, 許可, セキュリティ・チェック等を付けるのに便利な機能です。
ESB Muleには2種類のインターセプタがあります:
- org.mule.interceptors.EnvelopeInterceptor - イベントが処理される前後に実行されるエンベロープ・フィルター。ログやプロファイリングを行うのに使われます。
- org.mule.umo.UMOInterceptor - 実行され、次の要素に処理を引き渡します。インターセプタは処理を中断して次の処理に進行しないようにすることもできます。例えば、許可やセキュリティ・チェックに使われます。
下の図は、一般的なインターセプタとイベント・フローを示します:
例外管理
例外処理はUMOComponentに定義されます。ただし、モデル内の全てのコンポーネントの例外処理を一括して定義することもできます。モデルに例外処理を定義すると、各例外処理の定義は不要になります(UMOコンポーネントに例外処理が定義されていないと、デフォルトで org.mule.impl.DefaultExceptionStrategy が使われます)。
多くの場合は、自前の例外処理を定義します。自前の例外を定義するには、 org.mule.umo.UMOExceptionStrategy を実装します。
ESB Muleオブジェクト階層
ESB Muleの要素は2種類のオブジェクトに分けられます:
- UMOManagerに設定され、ESB Muleインスタンスのどこからも参照できるグローバル・オブジェクト。
- モデル・オブジェクト。ESB Muleモデル内で構成されたシステムのその他の全ての要素です。
これらのオブジェクトの階層は下の木構成で示した通りです。オブジェクトはmule-config.xmlファイルでコンポーネント名とオブジェクトを表すクラスとして説明されています。