From 6b82463f58d44f93bcd710fbba889583a9125e65 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Wed, 22 Oct 2014 16:06:22 -0400 Subject: [PATCH] AMQP-426 SMLC: Support Routing Connection Factory JIRA: https://jira.spring.io/browse/AMQP-436 Use the list of queue names as the lookup key. Polishing `testAbstractRoutingConnectionFactoryWithListenerContainer()` to reflect the dynamic usage --- .../AbstractMessageListenerContainer.java | 15 +++++++ .../RoutingConnectionFactoryTests.java | 44 +++++++++++++++++++ src/reference/docbook/amqp.xml | 6 +++ src/reference/docbook/whats-new.xml | 7 +++ 4 files changed, 72 insertions(+) diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/AbstractMessageListenerContainer.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/AbstractMessageListenerContainer.java index 9e91f69f..f16d65d3 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/AbstractMessageListenerContainer.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/AbstractMessageListenerContainer.java @@ -27,7 +27,9 @@ import org.springframework.amqp.core.AcknowledgeMode; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessageListener; import org.springframework.amqp.core.Queue; +import org.springframework.amqp.rabbit.connection.AbstractRoutingConnectionFactory; import org.springframework.amqp.rabbit.connection.Connection; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils; import org.springframework.amqp.rabbit.connection.RabbitAccessor; import org.springframework.amqp.rabbit.connection.RabbitResourceHolder; @@ -352,6 +354,19 @@ public abstract class AbstractMessageListenerContainer extends RabbitAccessor this.applicationContext = applicationContext; } + @Override + public ConnectionFactory getConnectionFactory() { + ConnectionFactory connectionFactory = super.getConnectionFactory(); + if (connectionFactory instanceof AbstractRoutingConnectionFactory) { + ConnectionFactory targetConnectionFactory = ((AbstractRoutingConnectionFactory) connectionFactory) + .getTargetConnectionFactory(this.queueNames.toString().replaceAll(" ", "")); + if (targetConnectionFactory != null) { + return targetConnectionFactory; + } + } + return connectionFactory; + } + /** * Delegates to {@link #validateConfiguration()} and {@link #initialize()}. */ diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/RoutingConnectionFactoryTests.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/RoutingConnectionFactoryTests.java index bb946a5e..ae3488ab 100644 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/RoutingConnectionFactoryTests.java +++ b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/RoutingConnectionFactoryTests.java @@ -16,6 +16,8 @@ package org.springframework.amqp.rabbit.connection; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import java.util.HashMap; import java.util.Map; @@ -28,6 +30,8 @@ import java.util.concurrent.atomic.AtomicInteger; import org.junit.Test; import org.mockito.Mockito; +import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; + /** * @author Artem Bilan * @author Josh Chappelle @@ -144,4 +148,44 @@ public class RoutingConnectionFactoryTests { Mockito.verify(targetConnectionFactory, Mockito.times(2)).addConnectionListener(Mockito.any(ConnectionListener.class)); } + + @Test + public void testAbstractRoutingConnectionFactoryWithListenerContainer() { + ConnectionFactory connectionFactory1 = mock(ConnectionFactory.class); + ConnectionFactory connectionFactory2 = mock(ConnectionFactory.class); + Map factories = new HashMap(2); + factories.put("[baz]", connectionFactory1); + factories.put("[foo,bar]", connectionFactory2); + ConnectionFactory defaultConnectionFactory = mock(ConnectionFactory.class); + + SimpleRoutingConnectionFactory connectionFactory = new SimpleRoutingConnectionFactory(); + + connectionFactory.setDefaultTargetConnectionFactory(defaultConnectionFactory); + connectionFactory.setTargetConnectionFactories(factories); + + SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory); + container.setQueueNames("foo, bar"); + container.afterPropertiesSet(); + container.start(); + + Mockito.verify(connectionFactory1, never()).createConnection(); + Mockito.verify(connectionFactory2).createConnection(); + Mockito.verify(defaultConnectionFactory, never()).createConnection(); + + Mockito.reset(connectionFactory1, connectionFactory2, defaultConnectionFactory); + container.setQueueNames("baz"); + Mockito.verify(connectionFactory1).createConnection(); + Mockito.verify(connectionFactory2, never()).createConnection(); + Mockito.verify(defaultConnectionFactory, never()).createConnection(); + + Mockito.reset(connectionFactory1, connectionFactory2, defaultConnectionFactory); + container.setQueueNames("qux"); + Mockito.verify(connectionFactory1, never()).createConnection(); + Mockito.verify(connectionFactory2, never()).createConnection(); + Mockito.verify(defaultConnectionFactory).createConnection(); + + container.stop(); + } + + } diff --git a/src/reference/docbook/amqp.xml b/src/reference/docbook/amqp.xml index 824849aa..33ddcd6e 100644 --- a/src/reference/docbook/amqp.xml +++ b/src/reference/docbook/amqp.xml @@ -469,6 +469,12 @@ trustStore.passPhrase=secret and receive-connection-factory-selector-expression attributes on the <rabbit:template> component. + + Also starting with version 1.4, you can configure a routing connection factory + in a SimpleMessageListenerContainer. In that case, the list of queue names + is used as the lookup key. For example, if you configure the container with + setQueueNames("foo, bar"), the lookup key will be "[foo,bar]" (no spaces). +
diff --git a/src/reference/docbook/whats-new.xml b/src/reference/docbook/whats-new.xml index 474f3363..1879795b 100644 --- a/src/reference/docbook/whats-new.xml +++ b/src/reference/docbook/whats-new.xml @@ -112,6 +112,13 @@ See .
+
+ + A SimpleMessageListenerContainer can be configured with a routing + connection factory to enable connection selection based on the queue names. + See . + +
RabbitTemplate: RecoveryCallback option