TechGeek
TechGeek

Reputation: 508

How to make GET api call based on content of body using apache camel

My requirement is to make GET api call based on the content of the body I spitted from flat file.And aggregate the api response with original body and generate xml.

Input:

0150519821|0000000078|0000004892|US| .   
0150519822|0000000078|0000004896|US| .  
0150519824|0000000078|0000004893|US| .  
0150519826|0000000078|0000004898|US|

Based on the fourth position if it is "US" in input source. I have to make a GET api call to get response.

Example:

GET: return --> { "iD" : 1,"total" :23,"carrier" : "UPS" }

I have to generate XML which includes, fields which GET api returned along with input source.

Example Output:

<?xml version="1.0" encoding="UTF-8"?>

<TEST>
  <NUM>0150519821</NUM>
  <ID>0000000078</ID>
  <TOTAL>23</TOTAL>
  <CARRIER>UPS</CARRIER>
</TEST>

Above given xml output does have both fields from flat file and api response.I'm using apache camel bindy to do splitting and generate an xml. I have to make api call based on the content I'm splitting and aggregate the response which api returned and generate the output xml.

Here is the routing logic I have implemented, Please help me how to make api call and aggregate it.

ConverterRoute.java

 public class ConverterRoute implements RoutesBuilder {

        private Logger logger = LoggerFactory.getLogger(ConverterRoute.class);

        private static final String SOURCE_INPUT_PATH = "file://inbox?fileName=test.txt";

        private static final String SOURCE_OUTPUT_PATH = "file://outbox?fileName=file_$simple{date:now:yyyyMMddHHmmssSSS}.xml";

        BindyBeanConfig bindyBeanConfig = new BindyBeanConfig();

        @Override
        public void addRoutesToCamelContext(CamelContext context) throws Exception {

            context.addRoutes(new RouteBuilder() {
                public void configure() {
                    try {

from(SOURCE_INPUT_PATH)
    .split().tokenize(System.lineSeparator())
        .log("After Split input from file and body is ${body}")
        .choice()
            .when(method(MySplitterBean.class,"splitBody").isEqualTo("IN"))
                .unmarshal(bindyBeanConfig())
                .log("After Unmarshal and body is ${body}")
                .marshal()
                .log("After Marshalling and body is ${body}")
                .to(SOURCE_OUTPUT_PATH)
                .log("Finished Transformation")
            .when(method(MySplitterBean.class,"splitBody").isEqualTo("UK"))
                .unmarshal(bindyBeanConfig())
                .marshal()
                .log("After Marshalling and body is ${body}")
                .to(SOURCE_OUTPUT_PATH)
                .log("Finished Transformation")
            .when(method(MySplitterBean.class,"splitBody").isEqualTo("US"))
                .unmarshal(bindyBeanConfig())
                .log("Before Marshalling and body is ${body}")
                .setHeader(Exchange.HTTP_METHOD,constant("GET"))
                .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
                .to("http://localhost:8081/US")
                .process(exchange -> log.info("The response is: {}", exchange.getIn().getBody()))
                .marshal()
                .log("After Marshalling and body is ${body}")
                .to(SOURCE_OUTPUT_PATH)
                .log("Finished Transformation")
        .end();

                    } catch (Exception e) {
                        logger.info(e.getMessage());
                        e.printStackTrace();
                    }
                }
            });
            context.suspend();
            context.stop();
            }
    }

Logs:

 2020-01-03 10:20:29.339  INFO 57630 --- [ - file://inbox] route1                                   : Finished Transformation
    2020-01-03 10:20:29.339  INFO 57630 --- [ - file://inbox] route1                                   : Before making api call <?xml version="1.0" encoding="UTF-8"?>

    <TEST>
      <NUM>0150519821</NUM>
      <ID>0000000078</ID>
    </TEST>
    2020-01-03 10:20:29.459  INFO 57630 --- [ - file://inbox] c.s.l.routes.ConverterRoute$1     : The response code is: org.apache.camel.converter.stream.CachedOutputStream$WrappedInputStream@1a7ebbd1

I was able to generate the XML without new fields(TOTAL,CARRIER) which I'm getting from GET api call. I'm getting the Output stream object which I want to enrich the xml with new two fields so the xml looks as below.

Expected Output after adding new two fields from GET API call.

<?xml version="1.0" encoding="UTF-8"?>

<TEST>
  <NUM>0150519821</NUM>
  <ID>0000000078</ID>
  <TOTAL>23</TOTAL>
  <CARRIER>UPS</CARRIER>
</TEST> 

Upvotes: 0

Views: 665

Answers (1)

burki
burki

Reputation: 7005

So if I understand correctly, you already achieved to get this XML

<TEST>
    <NUM>0150519821</NUM>
    <ID>0000000078</ID>
</TEST>

but you need to enrich it with data from the API call to get this

<TEST>
    <NUM>0150519821</NUM>
    <ID>0000000078</ID>
    <TOTAL>23</TOTAL>
    <CARRIER>UPS</CARRIER>
</TEST>

You can for example use the Camel Enrich EIP. There is a nice example on this page.

In your case you could

  • externalize the API call to a dedicated route
  • call the new route from the main route to enrich the current message body with the API response

How the message bodies are merged is implemented in the aggregation strategy that is referenced in the enrich. You can use a POJO as aggregationStrategy, see linked example.

You can either directly enrich the XML body with the new data in the aggregation. Or you can keep the old message body and save the new data as message headers in the aggregation. Then you can enrich the XML body in an additional step. Whatever is more appropriate in your case.

.when(method(MySplitterBean.class,"splitBody").isEqualTo("US"))
    ...        
    .enrich("direct:getCarrierData", aggregationStrategy)
    ...;

from("direct:getCarrierData")
    .setHeader(Exchange.HTTP_METHOD,constant("GET"))
    .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
    .to("http://localhost:8081/US")

Upvotes: 1

Related Questions