From 0e24dd5e5d43a73e3fb31ecbdb3c2564a6431de8 Mon Sep 17 00:00:00 2001 From: dsyer Date: Fri, 30 Nov 2007 09:21:36 +0000 Subject: [PATCH] IN PROGRESS - BATCH-127: Allow job configuration to control re-entrant behavior http://opensource.atlassian.com/projects/spring/browse/BATCH-127 Added additional exception to signature of JobRepository.findOrCreate(). --- .../batch/core/repository/JobRepository.java | 9 +++++---- .../execution/launch/JobExecutorFacade.java | 3 ++- .../launch/SimpleJobExecutorFacade.java | 19 +++++++++++-------- .../launch/SimpleJobExecutorFacadeTests.java | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/org/springframework/batch/core/repository/JobRepository.java b/core/src/main/java/org/springframework/batch/core/repository/JobRepository.java index 32cf692c9..9aa73c013 100644 --- a/core/src/main/java/org/springframework/batch/core/repository/JobRepository.java +++ b/core/src/main/java/org/springframework/batch/core/repository/JobRepository.java @@ -47,10 +47,11 @@ import org.springframework.batch.core.domain.StepInstance; public interface JobRepository { /** - * Find or create a job for a given Job identifier or configuration. If the - * job that is uniquely identified by JobIdentifier already exists, it's - * persisted values (including ID) will be returned in a new Job object. If - * no previous run is found, a new job will be created and returned. + * Find or create a job for a given {@link JobIdentifier} and configuration. + * If the job that is uniquely identified by {@link JobIdentifier} already + * exists, its persisted values (including ID) will be returned in a new + * {@link JobInstance} object. If no previous run is found, a new job will + * be created and returned. * * @param jobConfiguration * describes the configuration for this job diff --git a/execution/src/main/java/org/springframework/batch/execution/launch/JobExecutorFacade.java b/execution/src/main/java/org/springframework/batch/execution/launch/JobExecutorFacade.java index 5942d35c7..89f44b0b4 100644 --- a/execution/src/main/java/org/springframework/batch/execution/launch/JobExecutorFacade.java +++ b/execution/src/main/java/org/springframework/batch/execution/launch/JobExecutorFacade.java @@ -41,9 +41,10 @@ interface JobExecutorFacade { * the identifier of the job to start * * @throws NoSuchJobConfigurationException + * @throws JobExecutionAlreadyRunningException */ JobExecution createExecutionFrom(JobIdentifier jobIdentifier) - throws NoSuchJobConfigurationException; + throws NoSuchJobConfigurationException, JobExecutionAlreadyRunningException; /** * Start a job execution. diff --git a/execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacade.java b/execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacade.java index af87584cd..742720498 100644 --- a/execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacade.java +++ b/execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacade.java @@ -139,7 +139,8 @@ class SimpleJobExecutorFacade implements JobExecutorFacade, * Locates a {@link JobConfiguration} by using the name of the provided * {@link JobIdentifier} and the {@link JobConfigurationLocator}. * - * @param jobIdentifier the identifier of the job that is being prepared. + * @param jobIdentifier + * the identifier of the job that is being prepared. * * @throws IllegalArgumentException * if the {@link JobIdentifier} is null or its name is null @@ -150,14 +151,15 @@ class SimpleJobExecutorFacade implements JobExecutorFacade, * @see org.springframework.batch.execution.launch.JobExecutorFacade#createExecutionFrom(org.springframework.batch.core.domain.JobIdentifier) */ public JobExecution createExecutionFrom(JobIdentifier jobIdentifier) - throws NoSuchJobConfigurationException { + throws NoSuchJobConfigurationException, JobExecutionAlreadyRunningException { Assert.notNull(jobIdentifier, "JobIdentifier must not be null."); Assert.notNull(jobIdentifier.getName(), "JobIdentifier name must not be null."); - Assert - .state(!jobExecutionRegistry.containsKey(jobIdentifier), - "A job with this JobRuntimeInformation is already executing in this container"); + if (jobExecutionRegistry.containsKey(jobIdentifier)) { + throw new JobExecutionAlreadyRunningException( + "A job with this JobIdentifier is already executing in this container: "+jobIdentifier); + }; JobConfiguration jobConfiguration = jobConfigurationLocator .getJobConfiguration(jobIdentifier.getName()); @@ -270,10 +272,11 @@ class SimpleJobExecutorFacade implements JobExecutorFacade, * * @see org.springframework.batch.container.BatchContainer#onStop(org.springframework.batch.container.common.runtime.JobRuntimeInformation) */ - public void stop(JobExecution execution) - throws NoSuchJobExecutionException { + public void stop(JobExecution execution) throws NoSuchJobExecutionException { if (!jobExecutionRegistry.containsValue(execution)) { - throw new NoSuchJobExecutionException("The job is not executing in this executor: ["+execution+"]"); + throw new NoSuchJobExecutionException( + "The job is not executing in this executor: [" + execution + + "]"); } for (Iterator iter = execution.getStepContexts().iterator(); iter .hasNext();) { diff --git a/execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacadeTests.java b/execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacadeTests.java index 32dc86418..19dfc12b4 100644 --- a/execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacadeTests.java +++ b/execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacadeTests.java @@ -247,6 +247,21 @@ public class SimpleJobExecutorFacadeTests extends TestCase { assertTrue(statistics.containsKey("job1.step1")); } + public void testJobAlreadyExecutingLocally() throws Exception { + SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier( + "TestJob"); + JobExecution execution = new JobExecution(new JobInstance( + runtimeInformation, new Long(0))); + registerExecution(runtimeInformation, execution); + try { + jobExecutorFacade.createExecutionFrom(runtimeInformation); + fail("Expected JobExecutionAlreadyRunningException"); + } catch (JobExecutionAlreadyRunningException e) { + // expected + assertTrue("Message does not contain TestJob: "+e.getMessage(), e.getMessage().indexOf("TestJob")>=0); + } + } + public void testListenersCalledLastOnStop() throws Exception { List listeners = new ArrayList(); listeners.add(new JobExecutionListenerSupport() {