Jms request/reply operations

This commit updates JmsMessagingTemplate to support the
MessageRequestReplyOperation interface that provides synchronous
request/reply operations.

As JmsMessagingTemplate delegates everything under the scenes to
JmsTemplate, the latter has been updated as well to offer such lower
level operation.

Issue: SPR-12037
This commit is contained in:
Stephane Nicoll
2014-07-28 15:22:31 +02:00
parent c89325b9ca
commit b6389a6c66
9 changed files with 557 additions and 46 deletions

View File

@@ -337,10 +337,120 @@ public class JmsMessagingTemplateTests {
assertNull(messagingTemplate.receiveAndConvert("myQueue", String.class));
}
@Test
public void sendAndReceive() {
Destination destination = new Destination() {};
Message<String> request = createTextMessage();
javax.jms.Message replyJmsMessage = createJmsTextMessage();
given(jmsTemplate.sendAndReceive(eq(destination), anyObject())).willReturn(replyJmsMessage);
Message<?> actual = messagingTemplate.sendAndReceive(destination, request);
verify(jmsTemplate, times(1)).sendAndReceive(eq(destination), anyObject());
assertTextMessage(actual);
}
@Test
public void sendAndReceiveName() {
Message<String> request = createTextMessage();
javax.jms.Message replyJmsMessage = createJmsTextMessage();
given(jmsTemplate.sendAndReceive(eq("myQueue"), anyObject())).willReturn(replyJmsMessage);
Message<?> actual = messagingTemplate.sendAndReceive("myQueue", request);
verify(jmsTemplate, times(1)).sendAndReceive(eq("myQueue"), anyObject());
assertTextMessage(actual);
}
@Test
public void sendAndReceiveDefaultDestination() {
Destination destination = new Destination() {};
messagingTemplate.setDefaultDestination(destination);
Message<String> request = createTextMessage();
javax.jms.Message replyJmsMessage = createJmsTextMessage();
given(jmsTemplate.sendAndReceive(eq(destination), anyObject())).willReturn(replyJmsMessage);
Message<?> actual = messagingTemplate.sendAndReceive(request);
verify(jmsTemplate, times(1)).sendAndReceive(eq(destination), anyObject());
assertTextMessage(actual);
}
@Test
public void sendAndReceiveDefaultDestinationName() {
messagingTemplate.setDefaultDestinationName("myQueue");
Message<String> request = createTextMessage();
javax.jms.Message replyJmsMessage = createJmsTextMessage();
given(jmsTemplate.sendAndReceive(eq("myQueue"), anyObject())).willReturn(replyJmsMessage);
Message<?> actual = messagingTemplate.sendAndReceive(request);
verify(jmsTemplate, times(1)).sendAndReceive(eq("myQueue"), anyObject());
assertTextMessage(actual);
}
@Test
public void sendAndReceiveNoDefaultSet() {
Message<String> message = createTextMessage();
thrown.expect(IllegalStateException.class);
messagingTemplate.sendAndReceive(message);
}
@Test
public void convertSendAndReceivePayload() throws JMSException {
Destination destination = new Destination() {};
javax.jms.Message replyJmsMessage = createJmsTextMessage("My reply");
given(jmsTemplate.sendAndReceive(eq(destination), anyObject())).willReturn(replyJmsMessage);
String reply = messagingTemplate.convertSendAndReceive(destination, "my Payload", String.class);
verify(jmsTemplate, times(1)).sendAndReceive(eq(destination), anyObject());
assertEquals("My reply", reply);
}
@Test
public void convertSendAndReceivePayloadName() throws JMSException {
javax.jms.Message replyJmsMessage = createJmsTextMessage("My reply");
given(jmsTemplate.sendAndReceive(eq("myQueue"), anyObject())).willReturn(replyJmsMessage);
String reply = messagingTemplate.convertSendAndReceive("myQueue", "my Payload", String.class);
verify(jmsTemplate, times(1)).sendAndReceive(eq("myQueue"), anyObject());
assertEquals("My reply", reply);
}
@Test
public void convertSendAndReceiveDefaultDestination() throws JMSException {
Destination destination = new Destination() {};
messagingTemplate.setDefaultDestination(destination);
javax.jms.Message replyJmsMessage = createJmsTextMessage("My reply");
given(jmsTemplate.sendAndReceive(eq(destination), anyObject())).willReturn(replyJmsMessage);
String reply = messagingTemplate.convertSendAndReceive("my Payload", String.class);
verify(jmsTemplate, times(1)).sendAndReceive(eq(destination), anyObject());
assertEquals("My reply", reply);
}
@Test
public void convertSendAndReceiveDefaultDestinationName() throws JMSException {
messagingTemplate.setDefaultDestinationName("myQueue");
javax.jms.Message replyJmsMessage = createJmsTextMessage("My reply");
given(jmsTemplate.sendAndReceive(eq("myQueue"), anyObject())).willReturn(replyJmsMessage);
String reply = messagingTemplate.convertSendAndReceive("my Payload", String.class);
verify(jmsTemplate, times(1)).sendAndReceive(eq("myQueue"), anyObject());
assertEquals("My reply", reply);
}
@Test
public void convertSendAndReceiveNoDefaultSet() throws JMSException {
thrown.expect(IllegalStateException.class);
messagingTemplate.convertSendAndReceive("my Payload", String.class);
}
private Message<String> createTextMessage(String payload) {
return MessageBuilder
.withPayload(payload).setHeader("foo", "bar").build();
}
private Message<String> createTextMessage() {
return MessageBuilder
.withPayload("Hello").setHeader("foo", "bar").build();
return createTextMessage("Hello");
}
private javax.jms.Message createJmsTextMessage(String payload) {

View File

@@ -30,6 +30,7 @@ import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TemporaryQueue;
import javax.jms.TextMessage;
import javax.naming.Context;
@@ -66,12 +67,13 @@ import static org.mockito.BDDMockito.*;
*
* @author Andre Biryukov
* @author Mark Pollack
* @author Stephane Nicoll
*/
public class JmsTemplateTests {
private Context jndiContext;
private ConnectionFactory connectionFactory;
private Connection connection;
protected Connection connection;
private Session session;
private Destination queue;
@@ -120,6 +122,9 @@ public class JmsTemplateTests {
return false;
}
protected Session getLocalSession() {
return session;
}
@Test
public void testExceptionStackTrace() {
@@ -630,6 +635,89 @@ public class JmsTemplateTests {
verify(messageConsumer).close();
}
@Test
public void testSendAndReceiveDefaultDestination() throws Exception {
doTestSendAndReceive(true, true, 1000L);
}
@Test
public void testSendAndReceiveDefaultDestinationName() throws Exception {
doTestSendAndReceive(false, true, 1000L);
}
@Test
public void testSendAndReceiveDestination() throws Exception {
doTestSendAndReceive(true, false, 1000L);
}
@Test
public void testSendAndReceiveDestinationName() throws Exception {
doTestSendAndReceive(false, false, 1000L);
}
private void doTestSendAndReceive(boolean explicitDestination, boolean useDefaultDestination, long timeout)
throws Exception {
JmsTemplate template = createTemplate();
template.setConnectionFactory(connectionFactory);
String destinationName = "testDestination";
if (useDefaultDestination) {
if (explicitDestination) {
template.setDefaultDestination(queue);
}
else {
template.setDefaultDestinationName(destinationName);
}
}
template.setReceiveTimeout(timeout);
Session localSession = getLocalSession();
TemporaryQueue replyDestination = mock(TemporaryQueue.class);
MessageProducer messageProducer = mock(MessageProducer.class);
given(localSession.createProducer(queue)).willReturn(messageProducer);
given(localSession.createTemporaryQueue()).willReturn(replyDestination);
MessageConsumer messageConsumer = mock(MessageConsumer.class);
given(localSession.createConsumer(replyDestination)).willReturn(messageConsumer);
TextMessage request = mock(TextMessage.class);
MessageCreator messageCreator = mock(MessageCreator.class);
given(messageCreator.createMessage(localSession)).willReturn(request);
TextMessage reply = mock(TextMessage.class);
if (timeout == JmsTemplate.RECEIVE_TIMEOUT_NO_WAIT) {
given(messageConsumer.receiveNoWait()).willReturn(reply);
}
else if (timeout == JmsTemplate.RECEIVE_TIMEOUT_INDEFINITE_WAIT) {
given(messageConsumer.receive()).willReturn(reply);
}
else {
given(messageConsumer.receive(timeout)).willReturn(reply);
}
Message message = null;
if (useDefaultDestination) {
message = template.sendAndReceive(messageCreator);
}
else if (explicitDestination) {
message = template.sendAndReceive(queue, messageCreator);
}
else {
message = template.sendAndReceive(destinationName, messageCreator);
}
// replyTO set on the request
verify(request).setJMSReplyTo(replyDestination);
assertSame("Reply message not received", reply, message);
verify(connection).start();
verify(connection).close();
verify(localSession).close();
verify(messageConsumer).close();
verify(messageProducer).close();
}
@Test
public void testIllegalStateException() throws Exception {
doTestJmsException(new javax.jms.IllegalStateException(""), org.springframework.jms.IllegalStateException.class);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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.
@@ -16,12 +16,33 @@
package org.springframework.jms.core;
import javax.jms.Session;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* @author Juergen Hoeller
* @author Stephane Nicoll
* @since 06.01.2005
*/
public class JmsTemplateTransactedTests extends JmsTemplateTests {
private Session localSession;
@Override
public void setupMocks() throws Exception {
super.setupMocks();
this.localSession = mock(Session.class);
given(this.connection.createSession(false,
Session.AUTO_ACKNOWLEDGE)).willReturn(this.localSession);
}
@Override
protected Session getLocalSession() {
return this.localSession;
}
@Override
protected boolean useTransactedSession() {
return true;