RESOLVED - BATCH-1026: Rename ExitStatus.FINISHED to ExitStatus.COMPLETED

This commit is contained in:
robokaso
2009-01-27 11:38:26 +00:00
parent 8e1e352be4
commit f4fa341233
31 changed files with 1240 additions and 1240 deletions

View File

@@ -49,7 +49,7 @@ public class ExitStatus implements Serializable, Comparable<ExitStatus> {
/** /**
* Convenient constant value representing finished processing. * Convenient constant value representing finished processing.
*/ */
public static final ExitStatus FINISHED = new ExitStatus("COMPLETED"); public static final ExitStatus COMPLETED = new ExitStatus("COMPLETED");
/** /**
* Convenient constant value representing job that did no processing (e.g. * Convenient constant value representing job that did no processing (e.g.
@@ -153,7 +153,7 @@ public class ExitStatus implements Serializable, Comparable<ExitStatus> {
* @return * @return
*/ */
private int severity(ExitStatus status) { private int severity(ExitStatus status) {
if (status.exitCode.startsWith(FINISHED.exitCode)) { if (status.exitCode.startsWith(COMPLETED.exitCode)) {
return 2; return 2;
} }
if (status.exitCode.startsWith(NOOP.exitCode)) { if (status.exitCode.startsWith(NOOP.exitCode)) {

View File

@@ -233,7 +233,7 @@ public abstract class AbstractJob implements Job, BeanNameAware, InitializingBea
// The job was already stopped before we even got this far. Deal // The job was already stopped before we even got this far. Deal
// with it in the same way as any other interruption. // with it in the same way as any other interruption.
execution.setStatus(BatchStatus.STOPPED); execution.setStatus(BatchStatus.STOPPED);
execution.setExitStatus(ExitStatus.FINISHED); execution.setExitStatus(ExitStatus.COMPLETED);
} }

View File

@@ -41,7 +41,7 @@ public class SimpleJvmExitCodeMapper implements ExitCodeMapper {
public SimpleJvmExitCodeMapper() { public SimpleJvmExitCodeMapper() {
mapping = new HashMap<String, Integer>(); mapping = new HashMap<String, Integer>();
mapping.put(ExitStatus.FINISHED.getExitCode(), JVM_EXITCODE_COMPLETED); mapping.put(ExitStatus.COMPLETED.getExitCode(), JVM_EXITCODE_COMPLETED);
mapping.put(ExitStatus.FAILED.getExitCode(), JVM_EXITCODE_GENERIC_ERROR); mapping.put(ExitStatus.FAILED.getExitCode(), JVM_EXITCODE_GENERIC_ERROR);
mapping.put(ExitCodeMapper.JOB_NOT_PROVIDED, JVM_EXITCODE_JOB_ERROR); mapping.put(ExitCodeMapper.JOB_NOT_PROVIDED, JVM_EXITCODE_JOB_ERROR);
mapping.put(ExitCodeMapper.NO_SUCH_JOB, JVM_EXITCODE_JOB_ERROR); mapping.put(ExitCodeMapper.NO_SUCH_JOB, JVM_EXITCODE_JOB_ERROR);

View File

@@ -1,104 +1,104 @@
/* /*
* Copyright 2006-2007 the original author or authors. * Copyright 2006-2007 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.batch.core.listener; package org.springframework.batch.core.listener;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job; import org.springframework.batch.core.Job;
import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.job.flow.support.util.PatternMatcher; import org.springframework.batch.core.job.flow.support.util.PatternMatcher;
import org.springframework.batch.item.ExecutionContext; import org.springframework.batch.item.ExecutionContext;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import com.sun.org.apache.xerces.internal.impl.xpath.XPath.Step; import com.sun.org.apache.xerces.internal.impl.xpath.XPath.Step;
/** /**
* This class can be used to automatically promote items from the {@link Step} * This class can be used to automatically promote items from the {@link Step}
* {@link ExecutionContext} to the {@link Job} {@link ExecutionContext} at the * {@link ExecutionContext} to the {@link Job} {@link ExecutionContext} at the
* end of a step. A list of keys should be provided that correspond to the items * end of a step. A list of keys should be provided that correspond to the items
* in the {@link Step} {@link ExecutionContext} that should be promoted. * in the {@link Step} {@link ExecutionContext} that should be promoted.
* *
* Additionally, an optional list of statuses can be set to indicate for which * Additionally, an optional list of statuses can be set to indicate for which
* exit status codes the promotion should occur. These statuses will be checked * exit status codes the promotion should occur. These statuses will be checked
* using the {@link PatternMatcher}, so wildcards are allowed. * using the {@link PatternMatcher}, so wildcards are allowed.
* *
* @author Dan Garrette * @author Dan Garrette
* @since 2.0 * @since 2.0
*/ */
public class ExecutionContextPromotionListener extends StepExecutionListenerSupport implements InitializingBean { public class ExecutionContextPromotionListener extends StepExecutionListenerSupport implements InitializingBean {
private List<String> keys = null; private List<String> keys = null;
private List<String> statuses = Collections.singletonList(ExitStatus.FINISHED.getExitCode()); private List<String> statuses = Collections.singletonList(ExitStatus.COMPLETED.getExitCode());
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.springframework.batch.core.domain.StepListener#afterStep(StepExecution * @see org.springframework.batch.core.domain.StepListener#afterStep(StepExecution
* stepExecution) * stepExecution)
*/ */
public ExitStatus afterStep(StepExecution stepExecution) { public ExitStatus afterStep(StepExecution stepExecution) {
if (statuses == null) { if (statuses == null) {
this.performPromotion(stepExecution); this.performPromotion(stepExecution);
} }
else { else {
String exitCode = stepExecution.getExitStatus().getExitCode(); String exitCode = stepExecution.getExitStatus().getExitCode();
for (String statusPattern : statuses) { for (String statusPattern : statuses) {
if (PatternMatcher.match(statusPattern, exitCode)) { if (PatternMatcher.match(statusPattern, exitCode)) {
this.performPromotion(stepExecution); this.performPromotion(stepExecution);
} }
} }
} }
return null; return null;
} }
private void performPromotion(StepExecution stepExecution) { private void performPromotion(StepExecution stepExecution) {
ExecutionContext stepContext = stepExecution.getExecutionContext(); ExecutionContext stepContext = stepExecution.getExecutionContext();
ExecutionContext jobContext = stepExecution.getJobExecution().getExecutionContext(); ExecutionContext jobContext = stepExecution.getJobExecution().getExecutionContext();
for (String key : keys) { for (String key : keys) {
jobContext.put(key, stepContext.get(key)); jobContext.put(key, stepContext.get(key));
} }
} }
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.notNull(this.keys, "The 'keys' property must be provided"); Assert.notNull(this.keys, "The 'keys' property must be provided");
Assert.notEmpty(this.statuses, "The 'keys' property must not be empty"); Assert.notEmpty(this.statuses, "The 'keys' property must not be empty");
Assert.notNull(this.statuses, "The 'statuses' property must be provided"); Assert.notNull(this.statuses, "The 'statuses' property must be provided");
Assert.notEmpty(this.statuses, "The 'statuses' property must not be empty"); Assert.notEmpty(this.statuses, "The 'statuses' property must not be empty");
} }
/** /**
* @param keys * @param keys
* A list of keys corresponding to items in the {@link Step} * A list of keys corresponding to items in the {@link Step}
* {@link ExecutionContext} that must be promoted. * {@link ExecutionContext} that must be promoted.
*/ */
public void setKeys(List<String> keys) { public void setKeys(List<String> keys) {
this.keys = keys; this.keys = keys;
} }
/** /**
* @param statuses * @param statuses
* A list of statuses for which the promotion should occur. * A list of statuses for which the promotion should occur.
* Statuses can may contain wildcards recognizable by the * Statuses can may contain wildcards recognizable by the
* {@link PatternMatcher} class. * {@link PatternMatcher} class.
*/ */
public void setStatuses(List<String> statuses) { public void setStatuses(List<String> statuses) {
this.statuses = statuses; this.statuses = statuses;
} }
} }

View File

@@ -1,84 +1,84 @@
/* /*
* Copyright 2006-2009 the original author or authors. * Copyright 2006-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.batch.core.step.item; package org.springframework.batch.core.step.item;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus; import org.springframework.batch.repeat.RepeatStatus;
/** /**
* A {@link Tasklet} implementing variations on read-process-write item * A {@link Tasklet} implementing variations on read-process-write item
* handling. * handling.
* *
* @author Dave Syer * @author Dave Syer
* *
* @param <I> input item type * @param <I> input item type
*/ */
public class ChunkOrientedTasklet<I> implements Tasklet { public class ChunkOrientedTasklet<I> implements Tasklet {
private static final String INPUTS_KEY = "INPUTS"; private static final String INPUTS_KEY = "INPUTS";
private final ChunkProcessor<I> chunkProcessor; private final ChunkProcessor<I> chunkProcessor;
private final ChunkProvider<I> chunkProvider; private final ChunkProvider<I> chunkProvider;
private boolean buffering = true; private boolean buffering = true;
public ChunkOrientedTasklet(ChunkProvider<I> chunkProvider, ChunkProcessor<I> chunkProcessor) { public ChunkOrientedTasklet(ChunkProvider<I> chunkProvider, ChunkProcessor<I> chunkProcessor) {
this.chunkProvider = chunkProvider; this.chunkProvider = chunkProvider;
this.chunkProcessor = chunkProcessor; this.chunkProcessor = chunkProcessor;
} }
/** /**
* Flag to indicate that items should be buffered once read. Defaults to * Flag to indicate that items should be buffered once read. Defaults to
* true, which is appropriate for forward-only, non-transactional item * true, which is appropriate for forward-only, non-transactional item
* readers. Main (or only) use case for setting this flag to true is a * readers. Main (or only) use case for setting this flag to true is a
* transactional JMS item reader. * transactional JMS item reader.
* *
* @param buffering * @param buffering
*/ */
public void setBuffering(boolean buffering) { public void setBuffering(boolean buffering) {
this.buffering = buffering; this.buffering = buffering;
} }
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Chunk<I> inputs = (Chunk<I>) chunkContext.getAttribute(INPUTS_KEY); Chunk<I> inputs = (Chunk<I>) chunkContext.getAttribute(INPUTS_KEY);
if (inputs == null) { if (inputs == null) {
inputs = chunkProvider.provide(contribution); inputs = chunkProvider.provide(contribution);
if (buffering) { if (buffering) {
chunkContext.setAttribute(INPUTS_KEY, inputs); chunkContext.setAttribute(INPUTS_KEY, inputs);
} }
} }
chunkProcessor.process(contribution, inputs); chunkProcessor.process(contribution, inputs);
chunkContext.removeAttribute(INPUTS_KEY); chunkContext.removeAttribute(INPUTS_KEY);
chunkContext.setComplete(); chunkContext.setComplete();
chunkProvider.postProcess(contribution, inputs); chunkProvider.postProcess(contribution, inputs);
if (inputs.isEnd()) { if (inputs.isEnd()) {
contribution.setExitStatus(ExitStatus.FINISHED); contribution.setExitStatus(ExitStatus.COMPLETED);
} }
return RepeatStatus.continueIf(!inputs.isEnd()); return RepeatStatus.continueIf(!inputs.isEnd());
} }
} }

View File

@@ -23,7 +23,7 @@ import org.springframework.batch.repeat.RepeatStatus;
/** /**
* A {@link Tasklet} that wraps a method in a POJO. By default the return * A {@link Tasklet} that wraps a method in a POJO. By default the return
* value is {@link ExitStatus#FINISHED} unless the delegate POJO itself returns * value is {@link ExitStatus#COMPLETED} unless the delegate POJO itself returns
* an {@link ExitStatus}. The POJO method is usually going to have no arguments, * an {@link ExitStatus}. The POJO method is usually going to have no arguments,
* but a static argument or array of arguments can be used by setting the * but a static argument or array of arguments can be used by setting the
* arguments property. * arguments property.
@@ -49,7 +49,7 @@ public class MethodInvokingTaskletAdapter extends AbstractMethodInvokingDelegato
/** /**
* If the result is an {@link ExitStatus} already just return that, * If the result is an {@link ExitStatus} already just return that,
* otherwise return {@link ExitStatus#FINISHED}. * otherwise return {@link ExitStatus#COMPLETED}.
* *
* @param result the value returned by the delegate method * @param result the value returned by the delegate method
* @return an {@link ExitStatus} consistent with the result * @return an {@link ExitStatus} consistent with the result
@@ -58,7 +58,7 @@ public class MethodInvokingTaskletAdapter extends AbstractMethodInvokingDelegato
if (result instanceof ExitStatus) { if (result instanceof ExitStatus) {
return (ExitStatus) result; return (ExitStatus) result;
} }
return ExitStatus.FINISHED; return ExitStatus.COMPLETED;
} }
} }

View File

@@ -1,38 +1,38 @@
/* /*
* Copyright 2006-2007 the original author or authors. * Copyright 2006-2007 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.batch.core.step.tasklet; package org.springframework.batch.core.step.tasklet;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
/** /**
* Simple {@link SystemProcessExitCodeMapper} implementation that performs following mapping: * Simple {@link SystemProcessExitCodeMapper} implementation that performs following mapping:
* *
* 0 -> ExitStatus.FINISHED * 0 -> ExitStatus.FINISHED
* else -> ExitStatus.FAILED * else -> ExitStatus.FAILED
* *
* @author Robert Kasanicky * @author Robert Kasanicky
*/ */
public class SimpleSystemProcessExitCodeMapper implements SystemProcessExitCodeMapper { public class SimpleSystemProcessExitCodeMapper implements SystemProcessExitCodeMapper {
public ExitStatus getExitStatus(int exitCode) { public ExitStatus getExitStatus(int exitCode) {
if (exitCode == 0) { if (exitCode == 0) {
return ExitStatus.FINISHED; return ExitStatus.COMPLETED;
} else { } else {
return ExitStatus.FAILED; return ExitStatus.FAILED;
} }
} }
} }

View File

@@ -42,7 +42,7 @@ public class ExitStatusTests {
@Test @Test
public void testExitStatusConstantsFinished() { public void testExitStatusConstantsFinished() {
ExitStatus status = ExitStatus.FINISHED; ExitStatus status = ExitStatus.COMPLETED;
assertEquals("COMPLETED", status.getExitCode()); assertEquals("COMPLETED", status.getExitCode());
} }
@@ -104,7 +104,7 @@ public class ExitStatusTests {
*/ */
@Test @Test
public void testAndExitStatusWhenFinishedAddedToContinuable() { public void testAndExitStatusWhenFinishedAddedToContinuable() {
assertEquals(ExitStatus.FINISHED.getExitCode(), ExitStatus.EXECUTING.and(ExitStatus.FINISHED).getExitCode()); assertEquals(ExitStatus.COMPLETED.getExitCode(), ExitStatus.EXECUTING.and(ExitStatus.COMPLETED).getExitCode());
} }
/** /**
@@ -114,7 +114,7 @@ public class ExitStatusTests {
*/ */
@Test @Test
public void testAndExitStatusWhenContinuableAddedToFinished() { public void testAndExitStatusWhenContinuableAddedToFinished() {
assertEquals(ExitStatus.FINISHED.getExitCode(), ExitStatus.FINISHED.and(ExitStatus.EXECUTING).getExitCode()); assertEquals(ExitStatus.COMPLETED.getExitCode(), ExitStatus.COMPLETED.and(ExitStatus.EXECUTING).getExitCode());
} }
/** /**
@@ -134,7 +134,7 @@ public class ExitStatusTests {
*/ */
@Test @Test
public void testAndExitStatusWhenCustomCompletedAddedToCompleted() { public void testAndExitStatusWhenCustomCompletedAddedToCompleted() {
assertEquals("COMPLETED_CUSTOM", ExitStatus.FINISHED.and(ExitStatus.EXECUTING.replaceExitCode("COMPLETED_CUSTOM")).getExitCode()); assertEquals("COMPLETED_CUSTOM", ExitStatus.COMPLETED.and(ExitStatus.EXECUTING.replaceExitCode("COMPLETED_CUSTOM")).getExitCode());
} }
/** /**
@@ -144,8 +144,8 @@ public class ExitStatusTests {
*/ */
@Test @Test
public void testAndExitStatusFailedPlusFinished() { public void testAndExitStatusFailedPlusFinished() {
assertEquals("FAILED", ExitStatus.FINISHED.and(ExitStatus.FAILED).getExitCode()); assertEquals("FAILED", ExitStatus.COMPLETED.and(ExitStatus.FAILED).getExitCode());
assertEquals("FAILED", ExitStatus.FAILED.and(ExitStatus.FINISHED).getExitCode()); assertEquals("FAILED", ExitStatus.FAILED.and(ExitStatus.COMPLETED).getExitCode());
} }
/** /**
@@ -155,7 +155,7 @@ public class ExitStatusTests {
*/ */
@Test @Test
public void testAndExitStatusWhenCustomContinuableAddedToFinished() { public void testAndExitStatusWhenCustomContinuableAddedToFinished() {
assertEquals(ExitStatus.FINISHED.getExitCode(), ExitStatus.FINISHED.and( assertEquals(ExitStatus.COMPLETED.getExitCode(), ExitStatus.COMPLETED.and(
ExitStatus.EXECUTING.replaceExitCode("CUSTOM")).getExitCode()); ExitStatus.EXECUTING.replaceExitCode("CUSTOM")).getExitCode());
} }

View File

@@ -110,8 +110,8 @@ public class StepExecutionTests {
@Test @Test
public void testGetExitCode() { public void testGetExitCode() {
assertEquals(ExitStatus.EXECUTING, execution.getExitStatus()); assertEquals(ExitStatus.EXECUTING, execution.getExitStatus());
execution.setExitStatus(ExitStatus.FINISHED); execution.setExitStatus(ExitStatus.COMPLETED);
assertEquals(ExitStatus.FINISHED, execution.getExitStatus()); assertEquals(ExitStatus.COMPLETED, execution.getExitStatus());
} }
/** /**

View File

@@ -11,7 +11,7 @@ public class TestTasklet extends AbstractTestComponent implements Tasklet {
public RepeatStatus execute(StepContribution contribution, public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext) throws Exception { ChunkContext chunkContext) throws Exception {
executed = true; executed = true;
contribution.setExitStatus(ExitStatus.FINISHED); contribution.setExitStatus(ExitStatus.COMPLETED);
return RepeatStatus.FINISHED; return RepeatStatus.FINISHED;
} }

View File

@@ -228,7 +228,7 @@ public class SimpleJobTests {
step2.setStartLimit(5); step2.setStartLimit(5);
job.execute(jobExecution); job.execute(jobExecution);
assertEquals(2, list.size()); assertEquals(2, list.size());
checkRepository(BatchStatus.COMPLETED, ExitStatus.FINISHED); checkRepository(BatchStatus.COMPLETED, ExitStatus.COMPLETED);
} }
@@ -536,7 +536,7 @@ public class SimpleJobTests {
if (runnable != null) { if (runnable != null) {
runnable.run(); runnable.run();
} }
stepExecution.setExitStatus(ExitStatus.FINISHED); stepExecution.setExitStatus(ExitStatus.COMPLETED);
stepExecution.setStatus(BatchStatus.COMPLETED); stepExecution.setStatus(BatchStatus.COMPLETED);
jobRepository.update(stepExecution); jobRepository.update(stepExecution);
jobRepository.updateExecutionContext(stepExecution); jobRepository.updateExecutionContext(stepExecution);

View File

@@ -1,270 +1,270 @@
/* /*
* Copyright 2006-2007 the original author or authors. * Copyright 2006-2007 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.batch.core.job.flow; package org.springframework.batch.core.job.flow;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobInterruptedException; import org.springframework.batch.core.JobInterruptedException;
import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step; import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.UnexpectedJobExecutionException; import org.springframework.batch.core.UnexpectedJobExecutionException;
import org.springframework.batch.core.job.flow.support.SimpleFlow; import org.springframework.batch.core.job.flow.support.SimpleFlow;
import org.springframework.batch.core.job.flow.support.StateTransition; import org.springframework.batch.core.job.flow.support.StateTransition;
import org.springframework.batch.core.job.flow.support.state.DecisionState; import org.springframework.batch.core.job.flow.support.state.DecisionState;
import org.springframework.batch.core.job.flow.support.state.EndState; import org.springframework.batch.core.job.flow.support.state.EndState;
import org.springframework.batch.core.job.flow.support.state.JobExecutionDecider; import org.springframework.batch.core.job.flow.support.state.JobExecutionDecider;
import org.springframework.batch.core.job.flow.support.state.StepState; import org.springframework.batch.core.job.flow.support.state.StepState;
import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean; import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.step.StepSupport; import org.springframework.batch.core.step.StepSupport;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager; import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
/** /**
* @author Dave Syer * @author Dave Syer
* *
*/ */
public class FlowJobTests { public class FlowJobTests {
private FlowJob job = new FlowJob(); private FlowJob job = new FlowJob();
private JobExecution jobExecution; private JobExecution jobExecution;
private JobRepository jobRepository; private JobRepository jobRepository;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
MapJobRepositoryFactoryBean.clear(); MapJobRepositoryFactoryBean.clear();
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(); MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
factory.setTransactionManager(new ResourcelessTransactionManager()); factory.setTransactionManager(new ResourcelessTransactionManager());
factory.afterPropertiesSet(); factory.afterPropertiesSet();
jobRepository = (JobRepository) factory.getObject(); jobRepository = (JobRepository) factory.getObject();
job.setJobRepository(jobRepository); job.setJobRepository(jobRepository);
jobExecution = jobRepository.createJobExecution("job", new JobParameters()); jobExecution = jobRepository.createJobExecution("job", new JobParameters());
} }
@Test @Test
public void testTwoSteps() throws Exception { public void testTwoSteps() throws Exception {
SimpleFlow flow = new SimpleFlow("job"); SimpleFlow flow = new SimpleFlow("job");
Collection<StateTransition> transitions = new ArrayList<StateTransition>(); Collection<StateTransition> transitions = new ArrayList<StateTransition>();
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2")); transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2")))); transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2"))));
flow.setStateTransitions(transitions); flow.setStateTransitions(transitions);
job.setFlow(flow); job.setFlow(flow);
job.afterPropertiesSet(); job.afterPropertiesSet();
StepExecution stepExecution = job.doExecute(jobExecution); StepExecution stepExecution = job.doExecute(jobExecution);
assertEquals(ExitStatus.FINISHED, stepExecution.getExitStatus()); assertEquals(ExitStatus.COMPLETED, stepExecution.getExitStatus());
assertEquals(2, jobExecution.getStepExecutions().size()); assertEquals(2, jobExecution.getStepExecutions().size());
} }
@Test @Test
public void testFailedStep() throws Exception { public void testFailedStep() throws Exception {
SimpleFlow flow = new SimpleFlow("job"); SimpleFlow flow = new SimpleFlow("job");
Collection<StateTransition> transitions = new ArrayList<StateTransition>(); Collection<StateTransition> transitions = new ArrayList<StateTransition>();
transitions.add(StateTransition.createStateTransition(new StepState(new StepSupport("step1") { transitions.add(StateTransition.createStateTransition(new StepState(new StepSupport("step1") {
@Override @Override
public void execute(StepExecution stepExecution) throws JobInterruptedException, public void execute(StepExecution stepExecution) throws JobInterruptedException,
UnexpectedJobExecutionException { UnexpectedJobExecutionException {
stepExecution.setStatus(BatchStatus.FAILED); stepExecution.setStatus(BatchStatus.FAILED);
stepExecution.setExitStatus(ExitStatus.FAILED); stepExecution.setExitStatus(ExitStatus.FAILED);
} }
}), "step2")); }), "step2"));
transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2")))); transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2"))));
flow.setStateTransitions(transitions); flow.setStateTransitions(transitions);
job.setFlow(flow); job.setFlow(flow);
job.afterPropertiesSet(); job.afterPropertiesSet();
StepExecution stepExecution = job.doExecute(jobExecution); StepExecution stepExecution = job.doExecute(jobExecution);
assertEquals(ExitStatus.FINISHED, stepExecution.getExitStatus()); assertEquals(ExitStatus.COMPLETED, stepExecution.getExitStatus());
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
assertEquals(2, jobExecution.getStepExecutions().size()); assertEquals(2, jobExecution.getStepExecutions().size());
} }
@Test @Test
public void testStoppingStep() throws Exception { public void testStoppingStep() throws Exception {
SimpleFlow flow = new SimpleFlow("job"); SimpleFlow flow = new SimpleFlow("job");
Collection<StateTransition> transitions = new ArrayList<StateTransition>(); Collection<StateTransition> transitions = new ArrayList<StateTransition>();
transitions.add(StateTransition.createStateTransition(new StepState(new StepSupport("step1") { transitions.add(StateTransition.createStateTransition(new StepState(new StepSupport("step1") {
@Override @Override
public void execute(StepExecution stepExecution) throws JobInterruptedException, public void execute(StepExecution stepExecution) throws JobInterruptedException,
UnexpectedJobExecutionException { UnexpectedJobExecutionException {
stepExecution.setStatus(BatchStatus.STOPPED); stepExecution.setStatus(BatchStatus.STOPPED);
} }
}), "step2")); }), "step2"));
transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2")))); transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2"))));
flow.setStateTransitions(transitions); flow.setStateTransitions(transitions);
job.setFlow(flow); job.setFlow(flow);
job.afterPropertiesSet(); job.afterPropertiesSet();
try { try {
job.doExecute(jobExecution); job.doExecute(jobExecution);
fail("Expected JobInterruptedException"); fail("Expected JobInterruptedException");
} }
catch (JobInterruptedException e) { catch (JobInterruptedException e) {
// expected // expected
} }
assertEquals(1, jobExecution.getStepExecutions().size()); assertEquals(1, jobExecution.getStepExecutions().size());
} }
@Test @Test
public void testEndStateStopped() throws Exception { public void testEndStateStopped() throws Exception {
SimpleFlow flow = new SimpleFlow("job"); SimpleFlow flow = new SimpleFlow("job");
Collection<StateTransition> transitions = new ArrayList<StateTransition>(); Collection<StateTransition> transitions = new ArrayList<StateTransition>();
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end")); transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end"));
transitions.add(StateTransition.createStateTransition(new EndState(BatchStatus.STOPPED, "end"), "step2")); transitions.add(StateTransition.createStateTransition(new EndState(BatchStatus.STOPPED, "end"), "step2"));
transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2")))); transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2"))));
flow.setStateTransitions(transitions); flow.setStateTransitions(transitions);
job.setFlow(flow); job.setFlow(flow);
job.afterPropertiesSet(); job.afterPropertiesSet();
try { try {
job.doExecute(jobExecution); job.doExecute(jobExecution);
fail("Expected JobInterruptedException"); fail("Expected JobInterruptedException");
} }
catch (JobInterruptedException e) { catch (JobInterruptedException e) {
// expected // expected
} }
assertEquals(1, jobExecution.getStepExecutions().size()); assertEquals(1, jobExecution.getStepExecutions().size());
} }
public void testEndStateFailed() throws Exception { public void testEndStateFailed() throws Exception {
SimpleFlow flow = new SimpleFlow("job"); SimpleFlow flow = new SimpleFlow("job");
Collection<StateTransition> transitions = new ArrayList<StateTransition>(); Collection<StateTransition> transitions = new ArrayList<StateTransition>();
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end")); transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end"));
transitions.add(StateTransition.createStateTransition(new EndState(BatchStatus.FAILED, "end"), "step2")); transitions.add(StateTransition.createStateTransition(new EndState(BatchStatus.FAILED, "end"), "step2"));
transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2")))); transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2"))));
flow.setStateTransitions(transitions); flow.setStateTransitions(transitions);
job.setFlow(flow); job.setFlow(flow);
job.afterPropertiesSet(); job.afterPropertiesSet();
job.doExecute(jobExecution); job.doExecute(jobExecution);
assertEquals(BatchStatus.FAILED, jobExecution.getStatus()); assertEquals(BatchStatus.FAILED, jobExecution.getStatus());
assertEquals(1, jobExecution.getStepExecutions().size()); assertEquals(1, jobExecution.getStepExecutions().size());
} }
@Test @Test
public void testEndStateStoppedWithRestart() throws Exception { public void testEndStateStoppedWithRestart() throws Exception {
SimpleFlow flow = new SimpleFlow("job"); SimpleFlow flow = new SimpleFlow("job");
Collection<StateTransition> transitions = new ArrayList<StateTransition>(); Collection<StateTransition> transitions = new ArrayList<StateTransition>();
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end")); transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end"));
transitions.add(StateTransition.createStateTransition(new EndState(BatchStatus.STOPPED, "end"), "step2")); transitions.add(StateTransition.createStateTransition(new EndState(BatchStatus.STOPPED, "end"), "step2"));
transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2")))); transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2"))));
flow.setStateTransitions(transitions); flow.setStateTransitions(transitions);
job.setFlow(flow); job.setFlow(flow);
job.afterPropertiesSet(); job.afterPropertiesSet();
// To test a restart we have to use the AbstractJob.execute()... // To test a restart we have to use the AbstractJob.execute()...
job.execute(jobExecution); job.execute(jobExecution);
assertEquals(BatchStatus.STOPPED, jobExecution.getStatus()); assertEquals(BatchStatus.STOPPED, jobExecution.getStatus());
assertEquals(1, jobExecution.getStepExecutions().size()); assertEquals(1, jobExecution.getStepExecutions().size());
jobExecution = jobRepository.createJobExecution("job", new JobParameters()); jobExecution = jobRepository.createJobExecution("job", new JobParameters());
job.execute(jobExecution); job.execute(jobExecution);
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
assertEquals(1, jobExecution.getStepExecutions().size()); assertEquals(1, jobExecution.getStepExecutions().size());
} }
@Test @Test
public void testBranching() throws Exception { public void testBranching() throws Exception {
SimpleFlow flow = new SimpleFlow("job"); SimpleFlow flow = new SimpleFlow("job");
Collection<StateTransition> transitions = new ArrayList<StateTransition>(); Collection<StateTransition> transitions = new ArrayList<StateTransition>();
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2")); transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "COMPLETED", transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "COMPLETED",
"step3")); "step3"));
transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2")))); transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2"))));
transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step3")))); transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step3"))));
flow.setStateTransitions(transitions); flow.setStateTransitions(transitions);
job.setFlow(flow); job.setFlow(flow);
job.afterPropertiesSet(); job.afterPropertiesSet();
StepExecution stepExecution = job.doExecute(jobExecution); StepExecution stepExecution = job.doExecute(jobExecution);
assertEquals(ExitStatus.FINISHED, stepExecution.getExitStatus()); assertEquals(ExitStatus.COMPLETED, stepExecution.getExitStatus());
assertEquals(2, jobExecution.getStepExecutions().size()); assertEquals(2, jobExecution.getStepExecutions().size());
assertEquals("step3", stepExecution.getStepName()); assertEquals("step3", stepExecution.getStepName());
} }
@Test @Test
public void testBasicFlow() throws Throwable { public void testBasicFlow() throws Throwable {
SimpleFlow flow = new SimpleFlow("job"); SimpleFlow flow = new SimpleFlow("job");
Step step = new StubStep("step"); Step step = new StubStep("step");
flow.setStateTransitions(Collections.singleton(StateTransition.createEndStateTransition(new StepState(step), flow.setStateTransitions(Collections.singleton(StateTransition.createEndStateTransition(new StepState(step),
"*"))); "*")));
job.setFlow(flow); job.setFlow(flow);
job.execute(jobExecution); job.execute(jobExecution);
if (!jobExecution.getAllFailureExceptions().isEmpty()) { if (!jobExecution.getAllFailureExceptions().isEmpty()) {
throw jobExecution.getAllFailureExceptions().get(0); throw jobExecution.getAllFailureExceptions().get(0);
} }
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
} }
@Test @Test
public void testDecisionFlow() throws Throwable { public void testDecisionFlow() throws Throwable {
SimpleFlow flow = new SimpleFlow("job"); SimpleFlow flow = new SimpleFlow("job");
JobExecutionDecider decider = new JobExecutionDecider() { JobExecutionDecider decider = new JobExecutionDecider() {
public String decide(JobExecution jobExecution, StepExecution stepExecution) { public String decide(JobExecution jobExecution, StepExecution stepExecution) {
assertNotNull(stepExecution); assertNotNull(stepExecution);
return "SWITCH"; return "SWITCH";
} }
}; };
Collection<StateTransition> transitions = new ArrayList<StateTransition>(); Collection<StateTransition> transitions = new ArrayList<StateTransition>();
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "*", "decision")); transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "*", "decision"));
transitions.add(StateTransition.createStateTransition(new DecisionState(decider, "decision"), "*", "step2")); transitions.add(StateTransition.createStateTransition(new DecisionState(decider, "decision"), "*", "step2"));
transitions.add(StateTransition transitions.add(StateTransition
.createStateTransition(new DecisionState(decider, "decision"), "SWITCH", "step3")); .createStateTransition(new DecisionState(decider, "decision"), "SWITCH", "step3"));
transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2")), "*")); transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step2")), "*"));
transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step3")), "*")); transitions.add(StateTransition.createEndStateTransition(new StepState(new StubStep("step3")), "*"));
flow.setStateTransitions(transitions); flow.setStateTransitions(transitions);
job.setFlow(flow); job.setFlow(flow);
StepExecution stepExecution = job.doExecute(jobExecution); StepExecution stepExecution = job.doExecute(jobExecution);
if (!jobExecution.getAllFailureExceptions().isEmpty()) { if (!jobExecution.getAllFailureExceptions().isEmpty()) {
throw jobExecution.getAllFailureExceptions().get(0); throw jobExecution.getAllFailureExceptions().get(0);
} }
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
assertEquals(2, jobExecution.getStepExecutions().size()); assertEquals(2, jobExecution.getStepExecutions().size());
assertEquals("step3", stepExecution.getStepName()); assertEquals("step3", stepExecution.getStepName());
} }
/** /**
* @author Dave Syer * @author Dave Syer
* *
*/ */
private class StubStep extends StepSupport { private class StubStep extends StepSupport {
private StubStep(String name) { private StubStep(String name) {
super(name); super(name);
} }
public void execute(StepExecution stepExecution) throws JobInterruptedException { public void execute(StepExecution stepExecution) throws JobInterruptedException {
stepExecution.setStatus(BatchStatus.COMPLETED); stepExecution.setStatus(BatchStatus.COMPLETED);
stepExecution.setExitStatus(ExitStatus.FINISHED); stepExecution.setExitStatus(ExitStatus.COMPLETED);
jobRepository.update(stepExecution); jobRepository.update(stepExecution);
} }
} }
} }

View File

@@ -52,7 +52,7 @@ public class SimpleJobLauncherTests {
private Job job = new JobSupport("foo") { private Job job = new JobSupport("foo") {
@Override @Override
public void execute(JobExecution execution) { public void execute(JobExecution execution) {
execution.setExitStatus(ExitStatus.FINISHED); execution.setExitStatus(ExitStatus.COMPLETED);
return; return;
} }
}; };
@@ -81,7 +81,7 @@ public class SimpleJobLauncherTests {
jobLauncher.afterPropertiesSet(); jobLauncher.afterPropertiesSet();
jobLauncher.run(job, jobParameters); jobLauncher.run(job, jobParameters);
assertEquals(ExitStatus.FINISHED, jobExecution.getExitStatus()); assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
verify(jobRepository); verify(jobRepository);
} }
@@ -100,7 +100,7 @@ public class SimpleJobLauncherTests {
@Override @Override
public void execute(JobExecution execution) { public void execute(JobExecution execution) {
execution.setExitStatus(ExitStatus.FINISHED); execution.setExitStatus(ExitStatus.COMPLETED);
return; return;
} }
}; };

View File

@@ -59,7 +59,7 @@ public class CommandLineJobRunnerTests {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
JobExecution jobExecution = new JobExecution(null, new Long(1)); JobExecution jobExecution = new JobExecution(null, new Long(1));
ExitStatus exitStatus = ExitStatus.FINISHED; ExitStatus exitStatus = ExitStatus.COMPLETED;
jobExecution.setExitStatus(exitStatus); jobExecution.setExitStatus(exitStatus);
StubJobLauncher.jobExecution = jobExecution; StubJobLauncher.jobExecution = jobExecution;
} }

View File

@@ -38,7 +38,7 @@ public class SimpleJvmExitCodeMapperTests extends TestCase {
ecm2 = new SimpleJvmExitCodeMapper(); ecm2 = new SimpleJvmExitCodeMapper();
Map<String, Integer> ecm2Map = new HashMap<String, Integer>(); Map<String, Integer> ecm2Map = new HashMap<String, Integer>();
ecm2Map.put(ExitStatus.FINISHED.getExitCode(), new Integer(-1)); ecm2Map.put(ExitStatus.COMPLETED.getExitCode(), new Integer(-1));
ecm2Map.put(ExitStatus.FAILED.getExitCode(), new Integer(-2)); ecm2Map.put(ExitStatus.FAILED.getExitCode(), new Integer(-2));
ecm2Map.put(ExitCodeMapper.JOB_NOT_PROVIDED, new Integer(-3)); ecm2Map.put(ExitCodeMapper.JOB_NOT_PROVIDED, new Integer(-3));
ecm2Map.put(ExitCodeMapper.NO_SUCH_JOB, new Integer(-3)); ecm2Map.put(ExitCodeMapper.NO_SUCH_JOB, new Integer(-3));
@@ -51,7 +51,7 @@ public class SimpleJvmExitCodeMapperTests extends TestCase {
public void testGetExitCodeWithpPredefinedCodes() { public void testGetExitCodeWithpPredefinedCodes() {
assertEquals( assertEquals(
ecm.intValue(ExitStatus.FINISHED.getExitCode()), ecm.intValue(ExitStatus.COMPLETED.getExitCode()),
ExitCodeMapper.JVM_EXITCODE_COMPLETED); ExitCodeMapper.JVM_EXITCODE_COMPLETED);
assertEquals( assertEquals(
ecm.intValue(ExitStatus.FAILED.getExitCode()), ecm.intValue(ExitStatus.FAILED.getExitCode()),
@@ -65,9 +65,9 @@ public class SimpleJvmExitCodeMapperTests extends TestCase {
} }
public void testGetExitCodeWithPredefinedCodesOverridden() { public void testGetExitCodeWithPredefinedCodesOverridden() {
System.out.println(ecm2.intValue(ExitStatus.FINISHED.getExitCode())); System.out.println(ecm2.intValue(ExitStatus.COMPLETED.getExitCode()));
assertEquals( assertEquals(
ecm2.intValue(ExitStatus.FINISHED.getExitCode()), -1); ecm2.intValue(ExitStatus.COMPLETED.getExitCode()), -1);
assertEquals( assertEquals(
ecm2.intValue(ExitStatus.FAILED.getExitCode()), -2); ecm2.intValue(ExitStatus.FAILED.getExitCode()), -2);
assertEquals( assertEquals(

View File

@@ -1,154 +1,154 @@
package org.springframework.batch.core.listener; package org.springframework.batch.core.listener;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.util.Collections; import java.util.Collections;
import org.junit.Test; import org.junit.Test;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.StepExecution;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* Tests for {@link ExecutionContextPromotionListener}. * Tests for {@link ExecutionContextPromotionListener}.
*/ */
public class ExecutionContextPromotionListenerTests { public class ExecutionContextPromotionListenerTests {
private static final String key = "testKey"; private static final String key = "testKey";
private static final String value = "testValue"; private static final String value = "testValue";
private static final String key2 = "testKey2"; private static final String key2 = "testKey2";
private static final String value2 = "testValue2"; private static final String value2 = "testValue2";
private static final String status = "COMPLETED WITH SKIPS"; private static final String status = "COMPLETED WITH SKIPS";
private static final String status2 = "FAILURE"; private static final String status2 = "FAILURE";
private static final String statusWildcard = "COMPL*SKIPS"; private static final String statusWildcard = "COMPL*SKIPS";
/** /**
* CONDITION: keys = {key1, key2}. statuses is not set (defaults to * CONDITION: keys = {key1, key2}. statuses is not set (defaults to
* {COMPLETED}). * {COMPLETED}).
* *
* EXPECTED: key is promoted. key2 is not. * EXPECTED: key is promoted. key2 is not.
*/ */
@Test @Test
public void promoteEntry_nullStatuses() throws Exception { public void promoteEntry_nullStatuses() throws Exception {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener(); ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
JobExecution jobExecution = new JobExecution(1L); JobExecution jobExecution = new JobExecution(1L);
StepExecution stepExecution = jobExecution.createStepExecution("step1"); StepExecution stepExecution = jobExecution.createStepExecution("step1");
stepExecution.setExitStatus(ExitStatus.FINISHED); stepExecution.setExitStatus(ExitStatus.COMPLETED);
Assert.state(jobExecution.getExecutionContext().isEmpty()); Assert.state(jobExecution.getExecutionContext().isEmpty());
Assert.state(stepExecution.getExecutionContext().isEmpty()); Assert.state(stepExecution.getExecutionContext().isEmpty());
stepExecution.getExecutionContext().putString(key, value); stepExecution.getExecutionContext().putString(key, value);
stepExecution.getExecutionContext().putString(key2, value2); stepExecution.getExecutionContext().putString(key2, value2);
listener.setKeys(Collections.singletonList(key)); listener.setKeys(Collections.singletonList(key));
listener.afterPropertiesSet(); listener.afterPropertiesSet();
listener.afterStep(stepExecution); listener.afterStep(stepExecution);
assertEquals(value, jobExecution.getExecutionContext().getString(key)); assertEquals(value, jobExecution.getExecutionContext().getString(key));
assertFalse(jobExecution.getExecutionContext().containsKey(key2)); assertFalse(jobExecution.getExecutionContext().containsKey(key2));
} }
/** /**
* CONDITION: keys = {key1, key2}. statuses = {status}. ExitStatus = status * CONDITION: keys = {key1, key2}. statuses = {status}. ExitStatus = status
* *
* EXPECTED: key is promoted. key2 is not. * EXPECTED: key is promoted. key2 is not.
*/ */
@Test @Test
public void promoteEntry_statusFound() throws Exception { public void promoteEntry_statusFound() throws Exception {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener(); ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
JobExecution jobExecution = new JobExecution(1L); JobExecution jobExecution = new JobExecution(1L);
StepExecution stepExecution = jobExecution.createStepExecution("step1"); StepExecution stepExecution = jobExecution.createStepExecution("step1");
stepExecution.setExitStatus(new ExitStatus(status)); stepExecution.setExitStatus(new ExitStatus(status));
Assert.state(jobExecution.getExecutionContext().isEmpty()); Assert.state(jobExecution.getExecutionContext().isEmpty());
Assert.state(stepExecution.getExecutionContext().isEmpty()); Assert.state(stepExecution.getExecutionContext().isEmpty());
stepExecution.getExecutionContext().putString(key, value); stepExecution.getExecutionContext().putString(key, value);
stepExecution.getExecutionContext().putString(key2, value2); stepExecution.getExecutionContext().putString(key2, value2);
listener.setKeys(Collections.singletonList(key)); listener.setKeys(Collections.singletonList(key));
listener.setStatuses(Collections.singletonList(status)); listener.setStatuses(Collections.singletonList(status));
listener.afterPropertiesSet(); listener.afterPropertiesSet();
listener.afterStep(stepExecution); listener.afterStep(stepExecution);
assertEquals(value, jobExecution.getExecutionContext().getString(key)); assertEquals(value, jobExecution.getExecutionContext().getString(key));
assertFalse(jobExecution.getExecutionContext().containsKey(key2)); assertFalse(jobExecution.getExecutionContext().containsKey(key2));
} }
/** /**
* CONDITION: keys = {key1, key2}. statuses = {status}. ExitStatus = status2 * CONDITION: keys = {key1, key2}. statuses = {status}. ExitStatus = status2
* *
* EXPECTED: no promotions. * EXPECTED: no promotions.
*/ */
@Test @Test
public void promoteEntry_statusNotFound() throws Exception { public void promoteEntry_statusNotFound() throws Exception {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener(); ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
JobExecution jobExecution = new JobExecution(1L); JobExecution jobExecution = new JobExecution(1L);
StepExecution stepExecution = jobExecution.createStepExecution("step1"); StepExecution stepExecution = jobExecution.createStepExecution("step1");
stepExecution.setExitStatus(new ExitStatus(status2)); stepExecution.setExitStatus(new ExitStatus(status2));
Assert.state(jobExecution.getExecutionContext().isEmpty()); Assert.state(jobExecution.getExecutionContext().isEmpty());
Assert.state(stepExecution.getExecutionContext().isEmpty()); Assert.state(stepExecution.getExecutionContext().isEmpty());
stepExecution.getExecutionContext().putString(key, value); stepExecution.getExecutionContext().putString(key, value);
stepExecution.getExecutionContext().putString(key2, value2); stepExecution.getExecutionContext().putString(key2, value2);
listener.setKeys(Collections.singletonList(key)); listener.setKeys(Collections.singletonList(key));
listener.setStatuses(Collections.singletonList(status)); listener.setStatuses(Collections.singletonList(status));
listener.afterPropertiesSet(); listener.afterPropertiesSet();
listener.afterStep(stepExecution); listener.afterStep(stepExecution);
assertFalse(jobExecution.getExecutionContext().containsKey(key)); assertFalse(jobExecution.getExecutionContext().containsKey(key));
assertFalse(jobExecution.getExecutionContext().containsKey(key2)); assertFalse(jobExecution.getExecutionContext().containsKey(key2));
} }
/** /**
* CONDITION: keys = {key1, key2}. statuses = {statusWildcard}. ExitStatus = * CONDITION: keys = {key1, key2}. statuses = {statusWildcard}. ExitStatus =
* status * status
* *
* EXPECTED: key is promoted. key2 is not. * EXPECTED: key is promoted. key2 is not.
*/ */
@Test @Test
public void promoteEntry_statusWildcardFound() throws Exception { public void promoteEntry_statusWildcardFound() throws Exception {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener(); ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
JobExecution jobExecution = new JobExecution(1L); JobExecution jobExecution = new JobExecution(1L);
StepExecution stepExecution = jobExecution.createStepExecution("step1"); StepExecution stepExecution = jobExecution.createStepExecution("step1");
stepExecution.setExitStatus(new ExitStatus(status)); stepExecution.setExitStatus(new ExitStatus(status));
Assert.state(jobExecution.getExecutionContext().isEmpty()); Assert.state(jobExecution.getExecutionContext().isEmpty());
Assert.state(stepExecution.getExecutionContext().isEmpty()); Assert.state(stepExecution.getExecutionContext().isEmpty());
stepExecution.getExecutionContext().putString(key, value); stepExecution.getExecutionContext().putString(key, value);
stepExecution.getExecutionContext().putString(key2, value2); stepExecution.getExecutionContext().putString(key2, value2);
listener.setKeys(Collections.singletonList(key)); listener.setKeys(Collections.singletonList(key));
listener.setStatuses(Collections.singletonList(statusWildcard)); listener.setStatuses(Collections.singletonList(statusWildcard));
listener.afterPropertiesSet(); listener.afterPropertiesSet();
listener.afterStep(stepExecution); listener.afterStep(stepExecution);
assertEquals(value, jobExecution.getExecutionContext().getString(key)); assertEquals(value, jobExecution.getExecutionContext().getString(key));
assertFalse(jobExecution.getExecutionContext().containsKey(key2)); assertFalse(jobExecution.getExecutionContext().containsKey(key2));
} }
/** /**
* CONDITION: keys = NULL * CONDITION: keys = NULL
* *
* EXPECTED: IllegalArgumentException * EXPECTED: IllegalArgumentException
*/ */
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void keysMustBeSet() throws Exception { public void keysMustBeSet() throws Exception {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener(); ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
// didn't set the keys, same as listener.setKeys(null); // didn't set the keys, same as listener.setKeys(null);
listener.afterPropertiesSet(); listener.afterPropertiesSet();
} }
} }

View File

@@ -1,125 +1,125 @@
package org.springframework.batch.core.listener; package org.springframework.batch.core.listener;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import java.lang.reflect.AccessibleObject; import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.configuration.util.MethodInvoker; import org.springframework.batch.core.configuration.util.MethodInvoker;
import org.springframework.batch.core.configuration.util.MethodInvokerUtils; import org.springframework.batch.core.configuration.util.MethodInvokerUtils;
import org.springframework.batch.core.configuration.util.SimpleMethodInvoker; import org.springframework.batch.core.configuration.util.SimpleMethodInvoker;
public class StepListenerMethodInterceptorTests { public class StepListenerMethodInterceptorTests {
MethodInvokerMethodInterceptor interceptor; MethodInvokerMethodInterceptor interceptor;
TestClass testClass; TestClass testClass;
@Before @Before
public void setUp(){ public void setUp(){
testClass = new TestClass(); testClass = new TestClass();
} }
@Test @Test
public void testNormalCase() throws Throwable{ public void testNormalCase() throws Throwable{
Map<String, Set<MethodInvoker>> invokerMap = new HashMap<String, Set<MethodInvoker>>(); Map<String, Set<MethodInvoker>> invokerMap = new HashMap<String, Set<MethodInvoker>>();
for(Method method : TestClass.class.getMethods()){ for(Method method : TestClass.class.getMethods()){
invokerMap.put(method.getName(), asSet( new SimpleMethodInvoker(testClass, method))); invokerMap.put(method.getName(), asSet( new SimpleMethodInvoker(testClass, method)));
} }
interceptor = new MethodInvokerMethodInterceptor(invokerMap); interceptor = new MethodInvokerMethodInterceptor(invokerMap);
interceptor.invoke(new StubMethodInvocation(TestClass.class.getMethod("method1"))); interceptor.invoke(new StubMethodInvocation(TestClass.class.getMethod("method1")));
assertEquals(1, testClass.method1Count); assertEquals(1, testClass.method1Count);
interceptor.invoke(new StubMethodInvocation(TestClass.class.getMethod("method2"))); interceptor.invoke(new StubMethodInvocation(TestClass.class.getMethod("method2")));
assertEquals(1, testClass.method2Count); assertEquals(1, testClass.method2Count);
} }
@Test @Test
public void testMultipleInvokersPerName() throws Throwable{ public void testMultipleInvokersPerName() throws Throwable{
Map<String, Set<MethodInvoker>> invokerMap = new HashMap<String, Set<MethodInvoker>>(); Map<String, Set<MethodInvoker>> invokerMap = new HashMap<String, Set<MethodInvoker>>();
Set<MethodInvoker> invokers = asSet(MethodInvokerUtils.createMethodInvokerByName(testClass, "method1", false)); Set<MethodInvoker> invokers = asSet(MethodInvokerUtils.createMethodInvokerByName(testClass, "method1", false));
invokers.add(MethodInvokerUtils.createMethodInvokerByName(testClass, "method2", false)); invokers.add(MethodInvokerUtils.createMethodInvokerByName(testClass, "method2", false));
invokerMap.put("method1", invokers); invokerMap.put("method1", invokers);
interceptor = new MethodInvokerMethodInterceptor(invokerMap); interceptor = new MethodInvokerMethodInterceptor(invokerMap);
interceptor.invoke(new StubMethodInvocation(TestClass.class.getMethod("method1"))); interceptor.invoke(new StubMethodInvocation(TestClass.class.getMethod("method1")));
assertEquals(1, testClass.method1Count); assertEquals(1, testClass.method1Count);
interceptor.invoke(new StubMethodInvocation(TestClass.class.getMethod("method2"))); interceptor.invoke(new StubMethodInvocation(TestClass.class.getMethod("method2")));
assertEquals(1, testClass.method2Count); assertEquals(1, testClass.method2Count);
} }
@Test @Test
public void testExitStatusReturn() throws Throwable{ public void testExitStatusReturn() throws Throwable{
Map<String, Set<MethodInvoker>> invokerMap = new HashMap<String, Set<MethodInvoker>>(); Map<String, Set<MethodInvoker>> invokerMap = new HashMap<String, Set<MethodInvoker>>();
Set<MethodInvoker> invokers = asSet(MethodInvokerUtils.createMethodInvokerByName(testClass, "method3", false)); Set<MethodInvoker> invokers = asSet(MethodInvokerUtils.createMethodInvokerByName(testClass, "method3", false));
invokers.add(MethodInvokerUtils.createMethodInvokerByName(testClass, "method3", false)); invokers.add(MethodInvokerUtils.createMethodInvokerByName(testClass, "method3", false));
invokerMap.put("method3", invokers); invokerMap.put("method3", invokers);
interceptor = new MethodInvokerMethodInterceptor(invokerMap); interceptor = new MethodInvokerMethodInterceptor(invokerMap);
assertEquals(ExitStatus.FINISHED, interceptor.invoke(new StubMethodInvocation(TestClass.class.getMethod("method3")))); assertEquals(ExitStatus.COMPLETED, interceptor.invoke(new StubMethodInvocation(TestClass.class.getMethod("method3"))));
} }
public Set<MethodInvoker> asSet(MethodInvoker methodInvoker){ public Set<MethodInvoker> asSet(MethodInvoker methodInvoker){
Set<MethodInvoker> invokerSet = new HashSet<MethodInvoker>(); Set<MethodInvoker> invokerSet = new HashSet<MethodInvoker>();
invokerSet.add(methodInvoker); invokerSet.add(methodInvoker);
return invokerSet; return invokerSet;
} }
private class TestClass{ private class TestClass{
int method1Count = 0; int method1Count = 0;
int method2Count = 0; int method2Count = 0;
int method3Count = 0; int method3Count = 0;
public void method1(){ public void method1(){
method1Count++; method1Count++;
} }
public void method2(){ public void method2(){
method2Count++; method2Count++;
} }
public ExitStatus method3(){ public ExitStatus method3(){
method3Count++; method3Count++;
return ExitStatus.FINISHED; return ExitStatus.COMPLETED;
} }
} }
private class StubMethodInvocation implements MethodInvocation{ private class StubMethodInvocation implements MethodInvocation{
Method method; Method method;
Object[] args; Object[] args;
public StubMethodInvocation(Method method, Object... args) { public StubMethodInvocation(Method method, Object... args) {
this.method = method; this.method = method;
this.args = args; this.args = args;
} }
public Method getMethod() { public Method getMethod() {
return method; return method;
} }
public Object[] getArguments() { public Object[] getArguments() {
return null; return null;
} }
public AccessibleObject getStaticPart() { public AccessibleObject getStaticPart() {
return null; return null;
} }
public Object getThis() { public Object getThis() {
return null; return null;
} }
public Object proceed() throws Throwable { public Object proceed() throws Throwable {
return null; return null;
} }
} }
} }

View File

@@ -1,107 +1,107 @@
/* /*
* Copyright 2006-2007 the original author or authors. * Copyright 2006-2007 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.batch.core.partition.support; package org.springframework.batch.core.partition.support;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import java.util.Collection; import java.util.Collection;
import java.util.Set; import java.util.Set;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step; import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.partition.PartitionHandler; import org.springframework.batch.core.partition.PartitionHandler;
import org.springframework.batch.core.partition.StepExecutionSplitter; import org.springframework.batch.core.partition.StepExecutionSplitter;
import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean; import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.step.StepSupport; import org.springframework.batch.core.step.StepSupport;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager; import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
/** /**
* @author Dave Syer * @author Dave Syer
* *
*/ */
public class PartitionStepTests { public class PartitionStepTests {
private PartitionStep step = new PartitionStep(); private PartitionStep step = new PartitionStep();
private Step remote = new StepSupport("remote"); private Step remote = new StepSupport("remote");
private JobRepository jobRepository; private JobRepository jobRepository;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
MapJobRepositoryFactoryBean.clear(); MapJobRepositoryFactoryBean.clear();
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(); MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
factory.setTransactionManager(new ResourcelessTransactionManager()); factory.setTransactionManager(new ResourcelessTransactionManager());
jobRepository = (JobRepository) factory.getObject(); jobRepository = (JobRepository) factory.getObject();
step.setJobRepository(jobRepository); step.setJobRepository(jobRepository);
} }
@Test @Test
public void testVanillaStepExecution() throws Exception { public void testVanillaStepExecution() throws Exception {
step.setStepExecutionSplitter(new SimpleStepExecutionSplitter(jobRepository, remote)); step.setStepExecutionSplitter(new SimpleStepExecutionSplitter(jobRepository, remote));
step.setPartitionHandler(new PartitionHandler() { step.setPartitionHandler(new PartitionHandler() {
public Collection<StepExecution> handle(StepExecutionSplitter stepSplitter, StepExecution stepExecution) public Collection<StepExecution> handle(StepExecutionSplitter stepSplitter, StepExecution stepExecution)
throws Exception { throws Exception {
Set<StepExecution> executions = stepSplitter.split(stepExecution, 2); Set<StepExecution> executions = stepSplitter.split(stepExecution, 2);
for (StepExecution execution : executions) { for (StepExecution execution : executions) {
execution.setStatus(BatchStatus.COMPLETED); execution.setStatus(BatchStatus.COMPLETED);
execution.setExitStatus(ExitStatus.FINISHED); execution.setExitStatus(ExitStatus.COMPLETED);
} }
return executions; return executions;
} }
}); });
step.afterPropertiesSet(); step.afterPropertiesSet();
JobExecution jobExecution = jobRepository.createJobExecution("vanillaJob", new JobParameters()); JobExecution jobExecution = jobRepository.createJobExecution("vanillaJob", new JobParameters());
StepExecution stepExecution = jobExecution.createStepExecution("foo"); StepExecution stepExecution = jobExecution.createStepExecution("foo");
jobRepository.add(stepExecution); jobRepository.add(stepExecution);
step.execute(stepExecution); step.execute(stepExecution);
// one master and two workers // one master and two workers
assertEquals(3, stepExecution.getJobExecution().getStepExecutions().size()); assertEquals(3, stepExecution.getJobExecution().getStepExecutions().size());
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
} }
@Test @Test
public void testFailedStepExecution() throws Exception { public void testFailedStepExecution() throws Exception {
step.setStepExecutionSplitter(new SimpleStepExecutionSplitter(jobRepository, remote)); step.setStepExecutionSplitter(new SimpleStepExecutionSplitter(jobRepository, remote));
step.setPartitionHandler(new PartitionHandler() { step.setPartitionHandler(new PartitionHandler() {
public Collection<StepExecution> handle(StepExecutionSplitter stepSplitter, StepExecution stepExecution) public Collection<StepExecution> handle(StepExecutionSplitter stepSplitter, StepExecution stepExecution)
throws Exception { throws Exception {
Set<StepExecution> executions = stepSplitter.split(stepExecution, 2); Set<StepExecution> executions = stepSplitter.split(stepExecution, 2);
for (StepExecution execution : executions) { for (StepExecution execution : executions) {
execution.setStatus(BatchStatus.FAILED); execution.setStatus(BatchStatus.FAILED);
execution.setExitStatus(ExitStatus.FAILED); execution.setExitStatus(ExitStatus.FAILED);
} }
return executions; return executions;
} }
}); });
step.afterPropertiesSet(); step.afterPropertiesSet();
JobExecution jobExecution = jobRepository.createJobExecution("vanillaJob", new JobParameters()); JobExecution jobExecution = jobRepository.createJobExecution("vanillaJob", new JobParameters());
StepExecution stepExecution = jobExecution.createStepExecution("foo"); StepExecution stepExecution = jobExecution.createStepExecution("foo");
jobRepository.add(stepExecution); jobRepository.add(stepExecution);
step.execute(stepExecution); step.execute(stepExecution);
// one master and two workers // one master and two workers
assertEquals(3, stepExecution.getJobExecution().getStepExecutions().size()); assertEquals(3, stepExecution.getJobExecution().getStepExecutions().size());
assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
} }
} }

View File

@@ -167,7 +167,7 @@ public abstract class AbstractJobDaoTests {
public void testUpdateJobExecution() { public void testUpdateJobExecution() {
jobExecution.setStatus(BatchStatus.COMPLETED); jobExecution.setStatus(BatchStatus.COMPLETED);
jobExecution.setExitStatus(ExitStatus.FINISHED); jobExecution.setExitStatus(ExitStatus.COMPLETED);
jobExecution.setEndTime(new Date(System.currentTimeMillis())); jobExecution.setEndTime(new Date(System.currentTimeMillis()));
jobExecutionDao.updateJobExecution(jobExecution); jobExecutionDao.updateJobExecution(jobExecution);

View File

@@ -30,7 +30,7 @@ public class JdbcJobDaoTests extends AbstractJobDaoTests {
assertTrue(LONG_STRING.length() > 250); assertTrue(LONG_STRING.length() > 250);
((JdbcJobExecutionDao) jobExecutionDao).setExitMessageLength(250); ((JdbcJobExecutionDao) jobExecutionDao).setExitMessageLength(250);
jobExecution.setExitStatus(ExitStatus.FINISHED jobExecution.setExitStatus(ExitStatus.COMPLETED
.addExitDescription(LONG_STRING)); .addExitDescription(LONG_STRING));
jobExecutionDao.updateJobExecution(jobExecution); jobExecutionDao.updateJobExecution(jobExecution);

View File

@@ -59,7 +59,7 @@ public class AbstractStepTests {
protected void doExecute(StepExecution context) throws Exception { protected void doExecute(StepExecution context) throws Exception {
assertSame(execution, context); assertSame(execution, context);
events.add("doExecute"); events.add("doExecute");
context.setExitStatus(ExitStatus.FINISHED); context.setExitStatus(ExitStatus.COMPLETED);
} }
protected void close(ExecutionContext ctx) throws Exception { protected void close(ExecutionContext ctx) throws Exception {
@@ -180,7 +180,7 @@ public class AbstractStepTests {
assertEquals("close", events.get(i++)); assertEquals("close", events.get(i++));
assertEquals(7, events.size()); assertEquals(7, events.size());
assertEquals(ExitStatus.FINISHED, execution.getExitStatus()); assertEquals(ExitStatus.COMPLETED, execution.getExitStatus());
assertTrue("Execution context modifications made by listener should be persisted", repository.saved assertTrue("Execution context modifications made by listener should be persisted", repository.saved
.containsKey("beforeStep")); .containsKey("beforeStep"));

View File

@@ -1,107 +1,107 @@
/* /*
* Copyright 2006-2009 the original author or authors. * Copyright 2006-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.batch.core.step.item; package org.springframework.batch.core.step.item;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import org.junit.Test; import org.junit.Test;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobInstance; import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.scope.context.ChunkContext;
/** /**
* @author Dave Syer * @author Dave Syer
* *
*/ */
public class ChunkOrientedTaskletTests { public class ChunkOrientedTaskletTests {
private ChunkContext context = new ChunkContext(null); private ChunkContext context = new ChunkContext(null);
@Test @Test
public void testHandle() throws Exception { public void testHandle() throws Exception {
ChunkOrientedTasklet<String> handler = new ChunkOrientedTasklet<String>(new ChunkProvider<String>() { ChunkOrientedTasklet<String> handler = new ChunkOrientedTasklet<String>(new ChunkProvider<String>() {
public Chunk<String> provide(StepContribution contribution) throws Exception { public Chunk<String> provide(StepContribution contribution) throws Exception {
contribution.incrementReadCount(); contribution.incrementReadCount();
Chunk<String> chunk = new Chunk<String>(); Chunk<String> chunk = new Chunk<String>();
chunk.add("foo"); chunk.add("foo");
return chunk; return chunk;
} }
public void postProcess(StepContribution contribution, Chunk<String> chunk) {}; public void postProcess(StepContribution contribution, Chunk<String> chunk) {};
}, new ChunkProcessor<String>() { }, new ChunkProcessor<String>() {
public void process(StepContribution contribution, Chunk<String> chunk) { public void process(StepContribution contribution, Chunk<String> chunk) {
contribution.incrementWriteCount(1); contribution.incrementWriteCount(1);
} }
}); });
StepContribution contribution = new StepContribution(new StepExecution("foo", new JobExecution(new JobInstance( StepContribution contribution = new StepContribution(new StepExecution("foo", new JobExecution(new JobInstance(
123L, new JobParameters(), "job")))); 123L, new JobParameters(), "job"))));
handler.execute(contribution, context); handler.execute(contribution, context);
assertEquals(1, contribution.getReadCount()); assertEquals(1, contribution.getReadCount());
assertEquals(1, contribution.getWriteCount()); assertEquals(1, contribution.getWriteCount());
assertEquals(0, context.attributeNames().length); assertEquals(0, context.attributeNames().length);
} }
@Test @Test
public void testFail() throws Exception { public void testFail() throws Exception {
ChunkOrientedTasklet<String> handler = new ChunkOrientedTasklet<String>(new ChunkProvider<String>() { ChunkOrientedTasklet<String> handler = new ChunkOrientedTasklet<String>(new ChunkProvider<String>() {
public Chunk<String> provide(StepContribution contribution) throws Exception { public Chunk<String> provide(StepContribution contribution) throws Exception {
throw new RuntimeException("Foo!"); throw new RuntimeException("Foo!");
} }
public void postProcess(StepContribution contribution, Chunk<String> chunk) {}; public void postProcess(StepContribution contribution, Chunk<String> chunk) {};
}, new ChunkProcessor<String>() { }, new ChunkProcessor<String>() {
public void process(StepContribution contribution, Chunk<String> chunk) { public void process(StepContribution contribution, Chunk<String> chunk) {
fail("Not expecting to get this far"); fail("Not expecting to get this far");
} }
}); });
StepContribution contribution = new StepContribution(new StepExecution("foo", new JobExecution(new JobInstance( StepContribution contribution = new StepContribution(new StepExecution("foo", new JobExecution(new JobInstance(
123L, new JobParameters(), "job")))); 123L, new JobParameters(), "job"))));
try { try {
handler.execute(contribution, context); handler.execute(contribution, context);
fail("Expected RuntimeException"); fail("Expected RuntimeException");
} }
catch (RuntimeException e) { catch (RuntimeException e) {
assertEquals("Foo!", e.getMessage()); assertEquals("Foo!", e.getMessage());
} }
assertEquals(0, contribution.getReadCount()); assertEquals(0, contribution.getReadCount());
} }
@Test @Test
public void testExitCode() throws Exception { public void testExitCode() throws Exception {
ChunkOrientedTasklet<String> handler = new ChunkOrientedTasklet<String>(new ChunkProvider<String>() { ChunkOrientedTasklet<String> handler = new ChunkOrientedTasklet<String>(new ChunkProvider<String>() {
public Chunk<String> provide(StepContribution contribution) throws Exception { public Chunk<String> provide(StepContribution contribution) throws Exception {
contribution.incrementReadCount(); contribution.incrementReadCount();
Chunk<String> chunk = new Chunk<String>(); Chunk<String> chunk = new Chunk<String>();
chunk.add("foo"); chunk.add("foo");
chunk.setEnd(); chunk.setEnd();
return chunk; return chunk;
} }
public void postProcess(StepContribution contribution, Chunk<String> chunk) {}; public void postProcess(StepContribution contribution, Chunk<String> chunk) {};
}, new ChunkProcessor<String>() { }, new ChunkProcessor<String>() {
public void process(StepContribution contribution, Chunk<String> chunk) { public void process(StepContribution contribution, Chunk<String> chunk) {
contribution.incrementWriteCount(1); contribution.incrementWriteCount(1);
} }
}); });
StepContribution contribution = new StepContribution(new StepExecution("foo", new JobExecution(new JobInstance( StepContribution contribution = new StepContribution(new StepExecution("foo", new JobExecution(new JobInstance(
123L, new JobParameters(), "job")))); 123L, new JobParameters(), "job"))));
handler.execute(contribution, context); handler.execute(contribution, context);
assertEquals(ExitStatus.FINISHED.getExitCode(), contribution.getExitStatus().getExitCode()); assertEquals(ExitStatus.COMPLETED.getExitCode(), contribution.getExitStatus().getExitCode());
} }
} }

View File

@@ -25,7 +25,7 @@ public class ConfigurableSystemProcessExitCodeMapperTests {
public void testMapping() { public void testMapping() {
Map<Object, ExitStatus> mappings = new HashMap<Object, ExitStatus>() { Map<Object, ExitStatus> mappings = new HashMap<Object, ExitStatus>() {
{ {
put(0, ExitStatus.FINISHED); put(0, ExitStatus.COMPLETED);
put(1, ExitStatus.FAILED); put(1, ExitStatus.FAILED);
put(2, ExitStatus.EXECUTING); put(2, ExitStatus.EXECUTING);
put(3, ExitStatus.NOOP); put(3, ExitStatus.NOOP);

View File

@@ -19,7 +19,7 @@ public class SimpleSystemProcessExitCodeMapperTests {
*/ */
@Test @Test
public void testMapping() { public void testMapping() {
assertEquals(ExitStatus.FINISHED, mapper.getExitStatus(0)); assertEquals(ExitStatus.COMPLETED, mapper.getExitStatus(0));
assertEquals(ExitStatus.FAILED, mapper.getExitStatus(1)); assertEquals(ExitStatus.FAILED, mapper.getExitStatus(1));
assertEquals(ExitStatus.FAILED, mapper.getExitStatus(-1)); assertEquals(ExitStatus.FAILED, mapper.getExitStatus(-1));
} }

View File

@@ -65,7 +65,7 @@ public class StepHandlerAdapterTests {
tasklet.setTargetMethod("process"); tasklet.setTargetMethod("process");
StepContribution contribution = stepExecution.createStepContribution(); StepContribution contribution = stepExecution.createStepContribution();
tasklet.execute(contribution,null); tasklet.execute(contribution,null);
assertEquals(ExitStatus.FINISHED, contribution.getExitStatus()); assertEquals(ExitStatus.COMPLETED, contribution.getExitStatus());
} }
@Test @Test
@@ -74,7 +74,7 @@ public class StepHandlerAdapterTests {
this.result = "foo"; this.result = "foo";
StepContribution contribution = stepExecution.createStepContribution(); StepContribution contribution = stepExecution.createStepContribution();
tasklet.execute(contribution,null); tasklet.execute(contribution,null);
assertEquals(ExitStatus.FINISHED, contribution.getExitStatus()); assertEquals(ExitStatus.COMPLETED, contribution.getExitStatus());
} }
} }

View File

@@ -224,7 +224,7 @@ public class SystemCommandTaskletIntegrationTests {
public ExitStatus getExitStatus(int exitCode) { public ExitStatus getExitStatus(int exitCode) {
if (exitCode == 0) { if (exitCode == 0) {
return ExitStatus.FINISHED; return ExitStatus.COMPLETED;
} }
else { else {
return ExitStatus.FAILED; return ExitStatus.FAILED;

View File

@@ -231,7 +231,7 @@ public class TaskletStepTests {
} }
catch (Exception ex) { catch (Exception ex) {
ExitStatus status = stepExecution.getExitStatus(); ExitStatus status = stepExecution.getExitStatus();
assertEquals(ExitStatus.FINISHED, status); assertEquals(ExitStatus.COMPLETED, status);
} }
} }

View File

@@ -1,195 +1,195 @@
/* /*
* Copyright 2006-2007 the original author or authors. * Copyright 2006-2007 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.batch.integration.chunk; package org.springframework.batch.integration.chunk;
import java.util.List; import java.util.List;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.listener.StepExecutionListenerSupport; import org.springframework.batch.core.listener.StepExecutionListenerSupport;
import org.springframework.batch.item.ExecutionContext; import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStream; import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemStreamException; import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.ItemWriter;
import org.springframework.integration.gateway.MessagingGateway; import org.springframework.integration.gateway.MessagingGateway;
import org.springframework.util.Assert; import org.springframework.util.Assert;
public class ChunkMessageChannelItemWriter<T> extends StepExecutionListenerSupport implements ItemWriter<T>, ItemStream { public class ChunkMessageChannelItemWriter<T> extends StepExecutionListenerSupport implements ItemWriter<T>, ItemStream {
private static final Log logger = LogFactory.getLog(ChunkMessageChannelItemWriter.class); private static final Log logger = LogFactory.getLog(ChunkMessageChannelItemWriter.class);
static final String ACTUAL = ChunkMessageChannelItemWriter.class.getName() + ".ACTUAL"; static final String ACTUAL = ChunkMessageChannelItemWriter.class.getName() + ".ACTUAL";
static final String EXPECTED = ChunkMessageChannelItemWriter.class.getName() + ".EXPECTED"; static final String EXPECTED = ChunkMessageChannelItemWriter.class.getName() + ".EXPECTED";
private static final long DEFAULT_THROTTLE_LIMIT = 6; private static final long DEFAULT_THROTTLE_LIMIT = 6;
private MessagingGateway messagingGateway; private MessagingGateway messagingGateway;
private LocalState localState = new LocalState(); private LocalState localState = new LocalState();
private long throttleLimit = DEFAULT_THROTTLE_LIMIT; private long throttleLimit = DEFAULT_THROTTLE_LIMIT;
/** /**
* Public setter for the throttle limit. This limits the number of pending * Public setter for the throttle limit. This limits the number of pending
* requests for chunk processing to avoid overwhelming the receivers. * requests for chunk processing to avoid overwhelming the receivers.
* @param throttleLimit the throttle limit to set * @param throttleLimit the throttle limit to set
*/ */
public void setThrottleLimit(long throttleLimit) { public void setThrottleLimit(long throttleLimit) {
this.throttleLimit = throttleLimit; this.throttleLimit = throttleLimit;
} }
public void setMessagingGateway(MessagingGateway messagingGateway) { public void setMessagingGateway(MessagingGateway messagingGateway) {
this.messagingGateway = messagingGateway; this.messagingGateway = messagingGateway;
} }
public void write(List<? extends T> items) throws Exception { public void write(List<? extends T> items) throws Exception {
// Block until expecting <= throttle limit // Block until expecting <= throttle limit
while (localState.getExpecting() > throttleLimit) { while (localState.getExpecting() > throttleLimit) {
getNextResult(); getNextResult();
} }
if (!items.isEmpty()) { if (!items.isEmpty()) {
logger.debug("Dispatching chunk: " + items); logger.debug("Dispatching chunk: " + items);
ChunkRequest<T> request = new ChunkRequest<T>(items, localState.getJobId(), localState ChunkRequest<T> request = new ChunkRequest<T>(items, localState.getJobId(), localState
.createStepContribution()); .createStepContribution());
messagingGateway.send(request); messagingGateway.send(request);
localState.expected++; localState.expected++;
} }
} }
@Override @Override
public void beforeStep(StepExecution stepExecution) { public void beforeStep(StepExecution stepExecution) {
localState.setStepExecution(stepExecution); localState.setStepExecution(stepExecution);
} }
@Override @Override
public ExitStatus afterStep(StepExecution stepExecution) { public ExitStatus afterStep(StepExecution stepExecution) {
if (!(stepExecution.getStatus() == BatchStatus.COMPLETED)) { if (!(stepExecution.getStatus() == BatchStatus.COMPLETED)) {
return ExitStatus.EXECUTING; return ExitStatus.EXECUTING;
} }
long expecting = localState.getExpecting(); long expecting = localState.getExpecting();
boolean timedOut; boolean timedOut;
try { try {
logger.debug("Waiting for results in step listener..."); logger.debug("Waiting for results in step listener...");
timedOut = !waitForResults(); timedOut = !waitForResults();
logger.debug("Finished waiting for results in step listener."); logger.debug("Finished waiting for results in step listener.");
} }
catch (RuntimeException e) { catch (RuntimeException e) {
logger.debug("Detected failure waiting for results in step listener.", e); logger.debug("Detected failure waiting for results in step listener.", e);
stepExecution.setStatus(BatchStatus.FAILED); stepExecution.setStatus(BatchStatus.FAILED);
return ExitStatus.FAILED.addExitDescription(e.getClass().getName() + ": " + e.getMessage()); return ExitStatus.FAILED.addExitDescription(e.getClass().getName() + ": " + e.getMessage());
} }
if (timedOut) { if (timedOut) {
stepExecution.setStatus(BatchStatus.FAILED); stepExecution.setStatus(BatchStatus.FAILED);
throw new ItemStreamException("Timed out waiting for back log at end of step"); throw new ItemStreamException("Timed out waiting for back log at end of step");
} }
return ExitStatus.FINISHED.addExitDescription("Waited for " + expecting + " results."); return ExitStatus.COMPLETED.addExitDescription("Waited for " + expecting + " results.");
} }
public void close() throws ItemStreamException { public void close() throws ItemStreamException {
localState.reset(); localState.reset();
} }
public void open(ExecutionContext executionContext) throws ItemStreamException { public void open(ExecutionContext executionContext) throws ItemStreamException {
if (executionContext.containsKey(EXPECTED)) { if (executionContext.containsKey(EXPECTED)) {
localState.expected = executionContext.getLong(EXPECTED); localState.expected = executionContext.getLong(EXPECTED);
localState.actual = executionContext.getLong(ACTUAL); localState.actual = executionContext.getLong(ACTUAL);
if (!waitForResults()) { if (!waitForResults()) {
throw new ItemStreamException("Timed out waiting for back log on open"); throw new ItemStreamException("Timed out waiting for back log on open");
} }
} }
} }
public void update(ExecutionContext executionContext) throws ItemStreamException { public void update(ExecutionContext executionContext) throws ItemStreamException {
executionContext.putLong(EXPECTED, localState.expected); executionContext.putLong(EXPECTED, localState.expected);
executionContext.putLong(ACTUAL, localState.actual); executionContext.putLong(ACTUAL, localState.actual);
} }
/** /**
* Wait until all the results that are in the pipeline come back to the * Wait until all the results that are in the pipeline come back to the
* reply channel. * reply channel.
* *
* @return true if successfully received a result, false if timed out * @return true if successfully received a result, false if timed out
*/ */
private boolean waitForResults() { private boolean waitForResults() {
// TODO: cumulative timeout, or throw an exception? // TODO: cumulative timeout, or throw an exception?
int count = 0; int count = 0;
int maxCount = 40; int maxCount = 40;
while (localState.getExpecting() > 0 && count++ < maxCount) { while (localState.getExpecting() > 0 && count++ < maxCount) {
getNextResult(); getNextResult();
} }
return count < maxCount; return count < maxCount;
} }
/** /**
* Get the next result if it is available within the timeout specified, * Get the next result if it is available within the timeout specified,
* otherwise return null. * otherwise return null.
*/ */
private void getNextResult() { private void getNextResult() {
ChunkResponse payload = (ChunkResponse) messagingGateway.receive(); ChunkResponse payload = (ChunkResponse) messagingGateway.receive();
if (payload != null) { if (payload != null) {
Long jobInstanceId = payload.getJobId(); Long jobInstanceId = payload.getJobId();
Assert.state(jobInstanceId != null, "Message did not contain job instance id."); Assert.state(jobInstanceId != null, "Message did not contain job instance id.");
Assert.state(jobInstanceId.equals(localState.getJobId()), "Message contained wrong job instance id [" Assert.state(jobInstanceId.equals(localState.getJobId()), "Message contained wrong job instance id ["
+ jobInstanceId + "] should have been [" + localState.getJobId() + "]."); + jobInstanceId + "] should have been [" + localState.getJobId() + "].");
localState.actual++; localState.actual++;
// TODO: apply the skip count // TODO: apply the skip count
if (!payload.isSuccessful()) { if (!payload.isSuccessful()) {
throw new AsynchronousFailureException("Failure or interrupt detected in handler: " throw new AsynchronousFailureException("Failure or interrupt detected in handler: "
+ payload.getMessage()); + payload.getMessage());
} }
} }
} }
private static class LocalState { private static class LocalState {
private long actual; private long actual;
private long expected; private long expected;
private StepExecution stepExecution; private StepExecution stepExecution;
public long getExpecting() { public long getExpecting() {
return expected - actual; return expected - actual;
} }
public StepContribution createStepContribution() { public StepContribution createStepContribution() {
return stepExecution.createStepContribution(); return stepExecution.createStepContribution();
} }
public Long getJobId() { public Long getJobId() {
return stepExecution.getJobExecution().getJobId(); return stepExecution.getJobExecution().getJobId();
} }
public void setStepExecution(StepExecution stepExecution) { public void setStepExecution(StepExecution stepExecution) {
this.stepExecution = stepExecution; this.stepExecution = stepExecution;
} }
public void reset() { public void reset() {
expected = actual = 0; expected = actual = 0;
} }
} }
} }

View File

@@ -116,7 +116,7 @@ public class MessageOrientedStep extends AbstractStep {
waitForReply(request.getJobId()); waitForReply(request.getJobId());
} }
stepExecution.setExitStatus(ExitStatus.FINISHED); stepExecution.setExitStatus(ExitStatus.COMPLETED);
} }

View File

@@ -32,7 +32,7 @@ public class TestTasklet implements Tasklet {
* *
*/ */
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
contribution.setExitStatus(ExitStatus.FINISHED); contribution.setExitStatus(ExitStatus.COMPLETED);
return RepeatStatus.FINISHED; return RepeatStatus.FINISHED;
} }

View File

@@ -1,19 +1,19 @@
package org.springframework.batch.sample.common; package org.springframework.batch.sample.common;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.job.flow.support.state.JobExecutionDecider; import org.springframework.batch.core.job.flow.support.state.JobExecutionDecider;
public class SkipCheckingDecider implements JobExecutionDecider { public class SkipCheckingDecider implements JobExecutionDecider {
public String decide(JobExecution jobExecution, StepExecution stepExecution) { public String decide(JobExecution jobExecution, StepExecution stepExecution) {
if (!stepExecution.getExitStatus().getExitCode().equals( if (!stepExecution.getExitStatus().getExitCode().equals(
ExitStatus.FAILED.getExitCode()) ExitStatus.FAILED.getExitCode())
&& stepExecution.getSkipCount() > 0) { && stepExecution.getSkipCount() > 0) {
return "COMPLETED WITH SKIPS"; return "COMPLETED WITH SKIPS";
} else { } else {
return ExitStatus.FINISHED.getExitCode(); return ExitStatus.COMPLETED.getExitCode();
} }
} }
} }