diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/Step.java b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/Step.java index e26e79608..6366dbc4b 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/Step.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/Step.java @@ -15,6 +15,7 @@ */ package org.springframework.batch.core.domain; +import org.springframework.batch.core.executor.StepExecutor; import org.springframework.batch.core.tasklet.Tasklet; /** @@ -56,5 +57,10 @@ public interface Step { * identifier. */ int getStartLimit(); + + /** + * @return a {@link StepExecutor} that could be used to execute this step + */ + StepExecutor createStepExecutor(); } \ No newline at end of file diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/StepSupport.java b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/StepSupport.java index 31237181d..2bf8ee0b6 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/StepSupport.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/StepSupport.java @@ -15,23 +15,28 @@ */ package org.springframework.batch.core.domain; +import org.springframework.batch.core.executor.StepExecutor; import org.springframework.batch.core.tasklet.Tasklet; import org.springframework.beans.factory.BeanNameAware; /** - * Basic no-op support implementation for use as base class for - * {@link Step}. + * Basic no-op support implementation for use as base class for {@link Step}. + * Implements {@link BeanNameAware} so that if no name is provided explicitly it + * will be inferred from the bean definition in Spring configuration. * * @author Dave Syer * */ -public class StepSupport implements Step, - BeanNameAware { +public class StepSupport implements Step, BeanNameAware { private String name; + private int startLimit = Integer.MAX_VALUE; + private Tasklet tasklet; + private boolean allowStartIfComplete; + private boolean saveRestartData = false; /** @@ -68,7 +73,7 @@ public class StepSupport implements Step, * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String) */ public void setBeanName(String name) { - if (this.name==null) { + if (this.name == null) { this.name = name; } } @@ -95,8 +100,7 @@ public class StepSupport implements Step, /** * Public setter for the startLimit. * - * @param startLimit - * the startLimit to set + * @param startLimit the startLimit to set */ public void setStartLimit(int startLimit) { this.startLimit = startLimit; @@ -114,8 +118,7 @@ public class StepSupport implements Step, /** * Public setter for the tasklet. * - * @param tasklet - * the tasklet to set + * @param tasklet the tasklet to set */ public void setTasklet(Tasklet tasklet) { this.tasklet = tasklet; @@ -133,8 +136,7 @@ public class StepSupport implements Step, /** * Public setter for the shouldAllowStartIfComplete. * - * @param allowStartIfComplete - * the shouldAllowStartIfComplete to set + * @param allowStartIfComplete the shouldAllowStartIfComplete to set */ public void setAllowStartIfComplete(boolean allowStartIfComplete) { this.allowStartIfComplete = allowStartIfComplete; @@ -148,4 +150,15 @@ public class StepSupport implements Step, return saveRestartData; } + /** + * Not supported but provided so that tests can easily create a step. + * + * @throws UnsupportedOperationException always + * + * @see org.springframework.batch.core.domain.Step#createStepExecutor() + */ + public StepExecutor createStepExecutor() { + throw new UnsupportedOperationException( + "Cannot create a StepExecutor. Use a smarter subclass of StepSupport like a SimpleStep."); + } } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/DefaultJobExecutor.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/DefaultJobExecutor.java index 1db48401f..a46099759 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/DefaultJobExecutor.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/DefaultJobExecutor.java @@ -31,7 +31,6 @@ import org.springframework.batch.core.domain.StepInstance; import org.springframework.batch.core.executor.ExitCodeExceptionClassifier; import org.springframework.batch.core.executor.JobExecutor; import org.springframework.batch.core.executor.StepExecutor; -import org.springframework.batch.core.executor.StepExecutorFactory; import org.springframework.batch.core.executor.StepInterruptedException; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.execution.step.simple.SimpleExitCodeExceptionClassifier; @@ -52,8 +51,6 @@ public class DefaultJobExecutor implements JobExecutor { private JobRepository jobRepository; - private StepExecutorFactory stepExecutorFactory = DEFAULT_STEP_EXECUTOR_FACTORY; - private ExitCodeExceptionClassifier exceptionClassifier = new SimpleExitCodeExceptionClassifier(); /** @@ -89,8 +86,7 @@ public class DefaultJobExecutor implements JobExecutor { if (shouldStart(stepInstance, step)) { startedCount++; updateStatus(execution, BatchStatus.STARTED); - StepExecutor stepExecutor = stepExecutorFactory - .getExecutor(step); + StepExecutor stepExecutor = step.createStepExecutor(); StepExecution stepExecution = execution.createStepExecution(stepInstance); status = stepExecutor.process(step, stepExecution); @@ -181,18 +177,6 @@ public class DefaultJobExecutor implements JobExecutor { DEFAULT_STEP_EXECUTOR_FACTORY.setJobRepository(jobRepository); } - /** - * Setter for injecting a {@link StepExecutorFactory}. The factory is - * responsible for providing a {@link StepExecutor} to execute each step in - * turn. The values returned from the factory are not cached or re-used by - * this implementation. - * - * @param stepExecutorFactory - */ - public void setStepExecutorFactory(StepExecutorFactory stepExecutorFactory) { - this.stepExecutorFactory = stepExecutorFactory; - } - /** * Public setter for injecting an {@link ExceptionClassifier} that can * translate exceptions to {@link ExitStatus}. diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/AbstractStep.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/AbstractStep.java deleted file mode 100644 index 16e584275..000000000 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/AbstractStep.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2006-2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.execution.step; - -import org.springframework.batch.core.domain.Step; -import org.springframework.batch.core.domain.StepSupport; -import org.springframework.batch.repeat.exception.handler.ExceptionHandler; -import org.springframework.beans.factory.BeanNameAware; - -/** - * A {@link Step} implementation that provides common behaviour to - * subclasses. Implements {@link BeanNameAware} so that if no name is provided - * explicitly it will be inferred from the bean definition in Spring - * configuration. - * - * @author Dave Syer - * - */ -public class AbstractStep extends StepSupport { - - private int skipLimit = 0; - - private ExceptionHandler exceptionHandler; - - /** - * Default constructor. - */ - public AbstractStep() { - super(); - } - - /** - * Convenient constructor for setting only the name property. - * @param name - */ - public AbstractStep(String name) { - super(name); - } - - public ExceptionHandler getExceptionHandler() { - return exceptionHandler; - } - - public void setExceptionHandler(ExceptionHandler exceptionHandler) { - this.exceptionHandler = exceptionHandler; - } - - public void setSkipLimit(int skipLimit) { - this.skipLimit = skipLimit; - } - - public int getSkipLimit() { - return skipLimit; - } - -} \ No newline at end of file diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/PrototypeBeanStepExecutorFactory.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/PrototypeBeanStepExecutorFactory.java deleted file mode 100644 index 7c34d2cac..000000000 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/PrototypeBeanStepExecutorFactory.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2006-2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.execution.step; - -import org.springframework.batch.core.domain.Step; -import org.springframework.batch.core.executor.StepExecutor; -import org.springframework.batch.core.executor.StepExecutorFactory; -import org.springframework.batch.execution.step.simple.SimpleStepExecutor; -import org.springframework.batch.repeat.RepeatOperations; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; - -/** - * A {@link StepExecutorFactory} that uses a prototype bean in the application - * context to satisfy the factory contract. If the prototype bean and - * {@link Step} are of known (simple) type, they can be combined to - * add the commit interval information from the step.
- * - * The nominated bean has to be a prototype because its state may be changed - * before it is used, applying values for things like commit interval from the - * {@link Step}. - * - * @author Dave Syer - * - */ -public class PrototypeBeanStepExecutorFactory implements StepExecutorFactory, - BeanFactoryAware, InitializingBean { - - private String stepExecutorName = null; - - private BeanFactory beanFactory; - - /** - * Setter for injected {@link BeanFactory}. - * - * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory) - */ - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; - } - - /** - * Assert that if the step executor name is provided, then it is valid and - * is of prototype scope. - * - * @see InitializingBean#afterPropertiesSet() - */ - public void afterPropertiesSet() throws Exception { - // Make an assertion that the bean exists and is of the correct type - Assert - .notNull(beanFactory.getBean(stepExecutorName, - StepExecutor.class), - "Step executor name must correspond to a StepExecutor instance."); - Assert.state(beanFactory.isPrototype(stepExecutorName), - "StepExecutor must be a prototype. Change the scope of the bean named '" - + stepExecutorName + "' to prototype."); - } - - /** - * Locate a {@link StepExecutor} for this configuration, allowing different - * strategies for configuring the inner loop (chunk operations). Try the - * following in this order, until one succeeds. In each case first obtain - * the {@link StepExecutor} referred to by the {@link #stepExecutorName}, - * then: - * - *
- * - * @throws IllegalStateException - * if no {@link StepExecutor} can be located. - * - * @see StepExecutorFactory#getExecutor(Step) - */ - public StepExecutor getExecutor(Step step) { - StepExecutor executor = getStepExecutor(); - executor.applyConfiguration(step); - return executor; - } - - /** - * Setter for the bean name of the {@link StepExecutor} to use. The - * corresponding bean must be prototype scoped, so that its properties can - * be overridden per execution by the {@link Step}. - * - * @param stepExecutor - * the stepExecutor to set - */ - public void setStepExecutorName(String stepExecutorName) { - this.stepExecutorName = stepExecutorName; - } - - /** - * Internal convenience method to get a step executor instance. - * - * @return the step executor instance to use. - */ - private StepExecutor getStepExecutor() { - return (StepExecutor) beanFactory.getBean(stepExecutorName, - StepExecutor.class); - } - -} diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/AbstractStep.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/AbstractStep.java new file mode 100644 index 000000000..10b9d9ca6 --- /dev/null +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/AbstractStep.java @@ -0,0 +1,121 @@ +/* + * Copyright 2006-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.execution.step.simple; + +import org.springframework.batch.core.domain.Step; +import org.springframework.batch.core.domain.StepSupport; +import org.springframework.batch.core.executor.StepExecutor; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.repeat.exception.handler.ExceptionHandler; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.util.Assert; + +/** + * A {@link Step} implementation that provides common behaviour to + * subclasses. + * + * @author Dave Syer + * + */ +public abstract class AbstractStep extends StepSupport { + + private int skipLimit = 0; + + private ExceptionHandler exceptionHandler; + + protected JobRepository jobRepository; + + protected PlatformTransactionManager transactionManager; + + /** + * Default constructor. + */ + public AbstractStep() { + super(); + } + + /** + * Convenient constructor for setting only the name property. + * @param name + */ + public AbstractStep(String name) { + super(name); + } + + public ExceptionHandler getExceptionHandler() { + return exceptionHandler; + } + + public void setExceptionHandler(ExceptionHandler exceptionHandler) { + this.exceptionHandler = exceptionHandler; + } + + public void setSkipLimit(int skipLimit) { + this.skipLimit = skipLimit; + } + + public int getSkipLimit() { + return skipLimit; + } + + /** + * Public setter for {@link JobRepository}. + * + * @param jobRepository + * is a mandatory dependence (no default). + */ + public void setJobRepository(JobRepository jobRepository) { + this.jobRepository = jobRepository; + } + + /** + * Public setter for the {@link PlatformTransactionManager}. + * @param transactionManager the transaction manager to set + */ + public void setTransactionManager(PlatformTransactionManager transactionManager) { + this.transactionManager = transactionManager; + } + + /** + * Assert that all mandatory properties are set (the {@link JobRepository}). + * + * @throws Exception + */ + public void afterPropertiesSet() throws Exception { + assertMandatoryProperties(); + } + + protected void assertMandatoryProperties() { + Assert.notNull(jobRepository, "JobRepository is mandatory"); + Assert.notNull(transactionManager, "TransactionManager is mandatory"); + } + + /** + * Create a {@link SimpleStepExecutor}. + * + * @see org.springframework.batch.core.domain.Step#createStepExecutor() + */ + public StepExecutor createStepExecutor() { + assertMandatoryProperties(); + SimpleStepExecutor executor = new SimpleStepExecutor(); + executor.setRepository(jobRepository); + executor.applyConfiguration(this); + executor.setTasklet(getTasklet()); + executor.setTransactionManager(transactionManager); + return executor; + } + +} \ No newline at end of file diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/RepeatOperationsHolder.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/RepeatOperationsHolder.java similarity index 94% rename from spring-batch-execution/src/main/java/org/springframework/batch/execution/step/RepeatOperationsHolder.java rename to spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/RepeatOperationsHolder.java index d34d93115..1efe2422f 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/RepeatOperationsHolder.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/RepeatOperationsHolder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.batch.execution.step; +package org.springframework.batch.execution.step.simple; import org.springframework.batch.core.domain.Step; import org.springframework.batch.core.executor.StepExecutor; diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/RepeatOperationsStep.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/RepeatOperationsStep.java similarity index 68% rename from spring-batch-execution/src/main/java/org/springframework/batch/execution/step/RepeatOperationsStep.java rename to spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/RepeatOperationsStep.java index 5f97f0522..530af6915 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/RepeatOperationsStep.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/RepeatOperationsStep.java @@ -14,14 +14,16 @@ * limitations under the License. */ -package org.springframework.batch.execution.step; +package org.springframework.batch.execution.step.simple; import org.springframework.batch.core.domain.Step; +import org.springframework.batch.core.executor.StepExecutor; import org.springframework.batch.repeat.RepeatOperations; +import org.springframework.util.Assert; /** - * {@link Step} implementation that allows full step of - * the {@link RepeatOperations} that will be used in the chunk (inner loop). + * {@link Step} implementation that allows full step of the + * {@link RepeatOperations} that will be used in the chunk (inner loop). * * @author Lucas Ward * @author Dave Syer @@ -31,6 +33,7 @@ public class RepeatOperationsStep extends AbstractStep implements RepeatOperatio // default chunkOperations is null private RepeatOperations chunkOperations; + // default stepOperations is null private RepeatOperations stepOperations; @@ -54,7 +57,7 @@ public class RepeatOperationsStep extends AbstractStep implements RepeatOperatio /** * Public accessor for the stepOperations property. - * + * * @return the stepOperations */ public RepeatOperations getStepOperations() { @@ -63,11 +66,28 @@ public class RepeatOperationsStep extends AbstractStep implements RepeatOperatio /** * Public setter for the {@link RepeatOperations} property. - * + * * @param stepOperations the stepOperations to set */ public void setStepOperations(RepeatOperations stepOperations) { this.stepOperations = stepOperations; } + /** + * Create a new {@link SimpleStepExecutor} with the step and chunk + * operations. + * + * @see org.springframework.batch.core.domain.StepSupport#createStepExecutor() + */ + public StepExecutor createStepExecutor() { + Assert.notNull(jobRepository, "JobRepository is mandatory"); + SimpleStepExecutor executor = (SimpleStepExecutor) super.createStepExecutor(); + if (stepOperations != null) { + executor.setStepOperations(stepOperations); + } + if (chunkOperations != null) { + executor.setChunkOperations(chunkOperations); + } + return executor; + } } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/SimpleStep.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStep.java similarity index 95% rename from spring-batch-execution/src/main/java/org/springframework/batch/execution/step/SimpleStep.java rename to spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStep.java index 273b4e6a7..376f126c6 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/SimpleStep.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStep.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.batch.execution.step; +package org.springframework.batch.execution.step.simple; import org.springframework.batch.core.domain.Step; import org.springframework.batch.core.tasklet.Tasklet; @@ -28,10 +28,9 @@ import org.springframework.batch.core.tasklet.Tasklet; * */ public class SimpleStep extends AbstractStep { - + // default commit interval is one private int commitInterval = 1; - public SimpleStep() { super(); } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java index 3fe9974c1..1a9e899d3 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java @@ -33,8 +33,6 @@ import org.springframework.batch.execution.scope.SimpleStepContext; import org.springframework.batch.execution.scope.StepContext; import org.springframework.batch.execution.scope.StepScope; import org.springframework.batch.execution.scope.StepSynchronizationManager; -import org.springframework.batch.execution.step.RepeatOperationsHolder; -import org.springframework.batch.execution.step.SimpleStep; import org.springframework.batch.io.Skippable; import org.springframework.batch.io.exception.BatchCriticalException; import org.springframework.batch.repeat.ExitStatus; @@ -96,6 +94,8 @@ public class SimpleStepExecutor implements StepExecutor { private StatisticsService statisticsService = new SimpleStatisticsService(); + private Tasklet tasklet; + /** * Public setter for the {@link StatisticsService}. This will be used to * create the {@link StepContext}, and hence any component that is a @@ -172,8 +172,6 @@ public class SimpleStepExecutor implements StepExecutor { boolean isRestart = stepInstance.getStepExecutionCount() > 0 ? true : false; Assert.notNull(stepInstance); - final Tasklet module = step.getTasklet(); - ExitStatus status = ExitStatus.FAILED; StepContext parentStepScopeContext = StepSynchronizationManager.getContext(); @@ -191,7 +189,7 @@ public class SimpleStepExecutor implements StepExecutor { final boolean saveRestartData = step.isSaveRestartData(); if (saveRestartData && isRestart) { - restoreFromRestartData(module, stepInstance.getRestartData()); + restoreFromRestartData(tasklet, stepInstance.getRestartData()); } status = stepOperations.iterate(new RepeatCallback() { @@ -232,7 +230,7 @@ public class SimpleStepExecutor implements StepExecutor { stepExecution.apply(contribution); if (saveRestartData) { - stepInstance.setRestartData(getRestartData(module)); + stepInstance.setRestartData(getRestartData(tasklet)); jobRepository.update(stepInstance); } jobRepository.saveOrUpdate(stepExecution); @@ -338,7 +336,7 @@ public class SimpleStepExecutor implements StepExecutor { } // check for interruption before each item as well interruptionPolicy.checkInterrupted(context); - ExitStatus exitStatus = doTaskletProcessing(step.getTasklet(), contribution); + ExitStatus exitStatus = doTaskletProcessing(tasklet, contribution); contribution.incrementTaskCount(); // check for interruption after each item as well interruptionPolicy.checkInterrupted(context); @@ -447,7 +445,6 @@ public class SimpleStepExecutor implements StepExecutor { RepeatOperationsHolder holder = (RepeatOperationsHolder) step; RepeatOperations chunkOperations = holder.getChunkOperations(); RepeatOperations stepOperations = holder.getStepOperations(); - Assert.state(chunkOperations != null, "Chunk operations obtained from step must be non-null."); if (chunkOperations != null) { setChunkOperations(chunkOperations); @@ -457,7 +454,7 @@ public class SimpleStepExecutor implements StepExecutor { } } - else if (step instanceof SimpleStep) { + else if (step instanceof AbstractStep) { SimpleStep simpleConfiguation = (SimpleStep) step; if (this.chunkOperations instanceof RepeatTemplate) { @@ -481,4 +478,11 @@ public class SimpleStepExecutor implements StepExecutor { } } + + /** + * @param tasklet a {@link Tasklet} to execute when a step is processed + */ + public void setTasklet(Tasklet tasklet) { + this.tasklet = tasklet; + } } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorFactory.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorFactory.java index e1e02dd62..e431fae39 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorFactory.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorFactory.java @@ -19,7 +19,6 @@ import org.springframework.batch.core.domain.Step; import org.springframework.batch.core.executor.StepExecutor; import org.springframework.batch.core.executor.StepExecutorFactory; import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.execution.step.SimpleStep; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; @@ -51,7 +50,7 @@ public class SimpleStepExecutorFactory implements StepExecutorFactory, public StepExecutor getExecutor(Step step) { Assert.notNull(jobRepository, "JobRepository cannot be null"); - Assert.state(step instanceof SimpleStep, + Assert.state(step instanceof AbstractStep, "Step must be instance of SimpleStep - found: [" + (step == null ? null : step .getClass()) + "]"); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java index ce8393180..284d14c9b 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java @@ -29,10 +29,8 @@ import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.core.domain.Step; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.core.domain.StepSupport; import org.springframework.batch.core.executor.ExitCodeExceptionClassifier; import org.springframework.batch.core.executor.StepExecutor; -import org.springframework.batch.core.executor.StepExecutorFactory; import org.springframework.batch.core.executor.StepInterruptedException; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.tasklet.Tasklet; @@ -41,7 +39,8 @@ import org.springframework.batch.execution.repository.dao.JobDao; import org.springframework.batch.execution.repository.dao.MapJobDao; import org.springframework.batch.execution.repository.dao.MapStepDao; import org.springframework.batch.execution.repository.dao.StepDao; -import org.springframework.batch.execution.step.SimpleStep; +import org.springframework.batch.execution.step.simple.AbstractStep; +import org.springframework.batch.execution.step.simple.SimpleStep; import org.springframework.batch.io.exception.BatchCriticalException; import org.springframework.batch.repeat.ExitStatus; @@ -91,9 +90,9 @@ public class DefaultJobExecutorTests extends TestCase { private StepExecution stepExecution2; - private StepSupport stepConfiguration1; + private AbstractStep stepConfiguration1; - private StepSupport stepConfiguration2; + private AbstractStep stepConfiguration2; private Job jobConfiguration; @@ -112,14 +111,19 @@ public class DefaultJobExecutorTests extends TestCase { jobExecutor = new DefaultJobExecutor(); jobExecutor.setJobRepository(jobRepository); - jobExecutor.setStepExecutorFactory(new StepExecutorFactory() { - public StepExecutor getExecutor(Step configuration) { + stepConfiguration1 = new SimpleStep("TestStep1") { + public StepExecutor createStepExecutor() { return defaultStepLifecycle; } - }); + }; + stepConfiguration2 = new SimpleStep("TestStep2") { + public StepExecutor createStepExecutor() { + return defaultStepLifecycle; + } + }; + stepConfiguration1.setJobRepository(jobRepository); + stepConfiguration2.setJobRepository(jobRepository); - stepConfiguration1 = new SimpleStep("TestStep1"); - stepConfiguration2 = new SimpleStep("TestStep2"); List stepConfigurations = new ArrayList(); stepConfigurations.add(stepConfiguration1); stepConfigurations.add(stepConfiguration2); @@ -183,25 +187,6 @@ public class DefaultJobExecutorTests extends TestCase { assertEquals(step2, stepExecution2.getStep()); } - public void testRunWithNonDefaultExecutor() throws Exception { - - jobExecutor.setStepExecutorFactory(new StepExecutorFactory() { - public StepExecutor getExecutor(Step configuration) { - return configuration == stepConfiguration2 ? defaultStepLifecycle - : configurationStepLifecycle; - } - }); - stepConfiguration1.setStartLimit(5); - stepConfiguration2.setStartLimit(5); - - jobExecutor.run(jobConfiguration, jobExecution); - - assertEquals(2, list.size()); - assertEquals("special", list.get(0)); - assertEquals("default", list.get(1)); - checkRepository(BatchStatus.COMPLETED); - } - public void testInterrupted() throws Exception { stepConfiguration1.setStartLimit(5); stepConfiguration2.setStartLimit(5); 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 73b81cb38..ef2dde300 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 @@ -27,15 +27,14 @@ import org.springframework.batch.core.domain.Job; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.domain.JobParameters; -import org.springframework.batch.core.domain.Step; -import org.springframework.batch.core.executor.StepExecutor; -import org.springframework.batch.core.executor.StepExecutorFactory; import org.springframework.batch.core.tasklet.Tasklet; import org.springframework.batch.execution.job.DefaultJobExecutor; import org.springframework.batch.execution.repository.SimpleJobRepository; import org.springframework.batch.execution.repository.dao.MapJobDao; import org.springframework.batch.execution.repository.dao.MapStepDao; -import org.springframework.batch.execution.step.SimpleStep; +import org.springframework.batch.execution.step.simple.AbstractStep; +import org.springframework.batch.execution.step.simple.RepeatOperationsStep; +import org.springframework.batch.execution.step.simple.SimpleStep; import org.springframework.batch.execution.step.simple.SimpleStepExecutor; import org.springframework.batch.execution.tasklet.ItemOrientedTasklet; import org.springframework.batch.item.ItemReader; @@ -47,9 +46,7 @@ import org.springframework.batch.repeat.exception.handler.ExceptionHandler; import org.springframework.batch.repeat.support.RepeatTemplate; import org.springframework.batch.support.transaction.ResourcelessTransactionManager; import org.springframework.batch.support.transaction.TransactionAwareProxyFactory; -import org.springframework.transaction.interceptor.TransactionProxyFactoryBean; import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.util.StringUtils; public class SimpleJobTests extends TestCase { @@ -75,11 +72,6 @@ public class SimpleJobTests extends TestCase { super.setUp(); jobExecutor.setJobRepository(repository); stepLifecycle.setRepository(repository); - jobExecutor.setStepExecutorFactory(new StepExecutorFactory() { - public StepExecutor getExecutor(Step configuration) { - return stepLifecycle; - } - }); } private Tasklet getTasklet(String arg) throws Exception { @@ -111,8 +103,14 @@ public class SimpleJobTests extends TestCase { public void testSimpleJob() throws Exception { Job jobConfiguration = new Job(); - jobConfiguration.addStep(new SimpleStep(getTasklet("foo", "bar"))); - jobConfiguration.addStep(new SimpleStep(getTasklet("spam"))); + AbstractStep step = new SimpleStep(getTasklet("foo", "bar")); + step.setJobRepository(repository); + step.setTransactionManager(new ResourcelessTransactionManager()); + jobConfiguration.addStep(step); + step = new SimpleStep(getTasklet("spam")); + step.setJobRepository(repository); + step.setTransactionManager(new ResourcelessTransactionManager()); + jobConfiguration.addStep(step); JobInstance job = repository.createJobExecution(jobConfiguration, new JobParameters()).getJobInstance(); @@ -138,15 +136,6 @@ public class SimpleJobTests extends TestCase { assertEquals("Try again Dummy!", throwable.getMessage()); } }); - stepLifecycle.setChunkOperations(chunkOperations); - - TransactionProxyFactoryBean proxyFactoryBean = new TransactionProxyFactoryBean(); - proxyFactoryBean.setTransactionManager(new ResourcelessTransactionManager()); - proxyFactoryBean.setTarget(stepLifecycle); - proxyFactoryBean.setTransactionAttributes(StringUtils.splitArrayElementsIntoProperties( - new String[] { "processChunk=PROPAGATION_REQUIRED" }, "=")); - proxyFactoryBean.setExposeProxy(true); - proxyFactoryBean.afterPropertiesSet(); /* * Each message fails once and the chunk (size=1) "rolls back"; then it @@ -154,7 +143,11 @@ public class SimpleJobTests extends TestCase { * definition above)... */ final ItemOrientedTasklet module = getTasklet(new String[] { "foo", "bar", "spam" }); - Step step = new SimpleStep(module); + RepeatOperationsStep step = new RepeatOperationsStep(); + step.setTasklet(module); + step.setChunkOperations(chunkOperations); + step.setJobRepository(repository); + step.setTransactionManager(new ResourcelessTransactionManager()); module.setItemWriter(new ItemWriter() { public void write(Object data) throws Exception { throw new RuntimeException("Try again Dummy!"); @@ -177,7 +170,9 @@ public class SimpleJobTests extends TestCase { Job jobConfiguration = new Job(); final ItemOrientedTasklet module = getTasklet(new String[] { "foo", "bar", "spam" }); - Step step = new SimpleStep(module); + AbstractStep step = new SimpleStep(module); + step.setJobRepository(repository); + step.setTransactionManager(new ResourcelessTransactionManager()); module.setItemWriter(new ItemWriter() { public void write(Object data) throws Exception { throw new RuntimeException("Foo"); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/PrototypeBeanStepExecutorFactoryTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/PrototypeBeanStepExecutorFactoryTests.java deleted file mode 100644 index 1caa2877f..000000000 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/PrototypeBeanStepExecutorFactoryTests.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2006-2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.execution.step; - -import java.util.ArrayList; -import java.util.List; - -import junit.framework.TestCase; - -import org.springframework.batch.core.domain.StepSupport; -import org.springframework.batch.core.executor.StepExecutor; -import org.springframework.batch.execution.step.simple.SimpleStepExecutor; -import org.springframework.batch.repeat.RepeatOperations; -import org.springframework.batch.repeat.support.RepeatTemplate; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.context.support.StaticApplicationContext; - -/** - * @author Dave Syer - * - */ -public class PrototypeBeanStepExecutorFactoryTests extends TestCase { - - private PrototypeBeanStepExecutorFactory factory = new PrototypeBeanStepExecutorFactory(); - private StaticApplicationContext applicationContext = new StaticApplicationContext(); - - protected void setUp() throws Exception { - factory.setBeanFactory(applicationContext); - } - - public void testMissingStepExecutorName() throws Exception { - try { - factory.afterPropertiesSet(); - fail("Expected IllegalArgumentException"); - } catch(IllegalArgumentException e) { - // Missing name is illegal - } - } - - public void testMissingStepExecutor() throws Exception { - factory.setStepExecutorName("foo"); - try { - factory.afterPropertiesSet(); - fail("Expected NoSuchBeanDefinitionException"); - } catch(NoSuchBeanDefinitionException e) { - // expected - } - } - - public void testSingletonStepExecutor() throws Exception { - applicationContext.getDefaultListableBeanFactory().registerBeanDefinition("foo", new RootBeanDefinition(SimpleStepExecutor.class)); - factory.setStepExecutorName("foo"); - try { - factory.afterPropertiesSet(); - fail("Expected IllegalStateException"); - } catch(IllegalStateException e) { - // expected - } - } - - public void testSuccessfulStepExecutor() throws Exception { - SimpleStepExecutor executor = new SimpleStepExecutor(); - applicationContext.getBeanFactory().registerSingleton("foo", executor); - factory.setStepExecutorName("foo"); - assertEquals(executor, factory.getExecutor(new SimpleStep())); - } - - public void testSuccessfulStepExecutorWithNonSimpleConfigugration() throws Exception { - SimpleStepExecutor executor = new SimpleStepExecutor(); - applicationContext.getBeanFactory().registerSingleton("foo", executor); - factory.setStepExecutorName("foo"); - assertEquals(executor, factory.getExecutor(new StepSupport())); - } - - public void testSuccessfulStepExecutorWithSimpleConfigurationAndNotSimpleExecutor() throws Exception { - StepExecutor executor = new SimpleStepExecutor(); - applicationContext.getBeanFactory().registerSingleton("foo", executor); - factory.setStepExecutorName("foo"); - assertEquals(executor, factory.getExecutor(new SimpleStep())); - } - - public void testSuccessfulStepExecutorHolderStrategy() throws Exception { - SimpleStepExecutor executor = new SimpleStepExecutor(); - applicationContext.getBeanFactory().registerSingleton("foo", executor); - factory.setStepExecutorName("foo"); - RepeatTemplate repeatTemplate = new RepeatTemplate(); - assertEquals(executor, factory.getExecutor(new SimpleHolderStepConfiguration(repeatTemplate))); - } - - public void testSuccessfulStepExecutorHolderStrategyWithStepOperations() throws Exception { - final List list = new ArrayList(); - SimpleStepExecutor executor = new SimpleStepExecutor() { - public void setChunkOperations(RepeatOperations chunkOperations) { - list.add(chunkOperations); - super.setChunkOperations(chunkOperations); - } - public void setStepOperations(RepeatOperations stepOperations) { - list.add(stepOperations); - super.setStepOperations(stepOperations); - } - }; - applicationContext.getBeanFactory().registerSingleton("foo", executor); - factory.setStepExecutorName("foo"); - RepeatTemplate chunkTemplate = new RepeatTemplate(); - RepeatTemplate stepTemplate = new RepeatTemplate(); - SimpleStepExecutor product = (SimpleStepExecutor) factory.getExecutor(new SimpleHolderStepConfiguration(chunkTemplate, stepTemplate)); - assertEquals(executor, product); - assertEquals(2, list.size()); - assertEquals(chunkTemplate, list.get(0)); - assertEquals(stepTemplate, list.get(1)); - } - - public void testUnsuccessfulStepExecutorHolderStrategy() throws Exception { - SimpleStepExecutor executor = new SimpleStepExecutor(); - applicationContext.getBeanFactory().registerSingleton("foo", executor); - factory.setStepExecutorName("foo"); - try { - factory.getExecutor(new SimpleHolderStepConfiguration(null)); - fail("Expected IllegalStateException"); - } catch (IllegalStateException e) { - // expected - } - } - - /** - * @author Dave Syer - * - */ - public class SimpleHolderStepConfiguration extends SimpleStep implements RepeatOperationsHolder { - private RepeatOperations chunkOperations; - private RepeatOperations stepOperations; - public SimpleHolderStepConfiguration(RepeatOperations executor) { - this.chunkOperations = executor; - } - public SimpleHolderStepConfiguration(RepeatOperations chunkOperations, - RepeatOperations stepOperations) { - this.chunkOperations = chunkOperations; - this.stepOperations = stepOperations; - } - public RepeatOperations getChunkOperations() { - return chunkOperations; - } - public RepeatOperations getStepOperations() { - return stepOperations; - } - } - -} diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/RepeatOperationsStepTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/RepeatOperationsStepTests.java index d17ed8dd2..73cd22c2d 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/RepeatOperationsStepTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/RepeatOperationsStepTests.java @@ -17,7 +17,6 @@ package org.springframework.batch.execution.step.simple; import junit.framework.TestCase; -import org.springframework.batch.execution.step.RepeatOperationsStep; import org.springframework.batch.repeat.support.RepeatTemplate; /** @@ -29,7 +28,7 @@ public class RepeatOperationsStepTests extends TestCase { RepeatOperationsStep configuration = new RepeatOperationsStep(); /** - * Test method for {@link org.springframework.batch.execution.step.RepeatOperationsStep#getChunkOperations()}. + * Test method for {@link org.springframework.batch.execution.step.simple.RepeatOperationsStep#getChunkOperations()}. */ public void testSetChunkOperations() { assertNull(configuration.getChunkOperations()); @@ -40,7 +39,7 @@ public class RepeatOperationsStepTests extends TestCase { } /** - * Test method for {@link org.springframework.batch.execution.step.RepeatOperationsStep#getChunkOperations()}. + * Test method for {@link org.springframework.batch.execution.step.simple.RepeatOperationsStep#getChunkOperations()}. */ public void testSetStepOperations() { assertNull(configuration.getChunkOperations()); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepConfigurationTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepConfigurationTests.java index 3e47914bd..feb3c3aa6 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepConfigurationTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepConfigurationTests.java @@ -18,7 +18,6 @@ package org.springframework.batch.execution.step.simple; import junit.framework.TestCase; import org.springframework.batch.core.tasklet.Tasklet; -import org.springframework.batch.execution.step.SimpleStep; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.exception.handler.DefaultExceptionHandler; @@ -31,7 +30,7 @@ public class SimpleStepConfigurationTests extends TestCase { SimpleStep configuration = new SimpleStep("foo"); /** - * Test method for {@link org.springframework.batch.execution.step.SimpleStep#SimpleStepConfiguration()}. + * Test method for {@link org.springframework.batch.execution.step.simple.SimpleStep#SimpleStepConfiguration()}. */ public void testSimpleStepConfiguration() { assertNotNull(configuration.getName()); @@ -40,7 +39,7 @@ public class SimpleStepConfigurationTests extends TestCase { } /** - * Test method for {@link org.springframework.batch.execution.step.SimpleStep#SimpleStepConfiguration(org.springframework.batch.core.tasklet.Tasklet)}. + * Test method for {@link org.springframework.batch.execution.step.simple.SimpleStep#SimpleStepConfiguration(org.springframework.batch.core.tasklet.Tasklet)}. */ public void testSimpleStepConfigurationTasklet() { Tasklet tasklet = new Tasklet() { @@ -53,7 +52,7 @@ public class SimpleStepConfigurationTests extends TestCase { } /** - * Test method for {@link org.springframework.batch.execution.step.SimpleStep#getCommitInterval()}. + * Test method for {@link org.springframework.batch.execution.step.simple.SimpleStep#getCommitInterval()}. */ public void testGetCommitInterval() { assertEquals(1, configuration.getCommitInterval()); @@ -62,7 +61,7 @@ public class SimpleStepConfigurationTests extends TestCase { } /** - * Test method for {@link org.springframework.batch.execution.step.AbstractStep#getExceptionHandler()}. + * Test method for {@link org.springframework.batch.execution.step.simple.AbstractStep#getExceptionHandler()}. */ public void testGetExceptionHandler() { assertNull(configuration.getExceptionHandler()); @@ -71,7 +70,7 @@ public class SimpleStepConfigurationTests extends TestCase { } /** - * Test method for {@link org.springframework.batch.execution.step.AbstractStep#getExceptionHandler()}. + * Test method for {@link org.springframework.batch.execution.step.simple.AbstractStep#getExceptionHandler()}. */ public void testSkipLimit() { assertEquals(0, configuration.getSkipLimit()); @@ -80,7 +79,7 @@ public class SimpleStepConfigurationTests extends TestCase { } /** - * Test method for {@link org.springframework.batch.execution.step.AbstractStep#getSkipLimit()}. + * Test method for {@link org.springframework.batch.execution.step.simple.AbstractStep#getSkipLimit()}. */ public void testGetSkipLimit() { assertEquals(0, configuration.getSkipLimit()); @@ -89,7 +88,7 @@ public class SimpleStepConfigurationTests extends TestCase { } /** - * Test method for {@link org.springframework.batch.execution.step.AbstractStep#isSaveRestartData()}. + * Test method for {@link org.springframework.batch.execution.step.simple.AbstractStep#isSaveRestartData()}. */ public void testIsSaveRestartData() { assertEquals(false, configuration.isSaveRestartData()); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorFactoryTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorFactoryTests.java index 930a770e7..3127f6579 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorFactoryTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorFactoryTests.java @@ -27,8 +27,6 @@ import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; import org.springframework.batch.core.domain.StepSupport; import org.springframework.batch.core.tasklet.Tasklet; -import org.springframework.batch.execution.step.RepeatOperationsHolder; -import org.springframework.batch.execution.step.SimpleStep; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatContext; import org.springframework.batch.repeat.RepeatOperations; @@ -36,6 +34,7 @@ import org.springframework.batch.repeat.exception.handler.ExceptionHandler; import org.springframework.batch.repeat.interceptor.RepeatInterceptorAdapter; import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; import org.springframework.batch.repeat.support.RepeatTemplate; +import org.springframework.batch.support.transaction.ResourcelessTransactionManager; /** * @author Dave Syer @@ -43,18 +42,17 @@ import org.springframework.batch.repeat.support.RepeatTemplate; */ public class SimpleStepExecutorFactoryTests extends TestCase { - private SimpleStepExecutorFactory factory = new SimpleStepExecutorFactory(); - - protected void setUp() throws Exception { - factory.setJobRepository(new JobRepositorySupport()); - } - public void testSuccessfulStepExecutor() throws Exception { - assertNotNull(factory.getExecutor(new SimpleStep())); + AbstractStep step = new SimpleStep(); + step.setJobRepository(new JobRepositorySupport()); + step.setTransactionManager(new ResourcelessTransactionManager()); + assertNotNull(step.createStepExecutor()); } public void testSuccessfulExceptionHandler() throws Exception { - SimpleStep configuration = new SimpleStep(); + AbstractStep configuration = new SimpleStep("foo"); + configuration.setJobRepository(new JobRepositorySupport()); + configuration.setTransactionManager(new ResourcelessTransactionManager()); final List list = new ArrayList(); configuration.setExceptionHandler(new ExceptionHandler() { public void handleException(RepeatContext context, @@ -63,8 +61,8 @@ public class SimpleStepExecutorFactoryTests extends TestCase { throw new RuntimeException("Oops"); } }); - SimpleStepExecutor executor = (SimpleStepExecutor) factory - .getExecutor(configuration); + SimpleStepExecutor executor = (SimpleStepExecutor) configuration + .createStepExecutor(); StepExecution stepExecution = new StepExecution(new StepInstance( new Long(11)), new JobExecution(new JobInstance(new Long(0L), new JobParameters()), new Long(12))); @@ -90,8 +88,10 @@ public class SimpleStepExecutorFactoryTests extends TestCase { repeatTemplate.setCompletionPolicy(new SimpleCompletionPolicy(2)); SimpleHolderStepConfiguration configuration = new SimpleHolderStepConfiguration( repeatTemplate); - SimpleStepExecutor executor = (SimpleStepExecutor) factory - .getExecutor(configuration); + configuration.setJobRepository(new JobRepositorySupport()); + configuration.setTransactionManager(new ResourcelessTransactionManager()); + SimpleStepExecutor executor = (SimpleStepExecutor) configuration + .createStepExecutor(); StepExecution stepExecution = new StepExecution(new StepInstance( new Long(11)), new JobExecution(new JobInstance(new Long(0L), new JobParameters()), new Long(12))); @@ -123,13 +123,15 @@ public class SimpleStepExecutorFactoryTests extends TestCase { stepTemplate.setCompletionPolicy(new SimpleCompletionPolicy(1)); SimpleHolderStepConfiguration configuration = new SimpleHolderStepConfiguration( chunkTemplate, stepTemplate); + configuration.setJobRepository(new JobRepositorySupport()); + configuration.setTransactionManager(new ResourcelessTransactionManager()); configuration.setTasklet(new Tasklet() { public ExitStatus execute() throws Exception { return ExitStatus.CONTINUABLE; } }); - SimpleStepExecutor executor = (SimpleStepExecutor) factory - .getExecutor(configuration); + SimpleStepExecutor executor = (SimpleStepExecutor) configuration + .createStepExecutor(); StepExecution stepExecution = new StepExecution(new StepInstance( new Long(11)), new JobExecution(new JobInstance(new Long(0L), new JobParameters()), new Long(12))); @@ -140,9 +142,9 @@ public class SimpleStepExecutorFactoryTests extends TestCase { public void testUnsuccessfulWrongConfiguration() throws Exception { try { - factory.getExecutor(new StepSupport()); - fail("Expected IllegalStateException"); - } catch (IllegalStateException e) { + new StepSupport().createStepExecutor(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException e) { // expected assertTrue( "Error message does not contain SimpleStep: " @@ -153,8 +155,7 @@ public class SimpleStepExecutorFactoryTests extends TestCase { public void testUnsuccessfulNoJobRepository() throws Exception { try { - factory = new SimpleStepExecutorFactory(); - factory.getExecutor(new SimpleStep()); + new SimpleStep().createStepExecutor(); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected @@ -165,9 +166,8 @@ public class SimpleStepExecutorFactoryTests extends TestCase { } public void testMandatoryProperties() throws Exception { - factory = new SimpleStepExecutorFactory(); try { - factory.afterPropertiesSet(); + new SimpleStep().afterPropertiesSet(); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException e) { // expected diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java index 161c8d63e..8185ce562 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java @@ -32,14 +32,12 @@ import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.core.domain.StepContribution; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.core.domain.StepSupport; import org.springframework.batch.core.tasklet.Tasklet; import org.springframework.batch.execution.repository.SimpleJobRepository; import org.springframework.batch.execution.repository.dao.MapJobDao; import org.springframework.batch.execution.repository.dao.MapStepDao; import org.springframework.batch.execution.scope.StepScope; import org.springframework.batch.execution.scope.StepSynchronizationManager; -import org.springframework.batch.execution.step.SimpleStep; import org.springframework.batch.execution.tasklet.ItemOrientedTasklet; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; @@ -56,6 +54,7 @@ import org.springframework.batch.restart.Restartable; import org.springframework.batch.statistics.StatisticsProvider; import org.springframework.batch.statistics.StatisticsService; import org.springframework.batch.support.PropertiesConverter; +import org.springframework.batch.support.transaction.ResourcelessTransactionManager; public class SimpleStepExecutorTests extends TestCase { @@ -69,7 +68,7 @@ public class SimpleStepExecutorTests extends TestCase { private SimpleStepExecutor stepExecutor; - private StepSupport stepConfiguration; + private AbstractStep stepConfiguration; private RepeatTemplate template; @@ -99,10 +98,11 @@ public class SimpleStepExecutorTests extends TestCase { */ protected void setUp() throws Exception { super.setUp(); - stepExecutor = new SimpleStepExecutor(); - stepExecutor.setRepository(new JobRepositorySupport()); stepConfiguration = new SimpleStep(); stepConfiguration.setTasklet(getTasklet(new String[] { "foo", "bar", "spam" })); + stepConfiguration.setJobRepository(new JobRepositorySupport()); + stepConfiguration.setTransactionManager(new ResourcelessTransactionManager()); + stepExecutor = (SimpleStepExecutor) stepConfiguration.createStepExecutor(); template = new RepeatTemplate(); template.setCompletionPolicy(new SimpleCompletionPolicy(1)); stepExecutor.setStepOperations(template); @@ -287,7 +287,7 @@ public class SimpleStepExecutorTests extends TestCase { public void testNonRestartedJob() { StepInstance step = new StepInstance(new Long(1)); MockRestartableTasklet tasklet = new MockRestartableTasklet(); - stepConfiguration.setTasklet(tasklet); + stepExecutor.setTasklet(tasklet); stepConfiguration.setSaveRestartData(true); JobExecution jobExecutionContext = new JobExecution(jobInstance); StepExecution stepExecution = new StepExecution(step, @@ -312,7 +312,7 @@ public class SimpleStepExecutorTests extends TestCase { StepInstance step = new StepInstance(new Long(1)); step.setStepExecutionCount(1); MockRestartableTasklet tasklet = new MockRestartableTasklet(); - stepConfiguration.setTasklet(tasklet); + stepExecutor.setTasklet(tasklet); stepConfiguration.setSaveRestartData(true); JobExecution jobExecutionContext = new JobExecution(jobInstance); StepExecution stepExecution = new StepExecution(step, @@ -379,7 +379,7 @@ public class SimpleStepExecutorTests extends TestCase { } public void testApplyConfigurationWithExceptionHandler() throws Exception { - SimpleStep stepConfiguration = new SimpleStep("foo"); + AbstractStep stepConfiguration = new SimpleStep("foo"); final List list = new ArrayList(); stepExecutor.setStepOperations(new RepeatTemplate() { public void setExceptionHandler(ExceptionHandler exceptionHandler) { @@ -392,7 +392,7 @@ public class SimpleStepExecutorTests extends TestCase { } public void testApplyConfigurationWithZeroSkipLimit() throws Exception { - SimpleStep stepConfiguration = new SimpleStep("foo"); + AbstractStep stepConfiguration = new SimpleStep("foo"); stepConfiguration.setSkipLimit(0); final List list = new ArrayList(); stepExecutor.setStepOperations(new RepeatTemplate() { @@ -405,7 +405,7 @@ public class SimpleStepExecutorTests extends TestCase { } public void testApplyConfigurationWithNonZeroSkipLimit() throws Exception { - SimpleStep stepConfiguration = new SimpleStep("foo"); + AbstractStep stepConfiguration = new SimpleStep("foo"); stepConfiguration.setSkipLimit(1); final List list = new ArrayList(); stepExecutor.setStepOperations(new RepeatTemplate() { diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java index 3cfd810ad..010ade0e2 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java @@ -27,7 +27,7 @@ import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.core.domain.StepSupport; +import org.springframework.batch.core.executor.StepExecutor; import org.springframework.batch.core.executor.StepInterruptedException; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.tasklet.Tasklet; @@ -36,10 +36,10 @@ import org.springframework.batch.execution.repository.dao.JobDao; import org.springframework.batch.execution.repository.dao.MapJobDao; import org.springframework.batch.execution.repository.dao.MapStepDao; import org.springframework.batch.execution.repository.dao.StepDao; -import org.springframework.batch.execution.step.SimpleStep; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; import org.springframework.batch.repeat.support.RepeatTemplate; +import org.springframework.batch.support.transaction.ResourcelessTransactionManager; public class StepExecutorInterruptionTests extends TestCase { @@ -51,26 +51,25 @@ public class StepExecutorInterruptionTests extends TestCase { private JobInstance job; - private StepSupport stepConfiguration; + private RepeatOperationsStep stepConfiguration; - private SimpleStepExecutor executor; + private StepExecutor executor; public void setUp() throws Exception { jobRepository = new SimpleJobRepository(jobDao, stepDao); Job jobConfiguration = new Job(); - stepConfiguration = new SimpleStep(); + stepConfiguration = new RepeatOperationsStep(); jobConfiguration.addStep(stepConfiguration); jobConfiguration.setBeanName("testJob"); job = jobRepository.createJobExecution(jobConfiguration, new JobParameters()).getJobInstance(); - executor = new SimpleStepExecutor(); + stepConfiguration.setJobRepository(jobRepository); + stepConfiguration.setTransactionManager(new ResourcelessTransactionManager()); } public void testInterruptChunk() throws Exception { - executor.setRepository(jobRepository); - List steps = job.getStepInstances(); final StepInstance step = (StepInstance) steps.get(0); JobExecution jobExecutionContext = new JobExecution(new JobInstance(new Long(0L), new JobParameters())); @@ -86,6 +85,7 @@ public class StepExecutorInterruptionTests extends TestCase { return new ExitStatus(foo != 1); } }); + executor = stepConfiguration.createStepExecutor(); Thread processingThread = new Thread() { public void run() { @@ -118,7 +118,7 @@ public class StepExecutorInterruptionTests extends TestCase { RepeatTemplate template = new RepeatTemplate(); // N.B, If we don't set the completion policy it might run forever template.setCompletionPolicy(new SimpleCompletionPolicy(2)); - executor.setChunkOperations(template); + stepConfiguration.setChunkOperations(template); testInterruptChunk(); } diff --git a/spring-batch-execution/src/test/resources/job-configuration.xml b/spring-batch-execution/src/test/resources/job-configuration.xml index d2f66f868..b17d35400 100644 --- a/spring-batch-execution/src/test/resources/job-configuration.xml +++ b/spring-batch-execution/src/test/resources/job-configuration.xml @@ -13,7 +13,7 @@ - + diff --git a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/job.xml b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/job.xml index d4c47c234..01dcf627d 100644 --- a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/job.xml +++ b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/job.xml @@ -9,7 +9,7 @@ - + diff --git a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/configuration/test-context.xml b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/configuration/test-context.xml index b9f4751e2..8327fc6ec 100644 --- a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/configuration/test-context.xml +++ b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/configuration/test-context.xml @@ -15,7 +15,7 @@ - + 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 6969e9e62..d8b07d59e 100644 --- a/spring-batch-execution/src/test/resources/simple-container-definition.xml +++ b/spring-batch-execution/src/test/resources/simple-container-definition.xml @@ -21,12 +21,6 @@ - - - - - diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/tasklet/ExceptionRestartableTasklet.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/tasklet/ExceptionRestartableTasklet.java index bb5cf3dc7..af50d1e05 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/tasklet/ExceptionRestartableTasklet.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/tasklet/ExceptionRestartableTasklet.java @@ -41,7 +41,7 @@ public class ExceptionRestartableTasklet extends RestartableItemOrientedTasklet counter++; if (counter == throwExceptionOnRecordNumber) { - throw new BatchCriticalException(); + throw new BatchCriticalException("Planned failure on count="+counter); } return super.execute(); diff --git a/spring-batch-samples/src/main/resources/jobs/adhocLoopJob.xml b/spring-batch-samples/src/main/resources/jobs/adhocLoopJob.xml index 708e8423c..ea82fae57 100644 --- a/spring-batch-samples/src/main/resources/jobs/adhocLoopJob.xml +++ b/spring-batch-samples/src/main/resources/jobs/adhocLoopJob.xml @@ -107,18 +107,8 @@ - - - - - - - - - - + + diff --git a/spring-batch-samples/src/main/resources/jobs/footballJob.xml b/spring-batch-samples/src/main/resources/jobs/footballJob.xml index ec745f784..0645049f5 100644 --- a/spring-batch-samples/src/main/resources/jobs/footballJob.xml +++ b/spring-batch-samples/src/main/resources/jobs/footballJob.xml @@ -18,8 +18,7 @@ - + @@ -44,8 +43,7 @@ - + @@ -64,8 +62,7 @@ - + diff --git a/spring-batch-samples/src/main/resources/jobs/hibernateJob.xml b/spring-batch-samples/src/main/resources/jobs/hibernateJob.xml index c6c08de7a..ed4eea8c7 100644 --- a/spring-batch-samples/src/main/resources/jobs/hibernateJob.xml +++ b/spring-batch-samples/src/main/resources/jobs/hibernateJob.xml @@ -18,8 +18,7 @@ - + diff --git a/spring-batch-samples/src/main/resources/jobs/infiniteLoopJob.xml b/spring-batch-samples/src/main/resources/jobs/infiniteLoopJob.xml index 9dd66c2e0..bd28eeb6f 100644 --- a/spring-batch-samples/src/main/resources/jobs/infiniteLoopJob.xml +++ b/spring-batch-samples/src/main/resources/jobs/infiniteLoopJob.xml @@ -14,7 +14,7 @@ - + diff --git a/spring-batch-samples/src/main/resources/jobs/parallelJob.xml b/spring-batch-samples/src/main/resources/jobs/parallelJob.xml index a5dfc606c..551cb823b 100644 --- a/spring-batch-samples/src/main/resources/jobs/parallelJob.xml +++ b/spring-batch-samples/src/main/resources/jobs/parallelJob.xml @@ -46,13 +46,12 @@ - + - + @@ -68,8 +67,7 @@ - + diff --git a/spring-batch-samples/src/main/resources/jobs/rollbackJob.xml b/spring-batch-samples/src/main/resources/jobs/rollbackJob.xml index c3d4e255c..d366d6bf0 100644 --- a/spring-batch-samples/src/main/resources/jobs/rollbackJob.xml +++ b/spring-batch-samples/src/main/resources/jobs/rollbackJob.xml @@ -17,9 +17,8 @@ - - + + @@ -37,7 +36,7 @@ + p:limit="5" p:type="java.lang.Exception" /> @@ -56,18 +55,21 @@ + p:dao-ref="tradeDao" p:failure="3" /> + - + - + diff --git a/spring-batch-samples/src/main/resources/simple-container-definition.xml b/spring-batch-samples/src/main/resources/simple-container-definition.xml index 71463babf..47393bc57 100644 --- a/spring-batch-samples/src/main/resources/simple-container-definition.xml +++ b/spring-batch-samples/src/main/resources/simple-container-definition.xml @@ -23,7 +23,7 @@ - + @@ -45,23 +45,17 @@ - - - - - - + - + - @@ -102,10 +96,12 @@ - + + + @@ -116,6 +112,15 @@ + + + + + + + diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/RestartFunctionalTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/RestartFunctionalTests.java index ac258adca..af10952ee 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/RestartFunctionalTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/RestartFunctionalTests.java @@ -17,6 +17,7 @@ package org.springframework.batch.sample; import org.springframework.batch.core.domain.JobParameters; +import org.springframework.batch.io.exception.BatchCriticalException; import org.springframework.jdbc.core.JdbcOperations; /** @@ -68,10 +69,14 @@ public class RestartFunctionalTests extends AbstractBatchLauncherTests { runJob(); fail("First run of the job is expected to fail."); } - catch (Exception expected) { + catch (BatchCriticalException expected) { //expected + assertTrue("Not planned exception: "+expected.getMessage(), expected.getMessage().toLowerCase().indexOf("planned")>=0); } + int medium = jdbcTemplate.queryForInt("SELECT COUNT(*) FROM TRADE"); +System.err.println(medium); + runJob(); int after = jdbcTemplate.queryForInt("SELECT COUNT(*) FROM TRADE");