Hi everyone,

recently we had a typo in one of our route definitions that resulted in a 
duplicate route ID but no error message and unexpected replacement of an 
existing route. This is the bootstrap order found in some Camel examples:

CamelContext context = new DefaultCamelContext();

context.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:foo").routeId("foo").stop();
    }
});

context.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:bar").routeId("foo").stop();
    }
});

context.start();

You'll get a duplicate route ID exception.

If instead you start the context before you add the routes, you won't get an 
exception and the "direct:bar" route will simply replace the "direct:foo" 
route, as they have the same ID. This is consistent with the Javadoc of the API 
and probably a useful feature.

However if like in our case you use camel-spring-boot, the RouteCollector will 
add routes after the Camel context has started. You won't detect duplicate 
route IDs but instead any later discovered RouteBuilder will override existing 
routes with the same ID.

I'm no Spring expert but it seems the CamelContext start should be deferred in 
the Spring Boot integration code: The CamelBeanPostProcessor factory method 
triggers CamelContext creation (due to injection in the factory method) and 
starts SpringCamelContext during the BeanPostProcessor initialization phase in 
Spring (InitializingBean). Any necessary transitive bean creation will 
therefore also happen in that phase. We see a lot of Spring warnings (actually 
INFO, but it probably should be WARN) that some BeanPostProcessors had to be 
skipped, because we are starting inside a BeanPostProcessor call.

One of those is for example our custom BeanPostProcessor which adds discovered 
EventNotifiers to the CamelContext, something the Spring Boot integration 
doesn't provide yet. We think this has to be done before the CamelContext is 
started, after looking at the ManagementStrategy code. Hence you can't do this 
with the CamelConfiguration interface of camel-spring-boot, the context has 
already been started at that point.

Our solution was a simple integration class for Spring Boot that starts the 
context later, after configuration. Would be great to know if we are missing 
something, although we'll probably stay on 2.14 anyway for this project due end 
of March.

Cheers,
Christian





Reply via email to