artur
artur

Reputation: 1760

Apache Camel how to add/remove endpoints dynamically from a route

I am trying to get familiar with EIP and Apache Camel and I have a use case that I am not quite sure how can be expressed or implemented using Camel

Use case:

Imagine you have designed an integration solution that takes files from an ftp, does some processing and uploads it to a queue. You chose Apache Camel to implement this solution and your route in Java DSL looks something like this:

 from("ftp://user@hostname/directoryname")
   .process(new Processor() {
              public void process(Exchange exchange) throws Exception
              {
                //my fantastic prosessing goes here
              }
 }).to("jms:queue:queueName");

the route could be way more complex than this, but it doesn't matter here. Imagine your solution is such a spectacular success that there's a plan to implement a service where anyone could add his ftp server and get the files processed and uploaded to the queue. So what you want is

  1. (Flexibility) Being able to dynamically add/remove servers from your app
  2. (Scaling) Being able to handle potentially large number of such servers

Let's forget about #2 and focus on Flexibility part.

So the question is, I suppose:

How to dynamically (at runtime) add/remove endpoints to/from Apache Camel route?

What I considered so far:

First, I admit I am not that familiar with Integration Patterns, but just scanning the catalogue, the only thing that kind of could fit the bill is the Content Enricher. It can take a message and just go off to somewhere else and bring sth else. So I was thinking if someone adds an ftp server, the connection details could be encapsulated in the message and a Content Enricher could then connect to that ftp server and fetch files and push it further through the route.... so it would effectively be a Content Enricher capable of connecting to multiple ftp servers.... That kind of sound wrong. First I don't think this is the intention behind that pattern and secondly since there's ftp Component in Camel, I should somehow be able to use it in that scenario

The second approach would be to break the route into two like using the vm component, like this:

 from("ftp://user@hostname/directoryname").to("vm:internalQ");
 from("vm:internalQ")
   .process(new Processor() {
              public void process(Exchange exchange) throws Exception
              {
                //my fantastic prosessing goes here
              }
 }).to("jms:queue:queueName");

so now, I can create many routes with ftp endpoints that write to that internal queue so it can be picked up. Adding route dynamically to CamelContext seems to be possible (Add camel route at runtime in Java). Is that the way to go? Or am I just trying to use Camel in a way that it was not designed to?

Upvotes: 5

Views: 4027

Answers (1)

Anton Krosnev
Anton Krosnev

Reputation: 4122

You can dynamically add routes to your CamelContext:

MyRouteBuilder trb = new MyRouteBuilder(servletEndpoint, mockEndpoint);
camelContext.addRoutes(trb);

And MyRouteBuilder:

MyRouteBuilder(Endpoint servletEndpointStart, MockEndpoint mockEndpointEnd, String allowedParameters){
        this._servletEndpoint = servletEndpointStart;
        this._mockEndpoint = mockEndpointEnd;
    }

    @Override
    public void configure() throws Exception {
        from(this._servletEndpoint)
        .id(TESTING_ROUTE_NAME)
        .process(new Processor(){ // some processor })
        .to(_mockEndpoint);
    }

You can also modify the route, but you will need to restart it, in order to work properly, checkout how it is done in: org.apache.camel.model.RouteDefinition.adviceWith(ModelCamelContext, RouteBuilder)

Upvotes: 3

Related Questions