/* * Copyright 2002-2015 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.annotation; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.List; import org.junit.Before; import org.junit.Test; import org.springframework.integration.annotation.Filter; import org.springframework.integration.annotation.MessageEndpoint; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.endpoint.EventDrivenConsumer; import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice; import org.springframework.integration.test.util.TestUtils; import org.springframework.integration.test.util.TestUtils.TestApplicationContext; import org.springframework.messaging.Message; import org.springframework.messaging.support.GenericMessage; /** * @author Mark Fisher * @author Gary Russell * @author Artem Bilan * @since 2.0 */ public class FilterAnnotationPostProcessorTests { private final TestApplicationContext context = TestUtils.createTestApplicationContext(); private final MessagingAnnotationPostProcessor postProcessor = new MessagingAnnotationPostProcessor(); private final DirectChannel inputChannel = new DirectChannel(); private final QueueChannel outputChannel = new QueueChannel(); @Before public void init() { context.registerChannel("input", inputChannel); context.registerChannel("output", outputChannel); postProcessor.setBeanFactory(context.getBeanFactory()); postProcessor.afterPropertiesSet(); } @Test public void filterAnnotationWithBooleanPrimitive() { testValidFilter(new TestFilterWithBooleanPrimitive()); } @Test public void filterAnnotationWithAdviceDiscardWithin() { TestAdvice advice = new TestAdvice(); context.registerBean("adviceChain", advice); testValidFilter(new TestFilterWithAdviceDiscardWithin()); EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("testFilter.filter.filter"); assertSame(advice, TestUtils.getPropertyValue(endpoint, "handler.adviceChain", List.class).get(0)); assertTrue(TestUtils.getPropertyValue(endpoint, "handler.postProcessWithinAdvice", Boolean.class)); } @Test public void filterAnnotationWithAdviceDiscardWithinTwice() { TestAdvice advice1 = new TestAdvice(); TestAdvice advice2 = new TestAdvice(); context.registerBean("adviceChain1", advice1); context.registerBean("adviceChain2", advice2); testValidFilter(new TestFilterWithAdviceDiscardWithinTwice()); EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("testFilter.filter.filter"); List<?> adviceList = TestUtils.getPropertyValue(endpoint, "handler.adviceChain", List.class); assertEquals(2, adviceList.size()); assertSame(advice1, adviceList.get(0)); assertSame(advice2, adviceList.get(1)); assertTrue(TestUtils.getPropertyValue(endpoint, "handler.postProcessWithinAdvice", Boolean.class)); } @Test public void filterAnnotationWithAdviceDiscardWithout() { TestAdvice advice = new TestAdvice(); context.registerBean("adviceChain", advice); testValidFilter(new TestFilterWithAdviceDiscardWithout()); EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("testFilter.filter.filter"); assertSame(advice, TestUtils.getPropertyValue(endpoint, "handler.adviceChain", List.class).get(0)); assertFalse(TestUtils.getPropertyValue(endpoint, "handler.postProcessWithinAdvice", Boolean.class)); } @Test public void filterAnnotationWithAdviceArray() { TestAdvice advice = new TestAdvice(); context.registerBean("adviceChain", new TestAdvice[] {advice}); testValidFilter(new TestFilterWithAdviceDiscardWithin()); EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("testFilter.filter.filter"); assertSame(advice, TestUtils.getPropertyValue(endpoint, "handler.adviceChain", List.class).get(0)); assertTrue(TestUtils.getPropertyValue(endpoint, "handler.postProcessWithinAdvice", Boolean.class)); } @Test public void filterAnnotationWithAdviceArrayTwice() { TestAdvice advice1 = new TestAdvice(); TestAdvice advice2 = new TestAdvice(); context.registerBean("adviceChain1", new TestAdvice[] {advice1, advice2}); TestAdvice advice3 = new TestAdvice(); TestAdvice advice4 = new TestAdvice(); context.registerBean("adviceChain2", new TestAdvice[] {advice3, advice4}); testValidFilter(new TestFilterWithAdviceDiscardWithinTwice()); EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("testFilter.filter.filter"); List<?> adviceList = TestUtils.getPropertyValue(endpoint, "handler.adviceChain", List.class); assertEquals(4, adviceList.size()); assertSame(advice1, adviceList.get(0)); assertSame(advice2, adviceList.get(1)); assertSame(advice3, adviceList.get(2)); assertSame(advice4, adviceList.get(3)); assertTrue(TestUtils.getPropertyValue(endpoint, "handler.postProcessWithinAdvice", Boolean.class)); } @Test public void filterAnnotationWithAdviceCollection() { TestAdvice advice = new TestAdvice(); context.registerBean("adviceChain", Arrays.asList(new TestAdvice[] {advice})); testValidFilter(new TestFilterWithAdviceDiscardWithin()); EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("testFilter.filter.filter"); assertSame(advice, TestUtils.getPropertyValue(endpoint, "handler.adviceChain", List.class).get(0)); assertTrue(TestUtils.getPropertyValue(endpoint, "handler.postProcessWithinAdvice", Boolean.class)); } @Test public void filterAnnotationWithAdviceCollectionTwice() { TestAdvice advice1 = new TestAdvice(); TestAdvice advice2 = new TestAdvice(); context.registerBean("adviceChain1", new TestAdvice[] {advice1, advice2}); TestAdvice advice3 = new TestAdvice(); TestAdvice advice4 = new TestAdvice(); context.registerBean("adviceChain2", new TestAdvice[] {advice3, advice4}); testValidFilter(new TestFilterWithAdviceDiscardWithinTwice()); EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("testFilter.filter.filter"); List<?> adviceList = TestUtils.getPropertyValue(endpoint, "handler.adviceChain", List.class); assertEquals(4, adviceList.size()); assertSame(advice1, adviceList.get(0)); assertSame(advice2, adviceList.get(1)); assertSame(advice3, adviceList.get(2)); assertSame(advice4, adviceList.get(3)); assertTrue(TestUtils.getPropertyValue(endpoint, "handler.postProcessWithinAdvice", Boolean.class)); } @Test public void filterAnnotationWithBooleanWrapperClass() { testValidFilter(new TestFilterWithBooleanWrapperClass()); } @Test(expected = IllegalArgumentException.class) public void invalidMethodWithStringReturnType() { Object filter = new TestFilterWithStringReturnType(); postProcessor.postProcessAfterInitialization(filter, "testFilter"); } @Test(expected = IllegalArgumentException.class) public void invalidMethodWithVoidReturnType() { Object filter = new TestFilterWithVoidReturnType(); postProcessor.postProcessAfterInitialization(filter, "testFilter"); } private void testValidFilter(Object filter) { postProcessor.postProcessAfterInitialization(filter, "testFilter"); context.refresh(); inputChannel.send(new GenericMessage<String>("good")); Message<?> passed = outputChannel.receive(0); assertNotNull(passed); inputChannel.send(new GenericMessage<String>("bad")); assertNull(outputChannel.receive(0)); context.stop(); } @MessageEndpoint public static class TestFilterWithBooleanPrimitive { @Filter(inputChannel = "input", outputChannel = "output") public boolean filter(String s) { return !s.contains("bad"); } } @MessageEndpoint public static class TestFilterWithAdviceDiscardWithin { @Filter(inputChannel = "input", outputChannel = "output", adviceChain = "adviceChain") public boolean filter(String s) { return !s.contains("bad"); } } @MessageEndpoint public static class TestFilterWithAdviceDiscardWithinTwice { @Filter(inputChannel = "input", outputChannel = "output", adviceChain = {"adviceChain1", "adviceChain2"}) public boolean filter(String s) { return !s.contains("bad"); } } @MessageEndpoint public static class TestFilterWithAdviceDiscardWithout { @Filter(inputChannel = "input", outputChannel = "output", adviceChain = "adviceChain", discardWithinAdvice = "false") public boolean filter(String s) { return !s.contains("bad"); } } @MessageEndpoint public static class TestFilterWithBooleanWrapperClass { @Filter(inputChannel = "input", outputChannel = "output") public Boolean filter(String s) { return !s.contains("bad"); } } @MessageEndpoint public static class TestFilterWithStringReturnType { @Filter(inputChannel = "input", outputChannel = "output") public String filter(String s) { return s; } } @MessageEndpoint public static class TestFilterWithVoidReturnType { @Filter(inputChannel = "input", outputChannel = "output") public void filter(String s) { } } public static class TestAdvice extends AbstractRequestHandlerAdvice { @Override protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception { return callback.execute(); } } }