From 2bb02b13aec27156adb008d6fef862f2572a9d46 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Thu, 17 Jun 2010 22:54:26 +0000 Subject: [PATCH] INT-789 --- ...alChannelInterceptorBeanPostProcessor.java | 199 +++++++----------- .../GlobalChannelInterceptorChain.java | 54 ----- .../GlobalChannelInterceptorWrapper.java | 85 ++++++++ .../xml/GlobalChannelInterceptorParser.java | 105 +++++---- .../xml/IntegrationNamespaceHandler.java | 2 +- .../config/xml/spring-integration-2.0.xsd | 25 ++- ...balChannelInterceptorTests-all-context.xml | 23 -- .../GlobalChannelInterceptorTests-context.xml | 47 +++-- ...ChannelInterceptorTests-failed-context.xml | 17 -- ...hannelInterceptorTests-ordered-context.xml | 40 ---- ...nnelInterceptorTests-unordered-context.xml | 34 --- .../GlobalChannelInterceptorTests.java | 171 ++++----------- 12 files changed, 313 insertions(+), 489 deletions(-) delete mode 100644 spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorChain.java create mode 100644 spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorWrapper.java delete mode 100644 spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-all-context.xml delete mode 100644 spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-failed-context.xml delete mode 100644 spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-ordered-context.xml delete mode 100644 spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-unordered-context.xml diff --git a/spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorBeanPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorBeanPostProcessor.java index 4de00ca897..593726caf8 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorBeanPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorBeanPostProcessor.java @@ -18,8 +18,10 @@ package org.springframework.integration.channel.interceptor; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -32,36 +34,10 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.core.OrderComparator; import org.springframework.integration.channel.AbstractMessageChannel; import org.springframework.integration.channel.ChannelInterceptor; -import org.springframework.util.CollectionUtils; /** - * Will apply global interceptors to channels (). Since global interceptors - * could be Ordered or un-Ordered they will be sorted before merged with other interceptors in the channel. - * Sorting will only be done within the given interceptor chain which itself defines 'order' attribute - * essentially creating a group of ordered interceptors which are ordered internally and then these chain - * groups are also ordered. For example: - *
- * channel-interceptor-chain channel-name-pattern="foo" order="5" - positive order value means AFTER local channel interceptors
- * 			Ordered-global interceptor (4)
- * 			Ordered-global interceptor (1)
- * channel-interceptor-chain
- * channel-interceptor-chain channel-name-pattern="foo" order="-1" - negative order value means AFTER local channel interceptors
- * 			Ordered-global interceptor (3)
- * 			Ordered-global interceptor (10)
- * channel-interceptor-chain
+ * Will apply global interceptors to channels (<channel-interceptor>). 
  * 
- * channel id="foo"
- * 		Ordered-in-channel interceptor (1)
- * channel
- * 
- * will result in channel with the following interceptors
- * Channel "foo"
- * 		Ordered-global interceptor (3)
- * 		Ordered-global interceptor (10)
- * 		Ordered-in-channel interceptor (1)
- * 		Ordered-global interceptor (1)
- * 		Ordered-global interceptor (4)
- * 
* * @author Oleg Zhurakousky * @since 2.0 @@ -69,18 +45,17 @@ import org.springframework.util.CollectionUtils; final class GlobalChannelInterceptorBeanPostProcessor implements BeanPostProcessor, InitializingBean{ private final static Log logger = LogFactory.getLog(GlobalChannelInterceptorBeanPostProcessor.class); private final OrderComparator comparator = new OrderComparator(); - private List allAvailablePatters; - private List globalInterceptors; + private List channelInterceptors; private final Map compiledPatterns = new HashMap(); - - private List positiveOrderChains = new ArrayList(); - private List negativeOrderChains = new ArrayList(); + + private final Set positiveOrderInterceptors = new LinkedHashSet(); + private final Set negativeOrderInterceptors = new LinkedHashSet(); /** - * + * * @param globalInterceptors */ - GlobalChannelInterceptorBeanPostProcessor(List globalInterceptors){ - this.globalInterceptors = globalInterceptors; + GlobalChannelInterceptorBeanPostProcessor(List channelInterceptors){ + this.channelInterceptors = channelInterceptors; } /* * (non-Javadoc) @@ -96,71 +71,16 @@ final class GlobalChannelInterceptorBeanPostProcessor implements BeanPostProcess */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (channelPatternMatches(beanName)){ - if (bean instanceof AbstractMessageChannel){ - logger.debug("Applying global interceptors on channel '" + beanName + "'"); - this.mergeInterceptorsToChannel((AbstractMessageChannel) bean, beanName); - } else { - logger.warn("Attempt to add channel interceptors is unsuccessfull. Global channel interceptors " + - "can only be added to AbstractMessageChannel. Current implementation is: " + bean.getClass() + - " This might happen becouse you specified a single wild-card '*' in 'channel-name-pattern'"); - } - } + + if (bean instanceof AbstractMessageChannel){ + + logger.debug("Applying global interceptors on channel '" + beanName + "'"); + this.addInterceptorsIfExist((AbstractMessageChannel) bean, beanName); + } + return bean; } - /** - * - * @param channel - * @param channelName - */ - private void mergeInterceptorsToChannel(AbstractMessageChannel channel, String channelName){ - List tInt = null; - List interceptors = this.getExistingInterceptors(channel); - // POSITIVE - List tempPositiveInterceptorChains = new ArrayList(); - for (GlobalChannelInterceptorChain positiveOrderChain : positiveOrderChains) { - if (channelPatternMatches(channelName, positiveOrderChain.getPatterns())){ - tempPositiveInterceptorChains.add(positiveOrderChain); - } - } - // sort chain - Collections.sort(tempPositiveInterceptorChains, comparator); - - for (GlobalChannelInterceptorChain globalChannelInterceptorChain : tempPositiveInterceptorChains) { - tInt = globalChannelInterceptorChain.getInterceptors(); - // sort within the chain - Collections.sort(tInt, comparator); - interceptors.addAll(tInt); - } - // NEGATIVE - List tempNegativeInterceptorChains = new ArrayList(); - for (GlobalChannelInterceptorChain negativeOrderChain : negativeOrderChains) { - if (channelPatternMatches(channelName, negativeOrderChain.getPatterns())){ - tempNegativeInterceptorChains.add(negativeOrderChain); - } - } - // sort chains - Collections.sort(tempNegativeInterceptorChains, comparator); - - for (GlobalChannelInterceptorChain globalChannelInterceptorChain : tempNegativeInterceptorChains) { - tInt = globalChannelInterceptorChain.getInterceptors(); - // sort within the chain - Collections.sort(tInt, comparator); - interceptors.addAll(0, tInt); - } - } - /* - * - */ - private void filterPositiveNegativeOrderChains(){ - for (GlobalChannelInterceptorChain globalInterceptorChain : globalInterceptors) { - if (globalInterceptorChain.getOrder() < 0){ - negativeOrderChains.add(globalInterceptorChain); - } else { - positiveOrderChains.add(globalInterceptorChain); - } - } - } + /* * */ @@ -175,38 +95,65 @@ final class GlobalChannelInterceptorBeanPostProcessor implements BeanPostProcess /* * */ - private boolean channelPatternMatches(String beanName, String... patternsToMatch){ - String[] patterns = null; - if (patternsToMatch.length > 0){ - patterns = patternsToMatch; - } else { - patterns = allAvailablePatters.toArray(new String[]{}); - } - for (String channelPattern : patterns) { - channelPattern = channelPattern.trim(); - if (channelPattern.trim().equals("*")){ - return true; - } - Pattern p = compiledPatterns.get(channelPattern); - if (p == null){ - p = Pattern.compile(channelPattern); - compiledPatterns.put(channelPattern, p); - } - Matcher m = p.matcher(beanName); - if (m.find()){ - return true; + private void addInterceptorsIfExist(AbstractMessageChannel channel, String beanName){ + List interceptors = this.getExistingInterceptors(channel); + List tempInterceptors = new ArrayList(); + for (GlobalChannelInterceptorWrapper globalChannelInterceptorWrapper : positiveOrderInterceptors) { + String[] patterns = globalChannelInterceptorWrapper.getPatterns(); + for (String channelPattern : patterns) { + channelPattern = channelPattern.trim(); + if (channelPattern.equals("*")){ + tempInterceptors.add(globalChannelInterceptorWrapper); + } else { + Pattern pattern = compiledPatterns.get(channelPattern); + + Matcher m = pattern.matcher(beanName); + if (m.find()){ + tempInterceptors.add(globalChannelInterceptorWrapper); + } + } } } - return false; + Collections.sort(tempInterceptors, comparator); + interceptors.addAll(tempInterceptors); + + tempInterceptors = new ArrayList(); + for (GlobalChannelInterceptorWrapper globalChannelInterceptorWrapper : negativeOrderInterceptors) { + String[] patterns = globalChannelInterceptorWrapper.getPatterns(); + for (String channelPattern : patterns) { + channelPattern = channelPattern.trim(); + Pattern pattern = compiledPatterns.get(channelPattern); + Matcher m = pattern.matcher(beanName); + if (m.find()){ + tempInterceptors.add(globalChannelInterceptorWrapper); + } + } + } + Collections.sort(tempInterceptors, comparator); + interceptors.addAll(0, tempInterceptors); } - - @SuppressWarnings("unchecked") + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ public void afterPropertiesSet() throws Exception { - allAvailablePatters = new ArrayList(); - for (GlobalChannelInterceptorChain globalInterceptorchain : globalInterceptors) { - allAvailablePatters.addAll(CollectionUtils.arrayToList(globalInterceptorchain.getPatterns())); + for (GlobalChannelInterceptorWrapper channelInterceptor : channelInterceptors) { + String[] patterns = channelInterceptor.getPatterns(); + for (String pattern : patterns) { + pattern = pattern.trim(); + if (!pattern.equals("*" )){ + Pattern p = compiledPatterns.get(pattern); + if (p == null){ + p = Pattern.compile(pattern); + compiledPatterns.put(pattern, p); + } + } + if (channelInterceptor.getOrder() >= 0){ + positiveOrderInterceptors.add(channelInterceptor); + } else { + negativeOrderInterceptors.add(channelInterceptor); + } + } } - this.filterPositiveNegativeOrderChains(); - logger.info("Initialized: '" + this.getClass().getSimpleName() + "' to apply global channel interceptors"); } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorChain.java b/spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorChain.java deleted file mode 100644 index 3b375b87a0..0000000000 --- a/spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorChain.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2002-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.integration.channel.interceptor; - -import java.util.List; - -import org.springframework.core.Ordered; -import org.springframework.integration.channel.ChannelInterceptor; - -/** - * @author Oleg Zhurakousky - * @since 2.0 - */ -final class GlobalChannelInterceptorChain implements Ordered{ - private List interceptors; - private String[] patterns; - - private int order; - - public GlobalChannelInterceptorChain(List interceptors, String[] patterns, int order){ - this.interceptors = interceptors; - this.patterns = patterns; - this.order = order; - } - - List getInterceptors(){ - return interceptors; - } - - String[] getPatterns() { - return patterns; - } - - public String toString(){ - return interceptors.toString(); - } - - public int getOrder() { - return order; - } -} diff --git a/spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorWrapper.java b/spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorWrapper.java new file mode 100644 index 0000000000..651257eb20 --- /dev/null +++ b/spring-integration-core/src/main/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorWrapper.java @@ -0,0 +1,85 @@ +/* + * Copyright 2002-2010 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.channel.interceptor; + +import org.springframework.core.Ordered; +import org.springframework.integration.channel.ChannelInterceptor; +import org.springframework.integration.core.Message; +import org.springframework.integration.core.MessageChannel; + +/** + * @author Oleg Zhurakousky + * @since 2.0 + */ +public class GlobalChannelInterceptorWrapper implements ChannelInterceptor, Ordered{ + private ChannelInterceptor channelInterceptor; + private String[] patterns; + private int order; + + public GlobalChannelInterceptorWrapper(ChannelInterceptor channelInterceptor){ + this.channelInterceptor = channelInterceptor; + // will set initial order for this interceptor wrapper to be the same as the + // underlying interceptor. Could be overridden with setOrder() method + if (channelInterceptor instanceof Ordered){ + order = ((Ordered)channelInterceptor).getOrder(); + } + } + + public int getOrder() { + return order; + } + + /** + * + * @param order + */ + public void setOrder(int order) { + this.order = order; + } + + public ChannelInterceptor getChannelInterceptor() { + return channelInterceptor; + } + + public String[] getPatterns() { + return patterns; + } + + public void setPatterns(String[] patterns) { + this.patterns = patterns; + } + + public Message postReceive(Message message, MessageChannel channel) { + return channelInterceptor.postReceive(message, channel); + } + + public void postSend(Message message, MessageChannel channel, + boolean sent) { + channelInterceptor.postSend(message, channel, sent); + } + + public boolean preReceive(MessageChannel channel) { + return channelInterceptor.preReceive(channel); + } + + public Message preSend(Message message, MessageChannel channel) { + return channelInterceptor.preSend(message, channel); + } + + public String toString(){ + return channelInterceptor.toString(); + } +} diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalChannelInterceptorParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalChannelInterceptorParser.java index 61b5a66918..bca19f6b22 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalChannelInterceptorParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalChannelInterceptorParser.java @@ -15,10 +15,7 @@ */ package org.springframework.integration.config.xml; -import java.util.List; - import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; @@ -26,10 +23,8 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; -import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.util.StringUtils; -import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; /** @@ -40,12 +35,10 @@ import org.w3c.dom.Element; */ public class GlobalChannelInterceptorParser extends AbstractBeanDefinitionParser { private static final String CONFIG_PACKAGE = IntegrationNamespaceUtils.BASE_PACKAGE + ".channel.interceptor."; - private final ManagedList globalInterceptorChains = new ManagedList(); - private final String GLOBAL_NAME_PATTERN_ATTR = "channel-name-pattern"; - private final String REF_ATTR = "ref"; - private final String BEAN_ATTR = "bean"; - private final String ORDER_ATTR = "order"; - private final String INTERCEPTOR_CHAIN_CLASS = "GlobalChannelInterceptorChain"; + private final ManagedList globalInterceptors = new ManagedList(); + private final static String CHANNELL_NAME_PATTERN_ATTR = "pattern"; + private final static String REF_ATTR = "ref"; + private final static String ORDER_ATTR = "order"; private final String GLOBAL_POST_PROCESSOR_CLASS = "GlobalChannelInterceptorBeanPostProcessor"; private boolean postProcessorCreated; @@ -56,35 +49,71 @@ public class GlobalChannelInterceptorParser extends AbstractBeanDefinitionParser protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { this.createAndRegisterGlobalPostProcessorIfNeeded(parserContext); - List interceptorElements = DomUtils.getChildElementsByTagName(element, new String[]{REF_ATTR, BEAN_ATTR}); + + + int order = this.getOrderAttribute(element); + String channelPattern = element.getAttribute(CHANNELL_NAME_PATTERN_ATTR); BeanDefinitionBuilder globalChannelInterceptorBuilder = - BeanDefinitionBuilder.genericBeanDefinition(CONFIG_PACKAGE + INTERCEPTOR_CHAIN_CLASS); - String[] channelPatterns = element.getAttribute(GLOBAL_NAME_PATTERN_ATTR).split(","); - int order = this.getOrderAttribute(element); - - ManagedList adviceChain = new ManagedList(); - for (Element interceptorElement : interceptorElements) { - if (interceptorElement.getNodeName().equals(BEAN_ATTR)){ - BeanDefinitionParserDelegate delegate = parserContext.getDelegate(); - BeanDefinitionHolder holder = delegate.parseBeanDefinitionElement(interceptorElement); - // needed for p: namespace - holder = delegate.decorateBeanDefinitionIfRequired(interceptorElement, holder); - parserContext.registerBeanComponent(new BeanComponentDefinition(holder)); - adviceChain.add(new RuntimeBeanReference(holder.getBeanName())); - } else if (interceptorElement.getNodeName().equals(REF_ATTR)) { - String ref = interceptorElement.getAttribute(BEAN_ATTR); - adviceChain.add(new RuntimeBeanReference(ref)); - } + BeanDefinitionBuilder.genericBeanDefinition(CONFIG_PACKAGE + "GlobalChannelInterceptorWrapper"); + BeanComponentDefinition interceptorBeanDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext); + if (interceptorBeanDefinition != null){ + globalChannelInterceptorBuilder.addConstructorArgValue(interceptorBeanDefinition); + } else { + String beanName = element.getAttribute(REF_ATTR); + globalChannelInterceptorBuilder.addConstructorArgValue(new RuntimeBeanReference(beanName)); } - globalChannelInterceptorBuilder.addConstructorArgValue(adviceChain); - globalChannelInterceptorBuilder.addConstructorArgValue(channelPatterns); - globalChannelInterceptorBuilder.addConstructorArgValue(order); - AbstractBeanDefinition interceptorChainDef = globalChannelInterceptorBuilder.getBeanDefinition(); - String interceptorChainName = - BeanDefinitionReaderUtils.generateBeanName(interceptorChainDef, parserContext.getRegistry()); - parserContext.registerBeanComponent(new BeanComponentDefinition(interceptorChainDef, interceptorChainName)); - globalInterceptorChains.add(new RuntimeBeanReference(interceptorChainName)); + + globalChannelInterceptorBuilder.addPropertyValue("order", order); + String[] patterns = null; + if (StringUtils.hasText(channelPattern)){ + patterns = StringUtils.commaDelimitedListToStringArray(channelPattern); + } else { + patterns = new String[]{"*"}; + } + globalChannelInterceptorBuilder.addPropertyValue("patterns", patterns); + + String beanName = + BeanDefinitionReaderUtils.generateBeanName(globalChannelInterceptorBuilder.getBeanDefinition(), parserContext.getRegistry()); + parserContext.registerBeanComponent(new BeanComponentDefinition(globalChannelInterceptorBuilder.getBeanDefinition(), beanName)); + globalInterceptors.add(new RuntimeBeanReference(beanName)); +// +// +// * +// +// +// +// +// +// List interceptorElements = DomUtils.getChildElementsByTagName(element, new String[]{REF_ATTR, BEAN_ATTR}); +// +// BeanDefinitionBuilder globalChannelInterceptorBuilder = +// BeanDefinitionBuilder.genericBeanDefinition(CONFIG_PACKAGE + INTERCEPTOR_CHAIN_CLASS); +// String[] channelPatterns = element.getAttribute(CHANNELL_NAME_PATTERN_ATTR).split(","); +// int order = this.getOrderAttribute(element); +// +// ManagedList adviceChain = new ManagedList(); +// for (Element interceptorElement : interceptorElements) { +// if (interceptorElement.getNodeName().equals(BEAN_ATTR)){ +// BeanDefinitionParserDelegate delegate = parserContext.getDelegate(); +// BeanDefinitionHolder holder = delegate.parseBeanDefinitionElement(interceptorElement); +// // needed for p: namespace +// holder = delegate.decorateBeanDefinitionIfRequired(interceptorElement, holder); +// parserContext.registerBeanComponent(new BeanComponentDefinition(holder)); +// adviceChain.add(new RuntimeBeanReference(holder.getBeanName())); +// } else if (interceptorElement.getNodeName().equals(REF_ATTR)) { +// String ref = interceptorElement.getAttribute(BEAN_ATTR); +// adviceChain.add(new RuntimeBeanReference(ref)); +// } +// } +// globalChannelInterceptorBuilder.addConstructorArgValue(adviceChain); +// globalChannelInterceptorBuilder.addConstructorArgValue(channelPatterns); +// globalChannelInterceptorBuilder.addConstructorArgValue(order); +// AbstractBeanDefinition interceptorChainDef = globalChannelInterceptorBuilder.getBeanDefinition(); +// String interceptorChainName = +// BeanDefinitionReaderUtils.generateBeanName(interceptorChainDef, parserContext.getRegistry()); +// parserContext.registerBeanComponent(new BeanComponentDefinition(interceptorChainDef, interceptorChainName)); +// globalInterceptorChains.add(new RuntimeBeanReference(interceptorChainName)); return null; } /* @@ -105,7 +134,7 @@ public class GlobalChannelInterceptorParser extends AbstractBeanDefinitionParser BeanDefinitionBuilder postProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition(CONFIG_PACKAGE + GLOBAL_POST_PROCESSOR_CLASS); BeanDefinition beanDef = postProcessorBuilder.getBeanDefinition(); - postProcessorBuilder.addConstructorArgValue(globalInterceptorChains); + postProcessorBuilder.addConstructorArgValue(globalInterceptors); String beanName = BeanDefinitionReaderUtils.generateBeanName(beanDef, parserContext.getRegistry()); parserContext.registerBeanComponent(new BeanComponentDefinition(beanDef, beanName)); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java index b472591759..4cf8e4ec2a 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java @@ -58,7 +58,7 @@ public class IntegrationNamespaceHandler extends AbstractIntegrationNamespaceHan registerBeanDefinitionParser("annotation-config", new AnnotationConfigParser()); registerBeanDefinitionParser("application-event-multicaster", new ApplicationEventMulticasterParser()); registerBeanDefinitionParser("publisher", new PublisherParser()); - registerBeanDefinitionParser("channel-interceptor-chain", new GlobalChannelInterceptorParser()); + registerBeanDefinitionParser("channel-interceptor", new GlobalChannelInterceptorParser()); } } diff --git a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd index 45f5edd5e1..603b7468d1 100644 --- a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd +++ b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd @@ -2172,7 +2172,7 @@ - + Allows you to define channel interceptors to be applied globally. @@ -2180,13 +2180,11 @@ - - + - + [REQUIRED] Channel name(s) or patterns. To specify more than one channel use @@ -2198,12 +2196,19 @@ - [OPTIONAL] Specifies the order in which these interceptors will be + [OPTIONAL] Specifies the order in which this interceptor will be added to the existing channel interceptors (if any). - Negative value (e.g., -2) will signify AFTER, but BEFORE the - the chain that might specify -1 (if any). Positive value (e.g., 2) - will signify BEFORE, but AFTER the chain that might specify 1 (if - any). + Negative value (e.g., -2) will signify BEFORE existing iinterceptors (if any). Positive value (e.g., 2) + will signify AFTER existing interceptors (if any) + + + + + + + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-all-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-all-context.xml deleted file mode 100644 index d9dbfd8a39..0000000000 --- a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-all-context.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-context.xml index 270fc85b0d..d8ad28913d 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-context.xml +++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-context.xml @@ -15,7 +15,7 @@ - + @@ -28,27 +28,36 @@ - - - - - + - - - - - - + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-failed-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-failed-context.xml deleted file mode 100644 index 3915e8682f..0000000000 --- a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-failed-context.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-ordered-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-ordered-context.xml deleted file mode 100644 index 9d7e396850..0000000000 --- a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-ordered-context.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-unordered-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-unordered-context.xml deleted file mode 100644 index bf92454584..0000000000 --- a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests-unordered-context.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests.java index 0185b176e6..e87a28aee3 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests.java @@ -33,8 +33,9 @@ import org.springframework.integration.core.MessageChannel; * @author Oleg Zhurakousky * @since 2.0 */ +@SuppressWarnings("all") public class GlobalChannelInterceptorTests { - @SuppressWarnings("unchecked") + @Test public void validateGlobalInterceptor(){ ApplicationContext applicationContext = @@ -46,149 +47,61 @@ public class GlobalChannelInterceptorTests { Object iList = cAccessor.getPropertyValue("interceptors"); DirectFieldAccessor iAccessor = new DirectFieldAccessor(iList); List interceptoList = (List) iAccessor.getPropertyValue("interceptors"); - if (channelName.equals("inputA")){ - SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{}); - Assert.assertTrue(inter.length == 13); - Assert.assertEquals("four", inter[0].getTestIdentifier()); - Assert.assertEquals("seven", inter[1].getTestIdentifier()); - Assert.assertEquals("five", inter[2].getTestIdentifier()); - Assert.assertEquals("seven", inter[3].getTestIdentifier()); - Assert.assertEquals("eight", inter[4].getTestIdentifier()); - Assert.assertEquals("seven", inter[5].getTestIdentifier()); - Assert.assertEquals("one", inter[6].getTestIdentifier()); - Assert.assertEquals("seven", inter[7].getTestIdentifier()); - Assert.assertEquals("two", inter[8].getTestIdentifier()); - Assert.assertEquals("three", inter[9].getTestIdentifier()); - Assert.assertEquals("seven", inter[10].getTestIdentifier()); - Assert.assertEquals("six", inter[11].getTestIdentifier()); - Assert.assertEquals("seven", inter[12].getTestIdentifier()); + if (channelName.equals("inputA")){ // 328741 + ChannelInterceptor[] inter = interceptoList.toArray(new ChannelInterceptor[]{}); + Assert.assertTrue(inter.length ==10); + Assert.assertEquals("interceptor-three", inter[0].toString()); + Assert.assertEquals("interceptor-two", inter[1].toString()); + Assert.assertEquals("interceptor-eight", inter[2].toString()); + Assert.assertEquals("interceptor-seven", inter[3].toString()); + Assert.assertEquals("interceptor-five", inter[4].toString()); + Assert.assertEquals("interceptor-six", inter[5].toString()); + Assert.assertEquals("interceptor-ten", inter[6].toString()); + Assert.assertEquals("interceptor-eleven", inter[7].toString()); + Assert.assertEquals("interceptor-four", inter[8].toString()); + Assert.assertEquals("interceptor-one", inter[9].toString()); } else if (channelName.equals("inputB")){ - SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{}); - Assert.assertTrue(inter.length == 11); - Assert.assertEquals("four", inter[0].getTestIdentifier()); - Assert.assertEquals("seven", inter[1].getTestIdentifier()); - Assert.assertEquals("five", inter[2].getTestIdentifier()); - Assert.assertEquals("seven", inter[3].getTestIdentifier()); - Assert.assertEquals("one", inter[4].getTestIdentifier()); - Assert.assertEquals("seven", inter[5].getTestIdentifier()); - Assert.assertEquals("two", inter[6].getTestIdentifier()); - Assert.assertEquals("three", inter[7].getTestIdentifier()); - Assert.assertEquals("seven", inter[8].getTestIdentifier()); - Assert.assertEquals("six", inter[9].getTestIdentifier()); - Assert.assertEquals("seven", inter[10].getTestIdentifier()); + ChannelInterceptor[] inter = interceptoList.toArray(new ChannelInterceptor[]{}); + Assert.assertTrue(inter.length == 6); + Assert.assertEquals("interceptor-three", inter[0].toString()); + Assert.assertEquals("interceptor-two", inter[1].toString()); + Assert.assertEquals("interceptor-ten", inter[2].toString()); + Assert.assertEquals("interceptor-eleven", inter[3].toString()); + Assert.assertEquals("interceptor-four", inter[4].toString()); + Assert.assertEquals("interceptor-one", inter[5].toString()); } else if (channelName.equals("foo")){ - SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{}); + ChannelInterceptor[] inter = interceptoList.toArray(new ChannelInterceptor[]{}); Assert.assertTrue(inter.length == 6); - Assert.assertEquals("four", inter[0].getTestIdentifier()); - Assert.assertEquals("seven", inter[1].getTestIdentifier()); - Assert.assertEquals("five", inter[2].getTestIdentifier()); - Assert.assertEquals("seven", inter[3].getTestIdentifier()); - Assert.assertEquals("six", inter[4].getTestIdentifier()); - Assert.assertEquals("seven", inter[5].getTestIdentifier()); + Assert.assertEquals("interceptor-two", inter[0].toString()); + Assert.assertEquals("interceptor-five", inter[1].toString()); + Assert.assertEquals("interceptor-ten", inter[2].toString()); + Assert.assertEquals("interceptor-eleven", inter[3].toString()); + Assert.assertEquals("interceptor-four", inter[4].toString()); + Assert.assertEquals("interceptor-one", inter[5].toString()); } else if (channelName.equals("bar")){ - SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{}); - Assert.assertTrue(inter.length == 2); - Assert.assertEquals("eight", inter[0].getTestIdentifier()); - Assert.assertEquals("seven", inter[1].getTestIdentifier()); + ChannelInterceptor[] inter = interceptoList.toArray(new ChannelInterceptor[]{}); + Assert.assertTrue(inter.length == 4); + Assert.assertEquals("interceptor-eight", inter[0].toString()); + Assert.assertEquals("interceptor-seven", inter[1].toString()); + Assert.assertEquals("interceptor-ten", inter[2].toString()); + Assert.assertEquals("interceptor-eleven", inter[3].toString()); } else if (channelName.equals("baz")){ - SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{}); - Assert.assertTrue(inter.length == 0); - } - } - } - /** - * Will test mix of Ordered and un-Ordered ChannelInterceptors - * Individual interceptors will only be sorted within groups they are defined. - * For example: interceptors defined inside of channels will be sorted according to Ordered implementation - * If global interceptors were added BEFORE (negative order) or AFTER (ppositive order) the global stack will be sorted - * and added before/after the existing stack - */ - @SuppressWarnings("unchecked") - @Test - public void validateGlobalInterceptorsOrdered(){ - ApplicationContext applicationContext = - new ClassPathXmlApplicationContext("GlobalChannelInterceptorTests-ordered-context.xml", GlobalChannelInterceptorTests.class); - Map channels = applicationContext.getBeansOfType(AbstractMessageChannel.class); - for (String channelName : channels.keySet()) { - AbstractMessageChannel channel = channels.get(channelName); - DirectFieldAccessor cAccessor = new DirectFieldAccessor(channel); - Object iList = cAccessor.getPropertyValue("interceptors"); - DirectFieldAccessor iAccessor = new DirectFieldAccessor(iList); - List interceptoList = (List) iAccessor.getPropertyValue("interceptors"); - if (channelName.equals("inputA")){ - SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{}); - Assert.assertTrue(inter.length == 10); - Assert.assertEquals("ten", inter[0].getTestIdentifier()); - Assert.assertEquals("four", inter[1].getTestIdentifier()); - Assert.assertEquals("ten", inter[2].getTestIdentifier()); - Assert.assertEquals("eight", inter[3].getTestIdentifier()); - Assert.assertEquals("seven", inter[4].getTestIdentifier()); - Assert.assertEquals("five", inter[5].getTestIdentifier()); - Assert.assertEquals("ten", inter[6].getTestIdentifier()); - Assert.assertEquals("one", inter[7].getTestIdentifier()); - Assert.assertEquals("six", inter[8].getTestIdentifier()); - Assert.assertEquals("seven", inter[9].getTestIdentifier()); - } - - } - } - @SuppressWarnings("unchecked") - @Test - public void validateGlobalInterceptorsUnOrdered(){ - ApplicationContext applicationContext = - new ClassPathXmlApplicationContext("GlobalChannelInterceptorTests-unordered-context.xml", GlobalChannelInterceptorTests.class); - Map channels = applicationContext.getBeansOfType(AbstractMessageChannel.class); - for (String channelName : channels.keySet()) { - AbstractMessageChannel channel = channels.get(channelName); - DirectFieldAccessor cAccessor = new DirectFieldAccessor(channel); - Object iList = cAccessor.getPropertyValue("interceptors"); - DirectFieldAccessor iAccessor = new DirectFieldAccessor(iList); - List interceptoList = (List) iAccessor.getPropertyValue("interceptors"); - if (channelName.equals("inputA")){ - SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{}); - Assert.assertTrue(inter.length == 7); - Assert.assertEquals("eight", inter[0].getTestIdentifier()); - Assert.assertEquals("seven", inter[1].getTestIdentifier()); - Assert.assertEquals("five", inter[2].getTestIdentifier()); - Assert.assertEquals("six", inter[3].getTestIdentifier()); - Assert.assertEquals("seven", inter[4].getTestIdentifier()); - Assert.assertEquals("seven", inter[5].getTestIdentifier()); - Assert.assertEquals("one", inter[6].getTestIdentifier()); - } - } - } - @SuppressWarnings("unchecked") - @Test - public void validateGlobalInterceptorsAllPattern(){ - ApplicationContext applicationContext = - new ClassPathXmlApplicationContext("GlobalChannelInterceptorTests-all-context.xml", GlobalChannelInterceptorTests.class); - Map channels = applicationContext.getBeansOfType(AbstractMessageChannel.class); - for (String channelName : channels.keySet()) { - AbstractMessageChannel channel = channels.get(channelName); - DirectFieldAccessor cAccessor = new DirectFieldAccessor(channel); - Object iList = cAccessor.getPropertyValue("interceptors"); - DirectFieldAccessor iAccessor = new DirectFieldAccessor(iList); - List interceptoList = (List) iAccessor.getPropertyValue("interceptors"); - if (channelName.equals("inputA")){ - SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{}); + ChannelInterceptor[] inter = interceptoList.toArray(new ChannelInterceptor[]{}); Assert.assertTrue(inter.length == 2); - } else if (channelName.equals("inputB")){ - SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{}); - Assert.assertTrue(inter.length == 1); - } else if (channelName.equals("inputC")){ - SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{}); - Assert.assertTrue(inter.length == 1); + Assert.assertEquals("interceptor-ten", inter[0].toString()); + Assert.assertEquals("interceptor-eleven", inter[1].toString()); } } } + public static class SampleInterceptor implements ChannelInterceptor { private String testIdentifier; @@ -210,6 +123,10 @@ public class GlobalChannelInterceptorTests { public Message preSend(Message message, MessageChannel channel) { return null; } + public String toString(){ + return "interceptor-" + testIdentifier; + } + } public static class SampleOrderedInterceptor extends SampleInterceptor implements Ordered { private int order;