After upgrading from Apache Camel 2.x to 3.7.2 in our Java 11 project we experience some crudities in a route configuration class, extending the RouteBuilder
(Documentation) class. With Camel 2 I used the SimpleExpression ${property[" Exchange.GROUPED_EXCHANGE "]}
, which has now been renamed in Camel 3.x to exchangeProperty
(Migration Guide). So far, so good.
@Override
public void configure() throws Exception {
final SimpleExpression documentAppendix =
new SimpleExpression("${body.appendix}");
final SimpleExpression groupedExchanges =
new SimpleExpression("${exchangeProperty[" Exchange.GROUPED_EXCHANGE "]}");
from("direct://input")
.choice()
.when(documentAppendix)
.split(documentAppendix, new GroupedExchangeAggregationStrategy())
.to("direct://input.splitted")
.end()
.setBody(groupedExchanges)
.endChoice()
.otherwise()
.setBody(constant(Lists.newArrayList()))
.end();
// ... omitted
}
After running the tests, everything failed because the body did not contain the expected number of appendices. At first, we thought there might be a problem with exchangeProperty
but after some time spent with the debugger we've found out the following trail where the property gets "lost":
GroupedExchangeAggregationStrategy
|
v
AbstractListAggregationStrategy
(This class sets the "CamelGroupedExchange" property!)
|
v
AggregateProcessor
doAggregation(...)
ExchangeHelper.preparteAggregation(...)
The expected return after aggregation should be a list of objects, accessible via the CamelGroupedExchange
or ${exchangeProperty[" Exchange.GROUPED_EXCHANGE "]}
but it gets overridden with the newExchange
in ExchangeHelper.preparteAggregation
.
As we did not find more evidence, could someone explain this weird behaviour after upgrading Camel to 3.7.2? Maybe there have been breaking changes in ExchangeHelper and the available ExchangePattern/MEP Pattern (CAMEL-13286) but we were not able to break down the issue.
Thanks for your help guys!
CodePudding user response:
We figured out that the AbstractListAggregationStrategy
in Camel 3.7.2 now sets the property as In
body on completion:
public abstract class AbstractListAggregationStrategy<V> implements AggregationStrategy {
public AbstractListAggregationStrategy() {
}
public abstract V getValue(Exchange exchange);
public boolean isStoreAsBodyOnCompletion() {
return true;
}
public void onCompletion(Exchange exchange) {
if (exchange != null && this.isStoreAsBodyOnCompletion()) {
List<V> list = (List)exchange.removeProperty("CamelGroupedExchange");
if (list != null) {
exchange.getIn().setBody(list);
}
}
}
// omitted
}
With this change our .setBody(groupedExchanges)
is redundant and we are able to access the list of exchanges via getIn()
.