如何将GroupedExchangeAggregationStrategy聚合交换拆分为原始交换?

时间:2019-04-09 17:22:00

标签: kotlin apache-camel spring-camel

使用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,但似乎不可能。

2 个答案:

答案 0 :(得分:1)

是的,GroupedExchangeAggregationStrategy除了创建所有java.util.ListExchanges之外没有做任何其他事情。另一方面,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()