骆驼聚合策略

时间:2014-10-13 18:43:17

标签: java apache-camel

我正在解析一个CSV文件,将其拆分并通过camel中的多个处理器进行路由。有两个端点,一个具有错误数据,另一个端点具有验证数据。

我需要汇总数据的建议。

让我们说CSV文件有10条记录,其中6条记录到达一个端点,而4条记录到达另一个端点。如何知道是否所有10个文件都已从每个端点的文件中完成并超过聚合器。 我需要创建两个文件,一个包含有效数据,另一个包含来自单个文件的损坏数据。

1 个答案:

答案 0 :(得分:9)

让我们看看拆分器返回的内容。

根据Camel 2.2的文档。或者更早,拆分器将默认使用您的示例返回最后一条拆分消息,这可能是完成其处理器的最后一行,因此它可能不是第10行(使用您的示例)。

在Camel 2.3和更新版本上,分割器默认返回原始输入消息,即全部10行。这是默认行为,您无需编写任何代码即可实现此功能。默认情况下,当拆分器完成时,它会将此消息传递给下一个端点。

所以如果我在Camel 2.3或更新版本上使用以下DSL:

<camelContext trace="false" id="blueprintContext" xmlns="http://camel.apache.org/schema/blueprint">
<route id="splitExample">
    <from uri="timer://myTimer?period=2000"/>
    <setBody>
        <simple>A\nB\nC</simple>

    </setBody>

    <log message="The message body before the splitter contains ${body}"/>
    <split>
        <tokenize token="\n"></tokenize>

        <log message="Split line ${body}"/>
    </split>
    <log message="The message body after the splitter contains ${body}"/>
</route>
</camelContext>  

以下内容将出现在日志中:

 INFO  The message body before the splitter contains 
       A
       B
       C
 INFO  Split line A
 INFO  Split line B
 INFO  Split line C
 INFO  The message body after the splitter contains 
       A
       B
       C

正如您所看到的,默认情况下,camel会在拆分器返回后将消息组合回一个消息。要覆盖此行为,您需要实现自己的聚合器。为此,创建一个类,让我们调用它MyAggregationStrategy并使类实现AggregationStrategy。我在here的apache文档中使用了该示例。例如,我们会汇总收到的出价,并希望汇总最高出价。

private static class MyAggregationStrategy implements AggregationStrategy {

    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) 
    {
        if (oldExchange == null) 
        { 
           // the first time we only have the new exchange so it wins the first round
           return newExchange;
        }
        int oldPrice = oldExchange.getIn().getBody(Integer.class);
        int newPrice = newExchange.getIn().getBody(Integer.class);
        // return the "winner" that has the highest price
        return newPrice > oldPrice ? newExchange : oldExchange;
    }
}

完成此操作后,您可以通过执行以下操作告诉拆分器使用您的聚合器:

Spring / XML DSL:

<split  strategyRef="MyAggregationStrategy ">

在Java中:

from("direct:start")
// aggregated by header id and use our own strategy how to aggregate
.aggregate(new MyAggregationStrategy())

希望这能让您充分了解分离器的工作原理。在你的情况下,我可能会为每一行设置一个标题值,表明它是成功还是失败,然后我会使用我的客户聚合器创建一个失败的新消息,并将成功分组为两个列表作为消息正文。一个列表包含失败,一个列表包含已完成的订单项。

然后,可以将此新聚合消息发送到处理器或其他端点以进行进一步处理。例如,您可以获取失败的列表并将其发送到生成文件的路由。 seda组件在这里可以提供很多帮助。