You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2016/07/19 09:00:21 UTC

[5/6] camel git commit: Added DSL and Groovy-DSL docs to Gitbook

Added DSL and Groovy-DSL docs to Gitbook


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/70d6968f
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/70d6968f
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/70d6968f

Branch: refs/heads/master
Commit: 70d6968fd5c2a79f2eb874bf6a854d8d3aaf58c3
Parents: b308eda
Author: Andrea Cosentino <an...@gmail.com>
Authored: Tue Jul 19 10:50:00 2016 +0200
Committer: Andrea Cosentino <an...@gmail.com>
Committed: Tue Jul 19 10:50:00 2016 +0200

----------------------------------------------------------------------
 docs/user-manual/en/SUMMARY.md      |   3 +-
 docs/user-manual/en/dsl.adoc        |  44 ++++
 docs/user-manual/en/groovy-dsl.adoc | 402 +++++++++++++++++++++++++++++++
 3 files changed, 448 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/70d6968f/docs/user-manual/en/SUMMARY.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/SUMMARY.md b/docs/user-manual/en/SUMMARY.md
index 610d9d4..448836f 100644
--- a/docs/user-manual/en/SUMMARY.md
+++ b/docs/user-manual/en/SUMMARY.md
@@ -17,6 +17,8 @@
     * [Delay Interceptor](delay-interceptor.adoc)
     * [Dependency Injection](dependency-injection.adoc)
     * [Dozer Type Conversion](dozer-type-conversion.adoc)
+    * [DSL](dsl.adoc)
+        * [Groovy DSL](groovy-dsl.adoc)
     * [Endpoint](endpoint.adoc)
     * [Exchange](exchange.adoc)
     * [Exchange Pattern](exchange-pattern.adoc)
@@ -28,7 +30,6 @@
 <!--
     * [AOP](aop.adoc)
     * [Camel-Core](camel-core.adoc)
-    * [DSL](dsl.adoc)
     * [Error Handler](.adoc)
     * [Expression](.adoc)
     * [Injector](.adoc)

http://git-wip-us.apache.org/repos/asf/camel/blob/70d6968f/docs/user-manual/en/dsl.adoc
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/dsl.adoc b/docs/user-manual/en/dsl.adoc
new file mode 100644
index 0000000..31f10ad
--- /dev/null
+++ b/docs/user-manual/en/dsl.adoc
@@ -0,0 +1,44 @@
+[[DSL-DSL]]
+DSL
+~~~
+
+Camel uses a Java _Domain Specific Language_ or DSL for creating
+link:enterprise-integration-patterns.html[Enterprise Integration
+Patterns] or link:routes.html[Routes] in a variety of domain-specific
+languages (DSL) as listed below.
+
+* link:java-dsl.html[Java DSL] - A Java based DSL using the fluent
+builder style.
+* link:spring.html[Spring XML] - A XML based DSL in Spring XML files
+* link:using-osgi-blueprint-with-camel.html[Blueprint XML] - A XML based
+DSL in OSGi Blueprint XML files
+* link:rest-dsl.html[Rest DSL] - A DSL to define REST services using a
+REST style in either Java or XML.
+* link:groovy-dsl.html[Groovy DSL] - A Groovy based DSL using Groovy
+programming language
+* link:scala-dsl.html[Scala DSL] - A Scala based DSL using Scala
+programming language
+* link:bean-integration.html[Annotation DSL] - Use annotations in Java
+beans.
+* https://github.com/koolio/kool/tree/master/kool-camel[Kotlin DSL] -
+*Work in progress* - Currently developed outside ASF, but will we
+included later in Camel when Kotlin and the DSL is ready.
+
+The main entry points for the DSL are
+
+* link:camelcontext.html[CamelContext] for creating a Camel routing
+rulebase
+* link:routebuilder.html[RouteBuilder] for creating a collection of
+routes using the routing DSL
+
+[[DSL-SeeAlso]]
+See Also
+^^^^^^^^
+
+For more examples of the DSL in action see
+
+* link:enterprise-integration-patterns.html[Enterprise Integration
+Patterns]
+* link:examples.html[Examples]
+* link:routes.html[Routes]
+

http://git-wip-us.apache.org/repos/asf/camel/blob/70d6968f/docs/user-manual/en/groovy-dsl.adoc
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/groovy-dsl.adoc b/docs/user-manual/en/groovy-dsl.adoc
new file mode 100644
index 0000000..8f3c126
--- /dev/null
+++ b/docs/user-manual/en/groovy-dsl.adoc
@@ -0,0 +1,402 @@
+[[GroovyDSL-AbouttheGroovyDSL]]
+About the Groovy DSL
+^^^^^^^^^^^^^^^^^^^^
+
+The Groovy DSL implementation is built on top of the existing Java-based
+link:dsl.html[DSL], but it additionally allows to use Groovy language
+features in your routes, particularly
+http://www.groovy-lang.org/closures.html[Closures] acting as
+link:processor.html[Processor], link:expression.html[Expression],
+link:predicate.html[Predicate], or link:aggregator.html[Aggregation
+Strategy]. +
+ With the Groovy DSL you write your RouteBuilder classes entirely in
+Groovy, while the link:scripting-languages.html[scripting component]
+allows to embed small scripts into Java routes. The Groovy DSL requires
+Groovy 2.0 or newer and is available as of *Camel 2.11*.
+
+[[GroovyDSL-Introduction]]
+Introduction
+^^^^^^^^^^^^
+
+Because Groovy is syntactically very similar to Java, you can write your
+Groovy routes just like Java routes. The same Java DSL classes are being
+used, with the exception that some of the DSL classes get extended with
+a bunch of new methods at runtime. This is achieved by turning
+camel-groovy into a Groovy
+http://docs.codehaus.org/display/GROOVY/Creating+an+extension+module[Extension
+Module] that defines extension methods on existing classes.
+
+The majority of the extension methods allow
+http://www.groovy-lang.org/closures.html[Closures] to be used as
+parameters e.g. for expressions, predicates, processors. The following
+example reverses a string in the message body and then prints the value
+to System.out:
+
+*MyRouteBuilder.groovy*
+
+[source,java]
+-----------------------------------------
+...
+   from('direct:test')
+      .transform { it.in.body.reverse() }
+      .process { println it.in.body }
+...
+-----------------------------------------
+
+The corresponding route in Java would look something like this:
+
+*MyRouteBuilder.java*
+
+[source,java]
+-----------------------------------------------------------------------------------------
+...
+   from("direct:test")
+      .transform(new Expression() {
+         @Override
+         public Object evaluate(Exchange e) {
+            return new StringBuffer(e.getIn().getBody().toString()).reverse().toString();
+         }
+      })
+      .process(new Processor() {
+         @Override
+         public void process(Exchange e) {
+           System.out.println(e.getIn().getBody());
+         }
+      });
+...
+-----------------------------------------------------------------------------------------
+
+[[GroovyDSL-DevelopingwiththeGroovyDSL]]
+Developing with the Groovy DSL
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To be able to use the Groovy DSL in your camel routes you need to add
+the a dependency on *camel-groovy* which implements the Groovy DSL.
+
+If you use Maven you can just add the following to your pom.xml,
+substituting the version number for the latest & greatest release (see
+the download page for the latest versions).
+
+[source,xml]
+---------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-groovy</artifactId>
+  <version>2.11.0</version>
+</dependency>
+---------------------------------------
+
+Additionally you need to make sure that the Groovy classes will be
+compiled. You can either use gmaven for this or, particularly with mixed
+projects containing Java and Groovy code, you might want to use the
+http://groovy.codehaus.org/Groovy-Eclipse+compiler+plugin+for+Maven[Groovy
+Eclipse compiler]:
+
+[source,xml]
+--------------------------------------------------------
+  <plugin>
+    <artifactId>maven-compiler-plugin</artifactId>
+    <configuration>
+      <compilerId>groovy-eclipse-compiler</compilerId>
+    </configuration>
+    <dependencies>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-eclipse-compiler</artifactId>
+    <version>2.7.0-01</version>
+      </dependency>
+    </dependencies>
+  </plugin>
+--------------------------------------------------------
+
+As Eclipse user, you might want to configure the Maven Eclipse plugin in
+a way so that your project is set up correctly for using
+http://groovy.codehaus.org/Eclipse+Plugin[Eclipse Plugin for Groovy]
+when `mvn eclipse:eclipse` is executed:
+
+[source,xml]
+----------------------------------------------------------------------------------------
+  <plugin>
+    <groupId>org.apache.maven.plugins</groupId>
+    <artifactId>maven-eclipse-plugin</artifactId>
+    <configuration>
+      <additionalProjectnatures>
+        <projectnature>org.eclipse.jdt.groovy.core.groovyNature</projectnature>
+      </additionalProjectnatures>
+      <classpathContainers>
+        <classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer>
+        <classpathContainer>GROOVY_DSL_SUPPORT</classpathContainer>
+      </classpathContainers>              
+    </configuration>
+  </plugin>     
+----------------------------------------------------------------------------------------
+
+[[GroovyDSL-UsingClosuresinyourroutes]]
+Using Closures in your routes
++++++++++++++++++++++++++++++
+
+Groovy closures can be used to write concise implementations of Camel
+processors, expressions, predicates, and aggregation strategies. It is
+recommended to keep more complicated implementations of these objects in
+their own classes, e.g. to be able to test them more easily and not to
+clutter up your routes with business logic.
+
+[[GroovyDSL-ProcessorClosures]]
+Processor Closures
+
+All Java DSL parameters of type `org.apache.camel.Processor` can be
+replaced by a closure that accepts an object of type
+`org.apache.camel.Exchange` as only parameter. The return value of the
+closure is disregarded. All closures may also refer to variables not
+listed in their parameter list. Example:
+
+[source,java]
+------------------------------------------------------------------------------
+...
+   private String someValue
+...
+   from('direct:test')
+      .process { Exchange exchange -> println (exchange.in.body + someValue) }
+      .process { println (it.in.body + someValue) } // equivalent
+...
+------------------------------------------------------------------------------
+
+[[GroovyDSL-ExpressionClosures]]
+Expression Closures
+
+All Java DSL parameters of type `org.apache.camel.Expression` can be
+replaced by a closure that accepts an object of type
+`org.apache.camel.Exchange` as only parameter. The return value of the
+closure is the result of the expression. Example:
+
+[source,java]
+-----------------------------------------------------
+...
+   private String someValue
+...
+   from('direct:test')
+      .transform { it.in.body.reverse() + someValue }
+      .setHeader("myHeader") { someValue.reverse() }
+...
+-----------------------------------------------------
+
+[[GroovyDSL-PredicateClosures]]
+Predicate Closures
+
+All Java DSL parameters of type `org.apache.camel.Predicate` can be
+replaced by a closure that accepts an object of type
+`org.apache.camel.Exchange` as only parameter. The return value of the
+closure is translated into a boolean value representing the result of
+the predicate. Example:
+
+[source,java]
+------------------------------------------------------
+...
+   private String someValue
+
+   // This time, the closure is stored in a variable
+   def pred = { Exchange e -> e.in.body != someValue }
+...
+   from('direct:test')
+      .filter(pred)
+...
+------------------------------------------------------
+
+[[GroovyDSL-AggregationStrategyClosures]]
+Aggregation Strategy Closures
+
+Java DSL parameters of type
+`org.apache.camel.processor.aggregate.AggregationStrategy` can be
+replaced by a closure that accepts two objects of type
+`org.apache.camel.Exchange` representing the two Exchanges to be
+aggregated. The return value of the closure must be the aggregated
+Exchange. Example:
+
+[source,java]
+-------------------------------------------------------------------------
+...
+   private String separator
+...
+   from('direct:test1')
+      .enrich('direct:enrich') { Exchange original, Exchange resource -> 
+         original.in.body += resource.in.body + separator
+         original  // don't forget to return resulting exchange
+      }
+...
+-------------------------------------------------------------------------
+
+[[GroovyDSL-Genericclosurebridges]]
+Generic closure bridges
+
+In addition to the above-mentioned DSL extensions, you can use closures
+even if no DSL method signature with closure parameters is available.
+Assuming there's no `filter(Closure)` method, you could instead write:
+
+[source,java]
+---------------------------------------------------------
+...
+   private String someValue
+
+   // This time, the closure is stored in a variable
+   def pred = { Exchange e -> e.in.body != someValue }
+...
+   from('direct:test')
+      // predicate(Closure) -> org.apache.camel.Predicate
+      .filter(predicate(pred))
+...
+---------------------------------------------------------
+
+Similarly, `expression(Closure)` returns a Camel expression,
+`processor(Closure)` returns a Processor, and `aggregator(Closure)`
+returns an AggregationStrategy.
+
+[[GroovyDSL-UsingGroovyXMLprocessing]]
+Using Groovy XML processing
++++++++++++++++++++++++++++
+
+Groovy provides special http://groovy-lang.org/processing-xml.html[XML
+processing support] through its `XmlParser`, `XmlNodePrinter` and
+`XmlSlurper` classes. camel-groovy provides two
+link:data-format.html[data formats] to use these classes directly in
+your routes.
+
+*Unmarshal XML with XmlParser*
+
+[source,java]
+-----------------------------------------------------
+...
+   from('direct:test1')
+      .unmarshal().gnode() 
+      // message body is now of type groovy.util.Node
+...
+-----------------------------------------------------
+
+By default, XML processing is _namespace-aware_. You can change this by
+providing a boolean `false` parameter.
+
+*Unmarshal XML with XmlSlurper*
+
+[source,java]
+---------------------------------------------------------------------------
+...
+   from('direct:test1')
+      .unmarshal().gpath(false) // explicitly namespace-unaware
+      // message body is now of type groovy.util.slurpersupport.GPathResult
+...
+---------------------------------------------------------------------------
+
+Currently, marshalling is only supported for `groovy.util.Node` objects.
+
+*Marshal XML with XmlNodePrinter*
+
+[source,java]
+------------------------------------------------------
+...
+   from('direct:test1')
+      // message body must be of type groovy.util.Node
+      .marshal().gnode()
+...
+------------------------------------------------------
+
+[[GroovyDSL-UsingGroovyGStrings]]
+Using Groovy GStrings
++++++++++++++++++++++
+
+Groovy
+http://docs.groovy-lang.org/latest/html/documentation/index.html#all-strings[GStrings]
+are declared inside double-quotes and can contain arbitrary Groovy
+expressions like accessing properties or calling methods, e.g.
+
+[source,java]
+-----------------------------------------
+def x = "It is currently ${ new Date() }"
+-----------------------------------------
+
+Because GStrings aren't Strings, camel-groovy adds the necessary
+link:type-converter.html[TypeConverter] to automatically turn them into
+the required type.
+
+[[GroovyDSL-CustomDSLextensions]]
+Custom DSL extensions
++++++++++++++++++++++
+
+You can easily define your custom extensions - be it as a Java DSL
+extension for your Groovy routes or for any other class unrelated to
+Camel. All you have to do is to write your extension methods and provide
+a extension module descriptor - the details are described in the
+http://www.groovy-lang.org/metaprogramming.html#_extension_modules[Groovy
+documentation]. And as long as you don't require other extension
+methods, you can even use plain Java code to achieve this! +
+ As an example, let's write two DSL extensions to make commonly used DSL
+methods more concise:
+
+*MyExtension.java*
+
+[source,java]
+-------------------------------------------------------------------------------------------------------------------------------
+import org.apache.camel.Endpoint;
+import org.apache.camel.Predicate;
+
+public final class MyExtension {
+    private MyExtension() {
+        // Utility Class
+    }
+
+    // Set the id of a route to its consumer URI
+    public static RouteDefinition fromId(RouteDefinition delegate, String uri) {
+       return delegate.from(uri).routeId(uri);
+    }
+
+    public static RouteDefinition fromId(RouteDefinition delegate, Endpoint endpoint) {
+       return delegate.from(endpoint).routeId(endpoint.getEndpointUri());
+    }
+
+    // Make common choice pattern more concise
+
+    public static ProcessorDefinition<?> fork(ProcessorDefinition<?> delegate, String uri1, String uri2, Predicate predicate) {
+       return delegate.choice().when(predicate).to(uri1).otherwise().to(uri2);
+    }
+
+}
+-------------------------------------------------------------------------------------------------------------------------------
+
+Add a corresponding extension module descriptor to `META-INF/services`:
+
+*META-INF/services/org.codehaus.groovy.runtime.ExtensionModule*
+
+[source,java]
+----------------------------
+moduleName=my-extension
+moduleVersion=2.11
+extensionClasses=MyExtension
+staticExtensionClasses=
+----------------------------
+
+And now your Groovy route can look like this:
+
+*MyRoute.groovy*
+
+[source,java]
+------------------------------------------------------------
+...
+   fromId('direct:test1')
+      .fork('direct:null','direct:not-null',body().isNull())
+...
+------------------------------------------------------------
+
+Using the plain Java DSL, the route would look something like this:
+
+*MyRoute.java*
+
+[source,java]
+-----------------------------------
+...
+   from("direct:test1")
+      .routeId("direct:test1")
+      .choice()
+         .when(body().isNull())
+            .to("direct:null")
+         .otherwise()
+            .to("direct:not-null");
+...
+-----------------------------------