Support custom resolution of response destination

Previously, the "pubSubDomain" drove the resolution of both the
destination of the listener and the default response destination.

A new "replyPubSubDomain" attribute has been added on the base listener
and  can be used to listen on a topic and reply to a queue (or vice
versa). The attribute is exposed via the "response-destination-type" XML
attribute on the listener container element. It is also available on the
JmsListenerContainerFactory for use with the @JmsListener infrastructure.

Issue: SPR-12911
This commit is contained in:
Stephane Nicoll
2015-04-16 17:29:48 +02:00
parent e403aefe86
commit 2c7d2d38a9
16 changed files with 835 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -155,6 +155,7 @@ public class JmsListenerContainerFactoryTests {
factory.setSessionTransacted(true);
factory.setSessionAcknowledgeMode(Session.DUPS_OK_ACKNOWLEDGE);
factory.setPubSubDomain(true);
factory.setReplyPubSubDomain(true);
factory.setSubscriptionDurable(true);
factory.setClientId("client-1234");
factory.setAutoStartup(false);
@@ -167,6 +168,7 @@ public class JmsListenerContainerFactoryTests {
assertEquals(true, container.isSessionTransacted());
assertEquals(Session.DUPS_OK_ACKNOWLEDGE, container.getSessionAcknowledgeMode());
assertEquals(true, container.isPubSubDomain());
assertEquals(true, container.isReplyPubSubDomain());
assertEquals(true, container.isSubscriptionDurable());
assertEquals("client-1234", container.getClientId());
assertEquals(false, container.isAutoStartup());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -152,6 +152,8 @@ public class JmsNamespaceHandlerTests {
context.getBean("testDestinationResolver"), container.getDestinationResolver());
assertEquals("explicit message converter not set",
context.getBean("testMessageConverter"), container.getMessageConverter());
assertEquals("Wrong pub/sub", true, container.isPubSubDomain());
assertEquals("Wrong durable flag", true, container.isSubscriptionDurable());
assertEquals("wrong cache", DefaultMessageListenerContainer.CACHE_CONNECTION, container.getCacheLevel());
assertEquals("wrong concurrency", 3, container.getConcurrentConsumers());
assertEquals("wrong concurrency", 5, container.getMaxConcurrentConsumers());
@@ -173,6 +175,7 @@ public class JmsNamespaceHandlerTests {
context.getBean("testResourceAdapter"),container.getResourceAdapter());
assertEquals("explicit message converter not set",
context.getBean("testMessageConverter"), container.getActivationSpecConfig().getMessageConverter());
assertEquals("Wrong pub/sub", true, container.isPubSubDomain());
assertEquals("wrong concurrency", 5, container.getActivationSpecConfig().getMaxConcurrency());
assertEquals("Wrong prefetch", 50, container.getActivationSpecConfig().getPrefetchSize());
assertEquals("Wrong phase", 77, container.getPhase());
@@ -249,6 +252,29 @@ public class JmsNamespaceHandlerTests {
listener4.getActivationSpecConfig().getMaxConcurrency());
}
@Test
public void testResponseDestination() {
// JMS
DefaultMessageListenerContainer listener1 = this.context
.getBean("listener1", DefaultMessageListenerContainer.class);
DefaultMessageListenerContainer listener2 = this.context
.getBean("listener2", DefaultMessageListenerContainer.class);
assertEquals("Wrong destination type on listener1", true, listener1.isPubSubDomain());
assertEquals("Wrong destination type on listener2", true, listener2.isPubSubDomain());
assertEquals("Wrong response destination type on listener1", false, listener1.isReplyPubSubDomain());
assertEquals("Wrong response destination type on listener2", false, listener2.isReplyPubSubDomain());
// JCA
JmsMessageEndpointManager listener3 = this.context
.getBean("listener3", JmsMessageEndpointManager.class);
JmsMessageEndpointManager listener4 = this.context
.getBean("listener4", JmsMessageEndpointManager.class);
assertEquals("Wrong destination type on listener3", true, listener3.isPubSubDomain());
assertEquals("Wrong destination type on listener4", true, listener4.isPubSubDomain());
assertEquals("Wrong response destination type on listener3", false, listener3.isReplyPubSubDomain());
assertEquals("Wrong response destination type on listener4", false, listener4.isReplyPubSubDomain());
}
@Test
public void testErrorHandlers() {
ErrorHandler expected = this.context.getBean("testErrorHandler", ErrorHandler.class);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -108,6 +108,11 @@ public class MessageListenerTestContainer
return true;
}
@Override
public boolean isReplyPubSubDomain() {
return isPubSubDomain();
}
@Override
public void afterPropertiesSet() {
initializationInvoked = true;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -241,6 +241,18 @@ public class MethodJmsListenerEndpointTests {
assertListenerMethodInvocation(sample, methodName);
}
@Test
public void processFromTopicAndReplyWithSendToQueue() throws JMSException {
String methodName = "processAndReplyWithSendTo";
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setPubSubDomain(true);
container.setReplyPubSubDomain(false);
MessagingMessageListenerAdapter listener = createInstance(this.factory,
getListenerMethod(methodName, String.class), container);
processAndReplyWithSendTo(listener, false);
assertListenerMethodInvocation(sample, methodName);
}
@Test
public void processAndReplyWithSendToTopic() throws JMSException {
String methodName = "processAndReplyWithSendTo";
@@ -252,6 +264,17 @@ public class MethodJmsListenerEndpointTests {
assertListenerMethodInvocation(sample, methodName);
}
@Test
public void processFromQueueAndReplyWithSendToTopic() throws JMSException {
String methodName = "processAndReplyWithSendTo";
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setReplyPubSubDomain(true);
MessagingMessageListenerAdapter listener = createInstance(this.factory,
getListenerMethod(methodName, String.class), container);
processAndReplyWithSendTo(listener, true);
assertListenerMethodInvocation(sample, methodName);
}
private void processAndReplyWithSendTo(MessagingMessageListenerAdapter listener, boolean pubSubDomain) throws JMSException {
String body = "echo text";
String correlationId = "link-1234";

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -37,6 +37,7 @@ public class JmsMessageEndpointManagerTests {
config.setPubSubDomain(false);
endpoint.setActivationSpecConfig(config);
assertEquals(false, endpoint.isPubSubDomain());
assertEquals(false, endpoint.isReplyPubSubDomain());
}
@Test
@@ -46,6 +47,18 @@ public class JmsMessageEndpointManagerTests {
config.setPubSubDomain(true);
endpoint.setActivationSpecConfig(config);
assertEquals(true, endpoint.isPubSubDomain());
assertEquals(true, endpoint.isReplyPubSubDomain());
}
@Test
public void pubSubDomainCustomForReply() {
JmsMessageEndpointManager endpoint = new JmsMessageEndpointManager();
JmsActivationSpecConfig config = new JmsActivationSpecConfig();
config.setPubSubDomain(true);
config.setReplyPubSubDomain(false);
endpoint.setActivationSpecConfig(config);
assertEquals(true, endpoint.isPubSubDomain());
assertEquals(false, endpoint.isReplyPubSubDomain());
}
@Test
@@ -56,6 +69,14 @@ public class JmsMessageEndpointManagerTests {
endpoint.isPubSubDomain();
}
@Test
public void isReplyPubSubDomainWithNoConfig() {
JmsMessageEndpointManager endpoint = new JmsMessageEndpointManager();
thrown.expect(IllegalStateException.class); // far from ideal
endpoint.isReplyPubSubDomain();
}
@Test
public void getMessageConverterNoConfig() {
JmsMessageEndpointManager endpoint = new JmsMessageEndpointManager();