You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Christian Bauer <ma...@christianbauer.name> on 2015/02/06 10:43:44 UTC

Duplicate route id detection and Spring Boot integration

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






Re: Duplicate route id detection and Spring Boot integration

Posted by Henryk Konsek <he...@gmail.com>.
I sneaked the fixed into 2.15.0 release. :) Thanks for reporting!

Laters!

On Wed, Mar 4, 2015 at 4:10 PM, Henryk Konsek <he...@gmail.com> wrote:
> Hi,
>
> Indeed, RoutesCollector was invoked after CamelContext is started.
> This is a bug. I will push fix to Camel 2.15.1.
>
> Thanks for catching this!
>
> Cheers.
>
> On Sun, Feb 15, 2015 at 10:26 PM, Henryk Konsek <he...@gmail.com> wrote:
>> Hi guys,
>>
>> I'm back from the short holidays. I will take a look at this issue
>> soon. Stay tuned!
>>
>> Laters!
>>
>> On Mon, Feb 9, 2015 at 9:28 AM, Christian Bauer
>> <ma...@christianbauer.name> wrote:
>>> https://issues.apache.org/jira/browse/CAMEL-8325
>>>
>>> On February 8, 2015 7:35:56 PM GMT+01:00, Claus Ibsen <cl...@gmail.com> wrote:
>>>>On Fri, Feb 6, 2015 at 10:43 AM, Christian Bauer
>>>><ma...@christianbauer.name> wrote:
>>>>> 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.
>>>>>
>>>>
>>>>Ah yeah I guess maybe camel-spring-boot calls start on CamelContext to
>>>>soon.
>>>>
>>>>As currently you can add your own duplication route id detection and
>>>>fail.
>>>>
>>>>
>>>>
>>>>> 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.
>>>>>
>>>>
>>>>Yeah I think it should start later. In camel-spring we only start
>>>>camel at the end when we receive an event from spring itself about the
>>>>context created/refresh.
>>>>
>>>>Maybe if Henryk got some time he could dive in and look as well.
>>>>
>>>>But anyone is of course welcome to help. We love contributions.
>>>>And you are welcome to log a JIRA ticket, it does indeed appear as the
>>>>start() is invoked too soon, which can also cause other side-effects.
>>>>
>>>>eg start should only be called after all the configuration has been
>>>>done.
>>>>
>>>>
>>>>> 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
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>>--
>>>>Claus Ibsen
>>>>-----------------
>>>>Red Hat, Inc.
>>>>Email: cibsen@redhat.com
>>>>Twitter: davsclaus
>>>>Blog: http://davsclaus.com
>>>>Author of Camel in Action: http://www.manning.com/ibsen
>>>>hawtio: http://hawt.io/
>>>>fabric8: http://fabric8.io/
>>
>>
>>
>> --
>> Henryk Konsek
>> http://henryk-konsek.blogspot.com
>
>
>
> --
> Henryk Konsek
> http://about.me/hekonsek



-- 
Henryk Konsek
http://about.me/hekonsek

Re: Duplicate route id detection and Spring Boot integration

Posted by Henryk Konsek <he...@gmail.com>.
Hi,

Indeed, RoutesCollector was invoked after CamelContext is started.
This is a bug. I will push fix to Camel 2.15.1.

Thanks for catching this!

Cheers.

On Sun, Feb 15, 2015 at 10:26 PM, Henryk Konsek <he...@gmail.com> wrote:
> Hi guys,
>
> I'm back from the short holidays. I will take a look at this issue
> soon. Stay tuned!
>
> Laters!
>
> On Mon, Feb 9, 2015 at 9:28 AM, Christian Bauer
> <ma...@christianbauer.name> wrote:
>> https://issues.apache.org/jira/browse/CAMEL-8325
>>
>> On February 8, 2015 7:35:56 PM GMT+01:00, Claus Ibsen <cl...@gmail.com> wrote:
>>>On Fri, Feb 6, 2015 at 10:43 AM, Christian Bauer
>>><ma...@christianbauer.name> wrote:
>>>> 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.
>>>>
>>>
>>>Ah yeah I guess maybe camel-spring-boot calls start on CamelContext to
>>>soon.
>>>
>>>As currently you can add your own duplication route id detection and
>>>fail.
>>>
>>>
>>>
>>>> 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.
>>>>
>>>
>>>Yeah I think it should start later. In camel-spring we only start
>>>camel at the end when we receive an event from spring itself about the
>>>context created/refresh.
>>>
>>>Maybe if Henryk got some time he could dive in and look as well.
>>>
>>>But anyone is of course welcome to help. We love contributions.
>>>And you are welcome to log a JIRA ticket, it does indeed appear as the
>>>start() is invoked too soon, which can also cause other side-effects.
>>>
>>>eg start should only be called after all the configuration has been
>>>done.
>>>
>>>
>>>> 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
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>>--
>>>Claus Ibsen
>>>-----------------
>>>Red Hat, Inc.
>>>Email: cibsen@redhat.com
>>>Twitter: davsclaus
>>>Blog: http://davsclaus.com
>>>Author of Camel in Action: http://www.manning.com/ibsen
>>>hawtio: http://hawt.io/
>>>fabric8: http://fabric8.io/
>
>
>
> --
> Henryk Konsek
> http://henryk-konsek.blogspot.com



-- 
Henryk Konsek
http://about.me/hekonsek

Re: Duplicate route id detection and Spring Boot integration

Posted by Henryk Konsek <he...@gmail.com>.
Hi guys,

I'm back from the short holidays. I will take a look at this issue
soon. Stay tuned!

Laters!

On Mon, Feb 9, 2015 at 9:28 AM, Christian Bauer
<ma...@christianbauer.name> wrote:
> https://issues.apache.org/jira/browse/CAMEL-8325
>
> On February 8, 2015 7:35:56 PM GMT+01:00, Claus Ibsen <cl...@gmail.com> wrote:
>>On Fri, Feb 6, 2015 at 10:43 AM, Christian Bauer
>><ma...@christianbauer.name> wrote:
>>> 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.
>>>
>>
>>Ah yeah I guess maybe camel-spring-boot calls start on CamelContext to
>>soon.
>>
>>As currently you can add your own duplication route id detection and
>>fail.
>>
>>
>>
>>> 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.
>>>
>>
>>Yeah I think it should start later. In camel-spring we only start
>>camel at the end when we receive an event from spring itself about the
>>context created/refresh.
>>
>>Maybe if Henryk got some time he could dive in and look as well.
>>
>>But anyone is of course welcome to help. We love contributions.
>>And you are welcome to log a JIRA ticket, it does indeed appear as the
>>start() is invoked too soon, which can also cause other side-effects.
>>
>>eg start should only be called after all the configuration has been
>>done.
>>
>>
>>> 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
>>>
>>>
>>>
>>>
>>>
>>
>>
>>
>>--
>>Claus Ibsen
>>-----------------
>>Red Hat, Inc.
>>Email: cibsen@redhat.com
>>Twitter: davsclaus
>>Blog: http://davsclaus.com
>>Author of Camel in Action: http://www.manning.com/ibsen
>>hawtio: http://hawt.io/
>>fabric8: http://fabric8.io/



-- 
Henryk Konsek
http://henryk-konsek.blogspot.com

Re: Duplicate route id detection and Spring Boot integration

Posted by Christian Bauer <ma...@christianbauer.name>.
https://issues.apache.org/jira/browse/CAMEL-8325

On February 8, 2015 7:35:56 PM GMT+01:00, Claus Ibsen <cl...@gmail.com> wrote:
>On Fri, Feb 6, 2015 at 10:43 AM, Christian Bauer
><ma...@christianbauer.name> wrote:
>> 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.
>>
>
>Ah yeah I guess maybe camel-spring-boot calls start on CamelContext to
>soon.
>
>As currently you can add your own duplication route id detection and
>fail.
>
>
>
>> 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.
>>
>
>Yeah I think it should start later. In camel-spring we only start
>camel at the end when we receive an event from spring itself about the
>context created/refresh.
>
>Maybe if Henryk got some time he could dive in and look as well.
>
>But anyone is of course welcome to help. We love contributions.
>And you are welcome to log a JIRA ticket, it does indeed appear as the
>start() is invoked too soon, which can also cause other side-effects.
>
>eg start should only be called after all the configuration has been
>done.
>
>
>> 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
>>
>>
>>
>>
>>
>
>
>
>-- 
>Claus Ibsen
>-----------------
>Red Hat, Inc.
>Email: cibsen@redhat.com
>Twitter: davsclaus
>Blog: http://davsclaus.com
>Author of Camel in Action: http://www.manning.com/ibsen
>hawtio: http://hawt.io/
>fabric8: http://fabric8.io/

Re: Duplicate route id detection and Spring Boot integration

Posted by Claus Ibsen <cl...@gmail.com>.
On Fri, Feb 6, 2015 at 10:43 AM, Christian Bauer
<ma...@christianbauer.name> wrote:
> 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.
>

Ah yeah I guess maybe camel-spring-boot calls start on CamelContext to soon.

As currently you can add your own duplication route id detection and fail.



> 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.
>

Yeah I think it should start later. In camel-spring we only start
camel at the end when we receive an event from spring itself about the
context created/refresh.

Maybe if Henryk got some time he could dive in and look as well.

But anyone is of course welcome to help. We love contributions.
And you are welcome to log a JIRA ticket, it does indeed appear as the
start() is invoked too soon, which can also cause other side-effects.

eg start should only be called after all the configuration has been done.


> 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
>
>
>
>
>



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen
hawtio: http://hawt.io/
fabric8: http://fabric8.io/