Search code examples
apache-camel

How to pass parameters to Apache Camel through command line?


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?


Solution

  • 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