我实际上想要一个flush或completionSize,但是对于聚合器中的所有聚合。就像全球的完成大小一样。
基本上我想确保聚合中的每条消息都被聚合,然后在读取最后一条消息时立即完成该聚合器中的所有聚合。
e.g. 1000 messages arrive (the length is not known beforehand)
aggregate on correlation id into bins
A 300
B 400
C 300 (size of the bins is not known before hand)
I want the aggregator not to complete until the 1000th exchange is aggregated
thereupon I want all of the aggregations in the aggregator to complete at once
不幸的是,CompleteSize适用于每个聚合,而不是整个聚合器。因此,如果我设置CompleteSize(1000),它将永远不会完成,因为每个聚合在“完成”之前必须超过1000
我可以通过构建一个Map对象来绕过它,但这有点回避了aggregateator2中的相关性,我更倾向于理想地使用
所以是的,无论是全局大小还是冲洗,有没有办法聪明地做到这一点?
答案 0 :(得分:3)
一个选项是简单地添加一些逻辑来保留全局计数器,并在达到Exchange.AGGREGATION_COMPLETE_ALL_GROUPS
标题后设置它......
自Camel 2.9起可用...您可以通过发送包含标题Exchange.AGGREGATION_COMPLETE_ALL_GROUPS设置为true的消息来手动完成所有当前聚合的交换。该消息仅被视为信号消息,否则将不处理消息标题/内容。
答案 1 :(得分:0)
我建议您查看Camel聚合器eip doc http://camel.apache.org/aggregator2,并阅读有关不同完成条件的信息。此外,Ben提到的特殊信息可以发送信号以完成所有飞行中的聚合。
如果您从批量消费者http://camel.apache.org/batch-consumer.html消费,那么您可以使用特殊完成,在批次完成时完成。例如,如果您从JPA数据库表等中拾取文件或行。然后,当批处理使用者的所有消息都已处理完毕后,聚合器可以使用completionFromBatchConsumer选项发出所有这些聚合消息的完成信号。
此外,如果你有一本Camel in Action书的副本,那么请阅读第8章第8.2节,因为它涉及更多细节所涵盖的聚合EIP。
答案 2 :(得分:0)
使用Exchange.AGGREGATION_COMPLETE_ALL_GROUPS_INCLUSIVE为我工作:
from(endpoint)
.unmarshal(csvFormat)
.split(body())
.bean(CsvProcessor())
.choice()
// If all messages are processed,
// flush the aggregation
.`when`(simple("\${property.CamelSplitComplete}"))
.setHeader(Exchange.AGGREGATION_COMPLETE_ALL_GROUPS_INCLUSIVE, constant(true))
.end()
.aggregate(simple("\${body.trackingKey}"),
AggregationStrategies.bean(OrderAggregationStrategy()))
.completionTimeout(10000)