Skip to content

Commit 3f390d5

Browse files
pisekjhoeller
authored andcommitted
Add overloaded sendAndReceive methods to JmsOperations and JmsTemplate to use explicit response queue
Signed-off-by: Michał Pisarski <pisekfm@o2.pl>
1 parent 2b96a61 commit 3f390d5

3 files changed

Lines changed: 129 additions & 6 deletions

File tree

spring-jms/src/main/java/org/springframework/jms/core/JmsOperations.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,36 @@ void convertAndSend(String destinationName, Object message, MessagePostProcessor
401401
*/
402402
@Nullable Message sendAndReceive(String destinationName, MessageCreator messageCreator) throws JmsException;
403403

404+
/**
405+
* Send a message and receive the reply from the specified destination. The
406+
* {@link MessageCreator} callback creates the message given a Session. A given
407+
* responseQueue is set in the {@code JMSReplyTO} header of the message.
408+
* @param destination the destination to send this message to
409+
* @param responseQueue the destination to receive the reply from
410+
* @param messageCreator callback to create a message
411+
* @return the reply, possibly {@code null} if the message could not be received,
412+
* for example due to a timeout
413+
* @throws JmsException checked JMSException converted to unchecked
414+
* @since 7.0.4
415+
*/
416+
@Nullable Message sendAndReceive(Destination destination, Destination responseQueue, MessageCreator messageCreator) throws JmsException;
417+
418+
/**
419+
* Send a message and receive the reply from the specified destination. The
420+
* {@link MessageCreator} callback creates the message given a Session. A given
421+
* responseQueue is set in the {@code JMSReplyTO} header of the message.
422+
* @param destinationName the name of the destination to send this message to
423+
* (to be resolved to an actual destination by a DestinationResolver)
424+
* @param responseQueueName the name of the destination to receive the reply from
425+
* (to be resolved to an actual destination by a DestinationResolver)
426+
* @param messageCreator callback to create a message
427+
* @return the reply, possibly {@code null} if the message could not be received,
428+
* for example due to a timeout
429+
* @throws JmsException checked JMSException converted to unchecked
430+
* @since 7.0.4
431+
*/
432+
@Nullable Message sendAndReceive(String destinationName, String responseQueueName, MessageCreator messageCreator) throws JmsException;
433+
404434

405435
//---------------------------------------------------------------------------------------
406436
// Convenience methods for browsing messages

spring-jms/src/main/java/org/springframework/jms/core/JmsTemplate.java

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,11 @@ else if (isClientAcknowledge(session)) {
898898
return executeLocal(session -> doSendAndReceive(session, destination, messageCreator), true);
899899
}
900900

901+
@Override
902+
public @Nullable Message sendAndReceive(Destination destination, Destination responseQueue, MessageCreator messageCreator) throws JmsException {
903+
return executeLocal(session -> doSendAndReceive(session, destination, responseQueue, messageCreator), true);
904+
}
905+
901906
@Override
902907
public @Nullable Message sendAndReceive(String destinationName, MessageCreator messageCreator) throws JmsException {
903908
return executeLocal(session -> {
@@ -906,22 +911,50 @@ else if (isClientAcknowledge(session)) {
906911
}, true);
907912
}
908913

914+
@Override
915+
public @Nullable Message sendAndReceive(String destinationName, String responseQueueName, MessageCreator messageCreator) throws JmsException {
916+
return executeLocal(session -> {
917+
Destination destination = resolveDestinationName(session, destinationName);
918+
Destination responseQueue = resolveDestinationName(session, responseQueueName);
919+
return doSendAndReceive(session, destination, responseQueue, messageCreator);
920+
}, true);
921+
}
922+
909923
/**
910-
* Send a request message to the given {@link Destination} and block until
924+
* Send a request message to the given {@link Destination destination} and block until
911925
* a reply has been received on a temporary queue created on-the-fly.
912926
* <p>Return the response message or {@code null} if no message has
913927
* @throws JMSException if thrown by JMS API methods
914928
*/
915929
protected @Nullable Message doSendAndReceive(Session session, Destination destination, MessageCreator messageCreator)
916930
throws JMSException {
917931

918-
Assert.notNull(messageCreator, "MessageCreator must not be null");
919932
TemporaryQueue responseQueue = null;
933+
try {
934+
responseQueue = session.createTemporaryQueue();
935+
return doSendAndReceive(session, destination, responseQueue, messageCreator);
936+
}
937+
finally {
938+
if (responseQueue != null) {
939+
responseQueue.delete();
940+
}
941+
}
942+
}
943+
944+
/**
945+
* Send a request message to the given {@link Destination destination} and block until
946+
* a reply has been received on a {@link Destination responseQueue} queue.
947+
* <p>Return the response message or {@code null} if no message has
948+
* @throws JMSException if thrown by JMS API methods
949+
*/
950+
protected @Nullable Message doSendAndReceive(Session session, Destination destination, Destination responseQueue, MessageCreator messageCreator)
951+
throws JMSException {
952+
953+
Assert.notNull(messageCreator, "MessageCreator must not be null");
920954
MessageProducer producer = null;
921955
MessageConsumer consumer = null;
922956
try {
923957
Message requestMessage = messageCreator.createMessage(session);
924-
responseQueue = session.createTemporaryQueue();
925958
producer = session.createProducer(destination);
926959
consumer = session.createConsumer(responseQueue);
927960
requestMessage.setJMSReplyTo(responseQueue);
@@ -934,9 +967,6 @@ else if (isClientAcknowledge(session)) {
934967
finally {
935968
JmsUtils.closeMessageConsumer(consumer);
936969
JmsUtils.closeMessageProducer(producer);
937-
if (responseQueue != null) {
938-
responseQueue.delete();
939-
}
940970
}
941971
}
942972

spring-jms/src/test/java/org/springframework/jms/core/JmsTemplateTests.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,69 @@ else if (explicitDestination) {
687687
verify(messageProducer).close();
688688
}
689689

690+
@Test
691+
void testSendAndReceiveDestinationWithResponseQueue() throws Exception {
692+
doTestSendAndReceiveWithResponseQueue(true, 1000L);
693+
}
694+
695+
@Test
696+
void testSendAndReceiveDestinationNameWithResponseQueueName() throws Exception {
697+
doTestSendAndReceiveWithResponseQueue(false, 1000L);
698+
}
699+
700+
private void doTestSendAndReceiveWithResponseQueue(boolean explicitDestination, long timeout)
701+
throws Exception {
702+
703+
JmsTemplate template = createTemplate();
704+
template.setConnectionFactory(this.connectionFactory);
705+
template.setReceiveTimeout(timeout);
706+
707+
String destinationName = "testDestination";
708+
String responseQueueName = "responseQueue";
709+
710+
Queue responseQueue = mock();
711+
given(this.jndiContext.lookup(responseQueueName)).willReturn(responseQueue);
712+
713+
Session localSession = getLocalSession();
714+
MessageProducer messageProducer = mock();
715+
given(localSession.createProducer(this.queue)).willReturn(messageProducer);
716+
717+
MessageConsumer messageConsumer = mock();
718+
given(localSession.createConsumer(responseQueue)).willReturn(messageConsumer);
719+
720+
TextMessage request = mock();
721+
MessageCreator messageCreator = mock();
722+
given(messageCreator.createMessage(localSession)).willReturn(request);
723+
724+
TextMessage reply = mock();
725+
if (timeout == JmsTemplate.RECEIVE_TIMEOUT_NO_WAIT) {
726+
given(messageConsumer.receiveNoWait()).willReturn(reply);
727+
}
728+
else if (timeout == JmsTemplate.RECEIVE_TIMEOUT_INDEFINITE_WAIT) {
729+
given(messageConsumer.receive()).willReturn(reply);
730+
}
731+
else {
732+
given(messageConsumer.receive(timeout)).willReturn(reply);
733+
}
734+
735+
Message message;
736+
if (explicitDestination) {
737+
message = template.sendAndReceive(this.queue, responseQueue, messageCreator);
738+
}
739+
else {
740+
message = template.sendAndReceive(destinationName, responseQueueName, messageCreator);
741+
}
742+
743+
// replyTO set on the request
744+
verify(request).setJMSReplyTo(responseQueue);
745+
assertThat(message).as("Reply message not received").isSameAs(reply);
746+
verify(this.connection).start();
747+
verify(this.connection).close();
748+
verify(localSession).close();
749+
verify(messageConsumer).close();
750+
verify(messageProducer).close();
751+
}
752+
690753
@Test
691754
void testIllegalStateException() throws Exception {
692755
doTestJmsException(new jakarta.jms.IllegalStateException(""), org.springframework.jms.IllegalStateException.class);

0 commit comments

Comments
 (0)