/* * 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.amqp.rabbit.core; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.willThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.io.Writer; import java.util.HashMap; import java.util.Map; import org.hamcrest.core.StringContains; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.amqp.core.MessageProperties; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.test.MessageTestUtils; import org.springframework.amqp.support.converter.MessageConversionException; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.amqp.support.converter.MessagingMessageConverter; import org.springframework.amqp.support.converter.SimpleMessageConverter; import org.springframework.amqp.utils.test.TestUtils; import org.springframework.messaging.Message; import org.springframework.messaging.converter.GenericMessageConverter; import org.springframework.messaging.support.MessageBuilder; /** * @author Stephane Nicoll * @author Gary Russell */ public class RabbitMessagingTemplateTests { @Rule public final ExpectedException thrown = ExpectedException.none(); @Captor private ArgumentCaptor<org.springframework.amqp.core.Message> amqpMessage; @Mock private RabbitTemplate rabbitTemplate; private RabbitMessagingTemplate messagingTemplate; @Before public void setup() { MockitoAnnotations.initMocks(this); messagingTemplate = new RabbitMessagingTemplate(rabbitTemplate); } @Test public void validateRabbitTemplate() { assertSame(this.rabbitTemplate, messagingTemplate.getRabbitTemplate()); this.rabbitTemplate.afterPropertiesSet(); } @Test public void verifyConverter() { RabbitTemplate template = new RabbitTemplate(mock(ConnectionFactory.class)); RabbitMessagingTemplate rmt = new RabbitMessagingTemplate(template); rmt.afterPropertiesSet(); assertSame(template.getMessageConverter(), TestUtils.getPropertyValue(rmt, "amqpMessageConverter.payloadConverter")); rmt = new RabbitMessagingTemplate(template); MessagingMessageConverter amqpMessageConverter = new MessagingMessageConverter(); MessageConverter payloadConverter = mock(MessageConverter.class); amqpMessageConverter.setPayloadConverter(payloadConverter); rmt.setAmqpMessageConverter(amqpMessageConverter); rmt.afterPropertiesSet(); assertSame(payloadConverter, TestUtils.getPropertyValue(rmt, "amqpMessageConverter.payloadConverter")); } @Test public void send() { Message<String> message = createTextMessage(); messagingTemplate.send("myQueue", message); verify(rabbitTemplate).send(eq("myQueue"), this.amqpMessage.capture()); assertTextMessage(this.amqpMessage.getValue()); } @Test public void sendExchange() { Message<String> message = createTextMessage(); messagingTemplate.send("myExchange", "myQueue", message); verify(rabbitTemplate).send(eq("myExchange"), eq("myQueue"), this.amqpMessage.capture()); assertTextMessage(this.amqpMessage.getValue()); } @Test public void sendDefaultDestination() { messagingTemplate.setDefaultDestination("default"); Message<String> message = createTextMessage(); messagingTemplate.send(message); verify(rabbitTemplate).send(eq("default"), this.amqpMessage.capture()); assertTextMessage(this.amqpMessage.getValue()); } @Test public void sendNoDefaultSet() { Message<String> message = createTextMessage(); thrown.expect(IllegalStateException.class); messagingTemplate.send(message); } @Test public void sendPropertyInjection() { RabbitMessagingTemplate t = new RabbitMessagingTemplate(); t.setRabbitTemplate(rabbitTemplate); t.setDefaultDestination("myQueue"); t.afterPropertiesSet(); Message<String> message = createTextMessage(); t.send(message); verify(rabbitTemplate).send(eq("myQueue"), this.amqpMessage.capture()); assertTextMessage(this.amqpMessage.getValue()); } @Test public void convertAndSendPayload() { messagingTemplate.convertAndSend("myQueue", "my Payload"); verify(rabbitTemplate).send(eq("myQueue"), amqpMessage.capture()); assertEquals("my Payload", MessageTestUtils.extractText(amqpMessage.getValue())); } @Test public void convertAndSendPayloadExchange() { messagingTemplate.convertAndSend("myExchange", "myQueue", "my Payload"); verify(rabbitTemplate).send(eq("myExchange"), eq("myQueue"), amqpMessage.capture()); assertEquals("my Payload", MessageTestUtils.extractText(amqpMessage.getValue())); } @Test public void convertAndSendDefaultDestination() { messagingTemplate.setDefaultDestination("default"); messagingTemplate.convertAndSend("my Payload"); verify(rabbitTemplate).send(eq("default"), amqpMessage.capture()); assertEquals("my Payload", MessageTestUtils.extractText(amqpMessage.getValue())); } @Test public void convertAndSendNoDefaultSet() { thrown.expect(IllegalStateException.class); messagingTemplate.convertAndSend("my Payload"); } @Test public void convertAndSendCustomAmqpMessageConverter() { messagingTemplate.setAmqpMessageConverter(new SimpleMessageConverter() { @Override protected org.springframework.amqp.core.Message createMessage(Object object, MessageProperties messageProperties) throws MessageConversionException { throw new MessageConversionException("Test exception"); } }); thrown.expect(org.springframework.messaging.converter.MessageConversionException.class); thrown.expectMessage(new StringContains("Test exception")); messagingTemplate.convertAndSend("myQueue", "msg to convert"); } @Test public void convertAndSendPayloadAndHeaders() { Map<String, Object> headers = new HashMap<String, Object>(); headers.put("foo", "bar"); messagingTemplate.convertAndSend("myQueue", (Object) "Hello", headers); verify(rabbitTemplate).send(eq("myQueue"), amqpMessage.capture()); assertTextMessage(amqpMessage.getValue()); } @Test public void convertAndSendPayloadAndHeadersExchange() { Map<String, Object> headers = new HashMap<String, Object>(); headers.put("foo", "bar"); messagingTemplate.convertAndSend("myExchange", "myQueue", "Hello", headers); verify(rabbitTemplate).send(eq("myExchange"), eq("myQueue"), amqpMessage.capture()); assertTextMessage(amqpMessage.getValue()); } @Test public void receive() { org.springframework.amqp.core.Message amqpMessage = createAmqpTextMessage(); given(rabbitTemplate.receive("myQueue")).willReturn(amqpMessage); Message<?> message = messagingTemplate.receive("myQueue"); verify(rabbitTemplate).receive("myQueue"); assertTextMessage(message); } @Test public void receiveDefaultDestination() { messagingTemplate.setDefaultDestination("default"); org.springframework.amqp.core.Message amqpMessage = createAmqpTextMessage(); given(rabbitTemplate.receive("default")).willReturn(amqpMessage); Message<?> message = messagingTemplate.receive(); verify(rabbitTemplate).receive("default"); assertTextMessage(message); } @Test public void receiveNoDefaultSet() { thrown.expect(IllegalStateException.class); messagingTemplate.receive(); } @Test public void receiveAndConvert() { org.springframework.amqp.core.Message amqpMessage = createAmqpTextMessage("my Payload"); given(rabbitTemplate.receive("myQueue")).willReturn(amqpMessage); String payload = messagingTemplate.receiveAndConvert("myQueue", String.class); assertEquals("my Payload", payload); verify(rabbitTemplate).receive("myQueue"); } @Test public void receiveAndConvertDefaultDestination() { messagingTemplate.setDefaultDestination("default"); org.springframework.amqp.core.Message amqpMessage = createAmqpTextMessage("my Payload"); given(rabbitTemplate.receive("default")).willReturn(amqpMessage); String payload = messagingTemplate.receiveAndConvert(String.class); assertEquals("my Payload", payload); verify(rabbitTemplate).receive("default"); } @Test public void receiveAndConvertWithConversion() { org.springframework.amqp.core.Message amqpMessage = createAmqpTextMessage("123"); given(rabbitTemplate.receive("myQueue")).willReturn(amqpMessage); messagingTemplate.setMessageConverter(new GenericMessageConverter()); Integer payload = messagingTemplate.receiveAndConvert("myQueue", Integer.class); assertEquals(Integer.valueOf(123), payload); verify(rabbitTemplate).receive("myQueue"); } @Test public void receiveAndConvertNoConverter() { org.springframework.amqp.core.Message amqpMessage = createAmqpTextMessage("Hello"); given(rabbitTemplate.receive("myQueue")).willReturn(amqpMessage); thrown.expect(org.springframework.messaging.converter.MessageConversionException.class); messagingTemplate.receiveAndConvert("myQueue", Writer.class); } @Test public void receiveAndConvertNoInput() { given(rabbitTemplate.receive("myQueue")).willReturn(null); assertNull(messagingTemplate.receiveAndConvert("myQueue", String.class)); } @Test public void sendAndReceive() { Message<String> request = createTextMessage(); org.springframework.amqp.core.Message reply = createAmqpTextMessage(); given(rabbitTemplate.sendAndReceive(eq("myQueue"), anyAmqpMessage())).willReturn(reply); Message<?> actual = messagingTemplate.sendAndReceive("myQueue", request); verify(rabbitTemplate, times(1)).sendAndReceive(eq("myQueue"), anyAmqpMessage()); assertTextMessage(actual); } @Test public void sendAndReceiveExchange() { Message<String> request = createTextMessage(); org.springframework.amqp.core.Message reply = createAmqpTextMessage(); given(rabbitTemplate.sendAndReceive(eq("myExchange"), eq("myQueue"), anyAmqpMessage())).willReturn(reply); Message<?> actual = messagingTemplate.sendAndReceive("myExchange", "myQueue", request); verify(rabbitTemplate, times(1)).sendAndReceive(eq("myExchange"), eq("myQueue"), anyAmqpMessage()); assertTextMessage(actual); } @Test public void sendAndReceiveDefaultDestination() { messagingTemplate.setDefaultDestination("default"); Message<String> request = createTextMessage(); org.springframework.amqp.core.Message reply = createAmqpTextMessage(); given(rabbitTemplate.sendAndReceive(eq("default"), anyAmqpMessage())).willReturn(reply); Message<?> actual = messagingTemplate.sendAndReceive(request); verify(rabbitTemplate, times(1)).sendAndReceive(eq("default"), anyAmqpMessage()); assertTextMessage(actual); } @Test public void sendAndReceiveNoDefaultSet() { Message<String> message = createTextMessage(); thrown.expect(IllegalStateException.class); messagingTemplate.sendAndReceive(message); } @Test public void convertSendAndReceivePayload() { org.springframework.amqp.core.Message replyMessage = createAmqpTextMessage("My reply"); given(rabbitTemplate.sendAndReceive(eq("myQueue"), anyAmqpMessage())).willReturn(replyMessage); String reply = messagingTemplate.convertSendAndReceive("myQueue", "my Payload", String.class); verify(rabbitTemplate, times(1)).sendAndReceive(eq("myQueue"), anyAmqpMessage()); assertEquals("My reply", reply); } @Test public void convertSendAndReceivePayloadExchange() { org.springframework.amqp.core.Message replyMessage = createAmqpTextMessage("My reply"); given(rabbitTemplate.sendAndReceive(eq("myExchange"), eq("myQueue"), anyAmqpMessage())).willReturn(replyMessage); String reply = messagingTemplate.convertSendAndReceive("myExchange", "myQueue", "my Payload", String.class); verify(rabbitTemplate, times(1)).sendAndReceive(eq("myExchange"), eq("myQueue"), anyAmqpMessage()); assertEquals("My reply", reply); } @Test public void convertSendAndReceiveDefaultDestination() { messagingTemplate.setDefaultDestination("default"); org.springframework.amqp.core.Message replyMessage = createAmqpTextMessage("My reply"); given(rabbitTemplate.sendAndReceive(eq("default"), anyAmqpMessage())).willReturn(replyMessage); String reply = messagingTemplate.convertSendAndReceive("my Payload", String.class); verify(rabbitTemplate, times(1)).sendAndReceive(eq("default"), anyAmqpMessage()); assertEquals("My reply", reply); } @Test public void convertSendAndReceiveNoDefaultSet() { thrown.expect(IllegalStateException.class); messagingTemplate.convertSendAndReceive("my Payload", String.class); } @Test public void convertMessageConversionExceptionOnSend() { Message<String> message = createTextMessage(); MessageConverter messageConverter = mock(MessageConverter.class); willThrow(org.springframework.amqp.support.converter.MessageConversionException.class) .given(messageConverter).toMessage(eq(message), anyMessageProperties()); messagingTemplate.setAmqpMessageConverter(messageConverter); thrown.expect(org.springframework.messaging.converter.MessageConversionException.class); messagingTemplate.send("myQueue", message); } @Test public void convertMessageConversionExceptionOnReceive() { org.springframework.amqp.core.Message message = createAmqpTextMessage(); MessageConverter messageConverter = mock(MessageConverter.class); willThrow(org.springframework.amqp.support.converter.MessageConversionException.class) .given(messageConverter).fromMessage(message); messagingTemplate.setAmqpMessageConverter(messageConverter); given(rabbitTemplate.receive("myQueue")).willReturn(message); thrown.expect(org.springframework.messaging.converter.MessageConversionException.class); messagingTemplate.receive("myQueue"); } private Message<String> createTextMessage(String payload) { return MessageBuilder .withPayload(payload).setHeader("foo", "bar").build(); } private Message<String> createTextMessage() { return createTextMessage("Hello"); } private org.springframework.amqp.core.Message createAmqpTextMessage(String payload) { MessageProperties properties = new MessageProperties(); properties.setHeader("foo", "bar"); return MessageTestUtils.createTextMessage(payload, properties); } private org.springframework.amqp.core.Message createAmqpTextMessage() { return createAmqpTextMessage("Hello"); } private void assertTextMessage(org.springframework.amqp.core.Message amqpMessage) { assertEquals("Wrong body message", "Hello", MessageTestUtils.extractText(amqpMessage)); assertEquals("Invalid foo property", "bar", amqpMessage.getMessageProperties().getHeaders().get("foo")); } private void assertTextMessage(Message<?> message) { assertNotNull("message should not be null", message); assertEquals("Wrong payload", "Hello", message.getPayload()); assertEquals("Invalid foo property", "bar", message.getHeaders().get("foo")); } private static org.springframework.amqp.core.Message anyAmqpMessage() { return any(org.springframework.amqp.core.Message.class); } private static MessageProperties anyMessageProperties() { return any(MessageProperties.class); } }