Merge remote-tracking branch 'upstream/master' into 4.0.0-WIP
Conflicts: spring-integration-core/src/main/java/org/springframework/integration/handler/ExpressionEvaluatingMessageHandler.java spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.java Resolve.
This commit is contained in:
@@ -62,7 +62,7 @@ public class GroovyRefreshTests {
|
||||
super.setValue(new CycleResource());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class CycleResource extends AbstractResource {
|
||||
|
||||
private int count = -1;
|
||||
@@ -71,12 +71,12 @@ public class GroovyRefreshTests {
|
||||
public String getDescription() {
|
||||
return "CycleResource";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getFilename() throws IllegalStateException {
|
||||
return "CycleResource";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long lastModified() throws IOException {
|
||||
return -1;
|
||||
@@ -88,6 +88,6 @@ public class GroovyRefreshTests {
|
||||
}
|
||||
return new ByteArrayInputStream(scripts[count].getBytes());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
|
||||
package org.springframework.integration.groovy.config;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import groovy.lang.GroovyObject;
|
||||
import groovy.lang.MissingPropertyException;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
@@ -44,6 +47,9 @@ import org.springframework.scripting.groovy.GroovyObjectCustomizer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import groovy.lang.GroovyObject;
|
||||
import groovy.lang.MissingPropertyException;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,10 @@ import org.springframework.messaging.Message;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* A default {@link ScriptVariableGenerator} implementation; used by script processors.
|
||||
* The result of {@link #generateScriptVariables(Message)} is a {@link Map} of any provided {@code variables}
|
||||
* plus {@code payload} and {@code headers} from the {@code Message} argument.
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Mark Fisher
|
||||
* @since 2.0.2
|
||||
@@ -53,7 +57,7 @@ public class DefaultScriptVariableGenerator implements ScriptVariableGenerator {
|
||||
if (!CollectionUtils.isEmpty(this.variableMap)) {
|
||||
for (Map.Entry<String, Object> entry : this.variableMap.entrySet()) {
|
||||
scriptVariables.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return scriptVariables;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,7 @@ import org.springframework.scripting.support.ResourceScriptSource;
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Artem Bilan
|
||||
* @since 2.0
|
||||
*/
|
||||
public class RefreshableResourceScriptSource implements ScriptSource {
|
||||
@@ -51,7 +52,10 @@ public class RefreshableResourceScriptSource implements ScriptSource {
|
||||
}
|
||||
|
||||
public String getScriptAsString() throws IOException {
|
||||
this.script = source.getScriptAsString();
|
||||
if (this.script == null || this.isModified()) {
|
||||
this.lastModifiedChecked.set(System.currentTimeMillis());
|
||||
this.script = source.getScriptAsString();
|
||||
}
|
||||
return this.script;
|
||||
}
|
||||
|
||||
@@ -60,15 +64,14 @@ public class RefreshableResourceScriptSource implements ScriptSource {
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
if (this.refreshDelay < 0) {
|
||||
return false;
|
||||
}
|
||||
long time = System.currentTimeMillis();
|
||||
if (this.refreshDelay == 0 || (time - this.lastModifiedChecked.get()) > this.refreshDelay) {
|
||||
this.lastModifiedChecked.set(time);
|
||||
return this.source.isModified();
|
||||
}
|
||||
return false;
|
||||
return this.refreshDelay >= 0 &&
|
||||
(System.currentTimeMillis() - this.lastModifiedChecked.get()) > this.refreshDelay &&
|
||||
this.source.isModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.source.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,9 @@ import java.util.Map;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
* Strategy interface to provide a {@link Map} of variables to the script execution context.
|
||||
* Variables may be extracted from the {@link Message} argument.
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0.2
|
||||
*/
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
@@ -14,13 +14,14 @@ package org.springframework.integration.scripting.jsr223;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.SimpleBindings;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.integration.scripting.ScriptExecutor;
|
||||
import org.springframework.integration.scripting.ScriptingException;
|
||||
import org.springframework.scripting.ScriptSource;
|
||||
@@ -28,9 +29,10 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base Class for {@link ScriptExecutor}
|
||||
*
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
* @since 2.1
|
||||
*/
|
||||
abstract class AbstractScriptExecutor implements ScriptExecutor {
|
||||
@@ -44,9 +46,9 @@ abstract class AbstractScriptExecutor implements ScriptExecutor {
|
||||
public AbstractScriptExecutor(String language) {
|
||||
Assert.hasText(language, "language must not be empty");
|
||||
this.language = language;
|
||||
|
||||
|
||||
scriptEngine = new ScriptEngineManager().getEngineByName(this.language);
|
||||
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
if (scriptEngine == null) {
|
||||
@@ -66,18 +68,18 @@ abstract class AbstractScriptExecutor implements ScriptExecutor {
|
||||
Object result = null;
|
||||
|
||||
try {
|
||||
if (variables != null) {
|
||||
for (Entry<String, Object> entry : variables.entrySet()) {
|
||||
scriptEngine.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
String script = scriptSource.getScriptAsString();
|
||||
Date start = new Date();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("executing script: " + script);
|
||||
}
|
||||
|
||||
result = scriptEngine.eval(script);
|
||||
if (variables != null) {
|
||||
result = scriptEngine.eval(script, new SimpleBindings(variables));
|
||||
}
|
||||
else {
|
||||
result = scriptEngine.eval(script);
|
||||
}
|
||||
|
||||
result = postProcess(result, scriptEngine, script);
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:script="http://www.springframework.org/schema/integration/scripting"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/scripting http://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd">
|
||||
|
||||
<transformer input-channel="referencedScriptInput" output-channel="outputChannel">
|
||||
<script:script refresh-check-delay="0"
|
||||
location="file:#{T(System).getProperty('java.io.tmpdir')}/Int3164Jsr223RefreshTests/int3164.groovy"/>
|
||||
</transformer>
|
||||
|
||||
<channel id="outputChannel">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.scripting.config.jsr223;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.MessageChannel;
|
||||
import org.springframework.integration.core.PollableChannel;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
* @since 3.0
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class Int3164Jsr223RefreshTests {
|
||||
|
||||
private static File workDir;
|
||||
|
||||
private static File scriptFile;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel referencedScriptInput;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel outputChannel;
|
||||
|
||||
@BeforeClass
|
||||
public static void start() throws IOException {
|
||||
String basePath = System.getProperty("java.io.tmpdir") + File.separator + "Int3164Jsr223RefreshTests";
|
||||
workDir = new File(basePath);
|
||||
shutdown();
|
||||
workDir.mkdir();
|
||||
workDir.deleteOnExit();
|
||||
scriptFile = new File(workDir, "int3164.groovy");
|
||||
scriptFile.createNewFile();
|
||||
FileCopyUtils.copy("1".getBytes(), scriptFile);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void shutdown() {
|
||||
if (workDir != null && workDir.exists()) {
|
||||
for (File file : workDir.listFiles()) {
|
||||
file.delete();
|
||||
}
|
||||
workDir.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshingScript() throws Exception {
|
||||
this.referencedScriptInput.send(new GenericMessage<Object>("test"));
|
||||
assertEquals(1, this.outputChannel.receive(100).getPayload());
|
||||
|
||||
FileCopyUtils.copy("2".getBytes(), scriptFile);
|
||||
scriptFile.setLastModified(System.currentTimeMillis() + 10000); // force refresh
|
||||
|
||||
this.referencedScriptInput.send(new GenericMessage<Object>("test"));
|
||||
assertEquals(2, this.outputChannel.receive(100).getPayload());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:script="http://www.springframework.org/schema/integration/scripting"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:script="http://www.springframework.org/schema/integration/scripting"
|
||||
xmlns:task="http://www.springframework.org/schema/task"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/scripting http://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd">
|
||||
http://www.springframework.org/schema/integration/scripting http://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd
|
||||
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
|
||||
|
||||
<transformer input-channel="referencedScriptInput">
|
||||
<script:script
|
||||
lang="ruby"
|
||||
lang="ruby"
|
||||
location="org/springframework/integration/scripting/config/jsr223/Jsr223TransformerTests.rb"/>
|
||||
</transformer>
|
||||
|
||||
@@ -19,4 +21,23 @@
|
||||
]]></script:script>
|
||||
</transformer>
|
||||
|
||||
<task:executor id="executor" pool-size="100"/>
|
||||
|
||||
<channel id="int3162InputChannel">
|
||||
<dispatcher task-executor="executor"/>
|
||||
</channel>
|
||||
|
||||
<channel id="int3162OutputChannel">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
<transformer input-channel="int3162InputChannel" output-channel="int3162OutputChannel">
|
||||
<script:script lang="javascript"><![CDATA[
|
||||
(function(){
|
||||
return payload;
|
||||
})();
|
||||
]]></script:script>
|
||||
</transformer>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,9 @@ package org.springframework.integration.scripting.config.jsr223;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -26,12 +29,15 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.PollableChannel;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
* @since 2.0
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@@ -44,6 +50,12 @@ public class Jsr223TransformerTests {
|
||||
@Autowired
|
||||
private MessageChannel inlineScriptInput;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel int3162InputChannel;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel int3162OutputChannel;
|
||||
|
||||
|
||||
@Test
|
||||
public void referencedScript() {
|
||||
@@ -73,4 +85,22 @@ public class Jsr223TransformerTests {
|
||||
assertNull(replyChannel.receive(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInt3162ScriptExecutorThreadSafety() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
this.int3162InputChannel.send(new GenericMessage<Object>(i));
|
||||
}
|
||||
|
||||
Set<Object> result = new HashSet<Object>();
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Message<?> message = this.int3162OutputChannel.receive(1000);
|
||||
result.add(message.getPayload());
|
||||
}
|
||||
|
||||
assertEquals(100, result.size());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -47,11 +47,11 @@
|
||||
</tip>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section id="amqp-inbound-channel-adapter">
|
||||
<title>Inbound Channel Adapter</title>
|
||||
|
||||
<para>A configuration sample for an AMQP Inbound Channel Adapter is shown
|
||||
below with all available parameters.</para>
|
||||
below.</para>
|
||||
<programlisting language="xml"><![CDATA[<int-amqp:inbound-channel-adapter id="inboundAmqp"]]><co id="amqp-inbound-channel-adapter-xml-01-co" linkends="amqp-inbound-channel-adapter-xml-01" /><![CDATA[
|
||||
channel="inboundChannel"]]><co id="amqp-inbound-channel-adapter-xml-02-co" linkends="amqp-inbound-channel-adapter-xml-02" /><![CDATA[
|
||||
queue-names="si.test.queue"]]><co id="amqp-inbound-channel-adapter-xml-03-co" linkends="amqp-inbound-channel-adapter-xml-03" /><![CDATA[
|
||||
@@ -165,7 +165,20 @@ this list can also be simple patterns to be matched against the header names (e.
|
||||
core responsibility of this Channel Adapter implementation,
|
||||
the referenced listener container must NOT already have its
|
||||
own MessageListener configured.
|
||||
<emphasis>Optional</emphasis>.</para>
|
||||
<emphasis>Optional</emphasis>.
|
||||
<note>
|
||||
Note that when configuring an external container, you cannot use the <emphasis role="bold">Spring AMQP</emphasis>
|
||||
namespace to define the container. This is because the namespace requires at least one <code><listener/></code>
|
||||
element. In this environment, the listener is internal to the adapter. For this reason, you must define
|
||||
the container using a normal Spring <code><bean/></code> definition, such as:
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<bean id="container"
|
||||
class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer">
|
||||
<property name="connectionFactory" ref="connectionFactory" />
|
||||
<property name="queueNames" value="foo.queue" />
|
||||
<property name="defaultRequeueRejected" value="false"/>
|
||||
</bean>]]></programlisting>
|
||||
</note></para>
|
||||
</callout>
|
||||
<callout arearefs="amqp-inbound-channel-adapter-xml-15-co" id="amqp-inbound-channel-adapter-xml-15">
|
||||
<para>The MessageConverter to use when receiving AMQP Messages.
|
||||
@@ -273,7 +286,7 @@ this list can also be simple patterns to be matched against the header names (e.
|
||||
<title>Outbound Channel Adapter</title>
|
||||
|
||||
<para>A configuration sample for an AMQP Outbound Channel Adapter is shown
|
||||
below with all available parameters.</para>
|
||||
below.</para>
|
||||
<programlisting language="xml"><![CDATA[<int-amqp:outbound-channel-adapter id="outboundAmqp"]]><co id="amqp-outbound-channel-adapter-xml-1-co" linkends="amqp-outbound-channel-adapter-xml-1" /><![CDATA[
|
||||
channel="outboundChannel"]]><co id="amqp-outbound-channel-adapter-xml-2-co" linkends="amqp-outbound-channel-adapter-xml-2" /><![CDATA[
|
||||
amqp-template="myAmqpTemplate"]]><co id="amqp-outbound-channel-adapter-xml-3-co" linkends="amqp-outbound-channel-adapter-xml-3" /><![CDATA[
|
||||
@@ -368,7 +381,7 @@ this list can also be simple patterns to be matched against the header names (e.
|
||||
<section>
|
||||
<title>Inbound Gateway</title>
|
||||
<para>A configuration sample for an AMQP Inbound Gateway is shown
|
||||
below with all available parameters.</para>
|
||||
below.</para>
|
||||
<programlisting language="xml"><![CDATA[<int-amqp:inbound-gateway id="inboundGateway"]]><co id="amqp-inbound-gateway-adapter-xml-1-co" linkends="amqp-inbound-gateway-adapter-xml-1" /><![CDATA[
|
||||
request-channel="myRequestChannel"]]><co id="amqp-inbound-gateway-adapter-xml-2-co" linkends="amqp-inbound-gateway-adapter-xml-2" /><![CDATA[
|
||||
queue-names="si.test.queue"]]><co id="amqp-inbound-gateway-adapter-xml-3-co" linkends="amqp-inbound-gateway-adapter-xml-3" /><![CDATA[
|
||||
@@ -415,12 +428,16 @@ this list can also be simple patterns to be matched against the header names (e.
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</para>
|
||||
<para>
|
||||
See the note in <xref linkend="amqp-inbound-channel-adapter"/> about configuring the <code>listener-container</code>
|
||||
attribute.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Outbound Gateway</title>
|
||||
<para>A configuration sample for an AMQP Outbound Gateway is shown
|
||||
below with all available parameters.</para>
|
||||
below.</para>
|
||||
<programlisting language="xml"><![CDATA[<int-amqp:outbound-gateway id="inboundGateway"]]><co id="amqp-outbound-gateway-adapter-xml-1-co" linkends="amqp-outbound-gateway-adapter-xml-1" /><![CDATA[
|
||||
request-channel="myRequestChannel"]]><co id="amqp-outbound-gateway-adapter-xml-2-co" linkends="amqp-outbound-gateway-adapter-xml-2" /><![CDATA[
|
||||
amqp-template=""]]><co id="amqp-outbound-gateway-adapter-xml-3-co" linkends="amqp-outbound-gateway-adapter-xml-3" /><![CDATA[
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
|
||||
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.
|
||||
For more information regarding <code><variable></code> and <code>script-variable-generator</code>, see the
|
||||
paragraph '<emphasis>Script variable bindings</emphasis>' of <xref linkend="scripting-config"/>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -8,26 +8,26 @@
|
||||
<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
|
||||
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
|
||||
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
|
||||
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>
|
||||
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 this section relevant as well</emphasis>.
|
||||
</tip>
|
||||
</para>
|
||||
@@ -50,28 +50,30 @@
|
||||
</int:filter>
|
||||
|
||||
<int:filter input-channel="inlineScriptInput">
|
||||
<int-script:script lang="groovy"><![CDATA[
|
||||
<int-script:script lang="groovy">
|
||||
<![CDATA[
|
||||
return payload == 'good'
|
||||
]]></int-script:script>
|
||||
]]>
|
||||
</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
|
||||
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
|
||||
<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>
|
||||
<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.
|
||||
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>
|
||||
|
||||
@@ -82,12 +84,12 @@
|
||||
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
|
||||
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"/>
|
||||
@@ -96,29 +98,32 @@
|
||||
</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
|
||||
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
|
||||
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>
|
||||
|
||||
If a <code>script-variable-generator</code> is not provided, script components use
|
||||
<classname>org.springframework.integration.scripting.DefaultScriptVariableGenerator</classname>, which merges
|
||||
any provided <code><variable></code>s with <emphasis>payload</emphasis> and <emphasis>headers</emphasis>
|
||||
variables from the <code>Message</code> in its <code>generateScriptVariables(Message)</code> method.
|
||||
<important>
|
||||
You cannot provide both the <code>script-variable-generator</code> attribute and <code><variable></code> sub-element(s)
|
||||
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>
|
||||
|
||||
Reference in New Issue
Block a user