5

I have to call a service for each element of an array B. but Array A is inside Array A. So I am trying to use split inside split as below in camel_Context.xml. Once the all inner split array value are executed, I need to aggregate them as well.

<split>
    <jsonpath>$.Request.Fruits</jsonpath>
    <split>
        <jsonpath>$.request.Fruits[index].item</jsonpath>

        <to someURI>
    </split>
</split> 

The index I have used in the inner split should say the current iteration of outer split. CamelSplitIndex will give you the iteration number of inner split. I am not sure how to use any explicit counter in the outer split. Is there any other way to achieve my goal please?

Alessandro Da Rugna
  • 4,571
  • 20
  • 40
  • 64
Jay
  • 79
  • 2
  • 11

2 Answers2

5

You can set a custom header

<split>
    <jsonpath>$.Request.Fruits</jsonpath>
    <setHeader headerName="OuterIndex">
        <simple>${header.CamelSplitIndex}</simple>
    </setHeader>
    <split strategyRef="aggregatorBean">
        <jsonpath>$.request.Fruits[index].item</jsonpath>
        <setHeader headerName="InnerIndex">
            <simple>${header.CamelSplitIndex}</simple>
        </setHeader>
        <to someURI>
        <log message="Hello from inner ${header.InnerIndex} of outer ${header.OuterIndex}" />
    </split>
</split>

You can use a bean as an AggregationStrategy to aggregate results using your logic (see Splitter pattern page for more details). In such strategy you can read both headers if required.

Mind that each <split> will automatically iterate over your array, much like java enhanced for, so imagine the route doing roughly as follows:

// <split> is very much like
for (Fruit f : request.getFruits()) {
    // outer loop
    for (Item i : f.getItems() {
        // inner loop, <to someURI> is located here
    }
}
Alessandro Da Rugna
  • 4,571
  • 20
  • 40
  • 64
  • Thank you . but the input to the inner split is coming as class java.util.LinkedHashMap. Is there any way to parse LikedHashMap in a route(like jsonpath) – Jay Nov 18 '16 at 10:04
  • I would either transform to a POJO http://camel.apache.org/json.html or use a processor https://camel.apache.org/processor.html , this depends on what the route actually does. – Alessandro Da Rugna Nov 18 '16 at 10:14
1

Actually when you split you get individual entries of your split array as the body inside the split portion and so you should be able to use it as below and as mentioned by @Alessandro you can use an aggregation strategy to aggregate the split entries how-to-implement-the-splitter-and-aggregator-patterns-with-apache-camel

<split>
    <jsonpath>$.Request.Fruits</jsonpath>
    <split strategyRef="aggregatorBean">
        <jsonpath>$.item</jsonpath> <!-- your body here itself is a Fruit-->
        <to someURI>
    </split>
</split>
Community
  • 1
  • 1
Sagar
  • 818
  • 1
  • 6
  • 13
  • Thank you sagar.. it helped me to understand better.. only thing is,since it is a json data, the output of outer splitter is in the LinkEdHashMap format. I have to use a bean to convert it to json again. – Jay Nov 18 '16 at 11:54