You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by huntc <hu...@mac.com> on 2009/12/29 00:29:47 UTC

Startup invocation of a route

One thing that has always eluded me is how to specify that something be done
immediately upon the CamelContext having started up.

For example, I have a Quartz based service that executes every hour at 10
minutes past the hour. However when the CamelContext starts up I'd like this
service to be invoked immediately and then go into its scheduling behaviour.
This is so that other consumers of the services I provide can get their data
immediately without having to wait up to an hour given service startup.

Firstly it'd be great if there was an option on the Quartz component to
always fire off an initial event. However in general terms it'd be great to
have the ability to specify that a route is invoked upon the CamelContext
having been established (with all of its routes configured within the
current RouterBuilder). Perhaps RouteBuilder needs a new overide-able method
that is invoked in this situation.

Incidentally I see many references to from("direct:start") throughout the
doco and examples, but no idea of how this route is invoked.

Thanks for any help in unwinding my confusion.
-- 
View this message in context: http://old.nabble.com/Startup-invocation-of-a-route-tp26949232p26949232.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Startup invocation of a route

Posted by Willem Jiang <wi...@gmail.com>.
Maybe we can add option in camel-quartz to let it fire the trigger when 
the route is started.

Willem

Stephen Gargan wrote:
> Christopher,
> 
> Claus has got you covered ;) There is an EventNotification mechanism
> that you can use. Add the following to your routes configure
> 
> public class InvokedOnStartupRoute extends RouteBuilder {
> 
>     @Override
>     public void configure() throws Exception {
>         final CamelContext context = getContext();
>         context.getManagementStrategy().setEventNotifier(new EventNotifier() {
>             public void notify(EventObject event) throws Exception {
>                if(event instanceof CamelContextStartedEvent)
>                {
>                    ProducerTemplate template = context.createProducerTemplate();
>                    template.sendBody("direct:invokedOnStartup", "Started");
>                }
>             }
>             public boolean isEnabled(EventObject event) {
>                 return true;
>             }
>         });
>         from("direct:invokedOnStartup").to("mock:invokedOnStartup");
>     }
> }
> 
> It might be nice also if there were a method in the LifecycleStrategy
> interface, onInitializationComplete or the like, that fit a similar
> purpose. I'll let Claus comment on that.
> 
> rgds,
> 
> ste
> 
> 
> On Mon, Dec 28, 2009 at 6:06 PM, huntc <hu...@mac.com> wrote:
>> Hi Stephen,
>>
>> Thanks for your response.
>>
>> I do understand the use of the direct component, but thanks for the
>> explanation any how.
>>
>> I guess using the Spring Events mechanism will get me there, but it'd be
>> nice to codify the solution in a way that remains agnostic of being invoked
>> from Spring.
>>
>> I'm thinking that it'd be useful to raise a JIRA so that RouteBuilder gets
>> the opportunity of kicking things off once the context is ready. What'd
>> think?
>>
>> BTW: I do not have a Main class as I'm using org.apache.camel.spring.Main.
>>
>> Kind regards,
>> Christopher
>> --
>> View this message in context: http://old.nabble.com/Startup-invocation-of-a-route-tp26949232p26950280.html
>> Sent from the Camel - Users mailing list archive at Nabble.com.
>>
>>
> 


Re: Startup invocation of a route

Posted by huntc <hu...@mac.com>.

Stephen Gargan wrote:
> 
> Claus has got you covered ;) 
> 

How could I have doubted him!


Stephen Gargan wrote:
> 
> There is an EventNotification mechanism
> that you can use...
> 
This works beautifully. Thanks so much.
-- 
View this message in context: http://old.nabble.com/Startup-invocation-of-a-route-tp26949232p26952882.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Startup invocation of a route

Posted by Stephen Gargan <st...@gmail.com>.
Christopher,

Claus has got you covered ;) There is an EventNotification mechanism
that you can use. Add the following to your routes configure

public class InvokedOnStartupRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        final CamelContext context = getContext();
        context.getManagementStrategy().setEventNotifier(new EventNotifier() {
            public void notify(EventObject event) throws Exception {
               if(event instanceof CamelContextStartedEvent)
               {
                   ProducerTemplate template = context.createProducerTemplate();
                   template.sendBody("direct:invokedOnStartup", "Started");
               }
            }
            public boolean isEnabled(EventObject event) {
                return true;
            }
        });
        from("direct:invokedOnStartup").to("mock:invokedOnStartup");
    }
}

It might be nice also if there were a method in the LifecycleStrategy
interface, onInitializationComplete or the like, that fit a similar
purpose. I'll let Claus comment on that.

rgds,

ste


On Mon, Dec 28, 2009 at 6:06 PM, huntc <hu...@mac.com> wrote:
>
> Hi Stephen,
>
> Thanks for your response.
>
> I do understand the use of the direct component, but thanks for the
> explanation any how.
>
> I guess using the Spring Events mechanism will get me there, but it'd be
> nice to codify the solution in a way that remains agnostic of being invoked
> from Spring.
>
> I'm thinking that it'd be useful to raise a JIRA so that RouteBuilder gets
> the opportunity of kicking things off once the context is ready. What'd
> think?
>
> BTW: I do not have a Main class as I'm using org.apache.camel.spring.Main.
>
> Kind regards,
> Christopher
> --
> View this message in context: http://old.nabble.com/Startup-invocation-of-a-route-tp26949232p26950280.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>

Re: Startup invocation of a route

Posted by huntc <hu...@mac.com>.
Hi Stephen,

Thanks for your response.

I do understand the use of the direct component, but thanks for the
explanation any how.

I guess using the Spring Events mechanism will get me there, but it'd be
nice to codify the solution in a way that remains agnostic of being invoked
from Spring.

I'm thinking that it'd be useful to raise a JIRA so that RouteBuilder gets
the opportunity of kicking things off once the context is ready. What'd
think?

BTW: I do not have a Main class as I'm using org.apache.camel.spring.Main.

Kind regards,
Christopher
-- 
View this message in context: http://old.nabble.com/Startup-invocation-of-a-route-tp26949232p26950280.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Startup invocation of a route

Posted by Stephen Gargan <st...@gmail.com>.
Hi,

So I like to think of "direct" endpoints as internal connectors for
for linking routes. They are a great way of decoupling the business
and workflow logic in your routes from the transport related logic.

Say for instance your service that Quartz executes is defined in a
bean 'myservice'. You might have a route that looks very like

from("quartz://services/myService?trigger.repeatInterval=10000").to("bean:myService");

you could decouple the bean invocation from the quartz trigger as follows.

from("quartz://services/myService?trigger.repeatInterval=10000").to("direct:my-service-in");
from("direct:my-service-in").to("bean:myservice");

the choice of "direct:my-service-in" as the name is entirely
arbitrary, as arbitrary as "direct:start" in lots of the tests. But as
it appears in the 'to' of one route and the 'from' in another the two
routes are now linked with this virtual channel and when the quartz
endpoint fires it will drive the direct endpoint which will
synchronously drive the bean my service.

Why would you want to do this? well think about testing your routes.
You have your business logic route which can now be very easily driven
and tested by sending exchanges to this "direct:my-service-in" with no
need to setup much transport logic. This makes for cheaper cleaner
route tests as you can test the transport and logic independently.

Getting back to your scenario, you want to be able to invoke the
service route on startup. Now that you have decoupled the routes you
can simply add another route that also sends an exchange 'to' the
"direct:my-service-in" uri when your app starts.

If you're using spring you get this very cheaply as the
SpringCamelContext will kick off a spring event when the context
starts. You could create a route to consume this spring event and
forward it to your service via its direct uri

from("spring-event:default").to("direct:my-service-in"); // note you
may need to filter the kinds of spring events you want to trigger the
service.

or you could just use a producer template to fire it in your main
class after everything is set up.

template.sendBody("direct:my-service-in"", "Inital invocation or whatever");

Main take away is that direct endpoints are your friend and great for
decoupling.

Hope this helps, shout back if not.

ste


On Mon, Dec 28, 2009 at 3:29 PM, huntc <hu...@mac.com> wrote:
>
> One thing that has always eluded me is how to specify that something be done
> immediately upon the CamelContext having started up.
>
> For example, I have a Quartz based service that executes every hour at 10
> minutes past the hour. However when the CamelContext starts up I'd like this
> service to be invoked immediately and then go into its scheduling behaviour.
> This is so that other consumers of the services I provide can get their data
> immediately without having to wait up to an hour given service startup.
>
> Firstly it'd be great if there was an option on the Quartz component to
> always fire off an initial event. However in general terms it'd be great to
> have the ability to specify that a route is invoked upon the CamelContext
> having been established (with all of its routes configured within the
> current RouterBuilder). Perhaps RouteBuilder needs a new overide-able method
> that is invoked in this situation.
>
> Incidentally I see many references to from("direct:start") throughout the
> doco and examples, but no idea of how this route is invoked.
>
> Thanks for any help in unwinding my confusion.
> --
> View this message in context: http://old.nabble.com/Startup-invocation-of-a-route-tp26949232p26949232.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>

Re: Startup invocation of a route

Posted by huntc <hu...@mac.com>.

Claus Ibsen-2 wrote:
> 
> On Tue, Dec 29, 2009 at 12:29 AM, huntc <hu...@mac.com> wrote:
> 
> Just a note. Do you want the route to trigger *only* when CamelContext
> has just been started?
> What if you stop and start the route later, eg using JMX?
> 
Having the route fired off in this circumstance is also good. For me it is
irrelevant what starts/stops the context.


Claus Ibsen-2 wrote:
> 
> I wonder if Quartz got some configuration to fire on startup as well?
> 
Dunno.



Claus Ibsen-2 wrote:
> 
> But the notification might be a nicer solution as you get fine grained
> callbacks and can fire upon camel context started etc.
> 
Yes indeed. Very nice.

Thanks again!
-- 
View this message in context: http://old.nabble.com/Startup-invocation-of-a-route-tp26949232p26953636.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Startup invocation of a route

Posted by Claus Ibsen <cl...@gmail.com>.
On Tue, Dec 29, 2009 at 12:29 AM, huntc <hu...@mac.com> wrote:
>
> One thing that has always eluded me is how to specify that something be done
> immediately upon the CamelContext having started up.
>
> For example, I have a Quartz based service that executes every hour at 10
> minutes past the hour. However when the CamelContext starts up I'd like this
> service to be invoked immediately and then go into its scheduling behaviour.
> This is so that other consumers of the services I provide can get their data
> immediately without having to wait up to an hour given service startup.
>
> Firstly it'd be great if there was an option on the Quartz component to
> always fire off an initial event. However in general terms it'd be great to
> have the ability to specify that a route is invoked upon the CamelContext
> having been established (with all of its routes configured within the
> current RouterBuilder). Perhaps RouteBuilder needs a new overide-able method
> that is invoked in this situation.
>
> Incidentally I see many references to from("direct:start") throughout the
> doco and examples, but no idea of how this route is invoked.
>

Just a note. Do you want the route to trigger *only* when CamelContext
has just been started?
What if you stop and start the route later, eg using JMX?

I wonder if Quartz got some configuration to fire on startup as well?

But anyway Stephen showed a great solution later in this mail thread.

Also you can just register some spring bean and have it depends on
camel and then fire in some messages to the routes you want to get
started.
But the notification might be a nicer solution as you get fine grained
callbacks and can fire upon camel context started etc.



> Thanks for any help in unwinding my confusion.
> --
> View this message in context: http://old.nabble.com/Startup-invocation-of-a-route-tp26949232p26949232.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>



-- 
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus