INT-3936: GlobalChIntercep: add negative pattern
JIRA: https://jira.spring.io/browse/INT-3936 * Extract `smartMatch()` logic from the `IntegrationManagementConfigurer` and `IntegrationMBeanExporter` into the `PatternMatchUtils` class * Add negative (`!`) pattern matching configuration support to the `GlobalChannelInterceptor` annotation and `<int:channel-interceptor>` component * Code style, Docs and JavaDocs polishing
This commit is contained in:
committed by
Artem Bilan
parent
671097fd50
commit
40783ff547
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2017 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.
|
||||
@@ -27,12 +27,15 @@ import java.lang.annotation.Target;
|
||||
* annotation will be applied as global channel interceptors
|
||||
* using the provided {@code patterns} to match channel names.
|
||||
* <p>
|
||||
* This annotation can be used at the {@code class} level for {@link org.springframework.stereotype.Component} beans
|
||||
* This annotation can be used at the {@code class} level
|
||||
* for {@link org.springframework.stereotype.Component} beans
|
||||
* and on methods with {@link org.springframework.context.annotation.Bean}.
|
||||
* <p>
|
||||
* This annotation is an analogue of {@code <int:channel-interceptor/>}.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @author Meherzad Lahewala
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@@ -41,9 +44,12 @@ import java.lang.annotation.Target;
|
||||
public @interface GlobalChannelInterceptor {
|
||||
|
||||
/**
|
||||
* An array of simple patterns against which channel names will be matched. Default is "*"
|
||||
* (all channels). See {@link org.springframework.util.PatternMatchUtils#simpleMatch(String, String)}.
|
||||
* An array of patterns against which channel names will be matched.
|
||||
* Since version 5.0 negative patterns are also supported.
|
||||
* A leading '!' negates the pattern match.
|
||||
* Default is "*" (all channels).
|
||||
* @return The pattern.
|
||||
* @see org.springframework.integration.util.PatternMatchUtils#smartMatch(String, String...)
|
||||
*/
|
||||
String[] patterns() default "*";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -37,10 +37,10 @@ import org.springframework.core.OrderComparator;
|
||||
import org.springframework.integration.channel.ChannelInterceptorAware;
|
||||
import org.springframework.integration.channel.interceptor.GlobalChannelInterceptorWrapper;
|
||||
import org.springframework.integration.channel.interceptor.VetoCapableInterceptor;
|
||||
import org.springframework.integration.util.PatternMatchUtils;
|
||||
import org.springframework.messaging.support.ChannelInterceptor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -50,6 +50,8 @@ import org.springframework.util.StringUtils;
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
* @author Meherzad Lahewala
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
final class GlobalChannelInterceptorProcessor implements BeanFactoryAware, SmartInitializingSingleton {
|
||||
@@ -59,11 +61,9 @@ final class GlobalChannelInterceptorProcessor implements BeanFactoryAware, Smart
|
||||
|
||||
private final OrderComparator comparator = new OrderComparator();
|
||||
|
||||
private final Set<GlobalChannelInterceptorWrapper> positiveOrderInterceptors =
|
||||
new LinkedHashSet<GlobalChannelInterceptorWrapper>();
|
||||
private final Set<GlobalChannelInterceptorWrapper> positiveOrderInterceptors = new LinkedHashSet<>();
|
||||
|
||||
private final Set<GlobalChannelInterceptorWrapper> negativeOrderInterceptors =
|
||||
new LinkedHashSet<GlobalChannelInterceptorWrapper>();
|
||||
private final Set<GlobalChannelInterceptorWrapper> negativeOrderInterceptors = new LinkedHashSet<>();
|
||||
|
||||
private ListableBeanFactory beanFactory;
|
||||
|
||||
@@ -89,6 +89,7 @@ final class GlobalChannelInterceptorProcessor implements BeanFactoryAware, Smart
|
||||
this.negativeOrderInterceptors.add(channelInterceptor);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, ChannelInterceptorAware> channels =
|
||||
this.beanFactory.getBeansOfType(ChannelInterceptorAware.class);
|
||||
for (Entry<String, ChannelInterceptorAware> entry : channels.entrySet()) {
|
||||
@@ -104,15 +105,18 @@ final class GlobalChannelInterceptorProcessor implements BeanFactoryAware, Smart
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Applying global interceptors on channel '" + beanName + "'");
|
||||
}
|
||||
List<GlobalChannelInterceptorWrapper> tempInterceptors = new ArrayList<GlobalChannelInterceptorWrapper>();
|
||||
|
||||
List<GlobalChannelInterceptorWrapper> tempInterceptors = new ArrayList<>();
|
||||
for (GlobalChannelInterceptorWrapper globalChannelInterceptorWrapper : this.positiveOrderInterceptors) {
|
||||
String[] patterns = globalChannelInterceptorWrapper.getPatterns();
|
||||
patterns = StringUtils.trimArrayElements(patterns);
|
||||
if (PatternMatchUtils.simpleMatch(patterns, beanName)) {
|
||||
if (beanName != null && Boolean.TRUE.equals(PatternMatchUtils.smartMatch(beanName, patterns))) {
|
||||
tempInterceptors.add(globalChannelInterceptorWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(tempInterceptors, this.comparator);
|
||||
|
||||
for (GlobalChannelInterceptorWrapper next : tempInterceptors) {
|
||||
ChannelInterceptor channelInterceptor = next.getChannelInterceptor();
|
||||
if (!(channelInterceptor instanceof VetoCapableInterceptor)
|
||||
@@ -122,14 +126,17 @@ final class GlobalChannelInterceptorProcessor implements BeanFactoryAware, Smart
|
||||
}
|
||||
|
||||
tempInterceptors.clear();
|
||||
|
||||
for (GlobalChannelInterceptorWrapper globalChannelInterceptorWrapper : this.negativeOrderInterceptors) {
|
||||
String[] patterns = globalChannelInterceptorWrapper.getPatterns();
|
||||
patterns = StringUtils.trimArrayElements(patterns);
|
||||
if (PatternMatchUtils.simpleMatch(patterns, beanName)) {
|
||||
if (beanName != null && Boolean.TRUE.equals(PatternMatchUtils.smartMatch(beanName, patterns))) {
|
||||
tempInterceptors.add(globalChannelInterceptorWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(tempInterceptors, this.comparator);
|
||||
|
||||
if (!tempInterceptors.isEmpty()) {
|
||||
for (int i = tempInterceptors.size() - 1; i >= 0; i--) {
|
||||
ChannelInterceptor channelInterceptor = tempInterceptors.get(i).getChannelInterceptor();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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,8 +30,8 @@ import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.integration.support.management.IntegrationManagement.ManagementOverrides;
|
||||
import org.springframework.integration.util.PatternMatchUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
* @author Meherzad Lahewala
|
||||
*
|
||||
* @since 4.2
|
||||
*
|
||||
*/
|
||||
@@ -71,9 +73,9 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
|
||||
private String metricsFactoryBeanName;
|
||||
|
||||
private String[] enabledCountsPatterns = { };
|
||||
private String[] enabledCountsPatterns = { };
|
||||
|
||||
private String[] enabledStatsPatterns = { };
|
||||
private String[] enabledStatsPatterns = { };
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
@@ -227,7 +229,7 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
AbstractMessageChannelMetrics metrics = this.metricsFactory.createChannelMetrics(name);
|
||||
Assert.state(metrics != null, "'metrics' must not be null");
|
||||
ManagementOverrides overrides = bean.getOverrides();
|
||||
Boolean enabled = smartMatch(this.enabledCountsPatterns, name);
|
||||
Boolean enabled = PatternMatchUtils.smartMatch(name, this.enabledCountsPatterns);
|
||||
if (enabled != null) {
|
||||
bean.setCountsEnabled(enabled);
|
||||
}
|
||||
@@ -236,7 +238,7 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
bean.setCountsEnabled(this.defaultCountsEnabled);
|
||||
}
|
||||
}
|
||||
enabled = smartMatch(this.enabledStatsPatterns, name);
|
||||
enabled = PatternMatchUtils.smartMatch(name, this.enabledStatsPatterns);
|
||||
if (enabled != null) {
|
||||
bean.setStatsEnabled(enabled);
|
||||
metrics.setFullStatsEnabled(enabled);
|
||||
@@ -258,7 +260,7 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
AbstractMessageHandlerMetrics metrics = this.metricsFactory.createHandlerMetrics(name);
|
||||
Assert.state(metrics != null, "'metrics' must not be null");
|
||||
ManagementOverrides overrides = bean.getOverrides();
|
||||
Boolean enabled = smartMatch(this.enabledCountsPatterns, name);
|
||||
Boolean enabled = PatternMatchUtils.smartMatch(name, this.enabledCountsPatterns);
|
||||
if (enabled != null) {
|
||||
bean.setCountsEnabled(enabled);
|
||||
}
|
||||
@@ -267,7 +269,7 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
bean.setCountsEnabled(this.defaultCountsEnabled);
|
||||
}
|
||||
}
|
||||
enabled = smartMatch(this.enabledStatsPatterns, name);
|
||||
enabled = PatternMatchUtils.smartMatch(name, this.enabledStatsPatterns);
|
||||
if (enabled != null) {
|
||||
bean.setStatsEnabled(enabled);
|
||||
metrics.setFullStatsEnabled(enabled);
|
||||
@@ -286,7 +288,7 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
}
|
||||
|
||||
private void configureSourceMetrics(String name, MessageSourceMetrics bean) {
|
||||
Boolean enabled = smartMatch(this.enabledCountsPatterns, name);
|
||||
Boolean enabled = PatternMatchUtils.smartMatch(name, this.enabledCountsPatterns);
|
||||
if (enabled != null) {
|
||||
bean.setCountsEnabled(enabled);
|
||||
}
|
||||
@@ -298,33 +300,6 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
this.sourcesByName.put(bean.getManagedName() != null ? bean.getManagedName() : name, bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple pattern match against the supplied patterns; also supports negated ('!')
|
||||
* patterns. First match wins (positive or negative).
|
||||
* @param patterns the patterns.
|
||||
* @param name the name to match.
|
||||
* @return null if no match; true for positive match; false for negative match.
|
||||
*/
|
||||
private Boolean smartMatch(String[] patterns, String name) {
|
||||
if (patterns != null) {
|
||||
for (String pattern : patterns) {
|
||||
boolean reverse = false;
|
||||
String patternToUse = pattern;
|
||||
if (pattern.startsWith("!")) {
|
||||
reverse = true;
|
||||
patternToUse = pattern.substring(1);
|
||||
}
|
||||
else if (pattern.startsWith("\\")) {
|
||||
patternToUse = pattern.substring(1);
|
||||
}
|
||||
if (PatternMatchUtils.simpleMatch(patternToUse, name)) {
|
||||
return !reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; //NOSONAR - intentional null return
|
||||
}
|
||||
|
||||
public String[] getChannelNames() {
|
||||
return this.channelsByName.keySet().toArray(new String[this.channelsByName.size()]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2017 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.util;
|
||||
|
||||
/**
|
||||
* Utility methods for pattern matching.
|
||||
* This utilities provide support of negative pattern matching as well
|
||||
* unlike {@link org.springframework.util.PatternMatchUtils}.
|
||||
*
|
||||
* @author Meherzad Lahewala
|
||||
*
|
||||
* @since 5.0
|
||||
*
|
||||
* @see org.springframework.util.PatternMatchUtils
|
||||
*/
|
||||
public final class PatternMatchUtils {
|
||||
|
||||
private PatternMatchUtils() { }
|
||||
|
||||
/**
|
||||
* Pattern match against the supplied patterns; also supports negated ('!')
|
||||
* patterns. First match wins (positive or negative).
|
||||
* To match the names starting with {@code !} symbol,
|
||||
* you have to escape it prepending with the {@code \} symbol in the pattern definition.
|
||||
* @param str the string to match.
|
||||
* @param patterns the patterns.
|
||||
* @return true for positive match; false for negative; null if no pattern matches.
|
||||
* @see org.springframework.util.PatternMatchUtils#simpleMatch(String[], String)
|
||||
*/
|
||||
public static Boolean smartMatch(String str, String... patterns) {
|
||||
if (patterns != null) {
|
||||
for (String pattern : patterns) {
|
||||
boolean reverse = false;
|
||||
String patternToUse = pattern;
|
||||
if (pattern.startsWith("!")) {
|
||||
reverse = true;
|
||||
patternToUse = pattern.substring(1);
|
||||
}
|
||||
else if (pattern.startsWith("\\")) {
|
||||
patternToUse = pattern.substring(1);
|
||||
}
|
||||
if (org.springframework.util.PatternMatchUtils.simpleMatch(patternToUse, str)) {
|
||||
return !reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; //NOSONAR - intentional null return
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4349,10 +4349,10 @@
|
||||
<xsd:attribute name="pattern" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
[REQUIRED] Channel name(s) or patterns. To specify more than one channel use
|
||||
','
|
||||
(e.g.,
|
||||
channel-name-pattern="input*, foo, bar")
|
||||
[REQUIRED] Channel name(s) or patterns. To specify more than one channel use ','.
|
||||
A leading '!' negates the pattern match ('!foo*' means don't add
|
||||
interceptor where the name matches the pattern 'foo*').
|
||||
For example "input*, foo, bar, !Foo*".
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
|
||||
<int:channel id="baz"/>
|
||||
|
||||
<int:channel id="test"/>
|
||||
|
||||
<int:channel-interceptor pattern="!tes*" order="8">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="twelve"/>
|
||||
</int:channel-interceptor>
|
||||
<int:channel-interceptor pattern="input*, foo" order="3">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="one"/>
|
||||
</int:channel-interceptor>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -16,13 +16,16 @@
|
||||
|
||||
package org.springframework.integration.channel.interceptor;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -42,6 +45,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
* @author Oleg Zhurakousky
|
||||
* @author David Turanski
|
||||
* @author Artem Bilan
|
||||
* @author Meherzad Lahewala
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@@ -65,52 +70,63 @@ public class GlobalChannelInterceptorTests {
|
||||
continue;
|
||||
}
|
||||
|
||||
ChannelInterceptor[] interceptors = channel.getChannelInterceptors().toArray(new ChannelInterceptor[channel.getChannelInterceptors().size()]);
|
||||
ChannelInterceptor[] interceptors = channel.getChannelInterceptors()
|
||||
.toArray(new ChannelInterceptor[channel.getChannelInterceptors().size()]);
|
||||
if (channelName.equals("inputA")) { // 328741
|
||||
Assert.assertTrue(interceptors.length == 10);
|
||||
Assert.assertEquals("interceptor-three", interceptors[0].toString());
|
||||
Assert.assertEquals("interceptor-two", interceptors[1].toString());
|
||||
Assert.assertEquals("interceptor-eight", interceptors[2].toString());
|
||||
Assert.assertEquals("interceptor-seven", interceptors[3].toString());
|
||||
Assert.assertEquals("interceptor-five", interceptors[4].toString());
|
||||
Assert.assertEquals("interceptor-six", interceptors[5].toString());
|
||||
Assert.assertEquals("interceptor-ten", interceptors[6].toString());
|
||||
Assert.assertEquals("interceptor-eleven", interceptors[7].toString());
|
||||
Assert.assertEquals("interceptor-four", interceptors[8].toString());
|
||||
Assert.assertEquals("interceptor-one", interceptors[9].toString());
|
||||
assertTrue(interceptors.length == 10);
|
||||
assertEquals("interceptor-three", interceptors[0].toString());
|
||||
assertEquals("interceptor-two", interceptors[1].toString());
|
||||
assertEquals("interceptor-eight", interceptors[2].toString());
|
||||
assertEquals("interceptor-seven", interceptors[3].toString());
|
||||
assertEquals("interceptor-five", interceptors[4].toString());
|
||||
assertEquals("interceptor-six", interceptors[5].toString());
|
||||
assertEquals("interceptor-ten", interceptors[6].toString());
|
||||
assertEquals("interceptor-eleven", interceptors[7].toString());
|
||||
assertEquals("interceptor-four", interceptors[8].toString());
|
||||
assertEquals("interceptor-one", interceptors[9].toString());
|
||||
}
|
||||
else if (channelName.equals("inputB")) {
|
||||
Assert.assertTrue(interceptors.length == 6);
|
||||
Assert.assertEquals("interceptor-three", interceptors[0].toString());
|
||||
Assert.assertEquals("interceptor-two", interceptors[1].toString());
|
||||
Assert.assertEquals("interceptor-ten", interceptors[2].toString());
|
||||
Assert.assertEquals("interceptor-eleven", interceptors[3].toString());
|
||||
Assert.assertEquals("interceptor-four", interceptors[4].toString());
|
||||
Assert.assertEquals("interceptor-one", interceptors[5].toString());
|
||||
assertTrue(interceptors.length == 6);
|
||||
assertEquals("interceptor-three", interceptors[0].toString());
|
||||
assertEquals("interceptor-two", interceptors[1].toString());
|
||||
assertEquals("interceptor-ten", interceptors[2].toString());
|
||||
assertEquals("interceptor-eleven", interceptors[3].toString());
|
||||
assertEquals("interceptor-four", interceptors[4].toString());
|
||||
assertEquals("interceptor-one", interceptors[5].toString());
|
||||
}
|
||||
else if (channelName.equals("foo")) {
|
||||
Assert.assertTrue(interceptors.length == 6);
|
||||
Assert.assertEquals("interceptor-two", interceptors[0].toString());
|
||||
Assert.assertEquals("interceptor-five", interceptors[1].toString());
|
||||
Assert.assertEquals("interceptor-ten", interceptors[2].toString());
|
||||
Assert.assertEquals("interceptor-eleven", interceptors[3].toString());
|
||||
Assert.assertEquals("interceptor-four", interceptors[4].toString());
|
||||
Assert.assertEquals("interceptor-one", interceptors[5].toString());
|
||||
assertTrue(interceptors.length == 6);
|
||||
assertEquals("interceptor-two", interceptors[0].toString());
|
||||
assertEquals("interceptor-five", interceptors[1].toString());
|
||||
assertEquals("interceptor-ten", interceptors[2].toString());
|
||||
assertEquals("interceptor-eleven", interceptors[3].toString());
|
||||
assertEquals("interceptor-four", interceptors[4].toString());
|
||||
assertEquals("interceptor-one", interceptors[5].toString());
|
||||
}
|
||||
else if (channelName.equals("bar")) {
|
||||
Assert.assertTrue(interceptors.length == 4);
|
||||
Assert.assertEquals("interceptor-eight", interceptors[0].toString());
|
||||
Assert.assertEquals("interceptor-seven", interceptors[1].toString());
|
||||
Assert.assertEquals("interceptor-ten", interceptors[2].toString());
|
||||
Assert.assertEquals("interceptor-eleven", interceptors[3].toString());
|
||||
assertTrue(interceptors.length == 4);
|
||||
assertEquals("interceptor-eight", interceptors[0].toString());
|
||||
assertEquals("interceptor-seven", interceptors[1].toString());
|
||||
assertEquals("interceptor-ten", interceptors[2].toString());
|
||||
assertEquals("interceptor-eleven", interceptors[3].toString());
|
||||
}
|
||||
else if (channelName.equals("baz")) {
|
||||
Assert.assertTrue(interceptors.length == 2);
|
||||
Assert.assertEquals("interceptor-ten", interceptors[0].toString());
|
||||
Assert.assertEquals("interceptor-eleven", interceptors[1].toString());
|
||||
assertTrue(interceptors.length == 2);
|
||||
assertEquals("interceptor-ten", interceptors[0].toString());
|
||||
assertEquals("interceptor-eleven", interceptors[1].toString());
|
||||
}
|
||||
else if (channelName.equals("inputWithProxy")) {
|
||||
Assert.assertTrue(interceptors.length == 6);
|
||||
assertTrue(interceptors.length == 6);
|
||||
}
|
||||
else if (channelName.equals("test")) {
|
||||
assertNotNull(interceptors);
|
||||
assertTrue(interceptors.length == 2);
|
||||
List<String> interceptorNames = new ArrayList<String>();
|
||||
for (ChannelInterceptor interceptor : interceptors) {
|
||||
interceptorNames.add(interceptor.toString());
|
||||
}
|
||||
assertTrue(interceptorNames.contains("interceptor-ten"));
|
||||
assertTrue(interceptorNames.contains("interceptor-eleven"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,8 +139,8 @@ public class GlobalChannelInterceptorTests {
|
||||
for (ChannelInterceptor interceptor : channelInterceptors) {
|
||||
interceptorNames.add(interceptor.toString());
|
||||
}
|
||||
Assert.assertTrue(interceptorNames.contains("interceptor-ten"));
|
||||
Assert.assertTrue(interceptorNames.contains("interceptor-eleven"));
|
||||
assertTrue(interceptorNames.contains("interceptor-ten"));
|
||||
assertTrue(interceptorNames.contains("interceptor-eleven"));
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +175,7 @@ public class GlobalChannelInterceptorTests {
|
||||
public String toString() {
|
||||
return "interceptor-" + testIdentifier;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -174,6 +191,7 @@ public class GlobalChannelInterceptorTests {
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TestInterceptor implements MethodInterceptor {
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2017 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.config;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.integration.channel.ChannelInterceptorAware;
|
||||
import org.springframework.integration.channel.interceptor.GlobalChannelInterceptorWrapper;
|
||||
import org.springframework.messaging.support.ChannelInterceptor;
|
||||
|
||||
/**
|
||||
* @author Meherzad Lahewala
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public class GlobalChannelInterceptorProcessorTests {
|
||||
|
||||
private GlobalChannelInterceptorProcessor globalChannelInterceptorProcessor;
|
||||
|
||||
private ListableBeanFactory beanFactory;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.globalChannelInterceptorProcessor = new GlobalChannelInterceptorProcessor();
|
||||
this.beanFactory = mock(ListableBeanFactory.class);
|
||||
this.globalChannelInterceptorProcessor.setBeanFactory(this.beanFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessorWithNoInterceptor() {
|
||||
when(this.beanFactory.getBeansOfType(GlobalChannelInterceptorWrapper.class))
|
||||
.thenReturn(Collections.emptyMap());
|
||||
this.globalChannelInterceptorProcessor.afterSingletonsInstantiated();
|
||||
verify(this.beanFactory)
|
||||
.getBeansOfType(GlobalChannelInterceptorWrapper.class);
|
||||
verify(this.beanFactory, Mockito.never())
|
||||
.getBeansOfType(ChannelInterceptorAware.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessorWithInterceptorDefaultPattern() {
|
||||
Map<String, GlobalChannelInterceptorWrapper> interceptors = new HashMap<>();
|
||||
Map<String, ChannelInterceptorAware> channels = new HashMap<>();
|
||||
ChannelInterceptor channelInterceptor = Mockito.mock(ChannelInterceptor.class);
|
||||
GlobalChannelInterceptorWrapper globalChannelInterceptorWrapper =
|
||||
new GlobalChannelInterceptorWrapper(channelInterceptor);
|
||||
|
||||
ChannelInterceptorAware channel = Mockito.mock(ChannelInterceptorAware.class);
|
||||
|
||||
interceptors.put("Test-1", globalChannelInterceptorWrapper);
|
||||
channels.put("Test-1", channel);
|
||||
when(this.beanFactory.getBeansOfType(GlobalChannelInterceptorWrapper.class))
|
||||
.thenReturn(interceptors);
|
||||
when(this.beanFactory.getBeansOfType(ChannelInterceptorAware.class))
|
||||
.thenReturn(channels);
|
||||
|
||||
this.globalChannelInterceptorProcessor.afterSingletonsInstantiated();
|
||||
|
||||
verify(channel)
|
||||
.addInterceptor(channelInterceptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessorWithInterceptorMatchingPattern() {
|
||||
Map<String, GlobalChannelInterceptorWrapper> interceptors = new HashMap<>();
|
||||
Map<String, ChannelInterceptorAware> channels = new HashMap<>();
|
||||
ChannelInterceptor channelInterceptor = Mockito.mock(ChannelInterceptor.class);
|
||||
GlobalChannelInterceptorWrapper globalChannelInterceptorWrapper =
|
||||
new GlobalChannelInterceptorWrapper(channelInterceptor);
|
||||
|
||||
ChannelInterceptorAware channel = Mockito.mock(ChannelInterceptorAware.class);
|
||||
|
||||
globalChannelInterceptorWrapper.setPatterns(new String[] { "Te*" });
|
||||
interceptors.put("Test-1", globalChannelInterceptorWrapper);
|
||||
channels.put("Test-1", channel);
|
||||
when(this.beanFactory.getBeansOfType(GlobalChannelInterceptorWrapper.class))
|
||||
.thenReturn(interceptors);
|
||||
when(this.beanFactory.getBeansOfType(ChannelInterceptorAware.class))
|
||||
.thenReturn(channels);
|
||||
this.globalChannelInterceptorProcessor.afterSingletonsInstantiated();
|
||||
|
||||
verify(channel)
|
||||
.addInterceptor(channelInterceptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessorWithInterceptorNotMatchingPattern() {
|
||||
Map<String, GlobalChannelInterceptorWrapper> interceptors = new HashMap<>();
|
||||
Map<String, ChannelInterceptorAware> channels = new HashMap<>();
|
||||
ChannelInterceptor channelInterceptor = Mockito.mock(ChannelInterceptor.class);
|
||||
GlobalChannelInterceptorWrapper globalChannelInterceptorWrapper =
|
||||
new GlobalChannelInterceptorWrapper(channelInterceptor);
|
||||
|
||||
ChannelInterceptorAware channel = Mockito.mock(ChannelInterceptorAware.class);
|
||||
|
||||
globalChannelInterceptorWrapper.setPatterns(new String[] { "te*" });
|
||||
interceptors.put("Test-1", globalChannelInterceptorWrapper);
|
||||
channels.put("Test-1", channel);
|
||||
when(this.beanFactory.getBeansOfType(GlobalChannelInterceptorWrapper.class))
|
||||
.thenReturn(interceptors);
|
||||
when(this.beanFactory.getBeansOfType(ChannelInterceptorAware.class))
|
||||
.thenReturn(channels);
|
||||
|
||||
this.globalChannelInterceptorProcessor.afterSingletonsInstantiated();
|
||||
|
||||
verify(channel, Mockito.never())
|
||||
.addInterceptor(channelInterceptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessorWithInterceptorMatchingNegativePattern() {
|
||||
Map<String, GlobalChannelInterceptorWrapper> interceptors = new HashMap<>();
|
||||
Map<String, ChannelInterceptorAware> channels = new HashMap<>();
|
||||
ChannelInterceptor channelInterceptor = Mockito.mock(ChannelInterceptor.class);
|
||||
GlobalChannelInterceptorWrapper globalChannelInterceptorWrapper =
|
||||
new GlobalChannelInterceptorWrapper(channelInterceptor);
|
||||
|
||||
ChannelInterceptorAware channel = Mockito.mock(ChannelInterceptorAware.class);
|
||||
|
||||
globalChannelInterceptorWrapper.setPatterns(new String[] { "!te*", "!Te*" });
|
||||
interceptors.put("Test-1", globalChannelInterceptorWrapper);
|
||||
channels.put("Test-1", channel);
|
||||
when(this.beanFactory.getBeansOfType(GlobalChannelInterceptorWrapper.class))
|
||||
.thenReturn(interceptors);
|
||||
when(this.beanFactory.getBeansOfType(ChannelInterceptorAware.class))
|
||||
.thenReturn(channels);
|
||||
this.globalChannelInterceptorProcessor.afterSingletonsInstantiated();
|
||||
|
||||
verify(channel, Mockito.never())
|
||||
.addInterceptor(channelInterceptor);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user