Added scala-dsl stuff in Gitbook
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/e148a9c1 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/e148a9c1 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/e148a9c1 Branch: refs/heads/master Commit: e148a9c1e4cf39f33c07fe8f83bd07ff018b9c2e Parents: 5145752 Author: Andrea Cosentino <anco...@gmail.com> Authored: Tue Jul 19 11:21:19 2016 +0200 Committer: Andrea Cosentino <anco...@gmail.com> Committed: Tue Jul 19 11:21:19 2016 +0200 ---------------------------------------------------------------------- docs/user-manual/en/SUMMARY.md | 3 + docs/user-manual/en/scala-dsl-eip.adoc | 407 +++++++++++++++++++ .../en/scala-dsl-getting-started.adoc | 64 +++ .../en/scala-dsl-supported-languages.adoc | 45 ++ 4 files changed, 519 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/e148a9c1/docs/user-manual/en/SUMMARY.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/SUMMARY.md b/docs/user-manual/en/SUMMARY.md index 3230475..539ab1d 100644 --- a/docs/user-manual/en/SUMMARY.md +++ b/docs/user-manual/en/SUMMARY.md @@ -21,6 +21,9 @@ * [Java DSL](java-dsl.adoc) * [Groovy DSL](groovy-dsl.adoc) * [Scala DSL](scala-dsl.adoc) + * [Scala DSL Getting Started](scala-dsl-getting-started.adoc) + * [Scala DSL EIP](scala-dsl-eip.adoc) + * [Scala DSL Supported Languages](scala-dsl-supported-languages.adoc) * [Endpoint](endpoint.adoc) * [Exchange](exchange.adoc) * [Exchange Pattern](exchange-pattern.adoc) http://git-wip-us.apache.org/repos/asf/camel/blob/e148a9c1/docs/user-manual/en/scala-dsl-eip.adoc ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/scala-dsl-eip.adoc b/docs/user-manual/en/scala-dsl-eip.adoc new file mode 100644 index 0000000..9c44469 --- /dev/null +++ b/docs/user-manual/en/scala-dsl-eip.adoc @@ -0,0 +1,407 @@ +*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") +---------------------------------------------------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/e148a9c1/docs/user-manual/en/scala-dsl-getting-started.adoc ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/scala-dsl-getting-started.adoc b/docs/user-manual/en/scala-dsl-getting-started.adoc new file mode 100644 index 0000000..8db7b26 --- /dev/null +++ b/docs/user-manual/en/scala-dsl-getting-started.adoc @@ -0,0 +1,64 @@ +Just like the link:dsl.html[Java DSL], the Scala DSL has a RouteBuilder +class (`org.apache.camel.scala.dsl.builder.RouteBuilder`) that you can +extend to implement your own routes. This example shows two very simple +routes: + +[source,java] +---------------------------------------------------------- +class MyRouteBuilder extends RouteBuilder { + "direct:a" --> "mock:a" + "direct:b" to "mock:b" +} +---------------------------------------------------------- + +INFO: From *Camel 2.15* onwards use +org.apache.camel.scala.dsl.builder.ScalaRouteBuilder and pass in the +CamelContext in the constructor, which will be used by the builder. The +old class RouteBuilder is deprecated. + + +If you compare this to the Java link:dsl.html[DSL], you notice: + +* there is no configure() method to override +* a route starts directly with a URI instead of `from(uri)` +* `â` is just an alias for `to` + +[[ScalaDSL-GettingStarted-SettingtherouteID]] +Setting the route ID +^^^^^^^^^^^^^^^^^^^^ + +To assign the unique ID to the Scala route, insert the `routeId` method +invocation after the "from" part of the DSL. + +[source,java] +----------------------------------------- + "direct:a" routeId "route-b" to "mock:b" +----------------------------------------- + +[[ScalaDSL-GettingStarted-CreatinganewCamelScalaproject]] +Creating a new Camel Scala project +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Camel offers link:camel-maven-archetypes.html[Maven archetypes] that +allow you to quickly setup a new project. + +To do this, you can execute the following Maven goal from the command +line (using Maven 3.0.3 or better): + +[source,java] +---------------------- +mvn archetype:generate +---------------------- + +This runs Maven interactively - just type `camel` and press <Enter> to +filter for Camel-related archetypes. + + From the list, pick the number for `camel-archetype-scala`, then fill +in the remaining details (such as the Camel version, _et cetera_). + +The generated project has a "readme" file with more instructions, and is +ready to compile and run from Maven using: + +[source,java] +--------------------- +mvn compile exec:java +--------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/e148a9c1/docs/user-manual/en/scala-dsl-supported-languages.adoc ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/scala-dsl-supported-languages.adoc b/docs/user-manual/en/scala-dsl-supported-languages.adoc new file mode 100644 index 0000000..5d74b17 --- /dev/null +++ b/docs/user-manual/en/scala-dsl-supported-languages.adoc @@ -0,0 +1,45 @@ +Support for link:languages.html[other languages] inside the Scala DSL +routes is delivered through traits. The +`org.apache.camel.scala.dsl.languages` package currently offers traits +to support XPath. To use any given language, you can mix-in the trait +when creating your `RouteBuilder`. + +You can use any of the supported Camel link:languages.html[Languages] in +the link:scala-dsl.html[Scala DSL]; see below for a couple of examples: + +[[ScalaDSL-Supportedlanguages-Using]] +Using link:xpath.html[XPath] +++++++++++++++++++++++++++++ + +With the XPath trait, you have an additional method available on an +`Exchange` to do XPath queries against the message. Just look at this +Splitter example, where the `xpath` method is used in a +`Exchange â Any*` function literal + +[source,java] +---------------------------------------------------------- +"direct:b" ==> { + as(classOf[Document]) + split(xpath("/persons/person")) { + to("mock:b") + to("mock:c") + } +} +---------------------------------------------------------- + +[[ScalaDSL-Supportedlanguages-Using.1]] +Using link:jxpath.html[JXPath] +++++++++++++++++++++++++++++++ + +With the `org.apache.camel.scala.dsl.languages.JXPath` trait, you can an +additional `jxpath` method on the `Exchange`. In the Recipient List +example below, JXPath is used for getting the next endpoint's name out +of the message body. + +[source,java] +---------------------------------------------------------- +"direct:c" ==> { + to("mock:c") + recipients(jxpath("./in/body/destination")) +} +----------------------------------------------------------