8.18. Dynamic Router

Dynamic Router

図8.12「Dynamic Router パターン」 に示すように、Dynamic Router パターンを使用すると、設計時にはステップの順序がわからない一連の処理ステップを介して、メッセージを連続してルーティングすることができます。メッセージが通過するエンドポイントのリストは、実行時に動的に計算されます。メッセージがエンドポイントから戻るたびに、動的ルーターはルート内の次のエンドポイントを発見するために Bean にコールバックします。

図8.12 Dynamic Router パターン

動的ルーター

Camel 2.5では、DSL に dynamicRouter が導入されました。これは、その場で slip を評価する動的な 「Routing Slip」 のようなものです。

注意事項

dynamicRouter (Bean など) に使用される式が null を返して終了を示すようにしなければなりません。そうしないと、dynamicRouter は無限ループで続行されます。

Camel 2.5 以降の Dynamic Router

Camel 2.5 以降では、「Dynamic Router」 は、slip を通過する際にエクスチェンジプロパティー Exchange.SLIP_ENDPOINT を現在のエンドポイントで更新します。これにより、エクスチェンジが slip 経由でどこまで進んでいるかを調べることができます。(slip としているのは、「Dynamic Router」 の実装が 「Routing Slip」 をベースとしているためです)。

Java DSL

Java DSL では、以下のように dynamicRouter を使用できます。

from("direct:start")
    // use a bean as the dynamic router
    .dynamicRouter(bean(DynamicRouterTest.class, "slip"));

Bean の統合を利用してその場で slip を計算していますが、これは以下のように実装することができます。

// Java
/**
 * Use this method to compute dynamic where we should route next.
 *
 * @param body the message body
 * @return endpoints to go, or <tt>null</tt> to indicate the end
 */
public String slip(String body) {
    bodies.add(body);
    invoked++;

    if (invoked == 1) {
        return "mock:a";
    } else if (invoked == 2) {
        return "mock:b,mock:c";
    } else if (invoked == 3) {
        return "direct:foo";
    } else if (invoked == 4) {
        return "mock:result";
    }

    // no more so return null
    return null;
    }
注記

上記の例はスレッドセーフではありません。スレッドの安全性を確保するために、Exchange に状態を格納する必要があります。

Spring XML

Spring XML での同じ例は次のとおりです。

<bean id="mySlip" class="org.apache.camel.processor.DynamicRouterTest"/>

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="direct:start"/>
        <dynamicRouter>
            <!-- use a method call on a bean as dynamic router -->
            <method ref="mySlip" method="slip"/>
        </dynamicRouter>
    </route>

    <route>
        <from uri="direct:foo"/>
        <transform><constant>Bye World</constant></transform>
        <to uri="mock:foo"/>
    </route>

</camelContext>

オプション

dynamicRouter DSL コマンドは以下のオプションをサポートします。

名前

デフォルト値

説明

uriDelimiter

,

パートII「ルーティング式と述語言語」 によって返された複数のエンドポイントに使用される区切り文字。

ignoreInvalidEndpoints

false

エンドポイント URI を解決できなかった場合は、無視されます。false の場合は、Camel はエンドポイント URI が有効ではないことを示す例外を出力します。

@DynamicRouter アノテーション

@DynamicRouter アノテーションを使用することもできます。以下に例を示します。

// Java
public class MyDynamicRouter {

    @Consume(uri = "activemq:foo")
    @DynamicRouter
    public String route(@XPath("/customer/id") String customerId, @Header("Location") String location, Document body) {
        // query a database to find the best match of the endpoint based on the input parameteres
        // return the next endpoint uri, where to go. Return null to indicate the end.
    }
}

route メソッドは、メッセージが処理される際に繰り返し呼び出されます。次の宛先のエンドポイント URI を返すために行われます。null を返して終了を示します。「Routing Slip」 のように複数のエンドポイントを返すことができ、各エンドポイントは区切り文字で区切られます。