Skip to content

Commit bbf35b7

Browse files
lcmarvinfmbenhassine
authored andcommitted
Make the meaning of running status consistent
- A running status is STARTING, STARTED, or STOPPING. - Update related tests. Resolves #1483
1 parent 930bb02 commit bbf35b7

File tree

12 files changed

+79
-12
lines changed

12 files changed

+79
-12
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/BatchStatus.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ public static BatchStatus max(BatchStatus status1, BatchStatus status2) {
8484

8585
/**
8686
* Convenience method to decide if a status indicates that work is in progress.
87-
* @return true if the status is STARTING, STARTED
87+
* @return true if the status is STARTING, STARTED, STOPPING
8888
*/
8989
public boolean isRunning() {
90-
return this == STARTING || this == STARTED;
90+
return this == STARTING || this == STARTED || this == STOPPING;
9191
}
9292

9393
/**

spring-batch-core/src/main/java/org/springframework/batch/core/JobExecution.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,11 @@ public StepExecution createStepExecution(String stepName) {
256256
/**
257257
* Test if this {@link JobExecution} indicates that it is running. Note that this does
258258
* not necessarily mean that it has been persisted.
259-
* @return {@code true} if the end time is null and the start time is not null.
259+
* @return {@code true} if the status is one of the running statuses.
260+
* @see BatchStatus#isRunning()
260261
*/
261262
public boolean isRunning() {
262-
return startTime != null && endTime == null;
263+
return status.isRunning();
263264
}
264265

265266
/**

spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/SimpleJobLauncher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public JobExecution run(final Job job, final JobParameters jobParameters)
119119
*/
120120
for (StepExecution execution : lastExecution.getStepExecutions()) {
121121
BatchStatus status = execution.getStatus();
122-
if (status.isRunning() || status == BatchStatus.STOPPING) {
122+
if (status.isRunning()) {
123123
throw new JobExecutionAlreadyRunningException(
124124
"A job execution for this job is already running: " + lastExecution);
125125
}

spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements
8888
+ " from %PREFIX%JOB_EXECUTION where JOB_EXECUTION_ID = ?";
8989

9090
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, "
91-
+ "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";
91+
+ "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";
9292

9393
private static final String CURRENT_VERSION_JOB_EXECUTION = "SELECT VERSION FROM %PREFIX%JOB_EXECUTION WHERE JOB_EXECUTION_ID=?";
9494

spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public JobExecution createJobExecution(String jobName, JobParameters jobParamete
136136

137137
// check for running executions and find the last started
138138
for (JobExecution execution : executions) {
139-
if (execution.isRunning() || execution.isStopping()) {
139+
if (execution.isRunning()) {
140140
throw new JobExecutionAlreadyRunningException(
141141
"A job execution for this job is already running: " + jobInstance);
142142
}

spring-batch-core/src/test/java/org/springframework/batch/core/BatchStatusTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ void testIsRunning() {
7171
assertFalse(BatchStatus.COMPLETED.isRunning());
7272
assertTrue(BatchStatus.STARTED.isRunning());
7373
assertTrue(BatchStatus.STARTING.isRunning());
74+
assertTrue(BatchStatus.STOPPING.isRunning());
7475
}
7576

7677
@Test

spring-batch-core/src/test/java/org/springframework/batch/core/JobExecutionTests.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,19 @@ void testGetEndTime() {
5656
}
5757

5858
/**
59-
* Test method for {@link org.springframework.batch.core.JobExecution#getEndTime()}.
59+
* Test method for {@link org.springframework.batch.core.JobExecution#isRunning()}.
6060
*/
6161
@Test
6262
void testIsRunning() {
63-
LocalDateTime now = LocalDateTime.now();
64-
execution.setStartTime(now);
63+
execution.setStatus(BatchStatus.STARTING);
64+
assertTrue(execution.isRunning());
65+
execution.setStatus(BatchStatus.STARTED);
6566
assertTrue(execution.isRunning());
66-
execution.setEndTime(now.plus(10, ChronoUnit.SECONDS));
67+
execution.setStatus(BatchStatus.STOPPING);
68+
assertTrue(execution.isRunning());
69+
execution.setStatus(BatchStatus.COMPLETED);
70+
assertFalse(execution.isRunning());
71+
execution.setStatus(BatchStatus.FAILED);
6772
assertFalse(execution.isRunning());
6873
}
6974

spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ void testStepAlreadyComplete() throws Exception {
363363
stepExecution1.setStatus(BatchStatus.COMPLETED);
364364
jobRepository.add(stepExecution1);
365365
jobExecution.setEndTime(LocalDateTime.now());
366+
jobExecution.setStatus(BatchStatus.COMPLETED);
366367
jobRepository.update(jobExecution);
367368
jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
368369
job.execute(jobExecution);

spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractJobExecutionDaoTests.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ void testFindRunningExecutions() {
204204
exec.setCreateTime(now);
205205
exec.setStartTime(now.plus(1, ChronoUnit.SECONDS));
206206
exec.setEndTime(now.plus(2, ChronoUnit.SECONDS));
207+
exec.setStatus(BatchStatus.COMPLETED);
207208
exec.setLastUpdated(now.plus(3, ChronoUnit.SECONDS));
208209
dao.saveJobExecution(exec);
209210

@@ -215,9 +216,17 @@ void testFindRunningExecutions() {
215216
exec.setLastUpdated(now.plus(3, ChronoUnit.SECONDS));
216217
dao.saveJobExecution(exec);
217218

219+
// Stopping JobExecution as status is STOPPING
220+
exec = new JobExecution(jobInstance, jobParameters);
221+
exec.setStartTime(now.plus(6, ChronoUnit.SECONDS));
222+
exec.setStatus(BatchStatus.STOPPING);
223+
exec.setLastUpdated(now.plus(7, ChronoUnit.SECONDS));
224+
dao.saveJobExecution(exec);
225+
218226
// Running JobExecution as StartTime is populated but EndTime is null
219227
exec = new JobExecution(jobInstance, jobParameters);
220228
exec.setStartTime(now.plus(2, ChronoUnit.SECONDS));
229+
exec.setStatus(BatchStatus.STARTED);
221230
exec.setLastUpdated(now.plus(3, ChronoUnit.SECONDS));
222231
exec.createStepExecution("step");
223232
dao.saveJobExecution(exec);
@@ -231,7 +240,7 @@ void testFindRunningExecutions() {
231240

232241
Set<JobExecution> values = dao.findRunningJobExecutions(exec.getJobInstance().getJobName());
233242

234-
assertEquals(1, values.size());
243+
assertEquals(3, values.size());
235244
JobExecution value = values.iterator().next();
236245
assertEquals(exec, value);
237246
assertEquals(now.plus(3, ChronoUnit.SECONDS), value.getLastUpdated());

spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryIntegrationTests.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import static org.junit.jupiter.api.Assertions.assertEquals;
3838
import static org.junit.jupiter.api.Assertions.assertNotNull;
3939
import static org.junit.jupiter.api.Assertions.assertThrows;
40+
import static org.junit.jupiter.api.Assertions.fail;
4041

4142
/**
4243
* Repository tests using JDBC DAOs (rather than mocks).
@@ -76,6 +77,7 @@ void testCreateAndFind() throws Exception {
7677
assertEquals(job.getName(), firstExecution.getJobInstance().getJobName());
7778

7879
jobRepository.update(firstExecution);
80+
firstExecution.setStatus(BatchStatus.FAILED);
7981
firstExecution.setEndTime(LocalDateTime.now());
8082
jobRepository.update(firstExecution);
8183
JobExecution secondExecution = jobRepository.createJobExecution(job.getName(), jobParams);
@@ -97,6 +99,7 @@ void testCreateAndFindWithNoStartDate() throws Exception {
9799
LocalDateTime now = LocalDateTime.now();
98100
firstExecution.setStartTime(now);
99101
firstExecution.setEndTime(now.plus(1, ChronoUnit.SECONDS));
102+
firstExecution.setStatus(BatchStatus.COMPLETED);
100103
jobRepository.update(firstExecution);
101104
JobExecution secondExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
102105

@@ -224,4 +227,48 @@ void testReExecuteWithSameJobParameters() throws Exception {
224227
assertNotNull(jobExecution2);
225228
}
226229

230+
/*
231+
* When a job execution is running, JobExecutionAlreadyRunningException should be
232+
* thrown if trying to create any other ones with same job parameters.
233+
*/
234+
@Transactional
235+
@Test
236+
public void testReExecuteWithSameJobParametersWhenRunning() throws Exception {
237+
JobParameters jobParameters = new JobParametersBuilder().addString("stringKey", "stringValue")
238+
.toJobParameters();
239+
240+
// jobExecution with status STARTING
241+
JobExecution jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
242+
try {
243+
jobRepository.createJobExecution(job.getName(), jobParameters);
244+
fail();
245+
}
246+
catch (JobExecutionAlreadyRunningException e) {
247+
// expected
248+
}
249+
250+
// jobExecution with status STARTED
251+
jobExecution.setStatus(BatchStatus.STARTED);
252+
jobExecution.setStartTime(LocalDateTime.now());
253+
jobRepository.update(jobExecution);
254+
try {
255+
jobRepository.createJobExecution(job.getName(), jobParameters);
256+
fail();
257+
}
258+
catch (JobExecutionAlreadyRunningException e) {
259+
// expected
260+
}
261+
262+
// jobExecution with status STOPPING
263+
jobExecution.setStatus(BatchStatus.STOPPING);
264+
jobRepository.update(jobExecution);
265+
try {
266+
jobRepository.createJobExecution(job.getName(), jobParameters);
267+
fail();
268+
}
269+
catch (JobExecutionAlreadyRunningException e) {
270+
// expected
271+
}
272+
}
273+
227274
}

spring-batch-core/src/test/java/org/springframework/batch/core/step/job/JobStepTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ public boolean isRestartable() {
163163
assertEquals("FOO", stepExecution.getFailureExceptions().get(0).getMessage());
164164
JobExecution jobExecution = stepExecution.getJobExecution();
165165
jobExecution.setEndTime(LocalDateTime.now());
166+
jobExecution.setStatus(BatchStatus.FAILED);
166167
jobRepository.update(jobExecution);
167168

168169
jobExecution = jobRepository.createJobExecution("job", new JobParameters());

spring-batch-test/src/test/java/org/springframework/batch/test/JobRepositoryTestUtilsTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.junit.jupiter.api.BeforeEach;
2525
import org.junit.jupiter.api.Test;
2626

27+
import org.springframework.batch.core.BatchStatus;
2728
import org.springframework.batch.core.JobExecution;
2829
import org.springframework.batch.core.JobParameters;
2930
import org.springframework.batch.core.JobParametersBuilder;
@@ -84,6 +85,7 @@ void testRemoveJobExecutionsWithSameJobInstance() throws Exception {
8485
List<JobExecution> list = new ArrayList<>();
8586
JobExecution jobExecution = jobRepository.createJobExecution("job", new JobParameters());
8687
jobExecution.setEndTime(LocalDateTime.now());
88+
jobExecution.setStatus(BatchStatus.COMPLETED);
8789
list.add(jobExecution);
8890
jobRepository.update(jobExecution);
8991
jobExecution = jobRepository.createJobExecution("job", new JobParameters());

0 commit comments

Comments
 (0)