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
This commit is contained in:
committed by
Artem Bilan
parent
6782c5accb
commit
6b82463f58
@@ -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()}.
|
||||
*/
|
||||
|
||||
@@ -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<Object, ConnectionFactory> factories = new HashMap<Object, ConnectionFactory>(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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -469,6 +469,12 @@ trustStore.passPhrase=secret</programlisting>
|
||||
and <code>receive-connection-factory-selector-expression</code> attributes
|
||||
on the <code><rabbit:template></code> component.
|
||||
</para>
|
||||
<para>
|
||||
Also starting with <emphasis>version 1.4</emphasis>, you can configure a routing connection factory
|
||||
in a <classname>SimpleMessageListenerContainer</classname>. In that case, the list of queue names
|
||||
is used as the lookup key. For example, if you configure the container with
|
||||
<code>setQueueNames("foo, bar")</code>, the lookup key will be <code>"[foo,bar]"</code> (no spaces).
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="cf-pub-conf-ret">
|
||||
|
||||
@@ -112,6 +112,13 @@
|
||||
See <xref linkend="routing-connection-factory"/>.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<para>
|
||||
A <classname>SimpleMessageListenerContainer</classname> can be configured with a routing
|
||||
connection factory to enable connection selection based on the queue names.
|
||||
See <xref linkend="routing-connection-factory"/>.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>RabbitTemplate: RecoveryCallback option</title>
|
||||
<para>
|
||||
|
||||
Reference in New Issue
Block a user