BATCH-2311 JobLauncher allows restart of job_execution with status
UNKNOWN * additionally prevent restart of step executions with status STARTING, STARTED or STOPPING * additionally prevent restart of job executions with status UNKNOWN or STOPPING
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2013 the original author or authors.
|
||||
* Copyright 2006-2014 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.
|
||||
@@ -101,15 +101,21 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
|
||||
throw new JobRestartException("JobInstance already exists and is not restartable");
|
||||
}
|
||||
/*
|
||||
* validate here if it has stepExecutions that are UNKNOWN
|
||||
* validate here if it has stepExecutions that are UNKNOWN, STARTING, STARTED and STOPPING
|
||||
* retrieve the previous execution and check
|
||||
*/
|
||||
for (StepExecution execution : lastExecution.getStepExecutions()) {
|
||||
if (execution.getStatus() == BatchStatus.UNKNOWN) {
|
||||
//throw
|
||||
throw new JobRestartException("Step [" + execution.getStepName() + "] is of status UNKNOWN");
|
||||
}//end if
|
||||
}//end for
|
||||
BatchStatus status = execution.getStatus();
|
||||
if (status.isRunning() || status == BatchStatus.STOPPING) {
|
||||
throw new JobExecutionAlreadyRunningException("A job execution for this job is already running: "
|
||||
+ lastExecution);
|
||||
} else if (status == BatchStatus.UNKNOWN) {
|
||||
throw new JobRestartException(
|
||||
"Cannot restart step [" + execution.getStepName() + "] from UNKNOWN status. "
|
||||
+ "The last execution ended with a failure that could not be rolled back, "
|
||||
+ "so it may be dangerous to proceed. Manual intervention is probably necessary.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the validity of the parameters before doing creating anything
|
||||
|
||||
@@ -116,12 +116,16 @@ public class SimpleJobRepository implements JobRepository {
|
||||
|
||||
// check for running executions and find the last started
|
||||
for (JobExecution execution : executions) {
|
||||
if (execution.isRunning()) {
|
||||
if (execution.isRunning() || execution.isStopping()) {
|
||||
throw new JobExecutionAlreadyRunningException("A job execution for this job is already running: "
|
||||
+ jobInstance);
|
||||
}
|
||||
|
||||
BatchStatus status = execution.getStatus();
|
||||
if (status == BatchStatus.UNKNOWN) {
|
||||
throw new JobRestartException("Cannot restart job from UNKNOWN status. "
|
||||
+ "The last execution ended with a failure that could not be rolled back, "
|
||||
+ "so it may be dangerous to proceed. Manual intervention is probably necessary.");
|
||||
}
|
||||
if (execution.getJobParameters().getParameters().size() > 0 && (status == BatchStatus.COMPLETED || status == BatchStatus.ABANDONED)) {
|
||||
throw new JobInstanceAlreadyCompleteException(
|
||||
"A job instance already exists and is complete for parameters=" + jobParameters
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2013 the original author or authors.
|
||||
* Copyright 2006-2014 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.
|
||||
@@ -41,6 +41,7 @@ import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.DefaultJobParametersValidator;
|
||||
import org.springframework.batch.core.job.JobSupport;
|
||||
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.JobRestartException;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
@@ -274,8 +275,25 @@ public class SimpleJobLauncherTests {
|
||||
*/
|
||||
@Test(expected=JobRestartException.class)
|
||||
public void testRunStepStatusUnknown() throws Exception {
|
||||
//try and restart a job where the step execution is UNKNOWN
|
||||
//setup
|
||||
testRestartStepExecutionInvalidStatus(BatchStatus.UNKNOWN);
|
||||
}
|
||||
|
||||
@Test(expected = JobExecutionAlreadyRunningException.class)
|
||||
public void testRunStepStatusStarting() throws Exception {
|
||||
testRestartStepExecutionInvalidStatus(BatchStatus.STARTING);
|
||||
}
|
||||
|
||||
@Test(expected = JobExecutionAlreadyRunningException.class)
|
||||
public void testRunStepStatusStarted() throws Exception {
|
||||
testRestartStepExecutionInvalidStatus(BatchStatus.STARTED);
|
||||
}
|
||||
|
||||
@Test(expected = JobExecutionAlreadyRunningException.class)
|
||||
public void testRunStepStatusStopping() throws Exception {
|
||||
testRestartStepExecutionInvalidStatus(BatchStatus.STOPPING);
|
||||
}
|
||||
|
||||
private void testRestartStepExecutionInvalidStatus(BatchStatus status) throws Exception {
|
||||
String jobName = "test_job";
|
||||
JobRepository jobRepository = mock(JobRepository.class);
|
||||
JobParameters parameters = new JobParametersBuilder().addLong("runtime", System.currentTimeMillis()).toJobParameters();
|
||||
@@ -288,7 +306,7 @@ public class SimpleJobLauncherTests {
|
||||
when(job.isRestartable()).thenReturn(true);
|
||||
when(job.getJobParametersValidator()).thenReturn(validator);
|
||||
when(jobRepository.getLastJobExecution(jobName, parameters)).thenReturn(jobExecution);
|
||||
when(stepExecution.getStatus()).thenReturn(BatchStatus.UNKNOWN);
|
||||
when(stepExecution.getStatus()).thenReturn(status);
|
||||
when(jobExecution.getStepExecutions()).thenReturn(Arrays.asList(stepExecution));
|
||||
|
||||
//setup launcher
|
||||
@@ -297,6 +315,5 @@ public class SimpleJobLauncherTests {
|
||||
|
||||
//run
|
||||
jobLauncher.run(job, parameters);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
* Copyright 2006-2014 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.
|
||||
@@ -25,6 +25,8 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -37,6 +39,9 @@ import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.JobSupport;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
||||
import org.springframework.batch.core.repository.JobRestartException;
|
||||
import org.springframework.batch.core.repository.dao.ExecutionContextDao;
|
||||
import org.springframework.batch.core.repository.dao.JobExecutionDao;
|
||||
import org.springframework.batch.core.repository.dao.JobInstanceDao;
|
||||
@@ -92,7 +97,7 @@ public class SimpleJobRepositoryTests {
|
||||
|
||||
jobRepository = new SimpleJobRepository(jobInstanceDao, jobExecutionDao, stepExecutionDao, ecDao);
|
||||
|
||||
jobParameters = new JobParametersBuilder().toJobParameters();
|
||||
jobParameters = new JobParametersBuilder().addString("bar", "test").toJobParameters();
|
||||
|
||||
job = new JobSupport();
|
||||
job.setBeanName("RepositoryTest");
|
||||
@@ -232,4 +237,37 @@ public class SimpleJobRepositoryTests {
|
||||
assertTrue(jobRepository.isJobInstanceExists("foo", new JobParameters()));
|
||||
}
|
||||
|
||||
@Test(expected = JobExecutionAlreadyRunningException.class)
|
||||
public void testCreateJobExecutionAlreadyRunning() throws Exception {
|
||||
jobExecution.setStatus(BatchStatus.STARTED);
|
||||
jobExecution.setEndTime(null);
|
||||
|
||||
when(jobInstanceDao.getJobInstance("foo", new JobParameters())).thenReturn(jobInstance);
|
||||
when(jobExecutionDao.findJobExecutions(jobInstance)).thenReturn(Arrays.asList(jobExecution));
|
||||
|
||||
jobRepository.createJobExecution("foo", new JobParameters());
|
||||
}
|
||||
|
||||
@Test(expected = JobRestartException.class)
|
||||
public void testCreateJobExecutionStatusUnknown() throws Exception {
|
||||
jobExecution.setStatus(BatchStatus.UNKNOWN);
|
||||
jobExecution.setEndTime(new Date());
|
||||
|
||||
when(jobInstanceDao.getJobInstance("foo", new JobParameters())).thenReturn(jobInstance);
|
||||
when(jobExecutionDao.findJobExecutions(jobInstance)).thenReturn(Arrays.asList(jobExecution));
|
||||
|
||||
jobRepository.createJobExecution("foo", new JobParameters());
|
||||
}
|
||||
|
||||
@Test(expected = JobInstanceAlreadyCompleteException.class)
|
||||
public void testCreateJobExecutionAlreadyComplete() throws Exception {
|
||||
jobExecution.setStatus(BatchStatus.COMPLETED);
|
||||
jobExecution.setEndTime(new Date());
|
||||
|
||||
when(jobInstanceDao.getJobInstance("foo", new JobParameters())).thenReturn(jobInstance);
|
||||
when(jobExecutionDao.findJobExecutions(jobInstance)).thenReturn(Arrays.asList(jobExecution));
|
||||
|
||||
jobRepository.createJobExecution("foo", new JobParameters());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user