Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I shutdown a standalone Apache Camel application in an automated way?

I'm trying to use Apache Camel to download and route files from an FTP server. However, files are only added to the FTP server once in a long while so having the program running continuously seems a bit overzealous. Instead, I would rather have a cronjob that runs weekly and processes any new files that have been added to the server.

Is there any way to get Camel to automatically shutdown once it no longer has any new files to process?

My current main function looks like this:

public static void main (String[] args) throws Exception {
    org.apache.camel.spring.Main main = new org.apache.camel.spring.Main ();
    main.setApplicationContextUri ("applicationContext.xml");
    main.enableHangupSupport ();
    main.run (args);
}

And the interesting part of the applicationContext.xml is:

<camelContext>
    <route>
        <from uri="ftp://ftp.example.com/remoteDir?username=user&amp;password=pass"/>
        <to uri="file:../ftp_data?tempPrefix=."/>
    </route>
</camelContext>
like image 733
Keith Avatar asked Jun 26 '13 04:06

Keith


3 Answers

Adding this example that may be useful to others without digging all the examples in the link.

Define a bean/processor that will launch a separate thread. This new thread will call stop() on the active CamelContext.

public class ShutdownBean {

    private final static Logger log = LoggerFactory.getLogger(ShutdownBean.class);

    public void process(Exchange exchange) throws Exception {
        final CamelContext camelContext = exchange.getContext();

        Thread shutdownThread = new Thread(() -> {
            Thread.currentThread().setName("ShutdownThread");
            try {
                camelContext.stop();
            } catch (Exception e) {
                log.error("Errore during shutdown", e);
            }
        });

        shutdownThread.start();
    }
}

In your application context define this route and call it when you need to shutdown Camel.

<bean id="shutdownBean"
      class="your.package.ShutdownBean" />

<camelContext>

    <route id="ShutdownRoute">
        <from uri="direct:shutdown" />
        <log message="Shutdown..." />
        <to uri="bean:shutdownBean" />
    </route>

</camelContext>

Note: enableHangupSupport() is deprecated on newer Camel versions: is enabled by default now, so no longer need to call this method.

like image 140
Alessandro Da Rugna Avatar answered Oct 28 '22 05:10

Alessandro Da Rugna


See this FAQ how to stop a route from a route: http://camel.apache.org/how-can-i-stop-a-route-from-a-route.html.

Then you can enable the option: sendEmptyMessageWhenIdle=true, and then in the route do a message filter, or content based route, and detect the empty message, and then stop the route and then after that CamelContext.

Though I also think this question has been discussed before, so you can maybe find other SO questions or google etc. As there is also alternative ways of doing this.

like image 36
Claus Ibsen Avatar answered Oct 28 '22 03:10

Claus Ibsen


Completing Claus answer, this code run in a only once fashioned way Main:

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.main.Main;

public class MyMainRouter extends RouteBuilder {

  static Main main;

  @Override
  public void configure() throws Exception {
    from("timer:foo?delay=5s")
        .log("Hello camel, main world after 5 seconds!")
        .process(processor -> main.completed());
  }

  public static void main(String[] args) throws Exception {
    main = new Main();
    main.addRouteBuilder(new MyMainRouter());
    main.run();
  }

}

After 5 seconds, the code will run only once, because we will call a processor that will call completed() method, wich internally have CountDownLatch stopping a route pattern from another thread.

like image 42
Valtoni Boaventura Avatar answered Oct 28 '22 04:10

Valtoni Boaventura