/* * Copyright 2014-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.xml; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; 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.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.springframework.integration.test.util.TestUtils.getPropertyValue; import java.io.ByteArrayInputStream; import java.util.List; import java.util.Map; import java.util.Properties; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.InputStreamResource; import org.springframework.integration.core.MessageSelector; import org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor; import org.springframework.integration.handler.MessageProcessor; import org.springframework.integration.handler.advice.IdempotentReceiverInterceptor; import org.springframework.integration.metadata.MetadataStore; import org.springframework.integration.selector.MetadataStoreSelector; import org.springframework.messaging.MessageChannel; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Artem Bilan * @since 4.1 */ @ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) @DirtiesContext public class IdempotentReceiverParserTests { @Autowired @Qualifier("org.springframework.integration.config.IdempotentReceiverAutoProxyCreator") private BeanPostProcessor idempotentReceiverAutoProxyCreator; @Autowired private IdempotentReceiverInterceptor selectorInterceptor; @Autowired private MessageSelector selector; @Autowired private IdempotentReceiverInterceptor strategyInterceptor; @Autowired private MessageProcessor<String> keyStrategy; @Autowired private MessageProcessor<String> valueStrategy; @Autowired @Qualifier("nullChannel") private MessageChannel nullChannel; @Autowired private IdempotentReceiverInterceptor expressionInterceptor; @Autowired private MetadataStore store; @Test public void testSelectorInterceptor() { assertSame(this.selector, getPropertyValue(this.selectorInterceptor, "messageSelector")); assertNull(getPropertyValue(this.selectorInterceptor, "discardChannel")); assertFalse(getPropertyValue(this.selectorInterceptor, "throwExceptionOnRejection", Boolean.class)); @SuppressWarnings("unchecked") Map<String, List<String>> idempotentEndpoints = (Map<String, List<String>>) getPropertyValue(this.idempotentReceiverAutoProxyCreator, "idempotentEndpoints", Map.class); List<String> endpoints = idempotentEndpoints.get("selectorInterceptor"); assertNotNull(endpoints); assertFalse(endpoints.isEmpty()); assertTrue(endpoints.contains("foo.handler")); } @Test public void testStrategyInterceptor() { assertSame(this.nullChannel, getPropertyValue(this.strategyInterceptor, "discardChannel")); assertTrue(getPropertyValue(this.strategyInterceptor, "throwExceptionOnRejection", Boolean.class)); Object messageSelector = getPropertyValue(this.strategyInterceptor, "messageSelector"); assertThat(messageSelector, instanceOf(MetadataStoreSelector.class)); assertSame(this.keyStrategy, getPropertyValue(messageSelector, "keyStrategy")); assertSame(this.valueStrategy, getPropertyValue(messageSelector, "valueStrategy")); @SuppressWarnings("unchecked") Map<String, List<String>> idempotentEndpoints = (Map<String, List<String>>) getPropertyValue(this.idempotentReceiverAutoProxyCreator, "idempotentEndpoints", Map.class); List<String> endpoints = idempotentEndpoints.get("strategyInterceptor"); assertNotNull(endpoints); assertFalse(endpoints.isEmpty()); assertTrue(endpoints.contains("foo.handler")); } @Test public void testExpressionInterceptor() { Object messageSelector = getPropertyValue(this.expressionInterceptor, "messageSelector"); assertThat(messageSelector, instanceOf(MetadataStoreSelector.class)); assertSame(this.store, getPropertyValue(messageSelector, "metadataStore")); Object keyStrategy = getPropertyValue(messageSelector, "keyStrategy"); assertThat(keyStrategy, instanceOf(ExpressionEvaluatingMessageProcessor.class)); assertThat(keyStrategy.toString(), containsString("headers.foo")); @SuppressWarnings("unchecked") Map<String, List<String>> idempotentEndpoints = (Map<String, List<String>>) getPropertyValue(this.idempotentReceiverAutoProxyCreator, "idempotentEndpoints", Map.class); List<String> endpoints = idempotentEndpoints.get("expressionInterceptor"); assertNotNull(endpoints); assertFalse(endpoints.isEmpty()); assertTrue(endpoints.contains("foo.handler")); assertTrue(endpoints.contains("bar*.handler")); } @Test public void testEmpty() throws Exception { try { bootStrap("empty"); fail("BeanDefinitionParsingException expected"); } catch (BeanDefinitionParsingException e) { assertThat(e.getMessage(), containsString("One of the 'selector', 'key-strategy' or 'key-expression' attributes " + "must be provided")); } } @Test public void testWithoutEndpoint() throws Exception { try { bootStrap("without-endpoint"); fail("BeanDefinitionParsingException expected"); } catch (BeanDefinitionParsingException e) { assertThat(e.getMessage(), containsString("he 'endpoint' attribute is required")); } } @Test public void testSelectorAndStore() throws Exception { try { bootStrap("selector-and-store"); fail("BeanDefinitionParsingException expected"); } catch (BeanDefinitionParsingException e) { assertThat(e.getMessage(), containsString("The 'selector' attribute is mutually exclusive with 'metadata-store', " + "'key-strategy', 'key-expression', 'value-strategy' or 'value-expression'")); } } @Test public void testSelectorAndKeyStrategy() throws Exception { try { bootStrap("selector-and-key-strategy"); fail("BeanDefinitionParsingException expected"); } catch (BeanDefinitionParsingException e) { assertThat(e.getMessage(), containsString("The 'selector' attribute is mutually exclusive with 'metadata-store', " + "'key-strategy', 'key-expression', 'value-strategy' or 'value-expression'")); } } @Test public void testSelectorAndKeyExpression() throws Exception { try { bootStrap("selector-and-key-expression"); fail("BeanDefinitionParsingException expected"); } catch (BeanDefinitionParsingException e) { assertThat(e.getMessage(), containsString("The 'selector' attribute is mutually exclusive with 'metadata-store', " + "'key-strategy', 'key-expression', 'value-strategy' or 'value-expression'")); } } @Test public void testSelectorAndValueStrategy() throws Exception { try { bootStrap("selector-and-value-strategy"); fail("BeanDefinitionParsingException expected"); } catch (BeanDefinitionParsingException e) { assertThat(e.getMessage(), containsString("The 'selector' attribute is mutually exclusive with 'metadata-store', " + "'key-strategy', 'key-expression', 'value-strategy' or 'value-expression'")); } } @Test public void testSelectorAndValueExpression() throws Exception { try { bootStrap("selector-and-value-expression"); fail("BeanDefinitionParsingException expected"); } catch (BeanDefinitionParsingException e) { assertThat(e.getMessage(), containsString("The 'selector' attribute is mutually exclusive with 'metadata-store', " + "'key-strategy', 'key-expression', 'value-strategy' or 'value-expression'")); } } @Test public void testKeyStrategyAndKeyExpression() throws Exception { try { bootStrap("key-strategy-and-key-expression"); fail("BeanDefinitionParsingException expected"); } catch (BeanDefinitionParsingException e) { assertThat(e.getMessage(), containsString("The 'key-strategy' and 'key-expression' attributes are mutually exclusive")); } } @Test public void testValueStrategyAndValueExpression() throws Exception { try { bootStrap("value-strategy-and-value-expression"); fail("BeanDefinitionParsingException expected"); } catch (BeanDefinitionParsingException e) { assertThat(e.getMessage(), containsString("The 'value-strategy' and 'value-expression' attributes are mutually exclusive")); } } private ApplicationContext bootStrap(String configProperty) throws Exception { PropertiesFactoryBean pfb = new PropertiesFactoryBean(); pfb.setLocation(new ClassPathResource( "org/springframework/integration/config/xml/idempotent-receiver-configs.properties")); pfb.afterPropertiesSet(); Properties prop = pfb.getObject(); ByteArrayInputStream stream = new ByteArrayInputStream((prop.getProperty("xmlheaders") + prop.getProperty(configProperty) + prop.getProperty("xmlfooter")).getBytes()); GenericApplicationContext ac = new GenericApplicationContext(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(ac); reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD); reader.loadBeanDefinitions(new InputStreamResource(stream)); ac.refresh(); return ac; } }