Java and Apache-Camel: from straight endpoint to file endpoint

I tried to create a route to copy files from one directory to another directory. But instead of using: from(file://source-directory).to(file://destination-directory)

I want to do something like this:

from(direct:start)
  .to(direct:doStuff)
  .to(direct:readDirectory)
  .to(file://destination-folder)

      

I did the following:

Route

@Component
public class Route extends AbstractRouteBuilder {
  @Override
  public void configure() throws Exception {
      from("direct:start")
        .bean(lookup(ReadDirectory.class))
        .split(body())
          .setHeader("FILENAME", method(lookup(CreateFilename.class)))
          .to("file:///path/to/my/output/directory/?fileName=${header.FILENAME}");
  }

      

CPU

@Component
public class ReadDirectory implements CamelProcessorBean {
  @Handler
  public ImmutableList<File> apply(@Header("SOURCE_DIR") final String sourceDir) {
    final File directory = new File(sourceDir);
    final File[] files = directory.listFiles();
    if (files == null) {
      return ImmutableList.copyOf(Lists.<File>newArrayList());
    }
    return ImmutableList.copyOf(files);
  }
}

      

I can start my route using the following pseudo test (the point is that I can manually start my route producer.sendBodyAndHeader(..)

)

public class RouteIT extends StandardIT {
  @Produce
  private ProducerTemplate producer;

  @Test
  public void testRoute() throws Exception {
    final String uri = "direct:start";
    producer.sendBodyAndHeaders(uri, InOut, null, header());
  }

  private Map<String, Object> header() {
    final Map<String, Object> header = Maps.newHashMap();
    header.put("SOURCE_DIR", "/path/to/my/input/directory/");
    return header;
  }
}

      

  • AbstractRouteBuilder

    extends SpringRouteBuilder

  • CamelProcessorBean

    is just a marker-interface
  • StandardIT

    loads SpringContext and stuff

The problem is that I have to set the filename. I read something that camel sets the header CamelFileNameProduced

(during the file endpoint). This is a shared string with a timestamp, and if I don't give a filename, the written files will get this shared string as the filename.

My question . Is there a nicer solution to copy the files (but starting from a direct endpoint and reading a directory in the middle of the route) and store the filename for the destination? (I don't need to specify the filename when using from("file:source").to("file:destination")

, why would I do that now?)

+3


source to share


1 answer


You can set the file name when submitting using the producer pattern, while the header propagates during routing between all routes, all of which are fine, which is what Camel does by default.

for example

  @Test
  public void testRoute() throws Exception {
    final String uri = "direct:start";
    Map headers = ...
    headers.put(Exchange.FILE_NAME, "myfile.txt");
    producer.sendBodyAndHeaders(uri, InOut, null, headers);
  }

      



The file component says more about how to manage the filename

+2


source







All Articles