From ae823fdb5dae6a2a89c002d82049d8bec1d6cf1c Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Mon, 31 Jan 2011 14:06:29 -0500 Subject: [PATCH] INT-1727 renamed DefaultScriptVariableSource to DefaultScriptVariableGenerator, documented the new feature in reference manual --- docs/src/reference/docbook/groovy.xml | 44 +++++++++++++++++++ ...va => DefaultScriptVariableGenerator.java} | 6 +-- .../groovy/GroovyCommandMessageProcessor.java | 4 +- ...GroovyScriptExecutingMessageProcessor.java | 6 +-- ...ator.java => ScriptVariableGenerator.java} | 2 +- .../config/GroovyControlBusFactoryBean.java | 4 +- .../groovy/config/GroovyScriptParser.java | 2 +- ...yScriptExecutingMessageProcessorTests.java | 14 +++--- ...ovyScriptPayloadMessageProcessorTests.java | 8 ++-- .../config/GroovyServiceActivatorTests.java | 4 +- 10 files changed, 69 insertions(+), 25 deletions(-) rename spring-integration-groovy/src/main/java/org/springframework/integration/groovy/{DefaultScriptVariableSource.java => DefaultScriptVariableGenerator.java} (90%) rename spring-integration-groovy/src/main/java/org/springframework/integration/groovy/{ScriptVariablesGenerator.java => ScriptVariableGenerator.java} (95%) diff --git a/docs/src/reference/docbook/groovy.xml b/docs/src/reference/docbook/groovy.xml index 70cf390122..ead41c03e9 100644 --- a/docs/src/reference/docbook/groovy.xml +++ b/docs/src/reference/docbook/groovy.xml @@ -74,6 +74,50 @@ 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. Inline defined scripts can not be reloaded. + + Custom bindings + + + 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 etc.) + To support this requirement we have defined a simple strategy ScriptVariableGenerator. + generateScriptVariables(Message message); + +}]]> + + As you can see the only method that needs to be implemented is generateScriptVariables(Message) which takes + Message as an argument (allowing you to use data available in Message payload/headers) and returns the Map of variables + that will be bound as Groovy bindings. This method will be called every time the script is executed. We also provide + default implementation and namespace based configuration for simple bindings via <variable> sub-element (see below): + + + + +]]> + + As you can see similar to other constructs in Spring, when setting binding variables you can either set scalar values + or reference another bean in the Application Context. + + + However if you need more dynamics with regard to how a particular variable is generated then all you need to do is + provide your own implementation of ScriptVariableGenerator and inject it via script-variable-source atribute: + +]]> + + + + Remember that script-variable-source and use of <variable> sub-element is mutually exclusive. + You can only use one of another. Also, the script-variable-source and/or <variable> sub-elements can + not be used when using inline script, only when pointing to the script via location attribute. + + + +
diff --git a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/DefaultScriptVariableSource.java b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/DefaultScriptVariableGenerator.java similarity index 90% rename from spring-integration-groovy/src/main/java/org/springframework/integration/groovy/DefaultScriptVariableSource.java rename to spring-integration-groovy/src/main/java/org/springframework/integration/groovy/DefaultScriptVariableGenerator.java index ee4fe3e7d5..0d0bcb5c0a 100644 --- a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/DefaultScriptVariableSource.java +++ b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/DefaultScriptVariableGenerator.java @@ -29,17 +29,17 @@ import org.springframework.util.CollectionUtils; * @author Oleg Zhurakousky * @since 2.0.2 */ -class DefaultScriptVariableSource implements BeanFactoryAware, ScriptVariablesGenerator { +class DefaultScriptVariableGenerator implements BeanFactoryAware, ScriptVariableGenerator { protected volatile ListableBeanFactory beanFactory; private volatile Map variableMap; - public DefaultScriptVariableSource(){ + public DefaultScriptVariableGenerator(){ this(null); } - public DefaultScriptVariableSource(Map variableMap){ + public DefaultScriptVariableGenerator(Map variableMap){ this.variableMap = variableMap; } diff --git a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyCommandMessageProcessor.java b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyCommandMessageProcessor.java index 3e0ff427ee..da0b7ce62c 100644 --- a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyCommandMessageProcessor.java +++ b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyCommandMessageProcessor.java @@ -30,9 +30,9 @@ import org.springframework.util.Assert; */ public class GroovyCommandMessageProcessor extends AbstractScriptExecutingMessageProcessor { - private final ScriptVariablesGenerator scriptVariableSource; + private final ScriptVariableGenerator scriptVariableSource; - public GroovyCommandMessageProcessor(ScriptVariablesGenerator scriptVariableSource) { + public GroovyCommandMessageProcessor(ScriptVariableGenerator scriptVariableSource) { this.scriptVariableSource = scriptVariableSource; } diff --git a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessor.java b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessor.java index 9b18bb1512..6449b34f13 100644 --- a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessor.java +++ b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessor.java @@ -38,16 +38,16 @@ public class GroovyScriptExecutingMessageProcessor extends AbstractScriptExecuti private volatile ScriptSource scriptSource; - protected final ScriptVariablesGenerator scriptVariableSource; + protected final ScriptVariableGenerator scriptVariableSource; /** * Create a processor for the given {@link ScriptSource}. */ public GroovyScriptExecutingMessageProcessor(ScriptSource scriptSource) { - this(scriptSource, new DefaultScriptVariableSource()); + this(scriptSource, new DefaultScriptVariableGenerator()); } - public GroovyScriptExecutingMessageProcessor(ScriptSource scriptSource, ScriptVariablesGenerator scriptVariableSource) { + public GroovyScriptExecutingMessageProcessor(ScriptSource scriptSource, ScriptVariableGenerator scriptVariableSource) { this.scriptSource = scriptSource; this.scriptVariableSource = scriptVariableSource; this.scriptFactory = new GroovyScriptFactory(this.getClass().getSimpleName(), this.customizer); diff --git a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/ScriptVariablesGenerator.java b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/ScriptVariableGenerator.java similarity index 95% rename from spring-integration-groovy/src/main/java/org/springframework/integration/groovy/ScriptVariablesGenerator.java rename to spring-integration-groovy/src/main/java/org/springframework/integration/groovy/ScriptVariableGenerator.java index b7f3595775..181dd3a356 100644 --- a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/ScriptVariablesGenerator.java +++ b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/ScriptVariableGenerator.java @@ -24,7 +24,7 @@ import org.springframework.integration.Message; * @author Oleg Zhurakousky * */ -public interface ScriptVariablesGenerator { +public interface ScriptVariableGenerator { Map generateScriptVariables(Message message); } diff --git a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyControlBusFactoryBean.java b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyControlBusFactoryBean.java index d068778a66..70c9206193 100644 --- a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyControlBusFactoryBean.java +++ b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyControlBusFactoryBean.java @@ -24,7 +24,7 @@ import org.springframework.integration.Message; import org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean; import org.springframework.integration.core.MessageHandler; import org.springframework.integration.groovy.GroovyCommandMessageProcessor; -import org.springframework.integration.groovy.ScriptVariablesGenerator; +import org.springframework.integration.groovy.ScriptVariableGenerator; import org.springframework.integration.handler.ServiceActivatingHandler; import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.util.CustomizableThreadCreator; @@ -58,7 +58,7 @@ public class GroovyControlBusFactoryBean extends AbstractSimpleMessageHandlerFac return handler; } - private class ManagedBeansScriptVariableSource implements ScriptVariablesGenerator { + private class ManagedBeansScriptVariableSource implements ScriptVariableGenerator { private final ListableBeanFactory beanFactory; public ManagedBeansScriptVariableSource(BeanFactory beanFactory){ diff --git a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyScriptParser.java b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyScriptParser.java index cdd2144644..720e387864 100644 --- a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyScriptParser.java +++ b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyScriptParser.java @@ -81,7 +81,7 @@ public class GroovyScriptParser extends AbstractSingleBeanDefinitionParser { if (!StringUtils.hasText(scriptVariableSourceName)){ BeanDefinitionBuilder scriptVariableSourceBuilder = - BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.groovy.DefaultScriptVariableSource"); + BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.groovy.DefaultScriptVariableGenerator"); ManagedMap variableMap = new ManagedMap(); for (Element childElement : variableElements) { diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessorTests.java b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessorTests.java index 77a3555195..3af24a373f 100644 --- a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessorTests.java +++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessorTests.java @@ -59,7 +59,7 @@ public class GroovyScriptExecutingMessageProcessorTests { Message message = MessageBuilder.withPayload("foo").setHeader("testHeader", "bar"+count).build(); TestResource resource = new TestResource(script, "simpleTest"); ScriptSource scriptSource = new ResourceScriptSource(resource); - MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource, new DefaultScriptVariableSource()); + MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource, new DefaultScriptVariableGenerator()); Object result = processor.processMessage(message); assertEquals("payload is foo, header is bar"+count, result.toString()); } @@ -72,7 +72,7 @@ public class GroovyScriptExecutingMessageProcessorTests { TestResource resource = new TestResource(script, "simpleTest"); ScriptSource scriptSource = new ResourceScriptSource(resource); Object result = null; - class CustomScriptVariableSource implements ScriptVariablesGenerator { + class CustomScriptVariableSource implements ScriptVariableGenerator { public Map generateScriptVariables(Message message) { Map variables = new HashMap(); variables.put("date", System.nanoTime()); @@ -82,7 +82,7 @@ public class GroovyScriptExecutingMessageProcessorTests { } } for (int i = 0; i < 5; i++) { - ScriptVariablesGenerator scriptVariableSource = new CustomScriptVariableSource(); + ScriptVariableGenerator scriptVariableSource = new CustomScriptVariableSource(); MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource, scriptVariableSource); Object newResult = processor.processMessage(message); assertFalse(newResult.equals(result)); // make sure that we get different nanotime verifying that resolveScriptVariables() is invoked @@ -106,7 +106,7 @@ public class GroovyScriptExecutingMessageProcessorTests { Message message = MessageBuilder.withPayload("foo").setHeader("testHeader", "bar").build(); TestResource resource = new TestResource(script, "simpleTest"); ScriptSource scriptSource = new ResourceScriptSource(resource); - MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource, new DefaultScriptVariableSource()); + MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource, new DefaultScriptVariableGenerator()); Thread.sleep(20L); resource.setScript("return \"payload is $payload\""); Object result = processor.processMessage(message); @@ -119,7 +119,7 @@ public class GroovyScriptExecutingMessageProcessorTests { Message message = MessageBuilder.withPayload("foo").setHeader("testHeader", "bar").build(); TestResource resource = new TestResource(script, "simpleTest"); ScriptSource scriptSource = new RefreshableResourceScriptSource(resource, 1000L); - MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource, new DefaultScriptVariableSource()); + MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource, new DefaultScriptVariableGenerator()); // should be the original script Object result = processor.processMessage(message); assertEquals("payload is foo, header is bar", result.toString()); @@ -143,7 +143,7 @@ public class GroovyScriptExecutingMessageProcessorTests { Message message = MessageBuilder.withPayload("foo").setHeader("testHeader", "bar").build(); TestResource resource = new TestResource(script, "simpleTest"); ScriptSource scriptSource = new RefreshableResourceScriptSource(resource, -1L); - MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource, new DefaultScriptVariableSource()); + MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource, new DefaultScriptVariableGenerator()); // process with the first script Object result = processor.processMessage(message); assertEquals("payload is foo, header is bar", result.toString()); @@ -160,7 +160,7 @@ public class GroovyScriptExecutingMessageProcessorTests { Message message = MessageBuilder.withPayload("foo").setHeader("testHeader", "bar").build(); TestResource resource = new TestResource(script, "simpleTest"); ScriptSource scriptSource = new RefreshableResourceScriptSource(resource, 0); - MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource, new DefaultScriptVariableSource()); + MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource, new DefaultScriptVariableGenerator()); // process with the first script Object result = processor.processMessage(message); assertEquals("payload is foo, header is bar", result.toString()); diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyScriptPayloadMessageProcessorTests.java b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyScriptPayloadMessageProcessorTests.java index 07c334a4ef..66611f250f 100644 --- a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyScriptPayloadMessageProcessorTests.java +++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyScriptPayloadMessageProcessorTests.java @@ -44,14 +44,14 @@ public class GroovyScriptPayloadMessageProcessorTests { public void testSimpleExecution() throws Exception { int count = countHolder.getAndIncrement(); Message message = MessageBuilder.withPayload("headers.foo" + count).setHeader("foo" + count, "bar").build(); - processor = new GroovyCommandMessageProcessor(new DefaultScriptVariableSource()); + processor = new GroovyCommandMessageProcessor(new DefaultScriptVariableGenerator()); Object result = processor.processMessage(message); assertEquals("bar", result.toString()); } @Test public void testDoubleExecutionWithNewScript() throws Exception { - processor = new GroovyCommandMessageProcessor(new DefaultScriptVariableSource()); + processor = new GroovyCommandMessageProcessor(new DefaultScriptVariableGenerator()); Message message = MessageBuilder.withPayload("headers.foo").setHeader("foo", "bar").build(); Object result = processor.processMessage(message); assertEquals("bar", result.toString()); @@ -64,8 +64,8 @@ public class GroovyScriptPayloadMessageProcessorTests { public void testSimpleExecutionWithContext() throws Exception { Message message = MessageBuilder.withPayload("\"spam is $spam foo is $headers.foo\"") .setHeader("foo", "bar").build(); - ScriptVariablesGenerator scriptVariableSource = - new DefaultScriptVariableSource(Collections.singletonMap("spam",(Object)"bucket")); + ScriptVariableGenerator scriptVariableSource = + new DefaultScriptVariableGenerator(Collections.singletonMap("spam",(Object)"bucket")); MessageProcessor processor = new GroovyCommandMessageProcessor(scriptVariableSource); Object result = processor.processMessage(message); assertEquals("spam is bucket foo is bar", result.toString()); diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.java b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.java index 7c42a2e6a9..c65481d8af 100644 --- a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.java +++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.java @@ -34,7 +34,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.Message; import org.springframework.integration.MessageChannel; import org.springframework.integration.channel.QueueChannel; -import org.springframework.integration.groovy.ScriptVariablesGenerator; +import org.springframework.integration.groovy.ScriptVariableGenerator; import org.springframework.integration.support.MessageBuilder; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -128,7 +128,7 @@ public class GroovyServiceActivatorTests { new ClassPathXmlApplicationContext("GroovyServiceActivatorTests-fail-withsource-context.xml", this.getClass()); } - public static class SampleScriptVariSource implements ScriptVariablesGenerator{ + public static class SampleScriptVariSource implements ScriptVariableGenerator{ public Map generateScriptVariables(Message message) { Map variables = new HashMap(); variables.put("foo", "foo");