javaintegrationapache-camelsplitter

Apache Camel File Splitter by Example


I'm being given a file containing numeric IDs that are delimited by newlines ("\n"):

123948
939904
129384
234049

etc. I want to use Camel to transform the file into an instance of the following POJO:

public class IDFile {
    private String fileName;    // The name of the file
    private List<Long> ids;     // All the IDs in the file (123948, 939904, etc.)

    // Constructor, getters/setters, etc.
}

I'm trying to see if I can use Camel's Splitter component to do this form me, but it feels like I'm trying to force a round peg into a square hole:

<route>
    <from uri="file://input/idfile"/>
    <split streaming="true">
        <tokenize token="\n" />
        <to uri="bean://idfileProcessor?method=process"/>
    </split>
</route>

The above looks like it would split my file into a List<Long>, but I need the file name associated with the list as well. Any ideas?


Solution

  • There is a header "CamelFileName" on the exchange. Your processor/bean is passed a reference to the exchange and you can get the header from there and associate it with the token you have been invoked with.

    Your route could look like this:

    <camel:route id="splitter_test">
        <camel:from uri="file:///home/steppra1/camel_test?delete=true&amp;idempotent=true" />
        <camel:to uri="bean:splitBean?method=init" />
        <camel:split streaming="true">
            <camel:tokenize token="\n" />
            <camel:to uri="bean:splitBean?method=addToken" />
        </camel:split>
        <camel:to uri="bean:splitBean?method=done" />
        <camel:log message="${in.body}" loggingLevel="INFO" logName="split_test" />
    </camel:route>
    

    The bean you are using to maintain the state on the exchange object:

    public class SplitBean {
        public Object init(Exchange exchange) {
            exchange.setProperty("splitTokens", new ArrayList<Integer>());
            return exchange.getIn().getBody();
        }
    
        public Object addToken(Exchange exchange) {
            ((List<Integer>)exchange.getProperty("splitTokens")).add(Integer.parseInt((String)exchange.getIn().getBody()));
            return null;
        }
    
        public Tuple done(Exchange exchange) {
            return new Tuple<String, List<Integer>>((String)exchange.getIn().getHeader("CamelFileName"), (List<Integer>)exchange.getProperty("splitTokens"));
        }
    }
    

    A file containing the rows

    1
    2
    3
    5
    

    fed to the route under the names splitter.text and splitter_2.txt yields the following log output:

    2013-12-18 18:20:02,081 INFO  split_test - Tuple [first=splitter.txt, second=[1, 2, 3, 5]]
    2013-12-18 18:20:46,610 INFO  split_test - Tuple [first=splitter_2.txt, second=[1, 2, 3, 5]]
    

    HTH