Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Information about propertyPrefix/Suffix - they're resolvable against system/env properties

...

The PropertiesResolver need to know a location(s) where to resolve the properties. You can define 1 to many locations. If you define the location in a single String property you can separate multiple locations with comma such as:

Code Block
java
java

pc.setLocation("com/mycompany/myprop.properties,com/mycompany/other.properties");

...

The location now supports using placeholders for JVM system properties and OS environments variables.

For example:

Code Block

location=file:${karaf.home}/etc/foo.properties

...

To use an OS environment variable instead you would have to prefix with env:

Code Block

location=file:${env:APP_HOME}/etc/foo.properties

...

You can have multiple placeholders in the same location, such as:

...

location, such as:

Code Block
location=file:${env:APP_HOME}/etc/${prop.name}.properties

Using system and environment variables to configure property prefixes and suffixes

Available as of Camel 2.12.5, 2.13.3, 2.14.0

propertyPrefix, propertySuffix configuration properties support using placeholders for JVM system properties and OS environments variables.

For example. if PropertiesComponent is configured with the following properties file:

No Format
dev.endpoint = result1
test.endpoint = result2

Then with the following route definition:

Code Block
java
java
PropertiesComponent pc = context.getComponent("properties", PropertiesComponent.class);
pc.setPropertyPrefix("${stage}.");
// ...
context.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start").to("properties:mock:{{endpoint}}");
    }
});

it is possible to change the target endpoint by changing system property stage either to dev (the message will be routed to mock:result1) or test (the message will be routed to mock:result2).

Configuring in Java DSL

You have to create and register the PropertiesComponent under the name properties such as:

Code Block
java
java

PropertiesComponent pc = new PropertiesComponent();
pc.setLocation("classpath:com/mycompany/myprop.properties");
context.addComponent("properties", pc);

...

Spring XML offers two variations to configure. You can define a spring bean as a PropertiesComponent which resembles the way done in Java DSL. Or you can use the <propertyPlaceholder> tag.

Code Block
xml
xml

<bean id="properties" class="org.apache.camel.component.properties.PropertiesComponent">
    <property name="location" value="classpath:com/mycompany/myprop.properties"/>
</bean>

Using the <propertyPlaceholder> tag makes the configuration a bit more fresh such as:

Code Block
xml
xml

<camelContext ...>
   <propertyPlaceholder id="properties" location="com/mycompany/myprop.properties"/>
</camelContext>

...

Then you could setup the Properties component as follows:

Code Block
xml
xml

   <propertyPlaceholder id="properties" location="ref:myProperties"/>

...

When using property placeholders in the endpoint URIs you can either use the properties: component or define the placeholders directly in the URI. We will show example of both cases, starting with the former.

Code Block

// properties
cool.end=mock:result

// route
from("direct:start").to("properties:{{cool.end}}");

You can also use placeholders as a part of the endpoint uri:

Code Block

// properties
cool.foo=result

// route
from("direct:start").to("properties:mock:{{cool.foo}}");

...

You can also have properties with refer to each other such as:

Code Block

// properties
cool.foo=result
cool.concat=mock:{{cool.foo}}

// route
from("direct:start").to("properties:mock:{{cool.concat}}");

...

The properties: component also offers you to override and provide a location in the given uri using the locations option:

Code Block

   from("direct:start").to("properties:bar.end?locations=com/mycompany/bar.properties");

...

You can also use property placeholders directly in the endpoint uris without having to use properties:.

Code Block

// properties
cool.foo=result

// route
from("direct:start").to("mock:{{cool.foo}}");

And you can use them in multiple wherever you want them:

Code Block

// properties
cool.start=direct:start
cool.showid=true
cool.result=result

// route
from("{{cool.start}}")
    .to("log:{{cool.start}}?showBodyType=false&showExchangeId={{cool.showid}}")
    .to("mock:{{cool.result}}");

You can also your property placeholders when using ProducerTemplate for example:

Code Block

template.sendBody("{{cool.start}}", "Hello World");

...

The Simple language now also support using property placeholders, for example in the route below:

Code Block

// properties
cheese.quote=Camel rocks

// route
from("direct:start")
    .transform().simple("Hi ${body} do you think ${properties:cheese.quote}?");

You can also specify the location in the Simple language for example:

Code Block

// bar.properties
bar.quote=Beer tastes good

// route
from("direct:start")
    .transform().simple("Hi ${body}. ${properties:com/mycompany/bar.properties:bar.quote}.");

...

Available as of Camel 2.5
It is possible to override a property value at runtime using a JVM System property without the need to restart the application to pick up the change. This may also be accomplished from the command line by creating a JVM System property of the same name as the property it replaces with a new value. An example of this is given below

Code Block

PropertiesComponent pc = context.getComponent("properties", PropertiesComponent.class);
pc.setCache(false);
        
System.setProperty("cool.end", "mock:override");
System.setProperty("cool.result", "override");

context.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start").to("properties:cool.end");
        from("direct:foo").to("properties:mock:{{cool.result}}");
    }
});
context.start();

getMockEndpoint("mock:override").expectedMessageCount(2);

template.sendBody("direct:start", "Hello World");
template.sendBody("direct:foo", "Hello Foo");

System.clearProperty("cool.end");
System.clearProperty("cool.result");
        
assertMockEndpointsSatisfied();

...

In our properties file we have the value defined as

Code Block

stop=true

Using property placeholder in the Java DSL

...

Notice how we use the blueprint scheme to refer to the OSGi blueprint placeholder by its id. This allows you to mix and match, for example you can also have additional schemes in the location. For example to load a file from the classpath you can do:

Code Block

location="blueprint:myblueprint.placeholder,classpath:myproperties.properties"

...

The stuff.cfg file is just a plain properties file with the property placeholders such as:

Code Block

## this is a comment
greeting=Bye

...

And the etc/stuff.cfg configuration file contains

Code Block

greeting=Bye
echo=Yay
destination=mock:result

...

Take notice when using Spring bridging placeholder then the spring ${ } syntax clashes with the Simple in Camel, and therefore take care. For example:

Code Block

<setHeader headerName="Exchange.FILE_NAME">
  <simple>{{file.rootdir}}/${in.header.CamelFileName}</simple>
</setHeader>

clashes with Spring property placeholders, and you should use $simple{ } to indicate using the Simple language in Camel.

Code Block

<setHeader headerName="Exchange.FILE_NAME">
  <simple>{{file.rootdir}}/$simple{in.header.CamelFileName}</simple>
</setHeader>

...

Camel allows to inject property placeholders in POJOs using the @PropertyInject annotation which can be set on fields and setter methods.
For example you can use that with RouteBuilder classes, such as shown below:

Code Block
java
java

public class MyRouteBuilder extends RouteBuilder {

    @PropertyInject("hello")
    private String greeting;

    @Override
    public void configure() throws Exception {
        from("direct:start")
            .transform().constant(greeting)
            .to("{{result}}");
    }

}

...

You can also use multiple placeholders and text in the key, for example we can do:

Code Block

    @PropertyInject("Hello {{name}} how are you?")
    private String greeting;

...

You can also add a default value if the key does not exists, such as:

Code Block

    @PropertyInject(value = "myTimeout", defaultValue = "5000")
    private int timeout;

...