/*
* 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.gateway;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.mock;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.PublishSubscribeChannel;
import org.springframework.integration.handler.ServiceActivatingHandler;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.test.util.TestUtils.TestApplicationContext;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.PollableChannel;
/**
* @author Iwein Fuld
* @author Mark Fisher
* @author Artem Bilan
* @author Gary Russell
*/
@SuppressWarnings("unchecked")
public class MessagingGatewayTests {
private volatile MessagingGatewaySupport messagingGateway;
private volatile MessageChannel requestChannel = Mockito.mock(MessageChannel.class);
private volatile PollableChannel replyChannel = Mockito.mock(PollableChannel.class);
@SuppressWarnings("rawtypes")
private volatile Message messageMock = Mockito.mock(Message.class);
@Before
public void initializeSample() {
this.messagingGateway = new MessagingGatewaySupport() { };
this.messagingGateway.setRequestChannel(requestChannel);
this.messagingGateway.setReplyChannel(replyChannel);
TestApplicationContext applicationContext = TestUtils.createTestApplicationContext();
this.messagingGateway.setBeanFactory(applicationContext);
this.messagingGateway.setCountsEnabled(true);
this.messagingGateway.afterPropertiesSet();
this.messagingGateway.start();
applicationContext.refresh();
}
/* send tests */
@Test
public void sendMessage() {
Mockito.when(requestChannel.send(messageMock, 1000L)).thenReturn(true);
this.messagingGateway.send(messageMock);
Mockito.verify(requestChannel).send(messageMock, 1000L);
assertEquals(1, this.messagingGateway.getMessageCount());
}
@Test(expected = MessageDeliveryException.class)
public void sendMessage_failure() {
Mockito.when(messageMock.getHeaders()).thenReturn(new MessageHeaders(null));
Mockito.when(requestChannel.send(messageMock, 1000L)).thenReturn(false);
this.messagingGateway.send(messageMock);
}
@Test
public void sendObject() {
Mockito.doAnswer(invocation -> {
assertEquals("test", ((Message<?>) invocation.getArguments()[0]).getPayload());
return true;
}).when(requestChannel).send(Mockito.any(Message.class), Mockito.eq(1000L));
this.messagingGateway.send("test");
Mockito.verify(requestChannel).send(Mockito.any(Message.class), Mockito.eq(1000L));
}
@Test(expected = MessageDeliveryException.class)
public void sendObject_failure() {
Mockito.doAnswer(invocation -> {
assertEquals("test", ((Message<?>) invocation.getArguments()[0]).getPayload());
return false;
}).when(requestChannel).send(Mockito.any(Message.class), Mockito.eq(1000L));
this.messagingGateway.send("test");
}
@Test(expected = IllegalArgumentException.class)
public void sendMessage_null() {
this.messagingGateway.send(null);
}
/* receive tests */
@Test
public void receiveMessage() {
Mockito.when(replyChannel.receive(1000L)).thenReturn(messageMock);
Mockito.when(messageMock.getPayload()).thenReturn("test");
assertEquals("test", this.messagingGateway.receive());
Mockito.verify(replyChannel).receive(1000L);
}
@Test
public void receiveMessage_null() {
Mockito.when(replyChannel.receive(1000L)).thenReturn(null);
assertNull(this.messagingGateway.receive());
Mockito.verify(replyChannel).receive(1000L);
}
/* send and receive tests */
@Test
public void sendObjectAndReceiveObject() {
Mockito.when(replyChannel.receive(100L)).thenReturn(messageMock);
Mockito.when(messageMock.getPayload()).thenReturn("test");
Mockito.doAnswer(invocation -> {
Message<?> message = (Message<?>) invocation.getArguments()[0];
MessageChannel replyChannel = (MessageChannel) message.getHeaders().getReplyChannel();
replyChannel.send(message);
return true;
}).when(requestChannel).send(Mockito.any(Message.class), Mockito.anyLong());
// TODO: if timeout is 0, this will fail occasionally
this.messagingGateway.setReplyTimeout(100);
Object test = this.messagingGateway.sendAndReceive("test");
assertEquals("test", test);
}
@Test
public void sendMessageAndReceiveObject() {
Map<String, Object> headers = new HashMap<String, Object>();
headers.put(MessageHeaders.ID, UUID.randomUUID());
MessageHeaders messageHeadersMock = new MessageHeaders(headers);
Mockito.when(replyChannel.receive(0)).thenReturn(messageMock);
Mockito.when(messageMock.getHeaders()).thenReturn(messageHeadersMock);
Mockito.when(messageMock.getPayload()).thenReturn("foo");
Mockito.doAnswer(invocation -> {
Message<?> message = (Message<?>) invocation.getArguments()[0];
MessageChannel replyChannel = (MessageChannel) message.getHeaders().getReplyChannel();
replyChannel.send(message);
return true;
}).when(requestChannel).send(Mockito.any(Message.class), Mockito.anyLong());
this.messagingGateway.setReplyTimeout(0);
Object o = this.messagingGateway.sendAndReceive(messageMock);
assertEquals("foo", o);
}
@Test(expected = IllegalArgumentException.class)
public void sendNullAndReceiveObject() {
this.messagingGateway.sendAndReceive(null);
}
@Test
public void sendObjectAndReceiveMessage() {
Mockito.when(messageMock.getPayload()).thenReturn("foo");
Mockito.when(replyChannel.receive(100L)).thenReturn(messageMock);
Mockito.doAnswer(invocation -> {
Message<?> message = (Message<?>) invocation.getArguments()[0];
MessageChannel replyChannel = (MessageChannel) message.getHeaders().getReplyChannel();
replyChannel.send(messageMock);
return true;
}).when(requestChannel).send(Mockito.any(Message.class), Mockito.anyLong());
this.messagingGateway.setReplyTimeout(100L);
Message<?> receiveMessage = this.messagingGateway.sendAndReceiveMessage("test");
assertSame(messageMock, receiveMessage);
}
@Test
public void sendMessageAndReceiveMessage() {
Map<String, Object> headers = new HashMap<String, Object>();
headers.put(MessageHeaders.ID, UUID.randomUUID());
headers.put(MessageHeaders.REPLY_CHANNEL, replyChannel);
MessageHeaders messageHeadersMock = new MessageHeaders(headers);
Mockito.when(replyChannel.receive(Mockito.anyLong())).thenReturn(messageMock);
Mockito.when(messageMock.getHeaders()).thenReturn(messageHeadersMock);
Mockito.when(messageMock.getPayload()).thenReturn("foo");
Mockito.doAnswer(invocation -> {
Message<?> message = (Message<?>) invocation.getArguments()[0];
MessageChannel replyChannel = (MessageChannel) message.getHeaders().getReplyChannel();
replyChannel.send(messageMock);
return true;
}).when(requestChannel).send(Mockito.any(Message.class), Mockito.anyLong());
Message<?> receiveMessage = this.messagingGateway.sendAndReceiveMessage(messageMock);
assertSame(messageMock, receiveMessage);
}
@Test(expected = IllegalArgumentException.class)
public void sendNullAndReceiveMessage() {
this.messagingGateway.sendAndReceiveMessage(null);
}
// should fail but it doesn't now
@Test(expected = MessagingException.class)
public void validateErroMessageCanNotBeReplyMessage() {
DirectChannel reqChannel = new DirectChannel();
reqChannel.subscribe(message -> {
throw new RuntimeException("ooops");
});
PublishSubscribeChannel errorChannel = new PublishSubscribeChannel();
ServiceActivatingHandler handler = new ServiceActivatingHandler(new MyErrorService());
handler.setBeanFactory(mock(BeanFactory.class));
handler.afterPropertiesSet();
errorChannel.subscribe(handler);
this.messagingGateway = new MessagingGatewaySupport() { };
this.messagingGateway.setRequestChannel(reqChannel);
this.messagingGateway.setErrorChannel(errorChannel);
this.messagingGateway.setReplyChannel(null);
this.messagingGateway.setBeanFactory(mock(BeanFactory.class));
this.messagingGateway.afterPropertiesSet();
this.messagingGateway.start();
this.messagingGateway.sendAndReceiveMessage("hello");
}
// should not fail but it does now
@Test
public void validateErrorChannelWithSuccessfulReply() {
TestUtils.TestApplicationContext testApplicationContext = TestUtils.createTestApplicationContext();
testApplicationContext.refresh();
DirectChannel reqChannel = new DirectChannel();
reqChannel.subscribe(message -> {
throw new RuntimeException("ooops");
});
PublishSubscribeChannel errorChannel = new PublishSubscribeChannel();
ServiceActivatingHandler handler = new ServiceActivatingHandler(new MyOneWayErrorService());
handler.setBeanFactory(testApplicationContext);
handler.afterPropertiesSet();
errorChannel.subscribe(handler);
this.messagingGateway = new MessagingGatewaySupport() { };
this.messagingGateway.setRequestChannel(reqChannel);
this.messagingGateway.setErrorChannel(errorChannel);
this.messagingGateway.setReplyChannel(null);
this.messagingGateway.setBeanFactory(mock(BeanFactory.class));
this.messagingGateway.afterPropertiesSet();
this.messagingGateway.start();
this.messagingGateway.send("hello");
testApplicationContext.close();
}
public static class MyErrorService {
public Message<?> handleErrorMessage(Message<?> errorMessage) {
return errorMessage;
}
}
public static class MyOneWayErrorService {
public void handleErrorMessage(Message<?> errorMessage) {
}
}
}