Java ApacheCamel:使用聚合的多播-AggregationStrategy调用太频繁

Java ApacheCamel:使用聚合的多播-AggregationStrategy调用太频繁,java,apache-camel,Java,Apache Camel,对于multi-cast+聚合,我有以下奇怪(或至少我不清楚)的行为。考虑以下路线: from("direct:multicaster") .multicast() .to("direct:A", "direct:B") .aggregationStrategy(new AggregationStrategy() {

对于multi-cast+聚合,我有以下奇怪(或至少我不清楚)的行为。考虑以下路线:

    from("direct:multicaster")
                .multicast()
                .to("direct:A", "direct:B")
                .aggregationStrategy(new AggregationStrategy() {
                    @Override
                    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
                        if (oldExchange == null) {
                            List firstResult = newExchange.getIn().getBody(List.class);
                            newExchange.getIn().setBody(ImmutableList.copyOf(firstResult));
                            return newExchange;
                        } else {
                            List oldResults = oldExchange.getIn().getBody(List.class);
                            List newResults = newExchange.getIn().getBody(List.class);
                            ImmutableList aggResult = ImmutableList.copyOf(Iterables.concat(oldResults, newResults));
                            oldExchange.getIn().setBody(aggResult);
                            return oldExchange;
                        }
                    }
                })
                .end()
//                .to("log:bla")
本质上,此路由接受输入,将其发送到
direct:A
direct:B
,期望来自这两个端点的列表并将它们连接起来(最后一行中的注释是出于我稍后将解释的原因)

现在假设这两个端点分别“返回”列表[A]和[B]。如果我将消息
M
发送到
direct:multicaster
,则聚合器将使用
oldchange=null
newExchange.in.body=[A]
调用一次,然后使用
oldchange.in.body=[A]
newExchange.out.body=[B]
(这是应该做的)

到目前为止一切都很好。但是使用
oldchange.in.body=[A,B]
newExchange.in=M
再次调用聚合器(
M
是初始消息)。这看起来类似于包含的扩展模式

您可以通过删除最后一行中的注释来获得预期的行为,即只需向(“log:bla”)添加一个伪
。在这种情况下,一切都按预期进行

更新:尝试(参见克劳斯提供的提示) 及

两者导致相同的行为

这里发生了什么-我做错了什么

提前谢谢
马库斯

我试图重现这个问题,但没有成功。这就是我所做的:

路线:

public class MulticastRoute extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        AggregationStrategy myAggregationStrategy = new MyAggregationStrategy();
        List<String> listA = Lists.newArrayList("A");
        List<String> listB = Lists.newArrayList("B");
        from("direct:multicast").routeId("multicastRoute").multicast(myAggregationStrategy).to("direct:A", "direct:B").end();

        from("direct:A").setBody(constant(listA));
        from("direct:B").setBody(constant(listB));
    }

    class MyAggregationStrategy implements AggregationStrategy {
        @Override
        public org.apache.camel.Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
            System.out.println("Aggregate called with oldExchange = " + (oldExchange == null ? "null" :
                    oldExchange.getIn().getBody().toString()) + ", newExchange = " +
                    newExchange.getIn().getBody().toString());
            return newExchange;
        }
    }
}
public class MulticastRouteTest extends CamelTestSupport {
  @Test
    public void testMulticastRoute() throws Exception {
        context.addRoutes(new MulticastRoute());
        template.sendBody("direct:multicast", null);
    }
}
这张照片是:

Aggregate called with oldExchange = null, newExchange = [A]
Aggregate called with oldExchange = [A], newExchange = [B]

这是我们所期望的。希望这对你有帮助。我看不出我做事的方式有什么不同,但希望你能发现。

我也有同样的问题。两件事似乎至关重要

  • 将AggregationStrategy before设置为(我会直接将其设置为多播的参数)
  • 使用“end()”结束多播

我认为,如果查看每个节点的返回类型,您可以看到差异。原因是聚合策略是跨不同对象实例的共享代码块。因此,无论何时创建实例,差异都会显现出来。

在toHi Claus之前,你应该有aggregationStrategy,我添加了两个新版本,我尝试了你的提示,但仍然得到了相同的行为-这里一定缺少一些东西。你使用的是哪一个版本的camel?您确定粘贴到问题中的代码与正在运行的代码完全相同吗?我不能复制这种行为。我sondrewe,我用的是2.11.1;我将尝试使用最新版本,如果仍然失败,我将提取完整(最小)示例我将创建一个显示完整示例的自包含示例(这是一个测试设置):。有两条重要的线需要查看:第91行和推荐的日志端点,以及第45行,我在其中编织了一个模拟端点,以使测试成为可能。删除第45行中的weaveAddLast()似乎可行,但无法对其进行测试。
public class MulticastRouteTest extends CamelTestSupport {
  @Test
    public void testMulticastRoute() throws Exception {
        context.addRoutes(new MulticastRoute());
        template.sendBody("direct:multicast", null);
    }
}
Aggregate called with oldExchange = null, newExchange = [A]
Aggregate called with oldExchange = [A], newExchange = [B]