Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

About

...

the

...

Groovy

...

DSL

...

The

...

Groovy

...

DSL

...

implementation

...

is

...

built

...

on

...

top

...

of

...

the

...

existing

...

Java-based

...

DSL

...

,

...

but

...

it

...

additionally

...

allows

...

to

...

use

...

Groovy

...

language

...

features

...

in

...

your

...

routes,

...

particularly

...

Closures

...

acting

...

as

...

Processor

...

,

...

Expression

...

,

...

Predicate

...

,

...

or

...

Aggregation

...

Strategy

...

.

...


With

...

the

...

Groovy

...

DSL

...

you

...

write

...

your

...

RouteBuilder

...

classes

...

entirely

...

in

...

Groovy,

...

while

...

the

...

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

...

.

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 Extension Module that defines extension methods on existing classes.

The majority of the extension methods allow 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:

Code Block
java
java
titleMyRouteBuilder.groovy


h3. 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 [Extension Module|http://docs.codehaus.org/display/GROOVY/Creating+an+extension+module] that defines extension methods on existing classes.

The majority of the extension methods allow [Closures|http://groovy.codehaus.org/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: 

{code:java|title=MyRouteBuilder.groovy}
...
   from('direct:test')
      .transform { it.in.body.reverse() }
      .process { println it.in.body }
...
{code}

The

...

corresponding

...

route

...

in

...

Java

...

would

...

look

...

something

...

like

...

this:

{:=
Code Block
title
MyRouteBuilder.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());
         }
      });
...
{code}




h3. 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).

{code:xml}

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).

Code Block
xml
xml
<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-groovy</artifactId>
  <version>2.11.0</version>
</dependency>
{code}

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

...

Groovy

...

Eclipse

...

compiler:

Code Block
xml
xml

|http://groovy.codehaus.org/Groovy-Eclipse+compiler+plugin+for+Maven]:

{code: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>
{code}

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

...

Eclipse

...

Plugin

...

for

...

Groovy when mvn eclipse:eclipse

...

is

...

executed:

Code Block
xml
xml


{code: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>	  
{code}

h4. Using Closures in your routes

h5. Processor Closures

All Java DSL parameters of type {{

Using Closures in your routes

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:

{:
Code Block
java
java
}
...
   private String someValue
...
   from('direct:test')
      .process { Exchange exchange -> println exchange.in.body + someValue }
      .process { println it.in.body + someValue } // equivalent
...
{code}

h5. Expression Closures

All Java DSL parameters of type {{
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:

Code Block
java
java


{code:java}
...
   private String someValue
...
   from('direct:test')
      .transform { it.in.body.reverse() + someValue }
      .setHeader("myHeader") { someValue.reverse() }
...
{code}


h5. Predicate Closures

All Java DSL parameters of type {{
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:

Code Block
java
java


{code:java}
...
   private String someValue

   // This time, the closure is stored in a variable
   def predicate = { Exchange e -> e.in.body != someValue }
...
   from('direct:test')
      .filter(predicate)
...
{code}


h5. Aggregation Strategy Closures

Java DSL parameters of type {{
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:

Code Block
java
java


{code: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
      }
...
{code}


h4. Using Groovy XML processing

Groovy provides special [XML processing support|http://groovy.codehaus.

Using Groovy XML processing

Groovy provides special XML processing support through its XmlParser, XmlNodePrinter and XmlSlurper classes. camel-groovy provides two data formats to use these classes directly in your routes.

Code Block
java
java
titleUnmarshal XML with XmlParser
org/Processing+XML] through its {{XmlParser}}, {{XmlNodePrinter}} and {{XmlSlurper}} classes. camel-groovy provides two [data formats|data format] to use these classes directly in your routes. 

{code:java|title=Unmarshal XML with XmlParser}
...
   from('direct:test1')
      .unmarshal().gnode() 
      // message body is now of type groovy.util.Node
...
{code}

By

...

default,

...

XML

...

processing

...

is

...

namespace-aware

...

.

...

You

...

can

...

change

...

this

...

by

...

providing

...

a

...

boolean

...

false

...

parameter.

Code Block
java
java
titleUnmarshal XML with XmlSlurper


{code:java|title=Unmarshal XML with XmlSlurper}
...
   from('direct:test1')
      .unmarshal().gpath(false) // explicitly namespace-unaware
      // message body is now of type groovy.util.slurpersupport.GPathResult
...
{code}

Currently,

...

marshalling

...

is

...

only

...

supported

...

for

...

groovy.util.Node

...

objects.

Code Block
java
java
titleMarshal XML with XmlNodePrinter


{code:java|title=Marshal XML with XmlNodePrinter}
...
   from('direct:test1')
      // message body must be of type groovy.util.Node
      .marshal().gnode()
...
{code}


h4. Using Groovy GStrings

Groovy [GStrings|http://groovy.codehaus.org/Strings+and

Using Groovy GStrings

Groovy GStrings are declared inside double-quotes and can contain arbitrary Groovy expressions like accessing properties or calling methods, e.g.

Code Block
+GString] are declared inside double-quotes and can contain arbitrary Groovy expressions like accessing properties or calling methods, e.g. 
{code}
def x = "It is currently ${ new Date() }"
{code}

Because

...

GStrings

...

aren't

...

Strings,

...

camel-groovy

...

adds

...

the

...

necessary

...

TypeConverter

...

to

...

automatically

...

turn

...

them

...

into

...

the

...

required

...

type.

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 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:

Code Block
java
java
titleMyExtension.java



h4. 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 [Groovy documentation|http://docs.codehaus.org/display/GROOVY/Creating+an+extension+module]. 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:

{code:java|title=MyExtension.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);
    }

}
{code}

Add

...

a

...

corresponding

...

extension

...

module

...

descriptor

...

to

...

META-INF/services

...

:

{|=
Code Block
title
META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
}
moduleName=my-extension
moduleVersion=2.11
extensionClasses=MyExtension
staticExtensionClasses=
{code}

And

...

now

...

your

...

Groovy

...

route

...

can

...

look

...

like

...

this:

{code:java|title=
Code Block
java
java
title
MyRoute.groovy
}
...
   fromId('direct:test1')
      .fork('direct:null','direct:not-null',body().isNull())
...
{code}

Using

...

the

...

plain

...

Java

...

DSL,

...

the

...

route

...

would

...

look

...

something

...

like

...

this:

{code:java|title=
Code Block
java
java
title
MyRoute.java
}
...
   from("direct:test1")
      .routeId("direct:test1")
      .choice()
         .when(body().isNull())
            .to("direct:null")
         .otherwise()
            .to("direct:not-null");
...
{code}