Spring Boot properties and Camel routes - an example

When you’re writing code you’re often reminded that hard-coding is bad; that including environment-dependent parameters inside your code, such as URLs, credentials and database configuration, is bad.

This advice is no different for writing Camel routes. If you find yourself in a situation where you’re hard-coding something - e.g. a REST service endpoint - then you should probably stop, and consider how you can externalise this configuration, in case the URL changes in future.

Fortunately, if you’re using Spring Boot, you get functionality to help you do this, as standard.

One of the cool features of Spring Boot is its ability to manage your application’s configuration and then pass that to your app, all without you having to explicitly write a line of code. You can read in parameters from config files, environment variables, and lots more. This makes it very easy to swap out different configurations for your app when you need them. Or, to make changes to the way your application runs, without having to recompile it.

When used with Camel, it’s especially useful because if you are developing some routes that are very similar, now you can write the code once and run multiple instances of the same route, with just the parameters modified.

Using application properties in Camel with Spring Boot - step-by-step example

Let’s create a Camel app with Spring Boot, and pass some configuration to it:

  1. Create your Spring Boot application

    You probably already know about Spring Initializr, the web tool for creating Spring Boot apps.

    But did you know that you can create Spring apps using the command line as well? Command line FTW!

    To do this, you just need to install the Spring Boot CLI. This will install the spring command into your environment. (Tip: if you’re using Mac OS, it’s also available through Homebrew; info in the link above).

    Then, to create a project, you can just run:

    spring init -d=camel -g=com.yourcompany your-project-name
    

    Where d=camel states that you want to use the camel dependency, and g=com.yourcompany is where you give the package name for your generated classes.

  2. Add a Camel route

    Once we’ve created our project, we need to add some Camel routes.

    Spring just gives us an empty boilerplate project, so let’s add a Camel RouteBuilder class. This class will configure a basic route that logs a greeting to the console at regular intervals, using a timer.

    Two aspects of the route are going to take values from Spring Boot configuration: the frequency of the timer, and the greeting phrase in the output. We mark parameters with curly braces {{ and }}, e.g. {{myvariable}}.

    So to create the route, create a file DemoRouteBuilder.java with these contents:

    import org.apache.camel.builder.RouteBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Component;
    
    @Component
    public class DemoRouteBuilder extends RouteBuilder {
    
        @Override
        public void configure() {
            from("timer:mytimer?period={{timer.period}}")
                .setBody(simple("{{greeting.word}}, this is Camel running in Spring Boot!"))
                .to("log:out");
    
        }
    
    }    
    
  3. Add configuration parameters

    Now we’ll configure the parameters for our application.

    Create a file src/main/resources/application.properties (or edit the file if it already exists).

    Firstly, add the following line:

    camel.springboot.main-run-controller=true
    

    This first line is important as it ensures that Spring Boot stays “up”. In other words, it keeps the Camel route running until you terminate the Spring Boot container.

    Then you add two config parameters like this:

    timer.period=5000
    greeting.word=Nihao
    
  4. Run your application

    Then, to run the app:

    mvn spring-boot:run
    

    Once Spring Boot has started up, you will see this in the logs:

    2017-08-16 21:24:16.126  INFO 70530 --- [inRunController] o.a.camel.spring.SpringCamelContext      : Route: route1 started and consuming from: timer://mytimer?period=5000
    2017-08-16 21:24:16.128  INFO 70530 --- [inRunController] o.a.camel.spring.SpringCamelContext      : Total 1 routes, of which 1 are started.
    2017-08-16 21:24:16.129  INFO 70530 --- [inRunController] o.a.camel.spring.SpringCamelContext      : Apache Camel 2.19.2 (CamelContext: camel-1) started in 0.300 seconds
    2017-08-16 21:24:17.160  INFO 70530 --- [timer://mytimer] out                                      : Exchange[ExchangePattern: InOnly, BodyType: String, Body: Nihao, this is Camel running in Spring Boot!]
    2017-08-16 21:24:22.139  INFO 70530 --- [timer://mytimer] out                                      : Exchange[ExchangePattern: InOnly, BodyType: String, Body: Nihao, this is Camel running in Spring Boot!]
    2017-08-16 21:24:27.140  INFO 70530 --- [timer://mytimer] out                                      : Exchange[ExchangePattern: InOnly, BodyType: String, Body: Nihao, this is Camel running in Spring Boot!]
    

    You can also change the configuration properties when you run the route by adding the -D argument, like this:

    mvn spring-boot:run -Dgreeting.word=Bonjour
    

    Which will give you this output:

    2017-08-16 21:27:06.215  INFO 70651 --- [timer://mytimer] out                                      : Exchange[ExchangePattern: InOnly, BodyType: String, Body: Bonjour, this is Camel running in Spring Boot!]
    2017-08-16 21:27:11.167  INFO 70651 --- [timer://mytimer] out                                      : Exchange[ExchangePattern: InOnly, BodyType: String, Body: Bonjour, this is Camel running in Spring Boot!]
    

Get the example code on GitHub

You’ve just witnessed an example of Spring’s convention over configuration, where Spring establishes a convention for something - in this case, application parameters - making it easy to set them up with minimum fuss.

You can use this powerful feature to easily parameterise your Camel routes, and reduce the number of things you hard-code.

You can read more about properties and configuration in the official Spring Boot documentation.