8.14. Composed Message Processor

Composed Message Processor

図8.10「Composed Message Processor パターン」 に記載されているように、 Composed Message Processor パターンでは、メッセージを分割し、そのサブメッセージをそれぞれ適切な宛先にルーティングし、そしてレスポンスを再度単一のメッセージに集約し直すといったやり方で、合成メッセージを処理できます。

図8.10 Composed Message Processor パターン

分散アグリゲート

Java DSL の例

以下の例では、複数パーツからなる注文に応じることができるかをチェックしています。ここでは、注文の各パーツでそれぞれ異なる在庫に対してチェックを行う必要があります。

// split up the order so individual OrderItems can be validated by the appropriate bean
from("direct:start")
    .split().body()
    .choice()
        .when().method("orderItemHelper", "isWidget")
            .to("bean:widgetInventory")
        .otherwise()
            .to("bean:gadgetInventory")
    .end()
    .to("seda:aggregate");

// collect and re-assemble the validated OrderItems into an order again
from("seda:aggregate")
    .aggregate(new MyOrderAggregationStrategy())
    .header("orderId")
    .completionTimeout(1000L)
    .to("mock:result");

XML DSL の例

上記のルートは、以下のように XML DSL で記述することもできます。

 <route>
   <from uri="direct:start"/>
   <split>
     <simple>body</simple>
     <choice>
       <when>
         <method bean="orderItemHelper" method="isWidget"/>
 	<to uri="bean:widgetInventory"/>
       </when>
       <otherwise>
 	<to uri="bean:gadgetInventory"/>
       </otherwise>
     </choice>
     <to uri="seda:aggregate"/>
   </split>
 </route>

 <route>
   <from uri="seda:aggregate"/>
   <aggregate strategyRef="myOrderAggregatorStrategy" completionTimeout="1000">
     <correlationExpression>
       <simple>header.orderId</simple>
     </correlationExpression>
     <to uri="mock:result"/>
   </aggregate>
 </route>

処理のステップ

処理は、「Splitter」 を使用して注文を分割することから始まります。「Splitter」 は続いて、個別の OrderItems「Content-Based Router」 に送信し、項目種別に基づいてメッセージをルーティングします。ウィジェット 項目はチェックのために widgetInventory Bean に送信され、ガジェット 項目は gadgetInventory Bean に送信されます。OrderItems はそれぞれ適切な Bean によって検証されると、「Aggregator」 に送信され、検証済みの OrderItems を収集して 1 つの注文に再び構築し直します。

受信した注文はそれぞれ、注文 ID を含んだヘッダーを持ちます。注文 ID は集約のステップで利用されます。aggregate() DSL コマンドの .header("orderId") 修飾子は、アグリゲーターがキー orderId のヘッダーを相関式として使用するように指示します。

詳細は、camel-core/src/test/java/org/apache/camel/processor にある ComposedMessageProcessorTest.java サンプルソースを確認してください。