RESOLVED - BATCH-1026: Rename ExitStatus.FINISHED to ExitStatus.COMPLETED
This commit is contained in:
@@ -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)) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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"));
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ public class MessageOrientedStep extends AbstractStep {
|
|||||||
waitForReply(request.getJobId());
|
waitForReply(request.getJobId());
|
||||||
}
|
}
|
||||||
|
|
||||||
stepExecution.setExitStatus(ExitStatus.FINISHED);
|
stepExecution.setExitStatus(ExitStatus.COMPLETED);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user