Skip to content

Commit 71dac69

Browse files
committed
Make the meaning of running status consistent
- A running status is STARTING, STARTED, or STOPPING. - Update related tests. Resolves spring-projects#1483
1 parent 0b2a2c2 commit 71dac69

File tree

9 files changed

+74
-11
lines changed

9 files changed

+74
-11
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: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,10 @@ 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 status.
260260
*/
261261
public boolean isRunning() {
262-
return startTime != null && endTime == null;
262+
return status.isRunning();
263263
}
264264

265265
/**

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
@@ -106,7 +106,7 @@ public JobExecution run(final Job job, final JobParameters jobParameters)
106106
*/
107107
for (StepExecution execution : lastExecution.getStepExecutions()) {
108108
BatchStatus status = execution.getStatus();
109-
if (status.isRunning() || status == BatchStatus.STOPPING) {
109+
if (status.isRunning()) {
110110
throw new JobExecutionAlreadyRunningException(
111111
"A job execution for this job is already running: " + lastExecution);
112112
}

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
@@ -84,7 +84,7 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements
8484
+ " from %PREFIX%JOB_EXECUTION where JOB_EXECUTION_ID = ?";
8585

8686
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, "
87-
+ "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";
87+
+ "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";
8888

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

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
@@ -121,7 +121,7 @@ public JobExecution createJobExecution(String jobName, JobParameters jobParamete
121121

122122
// check for running executions and find the last started
123123
for (JobExecution execution : executions) {
124-
if (execution.isRunning() || execution.isStopping()) {
124+
if (execution.isRunning()) {
125125
throw new JobExecutionAlreadyRunningException(
126126
"A job execution for this job is already running: " + jobInstance);
127127
}

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
@@ -72,6 +72,7 @@ public void testIsRunning() {
7272
assertFalse(BatchStatus.COMPLETED.isRunning());
7373
assertTrue(BatchStatus.STARTED.isRunning());
7474
assertTrue(BatchStatus.STARTING.isRunning());
75+
assertTrue(BatchStatus.STOPPING.isRunning());
7576
}
7677

7778
@Test

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,19 @@ public void testGetEndTime() {
5454
}
5555

5656
/**
57-
* Test method for {@link org.springframework.batch.core.JobExecution#getEndTime()}.
57+
* Test method for {@link org.springframework.batch.core.JobExecution#isRunning()}.
5858
*/
5959
@Test
6060
public void testIsRunning() {
61-
execution.setStartTime(new Date());
61+
execution.setStatus(BatchStatus.STARTING);
6262
assertTrue(execution.isRunning());
63-
execution.setEndTime(new Date(100L));
63+
execution.setStatus(BatchStatus.STARTED);
64+
assertTrue(execution.isRunning());
65+
execution.setStatus(BatchStatus.STOPPING);
66+
assertTrue(execution.isRunning());
67+
execution.setStatus(BatchStatus.COMPLETED);
68+
assertFalse(execution.isRunning());
69+
execution.setStatus(BatchStatus.FAILED);
6470
assertFalse(execution.isRunning());
6571
}
6672

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
@@ -201,6 +201,7 @@ public void testFindRunningExecutions() {
201201
exec.setCreateTime(new Date(0));
202202
exec.setStartTime(new Date(1L));
203203
exec.setEndTime(new Date(2L));
204+
exec.setStatus(BatchStatus.COMPLETED);
204205
exec.setLastUpdated(new Date(5L));
205206
dao.saveJobExecution(exec);
206207

@@ -212,9 +213,17 @@ public void testFindRunningExecutions() {
212213
exec.setLastUpdated(new Date(5L));
213214
dao.saveJobExecution(exec);
214215

216+
// Stopping JobExecution as status is STOPPING
217+
exec = new JobExecution(jobInstance, jobParameters);
218+
exec.setStartTime(new Date(3L));
219+
exec.setStatus(BatchStatus.STOPPING);
220+
exec.setLastUpdated(new Date(5L));
221+
dao.saveJobExecution(exec);
222+
215223
// Running JobExecution as StartTime is populated but EndTime is null
216224
exec = new JobExecution(jobInstance, jobParameters);
217225
exec.setStartTime(new Date(2L));
226+
exec.setStatus(BatchStatus.STARTED);
218227
exec.setLastUpdated(new Date(5L));
219228
exec.createStepExecution("step");
220229
dao.saveJobExecution(exec);
@@ -228,7 +237,7 @@ public void testFindRunningExecutions() {
228237

229238
Set<JobExecution> values = dao.findRunningJobExecutions(exec.getJobInstance().getJobName());
230239

231-
assertEquals(1, values.size());
240+
assertEquals(3, values.size());
232241
JobExecution value = values.iterator().next();
233242
assertEquals(exec, value);
234243
assertEquals(5L, value.getLastUpdated().getTime());

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
@@ -79,6 +79,7 @@ public void testCreateAndFind() throws Exception {
7979
assertEquals(job.getName(), firstExecution.getJobInstance().getJobName());
8080

8181
jobRepository.update(firstExecution);
82+
firstExecution.setStatus(BatchStatus.FAILED);
8283
firstExecution.setEndTime(new Date());
8384
jobRepository.update(firstExecution);
8485
JobExecution secondExecution = jobRepository.createJobExecution(job.getName(), jobParams);
@@ -99,6 +100,7 @@ public void testCreateAndFindWithNoStartDate() throws Exception {
99100
JobExecution firstExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
100101
firstExecution.setStartTime(new Date(0));
101102
firstExecution.setEndTime(new Date(1));
103+
firstExecution.setStatus(BatchStatus.COMPLETED);
102104
jobRepository.update(firstExecution);
103105
JobExecution secondExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
104106

@@ -231,4 +233,49 @@ public void testReExecuteWithSameJobParameters() throws Exception {
231233
assertNotNull(jobExecution2);
232234
}
233235

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

0 commit comments

Comments
 (0)