diff --git a/docs/src/reference/docbook/router.xml b/docs/src/reference/docbook/router.xml index 5f5d896d4b..e4bfe6b2d4 100644 --- a/docs/src/reference/docbook/router.xml +++ b/docs/src/reference/docbook/router.xml @@ -96,10 +96,6 @@ order - - channel-resolver - - method @@ -188,10 +184,6 @@ order - - channel-resolver - - method @@ -793,8 +785,8 @@ public List route(@Header("orderStatus") OrderStatus status)]]> Step 3 - Resolve channel name to the actual instance of the - MessageChannel where using ChannelResolver, the router will obtain a - reference to a bean (which is hopefully a MessageChannel) identified by the result of the + MessageChannel as a reference to a bean within the Application Context + (which is hopefully a MessageChannel) identified by the result of the previous step. @@ -825,8 +817,8 @@ public List route(@Header("orderStatus") OrderStatus status)]]> Step 3 - Resolve channel name to the actual instance of the - MessageChannel where using ChannelResolver, the router will obtain a - reference to a bean (which is hopefully a MessageChannel) identified by the result of the + MessageChannel as a reference to a bean within the Application Context + (which is hopefully a MessageChannel) identified by the result of the previous step. @@ -860,9 +852,8 @@ public List route(@Header("orderStatus") OrderStatus status)]]> So all that is left is for Step 3 to resolve the channel name ('kermit') to an actual instance of the - MessageChannel identified by this name. That will be done via the default - ChannelResolver implementation which is a BeanFactoryChannelResolver. It - basically does a bean lookup for the name provided. So now all messages which contain the header/value pair as testHeader=kermit + MessageChannel identified by this name. That basically involves a bean lookup + for the name provided. So now all messages which contain the header/value pair as testHeader=kermit are going to be routed to a MessageChannel whose bean name (id) is 'kermit'. diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/RouterFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/RouterFactoryBean.java index 4580252a1a..99c2abfaae 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/RouterFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/RouterFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 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 @@ -18,10 +18,9 @@ import java.util.Map; import org.springframework.expression.Expression; import org.springframework.integration.MessageChannel; import org.springframework.integration.core.MessageHandler; -import org.springframework.integration.router.AbstractMessageRouter; +import org.springframework.integration.router.AbstractMappingMessageRouter; import org.springframework.integration.router.ExpressionEvaluatingRouter; import org.springframework.integration.router.MethodInvokingRouter; -import org.springframework.integration.support.channel.ChannelResolver; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -35,9 +34,7 @@ import org.springframework.util.StringUtils; */ public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean { - private volatile ChannelResolver channelResolver; - - private volatile Map channelIdentifierMap; + private volatile Map channelMappings; private volatile MessageChannel defaultOutputChannel; @@ -50,10 +47,6 @@ public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean private volatile Boolean ignoreSendFailures; - public void setChannelResolver(ChannelResolver channelResolver) { - this.channelResolver = channelResolver; - } - public void setDefaultOutputChannel(MessageChannel defaultOutputChannel) { this.defaultOutputChannel = defaultOutputChannel; } @@ -74,14 +67,14 @@ public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean this.ignoreSendFailures = ignoreSendFailures; } - public void setChannelIdentifierMap(Map channelIdentifierMap) { - this.channelIdentifierMap = channelIdentifierMap; + public void setChannelMappings(Map channelMappings) { + this.channelMappings = channelMappings; } @Override MessageHandler createMethodInvokingHandler(Object targetObject, String targetMethodName) { Assert.notNull(targetObject, "target object must not be null"); - AbstractMessageRouter router = this.extractTypeIfPossible(targetObject, AbstractMessageRouter.class); + AbstractMappingMessageRouter router = this.extractTypeIfPossible(targetObject, AbstractMappingMessageRouter.class); if (router == null) { router = this.createMethodInvokingRouter(targetObject, targetMethodName); this.configureRouter(router); @@ -102,19 +95,16 @@ public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean return this.configureRouter(new ExpressionEvaluatingRouter(expression)); } - private AbstractMessageRouter createMethodInvokingRouter(Object targetObject, String targetMethodName) { + private AbstractMappingMessageRouter createMethodInvokingRouter(Object targetObject, String targetMethodName) { MethodInvokingRouter router = (StringUtils.hasText(targetMethodName)) ? new MethodInvokingRouter(targetObject, targetMethodName) : new MethodInvokingRouter(targetObject); return router; } - private AbstractMessageRouter configureRouter(AbstractMessageRouter router) { - if (this.channelResolver != null) { - router.setChannelResolver(this.channelResolver); - } - if (this.channelIdentifierMap != null) { - router.setChannelIdentifierMap(this.channelIdentifierMap); + private AbstractMappingMessageRouter configureRouter(AbstractMappingMessageRouter router) { + if (this.channelMappings != null) { + router.setChannelMappings(this.channelMappings); } if (this.defaultOutputChannel != null) { router.setDefaultOutputChannel(this.defaultOutputChannel); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/RouterAnnotationPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/RouterAnnotationPostProcessor.java index 10292e524b..afbc6f1cd4 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/RouterAnnotationPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/RouterAnnotationPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2011 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. @@ -41,7 +41,7 @@ public class RouterAnnotationPostProcessor extends AbstractMethodAnnotationPostP @Override protected MessageHandler createHandler(Object bean, Method method, Router annotation) { MethodInvokingRouter router = new MethodInvokingRouter(bean, method); - router.setChannelResolver(this.channelResolver); + router.setBeanFactory(this.beanFactory); String defaultOutputChannelName = annotation.defaultOutputChannel(); if (StringUtils.hasText(defaultOutputChannelName)) { MessageChannel defaultOutputChannel = this.channelResolver.resolveChannelName(defaultOutputChannelName); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractRouterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractRouterParser.java index d71772d157..2923617092 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractRouterParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractRouterParser.java @@ -21,11 +21,11 @@ import java.util.List; import org.w3c.dom.Element; import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.ManagedMap; import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.StringUtils; +import org.springframework.integration.config.RouterFactoryBean; +import org.springframework.util.CollectionUtils; import org.springframework.util.xml.DomUtils; /** @@ -37,8 +37,7 @@ public abstract class AbstractRouterParser extends AbstractConsumerEndpointParse @Override protected final BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( - IntegrationNamespaceUtils.BASE_PACKAGE + ".config.RouterFactoryBean"); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RouterFactoryBean.class); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "default-output-channel"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "timeout"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "resolution-required"); @@ -52,28 +51,28 @@ public abstract class AbstractRouterParser extends AbstractConsumerEndpointParse protected final BeanDefinition parseRouter(Element element, ParserContext parserContext) { BeanDefinition beanDefinition = this.doParseRouter(element, parserContext); if (beanDefinition != null) { - String channelResolver = element.getAttribute("channel-resolver"); - if (StringUtils.hasText(channelResolver)){ - beanDefinition.getPropertyValues().add("channelResolver", new RuntimeBeanReference(channelResolver)); - } // check if mapping is provided otherwise returned values will be treated as channel names - List childElements = DomUtils.getChildElementsByTagName(element, "mapping"); - if (childElements != null && childElements.size() > 0) { - ManagedMap channelMap = new ManagedMap(); - for (Element childElement : childElements) { - String key = childElement.getAttribute(this.getMappingKeyAttributeValue()); - channelMap.put(key, childElement.getAttribute("channel")); + List mappingElements = DomUtils.getChildElementsByTagName(element, "mapping"); + if (!CollectionUtils.isEmpty(mappingElements)) { + ManagedMap channelMappings = new ManagedMap(); + for (Element mappingElement : mappingElements) { + String key = mappingElement.getAttribute(this.getMappingKeyAttributeName()); + channelMappings.put(key, mappingElement.getAttribute("channel")); } - beanDefinition.getPropertyValues().add("channelIdentifierMap", channelMap); + beanDefinition.getPropertyValues().add("channelMappings", channelMappings); } } return beanDefinition; } - protected abstract BeanDefinition doParseRouter(Element element, ParserContext parserContext); - - protected String getMappingKeyAttributeValue(){ + /** + * Returns the name of the attribute that provides a key for the + * channel mappings. This can be overridden by subclasses. + */ + protected String getMappingKeyAttributeName() { return "value"; } + protected abstract BeanDefinition doParseRouter(Element element, ParserContext parserContext); + } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultRouterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultRouterParser.java index 6d41dba418..d434544a6b 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultRouterParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultRouterParser.java @@ -18,14 +18,13 @@ package org.springframework.integration.config.xml; import java.util.List; +import org.w3c.dom.Element; + import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.ManagedMap; -import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; /** * Parser for the <router/> element. @@ -35,9 +34,6 @@ import org.w3c.dom.Element; */ public class DefaultRouterParser extends AbstractDelegatingConsumerEndpointParser { - private static final String CHANNEL_RESOLVER_PROPERTY = "channelResolver"; - - @Override String getFactoryBeanClassName() { return IntegrationNamespaceUtils.BASE_PACKAGE + ".config.RouterFactoryBean"; @@ -50,30 +46,13 @@ public class DefaultRouterParser extends AbstractDelegatingConsumerEndpointParse @Override protected void postProcess(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) { - String resolverBeanName = element.getAttribute("channel-resolver"); List mappingElements = DomUtils.getChildElementsByTagName(element, "mapping"); if (!CollectionUtils.isEmpty(mappingElements)) { - if (StringUtils.hasText(resolverBeanName)) { - parserContext.getReaderContext().error( - "The 'channel-resolver' attribute and 'mapping' sub-elements are mutually exclusive.", - parserContext.extractSource(element)); - } - BeanDefinitionBuilder channelResolverBuilder = BeanDefinitionBuilder.genericBeanDefinition( - IntegrationNamespaceUtils.BASE_PACKAGE + ".support.channel.BeanFactoryChannelResolver"); - ManagedMap channelMap = new ManagedMap(); + ManagedMap channelMappings = new ManagedMap(); for (Element mappingElement : mappingElements) { - channelMap.put(mappingElement.getAttribute("value"), mappingElement.getAttribute("channel")); + channelMappings.put(mappingElement.getAttribute("value"), mappingElement.getAttribute("channel")); } - builder.addPropertyValue("channelIdentifierMap", channelMap); - builder.addPropertyValue(CHANNEL_RESOLVER_PROPERTY, channelResolverBuilder.getBeanDefinition()); - } - else if (StringUtils.hasText(resolverBeanName)) { - builder.addPropertyReference(CHANNEL_RESOLVER_PROPERTY, resolverBeanName); - } - else { - RootBeanDefinition resolverBeanDefintion = new RootBeanDefinition( - IntegrationNamespaceUtils.BASE_PACKAGE + ".support.channel.BeanFactoryChannelResolver"); - builder.addPropertyValue(CHANNEL_RESOLVER_PROPERTY, resolverBeanDefintion); + builder.addPropertyValue("channelMappings", channelMappings); } IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "default-output-channel"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "timeout"); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ErrorMessageExceptionTypeRouterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ErrorMessageExceptionTypeRouterParser.java index 6086db8033..d431f55812 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ErrorMessageExceptionTypeRouterParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ErrorMessageExceptionTypeRouterParser.java @@ -16,11 +16,13 @@ package org.springframework.integration.config.xml; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.xml.ParserContext; import org.w3c.dom.Element; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.integration.router.ErrorMessageExceptionTypeRouter; + /** * Parser for the <exception-type-router/> element. * @@ -28,17 +30,15 @@ import org.w3c.dom.Element; * @since 2.0.4 */ public class ErrorMessageExceptionTypeRouterParser extends AbstractRouterParser { - + @Override - protected BeanDefinition doParseRouter(Element element, - ParserContext parserContext) { - BeanDefinitionBuilder payloadTypeRouterBuilder = BeanDefinitionBuilder.genericBeanDefinition( - IntegrationNamespaceUtils.BASE_PACKAGE + ".router.ErrorMessageExceptionTypeRouter"); - return payloadTypeRouterBuilder.getBeanDefinition(); - } - - @Override - protected String getMappingKeyAttributeValue(){ + protected String getMappingKeyAttributeName() { return "exception-type"; } + + @Override + protected BeanDefinition doParseRouter(Element element, ParserContext parserContext) { + return new RootBeanDefinition(ErrorMessageExceptionTypeRouter.class); + } + } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderValueRouterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderValueRouterParser.java index 704489c496..ae4cfcc045 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderValueRouterParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderValueRouterParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.w3c.dom.Element; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.integration.router.HeaderValueRouter; /** * Parser for the <header-value-router/> element. @@ -33,8 +34,7 @@ public class HeaderValueRouterParser extends AbstractRouterParser { @Override protected BeanDefinition doParseRouter(Element element, ParserContext parserContext) { - BeanDefinitionBuilder headerValueRouterBuilder = BeanDefinitionBuilder.genericBeanDefinition( - IntegrationNamespaceUtils.BASE_PACKAGE + ".router.HeaderValueRouter"); + BeanDefinitionBuilder headerValueRouterBuilder = BeanDefinitionBuilder.genericBeanDefinition(HeaderValueRouter.class); headerValueRouterBuilder.addConstructorArgValue(element.getAttribute("header-name")); return headerValueRouterBuilder.getBeanDefinition(); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadTypeRouterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadTypeRouterParser.java index 3c3f565014..15d79ba7d9 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadTypeRouterParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadTypeRouterParser.java @@ -17,8 +17,9 @@ package org.springframework.integration.config.xml; import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.integration.router.PayloadTypeRouter; import org.w3c.dom.Element; /** @@ -29,17 +30,15 @@ import org.w3c.dom.Element; * @since 1.0.3 */ public class PayloadTypeRouterParser extends AbstractRouterParser { - + @Override - protected BeanDefinition doParseRouter(Element element, - ParserContext parserContext) { - BeanDefinitionBuilder payloadTypeRouterBuilder = BeanDefinitionBuilder.genericBeanDefinition( - IntegrationNamespaceUtils.BASE_PACKAGE + ".router.PayloadTypeRouter"); - return payloadTypeRouterBuilder.getBeanDefinition(); - } - - @Override - protected String getMappingKeyAttributeValue(){ + protected String getMappingKeyAttributeName() { return "type"; } + + @Override + protected BeanDefinition doParseRouter(Element element, ParserContext parserContext) { + return new RootBeanDefinition(PayloadTypeRouter.class); + } + } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java new file mode 100644 index 0000000000..69229406fa --- /dev/null +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java @@ -0,0 +1,229 @@ +/* + * Copyright 2002-2011 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; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.integration.Message; +import org.springframework.integration.MessageChannel; +import org.springframework.integration.MessagingException; +import org.springframework.integration.support.channel.BeanFactoryChannelResolver; +import org.springframework.integration.support.channel.ChannelResolutionException; +import org.springframework.integration.support.channel.ChannelResolver; +import org.springframework.jmx.export.annotation.ManagedOperation; +import org.springframework.jmx.export.annotation.ManagedResource; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Base class for all Message Routers. + * + * @author Mark Fisher + * @author Oleg Zhurakousky + * @author Gunnar Hillert + * @since 2.1 + */ +@ManagedResource +public abstract class AbstractMappingMessageRouter extends AbstractMessageRouter { + + private final Map channelMappings = new ConcurrentHashMap(); + + private volatile ChannelResolver channelResolver; + + private volatile String prefix; + + private volatile String suffix; + + private volatile boolean resolutionRequired = true; + + + /** + * Provide mappings from channel keys to channel names. + * Channel names will be resolved by the {@link ChannelResolver}. + */ + public void setChannelMappings(Map channelMappings) { + this.channelMappings.clear(); + this.channelMappings.putAll(channelMappings); + } + + /** + * Specify the {@link ChannelResolver} strategy to use. + * The default is a BeanFactoryChannelResolver. + */ + public void setChannelResolver(ChannelResolver channelResolver) { + Assert.notNull(channelResolver, "'channelResolver' must not be null"); + this.channelResolver = channelResolver; + } + + /** + * Specify a prefix to be added to each channel name prior to resolution. + */ + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + /** + * Specify a suffix to be added to each channel name prior to resolution. + */ + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + /** + * Specify whether this router should ignore any failure to resolve a channel name to + * an actual MessageChannel instance when delegating to the ChannelResolver strategy. + */ + public void setResolutionRequired(boolean resolutionRequired) { + this.resolutionRequired = resolutionRequired; + } + + /** + * Returns an unmodifiable version of the channel mappings. + * This is intended for use by subclasses only. + */ + protected Map getChannelMappings() { + return Collections.unmodifiableMap(this.channelMappings); + } + + /** + * Add a channel mapping from the provided key to channel name. + */ + @ManagedOperation + public void setChannelMapping(String key, String channelName) { + this.channelMappings.put(key, channelName); + } + + /** + * Remove a channel mapping for the given key if present. + */ + @ManagedOperation + public void removeChannelMapping(String key) { + this.channelMappings.remove(key); + } + + @Override + public void onInit() { + BeanFactory beanFactory = this.getBeanFactory(); + if (this.channelResolver == null && beanFactory != null) { + this.channelResolver = new BeanFactoryChannelResolver(beanFactory); + } + } + + /** + * Subclasses must implement this method to return the channel keys. + * A "key" might be present in this router's "channelMappings", or it + * could be the channel's name or even the Message Channel instance itself. + */ + protected abstract List getChannelKeys(Message message); + + + @Override + protected Collection determineTargetChannels(Message message) { + Collection channels = new ArrayList(); + Collection channelKeys = this.getChannelKeys(message); + addToCollection(channels, channelKeys, message); + return channels; + } + + private MessageChannel resolveChannelForName(String channelName, Message message) { + if (this.channelResolver == null) { + this.onInit(); + } + 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 (this.resolutionRequired) { + throw new MessagingException(message, "failed to resolve channel name '" + channelName + "'", e); + } + } + if (channel == null && this.resolutionRequired) { + throw new MessagingException(message, "failed to resolve channel name '" + channelName + "'"); + } + return channel; + } + + private void addChannelFromString(Collection channels, String channelKey, Message message) { + if (channelKey.indexOf(',') != -1) { + for (String name : StringUtils.tokenizeToStringArray(channelKey, ",")) { + addChannelFromString(channels, name, message); + } + return; + } + + // if the channelMappings contains a mapping, we'll use the mapped value + // otherwise, the String-based channelKey itself will be used as the channel name + String channelName = channelKey; + if (this.channelMappings.containsKey(channelKey)) { + channelName = this.channelMappings.get(channelKey); + } + if (this.prefix != null) { + channelName = this.prefix + channelName; + } + if (this.suffix != null) { + channelName = channelName + this.suffix; + } + MessageChannel channel = resolveChannelForName(channelName, message); + if (channel != null) { + channels.add(channel); + } + } + + private void addToCollection(Collection channels, Collection channelKeys, Message message) { + if (channelKeys == null) { + return; + } + for (Object channelKey : channelKeys) { + if (channelKey == null) { + continue; + } + else if (channelKey instanceof MessageChannel) { + channels.add((MessageChannel) channelKey); + } + else if (channelKey instanceof MessageChannel[]) { + channels.addAll(Arrays.asList((MessageChannel[]) channelKey)); + } + else if (channelKey instanceof String) { + addChannelFromString(channels, (String) channelKey, message); + } + else if (channelKey instanceof String[]) { + for (String indicatorName : (String[]) channelKey) { + addChannelFromString(channels, indicatorName, message); + } + } + else if (channelKey instanceof Collection) { + addToCollection(channels, (Collection) channelKey, message); + } + else if (this.getRequiredConversionService().canConvert(channelKey.getClass(), String.class)) { + addChannelFromString(channels, this.getConversionService().convert(channelKey, String.class), message); + } + else { + throw new MessagingException("unsupported return type for router [" + channelKey.getClass() + "]"); + } + } + } + +} diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageProcessingRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageProcessingRouter.java index 6bcd5011aa..49a5d07108 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageProcessingRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageProcessingRouter.java @@ -32,7 +32,7 @@ import org.springframework.util.Assert; * @author Mark Fisher * @since 2.0 */ -class AbstractMessageProcessingRouter extends AbstractMessageRouter { +class AbstractMessageProcessingRouter extends AbstractMappingMessageRouter { private final MessageProcessor messageProcessor; @@ -55,7 +55,7 @@ class AbstractMessageProcessingRouter extends AbstractMessageRouter { } @Override - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { Object result = this.messageProcessor.processMessage(message); return Collections.singletonList(result); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java index a1e05df3b2..e4406e6c8d 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java @@ -16,14 +16,8 @@ package org.springframework.integration.router; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import org.springframework.beans.factory.BeanFactory; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.ConversionServiceFactory; import org.springframework.integration.Message; @@ -34,14 +28,7 @@ import org.springframework.integration.channel.NullChannel; import org.springframework.integration.core.MessagingTemplate; import org.springframework.integration.handler.AbstractMessageHandler; import org.springframework.integration.support.MessageBuilder; -import org.springframework.integration.support.channel.BeanFactoryChannelResolver; -import org.springframework.integration.support.channel.ChannelResolutionException; -import org.springframework.integration.support.channel.ChannelResolver; -import org.springframework.jmx.export.annotation.ManagedOperation; import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; /** * Base class for all Message Routers. @@ -61,63 +48,6 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler { private final MessagingTemplate messagingTemplate = new MessagingTemplate(); - private volatile String prefix; - - private volatile String suffix; - - private volatile ChannelResolver channelResolver; - - private volatile boolean resolutionRequired = true; - - protected volatile Map channelIdentifierMap = new ConcurrentHashMap(); - - - /** - * Specify the {@link ChannelResolver} strategy to use. - * The default is a BeanFactoryChannelResolver. - */ - public void setChannelResolver(ChannelResolver channelResolver) { - Assert.notNull(channelResolver, "'channelResolver' must not be null"); - this.channelResolver = channelResolver; - } - - /** - * Specify a prefix to be added to each channel name prior to resolution. - */ - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - /** - * Specify a suffix to be added to each channel name prior to resolution. - */ - public void setSuffix(String suffix) { - this.suffix = suffix; - } - - /** - * Allows you to set the map which will map channel identifiers to channel names. - * Channel names will be resolve via {@link ChannelResolver} - * @param channelIdentifierMap - */ - public void setChannelIdentifierMap(Map channelIdentifierMap) { - this.channelIdentifierMap.clear(); - this.channelIdentifierMap.putAll(channelIdentifierMap); - } - - @ManagedOperation - public void setChannelMapping(String channelIdentifier, String channelName) { - this.channelIdentifierMap.put(channelIdentifier, channelName); - } - - /** - * Removes channel mapping for a give channel identifier - * @param channelIdentifier - */ - @ManagedOperation - public void removeChannelMapping(String channelIdentifier) { - this.channelIdentifierMap.remove(channelIdentifier); - } /** * Set the default channel where Messages should be sent if channel resolution @@ -139,14 +69,6 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler { this.messagingTemplate.setSendTimeout(timeout); } - /** - * Specify whether this router should ignore any failure to resolve a channel name to - * an actual MessageChannel instance when delegating to the ChannelResolver strategy. - */ - public void setResolutionRequired(boolean resolutionRequired) { - this.resolutionRequired = resolutionRequired; - } - /** * Specify whether send failures for one or more of the recipients should be ignored. By default this is * false meaning that an Exception will be thrown whenever a send fails. To override this and suppress @@ -178,14 +100,6 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler { return this.messagingTemplate; } - @Override - public void onInit() { - BeanFactory beanFactory = this.getBeanFactory(); - if (this.channelResolver == null && beanFactory != null) { - this.channelResolver = new BeanFactoryChannelResolver(beanFactory); - } - } - protected ConversionService getRequiredConversionService() { if (this.getConversionService() == null) { this.setConversionService(ConversionServiceFactory.createDefaultConversionService()); @@ -194,10 +108,10 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler { } /** - * Subclasses must implement this method to return the channel identifiers. + * Subclasses must implement this method to return a Collection of zero or more + * MessageChannels to which the given Message should be routed. */ - protected abstract List getChannelIdentifiers(Message message); - + protected abstract Collection determineTargetChannels(Message message); @Override protected void handleMessageInternal(Message message) { @@ -228,103 +142,12 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler { if (!sent) { if (this.defaultOutputChannel != null) { this.messagingTemplate.send(this.defaultOutputChannel, message); - } else { + } + else { throw new MessageDeliveryException(message, "no channel resolved by router and no default output channel defined"); } } } - private Collection determineTargetChannels(Message message) { - Collection channels = new ArrayList(); - Collection channelsReturned = this.getChannelIdentifiers(message); - addToCollection(channels, channelsReturned, message); - return channels; - } - - private MessageChannel resolveChannelForName(String channelName, Message message) { - if (this.channelResolver == null) { - this.onInit(); - } - 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 (this.resolutionRequired) { - throw new MessagingException(message, - "failed to resolve channel name '" + channelName + "'", e); - } - } - if (channel == null && this.resolutionRequired) { - throw new MessagingException(message, - "failed to resolve channel name '" + channelName + "'"); - } - return channel; - } - - private void addChannelFromString(Collection channels, String channelIdentifier, Message message) { - if (channelIdentifier.indexOf(',') != -1) { - for (String name : StringUtils.commaDelimitedListToStringArray(channelIdentifier)) { - addChannelFromString(channels, name, message); - } - return; - } - - // if the channelIdentifierMap contains a mapping, we'll use the mapped value - // otherwise, the String-based channelIdentifier itself will be used as the channel name - String channelName = channelIdentifier; - if (!CollectionUtils.isEmpty(channelIdentifierMap) && channelIdentifierMap.containsKey(channelIdentifier)) { - channelName = channelIdentifierMap.get(channelIdentifier); - } - 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); - } - } - - private void addToCollection(Collection channels, Collection channelIndicators, Message message) { - if (channelIndicators == null) { - return; - } - for (Object channelIndicator : channelIndicators) { - if (channelIndicator == null) { - continue; - } - else if (channelIndicator instanceof MessageChannel) { - channels.add((MessageChannel) channelIndicator); - } - else if (channelIndicator instanceof MessageChannel[]) { - channels.addAll(Arrays.asList((MessageChannel[]) channelIndicator)); - } - else if (channelIndicator instanceof String) { - addChannelFromString(channels, (String) channelIndicator, message); - } - else if (channelIndicator instanceof String[]) { - for (String indicatorName : (String[]) channelIndicator) { - addChannelFromString(channels, indicatorName, message); - } - } - else if (channelIndicator instanceof Collection) { - addToCollection(channels, (Collection) channelIndicator, message); - } - else if (this.getRequiredConversionService().canConvert(channelIndicator.getClass(), String.class)) { - addChannelFromString(channels, - this.getConversionService().convert(channelIndicator, String.class), message); - } - else { - throw new MessagingException( - "unsupported return type for router [" + channelIndicator.getClass() + "]"); - } - } - } - } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/ErrorMessageExceptionTypeRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/ErrorMessageExceptionTypeRouter.java index 6be71ca33f..30bc6260a9 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/ErrorMessageExceptionTypeRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/ErrorMessageExceptionTypeRouter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 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. @@ -30,23 +30,23 @@ import org.springframework.integration.MessageChannel; * @author Mark Fisher * @author Oleg Zhurakousky */ -public class ErrorMessageExceptionTypeRouter extends AbstractMessageRouter { +public class ErrorMessageExceptionTypeRouter extends AbstractMappingMessageRouter { @Override - protected List getChannelIdentifiers(Message message) { - String channelIdentifier = null; + protected List getChannelKeys(Message message) { + String mostSpecificCause = null; Object payload = message.getPayload(); - if (payload != null && (payload instanceof Throwable) && this.channelIdentifierMap != null) { - Throwable mostSpecificCause = (Throwable) payload; - while (mostSpecificCause != null) { - String mappedChannelIdentifier = this.channelIdentifierMap.get(mostSpecificCause.getClass().getName()); - if (mappedChannelIdentifier != null) { - channelIdentifier = mappedChannelIdentifier; + if (payload instanceof Throwable) { + Throwable cause = (Throwable) payload; + while (cause != null) { + String causeName = cause.getClass().getName(); + if (this.getChannelMappings().keySet().contains(causeName)) { + mostSpecificCause = causeName; } - mostSpecificCause = mostSpecificCause.getCause(); + cause = cause.getCause(); } } - return Collections.singletonList((Object) channelIdentifier); + return Collections.singletonList((Object) mostSpecificCause); } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/HeaderValueRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/HeaderValueRouter.java index 95b409be38..85ff6f7e24 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/HeaderValueRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/HeaderValueRouter.java @@ -30,7 +30,7 @@ import org.springframework.util.StringUtils; * @author Mark Fisher * @since 1.0.3 */ -public class HeaderValueRouter extends AbstractMessageRouter { +public class HeaderValueRouter extends AbstractMappingMessageRouter { private final String headerName; @@ -43,7 +43,7 @@ public class HeaderValueRouter extends AbstractMessageRouter { } @Override - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { Object value = message.getHeaders().get(this.headerName); if (value instanceof String && ((String) value).indexOf(',') != -1) { value = StringUtils.tokenizeToStringArray((String) value, ",", true, true); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/PayloadTypeRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/PayloadTypeRouter.java index 48aa1a1066..0a333bf218 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/PayloadTypeRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/PayloadTypeRouter.java @@ -31,7 +31,7 @@ import org.springframework.util.CollectionUtils; * @author Mark Fisher * @author Oleg Zhurakousky */ -public class PayloadTypeRouter extends AbstractMessageRouter { +public class PayloadTypeRouter extends AbstractMappingMessageRouter { private static final String ARRAY_SUFFIX = "[]"; @@ -45,13 +45,8 @@ public class PayloadTypeRouter extends AbstractMessageRouter { * preferring direct interface over indirect subclass */ @Override - protected List getChannelIdentifiers(Message message) { - String channelName = this.getChannelName(message); - return (channelName != null) ? Collections.singletonList(channelName) : null; - } - - private String getChannelName(Message message) { - if (CollectionUtils.isEmpty(this.channelIdentifierMap)) { + protected List getChannelKeys(Message message) { + if (CollectionUtils.isEmpty(this.getChannelMappings())) { return null; } Class type = message.getPayload().getClass(); @@ -59,13 +54,15 @@ public class PayloadTypeRouter extends AbstractMessageRouter { if (isArray) { type = type.getComponentType(); } - return this.findClosestMatch(type, isArray); + String closestMatch = this.findClosestMatch(type, isArray); + return (closestMatch != null) ? Collections.singletonList(closestMatch) : null; } + private String findClosestMatch(Class type, boolean isArray) { int minTypeDiffWeight = Integer.MAX_VALUE; List matches = new ArrayList(); - for (String candidate : this.channelIdentifierMap.keySet()) { + for (String candidate : this.getChannelMappings().keySet()) { if (isArray) { if (!candidate.endsWith(ARRAY_SUFFIX)) { continue; @@ -96,7 +93,7 @@ public class PayloadTypeRouter extends AbstractMessageRouter { return null; } // we have a winner - return this.channelIdentifierMap.get(matches.get(0)); + return matches.get(0); } private int determineTypeDifferenceWeight(String candidate, Class type, int level) { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/RecipientListRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/RecipientListRouter.java index f4a5da0cdb..7d39102ce7 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/RecipientListRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/RecipientListRouter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 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. @@ -17,6 +17,7 @@ package org.springframework.integration.router; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import org.springframework.beans.factory.InitializingBean; @@ -39,7 +40,7 @@ import org.springframework.util.Assert; * the values can be provided via the {@link #setRecipients(List)} method. *

* For more advanced, programmatic control of dynamic recipient lists, consider - * using the @Router annotation or extending {@link AbstractMessageRouter} instead. + * using the @Router annotation or extending {@link AbstractMappingMessageRouter} instead. *

* Contrary to a standard <router .../> this handler will try to send to * all channels that are configured as recipients. It is to channels what a @@ -90,8 +91,8 @@ public class RecipientListRouter extends AbstractMessageRouter implements Initia } @Override - protected List getChannelIdentifiers(Message message) { - List channels = new ArrayList(); + protected Collection determineTargetChannels(Message message) { + List channels = new ArrayList(); List recipientList = this.recipients; for (Recipient recipient : recipientList) { if (recipient.accept(message)) { diff --git a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.1.xsd b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.1.xsd index 376db49549..49e876e88e 100644 --- a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.1.xsd +++ b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.1.xsd @@ -2115,22 +2115,6 @@ endpoint itself is a Polling Consumer for a channel with a queue. - - - - - - - - - - diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/RouterFactoryBeanDelegationTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/RouterFactoryBeanDelegationTests-context.xml index 45dd357678..9b10eb8e90 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/RouterFactoryBeanDelegationTests-context.xml +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/RouterFactoryBeanDelegationTests-context.xml @@ -19,7 +19,7 @@ - + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/RouterFactoryBeanDelegationTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/RouterFactoryBeanDelegationTests.java index ba5b15c1fb..e690afaee5 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/RouterFactoryBeanDelegationTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/RouterFactoryBeanDelegationTests.java @@ -29,7 +29,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.integration.MessageChannel; import org.springframework.integration.core.PollableChannel; import org.springframework.integration.message.GenericMessage; -import org.springframework.integration.router.AbstractMessageRouter; +import org.springframework.integration.router.AbstractMappingMessageRouter; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -50,7 +50,7 @@ public class RouterFactoryBeanDelegationTests { private PollableChannel discard; @Autowired @Qualifier("org.springframework.integration.config.RouterFactoryBean#0") - private AbstractMessageRouter router; + private AbstractMappingMessageRouter router; @Test diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/ErrorMessageExceptionTypeRouterTests.java b/spring-integration-core/src/test/java/org/springframework/integration/router/ErrorMessageExceptionTypeRouterTests.java index 5854782d7b..716b958bbe 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/ErrorMessageExceptionTypeRouterTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/ErrorMessageExceptionTypeRouterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 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. @@ -72,7 +72,7 @@ public class ErrorMessageExceptionTypeRouterTests { exceptionTypeChannelMap.put(IllegalArgumentException.class.getName(), "illegalArgumentChannel"); exceptionTypeChannelMap.put(RuntimeException.class.getName(), "runtimeExceptionChannel"); exceptionTypeChannelMap.put(MessageHandlingException.class.getName(), "messageHandlingExceptionChannel"); - router.setChannelIdentifierMap(exceptionTypeChannelMap); + router.setChannelMappings(exceptionTypeChannelMap); router.setBeanFactory(beanFactory); @@ -95,7 +95,7 @@ public class ErrorMessageExceptionTypeRouterTests { Map exceptionTypeChannelMap = new HashMap(); exceptionTypeChannelMap.put(RuntimeException.class.getName(), "runtimeExceptionChannel"); exceptionTypeChannelMap.put(MessageHandlingException.class.getName(), "runtimeExceptionChannel"); - router.setChannelIdentifierMap(exceptionTypeChannelMap); + router.setChannelMappings(exceptionTypeChannelMap); router.setBeanFactory(beanFactory); router.setDefaultOutputChannel(defaultChannel); @@ -116,7 +116,7 @@ public class ErrorMessageExceptionTypeRouterTests { ErrorMessageExceptionTypeRouter router = new ErrorMessageExceptionTypeRouter(); Map exceptionTypeChannelMap = new HashMap(); exceptionTypeChannelMap.put(MessageHandlingException.class.getName(), "messageHandlingExceptionChannel"); - router.setChannelIdentifierMap(exceptionTypeChannelMap); + router.setChannelMappings(exceptionTypeChannelMap); router.setBeanFactory(beanFactory); router.setDefaultOutputChannel(defaultChannel); router.handleMessage(message); @@ -152,7 +152,7 @@ public class ErrorMessageExceptionTypeRouterTests { ErrorMessageExceptionTypeRouter router = new ErrorMessageExceptionTypeRouter(); Map exceptionTypeChannelMap = new HashMap(); exceptionTypeChannelMap.put(MessageDeliveryException.class.getName(), "messageDeliveryExceptionChannel"); - router.setChannelIdentifierMap(exceptionTypeChannelMap); + router.setChannelMappings(exceptionTypeChannelMap); router.setBeanFactory(beanFactory); router.setResolutionRequired(true); router.handleMessage(message); @@ -170,7 +170,7 @@ public class ErrorMessageExceptionTypeRouterTests { exceptionTypeChannelMap.put(IllegalArgumentException.class.getName(), "illegalArgumentChannel"); exceptionTypeChannelMap.put(RuntimeException.class.getName(), "runtimeExceptionChannel"); exceptionTypeChannelMap.put(MessageHandlingException.class.getName(), "messageHandlingExceptionChannel"); - router.setChannelIdentifierMap(exceptionTypeChannelMap); + router.setChannelMappings(exceptionTypeChannelMap); router.setBeanFactory(beanFactory); router.setDefaultOutputChannel(defaultChannel); router.handleMessage(message); @@ -191,7 +191,7 @@ public class ErrorMessageExceptionTypeRouterTests { Map exceptionTypeChannelMap = new HashMap(); exceptionTypeChannelMap.put(IllegalArgumentException.class.getName(), "illegalArgumentChannel"); exceptionTypeChannelMap.put(MessageHandlingException.class.getName(), "messageHandlingExceptionChannel"); - router.setChannelIdentifierMap(exceptionTypeChannelMap); + router.setChannelMappings(exceptionTypeChannelMap); router.setBeanFactory(beanFactory); router.setDefaultOutputChannel(defaultChannel); router.handleMessage(message); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/HeaderValueRouterTests.java b/spring-integration-core/src/test/java/org/springframework/integration/router/HeaderValueRouterTests.java index 34417791d7..ddcd8eb984 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/HeaderValueRouterTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/HeaderValueRouterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2011 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. @@ -90,12 +90,12 @@ public class HeaderValueRouterTests { @SuppressWarnings({ "unchecked", "rawtypes" }) public void resolveChannelNameFromMap() { StaticApplicationContext context = new StaticApplicationContext(); - ManagedMap channelMap = new ManagedMap(); - channelMap.put("testKey", "testChannel"); + ManagedMap channelMappings = new ManagedMap(); + channelMappings.put("testKey", "testChannel"); RootBeanDefinition routerBeanDefinition = new RootBeanDefinition(HeaderValueRouter.class); routerBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue("testHeaderName"); routerBeanDefinition.getPropertyValues().addPropertyValue("resolutionRequired", "true"); - routerBeanDefinition.getPropertyValues().addPropertyValue("channelIdentifierMap", channelMap); + routerBeanDefinition.getPropertyValues().addPropertyValue("channelMappings", channelMappings); routerBeanDefinition.getPropertyValues().addPropertyValue("beanFactory", context); context.registerBeanDefinition("router", routerBeanDefinition); context.registerBeanDefinition("testChannel", new RootBeanDefinition(QueueChannel.class)); @@ -112,12 +112,12 @@ public class HeaderValueRouterTests { @SuppressWarnings({ "unchecked", "rawtypes" }) public void resolveChannelNameFromMapAndCustomeResolver() { final StaticApplicationContext context = new StaticApplicationContext(); - ManagedMap channelMap = new ManagedMap(); - channelMap.put("testKey", "testChannel"); + ManagedMap channelMappings = new ManagedMap(); + channelMappings.put("testKey", "testChannel"); RootBeanDefinition routerBeanDefinition = new RootBeanDefinition(HeaderValueRouter.class); routerBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue("testHeaderName"); routerBeanDefinition.getPropertyValues().addPropertyValue("resolutionRequired", "true"); - routerBeanDefinition.getPropertyValues().addPropertyValue("channelIdentifierMap", channelMap); + routerBeanDefinition.getPropertyValues().addPropertyValue("channelMappings", channelMappings); routerBeanDefinition.getPropertyValues().addPropertyValue("beanFactory", context); routerBeanDefinition.getPropertyValues().addPropertyValue("channelResolver", new ChannelResolver() { public MessageChannel resolveChannelName(String channelName) { diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/MultiChannelRouterTests.java b/spring-integration-core/src/test/java/org/springframework/integration/router/MultiChannelRouterTests.java index 9510075228..1ccae67586 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/MultiChannelRouterTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/MultiChannelRouterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 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. @@ -23,6 +23,7 @@ import static org.mockito.Mockito.mock; import java.util.List; import org.junit.Test; + import org.springframework.beans.factory.BeanFactory; import org.springframework.integration.Message; import org.springframework.integration.MessagingException; @@ -38,9 +39,9 @@ public class MultiChannelRouterTests { @Test public void routeWithChannelMapping() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - public List getChannelIdentifiers(Message message) { + public List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new String[] {"channel1", "channel2"}); } }; @@ -62,9 +63,9 @@ public class MultiChannelRouterTests { @Test(expected = MessagingException.class) public void channelNameLookupFailure() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - public List getChannelIdentifiers(Message message) { + public List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new String[] {"noSuchChannel"} ); } }; @@ -76,9 +77,9 @@ public class MultiChannelRouterTests { @Test(expected = MessagingException.class) public void channelMappingNotAvailable() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - public List getChannelIdentifiers(Message message) { + public List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new String[] {"noSuchChannel"}); } }; diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/PayloadTypeRouterTests.java b/spring-integration-core/src/test/java/org/springframework/integration/router/PayloadTypeRouterTests.java index 0a132ea2ee..bcbcb21377 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/PayloadTypeRouterTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/PayloadTypeRouterTests.java @@ -51,22 +51,32 @@ public class PayloadTypeRouterTests { payloadTypeChannelMap.put(String.class.getName(), "stringChannel"); payloadTypeChannelMap.put(Integer.class.getName(), "integerChannel"); PayloadTypeRouter router = new PayloadTypeRouter(); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setBeanFactory(beanFactory); Message message1 = new GenericMessage("test"); Message message2 = new GenericMessage(123); - assertEquals(1, router.getChannelIdentifiers(message1).size()); - assertEquals("stringChannel", router.getChannelIdentifiers(message1).iterator().next()); - assertEquals(1, router.getChannelIdentifiers(message2).size()); - assertEquals("integerChannel", router.getChannelIdentifiers(message2).iterator().next()); + assertEquals(1, router.getChannelKeys(message1).size()); + assertNull(stringChannel.receive(0)); + router.handleMessage(message1); + assertEquals(message1, stringChannel.receive(0)); + + assertEquals(1, router.getChannelKeys(message2).size()); + + assertNull(integerChannel.receive(0)); + router.handleMessage(message2); + assertEquals(message2, integerChannel.receive(0)); + // validate dynamics QueueChannel newChannel = new QueueChannel(); beanFactory.registerSingleton("newChannel", newChannel); router.setChannelMapping(String.class.getName(), "newChannel"); - assertEquals(1, router.getChannelIdentifiers(message1).size()); - assertEquals("newChannel", router.getChannelIdentifiers(message1).iterator().next()); + assertEquals(1, router.getChannelKeys(message1).size()); + + assertNull(newChannel.receive(0)); + router.handleMessage(message1); + assertEquals(message1, newChannel.receive(0)); // validate exception is thrown if mappings were removed and // channelResolutionRequires = true (which is the default) @@ -98,7 +108,7 @@ public class PayloadTypeRouterTests { Map payloadTypeChannelMap = new ConcurrentHashMap(); payloadTypeChannelMap.put(Number.class.getName(), "numberChannel"); PayloadTypeRouter router = new PayloadTypeRouter(); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setBeanFactory(beanFactory); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(99); @@ -112,7 +122,7 @@ public class PayloadTypeRouterTests { QueueChannel newChannel = new QueueChannel(); beanFactory.registerSingleton("newChannel", newChannel); router.setChannelMapping(Integer.class.getName(), "newChannel"); - assertEquals(1, router.getChannelIdentifiers(message).size()); + assertEquals(1, router.getChannelKeys(message).size()); router.handleMessage(message); result = newChannel.receive(10); assertNotNull(result); @@ -138,7 +148,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(99); @@ -166,7 +176,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(99); @@ -193,7 +203,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(new C1()); @@ -224,7 +234,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(new C1()); @@ -255,7 +265,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(new C1()); @@ -286,7 +296,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(new C1()); @@ -315,7 +325,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(99); @@ -330,7 +340,7 @@ public class PayloadTypeRouterTests { QueueChannel newChannel = new QueueChannel(); beanFactory.registerSingleton("newChannel", newChannel); router.setChannelMapping(Integer.class.getName(), "newChannel"); - assertEquals(1, router.getChannelIdentifiers(message).size()); + assertEquals(1, router.getChannelKeys(message).size()); router.handleMessage(message); result = newChannel.receive(10); assertNotNull(result); @@ -356,7 +366,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage("test"); @@ -383,7 +393,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(99); @@ -412,7 +422,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); Message message1 = new GenericMessage("test"); Message message2 = new GenericMessage(123); @@ -440,7 +450,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message1 = new GenericMessage("test"); @@ -481,7 +491,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(new C1()); @@ -515,7 +525,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(new C1()); @@ -548,7 +558,7 @@ public class PayloadTypeRouterTests { PayloadTypeRouter router = new PayloadTypeRouter(); router.setBeanFactory(beanFactory); - router.setChannelIdentifierMap(payloadTypeChannelMap); + router.setChannelMappings(payloadTypeChannelMap); router.setDefaultOutputChannel(defaultChannel); Message message = new GenericMessage(new C1()); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/RouterTests.java b/spring-integration-core/src/test/java/org/springframework/integration/router/RouterTests.java index 57bb3bd919..a57469f7c9 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/RouterTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/RouterTests.java @@ -44,9 +44,9 @@ public class RouterTests { @Test(expected = MessageDeliveryException.class) public void nullChannelRaisesMessageDeliveryExceptionByDefault() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @Override - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return null; } }; @@ -56,9 +56,9 @@ public class RouterTests { @Test(expected = MessageDeliveryException.class) public void nullChannelIdentifierUsingChannelResolverRaisesMessageDeliveryExceptionByDefault() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @Override - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return null; } }; @@ -70,9 +70,9 @@ public class RouterTests { @Test(expected = MessageDeliveryException.class) public void nullChannelIdentifierInListRaisesMessageDeliveryExceptionByDefault() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @Override - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return Collections.singletonList(null); } }; @@ -84,8 +84,8 @@ public class RouterTests { @Test(expected = MessageDeliveryException.class) public void emptyChannelNameArrayRaisesMessageDeliveryExceptionByDefault() { - AbstractMessageRouter router = new AbstractMessageRouter() { - protected List getChannelIdentifiers(Message message) { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { + protected List getChannelKeys(Message message) { return new ArrayList(); } }; @@ -97,9 +97,9 @@ public class RouterTests { @Test(expected = MessagingException.class) public void channelMappingIsRequiredWhenResolvingChannelNames() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message){ + protected List getChannelKeys(Message message){ return CollectionUtils.arrayToList(new String[] { "notImportant" }); } }; @@ -109,9 +109,9 @@ public class RouterTests { @Test public void beanFactoryWithRouter() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new String[] { "testChannel" }); } }; @@ -126,9 +126,9 @@ public class RouterTests { @Test public void beanFactoryWithRouterAndMultipleCommaSeparatedChannelNames() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new String[] { "testChannel1,testChannel2" }); } }; @@ -154,9 +154,9 @@ public class RouterTests { @Test(expected = MessagingException.class) public void channelResolutionIsRequiredByDefault() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new String[] { "testChannelDoesNotExist", "testChannel" }); } }; @@ -172,9 +172,9 @@ public class RouterTests { @Test public void unresolvableChannelIdentifierInListAreIgnoredWhenResolutionRequiredIsFalse() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new String[] { "testChannelDoesNotExist", "testChannel" }); } }; @@ -193,9 +193,9 @@ public class RouterTests { @Test public void beanFactoryWithRouterAndChannelPrefix() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new String[] { "MyChannel" }); } }; @@ -214,9 +214,9 @@ public class RouterTests { @Test(expected = MessagingException.class) public void beanFactoryWithRouterAndChannelPrefixFailing() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new String[] { "testing_MyChannel" }); } }; @@ -233,9 +233,9 @@ public class RouterTests { @Test public void beanFactoryWithRouterAndChannelSuffix() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new String[] { "MyChannel" }); } }; @@ -253,9 +253,9 @@ public class RouterTests { @Test(expected = MessagingException.class) public void beanFactoryWithRouterAndChannelSuffixFailing() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new String[] { "MyChannel_withSuffix" }); } }; @@ -272,9 +272,9 @@ public class RouterTests { @Test public void beanFactoryWithRouterAndChannelIdentifiersInListWithinAList() { - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { List channelNames1 = CollectionUtils.arrayToList(new String[] { "channel1" }); List channelNames2 = CollectionUtils.arrayToList(new String[] { "channel2" }); @@ -312,9 +312,9 @@ public class RouterTests { final QueueChannel testChannel1 = new QueueChannel(); final QueueChannel testChannel2 = new QueueChannel(); - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { MessageChannel[] channelNames1 = new MessageChannel[] { testChannel1 }; MessageChannel[] channelNames2 = new MessageChannel[] { testChannel2 }; @@ -349,9 +349,9 @@ public class RouterTests { final QueueChannel testChannel1 = new QueueChannel(); final QueueChannel testChannel2 = new QueueChannel(); - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new Integer[] { 100, 200 }); } }; @@ -375,6 +375,7 @@ public class RouterTests { String channel = "channel1"; + @SuppressWarnings("unused") public String getChannel() { return this.channel; } @@ -386,9 +387,9 @@ public class RouterTests { final QueueChannel testChannel1 = new QueueChannel(); - AbstractMessageRouter router = new AbstractMessageRouter() { + AbstractMappingMessageRouter router = new AbstractMappingMessageRouter() { @SuppressWarnings("unchecked") - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return CollectionUtils.arrayToList(new CustomObjectWithChannelName[] { new CustomObjectWithChannelName() }); } }; diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/config/RouterParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/router/config/RouterParserTests.java index 372d5cc70b..6f3ed419b7 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/config/RouterParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/config/RouterParserTests.java @@ -19,7 +19,6 @@ package org.springframework.integration.router.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -29,6 +28,7 @@ import java.util.List; import org.junit.Test; import org.mockito.Mockito; + import org.springframework.beans.DirectFieldAccessor; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.Message; @@ -41,7 +41,7 @@ import org.springframework.integration.core.MessagingTemplate; import org.springframework.integration.core.PollableChannel; import org.springframework.integration.core.SubscribableChannel; import org.springframework.integration.message.GenericMessage; -import org.springframework.integration.router.AbstractMessageRouter; +import org.springframework.integration.router.AbstractMappingMessageRouter; import org.springframework.integration.router.MethodInvokingRouter; import org.springframework.integration.support.channel.ChannelResolver; import org.springframework.integration.test.util.TestUtils; @@ -142,18 +142,6 @@ public class RouterParserTests { assertEquals(new Long(1234), timeout); } - @Test - public void channelResolverConfigured() { - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( - "routerParserTests.xml", this.getClass()); - Object channelResolverBean = context.getBean("testChannelResolver"); - Object endpoint = context.getBean("routerWithChannelResolver"); - MethodInvokingRouter router = TestUtils.getPropertyValue(endpoint, "handler", MethodInvokingRouter.class); - ChannelResolver channelResolver = (ChannelResolver) - new DirectFieldAccessor(router).getPropertyValue("channelResolver"); - assertSame(channelResolverBean, channelResolver); - } - @Test public void sequence() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( @@ -196,7 +184,7 @@ public class RouterParserTests { } } - public static class TestRouterImplementation extends AbstractMessageRouter { + public static class TestRouterImplementation extends AbstractMappingMessageRouter { private final MessageChannel channel; @@ -206,7 +194,7 @@ public class RouterParserTests { @Override - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { return Collections.singletonList((Object)this.channel); } } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/config/RouterWithMappingTests.java b/spring-integration-core/src/test/java/org/springframework/integration/router/config/RouterWithMappingTests.java index ea3baaeccb..8a0bc215dd 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/config/RouterWithMappingTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/config/RouterWithMappingTests.java @@ -28,7 +28,7 @@ import org.springframework.integration.Message; import org.springframework.integration.MessageChannel; import org.springframework.integration.config.ConsumerEndpointFactoryBean; import org.springframework.integration.core.PollableChannel; -import org.springframework.integration.router.AbstractMessageRouter; +import org.springframework.integration.router.AbstractMappingMessageRouter; import org.springframework.integration.support.MessageBuilder; import org.springframework.integration.test.util.TestUtils; import org.springframework.test.context.ContextConfiguration; @@ -87,7 +87,7 @@ public class RouterWithMappingTests { assertNull(fooChannelForExpression.receive(0)); assertNull(barChannelForExpression.receive(0)); // validate dynamics - AbstractMessageRouter router = (AbstractMessageRouter) TestUtils.getPropertyValue(spelRouter, "handler"); + AbstractMappingMessageRouter router = (AbstractMappingMessageRouter) TestUtils.getPropertyValue(spelRouter, "handler"); router.setChannelMapping("baz", "fooChannelForExpression"); expressionRouter.send(message3); assertNull(defaultChannelForExpression.receive(10)); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/config/routerParserTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/router/config/routerParserTests.xml index 3a1c69ac26..805da92b92 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/config/routerParserTests.xml +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/config/routerParserTests.xml @@ -80,10 +80,6 @@ - - - diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/config/XPathRouterParser.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/config/XPathRouterParser.java index ad5b5c7499..0b17a95ba9 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/config/XPathRouterParser.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/config/XPathRouterParser.java @@ -24,6 +24,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.xml.AbstractRouterParser; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; +import org.springframework.integration.xml.router.XPathRouter; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -36,15 +37,13 @@ import org.springframework.util.StringUtils; */ public class XPathRouterParser extends AbstractRouterParser { - private XPathExpressionParser xpathParser = new XPathExpressionParser(); + private final XPathExpressionParser xpathParser = new XPathExpressionParser(); @Override protected BeanDefinition doParseRouter(Element element, ParserContext parserContext) { - BeanDefinitionBuilder xpathRouterBuilder = BeanDefinitionBuilder.genericBeanDefinition( - "org.springframework.integration.xml.router.XPathRouter"); - NodeList xPathExpressionNodes = element.getElementsByTagNameNS( - element.getNamespaceURI(), "xpath-expression"); + BeanDefinitionBuilder xpathRouterBuilder = BeanDefinitionBuilder.genericBeanDefinition(XPathRouter.class); + NodeList xPathExpressionNodes = element.getElementsByTagNameNS(element.getNamespaceURI(), "xpath-expression"); Assert.isTrue(xPathExpressionNodes.getLength() <= 1, "At most one xpath-expression child may be specified."); String xPathExpressionRef = element.getAttribute("xpath-expression-ref"); IntegrationNamespaceUtils.setValueIfAttributeDefined(xpathRouterBuilder, element, "evaluate-as-string"); @@ -53,8 +52,7 @@ public class XPathRouterParser extends AbstractRouterParser { Assert.isTrue(xPathExpressionChildPresent ^ xPathReferencePresent, "Exactly one of 'xpath-expression' or 'xpath-expression-ref' is required."); if (xPathExpressionChildPresent) { - BeanDefinition beanDefinition = this.xpathParser.parse( - (Element) xPathExpressionNodes.item(0), parserContext); + BeanDefinition beanDefinition = this.xpathParser.parse((Element) xPathExpressionNodes.item(0), parserContext); xpathRouterBuilder.addConstructorArgValue(beanDefinition); } else { diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/router/XPathRouter.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/router/XPathRouter.java index ddb24fb791..dbd604d8bc 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/router/XPathRouter.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/router/XPathRouter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 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. @@ -22,7 +22,7 @@ import java.util.List; import java.util.Map; import org.springframework.integration.Message; -import org.springframework.integration.router.AbstractMessageRouter; +import org.springframework.integration.router.AbstractMappingMessageRouter; import org.springframework.integration.xml.DefaultXmlPayloadConverter; import org.springframework.integration.xml.XmlPayloadConverter; import org.springframework.util.Assert; @@ -38,7 +38,7 @@ import org.w3c.dom.Node; * @author Jonas Partner * @author Oleg Zhurakousky */ -public class XPathRouter extends AbstractMessageRouter { +public class XPathRouter extends AbstractMappingMessageRouter { private volatile NodeMapper nodeMapper = new TextContentNodeMapper(); @@ -113,10 +113,10 @@ public class XPathRouter extends AbstractMessageRouter { } @Override - protected List getChannelIdentifiers(Message message) { + protected List getChannelKeys(Message message) { Node node = this.converter.convertToNode(message.getPayload()); - if (this.evaluateAsString){ - return Collections.singletonList((Object)this.xPathExpression.evaluateAsString(node)); + if (this.evaluateAsString) { + return Collections.singletonList((Object) this.xPathExpression.evaluateAsString(node)); } else { return this.xPathExpression.evaluate(node, this.nodeMapper); diff --git a/spring-integration-xml/src/test/java/org/springframework/integration/xml/config/XPathRouterParserTests.java b/spring-integration-xml/src/test/java/org/springframework/integration/xml/config/XPathRouterParserTests.java index 84c7e5e7cb..7096faef01 100644 --- a/spring-integration-xml/src/test/java/org/springframework/integration/xml/config/XPathRouterParserTests.java +++ b/spring-integration-xml/src/test/java/org/springframework/integration/xml/config/XPathRouterParserTests.java @@ -37,7 +37,7 @@ import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.core.PollableChannel; import org.springframework.integration.endpoint.EventDrivenConsumer; import org.springframework.integration.message.GenericMessage; -import org.springframework.integration.router.AbstractMessageRouter; +import org.springframework.integration.router.AbstractMappingMessageRouter; import org.springframework.integration.support.MessageBuilder; import org.springframework.integration.test.util.TestUtils; import org.springframework.integration.xml.DefaultXmlPayloadConverter; @@ -181,7 +181,7 @@ public class XPathRouterParserTests { assertNull(channelB.receive(10)); EventDrivenConsumer routerEndpoint = ac.getBean("xpathRouterEmpty", EventDrivenConsumer.class); - AbstractMessageRouter xpathRouter = (AbstractMessageRouter) TestUtils.getPropertyValue(routerEndpoint, "handler"); + AbstractMappingMessageRouter xpathRouter = (AbstractMappingMessageRouter) TestUtils.getPropertyValue(routerEndpoint, "handler"); xpathRouter.setChannelMapping("channelA", "channelB"); inputChannel.send(docMessage); assertNotNull(channelB.receive(10)); @@ -201,7 +201,7 @@ public class XPathRouterParserTests { assertNotNull(channelB.receive(10)); EventDrivenConsumer routerEndpoint = ac.getBean("xpathRouterWithMapping", EventDrivenConsumer.class); - AbstractMessageRouter xpathRouter = (AbstractMessageRouter) TestUtils.getPropertyValue(routerEndpoint, "handler"); + AbstractMappingMessageRouter xpathRouter = (AbstractMappingMessageRouter) TestUtils.getPropertyValue(routerEndpoint, "handler"); xpathRouter.removeChannelMapping("channelA"); inputChannel.send(docMessage); assertNotNull(channelA.receive(10)); @@ -223,7 +223,7 @@ public class XPathRouterParserTests { assertNull(channelB.receive(10)); EventDrivenConsumer routerEndpoint = ac.getBean("xpathRouterWithMappingMultiChannel", EventDrivenConsumer.class); - AbstractMessageRouter xpathRouter = (AbstractMessageRouter) TestUtils.getPropertyValue(routerEndpoint, "handler"); + AbstractMappingMessageRouter xpathRouter = (AbstractMappingMessageRouter) TestUtils.getPropertyValue(routerEndpoint, "handler"); xpathRouter.removeChannelMapping("channelA"); xpathRouter.removeChannelMapping("channelB"); inputChannel.send(docMessage); diff --git a/spring-integration-xml/src/test/java/org/springframework/integration/xml/router/XPathRouterTests.java b/spring-integration-xml/src/test/java/org/springframework/integration/xml/router/XPathRouterTests.java index e2de69e94b..bef0c73a43 100644 --- a/spring-integration-xml/src/test/java/org/springframework/integration/xml/router/XPathRouterTests.java +++ b/spring-integration-xml/src/test/java/org/springframework/integration/xml/router/XPathRouterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 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. @@ -41,7 +41,7 @@ public class XPathRouterTests { Document doc = XmlTestUtil.getDocumentForString(""); XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); XPathRouter router = new XPathRouter(expression); - Object[] channelNames = router.getChannelIdentifiers(new GenericMessage(doc)).toArray(); + Object[] channelNames = router.getChannelKeys(new GenericMessage(doc)).toArray(); assertEquals("Wrong number of channels returned", 1, channelNames.length); assertEquals("Wrong channel name", "one", channelNames[0]); } @@ -53,7 +53,7 @@ public class XPathRouterTests { XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); XPathRouter router = new XPathRouter(expression); router.setEvaluateAsString(true); - Object[] channelNames = router.getChannelIdentifiers(new GenericMessage(doc)).toArray(); + Object[] channelNames = router.getChannelKeys(new GenericMessage(doc)).toArray(); assertEquals("Wrong number of channels returned", 1, channelNames.length); assertEquals("Wrong channel name", "one", channelNames[0]); } @@ -65,7 +65,7 @@ public class XPathRouterTests { XPathExpression expression = XPathExpressionFactory.createXPathExpression("name(./node())"); XPathRouter router = new XPathRouter(expression); router.setEvaluateAsString(true); - Object[] channelNames = router.getChannelIdentifiers(new GenericMessage(doc)).toArray(); + Object[] channelNames = router.getChannelKeys(new GenericMessage(doc)).toArray(); assertEquals("Wrong number of channels returned", 1, channelNames.length); assertEquals("Wrong channel name", "doc", channelNames[0]); } @@ -76,7 +76,7 @@ public class XPathRouterTests { Document doc = XmlTestUtil.getDocumentForString("bOnebTwo"); XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/book"); XPathRouter router = new XPathRouter(expression); - Object[] channelNames = router.getChannelIdentifiers(new GenericMessage(doc)).toArray(); + Object[] channelNames = router.getChannelKeys(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]); @@ -96,7 +96,7 @@ public class XPathRouterTests { XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/book"); XPathRouter router = new XPathRouter(expression); router.setEvaluateAsString(true); - Object[] channelNames = router.getChannelIdentifiers(new GenericMessage("bOnebTwo")).toArray(); + Object[] channelNames = router.getChannelKeys(new GenericMessage("bOnebTwo")).toArray(); assertEquals("Wrong number of channels returned", 1, channelNames.length); assertEquals("Wrong channel name", "bOne", channelNames[0]); } @@ -105,14 +105,14 @@ public class XPathRouterTests { public void nonNodePayload() throws Exception { XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); XPathRouter router = new XPathRouter(expression); - router.getChannelIdentifiers(new GenericMessage("test")); + router.getChannelKeys(new GenericMessage("test")); } @Test public void nodePayload() throws Exception { XPathRouter router = new XPathRouter("./three/text()"); Document testDocument = XmlTestUtil.getDocumentForString("bobdave"); - Object[] channelNames = router.getChannelIdentifiers(new GenericMessage(testDocument.getElementsByTagName("two").item(0))).toArray(); + Object[] channelNames = router.getChannelKeys(new GenericMessage(testDocument.getElementsByTagName("two").item(0))).toArray(); assertEquals("bob",channelNames[0]); assertEquals("dave",channelNames[1]); } @@ -122,7 +122,7 @@ public class XPathRouterTests { Document doc = XmlTestUtil.getDocumentForString(""); XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); XPathRouter router = new XPathRouter(expression); - Object channelName = router.getChannelIdentifiers(new GenericMessage(doc)).toArray()[0]; + Object channelName = router.getChannelKeys(new GenericMessage(doc)).toArray()[0]; assertEquals("Wrong channel name", "one", channelName); } @@ -130,7 +130,7 @@ public class XPathRouterTests { public void testSimpleStringDoc() throws Exception { XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); XPathRouter router = new XPathRouter(expression); - Object channelName = router.getChannelIdentifiers(new GenericMessage("")).toArray()[0]; + Object channelName = router.getChannelKeys(new GenericMessage("")).toArray()[0]; assertEquals("Wrong channel name", "one", channelName); } @@ -138,14 +138,14 @@ public class XPathRouterTests { public void testNonNodePayload() throws Exception { XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); XPathRouter router = new XPathRouter(expression); - router.getChannelIdentifiers(new GenericMessage("test")); + router.getChannelKeys(new GenericMessage("test")); } @Test public void testNodePayload() throws Exception { XPathRouter router = new XPathRouter("./three/text()"); Document testDocument = XmlTestUtil.getDocumentForString("bob"); - Object[] channelNames = router.getChannelIdentifiers(new GenericMessage(testDocument + Object[] channelNames = router.getChannelKeys(new GenericMessage(testDocument .getElementsByTagName("two").item(0))).toArray(); assertEquals("bob", channelNames[0]); } @@ -155,7 +155,7 @@ public class XPathRouterTests { Document doc = XmlTestUtil.getDocumentForString(""); XPathExpression expression = XPathExpressionFactory.createXPathExpression("/somethingelse/@type"); XPathRouter router = new XPathRouter(expression); - List channelNames = router.getChannelIdentifiers(new GenericMessage(doc)); + List channelNames = router.getChannelKeys(new GenericMessage(doc)); assertEquals(0, channelNames.size()); }