Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.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 从组合路线获得准确响应_Java_Apache Camel - Fatal编程技术网

Java 从组合路线获得准确响应

Java 从组合路线获得准确响应,java,apache-camel,Java,Apache Camel,我有一个动态路由创建者web应用程序。根据流程设计,我制作了骆驼路线。路由可能包含多播、筛选器、聚合、处理器等。在通过UI设计流后,我的路由创建如下: from("seda:start").routeId("idx") .multicast() .to("direct:a", "direct:b", "direct:c") .parallelProcessing() .end(); from("direct:a").transform(constant(

我有一个动态路由创建者web应用程序。根据流程设计,我制作了骆驼路线。路由可能包含多播、筛选器、聚合、处理器等。在通过UI设计流后,我的路由创建如下:

from("seda:start").routeId("idx")
    .multicast()
      .to("direct:a", "direct:b", "direct:c")
      .parallelProcessing()
    .end();

from("direct:a").transform(constant("A")).delay(1000).to("direct:merge");
from("direct:b").transform(constant("B")).delay(2000).to("direct:merge");
from("direct:c").transform(constant("C")).delay(3000).to("direct:merge");

from("direct:merge")
    .aggregate(new MyAggregationStrategy()).constant(true).completionSize(3)
    .to("mock:end");
from("seda:start").routeId("idx")
    .multicast()
        .to("direct:a", "direct:b", "direct:c", "direct:d", "direct:e")
        .parallelProcessing()
    .end();

from("direct:a").transform(constant("A")).delay(1000).to("direct:merge1");
from("direct:b").transform(constant("B")).delay(2000).to("direct:merge1");

from("direct:c").transform(constant("C")).delay(3000).to("direct:merge2");
from("direct:d").transform(constant("D")).delay(1000).to("direct:merge2");

from("direct:e").transform(constant("E")).delay(1000).to("mock:anywhere");

from("direct:merge1").aggregate(new MyAggregationStrategy()).constant(true).completionSize(2).to("direct:merge3");
from("direct:merge2").aggregate(new MyAggregationStrategy()).constant(true).completionSize(2).to("direct:merge3");

from("direct:merge3").aggregate(new MyAggregationStrategy()).constant(true).completionSize(2).to("mock:end");
我有一个API向用户提供此路由的结果。当我使用InOut MEP执行此路由时,响应为“C”,但mock:end对“ABC”表示满意:

MockEndpoint mock = getMockEndpoint("mock:end");
    mock.expectedBodiesReceived("ABC");  //works as expected

    String reply = template.requestBody("seda:start", "", String.class);

    assertEquals("ABC", reply);   //it returns 'C', but I expect 'ABC'

    assertMockEndpointsSatisfied();
如何更改代码以通过同步调用获得聚合结果?代码如下:

public class ResponseTest extends CamelTestSupport {

@Test
public void testAsyncInOut() throws Exception {
    MockEndpoint mock = getMockEndpoint("mock:end");
    mock.expectedBodiesReceived("ABC");  //works as expected

    String reply = template.requestBody("seda:start", "", String.class);

    assertEquals("ABC", reply);   //it returns 'C', but I expect 'ABC'

    assertMockEndpointsSatisfied();
}

@Override
protected RouteBuilder createRouteBuilder() throws Exception {
    return new RouteBuilder() {
        @Override
        public void configure() throws Exception {
            from("seda:start").routeId("idx")
                .multicast()
                    .to("direct:a", "direct:b", "direct:c")
                    .parallelProcessing()
                .end();

            from("direct:a").transform(constant("A")).delay(1000).to("direct:merge");
            from("direct:b").transform(constant("B")).delay(2000).to("direct:merge");
            from("direct:c").transform(constant("C")).delay(3000).to("direct:merge");

            from("direct:merge")
                .aggregate(new MyAggregationStrategy()).constant(true).completionSize(3)
                .to("mock:end");
        }
    };
}

class MyAggregationStrategy implements AggregationStrategy {

    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
        if (oldExchange == null) {
            // this is the first time so no existing aggregated exchange
            return newExchange;
        }

        // append the new word to the existing
        String body = newExchange.getIn().getBody(String.class);
        String existing = oldExchange.getIn().getBody(String.class);

        oldExchange.getIn().setBody(existing + body);
        return oldExchange;
    }
}
}
编辑

将消息多播到5个不同的端点并不意味着所有消息将在以后聚合。所以我不能在多播定义中使用聚合策略。其中一些可能被用于另一种工作。流定义可能如下所示: 在多播消息发送到“a”、“b”、“c”、“d”、“e”端点之后,“a”和“b”可以聚合在一起(“direct:merge1”),“c”和“d”聚合在一起(“direct:merge2”),“e”可以用于其他用途。 最终的聚合器将聚合为“direct:merge1”和“direct:merge2” 至“直接:合并3”。所有这些端点都是动态创建的('direct:a'、'direct:b'、'direct:c'、'direct:d'、'direct:e'、'direct:merge1'、'direct:merge2'、'direct:merge3')。此场景将按如下方式创建:

from("seda:start").routeId("idx")
    .multicast()
      .to("direct:a", "direct:b", "direct:c")
      .parallelProcessing()
    .end();

from("direct:a").transform(constant("A")).delay(1000).to("direct:merge");
from("direct:b").transform(constant("B")).delay(2000).to("direct:merge");
from("direct:c").transform(constant("C")).delay(3000).to("direct:merge");

from("direct:merge")
    .aggregate(new MyAggregationStrategy()).constant(true).completionSize(3)
    .to("mock:end");
from("seda:start").routeId("idx")
    .multicast()
        .to("direct:a", "direct:b", "direct:c", "direct:d", "direct:e")
        .parallelProcessing()
    .end();

from("direct:a").transform(constant("A")).delay(1000).to("direct:merge1");
from("direct:b").transform(constant("B")).delay(2000).to("direct:merge1");

from("direct:c").transform(constant("C")).delay(3000).to("direct:merge2");
from("direct:d").transform(constant("D")).delay(1000).to("direct:merge2");

from("direct:e").transform(constant("E")).delay(1000).to("mock:anywhere");

from("direct:merge1").aggregate(new MyAggregationStrategy()).constant(true).completionSize(2).to("direct:merge3");
from("direct:merge2").aggregate(new MyAggregationStrategy()).constant(true).completionSize(2).to("direct:merge3");

from("direct:merge3").aggregate(new MyAggregationStrategy()).constant(true).completionSize(2).to("mock:end");
当我向seda发送消息时:开始,我期望ABDC,但我得到了“E”。有没有办法获取最终聚合消息(“ABDC”)?以下是测试方法:

@Test
public void testAsyncInOut() throws Exception {
    MockEndpoint mock = getMockEndpoint("mock:end");
    mock.expectedBodiesReceived("ABDC");  //works as expected

    String reply = template.requestBody("seda:start", "", String.class);

    assertEquals("ABDC", reply);   //it returns 'E' because of default multicast behavior, but I expect 'ABDC'

    assertMockEndpointsSatisfied();
}

多播

默认情况下,Camel将使用最后一个回复作为传出消息

如果要将多播结果聚合到单个消息中,请在多播定义中声明

@Override
public void configure() throws Exception {
  from("seda:start").routeId("idx")
    .multicast(new MyAggregationStrategy()) //Put the Aggregation Strategy here!
      .to("direct:a", "direct:b", "direct:c")
      .parallelProcessing()
    .end();

  from("direct:a").transform(constant("A")).delay(1000).to("direct:merge");                      
  from("direct:b").transform(constant("B")).delay(2000).to("direct:merge");
  from("direct:c").transform(constant("C")).delay(3000).to("direct:merge");

  from("direct:merge")
    .to("mock:end");
}

请注意,您的模拟端点现在将被调用3次,因为聚合直到稍后才会发生。您需要相应地修改测试。

谢谢您的回答,但我想我无法清楚地解释我的问题。我不能在多播定义中使用聚合策略。由于根据我在编辑中解释的流程设计,聚合消息中可能不包含某些消息,因此我认为您可以将调用嵌套到
多播(new MyAggregationStrategy())
,以获得所需的结果。