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&password=pass"/>
<to uri="file:../ftp_data?tempPrefix=."/>
</route>
</camelContext>
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With