简体   繁体   中英

Apache Camel - Build both from and to endpoints dynamically

I have a camel route which processes a message from a process queue and sends it to upload queue .

from("activemq:queue:process" ).routeId("activemq_processqueue")
        .process(exchange -> {
            SomeImpl impl = new SomeImpl();
            impl.process(exchange);
        })
        .to(ExchangePattern.InOnly, "activemq:queue:upload");

In impl.process I am populating an Id and destination server path . Now I need to define a new route which consumes messages from upload queue ,and copy a local folder (based on Id generated in previous route) and upload it to destination folder which is an ftp server (this is also populated in previous route)

So how to design a new route where both from and to endpoints are dynamic which would look something like below ?

from("activemq:queue:upload" )
        .from("file:basePath/"+{idFromExchangeObject})
    .to("ftp:"+{serverIpFromExchangeObject}+"/"+{pathFromExchangeObject});

Adding a dynamic to endpoint in Camel (as noted in the comment) can be done with the .toD() which is described on this page on the Camel site. I don't know of any fromD() equivalent. However, you could add a dynamic route by calling the addRoutes method on the CamelContext . This is described on this page on the Camel site.

Expanding slightly on the example from the Camel site here is something that should get you heading in the right direction.

public void process(Exchange exchange) throws Exception {
   String idFromExchangeObject = ...
   String serverIpFromExchangeObject = ...
   String pathFromExchangeObject = ...

   exchange.getContext().addRoutes(new RouteBuilder() {
       public void configure() {
           from("file:basePath/"+ idFromExchangeObject)
            .to("ftp:"+ serverIpFromExchangeObject +"/"+pathFromExchangeObject);
       }
   });
}

There may be other options in Camel as well since this framework has an amazing number of EIP and capabilities.

I think there is a better alternative for your case, taking as granted that you are using a Camel version newer than 2.16.(alternatives for a previous version exist but the are more complicated and don't look elegant - ( eg consumerTemplate & recipientList).

You can replace the first "dynamic from" with pollEnrich which enriches the message using a polling consumer and simple expression to build the dynamic file endpoint. For the second part, as already mentioned, a dynamic uri .toD will do the job. So your route would look like this:

 from("activemq:queue:upload" )
    .pollEnrich().simple("file:basePath/${header.idFromExchangeObject})
    .aggregationStrategy(new ExampleAggregationStrategy()) // * see explanation 
    .timeout(2000) // the timeout is optional but recommended
    .toD("ftp:${header.serverIpFromExchangeObject}/${header.pathFromExchangeObject}") 
  1. See content enricher section "Using dynamic uris" http://camel.apache.org/content-enricher.html .

    You will need an aggregation strategy, to combine the original exchange with the resource exchange in order to make sure that the headers serverIpFromExchangeObject, pathFromExchangeObject will be included in the aggregated exchange after the enrichment. If you don't include the custom strategy then Camel will by default use the body obtained from the resource. Have a look at the ExampleAggregationStrategy example in content-enricher.html to see how this works.

  2. For the .toD() have a look at http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM