AMQP-118: removed template constructor from RabbitAdmin

This commit is contained in:
Dave Syer
2011-03-14 17:49:12 +00:00
parent f1d783cf5c
commit 5c4d13ca26
14 changed files with 58 additions and 208 deletions

View File

@@ -25,12 +25,10 @@ import org.w3c.dom.Element;
*/
class AdminParser extends AbstractSingleBeanDefinitionParser {
private static final String TEMPLATE_ATTRIBUTE = "template";
private static final String CONNECTION_FACTORY_ATTRIBUTE = "connection-factory";
private static final String PHASE_ATTRIBUTE = "phase";
private static final String AUTO_STARTUP_ATTRIBUTE = "auto-startup";
@Override
@@ -50,30 +48,15 @@ class AdminParser extends AbstractSingleBeanDefinitionParser {
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
boolean templateAttributeExist = element.getAttributeNode(TEMPLATE_ATTRIBUTE) != null;
boolean connectionFactoryAttributeExist = element.getAttributeNode(CONNECTION_FACTORY_ATTRIBUTE) != null;
// Only one of 'templateRef' or 'connectionFactoryRef' can be set.
if (templateAttributeExist && connectionFactoryAttributeExist) {
parserContext.getReaderContext().error(
"Either '" + TEMPLATE_ATTRIBUTE + "' or '" + CONNECTION_FACTORY_ATTRIBUTE
+ "' attribute must be set.", element);
}
String templateRef = element.getAttribute(TEMPLATE_ATTRIBUTE);
String connectionFactoryRef = element.getAttribute(CONNECTION_FACTORY_ATTRIBUTE);
// At least one of 'templateRef' or 'connectionFactoryRef' attribute must be set.
if (!StringUtils.hasText(templateRef) && !StringUtils.hasText(connectionFactoryRef)) {
parserContext.getReaderContext().error(
"One of '" + TEMPLATE_ATTRIBUTE + "' or '" + CONNECTION_FACTORY_ATTRIBUTE
+ "' attribute must be set.", element);
if (!StringUtils.hasText(connectionFactoryRef)) {
parserContext.getReaderContext().error("A '" + CONNECTION_FACTORY_ATTRIBUTE + "' attribute must be set.",
element);
}
if (StringUtils.hasText(templateRef)) {
// Use constructor with template parameter
builder.addConstructorArgReference(templateRef);
} else if (StringUtils.hasText(connectionFactoryRef)) {
if (StringUtils.hasText(connectionFactoryRef)) {
// Use constructor with connectionFactory parameter
builder.addConstructorArgReference(connectionFactoryRef);
}
@@ -83,7 +66,7 @@ class AdminParser extends AbstractSingleBeanDefinitionParser {
if (StringUtils.hasText(attributeValue)) {
builder.addPropertyValue("phase", attributeValue);
}
attributeValue = element.getAttribute(AUTO_STARTUP_ATTRIBUTE);
if (StringUtils.hasText(attributeValue)) {
builder.addPropertyValue("autoStartup", attributeValue);

View File

@@ -61,11 +61,6 @@ public class RabbitAdmin implements AmqpAdmin, ApplicationContextAware, SmartLif
this.rabbitTemplate = new RabbitTemplate(connectionFactory);
}
public RabbitAdmin(RabbitTemplate rabbitTemplate) {
Assert.notNull(rabbitTemplate, "RabbitTemplate must not be null");
this.rabbitTemplate = rabbitTemplate;
}
public void setAutoStartup(boolean autoStartup) {
this.autoStartup = autoStartup;
}

View File

@@ -551,20 +551,6 @@
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="template" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Reference to rabbit template. Either 'template' or 'connection-factory' attribute
can be set.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type
type="org.springframework.amqp.rabbit.core.RabbitTemplate" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="connection-factory" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[

View File

@@ -16,21 +16,12 @@ package org.springframework.amqp.rabbit.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.util.Arrays;
import java.util.Collection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Level;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.test.Log4jLevelAdjuster;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
@@ -41,12 +32,9 @@ import org.springframework.util.StringUtils;
* @author tomas.lukosius@opencredo.com
*
*/
@RunWith(Parameterized.class)
public final class AdminParserTests {
private static Log logger = LogFactory.getLog(AdminParserTests.class);
@Rule
public Log4jLevelAdjuster logLevels = new Log4jLevelAdjuster(Level.ERROR, AdminParserTests.class);
private static Log logger = LogFactory.getLog(AdminParserTests.class);
// Specifies if test case expects context to be valid or not: true - context expects to be valid.
private boolean validContext = true;
@@ -63,57 +51,22 @@ public final class AdminParserTests {
private boolean initialisedWithTemplate;
public AdminParserTests(int contextIndex, boolean validContext, String adminBeanName, int expectedPhase,
boolean expectedAutoStartup, boolean initialisedWithTemplate) {
super();
this.contextIndex = contextIndex;
this.validContext = validContext;
this.adminBeanName = adminBeanName;
this.expectedPhase = expectedPhase;
this.expectedAutoStartup = expectedAutoStartup;
this.initialisedWithTemplate = initialisedWithTemplate;
}
@Parameters
public static Collection<Object[]> data() {
Object[][] data = new Object[][] { //
params(0, true), // #0
params(1, false), // #1
params(2, false), // #2
params(3, false), // #3
params(4, false), // #4
params(5, true, "admin-test", 12, false, false), // #5
params(6, true, "admin-test", 12, false, true) // #6
};
return Arrays.asList(data);
}
private static Object[] params(int index, boolean validContext) {
return params(index, validContext, null, Integer.MIN_VALUE, true, false);
}
/**
*
* @param contextIndex The index of spring context. Context file name template:
* &lt;class-name&gt;-&lt;contextIndex&gt;-context.xml
* @param validContext <code>true</code> if spring-context is expected to be loaded without failures.
* @param adminBeanName The bean name of expected rabbit admin. If its not specified - rabbit admin will be
* retrieved by type.
* @param expectedPhase 'phase' expected in {@link RabbitAdmin}.
* @param expectedAutoStartup 'autoStartup' expected in {@link RabbitAdmin}.
* @param initialisedWithTemplat <code>true</code> if {@link RabbitAdmin} in spring-context initialized by passing
* {@link RabbitTemplate} as constructor parameter, <code>false</code> - initialized by passing
* {@link ConnectionFactory} as constructor parameter.
* @return
*/
private static Object[] params(int contextIndex, boolean validContext, String adminBeanName, int expectedPhase,
boolean expectedAutoStartup, boolean initialisedWithTemplat) {
return new Object[] { contextIndex, validContext, adminBeanName, expectedPhase, expectedAutoStartup,
initialisedWithTemplat };
@Test
public void testInvalid() throws Exception {
contextIndex = 1;
validContext = false;
doTest();
}
@Test
public void testParse() throws Exception {
public void testValid() throws Exception {
contextIndex = 2;
validContext = true;
expectedPhase = 12;
doTest();
}
private void doTest() throws Exception {
// Create context
XmlBeanFactory beanFactory = loadContext();
if (beanFactory == null) {

View File

@@ -44,7 +44,7 @@ public class CachingConnectionFactoryIntegrationTests {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
RabbitAdmin admin = new RabbitAdmin(template);
RabbitAdmin admin = new RabbitAdmin(connectionFactory);
Queue queue = admin.declareQueue();
template.convertAndSend(queue.getName(), "message");
String result = (String) template.receiveAndConvert(queue.getName());
@@ -57,7 +57,7 @@ public class CachingConnectionFactoryIntegrationTests {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
RabbitAdmin admin = new RabbitAdmin(template);
RabbitAdmin admin = new RabbitAdmin(connectionFactory);
Queue queue = admin.declareQueue();
template.convertAndSend(queue.getName(), "message");
@@ -80,7 +80,7 @@ public class CachingConnectionFactoryIntegrationTests {
RabbitTemplate template2 = new RabbitTemplate(connectionFactory);
template1.setChannelTransacted(true);
RabbitAdmin admin = new RabbitAdmin(template1);
RabbitAdmin admin = new RabbitAdmin(connectionFactory);
Queue queue = admin.declareQueue();
template1.convertAndSend(queue.getName(), "message");

View File

@@ -3,14 +3,15 @@ package org.springframework.amqp.rabbit.core;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
public class RabbitAdminTests {
@Test
public void testSettingOfNullRabbitTemplate() {
RabbitTemplate rabbitTemplate = null;
ConnectionFactory connectionFactory = null;
try {
new RabbitAdmin(rabbitTemplate);
new RabbitAdmin(connectionFactory);
fail("should have thrown IllegalStateException when RabbitTemplate is not set.");
}
catch (IllegalArgumentException e) {

View File

@@ -12,6 +12,7 @@ import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.BlockingQueueConsumer;
import org.springframework.amqp.rabbit.support.RabbitAccessor;
import org.springframework.amqp.rabbit.test.BrokerRunning;
@@ -23,7 +24,9 @@ public class RabbitBindingIntegrationTests {
private static Queue queue = new Queue("test.queue");
private RabbitTemplate template = new RabbitTemplate(new CachingConnectionFactory());
private ConnectionFactory connectionFactory = new CachingConnectionFactory();
private RabbitTemplate template = new RabbitTemplate(connectionFactory );
@Rule
public BrokerRunning brokerIsRunning = BrokerRunning.isRunningWithEmptyQueue(queue);
@@ -31,7 +34,7 @@ public class RabbitBindingIntegrationTests {
@Test
public void testSendAndReceiveWithTopicSingleCallback() throws Exception {
final RabbitAdmin admin = new RabbitAdmin(template);
final RabbitAdmin admin = new RabbitAdmin(connectionFactory);
final TopicExchange exchange = new TopicExchange("topic");
admin.declareExchange(exchange);
template.setExchange(exchange.getName());
@@ -71,7 +74,7 @@ public class RabbitBindingIntegrationTests {
@Test
public void testSendAndReceiveWithNonDefaultExchange() throws Exception {
final RabbitAdmin admin = new RabbitAdmin(template);
final RabbitAdmin admin = new RabbitAdmin(connectionFactory);
final TopicExchange exchange = new TopicExchange("topic");
admin.declareExchange(exchange);
@@ -110,7 +113,7 @@ public class RabbitBindingIntegrationTests {
// @Ignore("Not sure yet if we need to support a use case like this")
public void testSendAndReceiveWithTopicConsumeInBackground() throws Exception {
RabbitAdmin admin = new RabbitAdmin(template);
RabbitAdmin admin = new RabbitAdmin(connectionFactory);
TopicExchange exchange = new TopicExchange("topic");
admin.declareExchange(exchange);
template.setExchange(exchange.getName());
@@ -147,7 +150,7 @@ public class RabbitBindingIntegrationTests {
@Test
public void testSendAndReceiveWithTopicTwoCallbacks() throws Exception {
RabbitAdmin admin = new RabbitAdmin(template);
RabbitAdmin admin = new RabbitAdmin(connectionFactory);
TopicExchange exchange = new TopicExchange("topic");
admin.declareExchange(exchange);
template.setExchange(exchange.getName());
@@ -199,7 +202,7 @@ public class RabbitBindingIntegrationTests {
@Test
public void testSendAndReceiveWithFanout() throws Exception {
RabbitAdmin admin = new RabbitAdmin(template);
RabbitAdmin admin = new RabbitAdmin(connectionFactory);
FanoutExchange exchange = new FanoutExchange("fanout");
admin.declareExchange(exchange);
template.setExchange(exchange.getName());

View File

@@ -17,7 +17,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.amqp.AmqpIllegalStateException;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.Queue;
@@ -138,16 +137,6 @@ public class MessageListenerBrokerInterruptionIntegrationTests {
}
@Test(expected=AmqpIllegalStateException.class)
public void testListenerDoesNotRecoverFromMissingQueue() throws Exception {
CountDownLatch latch = new CountDownLatch(messageCount);
container = createContainer("nonexistent", new VanillaListener(latch), connectionFactory);
brokerAdmin.stopBrokerApplication();
}
private SimpleMessageListenerContainer createContainer(String queueName, Object listener,
ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);

View File

@@ -14,6 +14,7 @@ import org.apache.log4j.Level;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.amqp.AmqpIllegalStateException;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.Queue;
@@ -23,6 +24,7 @@ import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionProxy;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.MessageListenerBrokerInterruptionIntegrationTests.VanillaListener;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.rabbit.test.BrokerRunning;
import org.springframework.amqp.rabbit.test.BrokerTestUtils;
@@ -80,7 +82,7 @@ public class MessageListenerRecoveryCachingConnectionIntegrationTests {
acknowledgeMode = AcknowledgeMode.MANUAL;
CountDownLatch latch = new CountDownLatch(messageCount);
container = createContainer(new ManualAckListener(latch), createConnectionFactory());
container = createContainer(queue.getName(), new ManualAckListener(latch), createConnectionFactory());
for (int i = 0; i < messageCount; i++) {
template.convertAndSend(queue.getName(), i + "foo");
}
@@ -100,7 +102,7 @@ public class MessageListenerRecoveryCachingConnectionIntegrationTests {
RabbitTemplate template = new RabbitTemplate(createConnectionFactory());
CountDownLatch latch = new CountDownLatch(messageCount);
container = createContainer(new AbortChannelListener(latch), createConnectionFactory());
container = createContainer(queue.getName(), new AbortChannelListener(latch), createConnectionFactory());
for (int i = 0; i < messageCount; i++) {
template.convertAndSend(queue.getName(), i + "foo");
}
@@ -120,7 +122,7 @@ public class MessageListenerRecoveryCachingConnectionIntegrationTests {
RabbitTemplate template = new RabbitTemplate(createConnectionFactory());
CountDownLatch latch = new CountDownLatch(messageCount);
container = createContainer(new AbortChannelListener(latch), createConnectionFactory());
container = createContainer(queue.getName(), new AbortChannelListener(latch), createConnectionFactory());
assertEquals(concurrentConsumers, container.getActiveConsumerCount());
for (int i = 0; i < messageCount; i++) {
@@ -147,8 +149,8 @@ public class MessageListenerRecoveryCachingConnectionIntegrationTests {
CountDownLatch latch = new CountDownLatch(messageCount);
ConnectionFactory connectionFactory = createConnectionFactory();
container = createContainer(new CloseConnectionListener((ConnectionProxy) connectionFactory.createConnection(),
latch), connectionFactory);
container = createContainer(queue.getName(), new CloseConnectionListener((ConnectionProxy) connectionFactory.createConnection(),
latch), connectionFactory);
for (int i = 0; i < messageCount; i++) {
template.convertAndSend(queue.getName(), i + "foo");
}
@@ -171,7 +173,7 @@ public class MessageListenerRecoveryCachingConnectionIntegrationTests {
acknowledgeMode = AcknowledgeMode.MANUAL;
CountDownLatch latch = new CountDownLatch(messageCount);
container = createContainer(new ManualAckListener(latch), connectionFactory);
container = createContainer(queue.getName(), new ManualAckListener(latch), connectionFactory);
for (int i = 0; i < messageCount; i++) {
template.convertAndSend(queue.getName(), i + "foo");
}
@@ -186,10 +188,18 @@ public class MessageListenerRecoveryCachingConnectionIntegrationTests {
}
private SimpleMessageListenerContainer createContainer(Object listener, ConnectionFactory connectionFactory) {
@Test(expected=AmqpIllegalStateException.class)
public void testListenerDoesNotRecoverFromMissingQueue() throws Exception {
// TODO: with only 1 this test tends to fail
concurrentConsumers = 3;
CountDownLatch latch = new CountDownLatch(messageCount);
container = createContainer("nonexistent", new VanillaListener(latch), createConnectionFactory());
}
private SimpleMessageListenerContainer createContainer(String queueName, Object listener, ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
container.setMessageListener(new MessageListenerAdapter(listener));
container.setQueueName(queue.getName());
container.setQueueName(queueName);
container.setTxSize(txSize);
container.setPrefetchCount(txSize);
container.setConcurrentConsumers(concurrentConsumers);

View File

@@ -1,19 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="connectionFactory"
class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory" />
<bean id="template" class="org.springframework.amqp.rabbit.core.RabbitTemplate">
<constructor-arg ref="connectionFactory" />
</bean>
<!-- 'rabbit-template' and 'rabbit-connection-factory' attributes are set
- context load should fail -->
<rabbit:admin connection-factory="connectionFactory"
template="template" />
<!-- Valid configuration -->
<rabbit:admin id="admin-test" connection-factory="connectionFactory" phase="12" auto-startup="false"/>
</beans>

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="connectionFactory"
class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory" />
<!-- 'template' and 'connection-factory' attributes are set
- context load should fail -->
<rabbit:admin connection-factory="connectionFactory"
template="" />
</beans>

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="connectionFactory"
class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory" />
<bean id="template" class="org.springframework.amqp.rabbit.core.RabbitTemplate">
<constructor-arg ref="connectionFactory" />
</bean>
<!-- 'template' and 'connection-factory' attributes are set - context load should fail -->
<rabbit:admin connection-factory="" template="template"/>
</beans>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="connectionFactory"
class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory" />
<!-- Valid configuration -->
<rabbit:admin id="admin-test" connection-factory="connectionFactory" phase="12" auto-startup="false"/>
</beans>

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="connectionFactory"
class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory" />
<bean id="template" class="org.springframework.amqp.rabbit.core.RabbitTemplate">
<constructor-arg ref="connectionFactory" />
</bean>
<!-- Valid configuration -->
<rabbit:admin id="admin-test"
template="template" phase="12" auto-startup="false" />
</beans>