RESOLVED - issue BATCH-1336: Add -restart and -next options to CommandLineJobRunner

This commit is contained in:
dsyer
2009-07-16 07:13:40 +00:00
parent 621327ea6c
commit 5bc4040efd
4 changed files with 139 additions and 22 deletions

View File

@@ -149,7 +149,10 @@ public class CommandLineJobRunner {
private JobLocator jobLocator;
private SystemExiter systemExiter = new JvmSystemExiter();
// Package private for unit test
private static SystemExiter systemExiter = new JvmSystemExiter();
private static String message = "";
private JobParametersConverter jobParametersConverter = new DefaultJobParametersConverter();
@@ -182,13 +185,35 @@ public class CommandLineJobRunner {
this.exitCodeMapper = exitCodeMapper;
}
/**
* Static setter for the {@link SystemExiter} so it can be adjusted before
* dependency injection. Typically overridden by
* {@link #setSystemExiter(SystemExiter)}.
*
* @param systemExitor
*/
public static void presetSystemExiter(SystemExiter systemExiter) {
CommandLineJobRunner.systemExiter = systemExiter;
}
/**
* Retrieve the error message set by an instance of
* {@link CommandLineJobRunner} as it exits. Empty if the last job launched
* was successful.
*
* @return the error message
*/
public static String getErrorMessage() {
return message;
}
/**
* Injection setter for the {@link SystemExiter}.
*
* @param systemExitor
*/
public void setSystemExiter(SystemExiter systemExitor) {
this.systemExiter = systemExitor;
public void setSystemExiter(SystemExiter systemExiter) {
CommandLineJobRunner.systemExiter = systemExiter;
}
/**
@@ -231,10 +256,10 @@ public class CommandLineJobRunner {
context.getAutowireCapableBeanFactory().autowireBeanProperties(this,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
Assert.notNull(launcher, "A JobLauncher must be provided. Please add one to the configuration.");
Assert.state(launcher != null, "A JobLauncher must be provided. Please add one to the configuration.");
if (opts.contains("-restart") || opts.contains("-next")) {
Assert
.notNull(jobExplorer,
.state(jobExplorer != null,
"A JobExplorer must be provided for a restart or start next operation. Please add one to the configuration.");
}
@@ -264,7 +289,9 @@ public class CommandLineJobRunner {
}
catch (Throwable e) {
logger.error("Job Terminated in error:", e);
String message = "Job Terminated in error: " + e.getMessage();
logger.error(message, e);
CommandLineJobRunner.message = message;
return exitCodeMapper.intValue(ExitStatus.FAILED.getExitCode());
}
finally {
@@ -287,6 +314,10 @@ public class CommandLineJobRunner {
JobParameters jobParameters = null;
if (lastInstances.isEmpty()) {
throw new JobParametersNotFoundException("No job instance found for job=" + jobName);
}
while (!lastInstances.isEmpty()) {
for (JobInstance jobInstance : lastInstances) {
@@ -308,10 +339,10 @@ public class CommandLineJobRunner {
start += count;
lastInstances = jobExplorer.getJobInstances(jobName, start, count);
}
}
if (jobParameters == null) {
throw new JobParametersNotFoundException("No job parameters found for failed execution of job=" + jobName);
throw new JobParametersNotFoundException("No failed or stopped execution found for job=" + jobName);
}
return jobParameters;
@@ -402,7 +433,9 @@ public class CommandLineJobRunner {
}
if (jobPath == null || jobName == null) {
logger.error("At least 2 arguments are required: JobPath and JobName.");
String message = "At least 2 arguments are required: JobPath and JobName.";
logger.error(message);
CommandLineJobRunner.message = message;
command.exit(1);
}

View File

@@ -27,7 +27,6 @@ import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
@@ -50,14 +49,10 @@ import org.springframework.util.ClassUtils;
*/
public class CommandLineJobRunnerTests {
private static final String JOB = ClassUtils.addResourcePathToPackagePath(CommandLineJobRunnerTests.class,
private String jobPath = ClassUtils.addResourcePathToPackagePath(CommandLineJobRunnerTests.class,
"job-with-environment.xml");
private static final String JOB_NAME = "test-job";
private String jobPath = JOB;
private String jobName = JOB_NAME;
private String jobName = "test-job";
private String jobKey = "job.Key=myKey";
@@ -82,6 +77,14 @@ public class CommandLineJobRunnerTests {
assertEquals(0, StubSystemExiter.getStatus());
}
@Test
public void testWithJobLocator() {
jobPath = ClassUtils.addResourcePathToPackagePath(CommandLineJobRunnerTests.class, "job-with-locator.xml");
CommandLineJobRunner.main(new String[] { jobPath, jobName, jobKey });
assertTrue("Injected JobParametersConverter not used instead of default", StubJobParametersConverter.called);
assertEquals(0, StubSystemExiter.getStatus());
}
@Test
public void testJobAlreadyRunning() throws Throwable {
StubJobLauncher.throwExecutionRunningException = true;
@@ -90,11 +93,13 @@ public class CommandLineJobRunnerTests {
}
@Test
@Ignore
public void testInvalidArgs() {
String[] args = new String[] {};
CommandLineJobRunner.presetSystemExiter(new StubSystemExiter());
CommandLineJobRunner.main(args);
assertEquals(1, StubSystemExiter.status);
String errorMessage = CommandLineJobRunner.getErrorMessage();
assertTrue("Wrong error message: " + errorMessage, errorMessage.contains("Config locations must not be null"));
}
@Test
@@ -102,6 +107,9 @@ public class CommandLineJobRunnerTests {
String[] args = new String[] { jobPath, "no-such-job" };
CommandLineJobRunner.main(args);
assertEquals(1, StubSystemExiter.status);
String errorMessage = CommandLineJobRunner.getErrorMessage();
assertTrue("Wrong error message: " + errorMessage, errorMessage
.contains("No bean named 'no-such-job' is defined"));
}
@Test
@@ -123,16 +131,59 @@ public class CommandLineJobRunnerTests {
}
@Test
public void testNext() throws Throwable {
String[] args = new String[] { jobPath, "-next", jobName };
public void testRestartNotFailed() throws Throwable {
String[] args = new String[] { jobPath, "-restart", jobName };
JobParameters jobParameters = new JobParametersBuilder().addString("foo", "bar").toJobParameters();
StubJobExplorer.jobInstances = Arrays.asList(new JobInstance(1L, jobParameters, jobName));
StubJobExplorer.jobInstances = Arrays.asList(new JobInstance(2L, jobParameters, jobName));
CommandLineJobRunner.main(args);
assertEquals(1, StubSystemExiter.status);
String errorMessage = CommandLineJobRunner.getErrorMessage();
assertTrue("Wrong error message: " + errorMessage, errorMessage
.contains("No failed or stopped execution found"));
}
@Test
public void testRestartNoParameters() throws Throwable {
String[] args = new String[] { jobPath, "-restart", jobName };
StubJobExplorer.jobInstances = new ArrayList<JobInstance>();
CommandLineJobRunner.main(args);
assertEquals(1, StubSystemExiter.status);
String errorMessage = CommandLineJobRunner.getErrorMessage();
assertTrue("Wrong error message: " + errorMessage, errorMessage.contains("No job instance found for job"));
}
@Test
public void testNext() throws Throwable {
String[] args = new String[] { jobPath, "-next", jobName, "bar=foo" };
JobParameters jobParameters = new JobParametersBuilder().addString("foo", "bar").addString("bar", "foo")
.toJobParameters();
StubJobExplorer.jobInstances = Arrays.asList(new JobInstance(2L, jobParameters, jobName));
CommandLineJobRunner.main(args);
assertEquals(0, StubSystemExiter.status);
jobParameters = new JobParametersBuilder().addString("foo", "spam").toJobParameters();
jobParameters = new JobParametersBuilder().addString("foo", "spam").addString("bar", "foo").toJobParameters();
assertEquals(jobParameters, StubJobLauncher.jobParameters);
}
@Test
public void testNextFirstInSequence() throws Throwable {
String[] args = new String[] { jobPath, "-next", jobName };
StubJobExplorer.jobInstances = new ArrayList<JobInstance>();
CommandLineJobRunner.main(args);
assertEquals(0, StubSystemExiter.status);
JobParameters jobParameters = new JobParametersBuilder().addString("foo", "spam").toJobParameters();
assertEquals(jobParameters, StubJobLauncher.jobParameters);
}
@Test
public void testNextWithNoParameters() {
jobPath = ClassUtils.addResourcePathToPackagePath(CommandLineJobRunnerTests.class, "job-with-locator.xml");
CommandLineJobRunner.main(new String[] { jobPath, "-next", "test-job2", jobKey });
assertEquals(1, StubSystemExiter.getStatus());
String errorMessage = CommandLineJobRunner.getErrorMessage();
assertTrue("Wrong error message: " + errorMessage, errorMessage
.contains(" No job parameters incrementer found"));
}
@Test
public void testDestroyCallback() throws Throwable {
String[] args = new String[] { jobPath, jobName };
@@ -207,6 +258,9 @@ public class CommandLineJobRunnerTests {
if (jobInstance.getId() == 0) {
return Arrays.asList(createJobInstance(jobInstance, BatchStatus.FAILED));
}
if (jobInstance.getId() == 1) {
return null;
}
return Arrays.asList(createJobInstance(jobInstance, BatchStatus.COMPLETED));
}
@@ -223,7 +277,12 @@ public class CommandLineJobRunnerTests {
}
public List<JobInstance> getJobInstances(String jobName, int start, int count) {
return jobInstances;
if (jobInstances == null) {
return new ArrayList<JobInstance>();
}
List<JobInstance> result = jobInstances;
jobInstances = null;
return result;
}
public StepExecution getStepExecution(Long jobExecutionId, Long stepExecutionId) {

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
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-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<import resource="test-environment.xml" />
<import resource="job.xml" />
<import resource="job2.xml" />
<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry"/>
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
<property name="jobRegistry" ref="jobRegistry"/>
</bean>
</beans>

View File

@@ -16,6 +16,8 @@
package org.springframework.batch.sample;
import static org.junit.Assert.assertEquals;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Assert;
@@ -87,6 +89,7 @@ public abstract class AbstractBatchLauncherTests implements ApplicationContextAw
public void testLaunchJob() throws Exception {
jobExecution = getLauncher().run(job, jobParameters);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
}
/**