Samples - 6.3

Talend ESB Mediation Developer Guide

EnrichVersion
6.3
EnrichProdName
Talend Data Fabric
Talend Data Services Platform
Talend ESB
Talend MDM Platform
Talend Open Studio for ESB
Talend Real-Time Big Data Platform
task
Design and Development
EnrichPlatform
Talend ESB

Read from a directory and write to another directory

from("file://inputdir/?delete=true").to("file://outputdir")

The above will listen on a directory and create a message for each file dropped there. It will copy the contents to the outputdir and delete the file in the inputdir. Using .to("file://outputdir?overruleFile=copy-of-${file:name}") instead will allow you to write to another directory using a dynamic overrule name.

Read from a directory and write to another directory using a overrule dynamic name
from("file://inputdir/?delete=true").to("file://outputdir?overruleFile=copy-of-${file:name}")

Listen on a directory and create a message for each file dropped there. Copy the contents to the outputdir and delete the file in the inputdir.

Reading recursively from a directory and writing to another

from("file://inputdir/?recursive=true&delete=true").to("file://outputdir")

Listen on a directory and create a message for each file dropped there. Copy the contents to the outputdir and delete the file in the inputdir. This will scan recursively into sub-directories, and lay out the files in the same directory structure in the outputdir as the inputdir, including any sub-directories.

inputdir/foo.txt
inputdir/sub/bar.txt

This will result in the following output layout:

outputdir/foo.txt
outputdir/sub/bar.txt
Using flatten

If you want to store the files in the outputdir directory in the same directory, disregarding the source directory layout (for example to flatten out the path), you add the flatten=true option on the file producer side:

from("file://inputdir/?recursive=true&delete=true")
   .to("file://outputdir?flatten=true")

This will result in the following output layout:

outputdir/foo.txt
outputdir/bar.txt

Reading from a directory and the default move operation

Camel will by default move any processed file into a .camel subdirectory in the directory the file was consumed from.

from("file://inputdir/?recursive=true&delete=true").to("file://outputdir")

Affects the layout as follows:

before

inputdir/foo.txt
inputdir/sub/bar.txt

after

inputdir/.camel/foo.txt
inputdir/sub/.camel/bar.txt
outputdir/foo.txt
outputdir/sub/bar.txt

Read from a directory and process the message in java

from("file://inputdir/").process(new Processor() {
   public void process(Exchange exchange) throws Exception {
      Object body = exchange.getIn().getBody();
      // do some business logic with the input body
      ...
   }
});

The body will be a File object that points to the file that was just dropped into the inputdir directory.

Writing to files

Camel is of course also able to write files, that is, produce files. In the sample below we receive some reports on the SEDA queue that we process before the reports are written to a directory.

public void testToFile() throws Exception {
   MockEndpoint mock = getMockEndpoint("mock:result");
   mock.expectedMessageCount(1);
   mock.expectedFileExists("target/test-reports/report.txt");

   template.sendBody("direct:reports", "This is a great report");

   assertMockEndpointsSatisfied();
}

protected JndiRegistry createRegistry() throws Exception {
   // bind our processor in the registry with the given id
   JndiRegistry reg = super.createRegistry();
   reg.bind("processReport", new ProcessReport());
   return reg;
}

protected RouteBuilder createRouteBuilder() throws Exception {
   return new RouteBuilder() {
      public void configure() throws Exception {
         // the reports from the seda queue are processed by our 
         // processor before they are written to files in the 
         // target/reports directory
         from("direct:reports").processRef("processReport")
            .to("file://target/test-reports", "mock:result");
      }
   };
}

private class ProcessReport implements Processor {

   public void process(Exchange exchange) throws Exception {
      String body = exchange.getIn().getBody(String.class);
      // do some business logic here
      ...
      // set the output to the file
      exchange.getOut().setBody(body);

      // set the output filename using java code logic, notice that this 
      // is done by setting a special header property of the out exchange
      exchange.getOut().setHeader(Exchange.FILE_NAME, "report.txt");
   }

}

Write to subdirectory using Exchange.FILE_NAME

Using a single route, it is possible to write a file to any number of subdirectories. If you have a route setup as such:

<route>
   <from uri="bean:myBean"/>
   <to uri="file:/rootDirectory"/>
</route>

You can have myBean set the header Exchange.FILE_NAME to values such as:

Exchange.FILE_NAME = hello.txt => /rootDirectory/hello.txt
Exchange.FILE_NAME = foo/bye.txt => /rootDirectory/foo/bye.txt

This allows you to have a single route to write files to multiple destinations.

Writing file through the temporary directory relative to the final destination

Sometime you need to temporarily write the files to some directory relative to the destination directory. Such situation usually happens when some external process with limited filtering capabilities is reading from the directory you are writing to. In the example below files will be written to the /var/myapp/filesInProgress directory and after data transfer is done, they will be atomically moved to the /var/myapp/finalDirectory directory.

from("direct:start").
  to("file:///var/myapp/finalDirectory?tempPrefix=/../filesInProgress/");  

Using expression for filenames

In this sample we want to move consumed files to a backup folder using today's date as a sub-folder name:

from("file://inbox?move=backup/${date:now:yyyyMMdd}/
   ${file:name}").to("...");

See File Language for more samples.