INT-2088 added documentation for scripting and updated groovy section
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
xmlns:ns="http://docbook.org/ns/docbook">
|
||||
<title>Groovy support</title>
|
||||
|
||||
<para>With Spring Integration 2.0 we've added Groovy support allowing you to
|
||||
<para>In Spring Integration 2.0 we added Groovy support allowing you to
|
||||
use the Groovy scripting language to provide the logic for
|
||||
various integration components similar to the way the Spring Expression Language
|
||||
(SpEL) is supported for routing, transformation and other integration
|
||||
@@ -17,18 +17,15 @@
|
||||
|
||||
<section id="groovy-config">
|
||||
<title>Groovy configuration</title>
|
||||
|
||||
<para>Depending on the complexity of your integration requirements Groovy
|
||||
scripts could be provided inline as CDATA in XML configuration or as a
|
||||
reference to a file containing the Groovy script. To enable Groovy support
|
||||
Spring Integration defines a
|
||||
<classname>GroovyScriptExecutingMessageProcessor</classname> which will
|
||||
bind the Message Payload as a
|
||||
<code>payload</code> variable and the Message Headers as a <code>headers</code>
|
||||
variable within the script execution context. All that is left for you to do is
|
||||
write a script that uses those
|
||||
variables. Below are a couple of sample configurations:</para>
|
||||
|
||||
<para>
|
||||
With Spring Integration 2.1, Groovy Support's configuration namespace
|
||||
is an extension of Spring Integration's Scripting Support and shares the core configuration
|
||||
and behavior described in detail in the
|
||||
<xref linkend="scripting">Scripting Support</xref> section. Even though Groovy scripts are
|
||||
well supported by generic Scripting Support, Groovy Support provides the
|
||||
<emphasis>Groovy</emphasis> configuration namespace which is backed by the Spring Framework's
|
||||
<classname>org.springframework.scripting.groovy.GroovyScriptFactory</classname> and related components,
|
||||
offering extended capabilities for using Groovy. Below are a couple of sample configurations:</para>
|
||||
<para><emphasis>Filter</emphasis> <programlisting language="xml"><int:filter input-channel="referencedScriptInput">
|
||||
<int-groovy:script location="some/path/to/groovy/file/GroovyFilterTests.groovy"/>
|
||||
</int:filter>
|
||||
@@ -38,89 +35,19 @@
|
||||
return payload == 'good'
|
||||
]]></int-groovy:script>
|
||||
</int:filter></programlisting>
|
||||
As the above examples show, the configuration looks identical to the general Scripting Support configuration. The only
|
||||
difference is the use of the Groovy namespace as indicated in the examples by the <emphasis>int-groovy</emphasis> namespace prefix.
|
||||
Also note that the <code>lang</code> attribute on the <code><script></code> tag is not valid in this namespace.
|
||||
</para>
|
||||
|
||||
Here, you see that the script can be included inline
|
||||
or via the <code>location</code> attribute using the groovy namespace
|
||||
support.</para>
|
||||
|
||||
<para>Other supported elements are <emphasis>router, service-activator,
|
||||
transformer, and splitter. The configuration would look identical to that
|
||||
above other than the main element's name.</emphasis></para>
|
||||
|
||||
<para>Another interesting aspect of using Groovy support is the framework's
|
||||
ability to update (reload) scripts without restarting the Application
|
||||
Context. To accomplish this, all you need to do is specify
|
||||
the <code>refresh-check-delay</code> attribute on the <emphasis>script</emphasis>
|
||||
element.
|
||||
|
||||
<programlisting language="xml"><int-groovy:script location="..." refresh-check-delay="5000"/></programlisting>
|
||||
|
||||
In the above example any invocations that occur within the 5 seconds immediately following the
|
||||
updating of the script would still be using the old script. However, any invocation that occurs
|
||||
after those 5 seconds have elapsed will
|
||||
result in execution of the new script. This is a good example where 'near real
|
||||
time' is acceptable.
|
||||
|
||||
<programlisting language="xml"><int-groovy:script location="..." refresh-check-delay="0"/></programlisting>
|
||||
|
||||
In the above example the context will be updated with any script modifications
|
||||
as soon as such modification occurs. Basically this is an example of
|
||||
'real-time' configuration and might not be the most efficient option (but could be useful during development).
|
||||
|
||||
<programlisting language="xml"><int-groovy:script location="..." refresh-check-delay="-1"/></programlisting>
|
||||
|
||||
Any negative number value means the script will never be refreshed after
|
||||
initial initialization of the application context. This is the default behavior.
|
||||
In this case, the "dynamic" aspect of Groovy is not being used, but the syntax
|
||||
might be the primary reason that Groovy has been chosen in the first place.
|
||||
<important>Inline defined scripts can not be reloaded.</important></para>
|
||||
|
||||
<para><emphasis>Groovy object customization</emphasis> </para>
|
||||
|
||||
<para><emphasis>Custom bindings</emphasis> </para>
|
||||
|
||||
<para>
|
||||
You already know that by default, 'payload' and 'headers' will be bound as Groovy binding variables.
|
||||
However, some times in order to take the most out of Groovy you may want to customize Groovy bindings
|
||||
(e.g., include extra variables pointing to some scalar values or bind some beans as variables).
|
||||
To support this requirement we have defined a simple strategy: ScriptVariableGenerator.
|
||||
<programlisting language="java"><![CDATA[public interface ScriptVariableGenerator {
|
||||
|
||||
Map<String, Object> generateScriptVariables(Message<?> message);
|
||||
|
||||
}]]></programlisting>
|
||||
|
||||
As you can see the only method to implement is <code>generateScriptVariables(Message)</code>. It takes the Message
|
||||
as an argument. That allows you to use data available in the Message payload and/or headers. The return value is
|
||||
the Map of variables that will be bound to the script's evaluation context. This method will be called every time
|
||||
the script is executed, corresponding to the processing of that particular Message. We also provide a
|
||||
default implementation and namespace based configuration for simple bindings via <variable> sub-elements (see below):
|
||||
<programlisting language="xml"><![CDATA[<groovy:script location="foo/bar/MyScript.groovy">
|
||||
<groovy:variable name="foo" value="foo"/>
|
||||
<groovy:variable name="bar" value="bar"/>
|
||||
<groovy:variable name="date" ref="date"/>
|
||||
</groovy:script>]]></programlisting>
|
||||
|
||||
As you can see similar to other constructs in Spring, when binding each of these variables you can either provide a
|
||||
scalar value or reference another bean in the Application Context.
|
||||
</para>
|
||||
<para>
|
||||
If you need more control over how a particular variable is generated, then all you need to do is
|
||||
provide your own implementation of ScriptVariableGenerator and reference it with the <code>script-variable-generator</code>
|
||||
attribute:
|
||||
<programlisting language="xml"><![CDATA[<int-groovy:script location="foo/bar/MyScript.groovy"
|
||||
script-variable-generator="variableGenerator"/>
|
||||
|
||||
<bean id="variableGenerator" class="foo.bar.MyScriptVariableGenerator"/>]]></programlisting>
|
||||
|
||||
<important>
|
||||
The <code>script-variable-generator</code> attribute and <variable> sub-element(s) are mutually exclusive.
|
||||
You can use at most one of them. Also, the <code>script-variable-generator</code> and <variable> sub-elements
|
||||
cannot be used with an inline script, but rather only when pointing to the script via the <code>location</code> attribute.
|
||||
</important>
|
||||
|
||||
<para>
|
||||
If you need to customize the Groovy object itself, beyond setting variables, you can reference
|
||||
a bean that implementats <code>org.springframework.scripting.groovy.GroovyObjectCustomizer</code> via the
|
||||
<code>customizer</code> attribute. For example, this might be useful if you want to configure a domain-specific
|
||||
language (DSL) by modifying the MetaClass and registering functions to be available within the script.
|
||||
a bean that implements <classname>org.springframework.scripting.groovy.GroovyObjectCustomizer</classname> via the
|
||||
<code>customizer</code> attribute. For example, this might be useful if you want to implement a domain-specific
|
||||
language (DSL) by modifying the MetaClass and registering functions to be available within the script:
|
||||
|
||||
<programlisting language="xml"><![CDATA[<int:service-activator input-channel="groovyChannel">
|
||||
<int-groovy:script location="foo/SomeScript.groovy" customizer="groovyCustomizer"/>
|
||||
@@ -128,7 +55,7 @@
|
||||
|
||||
<beans:bean id="groovyCustomizer" class="org.foo.MyGroovyObjectCustomizer"/>]]></programlisting>
|
||||
|
||||
Setting a custom GroovyObjectCustomizer is not mutually exclusive with <variable> sub-elements or
|
||||
Setting a custom GroovyObjectCustomizer is not mutually exclusive with <code><variable></code> sub-elements or
|
||||
the <code>script-variable-generator</code> attribute. It can also be provided when defining an inline script.
|
||||
</para>
|
||||
</section>
|
||||
@@ -150,15 +77,15 @@
|
||||
|
||||
<para>The Groovy Control Bus executes messages on the input channel as
|
||||
Groovy scripts. It takes a message, compiles the body to a Script,
|
||||
customizes it with a GroovyObjectCustomizer, and then executes it. The
|
||||
customizes it with a <classname>GroovyObjectCustomizer</classname>, and then executes it. The
|
||||
Control Bus' customizer exposes all the beans in the application context
|
||||
that are annotated with @ManagedResource, implement Spring's
|
||||
Lifecycle interface or extend Spring's CustomizableThreadCreator base class
|
||||
(e.g. several of the TaskExecutor and TaskScheduler implementations).</para>
|
||||
that are annotated with <code>@ManagedResource</code>, implement Spring's
|
||||
<classname>Lifecycle</classname>interface or extend Spring's <classname>CustomizableThreadCreator</classname> base class
|
||||
(e.g. several of the <classname>TaskExecutor</classname> and <classname>TaskScheduler</classname> implementations).</para>
|
||||
|
||||
<para>
|
||||
If you need to further customize the Groovy objects, you can also provide a reference to a bean
|
||||
that implements <code>org.springframework.scripting.groovy.GroovyObjectCustomizer</code> via
|
||||
that implements <classname>org.springframework.scripting.groovy.GroovyObjectCustomizer</classname> via
|
||||
the <code>customizer</code> attribute.
|
||||
|
||||
<programlisting language="xml"><![CDATA[<int-groovy:control-bus input-channel="input"
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
<xi:include href="./endpoint.xml"/>
|
||||
<xi:include href="./gateway.xml"/>
|
||||
<xi:include href="./service-activator.xml"/>
|
||||
<xi:include href="./delayer.xml"/>
|
||||
<xi:include href="./delayer.xml"/>
|
||||
<xi:include href="./scripting.xml"/>
|
||||
<xi:include href="./groovy.xml"/>
|
||||
|
||||
</chapter>
|
||||
|
||||
126
docs/src/reference/docbook/scripting.xml
Normal file
126
docs/src/reference/docbook/scripting.xml
Normal file
@@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<section version="5.0" xml:id="scripting" xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:ns5="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ns4="http://www.w3.org/1998/Math/MathML"
|
||||
xmlns:ns3="http://www.w3.org/2000/svg"
|
||||
xmlns:ns="http://docbook.org/ns/docbook">
|
||||
<title>Scripting support</title>
|
||||
|
||||
<para>With Spring Integration 2.1 we've added support for the <ulink url="http://jcp.org/aboutJava/communityprocess/pr/jsr223/">
|
||||
JSR223 Scripting for Java specification</ulink>,
|
||||
introduced in Java version 6. This allows you to use scripts written in any supported language including
|
||||
Ruby/JRuby, Javascript and Groovy to provide the logic for various integration components similar to the way
|
||||
the Spring Expression Language (SpEL) is used in Spring Integration. For more information about JSR223 please refer to the
|
||||
<ulink url="http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting/">documentation</ulink>
|
||||
<important>
|
||||
Note that this feature requires Java 6 or higher. Sun developed a JSR223 reference implementation which works with
|
||||
Java 5 but it is not officially supported and we have not tested it with Spring Integration.
|
||||
</important>
|
||||
</para>
|
||||
<para>
|
||||
In order to use a JVM scripting language, a JSR223 implementation for that language must be included in your class path. Java 6 natively
|
||||
supports Javascript. The <ulink url="http://groovy.codehaus.org">Groovy</ulink> and
|
||||
<ulink url="http://jruby.org/">JRuby</ulink> projects provide JSR233 support in their standard distribution.
|
||||
Other language implementations may be available or under development. Please refer to the appropriate project website for more information.
|
||||
<important>
|
||||
Various JSR223 language implementations have been developed by third parties. A particular implementation's compatibility
|
||||
with Spring Integration depends on how well it conforms to the specification and/or the implementer's interpretation of the specification.
|
||||
</important>
|
||||
<tip>If you plan to use Groovy as your scripting language, we recommended you use <xref linkend="groovy">Spring-Integration's Groovy Support</xref>
|
||||
as it offers additional features specific to Groovy. <emphasis>However you will find his section relevant as well</emphasis>.
|
||||
</tip>
|
||||
</para>
|
||||
|
||||
<section id="scripting-config">
|
||||
<title>Script configuration</title>
|
||||
|
||||
<para>Depending on the complexity of your integration requirements
|
||||
scripts may be provided inline as CDATA in XML configuration or as a
|
||||
reference to a Spring resource containing the script. To enable scripting support
|
||||
Spring Integration defines a
|
||||
<classname>ScriptExecutingMessageProcessor</classname> which will
|
||||
bind the Message Payload to a
|
||||
variable named <code>payload</code> and the Message Headers to a <code>headers</code>
|
||||
variable, both accessible within the script execution context. All that is left for you to do is
|
||||
write a script that uses these variables. Below are a couple of sample configurations:</para>
|
||||
|
||||
<para><emphasis>Filter</emphasis> <programlisting language="xml"><int:filter input-channel="referencedScriptInput">
|
||||
<int-script:script lang="ruby" location="some/path/to/ruby/script/RubyFilterTests.rb"/>
|
||||
</int:filter>
|
||||
|
||||
<int:filter input-channel="inlineScriptInput">
|
||||
<int-script:script lang="groovy"><![CDATA[
|
||||
return payload == 'good'
|
||||
]]></int-script:script>
|
||||
</int:filter></programlisting>
|
||||
|
||||
Here, you see that the script can be included inline
|
||||
or can reference a resource location via the <code>location</code> attribute. Additionally the <code>lang</code> attribute
|
||||
corresponds to the language name (or JSR223 alias)</para>
|
||||
|
||||
<para>Other Spring Integration endpoint elements which support scripting include <emphasis>router</emphasis>, <emphasis>service-activator</emphasis>,
|
||||
<emphasis>transformer</emphasis>, and <emphasis>splitter</emphasis>. The scripting configuration in each case would be identical to the above
|
||||
(besides the endpoint element).
|
||||
</para>
|
||||
|
||||
<para>Another useful feature of Scripting support is the ability to update (reload) scripts without
|
||||
having to restart the Application Context. To accomplish this, specify the <code>refresh-check-delay</code>
|
||||
attribute on the <emphasis>script</emphasis> element:
|
||||
|
||||
<programlisting language="xml"><int-script:script location="..." refresh-check-delay="5000"/></programlisting>
|
||||
|
||||
In the above example, the script location will be checked for updates every 5 seconds. If the script is updated,
|
||||
any invocation that occurs later than 5 seconds since the update will result in execution of the new script.
|
||||
|
||||
<programlisting language="xml"><int-script:script location="..." refresh-check-delay="0"/></programlisting>
|
||||
|
||||
In the above example the context will be updated with any script modifications
|
||||
as soon as such modification occurs, providing a simple mechanism for 'real-time' configuration.
|
||||
|
||||
Any negative number value means the script will not be reloaded after initialization of the application context.
|
||||
This is the default behavior. <important>Inline scripts can not be reloaded.</important></para>
|
||||
|
||||
<programlisting language="xml"><int-script:script location="..." refresh-check-delay="-1"/></programlisting>
|
||||
|
||||
<para><emphasis>Script variable bindings</emphasis> </para>
|
||||
|
||||
<para>
|
||||
Variable bindings are required to enable the script to reference variables externally provided to the script's execution context.
|
||||
As we have seen, <code>payload</code> and <code>headers</code> are used as binding variables by default. You can bind additional variables
|
||||
to a script via <code><variable></code> sub-elements:
|
||||
<programlisting language="xml"><![CDATA[<script:script lang="js" location="foo/bar/MyScript.js">
|
||||
<script:variable name="foo" value="foo"/>
|
||||
<script:variable name="bar" value="bar"/>
|
||||
<script:variable name="date" ref="date"/>
|
||||
</script:script>]]></programlisting>
|
||||
As shown in the above example, you can bind a script variable either to a scalar value or a Spring bean reference. Note that
|
||||
<code>payload</code> and <code>headers</code> will still be included as binding variables.
|
||||
|
||||
</para>
|
||||
<para>
|
||||
If you need more control over how variables are generated, you can implement your own Java class
|
||||
using the <classname>ScriptVariableGenerator</classname> strategy:
|
||||
<programlisting language="java"><![CDATA[public interface ScriptVariableGenerator {
|
||||
|
||||
Map<String, Object> generateScriptVariables(Message<?> message);
|
||||
|
||||
}]]></programlisting>
|
||||
|
||||
This interface requires you to implement the method <code>generateScriptVariables(Message)</code>. The Message
|
||||
argument allows you to access any data available in the Message payload and headers and the return value is
|
||||
the Map of bound variables. This method will be called every time the script is executed for a Message. All you need to do is
|
||||
provide an implementation of <classname>ScriptVariableGenerator</classname> and reference it with the <code>script-variable-generator</code>
|
||||
attribute:
|
||||
<programlisting language="xml"><![CDATA[<int-script:script location="foo/bar/MyScript.groovy"
|
||||
script-variable-generator="variableGenerator"/>
|
||||
|
||||
<bean id="variableGenerator" class="foo.bar.MyScriptVariableGenerator"/>]]></programlisting>
|
||||
|
||||
<important>
|
||||
You cannot provide both the <code>script-variable-generator</code> attribute and <code><variable></code> sub-element(s)
|
||||
as they are mutually exclusive. Also, custom variable bindings cannot be used with an inline script.
|
||||
</important>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
@@ -88,30 +88,24 @@
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-core</artifactId>
|
||||
<version>2.1.0.BUILD-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<version>2.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-test</artifactId>
|
||||
<version>2.1.0.BUILD-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymockclassextension</artifactId>
|
||||
<version>2.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-core</artifactId>
|
||||
<version>2.1.0.BUILD-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
@@ -136,6 +130,12 @@
|
||||
<version>1.7.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-test</artifactId>
|
||||
<version>2.1.0.BUILD-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user