我有一条路线,当推出时,请求来自两个数据源(routeA和routeB)的消息,并将它们聚合成一条消息。每个聚合消息必须包含一个routeA消息和一个routeB消息,如果没有,则删除它。
此过程必须按特定时间间隔启动(即:每5分钟一次)。
我的问题是,我怎样才能让聚合器知道来自routeA和routeB的所有处理过的消息以及没有找到它们的消息的消息都必须下载?
我目前正在使用 completionTimeout 功能,但出于显而易见的原因,我不喜欢这种解决方案。
我知道camel有一个 completionFromBatchConsumer 功能,但我不知道如何将它与多个数据集一起使用。
对任何建议都很满意。
这就是我现在所拥有的:
<!-- main route -->
<route id="main">
<camel:from uri="timer://timer1?period=20000"/>
<multicast>
<to uri="direct:startA"/>
<to uri="direct:startB"/>
</multicast>
</route>
<!-- messages from route A -->
<route id="routeA" />
<from uri="direct:startA" />
<to uri="sql:select * from sampleDB?dataSource=ds"/>
<split>
<simple>${body}<simple>
<marshal ref="ObjectAJsonConverter"/>
<unmarshal ref="ObjectAJsonConverter"/>
<to uri="bean:myProcessor?method=addObjectACorrelationKey"/>
<to uri="seda:myAggregator"/>
</split>
<!-- messages from route B -->
<route id="routeB" />
<from uri="direct:startB"/>
<to uri="ldap:ldapcontext?base=DC=company,DC=net"/>
<split>
<simple>${body}<simple>
<marshal ref="ObjectBJsonConverter"/>
<unmarshal ref="ObjectBJsonConverter"/>
<to uri="bean:myProcessor?method=addObjectBCorrelationKey"/>
<to uri="seda:myAggregator"/>
</split>
<!-- aggregate the messages, create new ObjectC that contains ObjectA and ObjectB -->
<!-- wait 200000 ms for all messages from routeA and routeB to enter the aggregator -->
<route id="aggretatorRoute">
<from uri="seda:myAggregator"/>
<aggregate ref="myEntityAggregator" completionSize="2" completionTimeout="200000" discartOnCompletionTimeout="true" ignoreInvalidCorrelationKeys="true">
<correlationExpression><simple>${in.header.objectid}</simple></correlationExpression>
<to uri="bean:myProcessor?method=doSomethingWithObjectC"/>
</aggregate>
答案 0 :(得分:0)
您只能在AggregationStrategy
中聚合ObjectA和ObjectB中的一个。因此,如果您看到其中任何一个中的第二个,那么就不要聚合它。如果你想放弃到目前为止所做的事情,那么你可以通过设置
exchange.setProperty("CamelRouteStop", true);
如果你想立即删除它,那么添加一个completionPredicate,检查是否已设置该停止。
<completionPredicate><simple>${property.CamelRouteStop} == true</simple></completionPredicate>
对于correlationExpression,您可能只使用<constant>true</constant>
,因为它似乎只适用于一个组。
答案 1 :(得分:0)
谢谢克劳斯。实际上我采取了不同的方法。而是使用聚合器来连接三个不同的对象,我现在查询一个id列表并使用它们逐步构建我的复杂对象。
<route id="composeObject">
<from uri="sql:select id from people?oneSource">
<split><simple>${body}</simple>
<to uri="direct:getobjectOne"/>;
<to uri="bean:addToComplexObject"/>
<to uri="direct:getObjectTwo/>
<to uri="bean:addToComplexObject"/>
<to uri="direct:getobjectThree/>
<to uri="bean:addToComplexObject"/>
<to uri="seda:outChannel"/>
</split>
</route>