2016-04-07 13 views
1

私はキャメルルートを設定するRouteBuilderサブクラスを持っています。それは春で作られています。最初は、次のようになりました。Camel:設定から条件付きで経路を構築する方法は?

@Override 
public void configure() throws Exception { 
    from(...) 
    .process(...) 
    .to(...) 
} 

構成に基づいて追加のエンドポイントルーティングを追加します。 SpringがRouteBuilder beanを作成するために使用するPropertiesファイルがあり、それが設定するフィールドの1つがboolean addAnotherEndpointです。このブール値が真であれば、別のtoを追加したいと思います。それが偽であれば、私はそれを現在の行動に戻すことを望みます。だから私はこれにそれを変更:

@Override 
public void configure() throws Exception { 
    from(...) 
    .process(...) 
    .to(...) 
    .choice() 
     when(constant(addAnotherEndpoint)).to(...) 
    .endChoice(); 
} 

を、これはそれがプロパティからaddAnotherEndpointの値を引いていますので、私は私がしようとしているにもかかわらず、(そのためのユニットテストを書くの問題を有するファイルてる望ましい行動を持っているように見えるが私のテストでそれを無効にする)。これを処理するより良い方法はありますか?私の現在のメソッドに意図しない副作用がありますか?

編集:私はCamelSpringTestSupportサブクラスを使用してテストしてい

(JUnitテストを使用)。 @Beforeメソッドでは、すべてのエンドポイントをモックで置き換えるAdviceWithRouteBuilderを作成します。

@Test 
public void testConditionalRouting() throws Exception { 
    context.start(); 
    MyRouteBuilder routeBuilder = (MyRouteBuilder) applicationContext.getBean("myRouteBuilder"); 
    routeBuilder.setAddAnotherEndpoint(true); 
    getMockEndpoint("myMockEndpoint").expectedMessageCount(1); 
    sendMockMessage(); 
    assertMockEndpointsSatisfied(); 
    context.stop(); 
} 

falseaddAnotherEndpointを設定し、0メッセージが受信されたと主張し、対応するテストがあります:私の@Testでは、私は、プロパティファイルから取得されaddAnotherEndpointの値を上書きしようとしています。問題は、この変数の値を上書きすることが機能していないように見えることです。 1つのテストに合格し、もう1つはプロパティファイルで値がtrueまたはfalseであるかどうかによって失敗します。これが私に示唆しているのは、設定を上書きする前に(したがってコンテキストが開始される前に)ルートが構築されているということです。私はデバッガをチェックインしました。が正しくオーバーライドされています。それだけでは何の影響もないようです。

EDIT 2:私のAdviceWithRouteBuilderから

@Override 
public void configure() throws Exception { 
    replaceFromWith(MOCK_FROM_ENDPOINT); 
    interceptSendToEndpoint(FIRST_TO_ENDPOINT) 
      .skipSendToOriginalEndpoint().to(MOCK_FIRST_TO_ENDPOINT); 
    weaveById(MY_PROCESSOR_ENDPOINT).replace() 
      .to(MOCK_MY_PROCESSOR_ENDPOINT); 
    weaveById(SECOND_TO_ENDPOINT).replace() 
      .to(MOCK_SECOND_TO_ENDPOINT); 
} 

これはモックエンドポイントと各EIPを置き換えます。私はこれらに依存する4つのテストを持っており、期待どおりに動作しているようですが、唯一の問題は条件付きルーティングです。

別にJUnitの注釈から、私のテストクラスの唯一の注釈は、新しい春のアプリケーションコンテキストを返しisUseAdviceWith()@Override(trueを返す)とcreateApplicationContext()、です。

context.start()なしでテストを実行しましたが、0のメッセージが受信されたと主張するものが1つだけでした(ルートが開始されていないと意味があります)。だから私はコンテキストが自動起動しているとは思わない。

私のテストは大丈夫だったが、私は、私は私のルートを構築したかを再考する必要がありました:

+0

これは私にとって非常に正常なルートのようです。私は唯一の問題はあなたがそれをテストする方法だろうと思います。実際の環境では、このルートは大丈夫です。どのようにテストしているのか分かりますか?それで、それを修正することもできます。ところで、条件を1つしか持たないChoiceではなく、Filterを使用する方が簡単です。 –

+0

提案していただきありがとうございます。私はそれをテストするために 'CamelSpringTestSupport'サブクラスを使用しています。これを含めるように質問を更新します。 – tytk

+0

AdviceWithRouteBuilderブロックも表示されますか?また、テストクラスには注釈がありますか? context.start()も削除できますか?あなたのテストの始めから、コンテキストを自動的に開始するかどうかを確認するために実行します。もしそうなら、問題はそこにあります... –

答えて

1

は、ここで作業を終わったものです。起こっていたことは、春のコンテキストが作成されたときに、ルートが構築されていたことでした。その時点でaddAnotherEndpointの値を確認し、それに基づいてconstantを設定します。しかしbooleanはプリミティブな値で、値渡しであったことを意味します。なぜこれは問題なのでしょうか? constant()関数は、ルートが構築された時点でその定数の値に基づいてルートを設定するだけなので、です。 Springを介して後でそれを変更しても、値はすでに読み込まれていたので影響はありませんでした。私がする必要があったのは、オブジェクトを述語として渡すようにして、後で同じオブジェクトをBeanとして操作できるようにすることでした。

また、choice()からfilter()に変更されました。春経由で操作することができ

@Override 
public void configure() throws Exception { 
    from(...) 
    .process(...) 
    .to(...) 
    .choice() 
     when(myBooleanPredicate).to(...) 
    .endChoice(); 
} 

そして、私のカスタム述語:

public class BooleanPredicate implements Predicate { 
    private boolean value; 

    @Override 
    public boolean matches(Exchange exchange) { 
    return value; 
    } 

    public void setValue(boolean value) { 
    this.value = value; 
    } 

このBooleanPredicateの内部valueaddAnotherPredicateに設定されているここで完成した製品です。 BooleanPredicateが参照渡しされてからルートが実行されるたびに読み直されます。

関連する問題