diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XmlPayloadValidatingRouterParser.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XmlPayloadValidatingRouterParser.java index b27bd57803..83f3e8f7e6 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XmlPayloadValidatingRouterParser.java +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XmlPayloadValidatingRouterParser.java @@ -34,8 +34,6 @@ import org.w3c.dom.Element; public class XmlPayloadValidatingRouterParser extends AbstractConsumerEndpointParser { - private XPathExpressionParser xpathParser = new XPathExpressionParser(); - @Override protected boolean shouldGenerateId() { return false; diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathMultiChannelRouter.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathMultiChannelRouter.java index b3f72aa8bc..696ac0966b 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathMultiChannelRouter.java +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathMultiChannelRouter.java @@ -19,14 +19,13 @@ package org.springframework.integration.xml.router; import java.util.List; import java.util.Map; -import org.w3c.dom.DOMException; -import org.w3c.dom.Node; - import org.springframework.integration.core.Message; import org.springframework.integration.xml.XmlPayloadConverter; import org.springframework.util.Assert; import org.springframework.xml.xpath.NodeMapper; import org.springframework.xml.xpath.XPathExpression; +import org.w3c.dom.DOMException; +import org.w3c.dom.Node; /** * A router that evaluates the XPath expression using @@ -77,10 +76,9 @@ public class XPathMultiChannelRouter extends AbstractXPathRouter { } @SuppressWarnings("unchecked") - public String[] determineTargetChannelNames(Message message) { + public List getChannelIndicatorList(Message message) { Node node = getConverter().convertToNode(message.getPayload()); - List channelNamesList = getXPathExpression().evaluate(node, this.nodeMapper); - return (String[]) channelNamesList.toArray(new String[channelNamesList.size()]); + return getXPathExpression().evaluate(node, this.nodeMapper); } @@ -92,4 +90,6 @@ public class XPathMultiChannelRouter extends AbstractXPathRouter { } + + } diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathSingleChannelRouter.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathSingleChannelRouter.java index d77479ac5a..426a64b6a4 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathSingleChannelRouter.java +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathSingleChannelRouter.java @@ -16,15 +16,16 @@ package org.springframework.integration.xml.router; +import java.util.ArrayList; +import java.util.List; import java.util.Map; -import org.w3c.dom.Node; - import org.springframework.integration.core.Message; import org.springframework.integration.core.MessagingException; import org.springframework.integration.xml.DefaultXmlPayloadConverter; import org.springframework.integration.xml.XmlPayloadConverter; import org.springframework.xml.xpath.XPathExpression; +import org.w3c.dom.Node; /** * Router that evaluates the payload using {@link XPathExpression#evaluateAsString(Node)} @@ -73,14 +74,20 @@ public class XPathSingleChannelRouter extends AbstractXPathRouter { * @throws MessagingException if the {@link XPathExpression} evaluates to * an empty string */ - public String[] determineTargetChannelNames(Message message) { + + @Override + protected List getChannelIndicatorList(Message message) { + List channels = new ArrayList(); Node node = getConverter().convertToNode(message.getPayload()); String result = getXPathExpression().evaluateAsString(node); if (result == null || "".equals(result)) { return null; + } else { + channels.add(result); } - return new String[] { result }; + return channels; + } } diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathMultiChannelRouterTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathMultiChannelRouterTests.java index d4011b2f29..a163f4aaf9 100644 --- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathMultiChannelRouterTests.java +++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathMultiChannelRouterTests.java @@ -40,7 +40,7 @@ public class XPathMultiChannelRouterTests { Document doc = XmlTestUtil.getDocumentForString(""); XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); XPathMultiChannelRouter router = new XPathMultiChannelRouter(expression); - String[] channelNames = router.determineTargetChannelNames(new GenericMessage(doc)); + Object[] channelNames = router.getChannelIndicatorList(new GenericMessage(doc)).toArray(); assertEquals("Wrong number of channels returned", 1, channelNames.length); assertEquals("Wrong channel name", "one", channelNames[0]); } @@ -51,7 +51,7 @@ public class XPathMultiChannelRouterTests { Document doc = XmlTestUtil.getDocumentForString("bOnebTwo"); XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/book"); XPathMultiChannelRouter router = new XPathMultiChannelRouter(expression); - String[] channelNames = router.determineTargetChannelNames(new GenericMessage(doc)); + Object[] channelNames = router.getChannelIndicatorList(new GenericMessage(doc)).toArray(); assertEquals("Wrong number of channels returned", 2, channelNames.length); assertEquals("Wrong channel name", "bOne", channelNames[0]); assertEquals("Wrong channel name", "bTwo", channelNames[1]); @@ -62,7 +62,7 @@ public class XPathMultiChannelRouterTests { public void multipleNodeValuesAsString() throws Exception { XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/book"); XPathMultiChannelRouter router = new XPathMultiChannelRouter(expression); - String[] channelNames = router.determineTargetChannelNames(new GenericMessage("bOnebTwo")); + Object[] channelNames = router.getChannelIndicatorList(new GenericMessage("bOnebTwo")).toArray(); assertEquals("Wrong number of channels returned", 2, channelNames.length); assertEquals("Wrong channel name", "bOne", channelNames[0]); assertEquals("Wrong channel name", "bTwo", channelNames[1]); @@ -72,14 +72,14 @@ public class XPathMultiChannelRouterTests { public void nonNodePayload() throws Exception { XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); XPathMultiChannelRouter router = new XPathMultiChannelRouter(expression); - router.determineTargetChannelNames(new StringMessage("test")); + router.getChannelIndicatorList(new StringMessage("test")); } @Test public void nodePayload() throws Exception { XPathMultiChannelRouter router = new XPathMultiChannelRouter("./three/text()"); Document testDocument = XmlTestUtil.getDocumentForString("bobdave"); - String[] channelNames = router.determineTargetChannelNames(new GenericMessage(testDocument.getElementsByTagName("two").item(0))); + Object[] channelNames = router.getChannelIndicatorList(new GenericMessage(testDocument.getElementsByTagName("two").item(0))).toArray(); assertEquals("bob",channelNames[0]); assertEquals("dave",channelNames[1]); } diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathSingleChannelRouterTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathSingleChannelRouterTests.java index b9b3f331ce..ecd6171571 100644 --- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathSingleChannelRouterTests.java +++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathSingleChannelRouterTests.java @@ -38,7 +38,7 @@ public class XPathSingleChannelRouterTests { Document doc = XmlTestUtil.getDocumentForString(""); XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); XPathSingleChannelRouter router = new XPathSingleChannelRouter(expression); - String channelName = router.determineTargetChannelNames(new GenericMessage(doc))[0]; + Object channelName = router.getChannelIndicatorList(new GenericMessage(doc)).toArray()[0]; assertEquals("Wrong channel name", "one", channelName); } @@ -46,7 +46,7 @@ public class XPathSingleChannelRouterTests { public void testSimpleStringDoc() throws Exception { XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); XPathSingleChannelRouter router = new XPathSingleChannelRouter(expression); - String channelName = router.determineTargetChannelNames(new GenericMessage(""))[0]; + Object channelName = router.getChannelIndicatorList(new GenericMessage("")).toArray()[0]; assertEquals("Wrong channel name", "one", channelName); } @@ -54,15 +54,15 @@ public class XPathSingleChannelRouterTests { public void testNonNodePayload() throws Exception { XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); XPathSingleChannelRouter router = new XPathSingleChannelRouter(expression); - router.determineTargetChannelNames(new StringMessage("test")); + router.getChannelIndicatorList(new StringMessage("test")); } @Test public void testNodePayload() throws Exception { XPathSingleChannelRouter router = new XPathSingleChannelRouter("./three/text()"); Document testDocument = XmlTestUtil.getDocumentForString("bob"); - String[] channelNames = router.determineTargetChannelNames(new GenericMessage(testDocument - .getElementsByTagName("two").item(0))); + Object[] channelNames = router.getChannelIndicatorList(new GenericMessage(testDocument + .getElementsByTagName("two").item(0))).toArray(); assertEquals("bob", channelNames[0]); } @@ -71,7 +71,7 @@ public class XPathSingleChannelRouterTests { Document doc = XmlTestUtil.getDocumentForString(""); XPathExpression expression = XPathExpressionFactory.createXPathExpression("/somethingelse/@type"); XPathSingleChannelRouter router = new XPathSingleChannelRouter(expression); - Object channelNames = router.determineTargetChannelNames(new GenericMessage(doc)); + Object channelNames = router.getChannelIndicatorList(new GenericMessage(doc)); assertEquals("Wrong channel name", null, channelNames); } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/RouterFactoryBean.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/RouterFactoryBean.java index a47761c4cb..2871c7dbda 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/RouterFactoryBean.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/RouterFactoryBean.java @@ -19,6 +19,7 @@ package org.springframework.integration.config; import org.springframework.integration.channel.ChannelResolver; import org.springframework.integration.core.MessageChannel; import org.springframework.integration.message.MessageHandler; +import org.springframework.integration.router.AbstractChannelNameResolvingMessageRouter; import org.springframework.integration.router.AbstractMessageRouter; import org.springframework.integration.router.MethodInvokingRouter; import org.springframework.util.Assert; @@ -28,13 +29,17 @@ import org.springframework.util.StringUtils; * Factory bean for creating a Message Router. * * @author Mark Fisher + * @author Jonas Partner */ public class RouterFactoryBean extends AbstractMessageHandlerFactoryBean { private volatile ChannelResolver channelResolver; private volatile MessageChannel defaultOutputChannel; + + private volatile boolean resolutionRequired; + private volatile Boolean ignoreChannelNameResolutionFailures; public void setChannelResolver(ChannelResolver channelResolver) { this.channelResolver = channelResolver; @@ -43,6 +48,14 @@ public class RouterFactoryBean extends AbstractMessageHandlerFactoryBean { public void setDefaultOutputChannel(MessageChannel defaultOutputChannel) { this.defaultOutputChannel = defaultOutputChannel; } + + public void setResolutionRequired(boolean resolutionRequired){ + this.resolutionRequired = resolutionRequired; + } + + public void setIgnoreChannelNameResolutionFailures(boolean ignoreChannelNameResolutionFailures){ + this.ignoreChannelNameResolutionFailures = ignoreChannelNameResolutionFailures; + } @Override protected MessageHandler createHandler(Object targetObject, String targetMethodName) { @@ -51,6 +64,12 @@ public class RouterFactoryBean extends AbstractMessageHandlerFactoryBean { if (this.defaultOutputChannel != null) { router.setDefaultOutputChannel(this.defaultOutputChannel); } + if(ignoreChannelNameResolutionFailures != null ){ + Assert.isTrue(router instanceof AbstractChannelNameResolvingMessageRouter, + "Ignore channel name resolution failures can only set on rotuers extending " + AbstractChannelNameResolvingMessageRouter.class.getName()); + ((AbstractChannelNameResolvingMessageRouter)router).setIgnoreChannelNameResolutionFailures(ignoreChannelNameResolutionFailures); + } + router.setResolutionRequired(resolutionRequired); return router; } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/RouterParser.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/RouterParser.java index 1b234f2768..b9c7717d09 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/RouterParser.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/RouterParser.java @@ -49,6 +49,8 @@ public class RouterParser extends AbstractConsumerEndpointParser { resolverBuilder.getBeanDefinition(), parserContext.getRegistry()); builder.addPropertyReference("channelResolver", resolverBeanName); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "default-output-channel"); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "resolution-required"); + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-channel-name-resolution-failures"); return builder; } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd index 00fe614a70..8e8e9260b9 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd @@ -788,6 +788,8 @@ + + diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/router/AbstractChannelNameResolvingMessageRouter.java b/org.springframework.integration/src/main/java/org/springframework/integration/router/AbstractChannelNameResolvingMessageRouter.java index b420ba8cfb..fcade39899 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/router/AbstractChannelNameResolvingMessageRouter.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/router/AbstractChannelNameResolvingMessageRouter.java @@ -17,12 +17,15 @@ package org.springframework.integration.router; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.List; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.integration.channel.BeanFactoryChannelResolver; +import org.springframework.integration.channel.ChannelResolutionException; import org.springframework.integration.channel.ChannelResolver; import org.springframework.integration.core.Message; import org.springframework.integration.core.MessageChannel; @@ -30,12 +33,14 @@ import org.springframework.integration.core.MessagingException; import org.springframework.util.Assert; /** - * A base class for router implementations that return only - * the channel name(s) rather than {@link MessageChannel} instances. + * A base class for router implementations that return only the channel name(s) + * rather than {@link MessageChannel} instances. * * @author Mark Fisher + * @author Jonas Partner */ -public abstract class AbstractChannelNameResolvingMessageRouter extends AbstractMessageRouter implements BeanFactoryAware, InitializingBean { +public abstract class AbstractChannelNameResolvingMessageRouter extends + AbstractMessageRouter implements BeanFactoryAware, InitializingBean { private volatile ChannelResolver channelResolver; @@ -45,6 +50,7 @@ public abstract class AbstractChannelNameResolvingMessageRouter extends Abstract private volatile BeanFactory beanFactory; + private volatile boolean ignoreChannelNameResolutionFailures; public void setChannelResolver(ChannelResolver channelResolver) { this.channelResolver = channelResolver; @@ -62,45 +68,97 @@ public abstract class AbstractChannelNameResolvingMessageRouter extends Abstract this.beanFactory = beanFactory; } + public void setIgnoreChannelNameResolutionFailures( + boolean ignoreChannelNameResolutionFailures) { + this.ignoreChannelNameResolutionFailures = ignoreChannelNameResolutionFailures; + } + public void afterPropertiesSet() { if (this.channelResolver == null) { - Assert.notNull(beanFactory, "either a ChannelResolver or BeanFactory is required"); - this.channelResolver = new BeanFactoryChannelResolver(this.beanFactory); + Assert.notNull(beanFactory, + "either a ChannelResolver or BeanFactory is required"); + this.channelResolver = new BeanFactoryChannelResolver( + this.beanFactory); } } + protected MessageChannel resolveChannelForName(String channelName, + Message message) { + Assert.state(this.channelResolver != null, + "unable to resolve channel names, no ChannelResolver available"); + + MessageChannel channel = null; + try { + channel = this.channelResolver.resolveChannelName(channelName); + } catch (ChannelResolutionException e) { + if (!ignoreChannelNameResolutionFailures) + throw new MessagingException(message, + "failed to resolve channel name '" + channelName + "'", e); + } + if(channel == null && !ignoreChannelNameResolutionFailures){ + throw new MessagingException(message, + "failed to resolve channel name '" + channelName + "'"); + } + return channel; + } + @Override - protected final Collection determineTargetChannels(Message message) { + protected Collection determineTargetChannels( + Message message) { this.afterPropertiesSet(); Collection channels = new ArrayList(); - String[] channelNames = this.determineTargetChannelNames(message); - if (channelNames == null) { + Collection channelsReturned = this.getChannelIndicatorList(message); + addToCollection(channels, channelsReturned, message); + if (channels == null) { return null; } - for (String channelName : channelNames) { - if (channelName != null) { - Assert.state(this.channelResolver != null, - "unable to resolve channel names, no ChannelResolver available"); - if (this.prefix != null) { - channelName = this.prefix + channelName; + + return channels; + } + + + protected void addToCollection(Collection channels, Collection channelIndicators, Message message){ + if(channelIndicators == null){ + return; + } + for (Object channelIndicator : channelIndicators) { + if (channelIndicator == null) { + continue; + } else if (channelIndicator instanceof String) { + addChannelFromString(channels, (String)channelIndicator, message); + } else if (channelIndicator instanceof MessageChannel){ + channels.add((MessageChannel)channelIndicator); + } else if (channelIndicator instanceof Collection){ + addToCollection(channels, (Collection)channelIndicator, message); + } else if (channelIndicator instanceof MessageChannel[]) { + channels.addAll(Arrays.asList((MessageChannel[]) channelIndicator)); + } else if (channelIndicator instanceof String[]) { + for (String indicatorName : (String[]) channelIndicator) { + addChannelFromString(channels, indicatorName, message); } - if (this.suffix != null) { - channelName = channelName + suffix; - } - MessageChannel channel = this.channelResolver.resolveChannelName(channelName); - if (channel == null) { - throw new MessagingException(message, - "failed to resolve channel name '" + channelName + "'"); - } - channels.add(channel); + }else { + throw new MessagingException("unsupported return type for router [" + channelIndicator.getClass() + "]"); } } - return channels; + } + + + protected void addChannelFromString(Collection channels, String channelName, Message message){ + if (this.prefix != null) { + channelName = this.prefix + channelName; + } + if (this.suffix != null) { + channelName = channelName + suffix; + } + MessageChannel channel = resolveChannelForName(channelName,message); + if (channel != null) { + channels.add(channel); + } } /** - * Subclasses must implement this method to return the channel name(s). + * Subclasses must implement this method to return the channel indicators. */ - protected abstract String[] determineTargetChannelNames(Message message); + protected abstract List getChannelIndicatorList(Message message); } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/router/AbstractSingleChannelNameRouter.java b/org.springframework.integration/src/main/java/org/springframework/integration/router/AbstractSingleChannelNameRouter.java index fe5c5f0263..e8ae0de2f9 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/router/AbstractSingleChannelNameRouter.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/router/AbstractSingleChannelNameRouter.java @@ -16,6 +16,10 @@ package org.springframework.integration.router; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + import org.springframework.integration.core.Message; /** @@ -27,9 +31,13 @@ import org.springframework.integration.core.Message; public abstract class AbstractSingleChannelNameRouter extends AbstractChannelNameResolvingMessageRouter { @Override - protected final String[] determineTargetChannelNames(Message message) { - String channelName = this.determineTargetChannelName(message); - return (channelName != null) ? new String[] { channelName } : null; + protected final List getChannelIndicatorList(Message message) { + List channelList = new ArrayList(); + String channelName = determineTargetChannelName(message); + if(channelName != null){ + channelList.add(channelName); + } + return channelList; } /** diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/router/MethodInvokingRouter.java b/org.springframework.integration/src/main/java/org/springframework/integration/router/MethodInvokingRouter.java index ba2dee0696..d927468eb7 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/router/MethodInvokingRouter.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/router/MethodInvokingRouter.java @@ -18,17 +18,13 @@ package org.springframework.integration.router; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; import org.springframework.integration.annotation.Router; import org.springframework.integration.channel.ChannelResolver; import org.springframework.integration.core.Message; -import org.springframework.integration.core.MessageChannel; -import org.springframework.integration.core.MessagingException; import org.springframework.integration.handler.MessageMappingMethodInvoker; -import org.springframework.util.Assert; /** * A Message Router that invokes the specified method on the given object. The @@ -39,12 +35,11 @@ import org.springframework.util.Assert; * * @author Mark Fisher */ -public class MethodInvokingRouter extends AbstractMessageRouter { +public class MethodInvokingRouter extends AbstractChannelNameResolvingMessageRouter { private final MessageMappingMethodInvoker invoker; - private volatile ChannelResolver channelResolver; - + public MethodInvokingRouter(Object object, Method method) { this.invoker = new MessageMappingMethodInvoker(object, method); @@ -58,68 +53,12 @@ public class MethodInvokingRouter extends AbstractMessageRouter { this.invoker = new MessageMappingMethodInvoker(object, Router.class); } - - /** - * Provide the {@link ChannelResolver} strategy to use for methods that - * return a channel name rather than a {@link MessageChannel} instance. - */ - public void setChannelResolver(ChannelResolver channelResolver) { - this.channelResolver = channelResolver; - } - @Override - protected final Collection determineTargetChannels(Message message) { + protected List getChannelIndicatorList(Message message) { Object result = this.invoker.invokeMethod(message); - if (result == null) { - return null; - } - List channels = new ArrayList(); - if (result instanceof Collection) { - for (Object next : (Collection) result) { - this.addChannel(next, channels); - } - } - else if (result instanceof MessageChannel[]) { - channels.addAll(Arrays.asList((MessageChannel[]) result)); - } - else if (result instanceof String[]) { - for (String channelName : (String[]) result) { - this.addChannel(channelName, channels); - } - } - else if (result instanceof MessageChannel) { - channels.add((MessageChannel) result); - } - else if (result instanceof String) { - this.addChannel((String) result, channels); - } - else { - throw new IllegalStateException( - "router method must return type 'MessageChannel' or 'String'"); - } - return channels; - } - - private void addChannel(Object channelOrName, List channels) { - if (channelOrName == null) { - return; - } - if (channelOrName instanceof MessageChannel) { - channels.add((MessageChannel) channelOrName); - } - else if (channelOrName instanceof String) { - String channelName = (String) channelOrName; - Assert.state(this.channelResolver != null, - "unable to resolve channel names, no ChannelResolver available"); - MessageChannel channel = this.channelResolver.resolveChannelName(channelName); - if (channel == null) { - throw new MessagingException("failed to resolve channel name '" + channelName + "'"); - } - channels.add(channel); - } - else { - throw new MessagingException("unsupported return type for router [" + channelOrName.getClass() + "]"); - } + List asList = new ArrayList(); + asList.add(result); + return asList; } } diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/router/MethodInvokingRouterTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/router/MethodInvokingRouterTests.java index 5ce5cb0a49..b3cf501e5a 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/router/MethodInvokingRouterTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/router/MethodInvokingRouterTests.java @@ -25,11 +25,10 @@ import java.util.ArrayList; import java.util.List; import org.junit.Test; - import org.springframework.integration.annotation.Header; import org.springframework.integration.channel.ChannelResolver; -import org.springframework.integration.channel.TestChannelResolver; import org.springframework.integration.channel.QueueChannel; +import org.springframework.integration.channel.TestChannelResolver; import org.springframework.integration.core.Message; import org.springframework.integration.core.MessageChannel; import org.springframework.integration.core.MessagingException; diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/router/MultiChannelRouterTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/router/MultiChannelRouterTests.java index 2675be8d40..82aca926e8 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/router/MultiChannelRouterTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/router/MultiChannelRouterTests.java @@ -19,13 +19,15 @@ package org.springframework.integration.router; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import org.junit.Test; +import java.util.List; +import org.junit.Test; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.channel.TestChannelResolver; import org.springframework.integration.core.Message; import org.springframework.integration.core.MessagingException; import org.springframework.integration.message.StringMessage; +import org.springframework.util.CollectionUtils; /** * @author Mark Fisher @@ -35,8 +37,9 @@ public class MultiChannelRouterTests { @Test public void routeWithChannelMapping() { AbstractChannelNameResolvingMessageRouter router = new AbstractChannelNameResolvingMessageRouter() { - public String[] determineTargetChannelNames(Message message) { - return new String[] {"channel1", "channel2"}; + @SuppressWarnings("unchecked") + public List getChannelIndicatorList(Message message) { + return CollectionUtils.arrayToList(new String[] {"channel1", "channel2"}); } }; QueueChannel channel1 = new QueueChannel(); @@ -60,8 +63,9 @@ public class MultiChannelRouterTests { @Test(expected = MessagingException.class) public void channelNameLookupFailure() { AbstractChannelNameResolvingMessageRouter router = new AbstractChannelNameResolvingMessageRouter() { - public String[] determineTargetChannelNames(Message message) { - return new String[] {"noSuchChannel"}; + @SuppressWarnings("unchecked") + public List getChannelIndicatorList(Message message) { + return CollectionUtils.arrayToList(new String[] {"noSuchChannel"} ); } }; TestChannelResolver channelResolver = new TestChannelResolver(); @@ -73,8 +77,9 @@ public class MultiChannelRouterTests { @Test(expected = MessagingException.class) public void channelMappingNotAvailable() { AbstractChannelNameResolvingMessageRouter router = new AbstractChannelNameResolvingMessageRouter() { - public String[] determineTargetChannelNames(Message message) { - return new String[] {"noSuchChannel"}; + @SuppressWarnings("unchecked") + public List getChannelIndicatorList(Message message) { + return CollectionUtils.arrayToList(new String[] {"noSuchChannel"}); } }; Message message = new StringMessage("test"); diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/router/RouterTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/router/RouterTests.java index c84ad74a12..ff1499cae5 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/router/RouterTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/router/RouterTests.java @@ -18,11 +18,11 @@ package org.springframework.integration.router; import static org.junit.Assert.assertEquals; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.Test; - import org.springframework.context.support.GenericApplicationContext; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.channel.TestChannelResolver; @@ -31,6 +31,7 @@ import org.springframework.integration.core.MessageChannel; import org.springframework.integration.core.MessagingException; import org.springframework.integration.message.MessageDeliveryException; import org.springframework.integration.message.StringMessage; +import org.springframework.util.CollectionUtils; /** * @author Mark Fisher @@ -86,7 +87,7 @@ public class RouterTests { @Test public void nullChannelNameArrayIgnoredByDefault() { AbstractChannelNameResolvingMessageRouter router = new AbstractChannelNameResolvingMessageRouter() { - public String[] determineTargetChannelNames(Message message) { + protected List getChannelIndicatorList(Message message) { return null; } }; @@ -99,7 +100,7 @@ public class RouterTests { @Test(expected = MessageDeliveryException.class) public void nullChannelNameArrayThrowsExceptionWhenResolutionRequired() { AbstractChannelNameResolvingMessageRouter router = new AbstractChannelNameResolvingMessageRouter() { - public String[] determineTargetChannelNames(Message message) { + protected List getChannelIndicatorList(Message message) { return null; } }; @@ -114,8 +115,8 @@ public class RouterTests { @Test public void emptyChannelNameArrayIgnoredByDefault() { AbstractChannelNameResolvingMessageRouter router = new AbstractChannelNameResolvingMessageRouter() { - public String[] determineTargetChannelNames(Message message) { - return new String[] {}; + protected List getChannelIndicatorList(Message message) { + return new ArrayList(); } }; TestChannelResolver channelResolver = new TestChannelResolver(); @@ -127,8 +128,9 @@ public class RouterTests { @Test(expected = MessageDeliveryException.class) public void emptyChannelNameArrayThrowsExceptionWhenResolutionRequired() { AbstractChannelNameResolvingMessageRouter router = new AbstractChannelNameResolvingMessageRouter() { - public String[] determineTargetChannelNames(Message message) { - return new String[] {}; + @SuppressWarnings("unchecked") + protected List getChannelIndicatorList(Message message) { + return CollectionUtils.arrayToList(new String[] {}); } }; TestChannelResolver channelResolver = new TestChannelResolver(); @@ -151,8 +153,9 @@ public class RouterTests { @Test(expected = MessagingException.class) public void channelMappingIsRequiredWhenResolvingChannelNamesWithMultiChannelRouter() { AbstractChannelNameResolvingMessageRouter router = new AbstractChannelNameResolvingMessageRouter() { - public String[] determineTargetChannelNames(Message message) { - return new String[] { "notImportant" }; + @SuppressWarnings("unchecked") + protected List getChannelIndicatorList(Message message){ + return CollectionUtils.arrayToList(new String[] { "notImportant" }); } }; router.handleMessage(new StringMessage("this should fail")); @@ -177,8 +180,9 @@ public class RouterTests { @Test public void beanFactoryWithMultiChannelRouter() { AbstractChannelNameResolvingMessageRouter router = new AbstractChannelNameResolvingMessageRouter() { - public String[] determineTargetChannelNames(Message message) { - return new String[] { "testChannel" }; + @SuppressWarnings("unchecked") + protected List getChannelIndicatorList(Message message) { + return CollectionUtils.arrayToList(new String[] { "testChannel" }); } }; QueueChannel testChannel = new QueueChannel(); diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/router/config/RouterParserTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/RouterParserTests.java index ab31cc56c1..58932e48c0 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/router/config/RouterParserTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/RouterParserTests.java @@ -24,17 +24,19 @@ import java.util.Collection; import java.util.Collections; import org.junit.Test; - import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.annotation.Router; import org.springframework.integration.channel.PollableChannel; import org.springframework.integration.core.Message; import org.springframework.integration.core.MessageChannel; +import org.springframework.integration.message.GenericMessage; +import org.springframework.integration.message.MessageDeliveryException; import org.springframework.integration.message.StringMessage; import org.springframework.integration.router.AbstractMessageRouter; /** * @author Mark Fisher + * @author Jonas Partner */ public class RouterParserTests { @@ -97,7 +99,25 @@ public class RouterParserTests { assertNotNull(result); assertEquals("test-annotation", result.getPayload()); } + + @Test(expected=MessageDeliveryException.class) + public void testResolutionRequired() { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "routerParserTests.xml", this.getClass()); + context.start(); + MessageChannel input = (MessageChannel) context.getBean("inputForRouterRequiringResolution"); + input.send(new GenericMessage(3)); + } + + @Test + public void testIgnoreChannelNameResolutionFailures() { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "routerParserTests.xml", this.getClass()); + context.start(); + MessageChannel input = (MessageChannel) context.getBean("ignoreChannelNameResolutionFailuresInput"); + input.send(new StringMessage("channelThatDoesNotExist")); + } public static class TestRouterImplementation extends AbstractMessageRouter { @@ -127,5 +147,16 @@ public class RouterParserTests { return this.channel; } } + + public static class ReturnStringPassedInAsChannelNameRouter { + + @Router + public String route(Message message) { + return (String)message.getPayload(); + } + + + } + } diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/router/config/routerParserTests.xml b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/routerParserTests.xml index 24be26f7f3..bbb4f4a457 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/router/config/routerParserTests.xml +++ b/org.springframework.integration/src/test/java/org/springframework/integration/router/config/routerParserTests.xml @@ -54,5 +54,14 @@ + + + + + + + + +