diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapJobExecutionDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapJobExecutionDao.java index 6a328d6a8..3c75b9bdb 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapJobExecutionDao.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapJobExecutionDao.java @@ -1,6 +1,7 @@ package org.springframework.batch.execution.repository.dao; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -8,8 +9,11 @@ import java.util.Set; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.support.transaction.TransactionAwareProxyFactory; -import org.springframework.util.Assert; +/** + * In-memory implementation of {@link JobExecutionDao}. + * + */ public class MapJobExecutionDao implements JobExecutionDao { private static Map executionsByJobInstanceId = TransactionAwareProxyFactory.createTransactionalMap(); @@ -22,8 +26,9 @@ public class MapJobExecutionDao implements JobExecutionDao { public int getJobExecutionCount(JobInstance jobInstance) { Set executions = (Set) executionsByJobInstanceId.get(jobInstance.getId()); - if (executions == null) + if (executions == null) { return 0; + } return executions.size(); } @@ -48,11 +53,24 @@ public class MapJobExecutionDao implements JobExecutionDao { } public void updateJobExecution(JobExecution jobExecution) { - Assert.notNull(jobExecution.getJobId()); + // no-op } public JobExecution getLastJobExecution(JobInstance jobInstance) { - Assert.notNull(jobInstance.getId()); - return null; + Set executions = (Set) executionsByJobInstanceId.get(jobInstance.getId()); + if (executions == null) { + return null; + } + JobExecution lastExec = null; + for (Iterator iterator = executions.iterator(); iterator.hasNext();) { + JobExecution exec = (JobExecution) iterator.next(); + if (lastExec == null) { + lastExec = exec; + } + if (lastExec.getStartTime().getTime() < exec.getStartTime().getTime()) { + lastExec = exec; + } + } + return lastExec; } } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapStepDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapStepExecutionDao.java similarity index 87% rename from spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapStepDao.java rename to spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapStepExecutionDao.java index 0ca393e54..01dcebb47 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapStepDao.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapStepExecutionDao.java @@ -25,7 +25,7 @@ import org.springframework.batch.item.ExecutionContext; import org.springframework.batch.support.transaction.TransactionAwareProxyFactory; import org.springframework.util.Assert; -public class MapStepDao implements StepExecutionDao { +public class MapStepExecutionDao implements StepExecutionDao { private static Map executionsByJobExecutionId; @@ -46,7 +46,12 @@ public class MapStepDao implements StepExecutionDao { return (ExecutionContext) contextsByStepExecutionId.get(stepExecution.getId()); } - public void saveOrUpdateExecutionContext(StepExecution stepExecution) { + public void saveExecutionContext(StepExecution stepExecution) { + contextsByStepExecutionId.put(stepExecution.getId(), stepExecution.getExecutionContext()); + } + + public void updateExecutionContext(StepExecution stepExecution) { + Assert.notNull(contextsByStepExecutionId.get(stepExecution.getId()), "execution context should already be saved"); contextsByStepExecutionId.put(stepExecution.getId(), stepExecution.getExecutionContext()); } @@ -78,4 +83,9 @@ public class MapStepDao implements StepExecutionDao { return (StepExecution) executions.get(step.getName()); } + public void saveOrUpdateExecutionContext(StepExecution stepExecution) { + // TODO Auto-generated method stub + + } + } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/SimpleJobTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/SimpleJobTests.java index c2f1bc724..3fa5255af 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/SimpleJobTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/SimpleJobTests.java @@ -35,7 +35,7 @@ import org.springframework.batch.execution.repository.dao.JobExecutionDao; import org.springframework.batch.execution.repository.dao.JobInstanceDao; import org.springframework.batch.execution.repository.dao.MapJobExecutionDao; import org.springframework.batch.execution.repository.dao.MapJobInstanceDao; -import org.springframework.batch.execution.repository.dao.MapStepDao; +import org.springframework.batch.execution.repository.dao.MapStepExecutionDao; import org.springframework.batch.execution.repository.dao.StepExecutionDao; import org.springframework.batch.execution.step.AbstractStep; import org.springframework.batch.io.exception.BatchCriticalException; @@ -43,7 +43,7 @@ import org.springframework.batch.item.reader.AbstractItemReader; import org.springframework.batch.repeat.ExitStatus; /** - * Tests for DefaultJobLifecycle. MapJobDao and MapStepDao are used instead of a + * Tests for DefaultJobLifecycle. MapJobDao and MapStepExecutionDao are used instead of a * mock repository to test that status is being stored correctly. * * @author Lucas Ward @@ -85,10 +85,10 @@ public class SimpleJobTests extends TestCase { MapJobInstanceDao.clear(); MapJobExecutionDao.clear(); - MapStepDao.clear(); + MapStepExecutionDao.clear(); jobInstanceDao = new MapJobInstanceDao(); jobExecutionDao = new MapJobExecutionDao(); - stepExecutionDao = new MapStepDao(); + stepExecutionDao = new MapStepExecutionDao(); jobRepository = new SimpleJobRepository(jobInstanceDao, jobExecutionDao, stepExecutionDao); job = new SimpleJob(); job.setJobRepository(jobRepository); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java index 37890e86a..50d7cbb60 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java @@ -32,7 +32,7 @@ import org.springframework.batch.execution.job.SimpleJob; import org.springframework.batch.execution.repository.SimpleJobRepository; import org.springframework.batch.execution.repository.dao.MapJobExecutionDao; import org.springframework.batch.execution.repository.dao.MapJobInstanceDao; -import org.springframework.batch.execution.repository.dao.MapStepDao; +import org.springframework.batch.execution.repository.dao.MapStepExecutionDao; import org.springframework.batch.execution.step.AbstractStep; import org.springframework.batch.execution.step.ItemOrientedStep; import org.springframework.batch.item.ItemReader; @@ -49,7 +49,7 @@ public class SimpleJobTests extends TestCase { private List recovered = new ArrayList(); - private SimpleJobRepository repository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(), new MapStepDao()); + private SimpleJobRepository repository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(), new MapStepExecutionDao()); private List processed = new ArrayList(); @@ -68,7 +68,7 @@ public class SimpleJobTests extends TestCase { job.setJobRepository(repository); MapJobInstanceDao.clear(); MapJobExecutionDao.clear(); - MapStepDao.clear(); + MapStepExecutionDao.clear(); } private AbstractStep getStep(String arg) throws Exception { diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapJobExecutionDaoTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapJobExecutionDaoTests.java index a3738a876..7d5fe2ba6 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapJobExecutionDaoTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapJobExecutionDaoTests.java @@ -1,9 +1,11 @@ package org.springframework.batch.execution.repository.dao; +import java.util.Date; import java.util.List; import junit.framework.TestCase; +import org.springframework.batch.core.domain.BatchStatus; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.domain.JobParameters; @@ -14,6 +16,8 @@ public class MapJobExecutionDaoTests extends TestCase { JobExecutionDao dao = new MapJobExecutionDao(); JobInstance jobInstance = new JobInstance(new Long(1), new JobParameters(), new JobSupport("execTestJob")); + + JobExecution execution = new JobExecution(jobInstance); protected void setUp() throws Exception { MapJobExecutionDao.clear(); @@ -23,35 +27,68 @@ public class MapJobExecutionDaoTests extends TestCase { * Save and find a job execution. */ public void testSaveAndFind() { - JobExecution exec = new JobExecution(jobInstance); - dao.saveJobExecution(exec); + + dao.saveJobExecution(execution); List executions = dao.findJobExecutions(jobInstance); assertTrue(executions.size() == 1); - assertEquals(exec, executions.get(0)); + assertEquals(execution, executions.get(0)); } - + /** * Saving sets id to the entity. */ public void testSaveAddsId() { - JobExecution exec = new JobExecution(jobInstance); - assertNull(exec.getId()); - dao.saveJobExecution(exec); - assertNotNull(exec.getId()); + + assertNull(execution.getId()); + dao.saveJobExecution(execution); + assertNotNull(execution.getId()); } + /** - * Execution count increases by one with every save - * for the same job instance. + * Execution count increases by one with every save for the same job + * instance. */ public void testGetExecutionCount() { + JobExecution exec1 = new JobExecution(jobInstance); JobExecution exec2 = new JobExecution(jobInstance); - + dao.saveJobExecution(exec1); assertEquals(1, dao.getJobExecutionCount(jobInstance)); - + dao.saveJobExecution(exec2); assertEquals(2, dao.getJobExecutionCount(jobInstance)); } + + /** + * Update and retrieve job execution - check attributes have changed as + * expected. + */ + public void testUpdateExecution() { + execution.setStatus(BatchStatus.STARTED); + dao.saveJobExecution(execution); + + execution.setStatus(BatchStatus.COMPLETED); + dao.updateJobExecution(execution); + + JobExecution updated = (JobExecution) dao.findJobExecutions(jobInstance).get(0); + assertEquals(execution, updated); + assertEquals(BatchStatus.COMPLETED, updated.getStatus()); + } + + /** + * Check the execution with most recent start time is returned + */ + public void testGetLastExecution() { + JobExecution exec1 = new JobExecution(jobInstance); + exec1.setStartTime(new Date(0)); + JobExecution exec2 = new JobExecution(jobInstance); + exec2.setStartTime(new Date(1)); + + dao.saveJobExecution(exec1); + dao.saveJobExecution(exec2); + + assertEquals(exec2, dao.getLastJobExecution(jobInstance)); + } } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapStepDaoTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapStepExecutionDaoTests.java similarity index 92% rename from spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapStepDaoTests.java rename to spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapStepExecutionDaoTests.java index c48768d32..a79da25e1 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapStepDaoTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapStepExecutionDaoTests.java @@ -26,9 +26,9 @@ import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.execution.job.JobSupport; import org.springframework.batch.execution.step.StepSupport; -public class MapStepDaoTests extends TestCase { +public class MapStepExecutionDaoTests extends TestCase { - MapStepDao dao = new MapStepDao(); + MapStepExecutionDao dao = new MapStepExecutionDao(); private JobInstance job; @@ -38,7 +38,7 @@ public class MapStepDaoTests extends TestCase { static long jobId = 100; protected void setUp() throws Exception { - MapStepDao.clear(); + MapStepExecutionDao.clear(); job = new JobInstance(new Long(jobId++), new JobParameters(), new JobSupport("testJob")); step = new StepSupport("foo"); } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/ItemOrientedStepTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/ItemOrientedStepTests.java index c5fcba801..ebd5f1b23 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/ItemOrientedStepTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/ItemOrientedStepTests.java @@ -33,7 +33,7 @@ import org.springframework.batch.execution.job.JobSupport; import org.springframework.batch.execution.repository.SimpleJobRepository; import org.springframework.batch.execution.repository.dao.MapJobExecutionDao; import org.springframework.batch.execution.repository.dao.MapJobInstanceDao; -import org.springframework.batch.execution.repository.dao.MapStepDao; +import org.springframework.batch.execution.repository.dao.MapStepExecutionDao; import org.springframework.batch.execution.scope.StepSynchronizationManager; import org.springframework.batch.execution.step.support.JobRepositorySupport; import org.springframework.batch.execution.step.support.StepInterruptionPolicy; @@ -195,7 +195,7 @@ public class ItemOrientedStepTests extends TestCase { public void testRepository() throws Exception { - SimpleJobRepository repository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(), new MapStepDao()); + SimpleJobRepository repository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(), new MapStepExecutionDao()); itemOrientedStep.setJobRepository(repository); JobExecution jobExecutionContext = new JobExecution(jobInstance); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/support/StepExecutorInterruptionTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/support/StepExecutorInterruptionTests.java index 5c8721a98..b7f02af8a 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/support/StepExecutorInterruptionTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/support/StepExecutorInterruptionTests.java @@ -31,7 +31,7 @@ import org.springframework.batch.execution.repository.dao.JobExecutionDao; import org.springframework.batch.execution.repository.dao.JobInstanceDao; import org.springframework.batch.execution.repository.dao.MapJobExecutionDao; import org.springframework.batch.execution.repository.dao.MapJobInstanceDao; -import org.springframework.batch.execution.repository.dao.MapStepDao; +import org.springframework.batch.execution.repository.dao.MapStepExecutionDao; import org.springframework.batch.execution.repository.dao.StepExecutionDao; import org.springframework.batch.execution.step.ItemOrientedStep; import org.springframework.batch.item.reader.AbstractItemReader; @@ -49,14 +49,14 @@ public class StepExecutorInterruptionTests extends TestCase { private JobExecutionDao jobExecutionDao = new MapJobExecutionDao(); - private StepExecutionDao stepExecutionDao = new MapStepDao(); + private StepExecutionDao stepExecutionDao = new MapStepExecutionDao(); private ItemOrientedStep step; public void setUp() throws Exception { MapJobInstanceDao.clear(); MapJobExecutionDao.clear(); - MapStepDao.clear(); + MapStepExecutionDao.clear(); jobRepository = new SimpleJobRepository(jobInstanceDao, jobExecutionDao, stepExecutionDao); diff --git a/spring-batch-execution/src/test/resources/simple-container-definition.xml b/spring-batch-execution/src/test/resources/simple-container-definition.xml index bc15e6e2a..2b3e26e62 100644 --- a/spring-batch-execution/src/test/resources/simple-container-definition.xml +++ b/spring-batch-execution/src/test/resources/simple-container-definition.xml @@ -58,7 +58,7 @@ + class="org.springframework.batch.execution.repository.dao.MapStepExecutionDao" /> + class="org.springframework.batch.execution.repository.dao.MapStepExecutionDao" />