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:
@@ -52,6 +52,8 @@ public abstract class AbstractJmsListenerContainerFactory<C extends AbstractMess
|
||||
|
||||
private Boolean pubSubDomain;
|
||||
|
||||
private Boolean replyPubSubDomain;
|
||||
|
||||
private Boolean subscriptionDurable;
|
||||
|
||||
private Boolean subscriptionShared;
|
||||
@@ -112,6 +114,13 @@ public abstract class AbstractJmsListenerContainerFactory<C extends AbstractMess
|
||||
this.pubSubDomain = pubSubDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AbstractMessageListenerContainer#setReplyPubSubDomain(boolean)
|
||||
*/
|
||||
public void setReplyPubSubDomain(Boolean replyPubSubDomain) {
|
||||
this.replyPubSubDomain = replyPubSubDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AbstractMessageListenerContainer#setSubscriptionDurable(boolean)
|
||||
*/
|
||||
@@ -172,6 +181,9 @@ public abstract class AbstractJmsListenerContainerFactory<C extends AbstractMess
|
||||
if (this.pubSubDomain != null) {
|
||||
instance.setPubSubDomain(this.pubSubDomain);
|
||||
}
|
||||
if (this.replyPubSubDomain != null) {
|
||||
instance.setReplyPubSubDomain(this.replyPubSubDomain);
|
||||
}
|
||||
if (this.subscriptionDurable != null) {
|
||||
instance.setSubscriptionDurable(this.subscriptionDurable);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -78,6 +78,8 @@ abstract class AbstractListenerContainerParser implements BeanDefinitionParser {
|
||||
|
||||
protected static final String DESTINATION_TYPE_SHARED_DURABLE_TOPIC = "sharedDurableTopic";
|
||||
|
||||
protected static final String RESPONSE_DESTINATION_TYPE_ATTRIBUTE = "response-destination-type";
|
||||
|
||||
protected static final String CLIENT_ID_ATTRIBUTE = "client-id";
|
||||
|
||||
protected static final String ACKNOWLEDGE_ATTRIBUTE = "acknowledge";
|
||||
@@ -170,7 +172,7 @@ abstract class AbstractListenerContainerParser implements BeanDefinitionParser {
|
||||
|
||||
if (listenerEle.hasAttribute(RESPONSE_DESTINATION_ATTRIBUTE)) {
|
||||
String responseDestination = listenerEle.getAttribute(RESPONSE_DESTINATION_ATTRIBUTE);
|
||||
Boolean pubSubDomain = (Boolean) commonContainerProperties.getPropertyValue("pubSubDomain").getValue();
|
||||
Boolean pubSubDomain = (Boolean) commonContainerProperties.getPropertyValue("replyPubSubDomain").getValue();
|
||||
listenerDef.getPropertyValues().add(
|
||||
pubSubDomain ? "defaultResponseTopicName" : "defaultResponseQueueName", responseDestination);
|
||||
if (containerDef.getPropertyValues().contains("destinationResolver")) {
|
||||
@@ -260,6 +262,23 @@ abstract class AbstractListenerContainerParser implements BeanDefinitionParser {
|
||||
properties.add("subscriptionDurable", subscriptionDurable);
|
||||
properties.add("subscriptionShared", subscriptionShared);
|
||||
|
||||
boolean replyPubSubDomain = false;
|
||||
String replyDestinationType = containerEle.getAttribute(RESPONSE_DESTINATION_TYPE_ATTRIBUTE);
|
||||
if (DESTINATION_TYPE_TOPIC.equals(replyDestinationType)) {
|
||||
replyPubSubDomain = true;
|
||||
}
|
||||
else if (DESTINATION_TYPE_QUEUE.equals(replyDestinationType)) {
|
||||
replyPubSubDomain = false;
|
||||
}
|
||||
else if (!StringUtils.hasText(replyDestinationType)) {
|
||||
replyPubSubDomain = pubSubDomain; // the default: same value as pubSubDomain
|
||||
}
|
||||
else if (StringUtils.hasText(replyDestinationType)) {
|
||||
parserContext.getReaderContext().error("Invalid listener container 'response-destination-type': only " +
|
||||
"\"queue\", \"topic\" supported.", containerEle);
|
||||
}
|
||||
properties.add("replyPubSubDomain", replyPubSubDomain);
|
||||
|
||||
if (containerEle.hasAttribute(CLIENT_ID_ATTRIBUTE)) {
|
||||
String clientId = containerEle.getAttribute(CLIENT_ID_ATTRIBUTE);
|
||||
if (!StringUtils.hasText(clientId)) {
|
||||
|
||||
@@ -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.
|
||||
@@ -89,7 +89,7 @@ public class MethodJmsListenerEndpoint extends AbstractJmsListenerEndpoint {
|
||||
messageListener.setHandlerMethod(invocableHandlerMethod);
|
||||
String responseDestination = getDefaultResponseDestination();
|
||||
if (StringUtils.hasText(responseDestination)) {
|
||||
if (container.isPubSubDomain()) {
|
||||
if (container.isReplyPubSubDomain()) {
|
||||
messageListener.setDefaultResponseTopicName(responseDestination);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -153,6 +153,8 @@ public abstract class AbstractMessageListenerContainer extends AbstractJmsListen
|
||||
|
||||
private String subscriptionName;
|
||||
|
||||
private Boolean replyPubSubDomain;
|
||||
|
||||
private boolean pubSubNoLocal = false;
|
||||
|
||||
private MessageConverter messageConverter;
|
||||
@@ -445,6 +447,34 @@ public abstract class AbstractMessageListenerContainer extends AbstractJmsListen
|
||||
return this.pubSubNoLocal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the reply destination type. By default, the configured {@code pubSubDomain}
|
||||
* value is used (see {@link #isPubSubDomain()}.
|
||||
* <p>This setting primarily indicates what type of destination to resolve
|
||||
* if dynamic destinations are enabled.
|
||||
* @param replyPubSubDomain "true" for the Publish/Subscribe domain ({@link javax.jms.Topic Topics}),
|
||||
* "false" for the Point-to-Point domain ({@link javax.jms.Queue Queues})
|
||||
* @see #setDestinationResolver
|
||||
*/
|
||||
public void setReplyPubSubDomain(boolean replyPubSubDomain) {
|
||||
this.replyPubSubDomain = replyPubSubDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the Publish/Subscribe domain ({@link javax.jms.Topic Topics}) is used
|
||||
* for replies. Otherwise, the Point-to-Point domain ({@link javax.jms.Queue Queues}) is
|
||||
* used.
|
||||
*/
|
||||
@Override
|
||||
public boolean isReplyPubSubDomain() {
|
||||
if (this.replyPubSubDomain != null) {
|
||||
return replyPubSubDomain;
|
||||
}
|
||||
else {
|
||||
return isPubSubDomain();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link MessageConverter} strategy for converting JMS Messages.
|
||||
* @since 4.1
|
||||
|
||||
@@ -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.
|
||||
@@ -47,4 +47,12 @@ public interface MessageListenerContainer extends SmartLifecycle {
|
||||
*/
|
||||
boolean isPubSubDomain();
|
||||
|
||||
/**
|
||||
* Return whether the reply destination uses Publish/Subscribe domain
|
||||
* ({@link javax.jms.Topic Topics}). Otherwise, the Point-to-Point domain
|
||||
* ({@link javax.jms.Queue Queues}) is used.
|
||||
* <p>By default, the value is identical to {@link #isPubSubDomain()}.
|
||||
*/
|
||||
boolean isReplyPubSubDomain();
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -46,6 +46,8 @@ public class JmsActivationSpecConfig {
|
||||
|
||||
private boolean pubSubDomain = false;
|
||||
|
||||
private Boolean replyPubSubDomain;
|
||||
|
||||
private boolean subscriptionDurable = false;
|
||||
|
||||
private boolean subscriptionShared = false;
|
||||
@@ -81,6 +83,19 @@ public class JmsActivationSpecConfig {
|
||||
return this.pubSubDomain;
|
||||
}
|
||||
|
||||
public void setReplyPubSubDomain(boolean replyPubSubDomain) {
|
||||
this.replyPubSubDomain = replyPubSubDomain;
|
||||
}
|
||||
|
||||
public boolean isReplyPubSubDomain() {
|
||||
if (this.replyPubSubDomain != null) {
|
||||
return this.replyPubSubDomain;
|
||||
}
|
||||
else {
|
||||
return isPubSubDomain();
|
||||
}
|
||||
}
|
||||
|
||||
public void setSubscriptionDurable(boolean subscriptionDurable) {
|
||||
this.subscriptionDurable = subscriptionDurable;
|
||||
if (subscriptionDurable) {
|
||||
|
||||
@@ -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.
|
||||
@@ -200,4 +200,13 @@ public class JmsMessageEndpointManager extends GenericMessageEndpointManager
|
||||
throw new IllegalStateException("Could not determine pubSubDomain - no activation spec config is set");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplyPubSubDomain() {
|
||||
JmsActivationSpecConfig config = getActivationSpecConfig();
|
||||
if (config != null) {
|
||||
return config.isReplyPubSubDomain();
|
||||
}
|
||||
throw new IllegalStateException("Could not determine reply pubSubDomain - no activation spec config is set");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,4 +4,5 @@ http\://www.springframework.org/schema/jms/spring-jms-3.1.xsd=org/springframewor
|
||||
http\://www.springframework.org/schema/jms/spring-jms-3.2.xsd=org/springframework/jms/config/spring-jms-3.2.xsd
|
||||
http\://www.springframework.org/schema/jms/spring-jms-4.0.xsd=org/springframework/jms/config/spring-jms-4.0.xsd
|
||||
http\://www.springframework.org/schema/jms/spring-jms-4.1.xsd=org/springframework/jms/config/spring-jms-4.1.xsd
|
||||
http\://www.springframework.org/schema/jms/spring-jms.xsd=org/springframework/jms/config/spring-jms-4.1.xsd
|
||||
http\://www.springframework.org/schema/jms/spring-jms-4.2.xsd=org/springframework/jms/config/spring-jms-4.2.xsd
|
||||
http\://www.springframework.org/schema/jms/spring-jms.xsd=org/springframework/jms/config/spring-jms-4.2.xsd
|
||||
|
||||
@@ -0,0 +1,638 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/jms"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
targetNamespace="http://www.springframework.org/schema/jms"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-4.2.xsd"/>
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines the configuration elements for the Spring Framework's JMS support.
|
||||
Allows for configuring JMS listener containers in XML 'shortcut' style as
|
||||
well as through annotation.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="annotation-driven">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Enables the detection of @JmsListener annotation on any Spring-managed object. If
|
||||
present, a message listener container will be created to receive the relevant
|
||||
messages and invoke the annotated method accordingly.
|
||||
|
||||
See Javadoc for the org.springframework.jms.annotation.EnableJms annotation for
|
||||
information on code-based alternatives to this XML element.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="registry" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies the org.springframework.jms.config.JmsListenerEndpointRegistry instance to
|
||||
use to register annotated jms listener endpoints. If not provided, a default instance
|
||||
will be used by default.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jms.config.JmsListenerEndpointRegistry"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="container-factory" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies the org.springframework.jms.config.JmsListenerContainerFactory instance to
|
||||
use to create the container for a jms listener endpoint that does not define a specific
|
||||
factory. This permits in practice to omit the "containerFactory" attribute of the JmsListener
|
||||
annotation. This attribute is not required as each endpoint may define the factory to use and,
|
||||
as a convenience, the JmsListenerContainerFactory with name 'jmsListenerContainerFactory' is
|
||||
looked up by default.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jms.config.JmsListenerContainerFactory"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="handler-method-factory" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies a custom org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory
|
||||
instance to use to configure the message listener responsible to serve an endpoint detected by this
|
||||
processor. By default, DefaultMessageHandlerMethodFactory is used and it can be configured
|
||||
further to support additional method arguments or to customize conversion and validation
|
||||
support. See org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory
|
||||
Javadoc for more details.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="listener-container">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Each listener child element will be hosted by a container whose configuration
|
||||
is determined by this parent element. This variant builds standard JMS
|
||||
listener containers, operating against a specified JMS ConnectionFactory. When
|
||||
a factory-id attribute is present, the configuration defined by this element is
|
||||
exposed as a org.springframework.jms.config.JmsListenerContainerFactory. It is
|
||||
therefore possible to only define this element without any child to just expose
|
||||
a container factory.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="org.springframework.jms.listener.AbstractMessageListenerContainer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="listener" type="listenerType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="factory-id" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Expose the settings defined by this element as a org.springframework.jms.config.JmsListenerContainerFactory
|
||||
so that they can be reused with other endpoints.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="container-type" default="default">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The type of this listener container: "default" or "simple", choosing
|
||||
between DefaultMessageListenerContainer and SimpleMessageListenerContainer.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="default"/>
|
||||
<xsd:enumeration value="simple"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="container-class" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A custom listener container implementation class as fully qualified class name.
|
||||
Default is Spring's standard DefaultMessageListenerContainer or
|
||||
SimpleMessageListenerContainer, according to the "container-type" attribute.
|
||||
Note that a custom container class will typically be a subclass of either of
|
||||
those two Spring-provided standard container classes: Nake sure that the
|
||||
"container-type" attribute matches the actual base type that the custom class
|
||||
derives from ("default" will usually be fine anyway, since most custom classes
|
||||
will derive from DefaultMessageListenerContainer).
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:expected-type type="java.lang.Class"/>
|
||||
<tool:assignable-to type="org.springframework.jms.listener.AbstractMessageListenerContainer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="connection-factory" type="xsd:string" default="connectionFactory">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to the JMS ConnectionFactory bean.
|
||||
Default is "connectionFactory".
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="javax.jms.ConnectionFactory"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="task-executor" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to a Spring TaskExecutor (or standard JDK 1.5 Executor) for executing
|
||||
JMS listener invokers. Default is a SimpleAsyncTaskExecutor in case of a
|
||||
DefaultMessageListenerContainer, using internally managed threads. For a
|
||||
SimpleMessageListenerContainer, listeners will always get invoked within the
|
||||
JMS provider's receive thread by default.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="java.util.concurrent.Executor"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="destination-resolver" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to the DestinationResolver strategy for resolving destination names.
|
||||
Default is a DynamicDestinationResolver, using the JMS provider's queue/topic
|
||||
name resolution. Alternatively, specify a reference to a JndiDestinationResolver
|
||||
(typically in a J2EE environment).
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jms.support.destination.DestinationResolver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="message-converter" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to the MessageConverter strategy for converting JMS Messages to
|
||||
listener method arguments. Default is a SimpleMessageConverter.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jms.support.converter.MessageConverter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="error-handler" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to an ErrorHandler strategy for handling any uncaught Exceptions
|
||||
that may occur during the execution of the MessageListener.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.util.ErrorHandler"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="destination-type" default="queue">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The JMS destination type for this listener: "queue", "topic", "durableTopic",
|
||||
"sharedTopic", "sharedDurableTopic". This enables potentially the "pubSubDomain",
|
||||
"subscriptionDurable" and "subscriptionShared" properties of the container. The
|
||||
default is "queue" (i.e. disabling those 3 properties).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="queue"/>
|
||||
<xsd:enumeration value="topic"/>
|
||||
<xsd:enumeration value="durableTopic"/>
|
||||
<xsd:enumeration value="sharedTopic"/>
|
||||
<xsd:enumeration value="sharedDurableTopic"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="response-destination-type" default="queue">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The JMS destination type for responses: "queue", "topic". Default
|
||||
is the value of the "destination-type" attribute.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="queue"/>
|
||||
<xsd:enumeration value="topic"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="client-id" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The JMS client id for this listener container.
|
||||
Needs to be specified when using subscriptions.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cache" default="auto">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The cache level for JMS resources: "none", "connection", "session", "consumer"
|
||||
or "auto". By default ("auto"), the cache level will effectively be "consumer",
|
||||
unless an external transaction manager has been specified - in which case the
|
||||
effective default will be "none" (assuming J2EE-style transaction management
|
||||
where the given ConnectionFactory is an XA-aware pool).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="none"/>
|
||||
<xsd:enumeration value="connection"/>
|
||||
<xsd:enumeration value="session"/>
|
||||
<xsd:enumeration value="consumer"/>
|
||||
<xsd:enumeration value="auto"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="acknowledge" default="auto">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The native JMS acknowledge mode: "auto", "client", "dups-ok" or "transacted".
|
||||
A value of "transacted" effectively activates a locally transacted Session;
|
||||
as alternative, specify an external "transaction-manager" via the corresponding
|
||||
attribute. Default is "auto".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="auto"/>
|
||||
<xsd:enumeration value="client"/>
|
||||
<xsd:enumeration value="dups-ok"/>
|
||||
<xsd:enumeration value="transacted"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="transaction-manager" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to an external PlatformTransactionManager (typically an
|
||||
XA-based transaction coordinator, e.g. Spring's JtaTransactionManager).
|
||||
If not specified, native acknowledging will be used (see "acknowledge" attribute).
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.transaction.PlatformTransactionManager"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="concurrency" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The number of concurrent sessions/consumers to start for each listener.
|
||||
Can either be a simple number indicating the maximum number (e.g. "5")
|
||||
or a range indicating the lower as well as the upper limit (e.g. "3-5").
|
||||
Note that a specified minimum is just a hint and might be ignored at runtime.
|
||||
Default is 1; keep concurrency limited to 1 in case of a topic listener
|
||||
or if message ordering is important; consider raising it for general queues.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="prefetch" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The maximum number of messages to load into a single session.
|
||||
Note that raising this number might lead to starvation of concurrent consumers!
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="receive-timeout" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The timeout to use for receive calls (in milliseconds).
|
||||
The default is 1000 ms (1 sec); -1 indicates no timeout at all.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="back-off" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specify the BackOff instance to use to compute the interval between recovery
|
||||
attempts. If the BackOff implementation returns "BackOffExecution#STOP", the listener
|
||||
container will not further attempt to recover. The recovery-interval value is
|
||||
ignored when this property is set. The default is a FixedBackOff with an
|
||||
interval of 5000 ms, that is 5 seconds.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.util.backoff.BackOff"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="recovery-interval" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specify the interval between recovery attempts, in milliseconds. Convenience
|
||||
way to create a FixedBackOff with the specified interval. For more recovery
|
||||
options, consider specifying a BackOff instance instead. The default is
|
||||
5000 ms, that is 5 seconds.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="phase" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The lifecycle phase within which this container should start and stop. The lower
|
||||
the value the earlier this container will start and the later it will stop. The
|
||||
default is Integer.MAX_VALUE meaning the container will start as late as possible
|
||||
and stop as soon as possible.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="jca-listener-container">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Each listener child element will be hosted by a container whose configuration
|
||||
is determined by this parent element. This variant builds standard JCA-based
|
||||
listener containers, operating against a specified JCA ResourceAdapter
|
||||
(which needs to be provided by the JMS message broker, e.g. ActiveMQ). When
|
||||
a factory-id attribute is present, the configuration defined by this element is
|
||||
exposed as a org.springframework.jms.config.JmsListenerContainerFactory. It is
|
||||
therefore possible to only define this element without any child to just expose
|
||||
a container factory.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="org.springframework.jms.listener.endpoint.JmsMessageEndpointManager"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="listener" type="listenerType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="factory-id" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Expose the settings defined by this element as a org.springframework.jms.config.JmsListenerContainerFactory
|
||||
so that they can be reused with other endpoints.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="resource-adapter" type="xsd:string" default="resourceAdapter">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to the JCA ResourceAdapter bean for the JMS provider.
|
||||
Default is "resourceAdapter".
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="javax.resource.spi.ResourceAdapter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="activation-spec-factory" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to the JmsActivationSpecFactory.
|
||||
Default is to autodetect the JMS provider and its ActivationSpec class
|
||||
(see DefaultJmsActivationSpecFactory).
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jms.listener.endpoint.JmsActivationSpecFactory"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="destination-resolver" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to the DestinationResolver strategy for resolving destination names.
|
||||
Default is to pass in the destination name Strings into the JCA ActivationSpec as-is.
|
||||
Alternatively, specify a reference to a JndiDestinationResolver (typically in a J2EE
|
||||
environment, in particular if the server insists on receiving Destination objects).
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jms.support.destination.DestinationResolver"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="message-converter" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to the MessageConverter strategy for converting JMS Messages to
|
||||
listener method arguments. Default is a SimpleMessageConverter.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jms.support.converter.MessageConverter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="destination-type" default="queue">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The JMS destination type for this listener: "queue", "topic" or "durableTopic".
|
||||
Default is "queue".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="queue"/>
|
||||
<xsd:enumeration value="topic"/>
|
||||
<xsd:enumeration value="durableTopic"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="response-destination-type" default="queue">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The JMS destination type for responses: "queue", "topic". Default
|
||||
is the value of the "destination-type" attribute.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="queue"/>
|
||||
<xsd:enumeration value="topic"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="client-id" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The JMS client id for this listener container.
|
||||
Needs to be specified when using durable subscriptions.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="acknowledge" default="auto">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The native JMS acknowledge mode: "auto", "client", "dups-ok" or "transacted".
|
||||
A value of "transacted" effectively activates a locally transacted Session;
|
||||
as alternative, specify an external "transaction-manager" via the corresponding
|
||||
attribute. Default is "auto".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="auto"/>
|
||||
<xsd:enumeration value="client"/>
|
||||
<xsd:enumeration value="dups-ok"/>
|
||||
<xsd:enumeration value="transacted"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="transaction-manager" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A reference to the Spring JtaTransactionManager or [javax.transaction.TransactionManager],
|
||||
for kicking off an XA transaction for each incoming message.
|
||||
If not specified, native acknowledging will be used (see "acknowledge" attribute).
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref"/>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="concurrency" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The number of concurrent sessions/consumers to start for each listener.
|
||||
Can either be a simple number indicating the maximum number (e.g. "5")
|
||||
or a range indicating the lower as well as the upper limit (e.g. "3-5").
|
||||
Note that a specified minimum is just a hint and will typically be ignored
|
||||
at runtime when using a JCA listener container. Default is 1.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="prefetch" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The maximum number of messages to load into a single session.
|
||||
Note that raising this number might lead to starvation of concurrent consumers!
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="phase" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The lifecycle phase within which this container should start and stop. The lower
|
||||
the value the earlier this container will start and the later it will stop. The
|
||||
default is Integer.MAX_VALUE meaning the container will start as late as possible
|
||||
and stop as soon as possible.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="listenerType">
|
||||
<xsd:attribute name="id" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The unique identifier for a listener.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="destination" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The destination name for this listener, resolved through the
|
||||
container-wide DestinationResolver strategy (if any). Required.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="subscription" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name for the durable subscription, if any.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="selector" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The JMS message selector for this listener.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="ref" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The bean name of the listener object, implementing
|
||||
the MessageListener/SessionAwareMessageListener interface
|
||||
or defining the specified listener method. Required.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref"/>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="method" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the listener method to invoke. If not specified,
|
||||
the target bean is supposed to implement the MessageListener
|
||||
or SessionAwareMessageListener interface.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="response-destination" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the default response destination to send response messages to.
|
||||
This will be applied in case of a request message that does not carry
|
||||
a "JMSReplyTo" field. The type of this destination will be determined
|
||||
by the listener-container's "response-destination-type" attribute.
|
||||
Note: This only applies to a listener method with a return value,
|
||||
for which each result object will be converted into a response message.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="concurrency" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The number of concurrent sessions/consumers to start for this listener.
|
||||
Can either be a simple number indicating the maximum number (e.g. "5")
|
||||
or a range indicating the lower as well as the upper limit (e.g. "3-5").
|
||||
Note that a specified minimum is just a hint and might be ignored at runtime.
|
||||
Default is the value provided by the container.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:jms="http://www.springframework.org/schema/jms"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.1.xsd">
|
||||
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.2.xsd">
|
||||
|
||||
<jms:listener-container factory-id="testJmsFactory"
|
||||
connection-factory="testConnectionFactory" task-executor="testTaskExecutor"
|
||||
destination-resolver="testDestinationResolver" message-converter="testMessageConverter"
|
||||
transaction-manager="testTransactionManager" error-handler="testErrorHandler"
|
||||
destination-type="durableTopic" response-destination-type="queue"
|
||||
cache="connection" concurrency="3-5" prefetch="50" receive-timeout="100" back-off="testBackOff" phase="99">
|
||||
<jms:listener id="listener1" destination="testDestination" ref="testBean1" method="setName"/>
|
||||
<jms:listener id="listener2" destination="testDestination" ref="testBean2" method="setName"
|
||||
@@ -30,7 +31,8 @@
|
||||
|
||||
<jms:jca-listener-container factory-id="testJcaFactory"
|
||||
resource-adapter="testResourceAdapter" activation-spec-factory="testActivationSpecFactory"
|
||||
message-converter="testMessageConverter" concurrency="5" prefetch="50" phase="77">
|
||||
message-converter="testMessageConverter" destination-type="topic" response-destination-type="queue"
|
||||
concurrency="5" prefetch="50" phase="77">
|
||||
<jms:listener id="listener3" destination="testDestination" ref="testBean1" method="setName"/>
|
||||
<jms:listener id="listener4" destination="testDestination" ref="testBean2" method="setName"
|
||||
concurrency="7" response-destination="responseDestination"/>
|
||||
|
||||
@@ -2869,7 +2869,7 @@ describes all available attributes:
|
||||
| The name of the default response destination to send response messages to. This will
|
||||
be applied in case of a request message that does not carry a "JMSReplyTo" field. The
|
||||
type of this destination will be determined by the listener-container's
|
||||
"destination-type" attribute. Note: This only applies to a listener method with a
|
||||
"response-destination-type" attribute. Note: This only applies to a listener method with a
|
||||
return value, for which each result object will be converted into a response message.
|
||||
|
||||
| subscription
|
||||
@@ -2958,6 +2958,10 @@ choices and message redelivery scenarios.
|
||||
and `subscriptionShared` properties of the container. The default is `queue` (i.e. disabling
|
||||
those 3 properties).
|
||||
|
||||
| response-destination-type
|
||||
| The JMS destination type for responses: "queue", "topic". Default is the value of the
|
||||
"destination-type" attribute.
|
||||
|
||||
| client-id
|
||||
| The JMS client id for this listener container. Needs to be specified when using
|
||||
durable subscriptions.
|
||||
@@ -3064,6 +3068,10 @@ table:
|
||||
and `subscriptionShared` properties of the container. The default is `queue` (i.e. disabling
|
||||
those 3 properties).
|
||||
|
||||
| response-destination-type
|
||||
| The JMS destination type for responses: "queue", "topic". Default is the value of the
|
||||
"destination-type" attribute.
|
||||
|
||||
| client-id
|
||||
| The JMS client id for this listener container. Needs to be specified when using
|
||||
durable subscriptions.
|
||||
|
||||
Reference in New Issue
Block a user