blob: 9c444697ec9590ff9bef4196c42c8405b29dded2 [file] [log] [blame]
*DSL supported*
The link:scala-dsl.html[Scala DSL] supports *every* DSL from the
link:dsl.html[Java DSL].
On this page we have examples for a number of the link:eip.html[EIP]s. +
You can check the
https://svn.apache.org/repos/asf/camel/trunk/components/camel-scala/src/test/scala/[unit
test source code] for the Scala Component to find more examples.
* 1 link:#ScalaDSL-EIP-Messagingsystems[Messaging systems]
** 1.1 link:#ScalaDSL-EIP-Pipelinepipeline[Pipeline]
** 1.2 link:#ScalaDSL-EIP-Filterfilter[Filter]
* 2 link:#ScalaDSL-EIP-Messagingchannels[Messaging channels]
** 2.1 link:#ScalaDSL-EIP-Deadletterchannel[Dead letter channel]
* 3 link:#ScalaDSL-EIP-Messagerouting[Message routing]
** 3.1 link:#ScalaDSL-EIP-Aggregator[Aggregator]
** 3.2 link:#ScalaDSL-EIP-Contentbasedrouter[Content based router]
** 3.3 link:#ScalaDSL-EIP-Delayer[Delayer]
** 3.4 link:#ScalaDSL-EIP-Loadbalancer[Load balancer]
** 3.5 link:#ScalaDSL-EIP-Multicast[Multicast]
** 3.6 link:#ScalaDSL-EIP-Recipientlist[Recipient list]
** 3.7 link:#ScalaDSL-EIP-Resequencer[Resequencer]
** 3.8 link:#ScalaDSL-EIP-Splitter[Splitter]
** 3.9 link:#ScalaDSL-EIP-Throttler[Throttler]
* 4 link:#ScalaDSL-EIP-Messagetransformation[Message transformation]
** 4.1 link:#ScalaDSL-EIP-Contentenricher[Content enricher]
[[ScalaDSL-EIP-Messagingsystems]]
Messaging systems
^^^^^^^^^^^^^^^^^
[[ScalaDSL-EIP-Pipelinepipeline]]
Pipeline
++++++++
There is a simple syntax available for specifying pipeline, by simple
putting `to` or `→` between the different steps in the pipeline.
[source,java]
----------------------------------------------------------
"direct:a" --> "mock:a" --> "mock:b"
"direct:c" to "mock:c" to "mock:d"
----------------------------------------------------------
For more advanced use cases, you can also use a block-based syntax,
where every step in the pipeline starts with either `to` or `→`.
[source,java]
----------------------------------------------------------
"direct:e" ==> {
--> ("mock:e")
--> ("mock:f")
}
"direct:g" ==> {
to ("mock:g")
to ("mock:h")
}
----------------------------------------------------------
[[ScalaDSL-EIP-Filterfilter]]
Filter
++++++
For a message filter, use the `when()` method with a parameter of type
The `Exchange ⇒ Boolean`. In the example below, we use a Scala
convenience method named `in` to access the 'in' message body; only
messages where the 'in' message is `<hello/>` will arrive at the
`mock:a` endpoint.
[source,scala]
----------------------------------------------------------
"direct:a" when(_.in == "<hello/>") to("mock:a")
----------------------------------------------------------
Once again, if you need to specify a more advanced route, you can use
the more elaborate syntax.
[source,java]
----------------------------------------------------------
"direct:b" ==> {
when(_.in == "<hallo/>") {
--> ("mock:b")
to ("mock:c")
} otherwise {
to ("mock:e")
}
to ("mock:d")
}
----------------------------------------------------------
[[ScalaDSL-EIP-Messagingchannels]]
Messaging channels
^^^^^^^^^^^^^^^^^^
[[ScalaDSL-EIP-Deadletterchannel]]
Dead letter channel
+++++++++++++++++++
The http://www.eaipatterns.com/DeadLetterChannel.html[dead letter
channel] can be created with the syntax similar to the one used in
http://camel.apache.org/dead-letter-channel.html[Java DSL].
[source,java]
------------------------------------------------------------------
"jms:in" errorHandler(deadLetterChannel("jms:error")) to "jms:out"
------------------------------------------------------------------
You can also use different error handler available for the
http://camel.apache.org/error-handler.html[Java DSL]. In particular
Scala DSL supports
http://camel.apache.org/defaulterrorhandler.html[DefaultErrorHandler]
and
http://camel.apache.org/error-handler.html#ErrorHandler-LoggingErrorHandler[LoggingErrorHandler].
[source,java]
----------------------------------------------------------------------------------------------------------------
// DefaultErrorHandler
"jms:in" errorHandler(defaultErrorHandler) to "jms:out"
// LoggingErrorHandler
"jms:in" errorHandler(loggingErrorHandler.level(LoggingLevel.INFO).logName("com.example.MyLogger")) to "jms:out"
----------------------------------------------------------------------------------------------------------------
[[ScalaDSL-EIP-Messagerouting]]
Message routing
^^^^^^^^^^^^^^^
[[ScalaDSL-EIP-Aggregator]]
Aggregator
++++++++++
The aggregator EIP aggregates messages based on some message correlation
criteria. In the Scala DSL, the `aggregate` method takes a function
`Exchange ⇒ Any` to determine the correlation value for the exchange. In
the sample below, message are being aggregated if the first 7 letters in
the message body are the same.
[[ScalaDSL-EIP-Contentbasedrouter]]
Content based router
++++++++++++++++++++
Similar to the link:scala-dsl-eip.html[Filter], the content based router
uses `when` methods with `Exchange ⇒ Boolean` function literals and an
optional `otherwise`. The function literal can contain plain Scala code
as well as any of the link:scala-dsl-supported-languages.html[supported
languages]. The example below routes a given message based on the
language of the message body.
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:a" ==> {
to ("mock:polyglot")
choice {
when (_.in == "<hello/>") to ("mock:english")
when (_.in == "<hallo/>") {
to ("mock:dutch")
to ("mock:german")
}
otherwise to ("mock:french")
}
}
----------------------------------------------------------------------------------------------------------------
[[ScalaDSL-EIP-Delayer]]
Delayer
+++++++
Unlike a throttler, which only slows down messages if the rate exceeds a
treshold, a delayer delays every messages with a fixed amount of time.
An example: to delay every message going from `seda:a` to `mock:a` with
1 second, you write...
[source,java]
----------------------------------------------------------------------------------------------------------------
"seda:a" delay(1 seconds) to ("mock:a")
----------------------------------------------------------------------------------------------------------------
Our second example will delay the entire block (containing `mock:c`)
without doing anything to `mock:b`
[source,java]
----------------------------------------------------------------------------------------------------------------
"seda:b" ==> {
to ("mock:b")
delay(1 seconds) {
to ("mock:c")
}
}
----------------------------------------------------------------------------------------------------------------
[[ScalaDSL-EIP-Loadbalancer]]
Load balancer
+++++++++++++
To distribute the message handling load over multiple endpoints, we add
a `loadbalance` to our route definition. You can optionally specify a
load balancer strategy, like `roundrobin`
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:a" ==> {
loadbalance roundrobin {
to ("mock:a")
to ("mock:b")
to ("mock:c")
}
}
----------------------------------------------------------------------------------------------------------------
[[ScalaDSL-EIP-Multicast]]
Multicast
+++++++++
Multicast allows you to send a message to multiple endpoints at the same
time. In a simple route, you can specify multiple targets in the `to` or
`→` method call:
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:a" --> ("mock:a", "mock:b") --> "mock:c"
"direct:d" to ("mock:d", "mock:e") to "mock:f"
----------------------------------------------------------------------------------------------------------------
[[ScalaDSL-EIP-Recipientlist]]
Recipient list
++++++++++++++
You can handle a static recipient list with a multicast or
link:scala-dsl-eip.html[pipeline], but this EIP is usually applied when
you want to dynamically determine the name(s) of the next endpoint(s) to
route to. Use the `recipients()` method with a function literal
(`Exchange => Any`) that returns the endpoint name(s). In the example
below, the target endpoint name can be found in the String message
starting at position 21.
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:a" recipients(_.in[String].substring(21))
----------------------------------------------------------------------------------------------------------------
Because the `recipients()` method just takes a function literal, you can
basically use any kind of valid Scala code to determine the endpoint
name. Have a look at the next example which uses pattern matching to
figure out where to send the message:
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:b" recipients(_.getIn.getBody match {
case Toddler(_) => "mock:playgarden"
case _ => "mock:work"
})
----------------------------------------------------------------------------------------------------------------
Again, we can also use the same thing in a more block-like syntax. For
this example, we use the Scala DSL's
link:scala-dsl-supported-languages.html[support for JXPath] to determine
the target.
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:c" ==> {
to("mock:c")
recipients(jxpath("./in/body/destination"))
}
----------------------------------------------------------------------------------------------------------------
[[ScalaDSL-EIP-Resequencer]]
Resequencer
+++++++++++
Use the `resequence` method to add a resequencer to the RouteBuilder.
The method takes a function (`Exchange ⇒ Unit`) that determines the
value to resequence on. In this example, we resequence messages based on
the 'in' message body.
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:a" resequence (_.in) to "mock:a"
----------------------------------------------------------------------------------------------------------------
The same EIP can also be used with a block-like syntax...
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:b" ==> {
to ("mock:b")
resequence (_.in) {
to ("mock:c")
}
}
----------------------------------------------------------------------------------------------------------------
... and with configurable batch size. In this last example, messages
will be send to `mock:e` whenever a batch of 5 messages is available.
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:d" ==> {
to ("mock:d")
resequence(_.in).batch(5) {
to ("mock:e")
}
}
----------------------------------------------------------------------------------------------------------------
[[ScalaDSL-EIP-Splitter]]
Splitter
++++++++
To handle large message in smaller chunks, you can write a Scala
`Exchange ⇒ Any*` method and add it to your route with the `splitter`
method. As with many other EIPs, we support a short, in-line version as
well as a more elaborate block based one.
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:a" as(classOf[Document]) split(xpath("/persons/person")) to "mock:a"
----------------------------------------------------------------------------------------------------------------
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:b" ==> {
as(classOf[Document])
split(xpath("/persons/person")) {
to("mock:b")
to("mock:c")
}
}
----------------------------------------------------------------------------------------------------------------
The above examples also show you how
link:scala-dsl-supported-languages.html[other languages] like XPath can
be within the Scala DSL.
[[ScalaDSL-EIP-Throttler]]
Throttler
+++++++++
The throttler allows you to slow down messages before sending them
along. The `throttle` methods allows you to specify the maximum
throughput rate of message:
[source,java]
----------------------------------------------------------------------------------------------------------------
"seda:a" throttle (3 per (2 seconds)) to ("mock:a")
----------------------------------------------------------------------------------------------------------------
It can also be used in front of block to throttle messages at that
point. In the example below, message are passed on to `mock:b` in a
normal rate (i.e. as fast as possible), but a maximum 3 messages/2
seconds will arrive at the `mock:c` endpoint.
[source,java]
----------------------------------------------------------------------------------------------------------------
"seda:b" ==> {
to ("mock:b")
throttle (3 per (2 seconds)) {
to ("mock:c")
}
}
----------------------------------------------------------------------------------------------------------------
[[ScalaDSL-EIP-Messagetransformation]]
Message transformation
^^^^^^^^^^^^^^^^^^^^^^
[[ScalaDSL-EIP-Contentenricher]]
Content enricher
++++++++++++++++
Using a processor function (`Exchange → Unit`), you can alter/enrich the
message content. This example uses a simple function literal to append
`" says Hello"` to the message content:
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:a" process(_.in += " says hello") to ("mock:a")
----------------------------------------------------------------------------------------------------------------
However, you can also define a separate method/function to handle the
transformation and pass that to the `process` method instead. The
example below uses pattern matching to enrich the message content:
[source,java]
----------------------------------------------------------------------------------------------------------------
val myProcessor = (exchange: Exchange) => {
exchange.in match {
case "hello" => exchange.in = "hello from the UK"
case "hallo" => exchange.in = "hallo vanuit Belgie"
case "bonjour" => exchange.in = "bonjour de la douce France"
}
}
"direct:b" process(myProcessor) to ("mock:b")
----------------------------------------------------------------------------------------------------------------
Off course, you can also use any other Camel component (e.g.
link:velocity.html[Velocity]) to enrich the content and add it to a
pipeline
[source,java]
----------------------------------------------------------------------------------------------------------------
"direct:c" to ("velocity:org/apache/camel/scala/dsl/enricher.vm") to ("mock:c")
----------------------------------------------------------------------------------------------------------------