使用GroupedExchangeAggregationStrategy
汇总交换后,我需要将它们拆分回去(以发出单独的处理时间指标)成原始交换。
我尝试了以下拆分,但生成的拆分交换包装了原始交换并将其放入Message
正文中。
是否可以在没有包装交换器的情况下将GroupedExchangeAggregationStrategy
聚合交换器拆分为原始交换器?我需要使用原始交换属性,并希望使用SpEL表达式。
.aggregate(constant(true), myGroupedExchangeAggregationStrategy)
.completionInterval(1000)
.completeAllOnStop()
.process { /* do stuff */ }
.split(exchangeProperty(Exchange.GROUPED_EXCHANGE))
.to(/* micrometer timer metric using SpEL expression */)
// ^- the resulting split exchange is wrapped in another exchange
如果当前不支持此功能,则我将尝试找出自己实现此行为的最佳方法,而无需为此单个功能创建自定义Splitter
处理器。我希望以某种方式覆盖进行包装的SplitterIterable
,但似乎不可能。
答案 0 :(得分:1)
是的,GroupedExchangeAggregationStrategy
除了创建所有java.util.List
的Exchanges之外没有做任何其他事情。另一方面,Splitter EIP默认情况下会将列表拆分为元素,然后将元素放入消息正文中。因此,您最终得到一个在其主体中包含Exchange 的Exchange。
您需要的是一个聚合策略,该策略收集列表中的所有正文对象,而不是所有交易所。
您可以尝试使用可通过流畅的API配置的骆驼FlexibleAggregationStrategy
。
new FlexibleAggregationStrategy() .storeInBody() .accumulateInCollection(ArrayList.class) .pick(new SimpleExpression(“ $ {body}”)));
这应该创建一个AggregationStrategy,以提取每条消息的主体(由于主体提取是pick的默认选择,因此您可以省略pick方法),将它们收集在List中并将聚合存储在消息主体中。
要再次拆分此聚合,一个简单的split(body())
就足够了。
是的,是的,我的解决方案的一个副作用是您丢失了原始邮件的属性和标头,因为它只聚合邮件正文。
您要执行的操作是将“ Exchange列表”拆分回原始文档。即拆分器不得创建新的Exchange,而应使用已经存在的交换器并丢弃聚合的包装器Exchange。
据我在source code of the Splitter中看到的,当前无法实现:
Exchange newExchange = ExchangeHelper.createCorrelatedCopy(copy, false);
...
if (part instanceof Message) {
newExchange.setIn((Message) part);
} else {
Message in = newExchange.getIn();
in.setBody(part);
}
答案 1 :(得分:0)
每个接受的答案似乎都不是本机支持的。
此自定义处理器将解包一个拆分交换(即,将嵌套交换Message
和属性复制到根交换)。展开后的交换将与原始交换几乎相同-它将保留根交换中所有不冲突的属性(例如,与Splitter
相关的属性,例如拆分索引等)>
class ExchangeUnwrapper : Processor {
override fun process(exchange: Exchange) {
val wrappedExchange = exchange.`in`.body as Exchange
ExchangeHelper.copyResultsPreservePattern(exchange, wrappedExchange)
}
}
// Route.kt
from(...)
.aggregate(...)
.process { /* do things with aggregate */ }
.split(exchangeProperty(Exchange.GROUPED_EXCHANGE))
.process(ExchangeUnwrapper())
.process { /* do something with the original exchange */ }
.end()