BATCH-1730: allow flow to be repeated in a PartitionStep

This commit is contained in:
Dave Syer
2011-05-05 08:58:48 +01:00
parent 3e95630fa6
commit 3f38056ff3
6 changed files with 269 additions and 17 deletions

View File

@@ -29,6 +29,8 @@ 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.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
@@ -36,15 +38,14 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Dave Syer
*
*
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class FlowStepParserTests {
@Autowired
@Qualifier("job1")
private Job job1;
@@ -53,12 +54,20 @@ public class FlowStepParserTests {
@Qualifier("job2")
private Job job2;
@Autowired
@Qualifier("job3")
private Job job3;
@Autowired
@Qualifier("job4")
private Job job4;
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
@Before
public void setUp() {
mapJobRepositoryFactoryBean.clear();
@@ -86,6 +95,36 @@ public class FlowStepParserTests {
assertEquals("[job2.s1, job2.flow, s2, s3, job2.s4]", stepNames.toString());
}
@Test
public void testRepeatedFlow() throws Exception {
assertNotNull(job3);
JobExecution jobExecution = jobRepository.createJobExecution(job3.getName(), new JobParameters());
job3.execute(jobExecution);
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
List<String> stepNames = getStepNames(jobExecution);
assertEquals(6, stepNames.size());
assertEquals("[job3.flow, s2, s3, job3.flow, s2, s3]", stepNames.toString());
}
@Test
// TODO: BATCH-1745
public void testRestartedFlow() throws Exception {
assertNotNull(job4);
JobExecution jobExecution = jobRepository.createJobExecution(job4.getName(), new JobParameters());
job4.execute(jobExecution);
assertEquals(BatchStatus.FAILED, jobExecution.getStatus());
List<String> stepNames = getStepNames(jobExecution);
assertEquals(3, stepNames.size());
assertEquals("[job4.flow, s2, s3]", stepNames.toString());
jobExecution = jobRepository.createJobExecution(job4.getName(), new JobParameters());
job4.execute(jobExecution);
assertEquals(BatchStatus.FAILED, jobExecution.getStatus());
stepNames = getStepNames(jobExecution);
assertEquals(1, stepNames.size());
// The flow executes again, but all the steps were already complete
assertEquals("[job4.flow]", stepNames.toString());
}
private List<String> getStepNames(JobExecution jobExecution) {
List<String> list = new ArrayList<String>();
for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
@@ -94,4 +133,16 @@ public class FlowStepParserTests {
return list;
}
public static class Decider implements JobExecutionDecider {
int count = 0;
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
if (count++ < 2) {
return new FlowExecutionStatus("OK");
}
return new FlowExecutionStatus("END");
}
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright 2006-2007 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.batch.core.configuration.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
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.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
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;
/**
* @author Dave Syer
* @author Josh Long
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class PartitionStepWithFlowParserTests {
@Autowired
@Qualifier("job1")
private Job job1;
@Autowired
@Qualifier("nameStoringTasklet")
private NameStoringTasklet nameStoringTasklet;
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
private List<String> savedStepNames = new ArrayList<String>();
@Before
public void setUp() {
nameStoringTasklet.setStepNamesList(savedStepNames);
mapJobRepositoryFactoryBean.clear();
}
@Test
public void testRepeatedFlowStep() throws Exception {
assertNotNull(job1);
JobExecution jobExecution = jobRepository.createJobExecution(job1.getName(), new JobParametersBuilder()
.addLong("gridSize", 1L).toJobParameters());
job1.execute(jobExecution);
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
Collections.sort(savedStepNames);
assertEquals("[s2, s2, s2, s2, s3, s3, s3, s3]", savedStepNames.toString());
List<String> stepNames = getStepNames(jobExecution);
assertEquals(14, stepNames.size());
assertEquals("[s1, s1, s1:partition0, s1:partition0, s1:partition1, s1:partition1, s2, s2, s2, s2, s3, s3, s3, s3]", stepNames.toString());
}
private List<String> getStepNames(JobExecution jobExecution) {
List<String> list = new ArrayList<String>();
for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
list.add(stepExecution.getStepName());
}
Collections.sort(list);
return list;
}
public static class Decider implements JobExecutionDecider {
int count = 0;
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
if (count++<2) {
return new FlowExecutionStatus("OK");
}
return new FlowExecutionStatus("END");
}
}
}

View File

@@ -14,7 +14,9 @@ import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionException;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
@@ -55,11 +57,12 @@ public class SimpleStepExecutionSplitterTests {
@Test
public void testSimpleStepExecutionProviderJobRepositoryStepPartitioner() throws Exception {
final Map<String, ExecutionContext> map = Collections.singletonMap("foo", new ExecutionContext());
SimpleStepExecutionSplitter splitter = new SimpleStepExecutionSplitter(jobRepository, true, step.getName(), new Partitioner() {
public Map<String, ExecutionContext> partition(int gridSize) {
return map;
}
});
SimpleStepExecutionSplitter splitter = new SimpleStepExecutionSplitter(jobRepository, true, step.getName(),
new Partitioner() {
public Map<String, ExecutionContext> partition(int gridSize) {
return map;
}
});
assertEquals(1, splitter.split(stepExecution, 2).size());
}
@@ -118,14 +121,25 @@ public class SimpleStepExecutionSplitterTests {
}
@Test
public void testCompleteStatus() throws Exception {
public void testCompleteStatusAfterFailure() throws Exception {
SimpleStepExecutionSplitter provider = new SimpleStepExecutionSplitter(jobRepository, false, step.getName(),
new SimplePartitioner());
Set<StepExecution> split = provider.split(stepExecution, 2);
assertEquals(2, split.size());
StepExecution nextExecution = update(split, stepExecution, BatchStatus.COMPLETED, false);
// If already complete in another JobExecution we don't execute again
assertEquals(0, provider.split(nextExecution, 2).size());
}
@Test
public void testCompleteStatusSameJobExecution() throws Exception {
SimpleStepExecutionSplitter provider = new SimpleStepExecutionSplitter(jobRepository, false, step.getName(),
new SimplePartitioner());
Set<StepExecution> split = provider.split(stepExecution, 2);
assertEquals(2, split.size());
stepExecution = update(split, stepExecution, BatchStatus.COMPLETED);
// If already complete we don't execute again
assertEquals(0, provider.split(stepExecution, 2).size());
// If already complete in the same JobExecution we should execute again
assertEquals(2, provider.split(stepExecution, 2).size());
}
@Test
@@ -164,6 +178,11 @@ public class SimpleStepExecutionSplitterTests {
private StepExecution update(Set<StepExecution> split, StepExecution stepExecution, BatchStatus status)
throws Exception {
return update(split, stepExecution, status, true);
}
private StepExecution update(Set<StepExecution> split, StepExecution stepExecution, BatchStatus status,
boolean sameJobExecution) throws Exception {
ExecutionContext executionContext = stepExecution.getExecutionContext();
@@ -177,7 +196,16 @@ public class SimpleStepExecutionSplitterTests {
stepExecution.setStatus(status);
jobRepository.update(stepExecution);
stepExecution = stepExecution.getJobExecution().createStepExecution(stepExecution.getStepName());
JobExecution jobExecution = stepExecution.getJobExecution();
if (!sameJobExecution) {
jobExecution.setStatus(BatchStatus.FAILED);
jobExecution.setEndTime(new Date());
jobRepository.update(jobExecution);
JobInstance jobInstance = jobExecution.getJobInstance();
jobExecution = jobRepository.createJobExecution(jobInstance.getJobName(), jobInstance.getJobParameters());
}
stepExecution = jobExecution.createStepExecution(stepExecution.getStepName());
stepExecution.setExecutionContext(executionContext);
jobRepository.add(stepExecution);