@SendTo support for jms listener endpoints

This commit replaces the "responseDestination" attribute on the
JmsListener annotation by a support of the standard SendTo annotation.

Issue: SPR-11707
This commit is contained in:
Stephane Nicoll
2014-04-24 15:33:24 +03:00
parent 4b0aba63df
commit bded025d9f
9 changed files with 153 additions and 45 deletions

View File

@@ -114,7 +114,7 @@ public abstract class AbstractJmsAnnotationDrivenTests {
static class FullBean {
@JmsListener(id = "listener1", containerFactory = "simpleFactory", destination = "queueIn",
responseDestination = "queueOut", selector = "mySelector", subscription = "mySubscription")
selector = "mySelector", subscription = "mySubscription")
public String fullHandle(String msg) {
return "reply";
}

View File

@@ -58,7 +58,6 @@ public class JmsListenerAnnotationBeanPostProcessorTests {
MethodJmsListenerEndpoint methodEndpoint = (MethodJmsListenerEndpoint) endpoint;
assertNotNull(methodEndpoint.getBean());
assertNotNull(methodEndpoint.getMethod());
assertNull(methodEndpoint.getResponseDestination());
assertTrue(methodEndpoint.isQueue());
assertTrue("Should have been started " + container, container.isStarted());

View File

@@ -27,6 +27,7 @@ import java.util.HashMap;
import java.util.Map;
import javax.jms.Destination;
import javax.jms.InvalidDestinationException;
import javax.jms.JMSException;
import javax.jms.ObjectMessage;
import javax.jms.QueueSender;
@@ -48,12 +49,14 @@ import org.springframework.jms.listener.adapter.ListenerExecutionFailedException
import org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter;
import org.springframework.jms.support.JmsMessageHeaderAccessor;
import org.springframework.jms.support.converter.JmsHeaders;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.converter.MessageConversionException;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.handler.annotation.support.MethodArgumentTypeMismatchException;
import org.springframework.util.ReflectionUtils;
import org.springframework.validation.Errors;
@@ -99,7 +102,6 @@ public class MethodJmsListenerEndpointTests {
endpoint.setBean(this);
endpoint.setMethod(getTestMethod());
endpoint.setJmsHandlerMethodFactory(factory);
endpoint.setResponseDestination("myResponseQueue");
assertNotNull(endpoint.createMessageListener(container));
}
@@ -217,6 +219,56 @@ public class MethodJmsListenerEndpointTests {
verify(queueSender).close();
}
@Test
public void processAndReplyWithSendTo() throws JMSException {
MessagingMessageListenerAdapter listener = createDefaultInstance(String.class);
String body = "echo text";
String correlationId = "link-1234";
Destination replyDestination = new Destination() {};
DestinationResolver destinationResolver = mock(DestinationResolver.class);
TextMessage reply = mock(TextMessage.class);
QueueSender queueSender = mock(QueueSender.class);
Session session = mock(Session.class);
given(destinationResolver.resolveDestinationName(session, "replyDestination", false))
.willReturn(replyDestination);
given(session.createTextMessage(body)).willReturn(reply);
given(session.createProducer(replyDestination)).willReturn(queueSender);
listener.setDestinationResolver(destinationResolver);
StubTextMessage inputMessage = createSimpleJmsTextMessage(body);
inputMessage.setJMSCorrelationID(correlationId);
listener.onMessage(inputMessage, session);
assertDefaultListenerMethodInvocation();
verify(destinationResolver).resolveDestinationName(session, "replyDestination", false);
verify(reply).setJMSCorrelationID(correlationId);
verify(queueSender).send(reply);
verify(queueSender).close();
}
@Test
public void emptySendTo() throws JMSException {
MessagingMessageListenerAdapter listener = createDefaultInstance(String.class);
TextMessage reply = mock(TextMessage.class);
Session session = mock(Session.class);
given(session.createTextMessage("content")).willReturn(reply);
thrown.expect(ListenerExecutionFailedException.class);
thrown.expectCause(Matchers.isA(InvalidDestinationException.class));
listener.onMessage(createSimpleJmsTextMessage("content"), session);
}
@Test
public void invalidSendTo() {
thrown.expect(IllegalStateException.class);
thrown.expectMessage("firstDestination");
thrown.expectMessage("secondDestination");
createDefaultInstance(String.class);
}
@Test
public void validatePayloadValid() throws JMSException {
String methodName = "validatePayload";
@@ -394,6 +446,24 @@ public class MethodJmsListenerEndpointTests {
return content;
}
@SendTo("replyDestination")
public String processAndReplyWithSendTo(String content) {
invocations.put("processAndReplyWithSendTo", true);
return content;
}
@SendTo("")
public String emptySendTo(String content) {
invocations.put("emptySendTo", true);
return content;
}
@SendTo({"firstDestination", "secondDestination"})
public String invalidSendTo(String content) {
invocations.put("invalidSendTo", true);
return content;
}
public void validatePayload(@Validated String payload) {
invocations.put("validatePayload", true);
}

View File

@@ -65,9 +65,12 @@ public class JmsMessageHeaderAccessorTests {
assertEquals("abcd-1234", headerAccessor.getMessageId());
assertEquals(Integer.valueOf(9), headerAccessor.getPriority());
assertEquals(replyTo, headerAccessor.getReplyTo());
assertEquals(replyTo, headerAccessor.getReplyChannel());
assertEquals(true, headerAccessor.getRedelivered());
assertEquals("type", headerAccessor.getType());
assertEquals(4567L, headerAccessor.getTimestamp(), 0.0);
// Making sure replyChannel is not mixed with replyTo
assertNull(headerAccessor.getReplyChannel());
}
}