Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Camel - extend Java DSL?

Tags:

apache-camel

I've got a repeating pattern in my routes - a certain Processor needs the same 3 Headers set every time I call it, so I've got the following code in my routes about 10+ times:

.whatever()
.setHeader("foo1", "bar1")
.setHeader("foo2", "bar2")
.setHeader("foo3", "bar3")
.processRef("processorBazThatNeedsHeaders")
.whatever()

The headers are populated differently every time, so abstracting this out into a subroute doesn't really buy me anything.

What I love to be able to do is subclass RouteDefinition to have another method in my DSL that would allow me to do this:

.whatever()
.bazProcessor("bar1", "bar2", "bar3")
.whatever()

and in 'bazProcessor', set the headers and call the processor.

I've tried to do this but it seems that it's only possible with some serious probably-not-future-proof surgery, and it seems that others have had similar luck.

I need them to be set as headers as opposed to passing them as parameters directly to the processor because the values are also used after the processor for routing.

Is there some hidden facility to achieve something like this?

like image 986
Roy Truelove Avatar asked Nov 04 '11 13:11

Roy Truelove


People also ask

What is DSL in Camel?

Camel uses a Java Domain Specific Language or DSL for creating Enterprise Integration Patterns or Routes in a variety of domain-specific languages (DSL) as listed below: Java DSL - A Java based DSL using the fluent builder style.

Is Apache Camel outdated?

Many open source projects and closed source technologies did not withstand the tests of time and have disappeared from the middleware stacks for good. After a decade, however, Apache Camel is still here and becoming even stronger for the next decade of integration.

What is direct in Camel?

The direct: component provides direct, synchronous invocation of any consumers when a producer sends a message exchange. This endpoint can be used to connect existing routes in the same camel context.

What is REST DSL?

The Rest DSL is a facade that builds Rest endpoints as consumers for Camel routes. The actual REST transport is leveraged by using Camel REST components such as Netty HTTP, Servlet, and others that has native REST integration.


2 Answers

By subclassing the RouteDefinition your extension will only be visible direct after from(...). This could be a limitation if you would like to use the DSL extension for example after the filter(...) DSL.

A simpler approach would be to encapsulate the logic somewhere, and use it in a class that implements the org.apache.camel.Processor interface, and then call an overload of .process(...), or bean(...) in the route to use the logic. You will be actually very closed to a DSL extension if you use a meaningful name for the Processor instance or a method, that returns that Processor instance. Here is an example of the suggested approach. At the end, your code could look like:

.whatever()
.process(setTheHeadersForBaz)
.whatever()

Just for reference: if you really need to do a DSL, there is a project that extends the Camel DSL based on Groovy. I guess a Scala way based on the Camel Scala DSL could be also an option.

like image 62
i000174 Avatar answered Sep 28 '22 04:09

i000174


Though slightly irrelevant, following is an example of extending Scala DSL.

We can create an implicit methods to DSL trait via an implicit class.

object DSLImplicits {
  implicit class RichDSL(val dsl: DSL) {
    def get = dsl.setHeader(Exchange.HTTP_METHOD, _ => HttpMethods.GET.name)

    def post = dsl.setHeader(Exchange.HTTP_METHOD, _ => HttpMethods.POST.name)
  }
}

And use it like this.

import DSLImplicits.RichDSL
//----------------------------
from("someWhere")
  //Do some processing
  .get.to("http://somewhere.com")

More details @ http://siliconsenthil.in/blog/2013/07/11/apache-camel-with-scala-extending-dsl/

like image 22
siliconsenthil Avatar answered Sep 28 '22 04:09

siliconsenthil