Apache Camel - Build both from and to endpoints dy

2019-07-08 23:31发布

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});

2条回答
放荡不羁爱自由
2楼-- · 2019-07-09 00:16

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.

查看更多
小情绪 Triste *
3楼-- · 2019-07-09 00:22

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 - ( e.g 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
查看更多
登录 后发表回答