Apache Camel:到同一路线的几条路线

时间:2016-02-22 14:52:19

标签: apache-camel

我想将来自更多路由的消息路由到同一路由,但它不会按照我的假设工作。我设置了以下内容(我只是放下了本质):

from("direct:a") [...]
    .to("direct:c");

from("direct:b") [...]
    .to("direct:c");

from(direct:c) <my aggregator functionality comes here>
    .to("direct:someOtherRoute");

然而,这只适用于“a”或“b”恰好一条路线转到“c”而不是两条路线的情况。 如何将“a”和“b”都路由到“c”?谢谢。

EDIT1:

我尝试了Alexey的解决方案,但使用“seda”或“vm”并没有解决问题。实际上,无论使用seda还是vm调用路由“c”,聚合器只能从路由“a”或路由“b”调用一次。

但是,如果我创建具有相同内容和路线的另一条路线“c2”,例如“b”到“c2”,然后就可以了。然而,解决它并不是一个很好的方法。

你有任何进一步的想法吗?我在同一个CamelContext中使用路由,因此在同一个JVM中。

我还在链接http://camel.apache.org/seda.html上发现了一个有趣的评论 它表示,Alexey和Sunar还告诉seda和vm是异步和直接同步的,但你也可以直接实现异步功能,如下所示:

from("direct:stageName").thread(5).process(...)

"[...] Instead, you might wish to configure a Direct endpoint with a thread pool, which can process messages both synchronously and asynchronously. [...]

我也测试了它,但在我的情况下,它没有产生任何成果。

EDIT2:

我在这里添加了如何使用聚合器,即在此示例中路由“c”:

from("vm:AGGREGATOR").routeId("AGGREGATOR")
        .aggregate( constant("AGG"), new RecordAggregator())
        .completionTimeout(AGGREGATOR_TIMEOUT)
        .process(new Processor() {
            public void process(Exchange exchange) throws Exception {
                LOGGER.info("### Process AGGREGATOR");
                [...]
             }
        })
        .marshal().csv()//.tracing()
        .to("file:extract?fileName=${in.header.AGG}.csv")
        .end();

在日志中,字符串“### Process Aggregator”仅出现一次。我只是想知道它是否不能依赖我正在使用的 .completionTimeout(AGGREGATOR_TIMEOUT)。在我的未完成版本中,应该在此时间内为标题中的每个不同AGG值创建一个文件。这种理解是否正确?

2 个答案:

答案 0 :(得分:1)

我认为使用异步组件,例如 seda vm activemq 可能会解决您的问题。

此类行为直接组件,因为 direct 是同步组件,这也可能与在第三条路线中使用聚合器有关。

示例:

from("direct:a") [...]
    .to("seda:c");

from("direct:b") [...]
    .to("seda:c");

from(seda:c) <your aggregator functionality comes here>
    .to("direct:someOtherRoute");

<强> EDIT1:

现在,当我看到一个聚合器时,我认为这就是完成标准中的问题。

在您的情况下,您必须使用correlationExpression的表达式:

from("vm:AGGREGATOR").routeId("AGGREGATOR")
    .aggregate().simple("${header.AGG}",String.class) // ${property.AGG}
        .aggregationStrategy(new RecordAggregator())
        .completionInterval(AGGREGATOR_TIMEOUT) //.completionTimeout(AGGREGATOR_TIMEOUT)
        .forceCompletionOnStop()
        .process(new Processor() {
            public void process(Exchange exchange) throws Exception {
                LOGGER.info("### Process AGGREGATOR");
                [...]
             }
        })
        .marshal().csv()//.tracing()
        .to("file:extract?fileName=${in.header.AGG}.csv&fileExist=Override")
    .end();

,也许completionTimeout太低了......

答案 1 :(得分:1)

试试下面的内容,这只是一个示例     从(&#34;计时器:FOO repeatCount = 1&安培;延迟= 1000&#34)。路由ID(&#34; firstroute&#34)                 .setBody(简单(&#34;孙大信&#34))至(&#34;直接:一个&#34);

    from("timer:foo1?repeatCount=1&delay=1000").routeId("secondRoute")
            .setBody(simple("sundar1")).to("direct:a");

    from("direct:a")
            .aggregate(new AggregationStrategy() {

                @Override
                public Exchange aggregate(Exchange arg0, Exchange arg1) {
                    Exchange argReturn = null;
                    if (arg0 == null) {
                        argReturn= arg1;
                    }
                    if (arg1 == null) {
                        argReturn= arg0;
                    }
                    if (arg1 != null && arg0 != null) {
                        try {
                            String arg1Str = arg1.getIn()
                                    .getMandatoryBody().toString();
                            String arg2Str = arg0.getIn()
                                    .getMandatoryBody().toString();
                            arg1.getIn().setBody(arg1Str + arg2Str);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        argReturn= arg1;
                    }
                    return argReturn;
                }
            }).constant(true).completionSize(2)
            .to("direct:b").end();

    from("direct:b").to("log:sundarLog?showAll=true&multiline=true");

您可以使用Yakunin指出的seda或其他异步路由。在这里使用聚合器主要争用点是completionSize,其中我使用了2,因为两条路由正在消息中发送。