1

I want to use apache camel to call an external REST service multiple times. After all calls complete, I want to aggregate the results. I know I can perform one call with camel as defined in camel FAQ like so:

protected RouteBuilder createRouteBuilder() throws Exception {
    return new RouteBuilder() {
        @Override
        public void configure() throws Exception {
            rest("/say")
                .get("/sample").to("direct:hello")
                .toD("placeIwantToCall")
        }
    };
}

But I do not know how I can call it multiple times.

Goal: The number of times I need to call this external rest service differs over time. ( Sometimes it is 1, sometimes it is 10, etc. I will however, know this number as I can read it from the incoming header ) Once all calls complete, I want to aggregate all of the results into one big result. How can I do this in Apache Camel? ( The solution from this question : Apache camel to aggregate multiple REST service responses : can probably be used here, but I am having a hard time wrapping my head around how I'd use it.

angryip
  • 2,140
  • 5
  • 33
  • 67
  • Create a list of rest calls send the list to a splitter and it will aggregate responses back. Since you know the amount of items in the list beforehand this should be simple. – Namphibian Feb 13 '19 at 21:45
  • Do you need to call the same rest endpoint multiple times, or different endpoints? – fg78nc Feb 14 '19 at 13:26
  • Please see my proposed solution below. – fg78nc Feb 14 '19 at 14:44
  • @fg78nc same endpoint, multiple times, and aggregate results. taking a look at your code now to understand it. – angryip Feb 14 '19 at 15:32

2 Answers2

0

You can also use a timer component to invoke the route several times. Set repeatCount to the desired value. You can store the results in a global list (with the help of Spring DI)

VarunKrish
  • 179
  • 1
  • 9
0

Possible solution: Required dependencies : camel-core, camel-http4, camel-test, slf4j, log4j

import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.invoke.MethodHandles;

public class RestMultiAggregation extends CamelTestSupport {

    Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    @Override
    protected RoutesBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("direct:start")
                        .setHeader("CamelHttpMethod", constant("GET"))
                        .loop(body())
                        .enrich("https4://cat-fact.herokuapp.com/facts/random",
                                (oldExchange, newExchange) -> {
                                    if (newExchange == null) {
                                        return oldExchange;
                                    }
                                    String prev = oldExchange.getIn().getBody(String.class);
                                    String curr = newExchange.getIn().getBody(String.class);
                                    String body = prev + "\n" + curr;
                                    oldExchange.getIn().setBody(body);
                                    return oldExchange;
                                })
                        .end()
                        .to("mock:result");
            }
        };
    }

    @Test
    public void testMultipleRestCalls() throws InterruptedException {
        MockEndpoint mock = getMockEndpoint("mock:result");
        mock.expectedMessageCount(1);
        template.sendBody("direct:start", "3");
        String aggregatedResponse = mock.getExchanges().get(0).getIn().getBody(String.class);
        log.info("Aggregated response: {}", aggregatedResponse);
        assertMockEndpointsSatisfied();
    }
}
fg78nc
  • 4,774
  • 3
  • 19
  • 32