From 5dc6488de07b9c50cf36e323db5fd5823f617d5c Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Sun, 6 Jul 2008 20:35:36 +0000 Subject: [PATCH] The element now creates a HandlerEndpoint instance. It now requires "input-channel" and "output-channel" (and it no longer accepts "default-reply-channel"). It also no longer accepts a sub-element. Instead, for a pojo-based adapter, add the "completion-strategy-method" attribute along with the "completion-strategy" reference (INT-285). --- .../config/AbstractHandlerEndpointParser.java | 8 +- .../integration/config/AggregatorParser.java | 128 +++++++----------- .../config/IntegrationNamespaceUtils.java | 11 +- .../config/spring-integration-core-1.0.xsd | 8 +- .../router/AggregatingMessageHandler.java | 2 +- .../config/AggregatorParserTests.java | 33 +++-- .../config/aggregatorParserTests.xml | 42 +++--- ...tionStrategyMethodWithMissingReference.xml | 7 +- ...ml => invalidCompletionStrategyMethod.xml} | 14 +- .../config/invalidMethodNameAggregator.xml | 6 +- .../router/config/NumberAdder.java | 34 +++++ .../router/config/NumberSplitter.java | 30 ++++ .../integration/router/config/Numbers.java | 37 +++++ .../config/SplitterAggregatorTests.java | 68 ++++++++++ .../router/config/splitterAggregatorTests.xml | 22 +++ 15 files changed, 312 insertions(+), 138 deletions(-) rename org.springframework.integration/src/test/java/org/springframework/integration/config/{duplicateCompletionStrategy.xml => invalidCompletionStrategyMethod.xml} (74%) create mode 100644 org.springframework.integration/src/test/java/org/springframework/integration/router/config/NumberAdder.java create mode 100644 org.springframework.integration/src/test/java/org/springframework/integration/router/config/NumberSplitter.java create mode 100644 org.springframework.integration/src/test/java/org/springframework/integration/router/config/Numbers.java create mode 100644 org.springframework.integration/src/test/java/org/springframework/integration/router/config/SplitterAggregatorTests.java create mode 100644 org.springframework.integration/src/test/java/org/springframework/integration/router/config/splitterAggregatorTests.xml diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/AbstractHandlerEndpointParser.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/AbstractHandlerEndpointParser.java index 0c35187761..b4b7d5b18d 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/AbstractHandlerEndpointParser.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/AbstractHandlerEndpointParser.java @@ -80,6 +80,10 @@ public abstract class AbstractHandlerEndpointParser extends AbstractSingleBeanDe return true; } + protected boolean shouldCreateAdapter(Element element) { + return StringUtils.hasText(element.getAttribute(METHOD_ATTRIBUTE)); + } + @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { String ref = element.getAttribute(REF_ATTRIBUTE); @@ -87,7 +91,7 @@ public abstract class AbstractHandlerEndpointParser extends AbstractSingleBeanDe throw new ConfigurationException("The '" + REF_ATTRIBUTE + "' attribute is required."); } String method = element.getAttribute(METHOD_ATTRIBUTE); - if (StringUtils.hasText(method)) { + if (this.shouldCreateAdapter(element)) { String adapterBeanName = this.parseAdapter(ref, method, element, parserContext); builder.addConstructorArgReference(adapterBeanName); } @@ -141,7 +145,7 @@ public abstract class AbstractHandlerEndpointParser extends AbstractSingleBeanDe } - private String parseAdapter(String ref, String method, Element element, ParserContext parserContext) { + protected String parseAdapter(String ref, String method, Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(this.getHandlerAdapterClass()); builder.addPropertyValue("object", new RuntimeBeanReference(ref)); builder.addPropertyValue("methodName", method); diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/AggregatorParser.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/AggregatorParser.java index a88b420b68..cebae71dcc 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/AggregatorParser.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/AggregatorParser.java @@ -17,15 +17,11 @@ package org.springframework.integration.config; import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.parsing.BeanComponentDefinition; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.integration.ConfigurationException; +import org.springframework.integration.handler.MessageHandler; import org.springframework.integration.router.AggregatingMessageHandler; import org.springframework.integration.router.AggregatorAdapter; import org.springframework.integration.router.CompletionStrategyAdapter; @@ -36,18 +32,13 @@ import org.springframework.util.StringUtils; * Registers the annotation-driven post-processors. * * @author Marius Bogoevici + * @author Mark Fisher */ -public class AggregatorParser implements BeanDefinitionParser { +public class AggregatorParser extends AbstractHandlerEndpointParser { - public static final String ID_ATTRIBUTE = "id"; + public static final String COMPLETION_STRATEGY_REF_ATTRIBUTE = "completion-strategy"; - public static final String REF_ATTRIBUTE = "ref"; - - public static final String METHOD_ATTRIBUTE = "method"; - - public static final String COMPLETION_STRATEGY_ATTRIBUTE = "completion-strategy"; - - public static final String DEFAULT_REPLY_CHANNEL_ATTRIBUTE = "default-reply-channel"; + public static final String COMPLETION_STRATEGY_METHOD_ATTRIBUTE = "completion-strategy-method"; public static final String DISCARD_CHANNEL_ATTRIBUTE = "discard-channel"; @@ -79,86 +70,61 @@ public class AggregatorParser implements BeanDefinitionParser { public static final String AGGREGATOR_ELEMENT = "aggregator"; - public static final String COMPLETION_STRATEGY_ELEMENT = "completion-strategy"; - - public BeanDefinition parse(Element element, ParserContext parserContext) { - return parseAggregatorElement(element, parserContext, true); + @Override + protected Class getHandlerAdapterClass() { + return AggregatingMessageHandler.class; } - private BeanDefinition parseAggregatorElement(Element element, ParserContext parserContext, boolean topLevel) { - final RootBeanDefinition aggregatorDef = new RootBeanDefinition(AggregatingMessageHandler.class); - aggregatorDef.setSource(parserContext.extractSource(element)); - final String id = element.getAttribute(ID_ATTRIBUTE); - final String ref = element.getAttribute(REF_ATTRIBUTE); - final String method = element.getAttribute(METHOD_ATTRIBUTE); - final String completionStrategyRef = element.getAttribute(COMPLETION_STRATEGY_ATTRIBUTE); - final NodeList completionStrategyChildElements = element.getElementsByTagName(COMPLETION_STRATEGY_ELEMENT); - if (!StringUtils.hasText(ref)) { - throw new ConfigurationException("The 'ref' attribute must be present"); - } - if (!topLevel && StringUtils.hasText(id)) { - parserContext.getReaderContext().error( - "The 'id' attribute is only supported for top-level elements.", - parserContext.extractSource(element)); - } - if (completionStrategyChildElements.getLength() > 0 && StringUtils.hasText(completionStrategyRef)) { - parserContext - .getReaderContext() - .error( - "The 'completion-strategy' element is only supported when no 'completion-strategy' attribute is specified.", - parserContext.extractSource(element)); - } - if (!StringUtils.hasText(method)) { - aggregatorDef.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference(ref)); + @Override + protected boolean shouldCreateAdapter(Element element) { + return true; + } + + @Override + protected String parseAdapter(String ref, String method, Element element, ParserContext parserContext) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(this.getHandlerAdapterClass()); + if (StringUtils.hasText(method)) { + String aggregatorAdapterBeanName = this.createAdapter(ref, method, parserContext, AggregatorAdapter.class); + builder.addConstructorArgReference(aggregatorAdapterBeanName); } else { - String adapterBeanName = createAdapterAndReturnBeanName(parserContext, ref, method, AggregatorAdapter.class); - aggregatorDef.getConstructorArgumentValues().addGenericArgumentValue( - new RuntimeBeanReference(adapterBeanName)); + builder.addConstructorArgReference(ref); } - + final String completionStrategyRef = element.getAttribute(COMPLETION_STRATEGY_REF_ATTRIBUTE); + final String completionStrategyMethod = element.getAttribute(COMPLETION_STRATEGY_METHOD_ATTRIBUTE); if (StringUtils.hasText(completionStrategyRef)) { - aggregatorDef.getPropertyValues().addPropertyValue(COMPLETION_STRATEGY_PROPERTY, - new RuntimeBeanReference(completionStrategyRef)); + if (StringUtils.hasText(completionStrategyMethod)) { + String adapterBeanName = this.createAdapter(completionStrategyRef, + completionStrategyMethod, parserContext, CompletionStrategyAdapter.class); + builder.addPropertyReference(COMPLETION_STRATEGY_PROPERTY, adapterBeanName); + } + else { + builder.addPropertyReference(COMPLETION_STRATEGY_PROPERTY, completionStrategyRef); + } } - else if (completionStrategyChildElements.getLength() > 0) { - Element completionStrategyElement = (Element) completionStrategyChildElements.item(0); - String childCompletionStrategyReference = completionStrategyElement.getAttribute(REF_ATTRIBUTE); - String childCompletionStrategyMethod = completionStrategyElement.getAttribute(METHOD_ATTRIBUTE); - String adapterBeanName = createAdapterAndReturnBeanName(parserContext, childCompletionStrategyReference, - childCompletionStrategyMethod, CompletionStrategyAdapter.class); - aggregatorDef.getPropertyValues().addPropertyValue(COMPLETION_STRATEGY_PROPERTY, - new RuntimeBeanReference(adapterBeanName)); - } - - IntegrationNamespaceUtils.setBeanReferenceIfAttributeDefined(aggregatorDef, DEFAULT_REPLY_CHANNEL_PROPERTY, - element, DEFAULT_REPLY_CHANNEL_ATTRIBUTE); - IntegrationNamespaceUtils.setBeanReferenceIfAttributeDefined(aggregatorDef, DISCARD_CHANNEL_PROPERTY, element, + IntegrationNamespaceUtils.setBeanReferenceIfAttributeDefined(builder, DEFAULT_REPLY_CHANNEL_PROPERTY, + element, OUTPUT_CHANNEL_ATTRIBUTE); + IntegrationNamespaceUtils.setBeanReferenceIfAttributeDefined(builder, DISCARD_CHANNEL_PROPERTY, element, DISCARD_CHANNEL_ATTRIBUTE); - IntegrationNamespaceUtils.setValueIfAttributeDefined(aggregatorDef, SEND_TIMEOUT_PROPERTY, element, + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, SEND_TIMEOUT_PROPERTY, element, SEND_TIMEOUT_ATTRIBUTE); - IntegrationNamespaceUtils.setValueIfAttributeDefined(aggregatorDef, SEND_PARTIAL_RESULT_ON_TIMEOUT_PROPERTY, + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, SEND_PARTIAL_RESULT_ON_TIMEOUT_PROPERTY, element, SEND_PARTIAL_RESULT_ON_TIMEOUT_ATTRIBUTE); - IntegrationNamespaceUtils.setValueIfAttributeDefined(aggregatorDef, REAPER_INTERVAL_PROPERTY, element, + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, REAPER_INTERVAL_PROPERTY, element, REAPER_INTERVAL_ATTRIBUTE); - IntegrationNamespaceUtils.setValueIfAttributeDefined(aggregatorDef, TRACKED_CORRELATION_ID_CAPACITY_PROPERTY, + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, TRACKED_CORRELATION_ID_CAPACITY_PROPERTY, element, TRACKED_CORRELATION_ID_CAPACITY_ATTRIBUTE); - IntegrationNamespaceUtils.setValueIfAttributeDefined(aggregatorDef, TIMEOUT, element, TIMEOUT_ATTRIBUTE); - String beanName = StringUtils.hasText(id) ? id : parserContext.getReaderContext().generateBeanName( - aggregatorDef); - parserContext.registerBeanComponent(new BeanComponentDefinition(aggregatorDef, beanName)); - return aggregatorDef; + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, TIMEOUT, element, TIMEOUT_ATTRIBUTE); + return BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), parserContext.getRegistry()); } - private String createAdapterAndReturnBeanName(ParserContext parserContext, final String ref, final String method, - Class adapterClass) { - BeanDefinition adapterDefinition = new RootBeanDefinition(adapterClass); - adapterDefinition.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference(ref)); - adapterDefinition.getConstructorArgumentValues().addGenericArgumentValue(method); - String adapterBeanName = parserContext.getReaderContext().generateBeanName(adapterDefinition); - parserContext.registerBeanComponent(new BeanComponentDefinition(adapterDefinition, adapterBeanName)); - return adapterBeanName; + private String createAdapter(String ref, String method, ParserContext parserContext, Class adapterClass) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(adapterClass); + builder.addConstructorArgReference(ref); + builder.addConstructorArgValue(method); + return BeanDefinitionReaderUtils.registerWithGeneratedName( + builder.getBeanDefinition(), parserContext.getRegistry()); } } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceUtils.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceUtils.java index 52d2875553..7963b7af93 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceUtils.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceUtils.java @@ -19,9 +19,8 @@ package org.springframework.integration.config; import org.w3c.dom.Element; import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.parsing.BeanComponentDefinition; -import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.util.StringUtils; @@ -45,11 +44,11 @@ public abstract class IntegrationNamespaceUtils { * @param attributeName - the name of the attribute whose value will be set * on the property */ - public static void setValueIfAttributeDefined(RootBeanDefinition beanDefinition, String propertyName, + public static void setValueIfAttributeDefined(BeanDefinitionBuilder builder, String propertyName, Element element, String attributeName) { final String attributeValue = element.getAttribute(attributeName); if (StringUtils.hasText(attributeValue)) { - beanDefinition.getPropertyValues().addPropertyValue(propertyName, attributeValue); + builder.addPropertyValue(propertyName, attributeValue); } } @@ -64,11 +63,11 @@ public abstract class IntegrationNamespaceUtils { * @param attributeName - the id of the bean which will be used to populate * the property */ - public static void setBeanReferenceIfAttributeDefined(RootBeanDefinition beanDefinition, String propertyName, + public static void setBeanReferenceIfAttributeDefined(BeanDefinitionBuilder builder, String propertyName, Element element, String attributeName) { final String attributeValue = element.getAttribute(attributeName); if (StringUtils.hasText(attributeValue)) { - beanDefinition.getPropertyValues().addPropertyValue(propertyName, new RuntimeBeanReference(attributeValue)); + builder.addPropertyReference(propertyName, attributeValue); } } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd b/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd index 1258dcca92..f5a8f7a1ef 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd @@ -355,15 +355,9 @@ - - - - - - + - diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/router/AggregatingMessageHandler.java b/org.springframework.integration/src/main/java/org/springframework/integration/router/AggregatingMessageHandler.java index f905df7572..77968ba38d 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/router/AggregatingMessageHandler.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/router/AggregatingMessageHandler.java @@ -62,7 +62,7 @@ public class AggregatingMessageHandler extends AbstractMessageBarrierHandler { this(aggregator, null); } - + /** * Strategy to determine whether the group of messages is complete. */ diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/AggregatorParserTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/config/AggregatorParserTests.java index b6b6ba4290..d68ac8ee38 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/AggregatorParserTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/AggregatorParserTests.java @@ -26,10 +26,10 @@ import org.junit.Test; import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.channel.MessageChannel; +import org.springframework.integration.endpoint.HandlerEndpoint; import org.springframework.integration.message.GenericMessage; import org.springframework.integration.message.Message; import org.springframework.integration.router.AggregatingMessageHandler; @@ -39,6 +39,7 @@ import org.springframework.integration.util.MethodInvoker; /** * @author Marius Bogoevici + * @author Mark Fisher */ public class AggregatorParserTests { @@ -52,8 +53,8 @@ public class AggregatorParserTests { @Test public void testAggregation() { - AggregatingMessageHandler aggregatingHandler = (AggregatingMessageHandler) context - .getBean("aggregatorWithReference"); + HandlerEndpoint endpoint = (HandlerEndpoint) context.getBean("aggregatorWithReference"); + AggregatingMessageHandler aggregatingHandler = (AggregatingMessageHandler) endpoint.getHandler(); TestAggregator aggregatorBean = (TestAggregator) context.getBean("aggregatorBean"); List> outboundMessages = new ArrayList>(); outboundMessages.add(createMessage("123", "id1", 3, 1, null)); @@ -71,8 +72,9 @@ public class AggregatorParserTests { @Test public void testPropertyAssignment() throws Exception { - AggregatingMessageHandler completeAggregatingMessageHandler = (AggregatingMessageHandler) context - .getBean("completelyDefinedAggregator"); + HandlerEndpoint endpoint = (HandlerEndpoint) context.getBean("completelyDefinedAggregator"); + AggregatingMessageHandler completeAggregatingMessageHandler = + (AggregatingMessageHandler) endpoint.getHandler(); TestAggregator testAggregator = (TestAggregator) context.getBean("aggregatorBean"); CompletionStrategy completionStrategy = (CompletionStrategy) context.getBean("completionStrategy"); MessageChannel defaultReplyChannel = (MessageChannel) context.getBean("replyChannel"); @@ -103,8 +105,9 @@ public class AggregatorParserTests { @Test public void testSimpleJavaBeanAggregator() { - AggregatingMessageHandler addingAggregator = (AggregatingMessageHandler) context.getBean("aggregatorWithReferenceAndMethod"); List> outboundMessages = new ArrayList>(); + HandlerEndpoint endpoint = (HandlerEndpoint) context.getBean("aggregatorWithReferenceAndMethod"); + AggregatingMessageHandler addingAggregator = (AggregatingMessageHandler) endpoint.getHandler(); outboundMessages.add(createMessage(1l, "id1", 3, 1, null)); outboundMessages.add(createMessage(2l, "id1", 3, 3, null)); outboundMessages.add(createMessage(3l, "id1", 3, 2, null)); @@ -121,21 +124,23 @@ public class AggregatorParserTests { context = new ClassPathXmlApplicationContext("invalidMethodNameAggregator.xml", this.getClass()); } - @Test(expected=BeanDefinitionParsingException.class) + @Test(expected=BeanCreationException.class) public void testDuplicateCompletionStrategyDefinition() { - context = new ClassPathXmlApplicationContext("completionStrategyMethodWithMissingReference.xml", this.getClass()); + context = new ClassPathXmlApplicationContext( + "completionStrategyMethodWithMissingReference.xml", this.getClass()); } @Test public void testAggregatorWithPojoCompletionStrategy(){ - AggregatingMessageHandler aggregatorWithPojoCompletionStrategy = (AggregatingMessageHandler) context.getBean("aggregatorWithPojoCompletionStrategy"); - CompletionStrategy completionStrategy = (CompletionStrategy)new DirectFieldAccessor(aggregatorWithPojoCompletionStrategy).getPropertyValue("completionStrategy"); + HandlerEndpoint endpoint = (HandlerEndpoint) context.getBean("aggregatorWithPojoCompletionStrategy"); + AggregatingMessageHandler aggregatorWithPojoCompletionStrategy = (AggregatingMessageHandler) endpoint.getHandler(); + CompletionStrategy completionStrategy = (CompletionStrategy) + new DirectFieldAccessor(aggregatorWithPojoCompletionStrategy).getPropertyValue("completionStrategy"); Assert.assertTrue(completionStrategy instanceof CompletionStrategyAdapter); DirectFieldAccessor completionStrategyAccessor = new DirectFieldAccessor(completionStrategy); MethodInvoker invoker = (MethodInvoker) completionStrategyAccessor.getPropertyValue("invoker"); Assert.assertTrue(new DirectFieldAccessor(invoker).getPropertyValue("object") instanceof MaxValueCompletionStrategy); Assert.assertTrue(((Method)completionStrategyAccessor.getPropertyValue("method")).getName().equals("checkCompleteness")); - aggregatorWithPojoCompletionStrategy.handle(createMessage(1l, "id1", 0 , 0, null)); aggregatorWithPojoCompletionStrategy.handle(createMessage(2l, "id1", 0 , 0, null)); aggregatorWithPojoCompletionStrategy.handle(createMessage(3l, "id1", 0 , 0, null)); @@ -148,9 +153,9 @@ public class AggregatorParserTests { Assert.assertEquals(11l, reply.getPayload()); } - @Test(expected=BeanDefinitionParsingException.class) - public void testAggregatorWithDuplicateCompletionStrategy() { - context = new ClassPathXmlApplicationContext("duplicateCompletionStrategy.xml", this.getClass()); + @Test(expected=BeanCreationException.class) + public void testAggregatorWithInvalidCompletionStrategyMethod() { + context = new ClassPathXmlApplicationContext("invalidCompletionStrategyMethod.xml", this.getClass()); } diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/aggregatorParserTests.xml b/org.springframework.integration/src/test/java/org/springframework/integration/config/aggregatorParserTests.xml index c29aeb04e1..12dcb99d5e 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/aggregatorParserTests.xml +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/aggregatorParserTests.xml @@ -9,27 +9,37 @@ - + + + - + + + send-timeout="86420000" + send-partial-result-on-timeout="true" + reaper-interval="135" + tracked-correlation-id-capacity="99" + timeout="42"/> - + - - - - - - + input-channel="inputChannel" + output-channel="replyChannel" + ref="adderBean" + method="add" + completion-strategy="pojoCompletionStrategy" + completion-strategy-method="checkCompleteness"/> diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/completionStrategyMethodWithMissingReference.xml b/org.springframework.integration/src/test/java/org/springframework/integration/config/completionStrategyMethodWithMissingReference.xml index f65c8f299c..79c7a8ce24 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/completionStrategyMethodWithMissingReference.xml +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/completionStrategyMethodWithMissingReference.xml @@ -9,14 +9,15 @@ - - + + - + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/duplicateCompletionStrategy.xml b/org.springframework.integration/src/test/java/org/springframework/integration/config/invalidCompletionStrategyMethod.xml similarity index 74% rename from org.springframework.integration/src/test/java/org/springframework/integration/config/duplicateCompletionStrategy.xml rename to org.springframework.integration/src/test/java/org/springframework/integration/config/invalidCompletionStrategyMethod.xml index 90793bdea9..789f480b67 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/duplicateCompletionStrategy.xml +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/invalidCompletionStrategyMethod.xml @@ -7,13 +7,15 @@ http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-core-1.0.xsd"> - - - + - + + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/invalidMethodNameAggregator.xml b/org.springframework.integration/src/test/java/org/springframework/integration/config/invalidMethodNameAggregator.xml index ab1a9712ea..f6429a06fc 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/invalidMethodNameAggregator.xml +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/invalidMethodNameAggregator.xml @@ -8,11 +8,13 @@ http://www.springframework.org/schema/integration/spring-integration-core-1.0.xsd"> - - + + + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/router/config/NumberAdder.java b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/NumberAdder.java new file mode 100644 index 0000000000..1939954d9a --- /dev/null +++ b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/NumberAdder.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002-2008 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.router.config; + +import java.util.List; + +/** + * @author Mark Fisher + */ +public class NumberAdder { + + public Integer sum(List values) { + int result = 0; + for (Integer value : values) { + result += value; + } + return result; + } + +} diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/router/config/NumberSplitter.java b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/NumberSplitter.java new file mode 100644 index 0000000000..579d0a213f --- /dev/null +++ b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/NumberSplitter.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002-2008 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.router.config; + +import java.util.List; + +/** + * @author Mark Fisher + */ +public class NumberSplitter { + + public List split(Numbers numbers) { + return numbers.getValues(); + } + +} diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/router/config/Numbers.java b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/Numbers.java new file mode 100644 index 0000000000..61ff60dd79 --- /dev/null +++ b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/Numbers.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002-2008 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.router.config; + +import java.util.List; + +/** + * @author Mark Fisher + */ +public class Numbers { + + private final List values; + + + public Numbers(List values) { + this.values = values; + } + + public List getValues() { + return this.values; + } + +} diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/router/config/SplitterAggregatorTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/SplitterAggregatorTests.java new file mode 100644 index 0000000000..6bef057a66 --- /dev/null +++ b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/SplitterAggregatorTests.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002-2008 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.router.config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.Test; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.integration.channel.MessageChannel; +import org.springframework.integration.message.GenericMessage; +import org.springframework.integration.message.Message; + +/** + * @author Mark Fisher + */ +public class SplitterAggregatorTests { + + private final AtomicInteger count = new AtomicInteger(); + + + @Test + public void testSplitterAndAggregator() { + ApplicationContext context = new ClassPathXmlApplicationContext( + "splitterAggregatorTests.xml", this.getClass()); + MessageChannel inputChannel = (MessageChannel) context.getBean("numbers"); + MessageChannel outputChannel = (MessageChannel) context.getBean("results"); + inputChannel.send(new GenericMessage(this.nextTen())); + Message result1 = outputChannel.receive(1000); + assertNotNull(result1); + assertEquals(Integer.class, result1.getPayload().getClass()); + assertEquals(55, result1.getPayload()); + inputChannel.send(new GenericMessage(this.nextTen())); + Message result2 = outputChannel.receive(1000); + assertNotNull(result2); + assertEquals(Integer.class, result2.getPayload().getClass()); + assertEquals(155, result2.getPayload()); + } + + private Numbers nextTen() { + List values = new ArrayList(); + for (int i = 0; i < 10; i++) { + values.add(this.count.incrementAndGet()); + } + return new Numbers(values); + } + +} diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/router/config/splitterAggregatorTests.xml b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/splitterAggregatorTests.xml new file mode 100644 index 0000000000..173b3147a7 --- /dev/null +++ b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/splitterAggregatorTests.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + +