I am new to Apache Camel and I would like to ask a few things. Basically, I want to call the API based on the resource ID list I have and combine all the responses from the API into one message. I have already tried AggregationStrategy, but it doesn't seem to be working. The message body always returns the last response from API and it doesn't keep the old list. I would be very grateful if you could give me some examples.
Route
from("file:C:\\Inbound")
//Get resourceID list and split it to call the API
.split(simple("${body}"))
.aggregationStrategy(new ArrayListAggregationStrategy())
.toD("{{api_url}}${body.resourceID}")
.log("After API call ${body}")
.end();
AggregationStrategy
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
Object newBody = newExchange.getIn().getBody();
ArrayList<Object> list = null;
if (oldExchange == null) {
list = new ArrayList<Object>();
list.add(newBody);
newExchange.getIn().setBody(list);
return newExchange;
} else {
list = oldExchange.getIn().getBody(ArrayList.class);
list.add(newBody);
return oldExchange;
}}}
Below you'll find a basic example how to implement .split
with AggregationStrategy
that returns a Java List
. It should be straightforward to apply to your specific scenario.
Routes.java
import org.apache.camel.builder.RouteBuilder;
public class Routes {
public static RouteBuilder routes() {
return
new RouteBuilder() {
public void configure() {
from("timer:mainRouteTrigger?repeatCount=1")
.routeId("MainRouteTrigger")
.setBody(constant("100\n200\n300"))
.to("direct:mainRoute")
.end()
;
from("direct:mainRoute")
.routeId("MainRoute")
.log("MainRoute BEGINS: BODY: ${body}")
.split(body().tokenize("\n"), new Aggregator())
.to("direct:singleRoute")
.end()
.log("MainRoute ENDS: BODY: ${body}")
.end()
;
from("direct:singleRoute")
.routeId("SingleRoute")
.log("SingleRoute BEGINS: BODY: ${body}")
.setBody(simple("this is a response for id ${body}"))
.log("SingleRoute ENDS: BODY: ${body}")
.end()
;
}
};
}
}
Aggregator.java
import org.apache.camel.AggregationStrategy;
import org.apache.camel.Exchange;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Aggregator implements AggregationStrategy {
@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
// first iteration
// oldExchange is null
// body of newExchange is String
if (oldExchange == null) {
List<String> newList = buildListFrom(newExchange);
newExchange.getMessage().setBody(newList, List.class);
return newExchange;
}
// second and subsequent iterations
// body of oldExchange is List<String>
// body of newExchange is String
List<String> oldList = oldExchange.getMessage().getBody(List.class);
List<String> newList = buildListFrom(newExchange);
List<String> combined = Stream.concat(oldList.stream(), newList.stream()).collect(Collectors.toList());
oldExchange.getMessage().setBody(combined);
return oldExchange;
}
private List<String> buildListFrom(Exchange exchange) {
String body = exchange.getMessage().getBody(String.class);
List<String> list = new ArrayList<String>();
list.add(body);
return list;
}
}
When executed the following expected outcome is logged:
AbstractCamelContext INFO Routes startup (total:3 started:3)
AbstractCamelContext INFO Started MainRouteTrigger (timer://mainRouteTrigger)
AbstractCamelContext INFO Started MainRoute (direct://mainRoute)
AbstractCamelContext INFO Started SingleRoute (direct://singleRoute)
AbstractCamelContext INFO Apache Camel 3.14.2 (camel-1) started in 133ms (build:14ms init:105ms start:14ms)
MainSupport INFO Waiting until complete: Duration max 5 seconds
MainRoute INFO MainRoute BEGINS: BODY: 100
200
300
SingleRoute INFO SingleRoute BEGINS: BODY: 100
SingleRoute INFO SingleRoute ENDS: BODY: this is a response for id 100
SingleRoute INFO SingleRoute BEGINS: BODY: 200
SingleRoute INFO SingleRoute ENDS: BODY: this is a response for id 200
SingleRoute INFO SingleRoute BEGINS: BODY: 300
SingleRoute INFO SingleRoute ENDS: BODY: this is a response for id 300
MainRoute INFO MainRoute ENDS: BODY: [this is a response for id 100, this is a response for id 200, this is a response for id 300]
MainSupport INFO Duration max seconds triggering shutdown of the JVM
AbstractCamelContext INFO Apache Camel 3.14.2 (camel-1) shutting down (timeout:45s)
AbstractCamelContext INFO Routes stopped (total:3 stopped:3)
AbstractCamelContext INFO Stopped SingleRoute (direct://singleRoute)
AbstractCamelContext INFO Stopped MainRoute (direct://mainRoute)
AbstractCamelContext INFO Stopped MainRouteTrigger (timer://mainRouteTrigger)
AbstractCamelContext INFO Apache Camel 3.14.2 (camel-1) shutdown in 34ms (uptime:5s54ms)
Note that
[this is a response for id 100, this is a response for id 200, this is a response for id 300]
Is a Java List
that has been converted to a string automatically by .log
.