I use Apache Camel’s Spring Main
to boot my Camel application. I need my application to read the command line arguments to set some parameters. So, I cannot use property files.
At the moment, I can pass arguments via the JVM system properties, and it works well:
Application.java
public class Application extends org.apache.camel.spring.Main {
public static void main(String[] args) throws Exception {
Application app = new Application();
instance = app;
app.run(args);
}
}
camel-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="shutdownBean" class="com.example.ShutdownBean" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="file:{{inputFile}}?noop=true"/>
<to uri="bean:shutdownBean" />
</route>
</camelContext>
</beans>
I run the app with java com.example.Application -DinputFile=C:/absolute/path/to/watch
and everything works fine:
…
FileEndpoint INFO Using default memory based idempotent repository with cache max size: 1000
InternalRouteStartupManager INFO Route: route1 started and consuming from: file://C:/absolute/path/to/watch
AbstractCamelContext INFO Total 1 routes, of which 1 are started
…
But I would like to have some input validation and make the app easier to use because -D
could be confusing for a non Java user. So I change Application.java
:
public class Application extends org.apache.camel.spring.Main {
private File inputFile;
public static void main(String[] args) throws Exception {
Application app = new Application();
instance = app;
app.run(args);
}
public Application() {
addOption(new ParameterOption("i", "inputFile", "The input file", "inputFile") {
@Override
protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
File file = FileUtils.getFile(parameter);
// some business validation
setInputFile(file);
}
});
}
private void setInputFile(File inputFile) {
this.inputFile = inputFile;
}
}
Then, I could use the following command to run the application: java com.example.Application -inputFile C:/absolute/path/to/watch
How can I use my inputFile
field into my Camel route?
Call addProperty(String key, String value)
in your doProcess
method. Then it will be accessible throught {{key}}
notation.
MyApplication:
public final class MyApplication extends Main {
private MyApplication() {
super();
addCliOption("g", "greeting", "Greeting");
addCliOption("n", "name", "Who to greet");
}
public static void main(String[] args) throws Exception {
MyApplication app = new MyApplication();
app.configure().addRoutesBuilder(MyRouteBuilder.class);
app.run(args);
}
private void addCliOption(String abbrevation, String parameterName, String description) {
addOption(new ParameterOption(abbrevation, parameterName, description, parameterName) {
protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
addProperty("console." + parameterName, parameter);
}
});
}
}
MyRouteBuilder:
public class MyRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
from("quartz:foo")
.log("{{console.greeting}} {{console.name}}");
}
}
java org.apache.camel.example.MyApplication -greeting Hello -name Morgan
23:10:25.862 [DefaultQuartzScheduler-MyCoolCamel_Worker-1] INFO route1 - Hello Morgan
23:10:26.832 [DefaultQuartzScheduler-MyCoolCamel_Worker-2] INFO route1 - Hello Morgan
23:10:27.829 [DefaultQuartzScheduler-MyCoolCamel_Worker-3] INFO route1 - Hello Morgan