BATCH-63: added <retry-listeners>
This commit is contained in:
@@ -266,6 +266,8 @@ public class StepParser {
|
||||
|
||||
handleListenersElement(element, bd, parserContext);
|
||||
|
||||
handleRetryListenersElement(element, bd, parserContext);
|
||||
|
||||
handleStreamsElement(element, bd, parserContext);
|
||||
|
||||
bd.setRole(BeanDefinition.ROLE_SUPPORT);
|
||||
@@ -299,50 +301,71 @@ public class StepParser {
|
||||
DomUtils.getChildElementByTagName(element, "listeners");
|
||||
if (listenersElement != null) {
|
||||
List<BeanReference> listenerBeans = new ArrayList<BeanReference>();
|
||||
List<Element> listenerElements =
|
||||
DomUtils.getChildElementsByTagName(listenersElement, "listener");
|
||||
if (listenerElements != null) {
|
||||
for (Element listenerElement : listenerElements) {
|
||||
String id = listenerElement.getAttribute("id");
|
||||
String listenerRef = listenerElement.getAttribute("ref");
|
||||
String className = listenerElement.getAttribute("class");
|
||||
if ((StringUtils.hasText(id) || StringUtils.hasText(className))
|
||||
&& StringUtils.hasText(listenerRef)) {
|
||||
NamedNodeMap attributeNodes = listenerElement.getAttributes();
|
||||
StringBuilder attributes = new StringBuilder();
|
||||
for (int i = 0; i < attributeNodes.getLength(); i++) {
|
||||
if (i > 0) {
|
||||
attributes.append(" ");
|
||||
}
|
||||
attributes.append(attributeNodes.item(i));
|
||||
}
|
||||
throw new BeanCreationException("Both 'id' or 'ref' plus 'class' specified; use 'class' with an optional 'id' or just 'ref' for <" +
|
||||
listenerElement.getTagName() + "> element with attributes: " + attributes);
|
||||
}
|
||||
if (StringUtils.hasText(listenerRef)) {
|
||||
BeanReference bean = new RuntimeBeanReference(listenerRef);
|
||||
listenerBeans.add(bean);
|
||||
}
|
||||
else if (StringUtils.hasText(className)) {
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(className, null, null);
|
||||
if (!StringUtils.hasText(id)) {
|
||||
id = parserContext.getReaderContext().generateBeanName(beanDef);
|
||||
}
|
||||
parserContext.getRegistry().registerBeanDefinition(id, beanDef);
|
||||
BeanReference bean = new RuntimeBeanReference(id);
|
||||
listenerBeans.add(bean);
|
||||
}
|
||||
else {
|
||||
throw new BeanCreationException("Neither 'ref' or 'class' specified for <" + listenerElement.getTagName() + "> element");
|
||||
}
|
||||
}
|
||||
}
|
||||
handleListenerElements(parserContext, listenersElement,
|
||||
listenerBeans);
|
||||
ManagedList arguments = new ManagedList();
|
||||
arguments.addAll(listenerBeans);
|
||||
bd.getPropertyValues().addPropertyValue("listeners", arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void handleRetryListenersElement(Element element, RootBeanDefinition bd, ParserContext parserContext) {
|
||||
Element retryListenersElement =
|
||||
DomUtils.getChildElementByTagName(element, "retry-listeners");
|
||||
if (retryListenersElement != null) {
|
||||
List<BeanReference> retryListenerBeans = new ArrayList<BeanReference>();
|
||||
handleListenerElements(parserContext, retryListenersElement,
|
||||
retryListenerBeans);
|
||||
ManagedList arguments = new ManagedList();
|
||||
arguments.addAll(retryListenerBeans);
|
||||
bd.getPropertyValues().addPropertyValue("retryListeners", arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void handleListenerElements(ParserContext parserContext,
|
||||
Element element, List<BeanReference> beans) {
|
||||
List<Element> listenerElements =
|
||||
DomUtils.getChildElementsByTagName(element, "listener");
|
||||
if (listenerElements != null) {
|
||||
for (Element listenerElement : listenerElements) {
|
||||
String id = listenerElement.getAttribute("id");
|
||||
String listenerRef = listenerElement.getAttribute("ref");
|
||||
String className = listenerElement.getAttribute("class");
|
||||
if ((StringUtils.hasText(id) || StringUtils.hasText(className))
|
||||
&& StringUtils.hasText(listenerRef)) {
|
||||
NamedNodeMap attributeNodes = listenerElement.getAttributes();
|
||||
StringBuilder attributes = new StringBuilder();
|
||||
for (int i = 0; i < attributeNodes.getLength(); i++) {
|
||||
if (i > 0) {
|
||||
attributes.append(" ");
|
||||
}
|
||||
attributes.append(attributeNodes.item(i));
|
||||
}
|
||||
throw new BeanCreationException("Both 'id' or 'ref' plus 'class' specified; use 'class' with an optional 'id' or just 'ref' for <" +
|
||||
listenerElement.getTagName() + "> element with attributes: " + attributes);
|
||||
}
|
||||
if (StringUtils.hasText(listenerRef)) {
|
||||
BeanReference bean = new RuntimeBeanReference(listenerRef);
|
||||
beans.add(bean);
|
||||
}
|
||||
else if (StringUtils.hasText(className)) {
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(className, null, null);
|
||||
if (!StringUtils.hasText(id)) {
|
||||
id = parserContext.getReaderContext().generateBeanName(beanDef);
|
||||
}
|
||||
parserContext.getRegistry().registerBeanDefinition(id, beanDef);
|
||||
BeanReference bean = new RuntimeBeanReference(id);
|
||||
beans.add(bean);
|
||||
}
|
||||
else {
|
||||
throw new BeanCreationException("Neither 'ref' or 'class' specified for <" + listenerElement.getTagName() + "> element");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void handleStreamsElement(Element element, RootBeanDefinition bd, ParserContext parserContext) {
|
||||
Element streamsElement =
|
||||
|
||||
@@ -251,7 +251,7 @@
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="retryListeners" minOccurs="0" maxOccurs="1">
|
||||
<xsd:element name="retry-listeners" minOccurs="0" maxOccurs="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
List of all listeners for the step definition
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
|
||||
import org.springframework.batch.core.step.item.FaultTolerantStepFactoryBean;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.retry.RetryListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -59,6 +60,9 @@ public class StepWithFaultTolerantProcessTaskJobParserTests {
|
||||
@Qualifier("listener")
|
||||
private TestListener listener;
|
||||
|
||||
@Autowired
|
||||
private TestRetryListener retryListener;
|
||||
|
||||
@Autowired
|
||||
private TestProcessor processor;
|
||||
|
||||
@@ -85,6 +89,8 @@ public class StepWithFaultTolerantProcessTaskJobParserTests {
|
||||
assertEquals("wrong retry-limit:", 3, rl);
|
||||
Object listeners = ReflectionTestUtils.getField(factory, "listeners");
|
||||
assertEquals("wrong number of listeners:", 2, ((StepListener[])listeners).length);
|
||||
Object retryListeners = ReflectionTestUtils.getField(factory, "retryListeners");
|
||||
assertEquals("wrong number of retry-listeners:", 1, ((RetryListener[])retryListeners).length);
|
||||
Object streams = ReflectionTestUtils.getField(factory, "streams");
|
||||
assertEquals("wrong number of streams:", 1, ((ItemStream[])streams).length);
|
||||
JobExecution jobExecution = jobRepository.createJobExecution(job.getName(), new JobParameters());
|
||||
@@ -96,5 +102,6 @@ public class StepWithFaultTolerantProcessTaskJobParserTests {
|
||||
assertTrue(processor.isExecuted());
|
||||
assertTrue(writer.isExecuted());
|
||||
assertTrue(listener.isExecuted());
|
||||
assertTrue(retryListener.isExecuted());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.springframework.batch.core.configuration.xml;
|
||||
|
||||
import org.springframework.batch.retry.RetryCallback;
|
||||
import org.springframework.batch.retry.RetryContext;
|
||||
import org.springframework.batch.retry.RetryListener;
|
||||
|
||||
public class TestRetryListener extends AbstractTestComponent implements RetryListener {
|
||||
|
||||
public <T> void close(RetryContext context, RetryCallback<T> callback,
|
||||
Throwable throwable) {
|
||||
}
|
||||
|
||||
public <T> void onError(RetryContext context, RetryCallback<T> callback,
|
||||
Throwable throwable) {
|
||||
}
|
||||
|
||||
public <T> boolean open(RetryContext context, RetryCallback<T> callback) {
|
||||
System.out.println("RETRY RETRY RETRY RETRY");
|
||||
executed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,6 +14,9 @@
|
||||
<listener class="org.springframework.batch.core.configuration.xml.TestListener"/>
|
||||
<listener ref="listener"/>
|
||||
</listeners>
|
||||
<retry-listeners>
|
||||
<listener class="org.springframework.batch.core.configuration.xml.TestRetryListener"/>
|
||||
</retry-listeners>
|
||||
<streams>
|
||||
<stream ref="reader"/>
|
||||
</streams>
|
||||
|
||||
Reference in New Issue
Block a user