* During pre-parsing of XML look for references to the same bean and if multiple

matches found, create new bean definitions and update the reference in the preprocessed
XML to allow for unique instances.

* Use job scope for job level listeners

* Remove call to application context close in JsrJobOperator.restart

Fixes TCK tests:
--
testTransitionElementOnAttrValuesWithRestartJobParamOverrides
testChunkArtifactInstanceUniqueness
testOneArtifactIsJobAndStepListener
This commit is contained in:
Chris Schaefer
2014-02-10 09:46:28 -05:00
parent 1a6ba98fc4
commit a1ee097dd4
10 changed files with 313 additions and 18 deletions

View File

@@ -6,15 +6,21 @@ import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.springframework.batch.core.jsr.JsrTestUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.xml.DefaultDocumentLoader;
import org.springframework.beans.factory.xml.DelegatingEntityResolver;
import org.springframework.beans.factory.xml.DocumentLoader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.SimpleSaxErrorHandler;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import javax.batch.api.Batchlet;
import javax.batch.runtime.JobExecution;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
@@ -124,6 +130,107 @@ public class JsrBeanDefinitionDocumentReaderTests {
assertEquals("myfile.txt", resolvedProperties.getProperty("jobProperty3"));
}
@Test
public void testGenerationOfBeanDefinitionsForMultipleReferences() throws Exception {
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(new Properties());
applicationContext.setValidating(false);
applicationContext.load(new ClassPathResource("baseContext.xml"),
new ClassPathResource("/META-INF/batch.xml"),
new ClassPathResource("/META-INF/batch-jobs/jsrUniqueInstanceTests.xml"));
applicationContext.refresh();
assertTrue("exitStatusSettingStepListener bean definition not found", applicationContext.containsBeanDefinition("exitStatusSettingStepListener"));
assertTrue("exitStatusSettingStepListener1 bean definition not found", applicationContext.containsBeanDefinition("exitStatusSettingStepListener1"));
assertTrue("exitStatusSettingStepListener2 bean definition not found", applicationContext.containsBeanDefinition("exitStatusSettingStepListener2"));
assertTrue("exitStatusSettingStepListener3 bean definition not found", applicationContext.containsBeanDefinition("exitStatusSettingStepListener3"));
assertTrue("exitStatusSettingStepListenerClassBeanDefinition bean definition not found", applicationContext.containsBeanDefinition("org.springframework.batch.core.jsr.step.listener.ExitStatusSettingStepListener"));
assertTrue("exitStatusSettingStepListener1ClassBeanDefinition bean definition not found", applicationContext.containsBeanDefinition("org.springframework.batch.core.jsr.step.listener.ExitStatusSettingStepListener1"));
assertTrue("exitStatusSettingStepListener2ClassBeanDefinition bean definition not found", applicationContext.containsBeanDefinition("org.springframework.batch.core.jsr.step.listener.ExitStatusSettingStepListener2"));
assertTrue("exitStatusSettingStepListener3ClassBeanDefinition bean definition not found", applicationContext.containsBeanDefinition("org.springframework.batch.core.jsr.step.listener.ExitStatusSettingStepListener3"));
assertTrue("testBatchlet bean definition not found", applicationContext.containsBeanDefinition("testBatchlet"));
assertTrue("testBatchlet1 bean definition not found", applicationContext.containsBeanDefinition("testBatchlet1"));
assertTrue("testBatchlet2 bean definition not found", applicationContext.containsBeanDefinition("testBatchlet2"));
}
@Test
public void testArtifactUniqueness() throws Exception {
JobExecution jobExecution = JsrTestUtils.runJob("jsrUniqueInstanceTests", new Properties(), 10000L);
String exitStatus = jobExecution.getExitStatus();
assertTrue("Exit status must contain listener3", exitStatus.contains("listener3"));
exitStatus = exitStatus.replace("listener3", "");
assertTrue("Exit status must contain listener2", exitStatus.contains("listener2"));
exitStatus = exitStatus.replace("listener2", "");
assertTrue("Exit status must contain listener1", exitStatus.contains("listener1"));
exitStatus = exitStatus.replace("listener1", "");
assertTrue("Exit status must contain listener0", exitStatus.contains("listener0"));
exitStatus = exitStatus.replace("listener0", "");
assertTrue("Exit status must contain listener7", exitStatus.contains("listener7"));
exitStatus = exitStatus.replace("listener7", "");
assertTrue("Exit status must contain listener6", exitStatus.contains("listener6"));
exitStatus = exitStatus.replace("listener6", "");
assertTrue("Exit status must contain listener5", exitStatus.contains("listener5"));
exitStatus = exitStatus.replace("listener5", "");
assertTrue("Exit status must contain listener4", exitStatus.contains("listener4"));
exitStatus = exitStatus.replace("listener4", "");
assertTrue("exitStatus must be empty", "".equals(exitStatus));
}
@Test
public void testGenerationOfSpringBeanDefinitionsForMultipleReferences() {
JsrXmlApplicationContext applicationContext = new JsrXmlApplicationContext(new Properties());
applicationContext.setValidating(false);
applicationContext.load(new ClassPathResource("baseContext.xml"),
new ClassPathResource("/META-INF/batch-jobs/jsrSpringInstanceTests.xml"));
applicationContext.refresh();
assertTrue("exitStatusSettingStepListener bean definition not found", applicationContext.containsBeanDefinition("exitStatusSettingStepListener"));
assertTrue("scopedTarget.exitStatusSettingStepListener bean definition not found", applicationContext.containsBeanDefinition("scopedTarget.exitStatusSettingStepListener"));
BeanDefinition exitStatusSettingStepListenerBeanDefinition = applicationContext.getBeanDefinition("scopedTarget.exitStatusSettingStepListener");
assertTrue("step".equals(exitStatusSettingStepListenerBeanDefinition.getScope()));
assertTrue("Should not contain bean definition for exitStatusSettingStepListener1", !applicationContext.containsBeanDefinition("exitStatusSettingStepListener1"));
assertTrue("Should not contain bean definition for exitStatusSettingStepListener2", !applicationContext.containsBeanDefinition("exitStatusSettingStepListener2"));
assertTrue("Should not contain bean definition for exitStatusSettingStepListener3", !applicationContext.containsBeanDefinition("exitStatusSettingStepListener3"));
assertTrue("Should not contain bean definition for testBatchlet1", !applicationContext.containsBeanDefinition("testBatchlet1"));
assertTrue("Should not contain bean definition for testBatchlet2", !applicationContext.containsBeanDefinition("testBatchlet2"));
assertTrue("testBatchlet bean definition not found", applicationContext.containsBeanDefinition("testBatchlet"));
BeanDefinition testBatchletBeanDefinition = applicationContext.getBeanDefinition("testBatchlet");
assertTrue("singleton".equals(testBatchletBeanDefinition.getScope()));
}
@Test
public void testSpringArtifactUniqueness() throws Exception {
JobExecution jobExecution = JsrTestUtils.runJob("jsrSpringInstanceTests", new Properties(), 10000L);
String exitStatus = jobExecution.getExitStatus();
assertEquals("listener1listener1listener4listener4", exitStatus);
assertTrue("Exit status must contain listener1", exitStatus.contains("listener1"));
assertTrue("exitStatus must contain 2 listener1 values", StringUtils.countOccurrencesOf(exitStatus, "listener1") == 2);
exitStatus = exitStatus.replace("listener1", "");
assertTrue("Exit status must contain listener4", exitStatus.contains("listener4"));
assertTrue("exitStatus must contain 2 listener4 values", StringUtils.countOccurrencesOf(exitStatus, "listener4") == 2);
exitStatus = exitStatus.replace("listener4", "");
assertTrue("exitStatus must be empty", "".equals(exitStatus));
}
private Document getDocument(String location) {
InputStream inputStream = ClassLoader.class.getResourceAsStream(location);
@@ -138,4 +245,16 @@ public class JsrBeanDefinitionDocumentReaderTests {
} catch (IOException e) { }
}
}
public static class TestBatchlet implements Batchlet {
@Override
public String process() throws Exception {
return null;
}
@Override
public void stop() throws Exception {
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-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.
@@ -60,6 +60,6 @@ public class ListenerParserTests {
listenerParser.applyListenerScope("jobListener", applicationContext);
BeanDefinition beanDefinition = applicationContext.getBeanDefinition("jobListener");
assertEquals("singleton", beanDefinition.getScope());
assertEquals("job", beanDefinition.getScope());
}
}

View File

@@ -0,0 +1,40 @@
package org.springframework.batch.core.jsr.step.listener;
import javax.batch.api.BatchProperty;
import javax.batch.api.listener.StepListener;
import javax.batch.runtime.context.JobContext;
import javax.inject.Inject;
/**
* <p>
* {@link StepListener} for testing. Sets or appends the value of the
* testProperty field to the {@link JobContext} exit status on afterStep.
* </p>
*
* @author Chris Schaefer
* @since 3.0
*/
public class ExitStatusSettingStepListener implements StepListener {
@Inject
@BatchProperty
private String testProperty;
@Inject
private JobContext jobContext;
@Override
public void beforeStep() throws Exception {
}
@Override
public void afterStep() throws Exception {
String exitStatus = jobContext.getExitStatus();
if("".equals(exitStatus) || exitStatus == null) {
jobContext.setExitStatus(testProperty);
} else {
jobContext.setExitStatus(exitStatus + testProperty);
}
}
}