INT-720 Added support for the "dispatcher" sub-element within a "channel". This is now where the failover, load-balancer, and task-executor attributes are to be configured.
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
@@ -37,6 +39,9 @@ public class PointToPointChannelParser extends AbstractChannelParser {
|
||||
private static final String DISPATCHER_PACKAGE = IntegrationNamespaceUtils.BASE_PACKAGE + ".dispatcher";
|
||||
|
||||
|
||||
private final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
|
||||
@Override
|
||||
protected BeanDefinitionBuilder buildBeanDefinition(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = null;
|
||||
@@ -64,16 +69,53 @@ public class PointToPointChannelParser extends AbstractChannelParser {
|
||||
builder = BeanDefinitionBuilder.genericBeanDefinition(CHANNEL_PACKAGE + ".RendezvousChannel");
|
||||
}
|
||||
|
||||
// verify that the 'task-executor' is not provided if a queue sub-element exists
|
||||
String taskExecutor = element.getAttribute("task-executor");
|
||||
if (queueElement != null && StringUtils.hasText(taskExecutor)) {
|
||||
parserContext.getReaderContext().error("The 'task-executor' attribute " +
|
||||
Element dispatcherElement = DomUtils.getChildElementByTagName(element, "dispatcher");
|
||||
|
||||
// check for the dispatcher attribute (deprecated)
|
||||
String dispatcherAttribute = element.getAttribute("dispatcher");
|
||||
boolean hasDispatcherAttribute = StringUtils.hasText(dispatcherAttribute);
|
||||
if (hasDispatcherAttribute && logger.isWarnEnabled()) {
|
||||
logger.warn("The 'dispatcher' attribute on the 'channel' element is deprecated. " +
|
||||
"Please use the 'dispatcher' sub-element instead.");
|
||||
}
|
||||
|
||||
// verify that a dispatcher is not provided if a queue sub-element exists
|
||||
if (queueElement != null && (dispatcherElement != null || hasDispatcherAttribute)) {
|
||||
parserContext.getReaderContext().error("The 'dispatcher' attribute or sub-element " +
|
||||
"and any queue sub-element are mutually exclusive.", element);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (builder == null) {
|
||||
if (queueElement != null) {
|
||||
return builder;
|
||||
}
|
||||
|
||||
if (dispatcherElement != null && hasDispatcherAttribute) {
|
||||
parserContext.getReaderContext().error("The 'dispatcher' attribute and 'dispatcher' " +
|
||||
"sub-element are mutually exclusive. NOTE: the attribute is DEPRECATED. " +
|
||||
"Please use the dispatcher sub-element instead.", element);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (hasDispatcherAttribute) {
|
||||
// this attribute is deprecated, but if set, we need to create a DirectChannel
|
||||
// without any LoadBalancerStrategy and the failover flag set to true (default).
|
||||
builder = BeanDefinitionBuilder.genericBeanDefinition(CHANNEL_PACKAGE + ".DirectChannel");
|
||||
if (!"failover".equals(dispatcherAttribute)) {
|
||||
// round-robin dispatcher is used by default, the "failover" value simply disables it
|
||||
builder.addConstructorArgValue(new RootBeanDefinition(
|
||||
DISPATCHER_PACKAGE + ".RoundRobinLoadBalancingStrategy", null, null));
|
||||
}
|
||||
}
|
||||
else if (dispatcherElement == null) {
|
||||
// configure the default DirectChannel with a RoundRobinLoadBalancingStrategy
|
||||
builder = BeanDefinitionBuilder.genericBeanDefinition(CHANNEL_PACKAGE + ".DirectChannel");
|
||||
builder.addConstructorArgValue(new RootBeanDefinition(
|
||||
DISPATCHER_PACKAGE + ".RoundRobinLoadBalancingStrategy", null, null));
|
||||
}
|
||||
else {
|
||||
// configure either an ExecutorChannel or DirectChannel based on existence of 'task-executor'
|
||||
String taskExecutor = dispatcherElement.getAttribute("task-executor");
|
||||
if (StringUtils.hasText(taskExecutor)) {
|
||||
builder = BeanDefinitionBuilder.genericBeanDefinition(CHANNEL_PACKAGE + ".ExecutorChannel");
|
||||
builder.addConstructorArgReference(taskExecutor);
|
||||
@@ -81,15 +123,15 @@ public class PointToPointChannelParser extends AbstractChannelParser {
|
||||
else {
|
||||
builder = BeanDefinitionBuilder.genericBeanDefinition(CHANNEL_PACKAGE + ".DirectChannel");
|
||||
}
|
||||
// this attribute is deprecated, but if set, we need to create a UnicastingDispatcher
|
||||
// without any LoadBalancerStrategy and the failover flag set to true (default).
|
||||
String dispatcherAttribute = element.getAttribute("dispatcher");
|
||||
if (!"failover".equals(dispatcherAttribute)) {
|
||||
// round-robin dispatcher by default, but TODO first we need to check for the dispatcher element.
|
||||
// unless the 'load-balancer' attribute is explicitly set to 'none',
|
||||
// configure the default RoundRobinLoadBalancingStrategy
|
||||
String loadBalancer = dispatcherElement.getAttribute("load-balancer");
|
||||
if (!"none".equals(loadBalancer)) {
|
||||
builder.addConstructorArgValue(new RootBeanDefinition(
|
||||
DISPATCHER_PACKAGE + ".RoundRobinLoadBalancingStrategy", null, null));
|
||||
}
|
||||
}
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, dispatcherElement, "failover");
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,25 +64,11 @@
|
||||
<xsd:element name="queue" type="queueType" />
|
||||
<xsd:element name="priority-queue" type="priorityQueueType" />
|
||||
<xsd:element name="rendezvous-queue" type="rendezvousQueueType" />
|
||||
<xsd:element name="dispatcher" type="dispatcherType" />
|
||||
</xsd:choice>
|
||||
<xsd:element name="interceptors" type="channelInterceptorsType"
|
||||
minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="task-executor" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Provide a TaskExecutor to use when dispatching Messages to this channel's subscribers. This is
|
||||
mutually exclusive with any of the queue sub-elements. Also, when using a TaskExecutor, keep in
|
||||
mind that any transaction active for the sender will NOT propagate to the handler invocation
|
||||
since the TaskExecutor dispatches to the handler on a separate Thread.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.core.task.TaskExecutor" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
@@ -133,6 +119,73 @@
|
||||
</xsd:annotation>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="dispatcherType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines the dispatching configuration for a non-buffering channel
|
||||
(i.e. one without a queue).
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:attribute name="load-balancer">
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines a load-balancing strategy for the channel's dispatcher.
|
||||
The default is a round-robin load balancer.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="round-robin">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
[DEFAULT] Defines a Round Robin dispatching strategy which allows for
|
||||
load balancing of messages between multiple Message Handlers. Which message
|
||||
handler receives the message first is determined by the 'order' attribute
|
||||
of such Message Handler.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
<xsd:enumeration value="none">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
No LoadBalancingStrategy will be used.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="failover" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specifies whether this dispatcher has failover enabled. By default,
|
||||
failover will be enabled. Set this to 'false' to disable it.
|
||||
When enabled and message delivery to the primary Message Handler fails,
|
||||
an attempt will be made to deliver the message to the next handler and so on...
|
||||
Primary, secondary etc... is determined by the load-balancing strategy in use
|
||||
(e.g. round-robin). If no load-balancer strategy is configured, the order will
|
||||
be fixed in a sequence determined by the 'order' attribute on the Message Handlers
|
||||
(or the @Ordered annotation on adapted methods).
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="task-executor" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Provide a TaskExecutor to use when dispatching Messages to this channel's subscribers. This is
|
||||
mutually exclusive with any of the queue sub-elements. Also, when using a TaskExecutor, keep in
|
||||
mind that any transaction active for the sender will NOT propagate to the handler invocation
|
||||
since the TaskExecutor dispatches to the handler on a separate Thread.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.core.task.TaskExecutor" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:element name="publish-subscribe-channel">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
@@ -215,31 +268,15 @@
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines a dispatching strategy for the channel.
|
||||
The default is a round
|
||||
robin load balancer. In case of a publish
|
||||
subscribe channel this
|
||||
attribute will be ignored.
|
||||
This attribute is DEPRECATED. Please use the dispatcher sub-element instead.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="failover">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines a fail over dispatching strategy.
|
||||
If message delivery to the primary Message Handler failed an
|
||||
attempt will be made to deliver the message to the secondary and so on...
|
||||
Primary, secondary etc... is determined by the 'order' attribute on the Message Handlers.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
<xsd:enumeration value="round-robin">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
[DEFAULT] Defines a Round Robin dispatching strategy which allows for
|
||||
load balancing of messages between multiple Message Handlers. Which message
|
||||
handler receives the message first is determined by the 'order' attribute
|
||||
of such Message Handler.
|
||||
Enables failover, but disables load-balancing.
|
||||
See the dispatcher sub-element for more information.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
|
||||
Reference in New Issue
Block a user