Conditional registration of routes (or route builders)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Conditional registration of routes (or route builders)

Bernard Ligny
This post was updated on .
Hi Camel folks

I would like to have some advices/recommandations about the following requirement.

We have a webapp with *many* Camel routes (started with Camel-CDI). This war is deployed on various application servers for various customers.
Some of theses routes are common to all customers, while other routes are limited/dedicated to a single customer (and should therefore not be "deployed" for all customers)

What would be the best solution to have a conditional (> depending on props/conf file) registration of my routes ?
Please note I wish a conditional *registration* and not *starting* (> I do not want the unused routes to be part of my CamelContext, nor to be visible in hawt-io).
So disabling autostart + manually starting needed routes is not an option...

Any idea  ? - of something different from this:

public MyRouteBuilder extends RouteBuilder {

	@PropertyInject(value="route1.on") 
	private boolean route1Enabled;
	
	@PropertyInject(value="route2.on") 
	private boolean route2Enabled;

	@Override
        public void configure() {
		
		if (route1Enabled) {
			from("direct:..")
				.id("my-route-1")
				.to("...");
		}
		
		if (route2Enabled) {
			from("direct:..")
				.id("my-route-2")
				.to("...");
		}	
			
}
I was thinking about a new annotation on the routebuilder, eg

@ContextName("camel-context")
@Conditional(property="myroutebuilder.on")
public MyRouteBuilder extends RouteBuilder {
   ...
}

Another alternative (but which requires a lot more refactoring) would be to have a more "micro-services" oriented approach, to break my monolithic war into a set of jars (each jar embedding a SINGLE RouteBuilder), and then in the war assembly phase, build a customer-specific artifact (that is, exclude the jars containing unneeded routes).
Reply | Threaded
Open this post in threaded view
|

Re: Conditional registration of routes (or route builders)

astefanutti
Hi Bernard,

One straightforward solution would be to implement a small CDI extension deployed within your WAR that would do the white (or black) listing of the RouteBuilder, depending on whatever condition (a properties file), e.g.:

public class CustomerRoutesExtension implements Extension {

  <X extends RouteBuilder> void excludeRoutes(@Observes ProcessAnnotatedType<X> pat) {
    if (toExcludeForCustomer(pat.getAnnotatedType().getJavaClass()))
      pat.veto();
  }

}

Similarly, you can easily veto all the RouteBuilder classes from being discovered and add them manually to implement a white listing strategy.

We may want to have an @Conditional annotation (like in Spring) but then the condition will have to be based on a generic semantic.

Antonin

> On 16 Mar 2017, at 14:34, Bernard Ligny <[hidden email]> wrote:
>
> Hi Camel folks
>
> I would like to have some advices/recommandations about the following
> requirement.
>
> We have a webapp with *many* Camel routes (started with Camel-CDI). This war
> is deployed on various application servers for various customers.
> Some of theses routes are common to all customers, while other routes are
> limited/dedicated to a single customer (and should therefore not be
> "deployed" for all customers)
>
> What would be the best solution to have a conditional (> depending on
> props/conf file) registration of my routes ?
> Please note I wish a conditional *registration* and not *starting* (> I do
> not want the unused routes to be part of my CamelContext, nor to be visible
> in hawt-io).
> So disabling autostart + manually starting needed routes is not an option...
>
> Any idea  ? - of something different from this:
>
>
> I was thinking about a new annotation on the routebuilder, eg
>
>
>
> Another alternative (but which requires a lot more refactoring) would be to
> have a more "micro-services" oriented approach, to break my monolithic war
> into a set of jars (each jar embedding a SINGLE RouteBuilder), and than in
> the war assembly phase, build a customer-specific artifact (that is, exclude
> the jars containing unneeded routes).
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Conditional-registration-of-routes-or-route-builders-tp5795589.html
> Sent from the Camel - Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: Conditional registration of routes (or route builders)

Bernard Ligny
This post was updated on .
Hi Antonin

Very interesting (and elegant!) suggestion.
I like the fact that
- I can leave untouched the existing code
- all the blacklisting logic is concentrated into one single class (=the extension)

I agree with you, a @Conditional annotation should be generic (ie not restricted to properties).

In the meantime, I was thinking about a third solution. Use "profile" like in Spring (again), ie:
@ApplicationScoped
public class EsbCamelContext extends CdiCamelContext {
 
    @PostConstruct
    void startUp() {
    	this.setActiveProfile("FooCustomer");   // <= NEW!	
    }
    
+

@Profile({"FooCustomer", "BarCustomer"})
public MyRouteBuilder extends RouteBuilder {   
}

OR

public MyRouteBuilder extends RouteBuilder {   
 		
        public void configure() {		
		from("direct:..")				
		.profiles("FooCustomer", "BarCustomer")  // <= NEW!	
		.to("...");
	}
}

Anyway, thanks a lot for the hint.

Regards,
Bernard.


Reply | Threaded
Open this post in threaded view
|

Re: Conditional registration of routes (or route builders)

souciance
I guess the solution I am describing doesn't apply to your case but perhaps worth as a discussion. What I have done previously is to describe my integrations via features in Karaf. Then I create a custom karaf distribution and install all the features on install level.

Then for every instance I am interested in I simply unpack the karaf distribution and only install the features I am interested in. The rest are not started. This can be automated in various ways.