Make the meaning of running status consistent
- A running status is STARTING, STARTED, or STOPPING. - Update related tests. Resolves #1483
This commit is contained in:
committed by
Mahmoud Ben Hassine
parent
930bb0243c
commit
bbf35b79f7
@@ -84,10 +84,10 @@ public enum BatchStatus {
|
||||
|
||||
/**
|
||||
* Convenience method to decide if a status indicates that work is in progress.
|
||||
* @return true if the status is STARTING, STARTED
|
||||
* @return true if the status is STARTING, STARTED, STOPPING
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return this == STARTING || this == STARTED;
|
||||
return this == STARTING || this == STARTED || this == STOPPING;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -256,10 +256,11 @@ public class JobExecution extends Entity {
|
||||
/**
|
||||
* Test if this {@link JobExecution} indicates that it is running. Note that this does
|
||||
* not necessarily mean that it has been persisted.
|
||||
* @return {@code true} if the end time is null and the start time is not null.
|
||||
* @return {@code true} if the status is one of the running statuses.
|
||||
* @see BatchStatus#isRunning()
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return startTime != null && endTime == null;
|
||||
return status.isRunning();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -119,7 +119,7 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
|
||||
*/
|
||||
for (StepExecution execution : lastExecution.getStepExecutions()) {
|
||||
BatchStatus status = execution.getStatus();
|
||||
if (status.isRunning() || status == BatchStatus.STOPPING) {
|
||||
if (status.isRunning()) {
|
||||
throw new JobExecutionAlreadyRunningException(
|
||||
"A job execution for this job is already running: " + lastExecution);
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements
|
||||
+ " from %PREFIX%JOB_EXECUTION where JOB_EXECUTION_ID = ?";
|
||||
|
||||
private static final String GET_RUNNING_EXECUTIONS = "SELECT E.JOB_EXECUTION_ID, E.START_TIME, E.END_TIME, E.STATUS, E.EXIT_CODE, E.EXIT_MESSAGE, E.CREATE_TIME, E.LAST_UPDATED, E.VERSION, "
|
||||
+ "E.JOB_INSTANCE_ID from %PREFIX%JOB_EXECUTION E, %PREFIX%JOB_INSTANCE I where E.JOB_INSTANCE_ID=I.JOB_INSTANCE_ID and I.JOB_NAME=? and E.START_TIME is not NULL and E.END_TIME is NULL order by E.JOB_EXECUTION_ID desc";
|
||||
+ "E.JOB_INSTANCE_ID from %PREFIX%JOB_EXECUTION E, %PREFIX%JOB_INSTANCE I where E.JOB_INSTANCE_ID=I.JOB_INSTANCE_ID and I.JOB_NAME=? and E.STATUS in ('STARTING', 'STARTED', 'STOPPING') order by E.JOB_EXECUTION_ID desc";
|
||||
|
||||
private static final String CURRENT_VERSION_JOB_EXECUTION = "SELECT VERSION FROM %PREFIX%JOB_EXECUTION WHERE JOB_EXECUTION_ID=?";
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ public class SimpleJobRepository implements JobRepository {
|
||||
|
||||
// check for running executions and find the last started
|
||||
for (JobExecution execution : executions) {
|
||||
if (execution.isRunning() || execution.isStopping()) {
|
||||
if (execution.isRunning()) {
|
||||
throw new JobExecutionAlreadyRunningException(
|
||||
"A job execution for this job is already running: " + jobInstance);
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ class BatchStatusTests {
|
||||
assertFalse(BatchStatus.COMPLETED.isRunning());
|
||||
assertTrue(BatchStatus.STARTED.isRunning());
|
||||
assertTrue(BatchStatus.STARTING.isRunning());
|
||||
assertTrue(BatchStatus.STOPPING.isRunning());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -56,14 +56,19 @@ class JobExecutionTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.core.JobExecution#getEndTime()}.
|
||||
* Test method for {@link org.springframework.batch.core.JobExecution#isRunning()}.
|
||||
*/
|
||||
@Test
|
||||
void testIsRunning() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
execution.setStartTime(now);
|
||||
execution.setStatus(BatchStatus.STARTING);
|
||||
assertTrue(execution.isRunning());
|
||||
execution.setEndTime(now.plus(10, ChronoUnit.SECONDS));
|
||||
execution.setStatus(BatchStatus.STARTED);
|
||||
assertTrue(execution.isRunning());
|
||||
execution.setStatus(BatchStatus.STOPPING);
|
||||
assertTrue(execution.isRunning());
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
assertFalse(execution.isRunning());
|
||||
execution.setStatus(BatchStatus.FAILED);
|
||||
assertFalse(execution.isRunning());
|
||||
}
|
||||
|
||||
|
||||
@@ -363,6 +363,7 @@ class SimpleJobTests {
|
||||
stepExecution1.setStatus(BatchStatus.COMPLETED);
|
||||
jobRepository.add(stepExecution1);
|
||||
jobExecution.setEndTime(LocalDateTime.now());
|
||||
jobExecution.setStatus(BatchStatus.COMPLETED);
|
||||
jobRepository.update(jobExecution);
|
||||
jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
|
||||
job.execute(jobExecution);
|
||||
|
||||
@@ -204,6 +204,7 @@ public abstract class AbstractJobExecutionDaoTests {
|
||||
exec.setCreateTime(now);
|
||||
exec.setStartTime(now.plus(1, ChronoUnit.SECONDS));
|
||||
exec.setEndTime(now.plus(2, ChronoUnit.SECONDS));
|
||||
exec.setStatus(BatchStatus.COMPLETED);
|
||||
exec.setLastUpdated(now.plus(3, ChronoUnit.SECONDS));
|
||||
dao.saveJobExecution(exec);
|
||||
|
||||
@@ -215,9 +216,17 @@ public abstract class AbstractJobExecutionDaoTests {
|
||||
exec.setLastUpdated(now.plus(3, ChronoUnit.SECONDS));
|
||||
dao.saveJobExecution(exec);
|
||||
|
||||
// Stopping JobExecution as status is STOPPING
|
||||
exec = new JobExecution(jobInstance, jobParameters);
|
||||
exec.setStartTime(now.plus(6, ChronoUnit.SECONDS));
|
||||
exec.setStatus(BatchStatus.STOPPING);
|
||||
exec.setLastUpdated(now.plus(7, ChronoUnit.SECONDS));
|
||||
dao.saveJobExecution(exec);
|
||||
|
||||
// Running JobExecution as StartTime is populated but EndTime is null
|
||||
exec = new JobExecution(jobInstance, jobParameters);
|
||||
exec.setStartTime(now.plus(2, ChronoUnit.SECONDS));
|
||||
exec.setStatus(BatchStatus.STARTED);
|
||||
exec.setLastUpdated(now.plus(3, ChronoUnit.SECONDS));
|
||||
exec.createStepExecution("step");
|
||||
dao.saveJobExecution(exec);
|
||||
@@ -231,7 +240,7 @@ public abstract class AbstractJobExecutionDaoTests {
|
||||
|
||||
Set<JobExecution> values = dao.findRunningJobExecutions(exec.getJobInstance().getJobName());
|
||||
|
||||
assertEquals(1, values.size());
|
||||
assertEquals(3, values.size());
|
||||
JobExecution value = values.iterator().next();
|
||||
assertEquals(exec, value);
|
||||
assertEquals(now.plus(3, ChronoUnit.SECONDS), value.getLastUpdated());
|
||||
|
||||
@@ -37,6 +37,7 @@ import java.util.Arrays;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Repository tests using JDBC DAOs (rather than mocks).
|
||||
@@ -76,6 +77,7 @@ class SimpleJobRepositoryIntegrationTests {
|
||||
assertEquals(job.getName(), firstExecution.getJobInstance().getJobName());
|
||||
|
||||
jobRepository.update(firstExecution);
|
||||
firstExecution.setStatus(BatchStatus.FAILED);
|
||||
firstExecution.setEndTime(LocalDateTime.now());
|
||||
jobRepository.update(firstExecution);
|
||||
JobExecution secondExecution = jobRepository.createJobExecution(job.getName(), jobParams);
|
||||
@@ -97,6 +99,7 @@ class SimpleJobRepositoryIntegrationTests {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
firstExecution.setStartTime(now);
|
||||
firstExecution.setEndTime(now.plus(1, ChronoUnit.SECONDS));
|
||||
firstExecution.setStatus(BatchStatus.COMPLETED);
|
||||
jobRepository.update(firstExecution);
|
||||
JobExecution secondExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
|
||||
|
||||
@@ -224,4 +227,48 @@ class SimpleJobRepositoryIntegrationTests {
|
||||
assertNotNull(jobExecution2);
|
||||
}
|
||||
|
||||
/*
|
||||
* When a job execution is running, JobExecutionAlreadyRunningException should be
|
||||
* thrown if trying to create any other ones with same job parameters.
|
||||
*/
|
||||
@Transactional
|
||||
@Test
|
||||
public void testReExecuteWithSameJobParametersWhenRunning() throws Exception {
|
||||
JobParameters jobParameters = new JobParametersBuilder().addString("stringKey", "stringValue")
|
||||
.toJobParameters();
|
||||
|
||||
// jobExecution with status STARTING
|
||||
JobExecution jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
|
||||
try {
|
||||
jobRepository.createJobExecution(job.getName(), jobParameters);
|
||||
fail();
|
||||
}
|
||||
catch (JobExecutionAlreadyRunningException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
// jobExecution with status STARTED
|
||||
jobExecution.setStatus(BatchStatus.STARTED);
|
||||
jobExecution.setStartTime(LocalDateTime.now());
|
||||
jobRepository.update(jobExecution);
|
||||
try {
|
||||
jobRepository.createJobExecution(job.getName(), jobParameters);
|
||||
fail();
|
||||
}
|
||||
catch (JobExecutionAlreadyRunningException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
// jobExecution with status STOPPING
|
||||
jobExecution.setStatus(BatchStatus.STOPPING);
|
||||
jobRepository.update(jobExecution);
|
||||
try {
|
||||
jobRepository.createJobExecution(job.getName(), jobParameters);
|
||||
fail();
|
||||
}
|
||||
catch (JobExecutionAlreadyRunningException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -163,6 +163,7 @@ class JobStepTests {
|
||||
assertEquals("FOO", stepExecution.getFailureExceptions().get(0).getMessage());
|
||||
JobExecution jobExecution = stepExecution.getJobExecution();
|
||||
jobExecution.setEndTime(LocalDateTime.now());
|
||||
jobExecution.setStatus(BatchStatus.FAILED);
|
||||
jobRepository.update(jobExecution);
|
||||
|
||||
jobExecution = jobRepository.createJobExecution("job", new JobParameters());
|
||||
|
||||
@@ -24,6 +24,7 @@ import javax.sql.DataSource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
@@ -84,6 +85,7 @@ class JobRepositoryTestUtilsTests {
|
||||
List<JobExecution> list = new ArrayList<>();
|
||||
JobExecution jobExecution = jobRepository.createJobExecution("job", new JobParameters());
|
||||
jobExecution.setEndTime(LocalDateTime.now());
|
||||
jobExecution.setStatus(BatchStatus.COMPLETED);
|
||||
list.add(jobExecution);
|
||||
jobRepository.update(jobExecution);
|
||||
jobExecution = jobRepository.createJobExecution("job", new JobParameters());
|
||||
|
||||
Reference in New Issue
Block a user