我正在寻找一种基于消息聚合来有条件地处理消息的方法。我已经研究了很多方法,但似乎Apache Camel不支持它。我将解释这个场景,然后解释我尝试的解决方案。
方案: 我正在尝试有条件地清理目录。我每隔x天从目录轮询并获取所有文件(file:// ...)。我将其路由到聚合,聚合将文件聚合为单个大小(directorySize)。然后我检查这个大小是否超过了某个阈值。
这就是问题所在。我现在想要删除某些文件,如果这个条件通过,但我不再访问原始邮件,因为它们是在新的交换中聚合的。
解决方案:
我认为的事情:
我有点震惊,你不能根据这些消息的聚合优雅地过滤消息。我在Camel中错过了一些可以提供优雅解决方案的东西吗?或者这是最不好的解决方案?
信息(文件)
消息(文件) - > AggregatedMessage(directorySize) - >删除某些文件?
信息(文件)
答案 0 :(得分:1)
Camel非常棒,但有时很难确切地看到使用哪种设计模式;)
首先,您需要保留文件对象的副本,因为在达到阈值之前您不知道是否删除它们 - 基本上(至少)有两种方法可以执行此操作。
备选方案1
第一种方法是在交换属性中使用List
。无论您使用交换 body 做什么,此属性都会出现。如果你看一下GroupedExchangeAggregationStrategy
的源代码,它就是这样做的:
list = new ArrayList<Exchange>();
answer.setProperty(Exchange.GROUPED_EXCHANGE, list);
// ...
list.add(newExchange);
或者您可以在自己的交易所属性上手动执行相同的操作。无论如何,像你一样使用Grouped聚合策略是完全没问题的。
备选方案2
“保留”旧邮件的第二种方法是将副本发送到已停止的SEDA
队列。所以你会做to("seda:xyz")
。您将此队列定义为.noAutoStartup()
。然后你可以向它发送消息,他们将在由camel管理的内部队列中排队。当您想要处理消息时,只需通过controlbus启动它,然后再将其停止。
一般情况下,除非绝对必要,否则应该避免乱跑和停止队列,但这当然是另一种方法
建议的解决方案
我建议你照你所做的那样做(即替代方案1):
aggregate
通过GroupedExchangeAggregationStrategy将各个文件保存在列表中filter(simple("${body} < 123"))
splitter(simple("${property.CamelGroupedExchange}"))
请告诉我这是否有意义,或者我是否以任何方式误解了您的问题。