メッセージ・ルータはシステムのコンポーネントのイベントの送受信を制御します。ESB Muleでは受信するイベントを制御するために受信(Inbound)ルータを定義することができ、送信するイベントを制御するために送信(Outbound)ルータを定義することができます。
クイック・リファレンス
ESB Muleはコンポーネント用に柔軟なメッセージ・ルーティングを提供しています。ルーティング機能はエンタープライズ統合パターンで必要とされてエンタープライズ・ルーティングに基づいています。以下はESB Muleのルーティングの要素です:
受信ルータ
一つのイベントはエンドポイントで受信されて、ルータはそのイベントはシステムに何時及びどのように引き渡されるかを制御します。
送信ルータ
コンポーネントでメッセージが処理された後に、どのコンポーネントが結果イベントを受け取るかを送信(Outbound)ルータで制御することができます。
レスポンス・ルータ
リクエストでイベントがトリガーされて、レスポンスを送信する前にイベントを集約する必要がある場合に使われます。古典的な例はリクエストを受信して、処理が平行して実行される場合です。全ての処理が終了して、その結果が集約されるまでレスポンスを送信することはできません。
フィルタ
フィルタは特定したルータを呼び出すためのロジックを提供します。例としてXPathFilterやPayloadTypeFilterが挙げられます。フィルタはロジック・フィルタ,AndFilter, OrFilter NotFilterを使って組み合わせることができます。全てのルータにフィルタを提要する必要はありませんが、全てのルータはフィルタに対応しています。詳細に付いては、フィルタを参照してください。
CatchAll処理(CatchAll Strategy)
CatchAll処理をルータに設定すると、イベントに対応したルーティング・パスが見つからない場合に呼ばれます。エンドポイントをCatchAll処理を関連付けると、該当しないイベントを一つのところへ転送して集中させることができます。
ルータの設定
受信ルータ(inbound-router)の設定
受信ルータは、コンポーネントが受信したイベントを制御するのに使えます。受信ルータは受信したイベントをフィルタしたり、集約・並べ替えたりすることができます。受信ルータは複数の受信エンドポイントをコンポーネントに登録する場合にも使われます。
受信ルータを連鎖することもでき、イベントは各ルータで処理されてからESB Muleコンポーネントに送られます。
受信ルータはエンドポイントが既に指定されている所が送信ルータと異なり(既にメッセージがエンドポイントで受信されているため)、役目としてはどのようにしてメッセージをコンポーネントに渡すかを制御することです。イベントを受け取るルータが設定されていない場合は、適用するためにcatch-all処理を設定することもできます。
受信ルータ(inbound router)は、mule-config.xml設定ファイル内のmule-descriptor要素に設定することができます:
<inbound-router>
<catch-all-strategy className="org.mule.routing.ForwardingCatchAllStrategy">
<endpoint address="jms://failure.queue"/>
</catch-all-strategy>
<router className="org.mule.routing.inbound.SelectiveConsumer">
<filter expression="(msg/header/resultcode)='success'"
className="org.mule.routing.filters.xml.JXPathFilter"/>
</router>
</inbound-router>
このinbound-routerにルータが設定されています。最初のルータは選択式であり、ペイロードにネストされた変数「resultcode」の値が「success」に設定されているイベントのみコンポーネントに渡されます。条件に一致するルータがない場合はcatch-allに設定されたエンドポイントに送られます。この例ではJMSキュー「failure.queue」へ送られます。
送信ルータ(outbound-router)の設定
送信(outbound-router)は、UMOコンポーネントが処理した後にどのエンドポイントでイベントを送信するかを制御します。メッセージ・ルータはコンポーネントに設定され、イベントに対して複数のルーティング制約を定義できます。イベントに対応したルートが無い場合にイベントを受けるcatch-allを設定することもできます。
以下は送信メッセージ・ルータ(outbound message router)の設定例です:
<outbound-router>
<catch-all-strategy className="org.mule.routing.ForwardingCatchAllStrategy">
<endpoint address="jms://default.queue"/>
</catch-all-strategy>
<router className="org.mule.routing.outbound.FilteringOutboundRouter">
<endpoint address="smtp://exceptions@muleumo.org" transformers="ExceptionToEmail">
<properties>
<property name="subject" value="Exception!"/>
<property name="fromAddress" value="mule@mycompany.com!"/>
</properties>
</endpoint>
<filter expectedType="java.lang.Exception"
className="org.mule.routing.filters.PayloadTypeFilter"/>
</router>
<router className="org.mule.routing.outbound.FilteringOutboundRouter">
<endpoint address="vm://my.component"/>
<filter className="org.mule.routing.filters.logic.AndFilter">
<left-filter expectedType="java.lang.String"
className="org.mule.routing.filters.PayloadTypeFilter"/>
<right-filter pattern="the quick brown (.*)"
className="org.mule.routing.filters.RegExFilter"/>
</filter>
</router>
</outbound-router>
この送信(outbound)ルータは2つのルータを定義します。最初のルータはペイロードのデータ型がjava.lang.exceptionか確認し、その場合はエンドポイントでメッセージを終了します。ここではSMTPでメールをexceptions@muleumo.orgへ送ります。エンドポイントにトランスフォーマ ExceptionToEmail が設定されています。このトランスフォーマはイベントを送信する前に例外を javax.mail.Message に変換します。
エンドポイントのプロパティに注目してください。これプロパティは、エンドポイント・インスタンスのSMTPコネクタ設定をオーバーライドします。イベント・ペイロードが例外(Exception)で無い場合は、2番目のルータが利用され、ペイロード型が文字列(String)か確認された後にペイロードが式表現(regular expression)が適用されて一致するか確認されます。両方のフィルタがイベントと一致した場合は、イベントはvm://my.componentをリスニングしているコンポーネントに転送されます。一致するルータが無い場合、イベントはCatch-all処理でJMSキュー「default queue」へ送られます。
全てのルータと一致する
最初に一致したルータだけではなく、一致する全てのルータを使うように送信ルータ(outbound-router)を設定することもできます。例えば入金した場合は必ず確認のメールを送るようにし、$100,000以上の場合は顧客管理マネージャに通知を送りたい場合は、下の例のようにルータにmatchAllプロパティを設定します:
<outbound-router matchAll="true">
<router className="org.mule.routing.outbound.FilteringOutboundRouter">
<endpoint address="jms://deposit.queue"/>
</router>
<router className="org.mule.routing.outbound.FilteringOutboundRouter">
<endpoint address="endpoints="jms://large.deposit.queue"/>
<filter expression="deposit/amount >= 100000"
className="org.mule.routing.filters.xml.JXPathFilter"/>
</router>
</router>
</outbound-router>
ここでは、最初のルータはフィルタが設定されていないので必ず一致します。2番目のルータは金額が$100,000以上(amount is >= $100000)の場合のみ一致します。金額が$100,000以上の場合は両ルータに一致し、使われます。
レスポンス・ルータの設定
レスポンス・ルータはリクエスト・レスポンスで、分岐したタスクを再び合わせます。レスポンス・ルータは同期呼び出しをするコンポーネントのみで使います(非同期の場合は、レスポンスが無いため)。ESB Muleはレスポンスを返す前にイベントを集合するResponseAggregatorルータを提供しています。ResponseAggregatorルータは、メッセージ分割および受け取りリストと使うことができます。
<response-router>
<endpoint address="jms://bank.quotes"/>
<router className="org.mule.samples.loanbroker.routers.BankQuotesResponseAggregator"/>
</response-router>
エンドポイントは処理するために、レスポンスを返すアドレスです。ここではルータは複数の銀行からの見積もり価格を1つに集合します。以下のLoanBrokerコンポーネントの設定を参照にしてください:
<mule-descriptor name="LoanBroker"
implementation="org.mule.samples.loanbroker.SyncLoanBroker">
<inbound-router>
<endpoint address="vm://Loan.Requests"/>
</inbound-router>
<response-router>
<endpoint address="jms://Loan.Quotes"/>
<router className="org.mule.samples.loanbroker.routers.BankQuotesResponseAggregator"/>
</response-router>
<outbound-router>
<router className="org.mule.routing.outbound.StaticRecipientList">
<reply-to address="jms://Loan.Quotes"/>
<filter expression="recipients!=null"
className="org.mule.routing.filters.MessagePropertyFilter"/>
</router>
</outbound-router>
</mule-descriptor>
フィルタやルータに付いては下節で説明しますので、ここでは気にしないでください。この設定は、LoanBrokerは vm://Loan.Requests からリクエストを受け取り、送信ルータ(outbound-router)を介して複数の銀行へリクエストを送信する定義です。銀行のエンドポイントは送信メッセージのプロパティ(詳細に付いては[ローン・ブローカ]を参照してください )である、「recipients」というリスト(List)で定義されています。送信ルータ(outbound-router)の重要な設定は<reply-to>エンドポイントです。この設定はESB Muleに全てのレスポンスをレスポンス・ルータが監視しているjms://Loan.Quotesへ送るように指示します。全てのレスポンスを受けると、 BankQuotesResponseAggregator は最安の見積もりを抽出して返します。ESB Muleがリクエストの出し主に値を送信します。<reply-to>エンドポイントは、次に呼び出されたコンポーネントに適用されます。即ち、もし コンポーネント1 が コンポーネント2 に送信し、 コンポーネント1 の送信ルータ(outbound-router)にreply-toエンドポイントが設定されている場合は、 コンポーネント2 は結果をreply-toエンドポイントへ返します。
レスポンス・トランスフォーマー
レスポンス・イベントに処理を行わなく、変換のみを行うには、レスポンス・ルータの transformers 属性にトランスフォーマを指定して、ルータにはルーティング設定を記述しません。
<response-router transformers="OrderConfirmationToXml XmlToWebPage"/>
入れ子ルータの設定(Nested Router Configuration)
入れ子ルータは、ワークフロー中にコンポーネントが外部サービスを呼び出す必要がある場合に使うことができます。入れ子ルータはJavaインターフェース・バインディングに基づいています。呼び出す外部サービスはインターフェースで実装します。コンポーネントはインターフェースへのリファレンスをカプセル化します。リファレンスはリフレクション・プロキシ・クラスを使って初期化されます。
public class Invoker
{
private HelloInterface hello;
public String invoke(String s)
{
return "Received: " + hello.helloMethod(s);
}
public void setHello(HelloInterface hello)
{
this.hello = hello;
}
public HelloInterface getHello()
{
return hello;
}
}
次に、入れ子ルータ(nested-router)を使って定義したインターフェースと外部サービスをバインドします。
<mule-descriptor name="InvokerComponent" implementation="org.mule.foo.Invoker">
<inbound-router>
<endpoint address="jms:/>
</inbound-router>
<nested-router>
<binding interface="org.mule.foo.HelloInterface">
<endpoint address="axis:http: remoteSync="true"/>
</binding>
</nested-router>
<outbound-router>
<router className="org.mule.routing.outbound.OutboundPassThroughRouter">
<endpoint address="jms:/>
</router>
</outbound-router>
</mule-descriptor>
コンポーネントのワークフローは呼び出しが終了するまで待つので、外部サービスは同期です。その結果、インターフェースに対応したエンドポイントは同期でなければなりません(VMトランスポートの場合は「remoteSync」ではなく、「synchronous」属性を使います)。
ESB Mule受信ルータ
以下の節は、ESB Muleの各受信ルータとその設定方法を説明します。
Idempotentリシーバ
IdempotentReceiverは、コンポーネントがユニークなメッセージのみを受信するための受信ルータ(inbound-router)です。受信するメッセージがユニークであることを確認するために、受信する各メッセージのIDを確認し、保存します。多くの場合は、IDは下層技術で設定されるユニークIDが使われ、ユニークIDに対応していないエンドポイントもあります。エンドポイントがユニークIDに対応していない場合は例外が投げられます。
org.mule.routers.inbound.IdempotentReceiver は簡単なIdepotentレシーバの実装です。デフォルトの実装は、メッセージIDを管理するのにファイルを使います。ただし、クラスを継承してメッセージIDをデータベースで管理するようにすることもできます。
設定
<inbound-router>
<router className="org.mule.routing.inbound.IdempotentReceiver">
<properties>
<property name="disablePersistence" value="false"/>
<property name="storePath" value="./idempotent"/>
</properties>
</router>
</inbound-router>
disablePersistence - メッセージIDをディスクに保管するか設定。ディスクに保管すると、再起動する前の状態を維持することができます。デフォルトはfalseです。
storePath - メッセージIDを管理するファイルの場所。ESB Muleのワーキング・ディレクトリは Muleconfiguration.setWorkingDir(...) で設定されます。デフォルトのワーキング・ディレクトリは ./.mule です。作成されるファイル名は、muleComponent_<コンポーネント名>です。このプロパティのデフォルト値は ./.mule/idempotent/ です。
Selective Consumer(選択ルータ)
選択ルータ(selective consumer)とは1つ以上のフィルタをイベント・ペイロードに適用できる受信ルータ(inbound router)です。フィルタの条件がイベントと一致した場合は次のコンポーネントへイベントへ転送しますが、不一致の場合はルータのcatch-all処理に渡されます。catch-all処理が設定されていない場合は、イベントは無視され、ログに注意(warning)が書き込まれます。
設定
<inbound-router>
<catch-all-strategy className="org.mule.routing.ForwardingCatchAllStrategy">
<endpoint address="jms://topic:error.topic"/>
</catch-all-strategy>
<router className="org.mule.routing.inbound.SelectiveConsumer">
<filter expression="msg/header/resultcode = 'success'"
className="org.mule.routing.filters.xml.JXPathFilter"/>
</router>
</inbound-router>
このルータにプロパティは設定されていません。ただし、どのようにフィルタを設定できるかに付いてフィルタページを参照してください。
デフォルトでは、受信エンドポイントに設定されたトランスフォーマで変換した後にイベント・ペイロードにフィルタは適用されます。場合によっては、トランスフォーマで変換する前にイベント・ペイロードにフィルタを適用する必要があります。このような場合は、ルータに transformFirst プロパティを設定します。
<inbound-router>
<catch-all-strategy className="org.mule.routing.ForwardingCatchAllStrategy">
<endpoint address="jms://topic:error.topic"/>
</catch-all-strategy>
<router className="org.mule.routing.inbound.SelectiveConsumer">
<filter expression="msg/header/resultcode = 'success'"
className="org.mule.routing.filters.xml.JXPathFilter"/>
<properties>
<property name="transformFirst" value="false"/>
</properties>
</router>
</inbound-router>
Aggregator(結合)
結合パターンは2つ以上のメッセージを1つの結果メッセージに結合します。ESB Muleはメッセージを結合するテンプレート・メソッドを定義した抽象クラスを提供しています。結合ルータは複数の結果を合わせる場合に使います。例えば、製品Xの最低販売価格をお店を探す場合などに使うことができます。
結合ルータは、選択ルータに基づいているため、メッセージにフィルタを適用することができます。
設定
<inbound-router>
<router className="org.mule.routing.inbound.CorrelationAggregator">
<filter expectedType="org.foo.some.Object"
className="org.mule.routing.filters.PayloadTypeFilter"/>
</router>
</inbound-router>
CorrelationAggregatorはCorrelationIdを使って条件に一致するメッセージを選択します。Correlation(相関)Idは受け取りリストやメッセージ分割のような送信ルータによってメッセージに設定されます。これらのメッセージはCorrelationAggregatorを使って再び結合することができます。
別の条件でメッセージを結合するAggregatorルータを作成することもできます。作成する場合は、既にあるスレッド・セーフなAbstractEventAggregatorを継承することを推奨します。
Resequencer(並び替え)
並び替えルータは、メッセージを一旦保留して、順番を並び替えた後にコンポーネントに送信します。イベントをソートするのに java.util.Comparator が使われます。このルータは、選択ルータに基づいているため、メッセージにフィルタを適用することができます。
設定
<inbound-router>
<router className="org.mule.routing.foo.SimpleEventResequencer">
<filter expression="msg/header/resultcode = 'success'"
className="org.mule.routing.filters.xml.JXPathFilter"/>
<properties>
<property name="comparator"
value="org.mule.routing.foo.EventPayloadComparator"/>
<property name="eventThreshold" value="5"/>
</properties>
</router>
</inbound-router>
EventPayloadComparator はイベントを並び替えるのに使われます。comparator(比較式)プロパティが設定されていない場合は、イベントは並び替えられません。
メッセージが送信された順をグループ(correlation idによってグループされる)して並び替えるCorrelationEventResequencerもあります。例えば、メッセージ分割を使って複数のイベントを発行した後に、それらの結果を指定した順で処理をしたい場合に使うことができます。
<inbound-router>
<router className="org.mule.routing.inbound.CorrelationEventResequencer"/>
</inbound-router>
この他の設定はMuleMessageの標準設定が使われるため、設定は不要です。
Forwarding Consumer(転送ルータ)
このルータは、コンポーネント処理が無く、イベントを送信エンドポイントへ転送します。受信エンドポイントと送信エンドポイントを繋ぐの橋のような役割をします。受信したイベントに処理を行う必要が無く、ネットワークの他アドレス(例:リモートESB Muleノート又はアプリケーション)にイベントを転送する場合に使います。
設定
<mule-descriptor name="FileReader"
inboundEndpoint="file:///temp/myfiles/in"
outboundTransformer="ObjectToByteArray"
outboundEndpoint="tcp://192.168.0.6:12345"
implementation="org.mule.components.simple.NullComponent">
<inbound-router>
<router className="org.mule.routing.inbound.ForwardingConsumer"/>
</inbound-router>
</mule-descriptor>
ファイルがローカル・ファイル・システムのディレクトリに置かれると、そのファイルがイベントとしてTCPアドレス192.168.0.6:12345へ転送されます。 outboundTransfrmer が設定されているのに注目してください。これはTCPで転送するまえに、イベント・ペイロード(ここではファイル)をバイト配列に変換するためです。また、コンポーネントの実装(implementation)には NullComponent が設定されています。ただし、ルータを追加して、条件によってもコンポーネントで処理されるようにすることもできます。
転送ルータは、選択ルータを継承しているため、このルーツにフィルタを設定することができます。
BridgeComponent
ESB Mule1.1からサポートされた BridgeComponent は、自動的に転送ルータ(Forwarding consumer)を設定し、上の例の NullComponent が不要になります。下は上の例を BridgeComponent を使って記述した例です:
<mule-descriptor name="FileReader"
inboundEndpoint="file:///temp/myfiles/in"
outboundTransformer="ObjectToByteArray"
outboundEndpoint="tcp://192.168.0.6:12345"
implementation="org.mule.components.simple.BridgeComponent">
</mule-descriptor>
ESB Mule送信(outbound)ルータ
以下の節は、ESB Muleの送信(outbound)ルータとその設定に付いて説明します。送信ルータには、1つ以上のフィルタを設定することができ、その条件によってルーティングを変えることができます。そのために、受信ルータよりも設定が複雑になる場合があります。
コンテキスト・ベース・ルータ
コンテキスト・ベース・ルーティングとは、イベントの内容によってイベントをルーティングする仕組みです。現在、ESB Muleはフィルタリング送信ルータ(Filtering Outbound Router)でコンテキスト・ベース・ルーティングを可能にしています。
送信ルータのフィルタ
コンテキスト・ベース・ルータはフィルタを使って、イベントの内容が特定の条件に一致するか判断します。一致した場合は、ルータに定義された1つ以上のエンドポイントにイベントを送ります。
全てのESB Mule送信ルータ(outbound router)はFilteringOutboundRouterを継承します。即ち、どの送信ルータにもフィルタを設定することができます。ただし例外としてOutboundPassThroughRouterには設定することができません。
設定
<outbound-router>
<catch-all-strategy className="org.mule.routing.ForwardingCatchAllStrategy">
<endpoint="jms://error.queue"/>
</catch-all-strategy>
<router className="org.mule.routing.outbound.FilteringOutboundRouter">
<endpoint address="smtp://ross@muleumo.org"/>
<filter expectedType="java.lang.Exception"
className="org.mule.routing.filters.PayloadTypeFilter"/>
</router>
<router className="org.mule.routing.outbound.FilteringOutboundRouter">
<endpoint address="jms://string.queue"/>
<filter className="org.mule.routing.filters.logic.AndFilter">
<left-filter expectedType="java.lang.String"
className="org.mule.routing.filters.PayloadTypeFilter"/>
<right-filter pattern="the quick brown (.*)"
className="org.mule.routing.filters.RegExFilter"/>
</filter>
</router>
</outbound-router>
イベントをトランスフォーマで変換する前に、イベント・ペイロードにフィルタが適用されます。フィルタを適用する前に変換を行う必要がある場合もあります。そのような場合は、フィルタを行う前にトランスフォーマで変換するようにルータを設定します。
<outbound-router>
<router className="org.mule.routing.outbound.FilteringOutboundRouter">
<endpoint address="smtp://ross@muleumo.org"/>
<filter expectedType="java.lang.Exception"
className="org.mule.routing.filters.PayloadTypeFilter"/>
<properties>
<property name="transformer" value="aTransformer"/>
</properties>
</router>
</outbound-router>
受け入れリスト(Recipient List)
受け入れリスト・ルータは、同じイベントを複数のエンドポイントに送信する場合や、次に送信する先がイベント・プロパティ又はペイロードで判断されるルーティング・スリップのような場合に使うことができます。
ESB Muleはスレッド・セーフな実装をしたorg.mule.routing.outbound.AbstractRecipientList抽象クラスを提供しています。ESB Muleは現イベント又は静的にエンドポイントに宣言されたエンドポイントのリストを受け取るStaticな受け入れリスト(static recipient list)も提供しています。
設定
<outbound-router>
<router className="org.mule.routing.outbound.StaticRecipientList">
<filter expectedType="javax.jms.Message"
className="org.mule.routing.filters.PayloadTypeFilter"/>
<properties>
<list name="recipients">
<entry value="jms://orders.queue"/>
<entry value="jms://tracking.queue"/>
</list>
</properties>
</router>
</outbound-router>
ReplyTo
送信ルータ(outbound-router)にreply-toプロパティを設定することができます。reply-toプロパティを設定すると、この送信ルータから送信された全てのメッセージの返信が指定された1つのアドレスへ送信されます。
<outbound-router>
<router className="org.mule.routing.outbound.StaticRecipientList">
<reply-to address="vm://component4"/>
<filter expectedType="javax.jms.Message"
className="org.mule.routing.filters.PayloadTypeFilter"/>
<properties>
<list name="recipients">
<entry value="jms://orders.queue"/>
<entry value="jms://tracking.queue"/>
</list>
</property>
</router>
</outbound-router>
この設定は、先ずJMSメッセージのペイロード型がJMSメッセージかを確認し、次に orders.queue と tracking.queue へメッセージを送信します。
マルチキャスト・ルータ
マルチキャスト・ルータは、複数のエンドポイントに同じイベントを送ります。このルータを利用する場合は、エンドポイントにイベント型を正しく処理するトランスフォーマを設定する必要があります。
設定
<outbound-router>
<router className="org.mule.routing.outbound.MulticastingRouter">
<endpoint address="jms://test.queue" transformers="StringToJmsMessage"/>
<endpoint address="http://10.192.111.11" transformers="StringToHttpClientRequest"/>
<endpoint address="tcp://10.192.111.12" transformers="StringToByteArray"/>
<filter expectedType="java.lang.String"
className="org.mule.routing.filters.PayloadTypeFilter"/>
</router>
</outbound-router>
ルーティングするメッセージをエンドポイントが処理できる形式に変換することを忘れないようにしてください。
ReplyTo
送信ルータ(outbound-router)にreply-toプロパティを設定することができます。reply-toプロパティを設定すると、この送信ルータから送信された全てのメッセージの返信が指定された1つのアドレスへ送信されます。
<outbound-router>
<router className="org.mule.routing.outbound.MulticastingRouter">
<endpoint address="jms://test.queue" transformers="StringToJmsMessage"/>
<endpoint address="http://10.192.111.11" transformers="StringToHttpClientRequest"/>
<endpoint address="tcp://10.192.111.12" transformers="StringToByteArray"/>
<reply-to address="vm://component4"/>
<filter expectedType="java.lang.String"
className="org.mule.routing.filters.PayloadTypeFilter"/>
</router>
</outbound-router>
例外ベース・ルータ(Exception Based router)
例外ベース・ルータは、トランスポートに最初に接続できるエンドポイントを利用してイベントを送信します。リトライを設定する場合に便利です。例えば、最初のエンドポイントでの接続が失敗した場合は次のエンドポイントを試します。それが失敗した場合は次のエンドポイントを試します。
注:利用できるエンドポイントを探している最中は、エンドポイントを同期モードにオーバーライドします。見つかった場合は、エンドポイント一覧の最後の設定のモードを使います。
設定
<outbound-router>
<router className="org.mule.routing.outbound.ExceptionBasedRouter">
<endpoint address="tcp://10.192.111.10:10001" />
<endpoint address="tcp://10.192.111.11:10001" />
<endpoint address="tcp://10.192.111.12:10001"/>
</router>
</outbound-router>
メッセージ分割(Message Splitter)
メッセージ分割は、送信メッセージを分割して、それぞれをルータに設定されている別のエンドポイントへ送ります。ESB Muleはメッセージ分割の抽象クラスorg.mule.routing.outbound.AbstractMessageSplitter を提供しています。このクラスは、スレッド・セーフなイベント・ルーティング処理を実装しています。開発者は、このクラスを継承して実際にどのようにしてメッセージを分割するかを定義するだけです。
設定
<outbound-router>
<router className="org.foo.ConcreteMessageSplitter">
<endpoint address="vm://component1"/>
<endpoint address="vm://component2"/>
<endpoint address="vm://component3"/>
</router>
</outbound-router>
他ルータの設定と同じようにルータのビーン・プロパティを設定するプロパティ要素を定義することができます。例えば、メッセージの部分を抽出するためいXPathのリストを定義することができます。詳細に付いてはプロパティの設定を参照してください。
デフォルトでは、AbstractMessageSplitterは送信(outbound)イベントにCorrelation IdとCorrelation Sequenceを設定します。その結果、AggregatorやResequencerのような受信(inbound)ルータは分割されたメッセージを並び替えたり、結合することができます。
ReplyTo
送信ルータ(outbound-router)にreply-toプロパティを設定することができます。reply-toプロパティを設定すると、この送信ルータから送信された全てのメッセージの返信が指定された1つのアドレスへ送信されます。
<outbound-router>
<router className="org.foo.ConcreteMessageSplitter">
<endpoint address="vm://component1"/>
<endpoint address="vm://component2"/>
<endpoint address="vm://component3"/>
<reply-to address="vm://component4"/>
</router>
</outbound-router>
メッセージ分割フィルタ・リスト(Filtering List Message Splitter)
このルータはオブジェクトのリストを受け取って、別々のエンドポイントにルーティングさせる機能をもつメッセージ分割ルータの実装です。リストの各オブジェクトに使われる実際のエンドポイントは、エンドポイントに設定されているフィルタによります。エンドポイントのフィルタがオブジェクトの型と一致している場合は、そのエンドポイントが使われます。
下に設定されたルータは java.util.List のメッセージ・ペイロードを受け取って、 com.foo.Order, com.foo.Item と com.foo.Customer のオブジェクトをルーティングします。ルータをこのオブジェクトの任意の組み合わせに設定することができます。
設定
<outbound-router>
<router className="org.mule.routing.outbound.FilteringListMessageSplitter">
<endpoint address="jms://order.queue">
<filter expectedType="com.foo.Order" className="org.mule.routing.filters.PayloadTypeFilter"/>
</endpoint>
<endpoint address="jms://item.queue">
<filter expectedType="com.foo.Item" className="org.mule.routing.filters.PayloadTypeFilter"/>
</endpoint>
<endpoint address="jms://customer.queue">
<filter expectedType="com.foo.Customer" className="org.mule.routing.filters.PayloadTypeFilter"/>
</endpoint>
<filter expectedType="java.util.List" className="org.mule.routing.filters.PayloadTypeFilter"/>
</router>
</outbound-router>
ルータにフィルタも設定されていますことに注目してください。このフィルタはルータは java.util.List 型のメッセージ・ペイロードしか受け取らないようにします。リスト内にフィルタの条件と一致しなオブジェクトがある場合は、ログに注意が書き出されて処理は継続します。もし不一致のオブジェクトを他エンドポイントにルーティングする場合は、フィルタを無くして、エンドポイントの一覧に新しくエンドポイントを追加します。
XMLメッセージ分割フィルタ(Filtering Xml Message Splitter)
上の類似していますが、XML文書を処理します。対応しているペイロード型は以下の通りです:
- org.dom4j.Document objects
- byte[]
- java.lang.String
一致した型が無い場合は、無視されます(ログにWARNレベルで記述されます)。
ルータは splitExpression プロパティによってペイロードをノードに分割します。リストの各オブジェクトに使われる実際のエンドポイントは、エンドポイントに設定されているフィルタによります。エンドポイントのフィルタがオブジェクトの型と一致している場合は、そのエンドポイントが使われます。
ルータは外部XML Sche
maを使って検証することもできます。 externalSchemaLocation をクラスパスのXSDファイルに設定します。設定した場合は、XML文書のヘッダに指定・設定したスキーマをオーバーライドします。
分割結果は新しいDOM4J文書として返されます。
設定
<outbound-router>
<router className="org.mule.routing.outbound.FilteringXmlMessageSplitter">
<endpoint address="vm://order">
<filter expectedType="com.foo.Order" className="org.mule.routing.filters.PayloadTypeFilter"/>
</endpoint>
<endpoint address="vm://item">
<filter expectedType="com.foo.Item" className="org.mule.routing.filters.PayloadTypeFilter"/>
</endpoint>
<endpoint address="vm://customer">
<filter expectedType="com.foo.Customer" className="org.mule.routing.filters.PayloadTypeFilter"/>
</endpoint>
<filter expectedType="org.dom4j.Document" className="org.mule.routing.filters.PayloadTypeFilter"/>
<properties>
<property name="splitExpression" value="/root/nodes"/>
<property name="validateSchema" value="true"/>
<property name="externalSchemaLocation" value="/com/example/TheSchema.xsd"/>
</properties>
</router>
</outbound-router>
連鎖ルータ(Chaining Router)
連鎖ルータは、イベントを連鎖させて複数のエンドポイントへ送る場合に使えます。一つのエンドポイントの結果が次のエンドポイントを入力になります。例えば、Web Serviceで実装した同時リクエスト-レスポンスの結果をJMSキューに送ることができます。
設定
<outbound-router>
<router className="org.mule.routing.outbound.ChainingRouter">
<endpoint address="axis:http://localhost:8081/services/xyz?
method=getSomething"/>
<endpoint address="jms://something.queue"
transformer="SomethingToJmsMessage"/>
</router>
</outbound-router>
Replytoエンドポイントの使い方
全ての送信(outbound)ルータに<reply-to>エンドポイントを定義することができます。<reply-to>エンドポイントは、ディスパッチしたイベントが処理された結果を送り先です。<reply-to>エンドポイントは、次のコンポーネントに適用されます。即ち、 コンポーネント1 が コンポーネント2 にイベントをディスパッチして、 コンポーネント1 にreply-toエンドポイントが定義されていると、 コンポーネント2 は結果をreply-toエンドポイントへ送ります。
<reply-to>エンドポイントには、任意のESB MuleエンドポイントURIを指定することができます。JMSのように下層トランスポートがreplyToをサポートしている場合は、そのreplyToが使われます。