Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Camel:如何根据配置有条件地构建路由?_Java_Spring_Apache Camel - Fatal编程技术网

Java Camel:如何根据配置有条件地构建路由?

Java Camel:如何根据配置有条件地构建路由?,java,spring,apache-camel,Java,Spring,Apache Camel,我有一个RouteBuilder子类,用于设置骆驼路线。它是由春天建造的。最初看起来是这样的: @Override public void configure() throws Exception { from(...) .process(...) .to(...) } 我想做的是根据配置添加一个额外的端点路由。Spring使用一个属性文件来创建RouteBuilderbean,它设置的一个字段是boolean addAnotherEndpoint。如果此布尔值为真,我

我有一个
RouteBuilder
子类,用于设置骆驼路线。它是由春天建造的。最初看起来是这样的:

@Override
public void configure() throws Exception {
    from(...)
    .process(...)
    .to(...)
}
我想做的是根据配置添加一个额外的端点路由。Spring使用一个属性文件来创建
RouteBuilder
bean,它设置的一个字段是
boolean addAnotherEndpoint
。如果此布尔值为真,我想向添加另一个
。如果它是假的,我希望它回到目前的行为。所以我把它改成:

@Override
public void configure() throws Exception {
    from(...)
    .process(...)
    .to(...)
    .choice()
        when(constant(addAnotherEndpoint)).to(...)
    .endChoice();
}
虽然这似乎具有所需的行为,但我在为其编写单元测试时遇到了问题(因为它从属性文件中提取
addAnotherEndpoint
的值,即使我试图在测试中覆盖它)。有没有更好的处理方法?我目前的方法会有任何意外的副作用吗

编辑:

我正在使用
CamelSpringTestSupport
子类(使用JUnit测试)进行测试。在
@Before
方法中,我创建了一个
AdviceWithRouteBuilder
,它用mock替换所有端点。在我的
@Test
中,我试图覆盖从属性文件中获取的
addAnotherEndpoint
的值:

@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();
}
有一个相应的测试将
addAnotherEndpoint
设置为
false
,并断言收到了0条消息。问题是重写此变量的值似乎不起作用。一个测试通过,另一个测试失败,这取决于我的属性文件是否说明该值应为
true
false
。这对我来说意味着路由是在覆盖设置之前构造的(因此也是在上下文启动之前)。我签入了调试器,设置被正确覆盖。这似乎没有任何影响

编辑2:

从我对RouteBuilder的
建议中:

@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()
(返回true)上的
@Override
,以及
createApplicationContext()
,它返回一个新的Spring应用程序上下文


我在没有
context.start()
的情况下运行了测试,唯一通过的测试是断言收到了0条消息的测试(如果路由没有启动,这是有意义的)。因此,我不认为上下文是自动启动的。

以下是最终起作用的内容:

我的测试很好,但我不得不重新思考我是如何建立我的路线的。发生的事情发生在创建Spring上下文时,路线正在构建中。它当时检查了
addAnotherEndpoint
的值,并根据该值设置
常量。但是
boolean
是一个基本值,这意味着它是通过值传递的。为什么这很重要?因为
constant()
函数只是根据构建路由时该常量的值来设置路由。后来通过Spring对其进行更改没有影响,因为该值已经被读取。我需要做的是让它以谓词的形式传递一个对象,这样我以后就可以将同一个对象作为bean进行操作

此外,我还按照建议将
choice()
更改为
filter()
。这是成品:

@Override
public void configure() throws Exception {
    from(...)
    .process(...)
    .to(...)
    .choice()
        when(myBooleanPredicate).to(...)
    .endChoice();
}
我的自定义谓词可以通过Spring进行操作:

public class BooleanPredicate implements Predicate {
  private boolean value;

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

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

布尔谓词
的内部
设置为
addAnotherPredicate
。每次运行路由时都会重新读取它,因为
布尔谓词
是通过引用传递的。

我刚刚发现

.when(exchange-> foo()==true)

足够了。

我觉得这是一条非常正常的路线。我想唯一的问题是你测试它的方式。在现场环境中,这条路线应该可以。你能分享一下你是如何测试它的吗?然后我们也可以解决这个问题。顺便说一句,如果你使用一个过滤器,而不是只有一个条件的选择,会更简单。谢谢你的建议。我正在使用
CamelSpringTestSupport
子类来测试它。我将更新此问题以包含此内容。我还可以看看您对RouteBuilder block的建议吗?另外,您的测试类是否有任何注释?还可以删除context.start();从测试开始,运行它们以查看上下文是否自动启动?如果是这样,问题就在那里…再次更新问题。您在那里做了很好的分析。如果不是我,我相信其他人会帮你的。在您做出选择之前,如果您记录addanTheEndpoint,您会看到什么?因为这是我唯一没有解决的问题,你能告诉我你是如何覆盖这个属性的吗?