1

I am curious how I can manage the HTTP REST requests in Apache Camel?

I need to iterate through the list of IDs and place the particular ID from the list in HTTP GET request. This list I would receive from a database. I need to send request to third party server and manage the response - insert it into DB.

How can I plan the ID parameter in the request within loop?

@Component
    public class EgrRegistryNumbersRoute
          extends RouteBuilder {
        private final JacksonDataFormat format = new ListJacksonDataFormat(NumbersDTO.class);
        @Autowired
        DataSource dataSource;

List myList = List.of(1, 2, 3, 4, 5);
        
        @Override
        public void configure() throws Exception {
            from("timer://foo?repeatCount=1")
                  .noAutoStartup()
                  .setHeader(Exchange.HTTP_METHOD, constant("GET"))
                  .to("http://server/api/v2/getRegNumByState/**{HERE I WANT VALUE FROM THE LIST}**")
                  .unmarshal(format)
                  .routeId("NumbersRoute-route")
                  .log(">>>${body}")
                  .process(new InsertProcessor("table_name", "column"))
                  .to("jdbc:dataSource");
        }
    }

Processor:

public class InsertProcessor
      implements Processor {
    private final String tableName;
    private final String columns;
    
    public InsertProcessor(String tableName, String columns) {
        this.tableName = tableName;
        this.columns = columns;
    }
    
    @Override
    public void process(Exchange exchange) throws Exception {
        List<NumbersDTO> inputList = exchange.getIn().getBody(List.class);
        StringBuilder queryBuilder = new StringBuilder("INSERT INTO " + tableName + "(" + columns + ") values ");
        System.out.println("Input to be persisted : " + inputList);
        
        inputList.forEach(v -> {
            queryBuilder.append("(").append(v.getNgrn()).append("),");
        });
        String insertQuery = queryBuilder.toString().replaceFirst(".$","");
        System.out.println("Insert Query is : " + insertQuery);
        exchange.getIn().setBody(insertQuery);
    }
}

1 Answers1

2

You can achieve this using split and by switching to to toD when defining your http producer endpoint. With toD you can use simple language with the URI.

from("direct:queryRestWithURI")
    .setBody(constant(myList))
    .split(body())
        .toD("http://server/api/v2/getRegNumByState/${body}")
        //do stuff
    .end();

If you don't want to use splitter you can use loop as well to loop through the list.

from("direct:queryRestWithURI")
    .routeId("NumbersRoute-route")
    .setBody(constant(myList))
    .loop(simple("${body.size()}"))
        .setHeader("loopItem", simple("${body[${exchangeProperty.CamelLoopIndex}]}"))
        .toD("http://server/api/v2/getRegNumByState/${headers.loopItem}")
        // do stuff
    .end();
Pasi Österman
  • 2,002
  • 1
  • 6
  • 13
  • Hello @pasi-Österman Thanks for your answer. Got the following error in first case: No type converter available to convert from type: org.springframework.util.LinkedCaseInsensitiveMap to the required type: java.io.InputStream with value {id=9} Whole code: `from("sql:select id from egr_status where id in (11, 9)?repeatCount=1") .log(">>>SQL: ${body}") .split(body()) .toD("http://egr.gov.by/api/v2/egr/getRegNumByState/${body}") .setHeader(Exchange.HTTP_METHOD, constant("GET")) ` – Andrei Gavrilov Aug 10 '21 at 18:57
  • SQL component by default returns result as `List>` so `split(body())` will split it to individual `Map` instances. If the value you want to use in your URL is in the map you'll have to use something like `.toD("http://egr.gov.by/api/v2/egr/getRegNumByState/${body[columnKey]}")` instead. – Pasi Österman Aug 10 '21 at 19:28