diff --git a/spring-integration-amqp/src/main/resources/org/springframework/integration/amqp/config/spring-integration-amqp-4.0.xsd b/spring-integration-amqp/src/main/resources/org/springframework/integration/amqp/config/spring-integration-amqp-4.0.xsd
index 9b46e0a2a7..446ea49d02 100644
--- a/spring-integration-amqp/src/main/resources/org/springframework/integration/amqp/config/spring-integration-amqp-4.0.xsd
+++ b/spring-integration-amqp/src/main/resources/org/springframework/integration/amqp/config/spring-integration-amqp-4.0.xsd
@@ -388,7 +388,7 @@
-
+
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java
index 2b4d108afd..b8a13d9b5e 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2014 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.
@@ -28,6 +28,7 @@ package org.springframework.integration.config.xml;
*/
public class IntegrationNamespaceHandler extends AbstractIntegrationNamespaceHandler {
+ @Override
public void init() {
registerBeanDefinitionParser("channel", new PointToPointChannelParser());
registerBeanDefinitionParser("publish-subscribe-channel", new PublishSubscribeChannelParser());
@@ -77,6 +78,9 @@ public class IntegrationNamespaceHandler extends AbstractIntegrationNamespaceHan
registerBeanDefinitionParser("transaction-synchronization-factory", new TransactionSynchronizationFactoryParser());
registerBeanDefinitionParser("spel-function", new SpelFunctionParser());
registerBeanDefinitionParser("spel-property-accessors", new SpelPropertyAccessorsParser());
+ RetryAdviceParser retryParser = new RetryAdviceParser();
+ registerBeanDefinitionParser("handler-retry-advice", retryParser);
+ registerBeanDefinitionParser("retry-advice", retryParser);
}
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/RetryAdviceParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/RetryAdviceParser.java
new file mode 100644
index 0000000000..9fecae64f8
--- /dev/null
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/RetryAdviceParser.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.integration.config.xml;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer;
+import org.springframework.integration.handler.advice.RequestHandlerRetryAdvice;
+import org.springframework.retry.backoff.ExponentialBackOffPolicy;
+import org.springframework.retry.backoff.FixedBackOffPolicy;
+import org.springframework.retry.policy.SimpleRetryPolicy;
+import org.springframework.retry.support.RetryTemplate;
+import org.springframework.util.StringUtils;
+import org.springframework.util.xml.DomUtils;
+
+/**
+ * @author Gary Russell
+ * @since 4.0
+ *
+ */
+public class RetryAdviceParser extends AbstractBeanDefinitionParser {
+
+ @Override
+ protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RequestHandlerRetryAdvice.class);
+ BeanDefinitionBuilder retryTemplateBuilder = BeanDefinitionBuilder.genericBeanDefinition(RetryTemplate.class);
+ boolean customTemplate = false;
+ Element backOffPolicyEle = DomUtils.getChildElementByTagName(element, "fixed-back-off");
+ BeanDefinitionBuilder backOffBuilder = null;
+ if (backOffPolicyEle != null) {
+ backOffBuilder = BeanDefinitionBuilder.genericBeanDefinition(FixedBackOffPolicy.class);
+ IntegrationNamespaceUtils.setValueIfAttributeDefined(backOffBuilder, backOffPolicyEle, "interval", "backOffPeriod");
+ }
+ else {
+ backOffPolicyEle = DomUtils.getChildElementByTagName(element, "exponential-back-off");
+ if (backOffPolicyEle != null) {
+ backOffBuilder = BeanDefinitionBuilder.genericBeanDefinition(ExponentialBackOffPolicy.class);
+ IntegrationNamespaceUtils.setValueIfAttributeDefined(backOffBuilder, backOffPolicyEle, "initial", "initialInterval");
+ IntegrationNamespaceUtils.setValueIfAttributeDefined(backOffBuilder, backOffPolicyEle, "multiplier");
+ IntegrationNamespaceUtils.setValueIfAttributeDefined(backOffBuilder, backOffPolicyEle, "maximum", "maxInterval");
+ }
+ }
+ if (backOffBuilder != null) {
+ retryTemplateBuilder.addPropertyValue("backOffPolicy", backOffBuilder.getBeanDefinition());
+ customTemplate = true;
+ }
+ String maxAttemptsAttr = element.getAttribute("max-attempts");
+ if (StringUtils.hasText(maxAttemptsAttr)) {
+ BeanDefinitionBuilder retryPolicyBuilder = BeanDefinitionBuilder.genericBeanDefinition(SimpleRetryPolicy.class);
+ IntegrationNamespaceUtils.setValueIfAttributeDefined(retryPolicyBuilder, element, "max-attempts");
+ retryTemplateBuilder.addPropertyValue("retryPolicy", retryPolicyBuilder.getBeanDefinition());
+ customTemplate = true;
+ }
+ if (customTemplate) {
+ builder.addPropertyValue("retryTemplate", retryTemplateBuilder.getBeanDefinition());
+ }
+ String recoveryChannelAttr = element.getAttribute("recovery-channel");
+ if (StringUtils.hasText(recoveryChannelAttr)) {
+ BeanDefinitionBuilder emsrBuilder = BeanDefinitionBuilder.genericBeanDefinition(ErrorMessageSendingRecoverer.class);
+ emsrBuilder.addConstructorArgReference(recoveryChannelAttr);
+ IntegrationNamespaceUtils.setValueIfAttributeDefined(emsrBuilder, element, "send-timeout");
+ builder.addPropertyValue("recoveryCallback", emsrBuilder.getBeanDefinition());
+ }
+ return builder.getBeanDefinition();
+ }
+
+}
diff --git a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-4.0.xsd b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-4.0.xsd
index 96824e4531..d0ddf26285 100644
--- a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-4.0.xsd
+++ b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-4.0.xsd
@@ -1321,7 +1321,7 @@
-
+
@@ -2599,7 +2599,7 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -4054,6 +4076,16 @@ The list of component name patterns you want to track (e.g., tracked-components
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/RetryAdviceParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/RetryAdviceParserTests-context.xml
new file mode 100644
index 0000000000..3a334835cb
--- /dev/null
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/RetryAdviceParserTests-context.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/RetryAdviceParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/RetryAdviceParserTests.java
new file mode 100644
index 0000000000..c6ad2de81c
--- /dev/null
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/RetryAdviceParserTests.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.integration.config.xml;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.integration.handler.advice.RequestHandlerRetryAdvice;
+import org.springframework.integration.test.util.TestUtils;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.MessageHandler;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Gary Russell
+ * @since 4.0
+ *
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class RetryAdviceParserTests {
+
+ @Autowired
+ private RequestHandlerRetryAdvice a1;
+
+ @Autowired
+ private RequestHandlerRetryAdvice a2;
+
+ @Autowired
+ private RequestHandlerRetryAdvice a3;
+
+ @Autowired
+ private RequestHandlerRetryAdvice a4;
+
+ @Autowired
+ private RequestHandlerRetryAdvice a5;
+
+ @Autowired
+ private RequestHandlerRetryAdvice a6;
+
+ @Autowired
+ private RequestHandlerRetryAdvice a7;
+
+ @Autowired @Qualifier("sa1.handler")
+ private MessageHandler handler1;
+
+ @Autowired @Qualifier("sa2.handler")
+ private MessageHandler handler2;
+
+ @Autowired
+ private MessageChannel foo;
+
+ @Test
+ public void testAll() {
+ assertEquals(Integer.valueOf(3), TestUtils.getPropertyValue(a1, "retryTemplate.retryPolicy.maxAttempts", Integer.class));
+ assertEquals(Integer.valueOf(4), TestUtils.getPropertyValue(a2, "retryTemplate.retryPolicy.maxAttempts", Integer.class));
+ assertEquals(Integer.valueOf(5), TestUtils.getPropertyValue(a3, "retryTemplate.retryPolicy.maxAttempts", Integer.class));
+ assertEquals(Integer.valueOf(6), TestUtils.getPropertyValue(a4, "retryTemplate.retryPolicy.maxAttempts", Integer.class));
+ assertEquals(Integer.valueOf(7), TestUtils.getPropertyValue(a5, "retryTemplate.retryPolicy.maxAttempts", Integer.class));
+ assertEquals(Integer.valueOf(8), TestUtils.getPropertyValue(a6, "retryTemplate.retryPolicy.maxAttempts", Integer.class));
+ assertEquals(Integer.valueOf(3), TestUtils.getPropertyValue(a7, "retryTemplate.retryPolicy.maxAttempts", Integer.class));
+
+ assertEquals(Long.valueOf(1000), TestUtils.getPropertyValue(a3, "retryTemplate.backOffPolicy.backOffPeriod", Long.class));
+ assertEquals(Long.valueOf(1234), TestUtils.getPropertyValue(a4, "retryTemplate.backOffPolicy.backOffPeriod", Long.class));
+
+ assertEquals(Long.valueOf(100), TestUtils.getPropertyValue(a5, "retryTemplate.backOffPolicy.initialInterval", Long.class));
+ assertEquals(Double.valueOf(2.0), TestUtils.getPropertyValue(a5, "retryTemplate.backOffPolicy.multiplier", Double.class));
+ assertEquals(Long.valueOf(30000), TestUtils.getPropertyValue(a5, "retryTemplate.backOffPolicy.maxInterval", Long.class));
+ assertEquals(Long.valueOf(1000), TestUtils.getPropertyValue(a6, "retryTemplate.backOffPolicy.initialInterval", Long.class));
+ assertEquals(Double.valueOf(3.0), TestUtils.getPropertyValue(a6, "retryTemplate.backOffPolicy.multiplier", Double.class));
+ assertEquals(Long.valueOf(10000), TestUtils.getPropertyValue(a6, "retryTemplate.backOffPolicy.maxInterval", Long.class));
+
+ assertNull(TestUtils.getPropertyValue(a1, "recoveryCallback"));
+ assertNotNull(TestUtils.getPropertyValue(a7, "recoveryCallback"));
+ assertSame(foo, TestUtils.getPropertyValue(a7, "recoveryCallback.messagingTemplate.defaultDestination"));
+ assertEquals(Long.valueOf(4567), TestUtils.getPropertyValue(a7, "recoveryCallback.messagingTemplate.sendTimeout"));
+
+ assertSame(a1, TestUtils.getPropertyValue(handler1, "adviceChain", List.class).get(0));
+ assertEquals(Integer.valueOf(9), TestUtils.getPropertyValue(TestUtils.getPropertyValue(handler2, "adviceChain", List.class).get(0),
+ "retryTemplate.retryPolicy.maxAttempts", Integer.class));
+ }
+
+}
diff --git a/spring-integration-event/src/main/resources/org/springframework/integration/event/config/spring-integration-event-4.0.xsd b/spring-integration-event/src/main/resources/org/springframework/integration/event/config/spring-integration-event-4.0.xsd
index 8d68e21fdb..cc42258eb6 100644
--- a/spring-integration-event/src/main/resources/org/springframework/integration/event/config/spring-integration-event-4.0.xsd
+++ b/spring-integration-event/src/main/resources/org/springframework/integration/event/config/spring-integration-event-4.0.xsd
@@ -69,7 +69,7 @@
-
+
diff --git a/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-4.0.xsd b/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-4.0.xsd
index b7aa392b24..21bc31d199 100644
--- a/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-4.0.xsd
+++ b/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-4.0.xsd
@@ -339,7 +339,7 @@ Only files matching this regular expression will be picked up by this adapter.
-
+
diff --git a/spring-integration-ftp/src/main/resources/org/springframework/integration/ftp/config/spring-integration-ftp-4.0.xsd b/spring-integration-ftp/src/main/resources/org/springframework/integration/ftp/config/spring-integration-ftp-4.0.xsd
index 51821b1df3..25dc7e44eb 100644
--- a/spring-integration-ftp/src/main/resources/org/springframework/integration/ftp/config/spring-integration-ftp-4.0.xsd
+++ b/spring-integration-ftp/src/main/resources/org/springframework/integration/ftp/config/spring-integration-ftp-4.0.xsd
@@ -24,7 +24,7 @@
-
+
@@ -204,7 +204,7 @@
-
+
diff --git a/spring-integration-gemfire/src/main/resources/org/springframework/integration/gemfire/config/xml/spring-integration-gemfire-4.0.xsd b/spring-integration-gemfire/src/main/resources/org/springframework/integration/gemfire/config/xml/spring-integration-gemfire-4.0.xsd
index 5275e684f7..5fbc3b26bd 100644
--- a/spring-integration-gemfire/src/main/resources/org/springframework/integration/gemfire/config/xml/spring-integration-gemfire-4.0.xsd
+++ b/spring-integration-gemfire/src/main/resources/org/springframework/integration/gemfire/config/xml/spring-integration-gemfire-4.0.xsd
@@ -141,7 +141,7 @@
-
+
diff --git a/spring-integration-groovy/src/main/resources/org/springframework/integration/groovy/config/spring-integration-groovy-4.0.xsd b/spring-integration-groovy/src/main/resources/org/springframework/integration/groovy/config/spring-integration-groovy-4.0.xsd
index 719a2f9d88..c91038cabd 100644
--- a/spring-integration-groovy/src/main/resources/org/springframework/integration/groovy/config/spring-integration-groovy-4.0.xsd
+++ b/spring-integration-groovy/src/main/resources/org/springframework/integration/groovy/config/spring-integration-groovy-4.0.xsd
@@ -52,7 +52,7 @@
-
+
diff --git a/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-4.0.xsd b/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-4.0.xsd
index e7185f417a..f51f0afb4c 100644
--- a/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-4.0.xsd
+++ b/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-4.0.xsd
@@ -326,7 +326,7 @@
-
+
@@ -360,7 +360,7 @@
-
+
diff --git a/spring-integration-ip/src/main/resources/org/springframework/integration/ip/config/spring-integration-ip-4.0.xsd b/spring-integration-ip/src/main/resources/org/springframework/integration/ip/config/spring-integration-ip-4.0.xsd
index f4cb3e21ff..e9f9d0119c 100644
--- a/spring-integration-ip/src/main/resources/org/springframework/integration/ip/config/spring-integration-ip-4.0.xsd
+++ b/spring-integration-ip/src/main/resources/org/springframework/integration/ip/config/spring-integration-ip-4.0.xsd
@@ -68,7 +68,7 @@
-
@@ -182,7 +182,7 @@
-
@@ -322,7 +322,7 @@
-
diff --git a/spring-integration-jdbc/src/main/resources/org/springframework/integration/jdbc/config/spring-integration-jdbc-4.0.xsd b/spring-integration-jdbc/src/main/resources/org/springframework/integration/jdbc/config/spring-integration-jdbc-4.0.xsd
index e4c8a09ea5..6fa18ccb42 100644
--- a/spring-integration-jdbc/src/main/resources/org/springframework/integration/jdbc/config/spring-integration-jdbc-4.0.xsd
+++ b/spring-integration-jdbc/src/main/resources/org/springframework/integration/jdbc/config/spring-integration-jdbc-4.0.xsd
@@ -226,7 +226,7 @@
-
+
@@ -313,7 +313,7 @@
-
+
@@ -610,7 +610,7 @@
-
+
@@ -746,7 +746,7 @@
-
+
diff --git a/spring-integration-jms/src/main/resources/org/springframework/integration/jms/config/spring-integration-jms-4.0.xsd b/spring-integration-jms/src/main/resources/org/springframework/integration/jms/config/spring-integration-jms-4.0.xsd
index f1d739066c..de57ec762e 100644
--- a/spring-integration-jms/src/main/resources/org/springframework/integration/jms/config/spring-integration-jms-4.0.xsd
+++ b/spring-integration-jms/src/main/resources/org/springframework/integration/jms/config/spring-integration-jms-4.0.xsd
@@ -738,7 +738,7 @@
-
+
-
+
diff --git a/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-4.0.xsd b/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-4.0.xsd
index c8bbf20c2f..6691dc9225 100644
--- a/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-4.0.xsd
+++ b/spring-integration-jmx/src/main/resources/org/springframework/integration/jmx/config/spring-integration-jmx-4.0.xsd
@@ -71,7 +71,7 @@
-
+
@@ -99,7 +99,7 @@
-
+
@@ -137,7 +137,7 @@
-
+
diff --git a/spring-integration-jpa/src/main/resources/org/springframework/integration/jpa/config/xml/spring-integration-jpa-4.0.xsd b/spring-integration-jpa/src/main/resources/org/springframework/integration/jpa/config/xml/spring-integration-jpa-4.0.xsd
index ba597fb9b1..829b175e3e 100644
--- a/spring-integration-jpa/src/main/resources/org/springframework/integration/jpa/config/xml/spring-integration-jpa-4.0.xsd
+++ b/spring-integration-jpa/src/main/resources/org/springframework/integration/jpa/config/xml/spring-integration-jpa-4.0.xsd
@@ -96,7 +96,7 @@
-
+
@@ -188,7 +188,7 @@
-
+
@@ -220,7 +220,7 @@
-
+
diff --git a/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-4.0.xsd b/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-4.0.xsd
index 93f816570d..e7d19fc3b2 100644
--- a/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-4.0.xsd
+++ b/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-4.0.xsd
@@ -28,7 +28,7 @@
-
+
diff --git a/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-4.0.xsd b/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-4.0.xsd
index 833050b12e..90726a84f2 100644
--- a/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-4.0.xsd
+++ b/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-4.0.xsd
@@ -95,7 +95,7 @@
-
+
diff --git a/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-4.0.xsd b/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-4.0.xsd
index 818e414895..a0b2114a4f 100644
--- a/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-4.0.xsd
+++ b/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-4.0.xsd
@@ -79,7 +79,7 @@
-
+
diff --git a/spring-integration-sftp/src/main/resources/org/springframework/integration/sftp/config/spring-integration-sftp-4.0.xsd b/spring-integration-sftp/src/main/resources/org/springframework/integration/sftp/config/spring-integration-sftp-4.0.xsd
index 335d417359..118b7bcca5 100644
--- a/spring-integration-sftp/src/main/resources/org/springframework/integration/sftp/config/spring-integration-sftp-4.0.xsd
+++ b/spring-integration-sftp/src/main/resources/org/springframework/integration/sftp/config/spring-integration-sftp-4.0.xsd
@@ -24,7 +24,7 @@
-
+
@@ -204,7 +204,7 @@
-
+
diff --git a/spring-integration-twitter/src/main/resources/org/springframework/integration/twitter/config/spring-integration-twitter-4.0.xsd b/spring-integration-twitter/src/main/resources/org/springframework/integration/twitter/config/spring-integration-twitter-4.0.xsd
index 1679579cc5..b2b9856daf 100644
--- a/spring-integration-twitter/src/main/resources/org/springframework/integration/twitter/config/spring-integration-twitter-4.0.xsd
+++ b/spring-integration-twitter/src/main/resources/org/springframework/integration/twitter/config/spring-integration-twitter-4.0.xsd
@@ -176,7 +176,7 @@
-
+
diff --git a/spring-integration-ws/src/main/resources/org/springframework/integration/ws/config/spring-integration-ws-4.0.xsd b/spring-integration-ws/src/main/resources/org/springframework/integration/ws/config/spring-integration-ws-4.0.xsd
index abd5fd5565..3c1fbb2075 100644
--- a/spring-integration-ws/src/main/resources/org/springframework/integration/ws/config/spring-integration-ws-4.0.xsd
+++ b/spring-integration-ws/src/main/resources/org/springframework/integration/ws/config/spring-integration-ws-4.0.xsd
@@ -29,7 +29,7 @@
-
+
diff --git a/spring-integration-xmpp/src/main/resources/org/springframework/integration/xmpp/config/spring-integration-xmpp-4.0.xsd b/spring-integration-xmpp/src/main/resources/org/springframework/integration/xmpp/config/spring-integration-xmpp-4.0.xsd
index 036089e8e7..e104841b86 100644
--- a/spring-integration-xmpp/src/main/resources/org/springframework/integration/xmpp/config/spring-integration-xmpp-4.0.xsd
+++ b/spring-integration-xmpp/src/main/resources/org/springframework/integration/xmpp/config/spring-integration-xmpp-4.0.xsd
@@ -194,7 +194,7 @@
-
+
diff --git a/src/reference/docbook/handler-advice.xml b/src/reference/docbook/handler-advice.xml
index 63af9ac14a..d3993c61dd 100644
--- a/src/reference/docbook/handler-advice.xml
+++ b/src/reference/docbook/handler-advice.xml
@@ -79,29 +79,29 @@
The retry advice (o.s.i.handler.advice.RequestHandlerRetryAdvice)
leverages the rich retry mechanisms provided by the
Spring Retry project. The core component
- of spring-retry is the RetryTemplate, which allows configuration
+ of spring-retry is the RetryTemplate, which allows configuration
of sophisticated retry scenarios, including RetryPolicy and BackoffPolicy
strategies, with a number of implementations,
as well as a RecoveryCallback strategy to determine the action to take when retries
are exhausted.
- Stateless Retry
+ Stateless Retry
Stateless retry is the case where the retry activity is handled entirely within the advice, where the thread
pauses (if so configured) and retries the action.
- Stateful Retry
+ Stateful Retry
Stateful retry is the case where the retry state is managed within the advice, but where an exception is thrown
and the caller resubmits the request. An example for stateful retry is when we want the message originator
(e.g. JMS) to be responsible for resubmitting, rather than performing it on the current thread. Stateful retry
needs some mechanism to detect a retried submission.
- Further Information
+ Further Information
- For more information on spring-retry, refer to the project's javadocs, as well as the
+ For more information on spring-retry, refer to the project's javadocs, as well as the
reference documentation for
- Spring Batch, where spring-retry originated.
+ Spring Batch, where spring-retry originated.
The default back off behavior is no back off - retries are attempted immediately.
@@ -120,14 +120,15 @@
}
}]]>
- Simple Stateless Retry
+ Simple Stateless Retry
- This example uses the default RetryTemplate which has a
- SimpleRetryPolicy which tries 3 times. There is no BackoffPolicy
+ This example uses the default RetryTemplate which has a
+ SimpleRetryPolicy which tries 3 times. There is no
+ BackOffPolicy
so the 3 attempts are made back-to-back-to-back with no delay between attempts. There is no
- RecoveryCallback so, the result is to throw the
+ RecoveryCallback so, the result is to throw the
exception to the caller after the final failed retry occurs. In a Spring Integration
- environment, this final exception might be handled using an error-channel on
+ environment, this final exception might be handled using an error-channel on
the inbound endpoint.
@@ -144,11 +145,11 @@ DEBUG [task-scheduler-2]Checking for rethrow: count=2
DEBUG [task-scheduler-2]Retry: count=2
DEBUG [task-scheduler-2]Checking for rethrow: count=3
DEBUG [task-scheduler-2]Retry failed last attempt: count=3]]>
- Simple Stateless Retry with Recovery
+ Simple Stateless Retry with Recovery
This example adds a RecoveryCallback to the
above example; it uses a ErrorMessageSendingRecoverer
- to send an ErrorMessage to a channel.
+ to send an ErrorMessage to a channel.
@@ -171,9 +172,9 @@ DEBUG [task-scheduler-2]Retry: count=2
DEBUG [task-scheduler-2]Checking for rethrow: count=3
DEBUG [task-scheduler-2]Retry failed last attempt: count=3
DEBUG [task-scheduler-2]Sending ErrorMessage :failedMessage:[Payload=...]]]>
- Stateless Retry with Customized Policies, and Recovery
+ Stateless Retry with Customized Policies, and Recovery
- For more sophistication, we can provide the advice with a customized RetryTemplate.
+ For more sophistication, we can provide the advice with a customized RetryTemplate.
This example continues to use the SimpleRetryPolicy but it
increases the attempts to 4. It also adds an ExponentialBackoffPolicy
where the first retry waits 1 second, the second waits 5 seconds and the third waits 25 (for 4
@@ -201,7 +202,8 @@ DEBUG [task-scheduler-2]Sending ErrorMessage :failedMessage:[Payload=...]]]>
-
+
+
@@ -220,11 +222,48 @@ DEBUG [task-scheduler-2]Sending ErrorMessage :failedMessage:[Payload=...]]]>
- Simple Stateful Retry with Recovery
+ Namespace Support for Stateless Retry
+
+ Starting with version 4.0, the above configuration can be greatly
+ simplified with the namespace support for the retry advice:
+
+
+
+
+
+
+
+
+
+]]>
+
+ In this example, the advice is defined as a top level bean so it can be used
+ in multiple request-handler-advice-chains. You can also
+ define the advice directly within the chain:
+
+
+
+
+
+
+
+]]>
+
+ A <handler-retry-advice/> with no child element uses
+ no back off; it can have a fixed-back-off or
+ exponential-back-off child element. If there is no
+ recovery-channel, the exception is thrown when retries are
+ exhausted. The namespace can only be used with stateless retry.
+
+
+ For more complex environments (custom policies etc), use normal
+ <bean/> definitions.
+
+ Simple Stateful Retry with Recovery
To make retry stateful, we need to provide the Advice with a RetryStateGenerator
implementation. This class is used to identify a message as being a resubmission
- so that the RetryTemplate can determine the current state of retry
+ so that the RetryTemplate can determine the current state of retry
for this message. The framework provides a SpelExpressionRetryStateGenerator
which determines the message identifier using a SpEL expression.
This is shown below; this example again uses the default policies (3 attempts with no back off); of
@@ -289,7 +328,7 @@ Caused by: java.lang.RuntimeException: foo
- Exception Classification for Retry
+ Exception Classification for Retry
diff --git a/src/reference/docbook/whats-new.xml b/src/reference/docbook/whats-new.xml
index e2aca6ccf9..819dabd3aa 100644
--- a/src/reference/docbook/whats-new.xml
+++ b/src/reference/docbook/whats-new.xml
@@ -133,5 +133,13 @@
For more information see .
+
+ Simpler Retry Advice Configuration
+
+ Simplified namespace support has been added to configure a
+ RequestHandlerRetryAdvice.
+ For more information see .
+
+