/* * 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. * 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.amqp.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.isNull; import java.lang.reflect.Field; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.springframework.amqp.core.Address; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessageProperties; import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.amqp.support.converter.SimpleMessageConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.amqp.inbound.AmqpInboundGateway; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.support.MessageBuilder; import org.springframework.integration.test.util.TestUtils; import org.springframework.messaging.MessageChannel; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.ReflectionUtils; /** * @author Mark Fisher * @author Gunnar Hillert * @author Artem Bilan * @author Gary Russell * * @since 2.1 */ @ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) @DirtiesContext public class AmqpInboundGatewayParserTests { @Autowired private ApplicationContext context; @Test public void customMessageConverter() { Object gateway = context.getBean("gateway"); MessageConverter gatewayConverter = TestUtils.getPropertyValue(gateway, "amqpMessageConverter", MessageConverter.class); MessageConverter templateConverter = TestUtils.getPropertyValue(gateway, "amqpTemplate.messageConverter", MessageConverter.class); TestConverter testConverter = context.getBean("testConverter", TestConverter.class); assertSame(testConverter, gatewayConverter); assertSame(testConverter, templateConverter); assertEquals(Boolean.TRUE, TestUtils.getPropertyValue(gateway, "autoStartup")); assertEquals(0, TestUtils.getPropertyValue(gateway, "phase")); assertEquals(Long.valueOf(1234L), TestUtils.getPropertyValue(gateway, "replyTimeout", Long.class)); assertEquals(Long.valueOf(1234L), TestUtils.getPropertyValue(gateway, "messagingTemplate.receiveTimeout", Long.class)); assertTrue(TestUtils.getPropertyValue(gateway, "messageListenerContainer.missingQueuesFatal", Boolean.class)); } @Test public void verifyLifeCycle() { Object gateway = context.getBean("autoStartFalseGateway"); assertEquals(Boolean.FALSE, TestUtils.getPropertyValue(gateway, "autoStartup")); assertEquals(123, TestUtils.getPropertyValue(gateway, "phase")); assertFalse(TestUtils.getPropertyValue(gateway, "messageListenerContainer.missingQueuesFatal", Boolean.class)); Object amqpTemplate = context.getBean("amqpTemplate"); assertSame(amqpTemplate, TestUtils.getPropertyValue(gateway, "amqpTemplate")); Address defaultReplyTo = TestUtils.getPropertyValue(gateway, "defaultReplyTo", Address.class); Address expected = new Address("fooExchange/barRoutingKey"); assertEquals(expected.getExchangeName(), defaultReplyTo.getExchangeName()); assertEquals(expected.getRoutingKey(), defaultReplyTo.getRoutingKey()); assertEquals(expected, defaultReplyTo); } @Test public void verifyUsageWithHeaderMapper() throws Exception { DirectChannel requestChannel = context.getBean("requestChannel", DirectChannel.class); requestChannel.subscribe(siMessage -> { org.springframework.messaging.Message<?> replyMessage = MessageBuilder.fromMessage(siMessage) .setHeader("bar", "bar").build(); MessageChannel replyChannel = (MessageChannel) siMessage.getHeaders().getReplyChannel(); replyChannel.send(replyMessage); }); final AmqpInboundGateway gateway = context.getBean("withHeaderMapper", AmqpInboundGateway.class); Field amqpTemplateField = ReflectionUtils.findField(AmqpInboundGateway.class, "amqpTemplate"); amqpTemplateField.setAccessible(true); RabbitTemplate amqpTemplate = TestUtils.getPropertyValue(gateway, "amqpTemplate", RabbitTemplate.class); amqpTemplate = Mockito.spy(amqpTemplate); Mockito.doAnswer(invocation -> { Object[] args = invocation.getArguments(); Message amqpReplyMessage = (Message) args[2]; MessageProperties properties = amqpReplyMessage.getMessageProperties(); assertEquals("bar", properties.getHeaders().get("bar")); return null; }).when(amqpTemplate).send(Mockito.any(String.class), Mockito.any(String.class), Mockito.any(Message.class), isNull()); ReflectionUtils.setField(amqpTemplateField, gateway, amqpTemplate); AbstractMessageListenerContainer mlc = TestUtils.getPropertyValue(gateway, "messageListenerContainer", AbstractMessageListenerContainer.class); ChannelAwareMessageListener listener = TestUtils.getPropertyValue(mlc, "messageListener", ChannelAwareMessageListener.class); MessageProperties amqpProperties = new MessageProperties(); amqpProperties.setAppId("test.appId"); amqpProperties.setClusterId("test.clusterId"); amqpProperties.setContentEncoding("test.contentEncoding"); amqpProperties.setContentLength(99L); amqpProperties.setReplyTo("oleg"); amqpProperties.setContentType("test.contentType"); amqpProperties.setHeader("foo", "foo"); amqpProperties.setHeader("bar", "bar"); Message amqpMessage = new Message("hello".getBytes(), amqpProperties); listener.onMessage(amqpMessage, null); Mockito.verify(amqpTemplate, Mockito.times(1)).send(Mockito.any(String.class), Mockito.any(String.class), Mockito.any(Message.class), isNull()); } @Test public void testInt2971HeaderMapperAndMappedHeadersExclusivity() { try { new ClassPathXmlApplicationContext("AmqpInboundGatewayParserTests-headerMapper-fail-context.xml", this.getClass()).close(); } catch (BeanDefinitionParsingException e) { assertTrue(e.getMessage().startsWith("Configuration problem: The 'header-mapper' attribute " + "is mutually exclusive with 'mapped-request-headers' or 'mapped-reply-headers'")); } } private static class TestConverter extends SimpleMessageConverter { } }