How can I include common behavior in several Apache Camel routes? - apache-camel

I am using Camel 2.19.2 in a Spring Boot 1.5.8 application. If I want, for example, to have several of my routes to be "status aware", how might I achieve this? What I mean by "status aware" is that the route will start, notify a component that the workflow has begun, then it will conduct route-specific logic, and when that is complete, it will notify a component that the workflow has completed. I want this to happen automatically, if possible, and without having to call the specific logic in each of the route builders that I want to use this capability.
Here is a code example like what I mean:
public class FooRouteBuilder extends StatusAwareRouteBuilder {
#Override
public void configure() {
// Here I want to have this route know how to notify something
// that this processing has begun, but I do not want to have
// to explicitly call a processor to make it happen, but it
// should know what to do by virtue of extending a custom
// route builder, if appropriate, or by some other/better
// mechanism
// Now conduct any route-specific logic
from("vm:myAction")
.process("myProcessor");
// Now handle the status notification that this is finished...
// Here I want to have this route know how to notify something
// that this processing has finished
}
}
Conceptually, this is almost like AOP, so I would like to be able to define this behavior in one place and include it in some number of routes that need to use this behavior. Is there a way that I can accomplish this? I saw that there is adviceWith for testing, but I need this for regular operation. Thanks in advance.

I think that RoutePolicy and RoutePolicyFactory can be the answer, i.e. you can have a callback invoked when the route or exchnage start/stop.
For more info see http://camel.apache.org/routepolicy.html

Perhaps Camel interceptors can help you. These are typically small generic routes that are applied to all or most of your routes.
For example to do a security check in every route. With an interceptor you write it once and it is applied to all routes, even new ones that are added.
There are three flavours.
intercept intercepts each and every processing step while routing
an Exchange in the route.
interceptFrom intercepts every incoming
Exchange in the route (start of processing)
interceptSendToEndpoint intercepts when an
Exchange is about to be sent to an endpoint.
The interceptors can be configured to "fire" only for specific endpoint types or by Camel predicate on other specific conditions.
There is also the onCompletion feature to do a similar thing at route completion. Either on successful completion on failure completion or both of them (default).

Related

How to send messages to same set of routes multiple times and execute it in async fashion on different threads concurrently?

I have a situation where we need to send a message to the same route multiple times that route will run infinitely such as,
from(file://configuration.txt)
.bean(parseToList.class)
.split(body()) // each iteration will have different config data
.to(route://xyz)
.end()
//this will run indefinetly
from(direct://xyz)
.to(sql:fetch query dynamically based on data)
.choice().when().simple(roucount>0).to(file://destination)
.sleep(3000)
.to(direct://xyz)
I need direct:XYZ should be called for every message on a different thread and should run forever. How to achieve this in camel?
Edit 1:
I got a suggestion to use seda: instead of direct to enable the async capability. But I also need the route to be transactional, So any suggestion to implement an async and transactional route?
I think what you are looking for can be implemented with SEDA component. direct: component is synchronous but SEDA provides async behaviour. Additionally checkout samples in Camel Examples repo.

Sharing state in camel?

It appears I am running into issues sharing information between routes.
What is the camel pattern for passing around information ?
I looked at exchange properties but that does not stick around between routes I think...
eg:
one file has one has some configutations
i have a route to read this file
and several other routes that will act on based on the configs,
how do I accomplish this ?
I thought of puttin the values in a singleton bean, but that seems kind of ugly...
Exchange properties are preserved across routes inside camel (but there are some limitations and special cases when using splitter/aggregator etc.)
Assign ID's to all sub routes which will act on based on the config. Then get the suitable Route or RouteDefinition from camel context and check whether you can advice or share information to the route according.
ModelCamelContext modelContext;
modelContext.getRouteDefinition(String routeId) or modelContext.getRoute(String routeId)

stop certain routes instead of completely stopping the whole camel context

I am wondering how can we stop certain routes instead of completely stopping the whole camel context and also is there any other alternative for Thread.sleep(); method for processing.
I would like to run a route once and stop the context when the route is completed. Currently I do the usual Thread.sleep(3000) in the main Java class to leave some time for the route to finish.
I saw some documentation saying camel route supports graceful shutdown but if i don't use Thread.sleep() route shut downs immediately without processing.
the CamelContext has APIs to stop individual routes (startRoute(routeId), stopRoute(routeId), etc) or you can use route policies for more advanced route control
also, to keep your context running, you don't need to use Thread.sleep, just bootstrap the context with Spring or using a Main class...

Transacted camel route with auto-startup set to false

I am in the process of developing a message router which has a bunch of routes that are started and stopped at runtime based some certain conditions.
By default all these routes are configured with auto-starup=false
Now I am trying to add transactional support to these routes and it seems that you cannot define a transacted route and control the its startup behavior at the same time. This is because RouteDefinition.transacted() returns a TransactedDefinition instance which does not have an autoStartup(boolean autoStartup) method.
I am sure I am not the only one to need this kind of functionality and just wondering what is the camel way of addressing such requirements.
Thank you in advance for your inputs
Maybe just set autoStartup first, eg
from("direct:start").autoStartup(false)
.transacted()
.to("mock:result");

Start Camel route in suspended state

Is there a way to build Camel routes that starts in suspended mode?
I'm looking so to say "declutch" at start up, then at some stage quickly start processing messages by just calling resumeRoute(routeId)
I could perhaps just create the route and then quickly call suspendRoute(routeId), after the route has been created, but at that stage, it would probably have consumed some messages (for instance in the case of JMS routes or polling consumer routes).
generally, you'd just disable the route by using autostartup(false)...
I assume you are asking though because you need the route started (warmed), but not active. In that case, then you should be able to use a custom route policy and some external variable to get this behavior

Resources