Split a List of Lists with camel splitter

Tags: , , , ,



I have many ArrayLists created to hold the collections of separate entities to be split in to their own entities. these are added to an ArrayList then pushed to the exchange where I try to split the List of Lists. I can’t seem to split a list of lists.

Tried many variations of the Splitter, with tokens, etc.

List<String> serviceRecords = new ArrayList<String>();  //holds an assets collection
List<String> toRecords = new ArrayList<String>();       //holds all asset collections

after collecting the items belonging to a group, they are added to an ArrayList.

serviceRecords.add(sb.toString());

after all the items have been added, the list is then added to a List.

toRecords.addAll(serviceRecords);

I then push the List to the exchange

exchange.getIn().setBody(toRecords);

Then the XML route, it’s in disarray trying different things. none of which work. there must be a trick to splitting an List of Lists.

    <route autoStartup="true" id="core.fleet.asset.splitterRoute">
        <from id="_from4" uri="{{fileEnrichmentEndpoint}}"/>
        <process id="_process4" ref="assetCollectorProcessor"/>
        <process id="_process5" ref="fleetAssetSplitter"/>
        <split id="FleetSplit">    <!-- strategyRef="tsAggregationStrategy" -->
        <!-- <simple>${body}</simple> -->
        <tokenize token="BLOCKMarker"/>
          <log id="splitBody" message="Split Body: ${body}"/>
          <to id="_splitOut" uri="{{fileSplitDestination}}/?fileName=GCMS_asset_${date:now:yyyyMMddhhmmss}.csv"/>
          <!-- <process id="getName" ref="fleetAssetFileName"/> -->
          <!-- <to id="_splitOut" uri="{{fileSplitDestination}}/?fileName=GCMS_asset_${date:now:yyyyMMdd}.csv"/> -->
        </split>
        <!-- <to id="_splitOut" uri="{{fileSplitDestination}}/?fileName=GCMS_asset_${date:now:yyyyMMdd}.csv"/> -->
        <stop/>
    </route>

multiple files generated from the splitting of the List of Lists.

Answer

I don’t know weather to delete this or leave for others interests.
After discovering that I was using the wrong List method, List.addAll() instead of List.add(object) and made this correction, my bad, Amazingly, everything works as expected theoretical expectations with everything in its realm, it works.

so it is quite simple. you don’t need to do anything special to split a list of lists. the splitter will iterate over the List and split out the individual Lists. you can then take hold of these lists and process them and forward them on. Silly of me to think the mature Camel Splitter EIP was acting weird, it is doing exactly what it should be.

this is the end result. ( thanks to burki and others for your help )

    <route autoStartup="true" id="core.fleet.asset.splitterRoute">
        <from id="_from4" uri="{{fileEnrichmentEndpoint}}"/>
        <process id="_process4" ref="assetCollectorProcessor"/>
        <process id="_process5" ref="fleetAssetSplitter"/>
        <split id="fs1">
            <simple>${body}</simple>
            <log id="lfs1" message="Original Body: ${body}"/>
            <process id="pfs1" ref="fileSplitter" />
            <to id="seda:fs1" uri="seda:fs1"/>
        </split>
    </route>

I hide the file name inside the inner lists list on position -0- so we just extract the fileName, set CamelFileName, massage the data a little and send it to the exchange.

    log.info("File Splitter :: Start");

    List<String> pl = (List<String>) exchange.getIn().getBody(List.class);
    log.info("File Pay Load: " + pl);

    fName = pl.get(0);  //get file name
    exchange.getIn().setHeader("CamelFileName", fName);
    pl.remove(0);
    log.debug("**** serviceRecords  ****");
    Iterator<String> pitr = pl.iterator(); 
    while ( pitr.hasNext()) {
          log.debug(pitr.next());
      }
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream out = new DataOutputStream(baos);
    for (String record : pl) {
        out.writeBytes(record + System.lineSeparator());
    }
    out.flush();
    exchange.getIn().setBody(baos.toByteArray());
    out.close();

    log.info("File Splitter :: Finish");


Source: stackoverflow