IN PROGRESS - issue BATCH-264: Dependencies among jobs
Implement ConditionalJob (branching but not concurrent execution) and tidy up Abstract and SimpleJob a bit.
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* 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.job;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
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.JobInterruptedException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.UnexpectedJobExecutionException;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
|
||||
import org.springframework.batch.core.step.StepSupport;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class ConditionalJobTests {
|
||||
|
||||
private ConditionalJob job = new ConditionalJob("job");
|
||||
|
||||
private JobExecution jobExecution;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MapJobRepositoryFactoryBean.clear();
|
||||
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
|
||||
factory.setTransactionManager(new ResourcelessTransactionManager());
|
||||
factory.afterPropertiesSet();
|
||||
JobRepository jobRepository = (JobRepository) factory.getObject();
|
||||
job.setJobRepository(jobRepository);
|
||||
jobExecution = jobRepository.createJobExecution("job", new JobParameters());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testEmptySteps() throws Exception {
|
||||
job.setStepTransitions(Collections.<StepTransition> emptySet());
|
||||
job.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNoNextStepSpecified() throws Exception {
|
||||
job.setStepTransitions(Collections.singleton(new StepTransition(new StepSupport("step"), "*", "foo")));
|
||||
job.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNoStartStep() throws Exception {
|
||||
job.setStepTransitions(Arrays.asList(new StepTransition(new StepSupport("step"), "FAILED", "step"),
|
||||
new StepTransition(new StepSupport("step"), "*")));
|
||||
job.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNoEndStep() throws Exception {
|
||||
job.setStepTransitions(Collections.singleton(new StepTransition(new StepSupport("step"), "FAILED", "step")));
|
||||
job.setStartStepName("step");
|
||||
job.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testMultipleStartSteps() throws Exception {
|
||||
job.setStepTransitions(Arrays.asList(new StepTransition(new StubStep("step1"), "*"), new StepTransition(
|
||||
new StubStep("step2"), "*")));
|
||||
job.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoMatchForNextStep() throws Exception {
|
||||
job.setStepTransitions(Arrays.asList(new StepTransition(new StubStep("step1"), "FOO", "step2"),
|
||||
new StepTransition(new StubStep("step2"), "*")));
|
||||
job.afterPropertiesSet();
|
||||
try {
|
||||
job.doExecute(jobExecution);
|
||||
fail("Expected JobExecutionException");
|
||||
}
|
||||
catch (JobExecutionException e) {
|
||||
// expected
|
||||
String message = e.getMessage();
|
||||
assertTrue("Wrong message: " + message, message.toLowerCase().contains("next step not found"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneStep() throws Exception {
|
||||
job.setStepTransitions(Arrays.asList(new StepTransition(new StubStep("step1"), "*")));
|
||||
job.afterPropertiesSet();
|
||||
StepExecution stepExecution = job.doExecute(jobExecution);
|
||||
assertEquals(ExitStatus.FINISHED, stepExecution.getExitStatus());
|
||||
assertEquals(1, jobExecution.getStepExecutions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExplicitStartStep() throws Exception {
|
||||
job.setStepTransitions(Arrays.asList(new StepTransition(new StubStep("step"), "FAILED", "step"),
|
||||
new StepTransition(new StubStep("step"), "*")));
|
||||
job.setStartStepName("step");
|
||||
job.afterPropertiesSet();
|
||||
StepExecution stepExecution = job.doExecute(jobExecution);
|
||||
assertEquals(ExitStatus.FINISHED, stepExecution.getExitStatus());
|
||||
assertEquals(1, jobExecution.getStepExecutions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoSteps() throws Exception {
|
||||
job.setStepTransitions(Arrays.asList(new StepTransition(new StubStep("step1"), "*", "step2"),
|
||||
new StepTransition(new StubStep("step2"), "*")));
|
||||
job.afterPropertiesSet();
|
||||
StepExecution stepExecution = job.doExecute(jobExecution);
|
||||
assertEquals(ExitStatus.FINISHED, stepExecution.getExitStatus());
|
||||
assertEquals(2, jobExecution.getStepExecutions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailedStep() throws Exception {
|
||||
job.setStepTransitions(Arrays.asList(new StepTransition(new StubStep("step1") {
|
||||
@Override
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException,
|
||||
UnexpectedJobExecutionException {
|
||||
stepExecution.setStatus(BatchStatus.FAILED);
|
||||
stepExecution.setExitStatus(ExitStatus.FAILED);
|
||||
}
|
||||
}, "*", "step2"), new StepTransition(new StubStep("step2"), "*")));
|
||||
job.afterPropertiesSet();
|
||||
StepExecution stepExecution = job.doExecute(jobExecution);
|
||||
assertEquals(ExitStatus.FINISHED, stepExecution.getExitStatus());
|
||||
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
|
||||
assertEquals(2, jobExecution.getStepExecutions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoppingStep() throws Exception {
|
||||
job.setStepTransitions(Arrays.asList(new StepTransition(new StubStep("step1") {
|
||||
@Override
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException,
|
||||
UnexpectedJobExecutionException {
|
||||
stepExecution.setStatus(BatchStatus.STOPPED);
|
||||
}
|
||||
}, "*", "step2"),
|
||||
new StepTransition(new StubStep("step2"), "*")));
|
||||
job.afterPropertiesSet();
|
||||
try {
|
||||
job.doExecute(jobExecution);
|
||||
fail("Expected JobInterruptedException");
|
||||
} catch (JobInterruptedException e) {
|
||||
// expected
|
||||
}
|
||||
assertEquals(1, jobExecution.getStepExecutions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBranching() throws Exception {
|
||||
job.setStepTransitions(Arrays.asList(new StepTransition(new StubStep("step1"), "*", "step2"),
|
||||
new StepTransition(new StubStep("step1"), "COMPLETED", "step3"), new StepTransition(new StubStep(
|
||||
"step2"), "*"), new StepTransition(new StubStep("step3"), "*")));
|
||||
job.afterPropertiesSet();
|
||||
StepExecution stepExecution = job.doExecute(jobExecution);
|
||||
assertEquals(ExitStatus.FINISHED, stepExecution.getExitStatus());
|
||||
assertEquals(2, jobExecution.getStepExecutions().size());
|
||||
assertEquals("step3", stepExecution.getStepName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
private static class StubStep extends StepSupport {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public StubStep() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
*/
|
||||
public StubStep(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see StepSupport#execute(StepExecution)
|
||||
*/
|
||||
@Override
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException,
|
||||
UnexpectedJobExecutionException {
|
||||
stepExecution.setStatus(BatchStatus.COMPLETED);
|
||||
stepExecution.setExitStatus(ExitStatus.FINISHED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -110,20 +110,18 @@ public class SimpleJobTests {
|
||||
job = new SimpleJob();
|
||||
job.setJobRepository(jobRepository);
|
||||
|
||||
step1 = new StubStep("TestStep1");
|
||||
step1 = new StubStep("TestStep1", jobRepository);
|
||||
step1.setCallback(new Runnable() {
|
||||
public void run() {
|
||||
list.add("default");
|
||||
}
|
||||
});
|
||||
step2 = new StubStep("TestStep2");
|
||||
step2 = new StubStep("TestStep2", jobRepository);
|
||||
step2.setCallback(new Runnable() {
|
||||
public void run() {
|
||||
list.add("default");
|
||||
}
|
||||
});
|
||||
step1.setJobRepository(jobRepository);
|
||||
step2.setJobRepository(jobRepository);
|
||||
|
||||
List<Step> steps = new ArrayList<Step>();
|
||||
steps.add(step1);
|
||||
@@ -250,8 +248,8 @@ public class SimpleJobTests {
|
||||
final JobInterruptedException exception = new JobInterruptedException("Interrupt!");
|
||||
step1.setProcessException(exception);
|
||||
job.execute(jobExecution);
|
||||
assertEquals(1, jobExecution.getAllFailureExceptions().size());
|
||||
assertEquals(exception, jobExecution.getAllFailureExceptions().get(0));
|
||||
assertEquals(2, jobExecution.getAllFailureExceptions().size());
|
||||
assertEquals(exception, jobExecution.getStepExecutions().iterator().next().getFailureExceptions().get(0));
|
||||
assertEquals(0, list.size());
|
||||
checkRepository(BatchStatus.STOPPED, ExitStatus.FAILED);
|
||||
}
|
||||
@@ -418,22 +416,24 @@ public class SimpleJobTests {
|
||||
@Test
|
||||
public void testInterruptJob() throws Exception {
|
||||
|
||||
step1 = new StubStep("interruptStep") {
|
||||
step1 = new StubStep("interruptStep", jobRepository) {
|
||||
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException,
|
||||
UnexpectedJobExecutionException {
|
||||
stepExecution.getJobExecution().stop();
|
||||
super.execute(stepExecution);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
job.setSteps(Arrays.asList(new Step[] { step1, step2 }));
|
||||
job.execute(jobExecution);
|
||||
Throwable expected = jobExecution.getAllFailureExceptions().get(0);
|
||||
assertTrue(expected instanceof JobInterruptedException);
|
||||
assertEquals("JobExecution interrupted.", expected.getMessage());
|
||||
assertEquals(1, jobExecution.getAllFailureExceptions().size());
|
||||
Throwable expected = jobExecution.getAllFailureExceptions().get(0);
|
||||
assertTrue("Wrong exception "+expected, expected instanceof JobInterruptedException);
|
||||
assertEquals("JobExecution interrupted.", expected.getMessage());
|
||||
|
||||
assertNull("Second step was not executed", step2.passedInStepContext);
|
||||
assertNull("Second step was not supposed to be executed", step2.passedInStepContext);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -446,7 +446,7 @@ public class SimpleJobTests {
|
||||
assertEquals(jobInstance.getId(), jobExecution.getJobId());
|
||||
assertEquals(status, jobExecution.getStatus());
|
||||
if (exitStatus != null) {
|
||||
assertEquals(jobExecution.getExitStatus().getExitCode(), exitStatus.getExitCode());
|
||||
assertEquals(exitStatus.getExitCode(), jobExecution.getExitStatus().getExitCode());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,8 +469,9 @@ public class SimpleJobTests {
|
||||
/**
|
||||
* @param string
|
||||
*/
|
||||
public StubStep(String string) {
|
||||
public StubStep(String string, JobRepository jobRepository) {
|
||||
super(string);
|
||||
this.jobRepository = jobRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -529,14 +530,5 @@ public class SimpleJobTests {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for {@link JobRepository}.
|
||||
*
|
||||
* @param jobRepository is a mandatory dependence (no default).
|
||||
*/
|
||||
public void setJobRepository(JobRepository jobRepository) {
|
||||
this.jobRepository = jobRepository;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.job;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.step.StepSupport;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class StepTransitionTests {
|
||||
|
||||
@Test
|
||||
public void testIsEnd() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "");
|
||||
assertTrue(transition.isEnd());
|
||||
assertNull(transition.getNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchesStar() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "*", "start");
|
||||
assertTrue(transition.matches(ExitStatus.CONTINUABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchesNull() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), null, "start");
|
||||
assertTrue(transition.matches(ExitStatus.CONTINUABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchesEmpty() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "", "start");
|
||||
assertTrue(transition.matches(ExitStatus.CONTINUABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchesExact() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "CONTINUABLE", "start");
|
||||
assertTrue(transition.matches(ExitStatus.CONTINUABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchesWildcard() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "CONTIN*", "start" );
|
||||
assertTrue(transition.matches(ExitStatus.CONTINUABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchesPlaceholder() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "CONTIN???LE", "start");
|
||||
assertTrue(transition.matches(ExitStatus.CONTINUABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleOrderingEqual() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "CONTIN???LE", "start");
|
||||
assertEquals(0, transition.compareTo(transition));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleOrderingMoreGeneral() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "CONTIN???LE", "start");
|
||||
StepTransition other = new StepTransition(new StepSupport(), "CONTINUABLE", "start");
|
||||
assertEquals(1, transition.compareTo(other));
|
||||
assertEquals(-1, other.compareTo(transition));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleOrderingMostGeneral() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "*", "start");
|
||||
StepTransition other = new StepTransition(new StepSupport(), "CONTINUABLE", "start");
|
||||
assertEquals(1, transition.compareTo(other));
|
||||
assertEquals(-1, other.compareTo(transition));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubstringAndWildcard() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "CONTIN*", "start");
|
||||
StepTransition other = new StepTransition(new StepSupport(), "CONTINUABLE", "start");
|
||||
assertEquals(1, transition.compareTo(other));
|
||||
assertEquals(-1, other.compareTo(transition));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleOrderingMostToNextGeneral() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "*", "start");
|
||||
StepTransition other = new StepTransition(new StepSupport(), "C?", "start");
|
||||
assertEquals(1, transition.compareTo(other));
|
||||
assertEquals(-1, other.compareTo(transition));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleOrderingAdjacent() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "CON*", "start");
|
||||
StepTransition other = new StepTransition(new StepSupport(), "CON?", "start");
|
||||
assertEquals(1, transition.compareTo(other));
|
||||
assertEquals(-1, other.compareTo(transition));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
StepTransition transition = new StepTransition(new StepSupport(), "CONTIN???LE", "start");
|
||||
String string = transition.toString();
|
||||
assertTrue("Wrong string: " + string, string.contains("StepTransition"));
|
||||
assertTrue("Wrong string: " + string, string.contains("start"));
|
||||
assertTrue("Wrong string: " + string, string.contains("CONTIN???LE"));
|
||||
assertTrue("Wrong string: " + string, string.contains("next="));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user