Merge pull request #29 from garyrussell/AMQP-201

* AMQP-201:
  AMQP-201 Exchange-to-Exchange Binding
This commit is contained in:
Oleg Zhurakousky
2012-05-10 13:52:59 -04:00
8 changed files with 38 additions and 6 deletions

View File

@@ -21,6 +21,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
@@ -42,6 +43,8 @@ public abstract class AbstractExchangeParser extends AbstractSingleBeanDefinitio
protected static final String BINDING_QUEUE_ATTR = "queue";
protected static final String BINDING_EXCHANGE_ATTR = "exchange";
@Override
protected boolean shouldGenerateIdAsFallback() {
return true;
@@ -87,4 +90,20 @@ public abstract class AbstractExchangeParser extends AbstractSingleBeanDefinitio
protected abstract AbstractBeanDefinition parseBinding(String exchangeName, Element binding,
ParserContext parserContext);
protected void parseDestination(Element binding, ParserContext parserContext, BeanDefinitionBuilder builder) {
String queueAttribute = binding.getAttribute(BINDING_QUEUE_ATTR);
String exchangeAttribute = binding.getAttribute(BINDING_EXCHANGE_ATTR);
boolean hasQueueAttribute = StringUtils.hasText(queueAttribute);
boolean hasExchangeAttribute = StringUtils.hasText(exchangeAttribute);
if (!(hasQueueAttribute ^ hasExchangeAttribute)) {
parserContext.getReaderContext().error("Binding must have exactly one of 'queue' or 'exchange'", binding);
}
if (hasQueueAttribute) {
builder.addPropertyReference("destinationQueue", queueAttribute);
}
if (hasExchangeAttribute) {
builder.addPropertyReference("destinationExchange", exchangeAttribute);
}
}
}

View File

@@ -40,7 +40,7 @@ public class DirectExchangeParser extends AbstractExchangeParser {
protected AbstractBeanDefinition parseBinding(String exchangeName, Element binding,
ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(BindingFactoryBean.class);
builder.addPropertyReference("destinationQueue", binding.getAttribute(BINDING_QUEUE_ATTR));
parseDestination(binding, parserContext, builder);
builder.addPropertyValue("exchange", new TypedStringValue(exchangeName));
String bindingKey = binding.getAttribute(BINDING_KEY_ATTR);
if (!StringUtils.hasText(bindingKey)) {

View File

@@ -36,7 +36,7 @@ public class FanoutExchangeParser extends AbstractExchangeParser {
@Override
protected AbstractBeanDefinition parseBinding(String exchangeName, Element binding, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(BindingFactoryBean.class);
builder.addPropertyReference("destinationQueue", binding.getAttribute(BINDING_QUEUE_ATTR));
parseDestination(binding, parserContext, builder);
builder.addPropertyValue("exchange", new TypedStringValue(exchangeName));
builder.addPropertyValue("arguments", Collections.<String, Object>emptyMap());
return builder.getBeanDefinition();

View File

@@ -38,7 +38,7 @@ public class HeadersExchangeParser extends AbstractExchangeParser {
@Override
protected AbstractBeanDefinition parseBinding(String exchangeName, Element binding, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(BindingFactoryBean.class);
builder.addPropertyReference("destinationQueue", binding.getAttribute(BINDING_QUEUE_ATTR));
parseDestination(binding, parserContext, builder);
builder.addPropertyValue("exchange", new TypedStringValue(exchangeName));
ManagedMap<TypedStringValue, TypedStringValue> map = new ManagedMap<TypedStringValue, TypedStringValue>();
String key = binding.getAttribute("key");

View File

@@ -41,7 +41,7 @@ public class TopicExchangeParser extends AbstractExchangeParser {
@Override
protected AbstractBeanDefinition parseBinding(String exchangeName, Element binding, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(BindingFactoryBean.class);
builder.addPropertyReference("destinationQueue", binding.getAttribute(BINDING_QUEUE_ATTR));
parseDestination(binding, parserContext, builder);
builder.addPropertyValue("exchange", new TypedStringValue(exchangeName));
builder.addPropertyValue("routingKey", new TypedStringValue(binding.getAttribute(BINDING_PATTERN_ATTR)));
builder.addPropertyValue("arguments", Collections.<String, Object>emptyMap());

View File

@@ -441,7 +441,7 @@
<xsd:sequence>
<xsd:element ref="binding-arguments" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="queue" use="required">
<xsd:attribute name="queue" use="optional">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.amqp.core.Queue"><![CDATA[
The bean name of the Queue to bind to this exchange.
@@ -453,6 +453,18 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="exchange" use="optional">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.amqp.core.Exchange"><![CDATA[
The bean name of another exchange to bind to this exchange.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.amqp.core.Exchange" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:element name="binding-arguments" type="mapType">

View File

@@ -80,7 +80,7 @@ public final class RabbitNamespaceHandlerTests {
public void testBindings() throws Exception {
Map<String, Binding> bindings = beanFactory.getBeansOfType(Binding.class);
// 4 for each exchange type
assertEquals(16, bindings.size());
assertEquals(17, bindings.size());
}
@Test

View File

@@ -22,6 +22,7 @@
<binding queue="bar" pattern="bar.#" />
<binding queue="spam" pattern="spam.#"/>
<binding queue="bucket" pattern="bucket.#"/>
<binding exchange="direct-test" pattern="qux" />
</bindings>
</topic-exchange>