Reputation: 459
Note: Question is about standalone (using Main class) behaviour of the unreleased Camel 3.0.0-M2 version which has many enhancements for standalone mode over Camel 2.x - the code below is not intended to work on Camel 2.x
Problem: I noticed that modifications on the properties component as described in [1] do not affect config properties injected into beans. In my case I want to set the pc's environmentVariableMode to override (fallback is the default).
While the override was effective on the route, the bean got injected with the original property value.
The property "hi" in application.properties is set to "Hello" and the environment variable "hi" is set to "Huhu" which should override the former when environmentVariableMode is set to override (2).
When run:
System env var hi=Huhu
14:34:02.282 [Camel (camel-1) thread #2 - timer://foo] INFO route1 - Huhu from route
14:34:02.297 [Camel (camel-1) thread #2 - timer://foo] INFO route1 - Hello from bean
Code:
public class MyApplication {
private MyApplication() {
}
public static void main(String[] args) throws Exception {
Main main = new Main();
main.addConfigurationClass(MyConfiguration.class);
main.addRouteBuilder(MyRouteBuilder.class);
main.run(args);
}
}
public class MyConfiguration {
@BindToRegistry
public MyBean myBean(@PropertyInject("hi") String hi) {
return new MyBean(hi);
}
}
public class MyBean {
private String hi;
public MyBean(String hi) {
this.hi = hi;
}
public String hello() {
return hi + " from bean";
}
}
public class MyRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
CamelContext context = getContext();
PropertiesComponent pc = context.getComponent("properties", PropertiesComponent.class);
pc.setEnvironmentVariableMode(PropertiesComponent.ENVIRONMENT_VARIABLES_MODE_OVERRIDE); //default is FALLBACK
System.out.println("System env var hi=" + System.getenv("hi"));
from("timer:foo?repeatCount=1")
.log("${properties:hi} from route")
.bean("myBean")
.log("${body}");
}
}
application.properties:
hi = Hello
The only way I could get it to work was to override Main#postProcessCamelContext -- is this really the way it is intended to use? Or is there a more idiomatic way?
public class MyApplication extends Main {
private MyApplication(String[] args) throws Exception {
addConfigurationClass(MyConfiguration.class);
addRouteBuilder(MyRouteBuilder.class);
run(args);
}
@Override
protected void postProcessCamelContext(CamelContext camelContext) throws Exception {
PropertiesComponent pc = camelContext.getComponent("properties", PropertiesComponent.class);
pc.setEnvironmentVariableMode(PropertiesComponent.ENVIRONMENT_VARIABLES_MODE_OVERRIDE);
super.postProcessCamelContext(camelContext);
}
public static void main(String[] args) throws Exception {
new MyApplication(args);
}
}
A suggestion to Camel development: Wouldn't it make more sense to set environmentVariableMode to override by default instead of fallback, especially when thinking about container deployments: Environment variables take precedence over system properties which take precedence over application configuration (e.g. application.properties)?
Upvotes: 0
Views: 351
Reputation: 55525
Yeah its better to have ENV override, you are welcome to log a JIRA and work on a github PR. We love contributions http://camel.apache.org/support.html
I logged a ticket: https://issues.apache.org/jira/browse/CAMEL-13502
Okay this has now been implement to be the default mode, and you can also configure this from the application.properties file etc: https://github.com/apache/camel/blob/master/examples/camel-example-main/src/main/resources/application.properties#L23
And the issue with @PropertyInject
has also been fixed, in Camel v3.0M3
Upvotes: 1