BATCH-1924: Updated SimpleFlow to correctly continue processing on the restart of a STOPPED state
This commit is contained in:
@@ -60,7 +60,7 @@ public class StopAndRestartFailedJobParserTests extends AbstractJobParserTests {
|
||||
}
|
||||
|
||||
private JobExecution launchAndAssert(String stepNames) throws JobInstanceAlreadyCompleteException, JobRestartException,
|
||||
JobExecutionAlreadyRunningException {
|
||||
JobExecutionAlreadyRunningException {
|
||||
JobExecution jobExecution = createJobExecution();
|
||||
job.execute(jobExecution);
|
||||
assertEquals(stepNames, stepNamesList.toString());
|
||||
|
||||
@@ -54,7 +54,7 @@ public class StopRestartOnCompletedStepJobParserTests extends AbstractJobParserT
|
||||
}
|
||||
|
||||
private void launchAndAssert(String stepNames) throws JobInstanceAlreadyCompleteException, JobRestartException,
|
||||
JobExecutionAlreadyRunningException {
|
||||
JobExecutionAlreadyRunningException {
|
||||
JobExecution jobExecution = createJobExecution();
|
||||
job.execute(jobExecution);
|
||||
assertEquals(stepNames, stepNamesList.toString());
|
||||
|
||||
@@ -54,7 +54,7 @@ public class StopRestartOnFailedStepJobParserTests extends AbstractJobParserTest
|
||||
}
|
||||
|
||||
private void launchAndAssert(String stepNames) throws JobInstanceAlreadyCompleteException, JobRestartException,
|
||||
JobExecutionAlreadyRunningException {
|
||||
JobExecutionAlreadyRunningException {
|
||||
JobExecution jobExecution = createJobExecution();
|
||||
job.execute(jobExecution);
|
||||
assertEquals(stepNames, stepNamesList.toString());
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
package org.springframework.batch.core.step;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
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.StepContribution;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.explore.JobExplorer;
|
||||
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.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.scope.context.ChunkContext;
|
||||
import org.springframework.batch.core.step.tasklet.Tasklet;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Michael Minella
|
||||
*
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class RestartInPriorStepTests {
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
@Autowired
|
||||
private JobExplorer jobExplorer;
|
||||
|
||||
@Autowired
|
||||
private JobLauncher jobLauncher;
|
||||
|
||||
@Autowired
|
||||
private Job job;
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
//
|
||||
// Run 1
|
||||
//
|
||||
JobExecution run1 = jobLauncher.run(job, new JobParameters());
|
||||
|
||||
assertEquals(BatchStatus.STOPPED, run1.getStatus());
|
||||
assertEquals(2, run1.getStepExecutions().size());
|
||||
|
||||
//
|
||||
// Run 2
|
||||
//
|
||||
JobExecution run2 = jobLauncher.run(job, new JobParameters());
|
||||
|
||||
assertEquals(BatchStatus.COMPLETED, run2.getStatus());
|
||||
assertEquals(6, run2.getStepExecutions().size());
|
||||
}
|
||||
|
||||
public static class DecidingTasklet implements Tasklet {
|
||||
|
||||
@Override
|
||||
public RepeatStatus execute(StepContribution contribution,
|
||||
ChunkContext chunkContext) throws Exception {
|
||||
Map<String, Object> context = chunkContext.getStepContext().getJobExecutionContext();
|
||||
|
||||
if(context.get("restart") != null) {
|
||||
contribution.setExitStatus(new ExitStatus("ES3"));
|
||||
} else {
|
||||
chunkContext.getStepContext().setAttribute("restart", true);
|
||||
contribution.setExitStatus(new ExitStatus("ES4"));
|
||||
}
|
||||
|
||||
return RepeatStatus.FINISHED;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CompletionDecider implements JobExecutionDecider {
|
||||
|
||||
private int count = 0;
|
||||
|
||||
@Override
|
||||
public FlowExecutionStatus decide(JobExecution jobExecution,
|
||||
StepExecution stepExecution) {
|
||||
count++;
|
||||
|
||||
if(count > 2) {
|
||||
return new FlowExecutionStatus("END");
|
||||
}
|
||||
else {
|
||||
return new FlowExecutionStatus("CONTINUE");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:util="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/util
|
||||
http://www.springframework.org/schema/util/spring-util.xsd
|
||||
http://www.springframework.org/schema/batch
|
||||
http://www.springframework.org/schema/batch/spring-batch-2.2.xsd">
|
||||
|
||||
<bean id="step1ItemReader" class="org.springframework.batch.item.support.ListItemReader">
|
||||
<constructor-arg>
|
||||
<util:list>
|
||||
<util:value>A</util:value>
|
||||
</util:list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="step1ItemWriter" class="org.springframework.batch.core.configuration.xml.DummyItemWriter"/>
|
||||
|
||||
<bean id="step2ItemReader" class="org.springframework.batch.item.support.ListItemReader">
|
||||
<constructor-arg>
|
||||
<util:list>
|
||||
<util:value>A</util:value>
|
||||
<util:value>B</util:value>
|
||||
</util:list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="step2ItemWriter" class="org.springframework.batch.core.configuration.xml.DummyItemWriter"/>
|
||||
|
||||
<bean id="step3ItemReader" class="org.springframework.batch.item.support.ListItemReader">
|
||||
<constructor-arg>
|
||||
<util:list>
|
||||
<util:value>A</util:value>
|
||||
<util:value>B</util:value>
|
||||
<util:value>C</util:value>
|
||||
</util:list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="step3ItemWriter" class="org.springframework.batch.core.configuration.xml.DummyItemWriter"/>
|
||||
|
||||
<bean id="decidingTasklet" class="org.springframework.batch.core.step.RestartInPriorStepTests$DecidingTasklet"/>
|
||||
|
||||
<bean id="completionDecider" class="org.springframework.batch.core.step.RestartInPriorStepTests$CompletionDecider"/>
|
||||
|
||||
<job id="restartJob" xmlns="http://www.springframework.org/schema/batch">
|
||||
<step id="step1" next="step2">
|
||||
<tasklet allow-start-if-complete="true">
|
||||
<chunk reader="step1ItemReader" writer="step1ItemWriter" commit-interval="10" />
|
||||
</tasklet>
|
||||
</step>
|
||||
<step id="step2">
|
||||
<tasklet ref="decidingTasklet"/>
|
||||
<next on="ES3" to="step3"/>
|
||||
<stop on="ES4" restart="step4"/>
|
||||
</step>
|
||||
<step id="step3" next="step4">
|
||||
<tasklet>
|
||||
<chunk reader="step2ItemReader" writer="step2ItemWriter" commit-interval="10" />
|
||||
</tasklet>
|
||||
</step>
|
||||
<step id="step4" next="completionDecider">
|
||||
<tasklet>
|
||||
<chunk reader="step3ItemReader" writer="step3ItemWriter" commit-interval="10" />
|
||||
</tasklet>
|
||||
</step>
|
||||
<decision decider="completionDecider" id="completionDecider">
|
||||
<next on="CONTINUE" to="step3"/>
|
||||
<end on="END"/>
|
||||
</decision>
|
||||
</job>
|
||||
|
||||
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
|
||||
|
||||
<bean id="jobExplorer" class="org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean">
|
||||
<property name="repositoryFactory" ref="&jobRepository"/>
|
||||
</bean>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
|
||||
|
||||
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
|
||||
<property name="jobRepository" ref="jobRepository"/>
|
||||
</bean>
|
||||
</beans>
|
||||
Reference in New Issue
Block a user