BATCH-1999: Initial commit of JSR parsing infrastructure

This commit is contained in:
Michael Minella
2013-05-03 11:23:11 -05:00
parent f4d2264c4a
commit e4c33965a0
44 changed files with 2234 additions and 80 deletions

View File

@@ -92,7 +92,6 @@ public class InlineItemHandlerParserTests {
Map<String,ItemReader> readers = context.getBeansOfType(ItemReader.class);
// Should be 2 each (proxy and target) for the two readers in the steps defined
assertEquals(4, readers.size());
// System.err.println(readers);
}
}

View File

@@ -0,0 +1,44 @@
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"DecisionParsingTests-context.xml", "jsr-base-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class DecisionParsingTests {
@Autowired
public Job job;
@Autowired
public JobLauncher jobLauncher;
@Test
public void test() throws Exception {
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
assertEquals(2, execution.getStepExecutions().size());
}
public static class TestDecider implements JobExecutionDecider {
@Override
public FlowExecutionStatus decide(JobExecution jobExecution,
StepExecution stepExecution) {
return new FlowExecutionStatus("step2");
}
}
}

View File

@@ -0,0 +1,93 @@
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"ExceptionHandlingParsingTests-context.xml", "jsr-base-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class ExceptionHandlingParsingTests {
@Autowired
public Job job;
@Autowired
public JobLauncher jobLauncher;
@Test
public void testSkippable() throws Exception {
JobExecution execution1 = jobLauncher.run(job, new JobParametersBuilder().addLong("run", 1l).toJobParameters());
assertEquals(BatchStatus.FAILED, execution1.getStatus());
assertEquals(1, execution1.getStepExecutions().size());
assertEquals(1, execution1.getStepExecutions().iterator().next().getSkipCount());
assertTrue(execution1.getAllFailureExceptions().get(0).getMessage().contains("But don't skip me"));
JobExecution execution2 = jobLauncher.run(job, new JobParametersBuilder().addLong("run", 2l).toJobParameters());
assertEquals(BatchStatus.FAILED, execution2.getStatus());
assertEquals(2, execution2.getStepExecutions().size());
assertTrue(execution2.getAllFailureExceptions().get(0).getMessage().contains("But don't retry me"));
JobExecution execution3 = jobLauncher.run(job, new JobParametersBuilder().addLong("run", 3l).toJobParameters());
assertEquals(BatchStatus.COMPLETED, execution3.getStatus());
assertEquals(3, execution3.getStepExecutions().size());
List<StepExecution> stepExecutions = new ArrayList<StepExecution>(execution3.getStepExecutions());
assertEquals(0, stepExecutions.get(2).getRollbackCount());
JobExecution execution4 = jobLauncher.run(job, new JobParametersBuilder().addLong("run", 4l).toJobParameters());
assertEquals(BatchStatus.COMPLETED, execution4.getStatus());
assertEquals(3, execution4.getStepExecutions().size());
}
public static class ProblemProcessor implements ItemProcessor<String, String> {
private long runId = 0;
private boolean hasRetried = false;
public void setRunId(long id) {
this.runId = id;
}
@Override
public String process(String item) throws Exception {
throwException(item);
return item;
}
private void throwException(String item) throws Exception {
if(runId == 1) {
if(item.equals("One")) {
throw new Exception("skip me");
} else if(item.equals("Two")){
throw new RuntimeException("But don't skip me");
}
} else if(runId == 2) {
if(item.equals("Three") && !hasRetried) {
hasRetried = true;
throw new Exception("retry me");
} else if(item.equals("Four")){
throw new RuntimeException("But don't retry me");
}
} else if(runId == 3) {
if(item.equals("Five")) {
throw new Exception("Don't rollback on my account");
}
}
}
}
}

View File

@@ -0,0 +1,178 @@
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.SkipListener;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"ItemSkipParsingTests-context.xml", "jsr-base-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class ItemSkipParsingTests {
@Autowired
public Job job;
@Autowired
public JobLauncher jobLauncher;
@Autowired
public TestSkipListener skipListener;
@Test
public void test() throws Exception {
// Read skip and fail
JobExecution execution = jobLauncher.run(job, new JobParametersBuilder().toJobParameters());
assertEquals(BatchStatus.FAILED, execution.getStatus());
assertEquals(1, execution.getStepExecutions().iterator().next().getSkipCount());
assertEquals(1, skipListener.readSkips);
assertEquals(0, skipListener.processSkips);
assertEquals(0, skipListener.writeSkips);
assertEquals("read fail because of me", execution.getAllFailureExceptions().get(0).getCause().getMessage());
skipListener.resetCounts();
// Process skip and fail
execution = jobLauncher.run(job, new JobParametersBuilder().toJobParameters());
assertEquals(BatchStatus.FAILED, execution.getStatus());
assertEquals(1, execution.getStepExecutions().iterator().next().getSkipCount());
assertEquals(0, skipListener.readSkips);
assertEquals(1, skipListener.processSkips);
assertEquals(0, skipListener.writeSkips);
assertEquals("process fail because of me", execution.getAllFailureExceptions().get(0).getCause().getMessage());
skipListener.resetCounts();
// Write skip and fail
execution = jobLauncher.run(job, new JobParametersBuilder().toJobParameters());
assertEquals(BatchStatus.FAILED, execution.getStatus());
assertEquals(1, execution.getStepExecutions().iterator().next().getSkipCount());
assertEquals(0, skipListener.readSkips);
assertEquals(0, skipListener.processSkips);
assertEquals(1, skipListener.writeSkips);
assertEquals("write fail because of me", execution.getAllFailureExceptions().get(0).getCause().getMessage());
skipListener.resetCounts();
// Complete
execution = jobLauncher.run(job, new JobParametersBuilder().toJobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
assertEquals(0, execution.getStepExecutions().iterator().next().getSkipCount());
assertEquals(0, skipListener.readSkips);
assertEquals(0, skipListener.processSkips);
assertEquals(0, skipListener.writeSkips);
}
public static class SkipErrorGeneratingReader implements ItemReader<String> {
private int count = 0;
@Override
public String read() throws Exception, UnexpectedInputException,
ParseException, NonTransientResourceException {
count++;
if(count == 1) {
throw new Exception("read skip me");
} else if (count == 2) {
return "item" + count;
} else if(count == 3) {
throw new RuntimeException("read fail because of me");
} else if(count < 15) {
return "item" + count;
} else {
return null;
}
}
}
public static class SkipErrorGeneratingProcessor implements ItemProcessor<String, String> {
private int count = 0;
@Override
public String process(String item) throws Exception {
count++;
if(count == 4) {
throw new Exception("process skip me");
} else if(count == 5) {
return item;
} else if(count == 6) {
throw new RuntimeException("process fail because of me");
} else {
return item;
}
}
}
public static class SkipErrorGeneratingWriter implements ItemWriter<String> {
private int count = 0;
protected List<String> writtenItems = new ArrayList<String>();
private List<String> skippedItems = new ArrayList<String>();
@Override
public void write(List<? extends String> items) throws Exception {
if(items.size() > 0 && !skippedItems.contains(items.get(0))) {
count++;
}
if(count == 7) {
skippedItems.addAll(items);
throw new Exception("write skip me");
} else if(count == 9) {
skippedItems = new ArrayList<String>();
throw new RuntimeException("write fail because of me");
} else {
writtenItems.addAll(items);
}
}
}
public static class TestSkipListener implements SkipListener<String, String> {
protected int readSkips = 0;
protected int processSkips = 0;
protected int writeSkips = 0;
@Override
public void onSkipInRead(Throwable t) {
readSkips++;
}
@Override
public void onSkipInWrite(String item, Throwable t) {
writeSkips++;
}
@Override
public void onSkipInProcess(String item, Throwable t) {
processSkips++;
}
public void resetCounts() {
readSkips = 0;
processSkips = 0;
writeSkips = 0;
}
}
}

View File

@@ -0,0 +1,58 @@
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"JobListenerParsingTests-context.xml", "jsr-base-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class JobListenerParsingTests {
@Autowired
public Job job;
@Autowired
public JobLauncher jobLauncher;
@Autowired
public JobListener listener;
@Test
public void test() throws Exception {
assertNotNull(job);
assertEquals("job1", job.getName());
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
assertEquals(2, execution.getStepExecutions().size());
assertEquals(1, listener.countAfterJob);
assertEquals(1, listener.countBeforeJob);
}
public static class JobListener implements JobExecutionListener {
protected int countBeforeJob = 0;
protected int countAfterJob = 0;
@Override
public void beforeJob(JobExecution jobExecution) {
countBeforeJob++;
}
@Override
public void afterJob(JobExecution jobExecution) {
countAfterJob++;
}
}
}

View File

@@ -0,0 +1,90 @@
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.repeat.CompletionPolicy;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"SimpleItemBasedJobParsingTests-context.xml", "jsr-base-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class SimpleItemBasedJobParsingTests {
@Autowired
public Job job;
@Autowired
public Step step1;
@Autowired
public CountingItemProcessor processor;
@Autowired
public CountingCompletionPolicy policy;
@Autowired
public JobLauncher jobLauncher;
@Test
public void test() throws Exception {
assertNotNull(job);
assertEquals("job1", job.getName());
assertNotNull(step1);
assertEquals("step1", step1.getName());
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
assertEquals(3, execution.getStepExecutions().size());
assertEquals(2, processor.count);
assertEquals(3, policy.counter);
}
public static class CountingItemProcessor implements ItemProcessor<String, String>{
protected int count = 0;
@Override
public String process(String item) throws Exception {
count++;
return item;
}
}
public static class CountingCompletionPolicy implements CompletionPolicy {
protected int counter;
@Override
public boolean isComplete(RepeatContext context, RepeatStatus result) {
return counter == 3;
}
@Override
public boolean isComplete(RepeatContext context) {
return counter == 3;
}
@Override
public RepeatContext start(RepeatContext parent) {
counter = 0;
return parent;
}
@Override
public void update(RepeatContext context) {
counter++;
}
}
}

View File

@@ -0,0 +1,56 @@
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"SimpleJobParsingTests-context.xml", "jsr-base-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class SimpleJobParsingTests {
@Autowired
public Job job;
@Autowired
@Qualifier("step1")
public Step step1;
@Autowired
@Qualifier("step2")
public Step step2;
@Autowired
@Qualifier("step3")
public Step step3;
@Autowired
public JobLauncher jobLauncher;
@Test
public void test() throws Exception {
assertNotNull(job);
assertEquals("job1", job.getName());
assertNotNull(step1);
assertEquals("step1", step1.getName());
assertNotNull(step2);
assertEquals("step2", step2.getName());
assertNotNull(step3);
assertEquals("step3", step3.getName());
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
assertEquals(3, execution.getStepExecutions().size());
}
}

View File

@@ -0,0 +1,53 @@
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"SplitParsingTests-context.xml", "jsr-base-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class SplitParsingTests {
@Autowired
public Job job;
@Autowired
public JobLauncher jobLauncher;
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void test() throws Exception {
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
assertEquals(5, execution.getStepExecutions().size());
}
@Test
public void testOneFlowInSplit() {
try {
new ClassPathXmlApplicationContext("/org/springframework/batch/core/jsr/configuration/xml/invalid-split-context.xml");
} catch (BeanDefinitionParsingException bdpe) {
assertTrue(bdpe.getMessage().indexOf("A <split/> must contain at least two 'flow' elements.") >= 0);
return;
}
fail("Expected exception was not thrown");
}
}

View File

@@ -0,0 +1,56 @@
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"StepListenerParsingTests-context.xml", "jsr-base-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class StepListenerParsingTests {
@Autowired
public Job job;
@Autowired
public JobLauncher jobLauncher;
@Autowired
public StepListener stepListener;
@Test
public void test() throws Exception {
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
assertEquals(2, execution.getStepExecutions().size());
assertEquals(2, stepListener.countBeforeStep);
assertEquals(2, stepListener.countAfterStep);
}
public static class StepListener implements StepExecutionListener {
protected int countBeforeStep = 0;
protected int countAfterStep = 0;
@Override
public void beforeStep(StepExecution stepExecution) {
countBeforeStep++;
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
countAfterStep++;
return null;
}
}
}

View File

@@ -0,0 +1,15 @@
package org.springframework.batch.core.step.tasklet;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.repeat.RepeatStatus;
public class TaskletSupport implements Tasklet {
@Override
public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext) throws Exception {
System.out.println("The tasklet was executed");
return RepeatStatus.FINISHED;
}
}