First attempt at adding more explicit skip handling and removing the need for 'SimpleStepExecutor'. There's still some cleanup that needs to happen, but it's moving in the right direction.
This commit is contained in:
@@ -15,16 +15,16 @@
|
||||
*/
|
||||
package org.springframework.batch.execution.step.simple;
|
||||
|
||||
import org.springframework.batch.core.domain.ItemFailureHandler;
|
||||
import org.springframework.batch.core.domain.ItemSkipPolicy;
|
||||
import org.springframework.batch.core.domain.JobInterruptedException;
|
||||
import org.springframework.batch.core.domain.Step;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.core.domain.JobInterruptedException;
|
||||
import org.springframework.batch.core.domain.StepSupport;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemRecoverer;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.stream.SimpleStreamManager;
|
||||
import org.springframework.batch.item.stream.StreamManager;
|
||||
import org.springframework.batch.repeat.exception.handler.ExceptionHandler;
|
||||
import org.springframework.batch.retry.RetryPolicy;
|
||||
@@ -42,21 +42,23 @@ public abstract class AbstractStep extends StepSupport implements InitializingBe
|
||||
|
||||
private int skipLimit = 0;
|
||||
|
||||
private ExceptionHandler exceptionHandler;
|
||||
protected ExceptionHandler exceptionHandler;
|
||||
|
||||
private RetryPolicy retryPolicy;
|
||||
protected RetryPolicy retryPolicy;
|
||||
|
||||
private JobRepository jobRepository;
|
||||
protected JobRepository jobRepository;
|
||||
|
||||
private PlatformTransactionManager transactionManager;
|
||||
protected PlatformTransactionManager transactionManager;
|
||||
|
||||
private StreamManager streamManager;
|
||||
protected StreamManager streamManager;
|
||||
|
||||
private ItemReader itemReader;
|
||||
protected ItemReader itemReader;
|
||||
|
||||
private ItemWriter itemWriter;
|
||||
|
||||
private ItemRecoverer itemRecoverer;
|
||||
protected ItemWriter itemWriter;
|
||||
|
||||
protected ItemSkipPolicy itemSkipPolicy = new NeverSkipItemSkipPolicy();
|
||||
|
||||
protected ItemFailureHandler itemFailureHandler = new DefaultItemFailureHandler();
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
@@ -147,11 +149,20 @@ public abstract class AbstractStep extends StepSupport implements InitializingBe
|
||||
this.itemWriter = itemWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param itemRecoverer the itemRecoverer to set
|
||||
*/
|
||||
public void setItemRecoverer(ItemRecoverer itemRecoverer) {
|
||||
this.itemRecoverer = itemRecoverer;
|
||||
public void setItemSkipPolicy(ItemSkipPolicy itemSkipPolicy) {
|
||||
this.itemSkipPolicy = itemSkipPolicy;
|
||||
}
|
||||
|
||||
public ItemSkipPolicy getItemSkipPolicy() {
|
||||
return itemSkipPolicy;
|
||||
}
|
||||
|
||||
public void setItemFailureHandler(ItemFailureHandler itemFailureHandler) {
|
||||
this.itemFailureHandler = itemFailureHandler;
|
||||
}
|
||||
|
||||
public ItemFailureHandler getItemFailureHandler() {
|
||||
return itemFailureHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,36 +185,5 @@ public abstract class AbstractStep extends StepSupport implements InitializingBe
|
||||
|
||||
}
|
||||
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException, BatchCriticalException {
|
||||
SimpleStepExecutor executor = createStepExecutor();
|
||||
executor.execute(stepExecution);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a {@link SimpleStepExecutor} that can be used to launch the job.
|
||||
* @throws BatchCriticalException
|
||||
*/
|
||||
protected SimpleStepExecutor createStepExecutor() throws BatchCriticalException {
|
||||
assertMandatoryProperties();
|
||||
// Do not set the streamManager field if it is null, otherwise
|
||||
// the mandatory properties check will fail.
|
||||
StreamManager manager = streamManager;
|
||||
if (streamManager == null) {
|
||||
manager = new SimpleStreamManager(transactionManager);
|
||||
}
|
||||
SimpleStepExecutor executor = new SimpleStepExecutor(this);
|
||||
executor.setItemReader(itemReader);
|
||||
executor.setItemWriter(itemWriter);
|
||||
executor.setItemRecoverer(itemRecoverer);
|
||||
executor.setRepository(jobRepository);
|
||||
executor.setRetryPolicy(retryPolicy);
|
||||
executor.setStreamManager(manager);
|
||||
try {
|
||||
executor.afterPropertiesSet();
|
||||
} catch (Exception e) {
|
||||
throw new BatchCriticalException(e);
|
||||
}
|
||||
executor.applyConfiguration(this);
|
||||
return executor;
|
||||
}
|
||||
public abstract void execute(StepExecution stepExecution) throws JobInterruptedException, BatchCriticalException;
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
package org.springframework.batch.execution.step.simple;
|
||||
|
||||
import org.springframework.batch.core.domain.ItemSkipPolicy;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link ItemSkipPolicy} interface that
|
||||
@@ -27,7 +27,7 @@ import org.springframework.batch.core.domain.StepExecution;
|
||||
*/
|
||||
public class AlwaysSkipItemSkipPolicy implements ItemSkipPolicy {
|
||||
|
||||
public boolean shouldSkip(Exception ex, StepExecution stepExecution) {
|
||||
public boolean shouldSkip(Exception ex, StepContribution stepContribution) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.batch.execution.step.simple;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -25,10 +26,10 @@ import org.springframework.batch.core.domain.Chunker;
|
||||
import org.springframework.batch.core.domain.ChunkingResult;
|
||||
import org.springframework.batch.core.domain.Dechunker;
|
||||
import org.springframework.batch.core.domain.DechunkingResult;
|
||||
import org.springframework.batch.core.domain.ItemFailureHandler;
|
||||
import org.springframework.batch.core.domain.ItemSkipPolicy;
|
||||
import org.springframework.batch.core.domain.JobInstance;
|
||||
import org.springframework.batch.core.domain.JobInterruptedException;
|
||||
import org.springframework.batch.core.domain.SkippedItemHandler;
|
||||
import org.springframework.batch.core.domain.Step;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
@@ -40,6 +41,7 @@ import org.springframework.batch.execution.scope.StepContext;
|
||||
import org.springframework.batch.execution.scope.StepScope;
|
||||
import org.springframework.batch.execution.scope.StepSynchronizationManager;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.io.exception.WriteFailureException;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
@@ -69,7 +71,7 @@ import org.springframework.util.Assert;
|
||||
* {@link Chunk} of items for processing. The number of items per chunks is
|
||||
* configurable as the chunk size. Once the chunk has been read, any errors
|
||||
* encountered while reading (usually skipped unless configured not to) will be
|
||||
* logged out via the {@link SkippedItemHandler}. The chunk will then be
|
||||
* logged out via the {@link ItemFailureHandler}. The chunk will then be
|
||||
* 'dechunked', which in most scenarios will mean delegating to an
|
||||
* {@link ItemWriter} by writing out one chunk at a time. The transaction
|
||||
* boundary is around this process. If any errors are encountered, the
|
||||
@@ -78,7 +80,7 @@ import org.springframework.util.Assert;
|
||||
* allowing for the number of retries and how long to wait between retries
|
||||
* (backoff) to be set. Once dechunking has been finished, any errors not fatal
|
||||
* to the chunk (usually because the error didn't invalidate the transaction)
|
||||
* will also be written out via the {@link SkippedItemHandler}
|
||||
* will also be written out via the {@link ItemFailureHandler}
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
@@ -134,7 +136,7 @@ public class ChunkedStep extends StepSupport implements InitializingBean {
|
||||
// default to checking current thread for interruption.
|
||||
private StepInterruptionPolicy interruptionPolicy = new ThreadStepInterruptionPolicy();
|
||||
|
||||
private SkippedItemHandler failureLog = new DefaultItemFailureLog();
|
||||
private ItemFailureHandler failureLog = new DefaultItemFailureHandler();
|
||||
|
||||
private StreamManager streamManager;
|
||||
|
||||
@@ -173,7 +175,7 @@ public class ChunkedStep extends StepSupport implements InitializingBean {
|
||||
this.streamManager = streamManager;
|
||||
}
|
||||
|
||||
public void setFailureLog(SkippedItemHandler failureLog) {
|
||||
public void setFailureLog(ItemFailureHandler failureLog) {
|
||||
this.failureLog = failureLog;
|
||||
}
|
||||
|
||||
@@ -445,18 +447,23 @@ public class ChunkedStep extends StepSupport implements InitializingBean {
|
||||
try {
|
||||
|
||||
ChunkingResult chunkingResult = chunker.chunk(chunkSize,
|
||||
stepExecution);
|
||||
contribution);
|
||||
|
||||
if (chunkingResult == null) {
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
|
||||
final Chunk chunk = chunkingResult.getChunk();
|
||||
failureLog.handle(chunkingResult.getExceptions());
|
||||
for(Iterator it = chunkingResult.getExceptions().iterator();it.hasNext();){
|
||||
failureLog.handleReadFailure((Exception)it.next());
|
||||
}
|
||||
|
||||
DechunkingResult dechunkingResult = dechunker.dechunk(chunk,
|
||||
stepExecution);
|
||||
failureLog.handle(dechunkingResult.getExceptions());
|
||||
contribution);
|
||||
for(Iterator it = dechunkingResult.getExceptions().iterator(); it.hasNext();){
|
||||
WriteFailureException exception = (WriteFailureException)it.next();
|
||||
failureLog.handleWriteFailure(exception.getItem(), (Exception)exception.getCause());
|
||||
}
|
||||
|
||||
// TODO: check that stepExecution can
|
||||
// aggregate these contributions if they
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.execution.step.simple;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.core.domain.ItemFailureHandler;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link ItemFailureHandler} interface that
|
||||
* writes all exceptions via commons logging. Since generics can't be used to
|
||||
* ensure the list contains exceptions, any non exceptions will be logged out by
|
||||
* calling toString on the object.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class DefaultItemFailureHandler implements ItemFailureHandler {
|
||||
|
||||
protected static final Log logger = LogFactory
|
||||
.getLog(DefaultItemFailureHandler.class);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.batch.core.domain.ItemFailureLog#log(java.util.List)
|
||||
*/
|
||||
public void handleReadFailure(Exception ex) {
|
||||
try {
|
||||
logger.error("Error encountered while reading", ex);
|
||||
} catch (Exception exception) {
|
||||
logger.error("Invalid type for logging: [" + exception.toString()
|
||||
+ "]");
|
||||
}
|
||||
}
|
||||
|
||||
public void handleWriteFailure(Object item, Exception ex) {
|
||||
try {
|
||||
logger.error("Error encountered while writing item: [ " + item + "]", ex);
|
||||
} catch (Exception exception) {
|
||||
logger.error("Invalid type for logging: [" + exception.toString()
|
||||
+ "]");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.execution.step.simple;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.core.domain.SkippedItemHandler;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link SkippedItemHandler} interface that
|
||||
* writes all exceptions via commons logging. Since generics can't be
|
||||
* used to ensure the list contains exceptions, any non exceptions will
|
||||
* be logged out by calling toString on the object.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class DefaultItemFailureLog implements SkippedItemHandler {
|
||||
|
||||
protected static final Log logger = LogFactory
|
||||
.getLog(DefaultItemFailureLog.class);
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.domain.ItemFailureLog#log(java.util.List)
|
||||
*/
|
||||
public void handle(List exceptions) {
|
||||
for(Iterator it = exceptions.iterator(); it.hasNext();){
|
||||
Object exception = it.next();
|
||||
try{
|
||||
Throwable t = (Throwable)exception;
|
||||
logger.error("Error encountered during processing", t);
|
||||
}
|
||||
catch(Exception ex){
|
||||
logger.error("Invalid type for logging: [" + exception.toString() + "]");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import org.springframework.batch.core.domain.Chunk;
|
||||
import org.springframework.batch.core.domain.Chunker;
|
||||
import org.springframework.batch.core.domain.ChunkingResult;
|
||||
import org.springframework.batch.core.domain.ItemSkipPolicy;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.io.exception.ReadFailureException;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
@@ -56,7 +57,7 @@ public class ItemChunker implements Chunker {
|
||||
this.itemSkipPolicy = itemSkipPolicy;
|
||||
}
|
||||
|
||||
public ChunkingResult chunk(int size, StepExecution stepExecution) throws ReadFailureException {
|
||||
public ChunkingResult chunk(int size, StepContribution stepContribution) throws ReadFailureException {
|
||||
Assert.isTrue(size > 0, "Chunk size must be greater than 0");
|
||||
|
||||
int counter = 0;
|
||||
@@ -74,7 +75,7 @@ public class ItemChunker implements Chunker {
|
||||
counter++;
|
||||
} catch (Exception ex) {
|
||||
exceptions.add(ex);
|
||||
if(!itemSkipPolicy.shouldSkip(ex, stepExecution)){
|
||||
if(!itemSkipPolicy.shouldSkip(ex, stepContribution)){
|
||||
rethrow(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.springframework.batch.core.domain.Chunk;
|
||||
import org.springframework.batch.core.domain.DechunkingResult;
|
||||
import org.springframework.batch.core.domain.Dechunker;
|
||||
import org.springframework.batch.core.domain.ItemSkipPolicy;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
import org.springframework.batch.io.exception.WriteFailureException;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
@@ -52,10 +52,10 @@ public class ItemDechunker implements Dechunker {
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.domain.Dechunker#dechunk(org.springframework.batch.core.domain.Chunk)
|
||||
*/
|
||||
public DechunkingResult dechunk(Chunk chunk, StepExecution stepExecution) throws Exception {
|
||||
public DechunkingResult dechunk(Chunk chunk, StepContribution stepContribution) throws Exception {
|
||||
|
||||
Assert.notNull(chunk, "Chunk must not be null");
|
||||
Assert.notNull(stepExecution, "StepExecution must not be null");
|
||||
Assert.notNull(stepContribution, "StepExecution must not be null");
|
||||
List skippedItems = new ArrayList();
|
||||
for(Iterator it = chunk.getItems().iterator(); it.hasNext();){
|
||||
|
||||
@@ -64,8 +64,8 @@ public class ItemDechunker implements Dechunker {
|
||||
itemWriter.write(item);
|
||||
}
|
||||
catch(Exception ex){
|
||||
if(itemSkipPolicy.shouldSkip(ex, stepExecution)){
|
||||
stepExecution.incrementSkipCount();
|
||||
if(itemSkipPolicy.shouldSkip(ex, stepContribution)){
|
||||
stepContribution.incrementSkipCount();
|
||||
skippedItems.add(new WriteFailureException(ex, item));
|
||||
}
|
||||
else{
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.core.domain.BatchStatus;
|
||||
import org.springframework.batch.core.domain.JobInstance;
|
||||
import org.springframework.batch.core.domain.JobInterruptedException;
|
||||
import org.springframework.batch.core.domain.Step;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
@@ -42,7 +41,6 @@ import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.exception.ResetFailedException;
|
||||
import org.springframework.batch.item.stream.SimpleStreamManager;
|
||||
import org.springframework.batch.item.stream.StreamManager;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatCallback;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
@@ -79,67 +77,26 @@ import org.springframework.util.Assert;
|
||||
* @author Lucas Ward
|
||||
* @author Ben Hale
|
||||
*/
|
||||
public class SimpleStepExecutor implements InitializingBean {
|
||||
public class ItemOrientedStep extends AbstractStep implements InitializingBean {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SimpleStepExecutor.class);
|
||||
private static final Log logger = LogFactory.getLog(ItemOrientedStep.class);
|
||||
|
||||
private RepeatOperations chunkOperations = new RepeatTemplate();
|
||||
|
||||
private RepeatOperations stepOperations = new RepeatTemplate();
|
||||
|
||||
private JobRepository jobRepository;
|
||||
|
||||
private ExitStatusExceptionClassifier exceptionClassifier = new SimpleExitStatusExceptionClassifier();
|
||||
|
||||
// default to checking current thread for interruption.
|
||||
private StepInterruptionPolicy interruptionPolicy = new ThreadStepInterruptionPolicy();
|
||||
|
||||
private AbstractStep step;
|
||||
|
||||
private StreamManager streamManager;
|
||||
|
||||
private ItemReader itemReader;
|
||||
|
||||
private ItemWriter itemWriter;
|
||||
|
||||
private RetryPolicy retryPolicy = null;
|
||||
|
||||
private ItemRecoverer itemRecoverer;
|
||||
|
||||
private RetryTemplate template = new RetryTemplate();
|
||||
|
||||
private ItemReaderRetryCallback retryCallback;
|
||||
|
||||
/**
|
||||
* Package private constructor so the step can create a the executor.
|
||||
*/
|
||||
SimpleStepExecutor(AbstractStep abstractStep) {
|
||||
this.step = abstractStep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the {@link StreamManager}. This will be used to create
|
||||
* the {@link StepContext}, and hence any component that is a
|
||||
* {@link ItemStream} and in step scope will be registered with the service.
|
||||
* The {@link StepContext} is then a source of aggregate statistics for the
|
||||
* step.
|
||||
*
|
||||
* @param streamManager the {@link StreamManager} to set. Default is a
|
||||
* {@link SimpleStreamManager}.
|
||||
*/
|
||||
public void setStreamManager(StreamManager streamManager) {
|
||||
this.streamManager = streamManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injected strategy for storage and retrieval of persistent step
|
||||
* information. Mandatory property.
|
||||
*
|
||||
* @param jobRepository
|
||||
*/
|
||||
public void setRepository(JobRepository jobRepository) {
|
||||
this.jobRepository = jobRepository;
|
||||
}
|
||||
|
||||
private int commitInterval = 0;
|
||||
|
||||
/**
|
||||
* The {@link RepeatOperations} to use for the outer loop of the batch
|
||||
@@ -184,29 +141,6 @@ public class SimpleStepExecutor implements InitializingBean {
|
||||
this.exceptionClassifier = exceptionClassifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param itemReader
|
||||
*/
|
||||
public void setItemReader(ItemReader itemReader) {
|
||||
this.itemReader = itemReader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param itemWriter
|
||||
*/
|
||||
public void setItemWriter(ItemWriter itemWriter) {
|
||||
this.itemWriter = itemWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for injecting optional recovery handler.
|
||||
*
|
||||
* @param itemRecoverer
|
||||
*/
|
||||
public void setItemRecoverer(ItemRecoverer itemRecoverer) {
|
||||
this.itemRecoverer = itemRecoverer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the retryPolicy.
|
||||
*
|
||||
@@ -215,6 +149,10 @@ public class SimpleStepExecutor implements InitializingBean {
|
||||
public void setRetryPolicy(RetryPolicy retryPolicy) {
|
||||
this.retryPolicy = retryPolicy;
|
||||
}
|
||||
|
||||
public void setCommitInterval(int commitInterval) {
|
||||
this.commitInterval = commitInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check mandatory properties (reader and writer).
|
||||
@@ -225,10 +163,6 @@ public class SimpleStepExecutor implements InitializingBean {
|
||||
Assert.notNull(itemReader, "ItemReader must be provided");
|
||||
Assert.notNull(itemWriter, "ItemWriter must be provided");
|
||||
|
||||
if (itemRecoverer == null && (itemReader instanceof ItemRecoverer)) {
|
||||
itemRecoverer = (ItemRecoverer) itemReader;
|
||||
}
|
||||
|
||||
ItemReaderRetryPolicy itemProviderRetryPolicy = new ItemReaderRetryPolicy(retryPolicy);
|
||||
template.setRetryPolicy(itemProviderRetryPolicy);
|
||||
|
||||
@@ -236,9 +170,22 @@ public class SimpleStepExecutor implements InitializingBean {
|
||||
Assert.state(itemReader instanceof KeyedItemReader,
|
||||
"ItemReader must be instance of KeyedItemReader to use the retry policy");
|
||||
retryCallback = new ItemReaderRetryCallback((KeyedItemReader) itemReader, itemWriter);
|
||||
retryCallback.setRecoverer(itemRecoverer);
|
||||
}
|
||||
|
||||
|
||||
if(streamManager == null && transactionManager != null){
|
||||
streamManager = new SimpleStreamManager(transactionManager);
|
||||
}
|
||||
else if(streamManager == null && transactionManager == null){
|
||||
throw new IllegalArgumentException("Either StreamManager or TransactionManager must be set");
|
||||
}
|
||||
|
||||
if(commitInterval > 0){
|
||||
((RepeatTemplate)chunkOperations).setCompletionPolicy(new SimpleCompletionPolicy(commitInterval));
|
||||
}
|
||||
|
||||
if(exceptionHandler != null){
|
||||
((RepeatTemplate)chunkOperations).setExceptionHandler(exceptionHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,7 +260,7 @@ public class SimpleStepExecutor implements InitializingBean {
|
||||
// the conversation in StepScope
|
||||
stepContext.setAttribute(StepScope.ID_KEY, stepExecution.getJobExecution().getId());
|
||||
|
||||
final boolean saveExecutionContext = step.isSaveExecutionContext();
|
||||
final boolean saveExecutionContext = isSaveExecutionContext();
|
||||
|
||||
streamManager.open(stepExecution);
|
||||
|
||||
@@ -338,13 +285,19 @@ public class SimpleStepExecutor implements InitializingBean {
|
||||
|
||||
try {
|
||||
|
||||
result = processChunk(step, contribution);
|
||||
result = processChunk(contribution);
|
||||
|
||||
// TODO: check that stepExecution can
|
||||
// aggregate these contributions if they
|
||||
// come in asynchronously.
|
||||
ExecutionContext statistics = streamManager.getExecutionContext(stepExecution);
|
||||
contribution.setExecutionContext(statistics);
|
||||
ExecutionContext statistics;
|
||||
if(isSaveExecutionContext()){
|
||||
statistics = streamManager.getExecutionContext(stepExecution);
|
||||
contribution.setExecutionContext(statistics);
|
||||
}
|
||||
else{
|
||||
statistics = new ExecutionContext();
|
||||
}
|
||||
contribution.incrementCommitCount();
|
||||
|
||||
// If the step operations are asynchronous then we need
|
||||
@@ -475,7 +428,7 @@ public class SimpleStepExecutor implements InitializingBean {
|
||||
* business logic.
|
||||
* @return true if there is more data to process.
|
||||
*/
|
||||
ExitStatus processChunk(final Step step, final StepContribution contribution) {
|
||||
ExitStatus processChunk(final StepContribution contribution) {
|
||||
ExitStatus result = chunkOperations.iterate(new RepeatCallback() {
|
||||
public ExitStatus doInIteration(final RepeatContext context) throws Exception {
|
||||
if (contribution.isTerminateOnly()) {
|
||||
@@ -515,10 +468,13 @@ public class SimpleStepExecutor implements InitializingBean {
|
||||
|
||||
}
|
||||
catch (Exception e) {
|
||||
skip();
|
||||
// Rethrow so that outer transaction is rolled back properly
|
||||
throw e;
|
||||
|
||||
if(getItemSkipPolicy().shouldSkip(e, contribution)){
|
||||
skip();
|
||||
}
|
||||
else{
|
||||
// Rethrow so that outer transaction is rolled back properly
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
return exitStatus;
|
||||
@@ -541,7 +497,14 @@ public class SimpleStepExecutor implements InitializingBean {
|
||||
private ExitStatus execute() throws Exception {
|
||||
|
||||
if (retryCallback == null) {
|
||||
Object item = itemReader.read();
|
||||
Object item = null;
|
||||
try{
|
||||
item = itemReader.read();
|
||||
}
|
||||
catch(Exception ex){
|
||||
getItemFailureHandler().handleReadFailure(ex);
|
||||
throw ex;
|
||||
}
|
||||
if (item == null) {
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
@@ -549,9 +512,8 @@ public class SimpleStepExecutor implements InitializingBean {
|
||||
itemWriter.write(item);
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (itemRecoverer != null) {
|
||||
itemRecoverer.recover(item, e);
|
||||
}
|
||||
|
||||
getItemFailureHandler().handleWriteFailure(item, e);
|
||||
// Re-throw the exception so that the surrounding transaction
|
||||
// rolls back if there is one
|
||||
throw e;
|
||||
@@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.core.domain.ItemSkipPolicy;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.io.exception.FlatFileParsingException;
|
||||
|
||||
@@ -64,10 +65,10 @@ public class LimitCheckingItemSkipPolicy implements ItemSkipPolicy {
|
||||
* is greater than the skipLimit, then a {@link SkipLimitExceededException}
|
||||
* will be thrown.
|
||||
*/
|
||||
public boolean shouldSkip(Exception ex, StepExecution stepExecution){
|
||||
public boolean shouldSkip(Exception ex, StepContribution stepContribution){
|
||||
if(skippableExceptions.contains(ex.getClass())){
|
||||
if(stepExecution.getSkipCount() < skipLimit){
|
||||
stepExecution.incrementSkipCount();
|
||||
if(stepContribution.getSkipCount() < skipLimit){
|
||||
stepContribution.incrementSkipCount();
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package org.springframework.batch.execution.step.simple;
|
||||
|
||||
import org.springframework.batch.core.domain.ItemSkipPolicy;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
|
||||
/**
|
||||
* {@link ItemSkipPolicy} implementation that always returns false,
|
||||
@@ -26,7 +26,7 @@ import org.springframework.batch.core.domain.StepExecution;
|
||||
*/
|
||||
public class NeverSkipItemSkipPolicy implements ItemSkipPolicy{
|
||||
|
||||
public boolean shouldSkip(Exception ex, StepExecution stepExecution) {
|
||||
public boolean shouldSkip(Exception ex, StepContribution stepContribution) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,16 +21,20 @@ import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.core.domain.JobInterruptedException;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.repeat.RepeatOperations;
|
||||
import org.springframework.batch.repeat.support.RepeatTemplate;
|
||||
|
||||
/**
|
||||
* {@link Step} implementation that allows full step of the
|
||||
* {@link RepeatOperations} that will be used in the chunk (inner loop).
|
||||
*
|
||||
* This class will likely not be necessary given current changes, however, it
|
||||
* is calling super classes for compatibility.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
* @author Dave Syer
|
||||
* @author Ben Hale
|
||||
*/
|
||||
public class RepeatOperationsStep extends AbstractStep implements RepeatOperationsHolder {
|
||||
public class RepeatOperationsStep extends ItemOrientedStep implements RepeatOperationsHolder {
|
||||
|
||||
private volatile RepeatOperations chunkOperations;
|
||||
|
||||
@@ -73,14 +77,12 @@ public class RepeatOperationsStep extends AbstractStep implements RepeatOperatio
|
||||
}
|
||||
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException, BatchCriticalException {
|
||||
assertMandatoryProperties();
|
||||
SimpleStepExecutor executor = (SimpleStepExecutor) super.createStepExecutor();
|
||||
if (stepOperations != null) {
|
||||
executor.setStepOperations(stepOperations);
|
||||
super.setStepOperations(stepOperations);
|
||||
}
|
||||
if (chunkOperations != null) {
|
||||
executor.setChunkOperations(chunkOperations);
|
||||
super.setChunkOperations(chunkOperations);
|
||||
}
|
||||
executor.execute(stepExecution);
|
||||
super.execute(stepExecution);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
|
||||
package org.springframework.batch.execution.step.simple;
|
||||
|
||||
import org.springframework.batch.core.domain.JobInterruptedException;
|
||||
import org.springframework.batch.core.domain.Step;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
|
||||
/**
|
||||
* Simple {@link Step} good enough for most purposes and easy to configure simple properties, principally the commit
|
||||
@@ -47,4 +50,10 @@ public class SimpleStep extends AbstractStep {
|
||||
return commitInterval;
|
||||
}
|
||||
|
||||
public void execute(StepExecution stepExecution)
|
||||
throws JobInterruptedException, BatchCriticalException {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot process a StepExecution. Use a smarter subclass of StepSupport.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.domain.BatchStatus;
|
||||
import org.springframework.batch.core.domain.ItemFailureHandler;
|
||||
import org.springframework.batch.core.domain.JobExecution;
|
||||
import org.springframework.batch.core.domain.JobInstance;
|
||||
import org.springframework.batch.core.domain.JobParameters;
|
||||
@@ -81,13 +82,13 @@ public class SimpleJobTests extends TestCase {
|
||||
List items = TransactionAwareProxyFactory.createTransactionalList();
|
||||
items.addAll(Arrays.asList(args));
|
||||
provider = new ListItemReader(items);
|
||||
step.setItemRecoverer(new ItemRecoverer() {
|
||||
public boolean recover(Object item, Throwable cause) {
|
||||
recovered.add(item);
|
||||
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
// step.setItemRecoverer(new ItemRecoverer() {
|
||||
// public boolean recover(Object item, Throwable cause) {
|
||||
// recovered.add(item);
|
||||
// assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
|
||||
// return true;
|
||||
// }
|
||||
// });
|
||||
step.setItemReader(provider);
|
||||
step.setItemWriter(processor);
|
||||
step.setJobRepository(repository);
|
||||
@@ -144,6 +145,17 @@ public class SimpleJobTests extends TestCase {
|
||||
throw new RuntimeException("Error!");
|
||||
}
|
||||
});
|
||||
step.setItemFailureHandler(new ItemFailureHandler(){
|
||||
|
||||
public void handleReadFailure(Exception ex) {
|
||||
recovered.add(ex);
|
||||
}
|
||||
|
||||
public void handleWriteFailure(Object item, Exception ex) {
|
||||
recovered.add(ex);
|
||||
}
|
||||
|
||||
});
|
||||
step.afterPropertiesSet();
|
||||
job.setSteps(Collections.singletonList(step));
|
||||
|
||||
|
||||
@@ -0,0 +1,564 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.execution.step.simple;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.core.domain.BatchStatus;
|
||||
import org.springframework.batch.core.domain.JobExecution;
|
||||
import org.springframework.batch.core.domain.JobInstance;
|
||||
import org.springframework.batch.core.domain.JobParameters;
|
||||
import org.springframework.batch.core.domain.JobSupport;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.execution.scope.StepScope;
|
||||
import org.springframework.batch.execution.scope.StepSynchronizationManager;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.batch.item.reader.ListItemReader;
|
||||
import org.springframework.batch.item.stream.ItemStreamAdapter;
|
||||
import org.springframework.batch.item.stream.SimpleStreamManager;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.interceptor.RepeatListenerAdapter;
|
||||
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
|
||||
import org.springframework.batch.repeat.support.RepeatTemplate;
|
||||
import org.springframework.batch.support.PropertiesConverter;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class ChunkedStepTests extends TestCase {
|
||||
|
||||
ArrayList processed = new ArrayList();
|
||||
|
||||
ItemWriter processor = new AbstractItemWriter() {
|
||||
public void write(Object data) throws Exception {
|
||||
processed.add((String) data);
|
||||
}
|
||||
};
|
||||
|
||||
private ChunkedStep chunkedStep;
|
||||
|
||||
private JobInstance jobInstance;
|
||||
|
||||
private ResourcelessTransactionManager transactionManager;
|
||||
|
||||
private JobExecution jobExecutionContext;
|
||||
private StepExecution stepExecution;
|
||||
|
||||
private ItemReader getReader(String[] args) {
|
||||
return new ListItemReader(Arrays.asList(args));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private ChunkedStep getStep(String[] strings) throws Exception {
|
||||
ChunkedStep step = new ChunkedStep();
|
||||
step.setItemWriter(processor);
|
||||
step.setItemReader(getReader(strings));
|
||||
step.setJobRepository(new JobRepositorySupport());
|
||||
step.setStreamManager(new SimpleStreamManager(transactionManager));
|
||||
step.afterPropertiesSet();
|
||||
return step;
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
transactionManager = new ResourcelessTransactionManager();
|
||||
chunkedStep = getStep(new String[] { "foo", "bar", "spam" });
|
||||
|
||||
// Only process one item:
|
||||
chunkedStep.setChunkSize(1);
|
||||
|
||||
jobInstance = new JobInstance(new Long(0), new JobParameters());
|
||||
jobInstance.setJob(new JobSupport("FOO"));
|
||||
|
||||
SimpleStreamManager streamManager = new SimpleStreamManager(transactionManager);
|
||||
streamManager.setUseClassNameAsPrefix(false);
|
||||
chunkedStep.setStreamManager(streamManager);
|
||||
chunkedStep.setJobRepository(new JobRepositorySupport());
|
||||
|
||||
jobExecutionContext = new JobExecution(jobInstance);
|
||||
stepExecution = new StepExecution("testStep", jobExecutionContext);
|
||||
}
|
||||
|
||||
public void testStepExecutor() throws Exception {
|
||||
|
||||
chunkedStep.execute(stepExecution);
|
||||
assertEquals(3, processed.size());
|
||||
assertEquals(stepExecution.getStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
|
||||
public void testStepContextInitialized() throws Exception {
|
||||
|
||||
final JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
final StepExecution stepExecution = new StepExecution("testStep", jobExecution);
|
||||
|
||||
chunkedStep.setChunker(new ItemChunker(new ItemReader() {
|
||||
int counter = 0;
|
||||
public Object read() throws Exception {
|
||||
assertNotNull(StepSynchronizationManager.getContext().getStepExecution());
|
||||
if(counter++ < 2){
|
||||
return "foo";
|
||||
}
|
||||
else{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
chunkedStep.execute(stepExecution);
|
||||
assertEquals(2, processed.size());
|
||||
}
|
||||
|
||||
public void testStepContextInitializedBeforeTasklet() throws Exception {
|
||||
|
||||
RepeatTemplate template = new RepeatTemplate();
|
||||
|
||||
// Only process one chunk:
|
||||
template.setCompletionPolicy(new SimpleCompletionPolicy(1));
|
||||
chunkedStep.setStepOperations(template);
|
||||
|
||||
final JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
jobExecution.setId(new Long(1));
|
||||
final StepExecution stepExecution = new StepExecution("testStep", jobExecution);
|
||||
|
||||
template.setListener(new RepeatListenerAdapter() {
|
||||
public void open(RepeatContext context) {
|
||||
assertNotNull(StepSynchronizationManager.getContext().getStepExecution());
|
||||
assertEquals(stepExecution, StepSynchronizationManager.getContext().getStepExecution());
|
||||
// StepScope can obtain id information....
|
||||
assertNotNull(StepSynchronizationManager.getContext().getAttribute(StepScope.ID_KEY));
|
||||
}
|
||||
});
|
||||
|
||||
chunkedStep.execute(stepExecution);
|
||||
assertEquals(1, processed.size());
|
||||
|
||||
}
|
||||
|
||||
public void testRepository() throws Exception {
|
||||
|
||||
MockControl repoControl = MockControl.createControl(JobRepository.class);
|
||||
JobRepository repository = (JobRepository)repoControl.getMock();
|
||||
chunkedStep.setJobRepository(repository);
|
||||
|
||||
// StepInstance step = new StepInstance(new Long(1));
|
||||
// JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
// StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
|
||||
repository.getLastStepExecution(jobInstance, "testStep");
|
||||
repoControl.setReturnValue(new StepExecution(null,null));
|
||||
repository.getStepExecutionCount(jobInstance, "testStep");
|
||||
repoControl.setReturnValue(0);
|
||||
repository.saveOrUpdate(stepExecution);
|
||||
repository.saveOrUpdate(stepExecution);
|
||||
repository.saveOrUpdate(stepExecution);
|
||||
repository.saveOrUpdate(stepExecution);
|
||||
repository.saveOrUpdate(stepExecution);
|
||||
repository.saveOrUpdate(stepExecution);
|
||||
repoControl.replay();
|
||||
chunkedStep.execute(stepExecution);
|
||||
assertEquals(3, processed.size());
|
||||
repoControl.verify();
|
||||
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
|
||||
}
|
||||
|
||||
//ReadFailures (meaning an item couldn't be skipped) should cause the job to
|
||||
//fail.
|
||||
public void testReadFailure() {
|
||||
|
||||
ItemReader itemReader = new ItemReader() {
|
||||
int counter = 0;
|
||||
public Object read() throws Exception {
|
||||
|
||||
counter++;
|
||||
|
||||
if (counter > 1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
return "foo";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
chunkedStep.setChunker(new ItemChunker(itemReader));
|
||||
|
||||
try {
|
||||
chunkedStep.execute(stepExecution);
|
||||
fail();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
assertEquals( 1, processed.size());
|
||||
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testWriterFailure(){
|
||||
|
||||
ItemWriter itemWriter = new ItemWriter(){
|
||||
public void write(Object item) throws Exception {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
};
|
||||
|
||||
chunkedStep.setDechunker(new ItemDechunker(itemWriter));
|
||||
|
||||
try{
|
||||
chunkedStep.execute(stepExecution);
|
||||
fail();
|
||||
}
|
||||
catch(Exception ex){
|
||||
//it should rollback three times since that's default behavior for a retry template.
|
||||
assertEquals(new Integer(1), stepExecution.getRollbackCount());
|
||||
}
|
||||
}
|
||||
|
||||
public void testExitCodeDefaultClassification() throws Exception {
|
||||
|
||||
ItemReader itemReader = new ItemReader() {
|
||||
int counter = 0;
|
||||
public Object read() throws Exception {
|
||||
counter++;
|
||||
|
||||
if (counter == 1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
chunkedStep.setItemReader(itemReader);
|
||||
|
||||
try {
|
||||
chunkedStep.execute(stepExecution);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ExitStatus status = stepExecution.getExitStatus();
|
||||
assertEquals("FATAL_EXCEPTION", status.getExitCode());
|
||||
assertFalse(status.isContinuable());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure a job that has never been executed before, but does have
|
||||
* saveExecutionAttributes = true, doesn't have restoreFrom called on it.
|
||||
*/
|
||||
// I can't get this test to pass, I think there is something wrong with the code I
|
||||
// pulled from SimpleStepExecutor
|
||||
// public void testNonRestartedJob() throws Exception {
|
||||
// MockRestartableItemReader reader = new MockRestartableItemReader();
|
||||
// chunkedStep.setItemReader(reader);
|
||||
// chunkedStep.setSaveExecutionAttributes(true);
|
||||
//
|
||||
// chunkedStep.execute(stepExecution);
|
||||
//
|
||||
// assertFalse(reader.isRestoreFromCalled());
|
||||
// assertTrue(reader.isGetExecutionAttributesCalled());
|
||||
// }
|
||||
//
|
||||
// /*
|
||||
// * make sure a job that has been executed before, and is therefore being
|
||||
// * restarted, is restored.
|
||||
// */
|
||||
// public void testRestartedJob() throws Exception {
|
||||
// StepInstance step = new StepInstance(new Long(1));
|
||||
// step.setStepExecutionCount(1);
|
||||
// MockRestartableTasklet tasklet = new MockRestartableTasklet();
|
||||
// chunkedStep.setItemReader(tasklet);
|
||||
// stepConfiguration.setSaveExecutionAttributes(true);
|
||||
// JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
// StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
//
|
||||
// stepExecution
|
||||
// .setExecutionAttributes(new ExecutionAttributes(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
// step.setLastExecution(stepExecution);
|
||||
// chunkedStep.execute(stepExecution);
|
||||
//
|
||||
// assertTrue(tasklet.isRestoreFromCalled());
|
||||
// assertTrue(tasklet.isRestoreFromCalledWithSomeContext());
|
||||
// assertTrue(tasklet.isGetExecutionAttributesCalled());
|
||||
// }
|
||||
//
|
||||
// /*
|
||||
// * Test that a job that is being restarted, but has saveExecutionAttributes
|
||||
// * set to false, doesn't have restore or getExecutionAttributes called on
|
||||
// * it.
|
||||
// */
|
||||
// public void testNoSaveExecutionAttributesRestartableJob() {
|
||||
// StepInstance step = new StepInstance(new Long(1));
|
||||
// step.setStepExecutionCount(1);
|
||||
// MockRestartableTasklet tasklet = new MockRestartableTasklet();
|
||||
// stepConfiguration.setItemReader(tasklet);
|
||||
// stepConfiguration.setSaveExecutionAttributes(false);
|
||||
// JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
// StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
//
|
||||
// try {
|
||||
// chunkedStep.execute(stepExecution);
|
||||
// }
|
||||
// catch (Throwable t) {
|
||||
// fail();
|
||||
// }
|
||||
//
|
||||
// assertFalse(tasklet.isRestoreFromCalled());
|
||||
// assertFalse(tasklet.isGetExecutionAttributesCalled());
|
||||
// }
|
||||
//
|
||||
// /*
|
||||
// * Even though the job is restarted, and saveExecutionAttributes is true,
|
||||
// * nothing will be restored because the Tasklet does not implement
|
||||
// * Restartable.
|
||||
// */
|
||||
// public void testRestartJobOnNonRestartableTasklet() throws Exception {
|
||||
// StepInstance step = new StepInstance(new Long(1));
|
||||
// step.setStepExecutionCount(1);
|
||||
// stepConfiguration.setItemReader(new ItemReader() {
|
||||
// public Object read() throws Exception {
|
||||
// return ExitStatus.FINISHED;
|
||||
// }
|
||||
// });
|
||||
// stepConfiguration.setSaveExecutionAttributes(true);
|
||||
// JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
// StepExecution stepExecution = new StepExecution(step, jobExecution);
|
||||
//
|
||||
// chunkedStep.execute(stepExecution);
|
||||
// }
|
||||
//
|
||||
//// public void testApplyConfigurationWithExceptionHandler() throws Exception {
|
||||
//// AbstractStep stepConfiguration = new SimpleStep("foo");
|
||||
//// final List list = new ArrayList();
|
||||
//// chunkedStep.setStepOperations(new RepeatTemplate() {
|
||||
//// public void setExceptionHandler(ExceptionHandler exceptionHandler) {
|
||||
//// list.add(exceptionHandler);
|
||||
//// }
|
||||
//// });
|
||||
//// stepConfiguration.setExceptionHandler(new DefaultExceptionHandler());
|
||||
//// chunkedStep.applyConfiguration(stepConfiguration);
|
||||
//// assertEquals(1, list.size());
|
||||
//// }
|
||||
////
|
||||
//// public void testApplyConfigurationWithZeroSkipLimit() throws Exception {
|
||||
//// AbstractStep stepConfiguration = new SimpleStep("foo");
|
||||
//// stepConfiguration.setSkipLimit(0);
|
||||
//// final List list = new ArrayList();
|
||||
//// chunkedStep.setStepOperations(new RepeatTemplate() {
|
||||
//// public void setExceptionHandler(ExceptionHandler exceptionHandler) {
|
||||
//// list.add(exceptionHandler);
|
||||
//// }
|
||||
//// });
|
||||
//// chunkedStep.applyConfiguration(stepConfiguration);
|
||||
//// assertEquals(0, list.size());
|
||||
//// }
|
||||
////
|
||||
//// public void testApplyConfigurationWithNonZeroSkipLimit() throws Exception {
|
||||
//// AbstractStep stepConfiguration = new SimpleStep("foo");
|
||||
//// stepConfiguration.setSkipLimit(1);
|
||||
//// final List list = new ArrayList();
|
||||
//// chunkedStep.setStepOperations(new RepeatTemplate() {
|
||||
//// public void setExceptionHandler(ExceptionHandler exceptionHandler) {
|
||||
//// list.add(exceptionHandler);
|
||||
//// }
|
||||
//// });
|
||||
//// chunkedStep.applyConfiguration(stepConfiguration);
|
||||
//// assertEquals(1, list.size());
|
||||
//// }
|
||||
//
|
||||
// public void testStreamManager() throws Exception {
|
||||
// StepInstance step = new StepInstance(new Long(1));
|
||||
// step.setStepExecutionCount(1);
|
||||
// stepConfiguration.setItemReader(new ItemReader() {
|
||||
// public Object read() throws Exception {
|
||||
// return ExitStatus.FINISHED;
|
||||
// }
|
||||
// });
|
||||
// stepConfiguration.setSaveExecutionAttributes(true);
|
||||
// JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
// StepExecution stepExecution = new StepExecution(step, jobExecution);
|
||||
//
|
||||
// assertEquals(false, stepExecution.getExecutionAttributes().containsKey("foo"));
|
||||
//
|
||||
// final Map map = new HashMap();
|
||||
// chunkedStep.setStreamManager(new SimpleStreamManager(new ResourcelessTransactionManager()) {
|
||||
// public ExecutionAttributes getExecutionAttributes(Object key) {
|
||||
// // TODO Auto-generated method stub
|
||||
// return new ExecutionAttributes(PropertiesConverter.stringToProperties("foo=bar"));
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// chunkedStep.execute(stepExecution);
|
||||
//
|
||||
// // At least once in that process the statistics service was asked for
|
||||
// // statistics...
|
||||
// assertEquals("bar", stepExecution.getExecutionAttributes().getString("foo"));
|
||||
// // ...but nothing was registered because nothing with step scoped.
|
||||
// assertEquals(0, map.size());
|
||||
// }
|
||||
//
|
||||
// public void testStatusForInterruptedException() {
|
||||
//
|
||||
// StepInterruptionPolicy interruptionPolicy = new StepInterruptionPolicy() {
|
||||
//
|
||||
// public void checkInterrupted(RepeatContext context) throws JobInterruptedException {
|
||||
// throw new JobInterruptedException("");
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// chunkedStep.setInterruptionPolicy(interruptionPolicy);
|
||||
//
|
||||
// ItemReader itemReader = new ItemReader() {
|
||||
//
|
||||
// public Object read() throws Exception {
|
||||
// int counter = 0;
|
||||
// counter++;
|
||||
//
|
||||
// if (counter == 1) {
|
||||
// throw new RuntimeException();
|
||||
// }
|
||||
//
|
||||
// return ExitStatus.CONTINUABLE;
|
||||
// }
|
||||
//
|
||||
// };
|
||||
//
|
||||
// chunkedStep.setItemReader(itemReader);
|
||||
//
|
||||
// StepInstance step = new StepInstance(new Long(1));
|
||||
// JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
// StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
//
|
||||
// stepExecution
|
||||
// .setExecutionAttributes(new ExecutionAttributes(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
// step.setLastExecution(stepExecution);
|
||||
//
|
||||
// try {
|
||||
// chunkedStep.execute(stepExecution);
|
||||
// fail("Expected StepInterruptedException");
|
||||
// }
|
||||
// catch (JobInterruptedException ex) {
|
||||
// assertEquals(BatchStatus.STOPPED, stepExecution.getStatus());
|
||||
// String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
// assertTrue("Message does not contain JobInterruptedException: " + msg, msg
|
||||
// .contains("JobInterruptedException"));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void testStatusForResetFailedException() throws Exception {
|
||||
//
|
||||
// ItemReader itemReader = new ItemReader() {
|
||||
// public Object read() throws Exception {
|
||||
// // Trigger a rollback
|
||||
// throw new RuntimeException("Foo");
|
||||
// }
|
||||
// };
|
||||
// chunkedStep.setItemReader(itemReader);
|
||||
// chunkedStep.setStreamManager(new SimpleStreamManager(transactionManager) {
|
||||
// public void rollback(TransactionStatus status) {
|
||||
// super.rollback(status);
|
||||
// // Simulate failure on rollback when stream resets
|
||||
// throw new ResetFailedException("Bar");
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// StepInstance step = new StepInstance(new Long(1));
|
||||
// JobExecution jobExecutionContext = jobInstance.createJobExecution();
|
||||
// StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
//
|
||||
// stepExecution
|
||||
// .setExecutionAttributes(new ExecutionAttributes(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
// step.setLastExecution(stepExecution);
|
||||
//
|
||||
// try {
|
||||
// chunkedStep.execute(stepExecution);
|
||||
// fail("Expected ResetFailedException");
|
||||
// }
|
||||
// catch (ResetFailedException ex) {
|
||||
// assertEquals(BatchStatus.UNKNOWN, stepExecution.getStatus());
|
||||
// String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
// assertTrue("Message does not contain ResetFailedException: " + msg, msg.contains("ResetFailedException"));
|
||||
// // The original rollback was caused by this one:
|
||||
// assertEquals("Foo", ex.getCause().getMessage());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
private class MockRestartableItemReader extends ItemStreamAdapter implements ItemReader {
|
||||
|
||||
private boolean getExecutionAttributesCalled = false;
|
||||
|
||||
private boolean restoreFromCalled = false;
|
||||
|
||||
private boolean restoreFromCalledWithSomeContext = false;
|
||||
|
||||
private int counter = 0;
|
||||
|
||||
public Object read() throws Exception {
|
||||
StepSynchronizationManager.getContext().setAttribute("TASKLET_TEST", this);
|
||||
counter++;
|
||||
if(counter > 4){
|
||||
return "item";
|
||||
}
|
||||
else{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRestoreFromCalledWithSomeContext() {
|
||||
return restoreFromCalledWithSomeContext;
|
||||
}
|
||||
|
||||
public ExecutionContext getExecutionContext() {
|
||||
getExecutionAttributesCalled = true;
|
||||
return new ExecutionContext(PropertiesConverter.stringToProperties("spam=bucket"));
|
||||
}
|
||||
|
||||
public void restoreFrom(ExecutionContext data) {
|
||||
restoreFromCalled = true;
|
||||
restoreFromCalledWithSomeContext = data.getProperties().size() > 0;
|
||||
}
|
||||
|
||||
public boolean isGetExecutionAttributesCalled() {
|
||||
return getExecutionAttributesCalled;
|
||||
}
|
||||
|
||||
public boolean isRestoreFromCalled() {
|
||||
return restoreFromCalled;
|
||||
}
|
||||
|
||||
public void open() throws StreamException {
|
||||
}
|
||||
|
||||
public void close() throws StreamException {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,23 +19,25 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.domain.ChunkingResult;
|
||||
import org.springframework.batch.core.domain.ItemSkipPolicy;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
|
||||
public class ItemChunkerTests extends TestCase {
|
||||
|
||||
StepExecution stepExecution;
|
||||
StepContribution stepContribution;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
stepExecution = new StepExecution(null,null);
|
||||
StepExecution execution = new StepExecution(null,null);
|
||||
stepContribution = execution.createStepContribution();
|
||||
}
|
||||
|
||||
public void testSizeNegative() {
|
||||
try {
|
||||
MockItemReader itemReader = new MockItemReader(10);
|
||||
ItemChunker chunkReader = new ItemChunker(itemReader);
|
||||
chunkReader.chunk(-1, stepExecution);
|
||||
chunkReader.chunk(-1, stepContribution);
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
@@ -45,7 +47,7 @@ public class ItemChunkerTests extends TestCase {
|
||||
try {
|
||||
MockItemReader itemReader = new MockItemReader(10);
|
||||
ItemChunker chunkReader = new ItemChunker(itemReader);
|
||||
chunkReader.chunk(0, stepExecution);
|
||||
chunkReader.chunk(0, stepContribution);
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
@@ -54,14 +56,14 @@ public class ItemChunkerTests extends TestCase {
|
||||
public void testSizePositive() {
|
||||
MockItemReader itemReader = new MockItemReader(10);
|
||||
ItemChunker chunkReader = new ItemChunker(itemReader);
|
||||
ChunkingResult chunkingResult = chunkReader.chunk(10, stepExecution);
|
||||
ChunkingResult chunkingResult = chunkReader.chunk(10, stepContribution);
|
||||
assertEquals(10, chunkingResult.getChunk().getItems().size());
|
||||
}
|
||||
|
||||
public void testIncompleteChunk() {
|
||||
MockItemReader itemReader = new MockItemReader(5);
|
||||
ItemChunker chunkReader = new ItemChunker(itemReader);
|
||||
ChunkingResult chunkingResult = chunkReader.chunk(10, stepExecution);
|
||||
ChunkingResult chunkingResult = chunkReader.chunk(10, stepContribution);
|
||||
assertEquals(5, chunkingResult.getChunk().getItems().size());
|
||||
}
|
||||
|
||||
@@ -71,7 +73,7 @@ public class ItemChunkerTests extends TestCase {
|
||||
ItemChunker chunkReader = new ItemChunker(itemReader);
|
||||
chunkReader.setItemSkipPolicy(new StubReadFailurePolicy(true));
|
||||
try {
|
||||
chunkReader.chunk(10, stepExecution);
|
||||
chunkReader.chunk(10, stepContribution);
|
||||
fail();
|
||||
} catch (RuntimeException e) {
|
||||
}
|
||||
@@ -82,7 +84,7 @@ public class ItemChunkerTests extends TestCase {
|
||||
itemReader.setFail(true);
|
||||
ItemChunker chunkReader = new ItemChunker(itemReader);
|
||||
chunkReader.setItemSkipPolicy(new StubReadFailurePolicy(false));
|
||||
ChunkingResult chunkingResult = chunkReader.chunk(1, stepExecution);
|
||||
ChunkingResult chunkingResult = chunkReader.chunk(1, stepContribution);
|
||||
assertEquals(1,chunkingResult.getChunk().getItems().size());
|
||||
}
|
||||
|
||||
@@ -94,7 +96,7 @@ public class ItemChunkerTests extends TestCase {
|
||||
this.fail = fail;
|
||||
}
|
||||
|
||||
public boolean shouldSkip(Exception ex, StepExecution stepExecution) {
|
||||
public boolean shouldSkip(Exception ex, StepContribution stepContribution) {
|
||||
return !fail;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.core.domain.Chunk;
|
||||
import org.springframework.batch.core.domain.DechunkingResult;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.io.exception.WriteFailureException;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
@@ -34,7 +35,7 @@ import junit.framework.TestCase;
|
||||
public class ItemDechunkerTests extends TestCase {
|
||||
|
||||
private ItemDechunker dechunker;
|
||||
private StepExecution stepExecution;
|
||||
private StepContribution stepContribution;
|
||||
private Chunk chunk;
|
||||
private ItemWriter itemWriter;
|
||||
private MockControl writerControl = MockControl.createControl(ItemWriter.class);
|
||||
@@ -47,7 +48,8 @@ public class ItemDechunkerTests extends TestCase {
|
||||
super.setUp();
|
||||
|
||||
itemWriter = (ItemWriter)writerControl.getMock();
|
||||
stepExecution = new StepExecution(null,null);
|
||||
StepExecution execution = new StepExecution(null,null);
|
||||
stepContribution = execution.createStepContribution();
|
||||
dechunker = new ItemDechunker(itemWriter);
|
||||
List items = new ArrayList();
|
||||
items.add("1");
|
||||
@@ -61,7 +63,7 @@ public class ItemDechunkerTests extends TestCase {
|
||||
itemWriter.write("1");
|
||||
itemWriter.write("2");
|
||||
writerControl.replay();
|
||||
dechunker.dechunk(chunk, stepExecution);
|
||||
dechunker.dechunk(chunk, stepContribution);
|
||||
writerControl.verify();
|
||||
}
|
||||
|
||||
@@ -72,7 +74,7 @@ public class ItemDechunkerTests extends TestCase {
|
||||
itemWriter.write("2");
|
||||
writerControl.setThrowable(new Exception());
|
||||
writerControl.replay();
|
||||
DechunkingResult result = dechunker.dechunk(chunk, stepExecution);
|
||||
DechunkingResult result = dechunker.dechunk(chunk, stepContribution);
|
||||
writerControl.verify();
|
||||
List exceptions = result.getExceptions();
|
||||
assertEquals(1, exceptions.size());
|
||||
@@ -87,7 +89,7 @@ public class ItemDechunkerTests extends TestCase {
|
||||
writerControl.setThrowable(new NullPointerException());
|
||||
writerControl.replay();
|
||||
try{
|
||||
dechunker.dechunk(chunk, stepExecution);
|
||||
dechunker.dechunk(chunk, stepContribution);
|
||||
fail();
|
||||
}
|
||||
catch(NullPointerException ex){
|
||||
|
||||
@@ -57,7 +57,7 @@ import org.springframework.batch.support.PropertiesConverter;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
|
||||
public class SimpleStepExecutorTests extends TestCase {
|
||||
public class ItemOrientedStepTests extends TestCase {
|
||||
|
||||
ArrayList processed = new ArrayList();
|
||||
|
||||
@@ -67,9 +67,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
}
|
||||
};
|
||||
|
||||
private SimpleStepExecutor stepExecutor;
|
||||
|
||||
private AbstractStep stepConfiguration;
|
||||
private ItemOrientedStep itemOrientedStep;
|
||||
|
||||
private RepeatTemplate template;
|
||||
|
||||
@@ -84,7 +82,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
|
||||
|
||||
private AbstractStep getStep(String[] strings) throws Exception {
|
||||
SimpleStep step = new SimpleStep();
|
||||
ItemOrientedStep step = new ItemOrientedStep();
|
||||
step.setItemWriter(processor);
|
||||
step.setItemReader(getReader(strings));
|
||||
step.setJobRepository(new JobRepositorySupport());
|
||||
@@ -95,23 +93,22 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
transactionManager = new ResourcelessTransactionManager();
|
||||
stepConfiguration = getStep(new String[] { "foo", "bar", "spam" });
|
||||
|
||||
stepExecutor = (SimpleStepExecutor) stepConfiguration.createStepExecutor();
|
||||
itemOrientedStep = (ItemOrientedStep) getStep(new String[] { "foo", "bar", "spam" });
|
||||
template = new RepeatTemplate();
|
||||
template.setCompletionPolicy(new SimpleCompletionPolicy(1));
|
||||
stepExecutor.setStepOperations(template);
|
||||
itemOrientedStep.setStepOperations(template);
|
||||
// Only process one item:
|
||||
template = new RepeatTemplate();
|
||||
template.setCompletionPolicy(new SimpleCompletionPolicy(1));
|
||||
stepExecutor.setChunkOperations(template);
|
||||
itemOrientedStep.setChunkOperations(template);
|
||||
|
||||
jobInstance = new JobInstance(new Long(0), new JobParameters());
|
||||
jobInstance.setJob(new JobSupport("FOO"));
|
||||
|
||||
SimpleStreamManager streamManager = new SimpleStreamManager(transactionManager);
|
||||
streamManager.setUseClassNameAsPrefix(false);
|
||||
stepExecutor.setStreamManager(streamManager);
|
||||
itemOrientedStep.setStreamManager(streamManager);
|
||||
|
||||
}
|
||||
|
||||
@@ -121,7 +118,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
assertEquals(1, processed.size());
|
||||
assertEquals(1, stepExecution.getTaskCount().intValue());
|
||||
}
|
||||
@@ -132,14 +129,14 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
|
||||
// Only process one item:
|
||||
template.setCompletionPolicy(new SimpleCompletionPolicy(1));
|
||||
stepExecutor.setChunkOperations(template);
|
||||
itemOrientedStep.setChunkOperations(template);
|
||||
|
||||
String step = "stepName";
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecution);
|
||||
StepContribution contribution = stepExecution.createStepContribution();
|
||||
stepExecutor.processChunk(stepConfiguration, contribution);
|
||||
itemOrientedStep.processChunk(contribution);
|
||||
assertEquals(1, processed.size());
|
||||
assertEquals(0, stepExecution.getTaskCount().intValue());
|
||||
assertEquals(1, contribution.getTaskCount());
|
||||
@@ -152,22 +149,21 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
|
||||
// Only process one item:
|
||||
template.setCompletionPolicy(new SimpleCompletionPolicy(1));
|
||||
stepExecutor.setChunkOperations(template);
|
||||
itemOrientedStep.setChunkOperations(template);
|
||||
|
||||
final String step = "stepName";
|
||||
final JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
final StepExecution stepExecution = new StepExecution(step, jobExecution);
|
||||
|
||||
stepConfiguration.setItemReader(new ItemReader() {
|
||||
itemOrientedStep.setItemReader(new ItemReader() {
|
||||
public Object read() throws Exception {
|
||||
assertEquals(step, stepExecution.getStepName());
|
||||
assertNotNull(StepSynchronizationManager.getContext().getStepExecution());
|
||||
processed.add("foo");
|
||||
return ExitStatus.CONTINUABLE;
|
||||
return "foo";
|
||||
}
|
||||
});
|
||||
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
assertEquals(1, processed.size());
|
||||
|
||||
}
|
||||
@@ -178,7 +174,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
|
||||
// Only process one chunk:
|
||||
template.setCompletionPolicy(new SimpleCompletionPolicy(1));
|
||||
stepExecutor.setStepOperations(template);
|
||||
itemOrientedStep.setStepOperations(template);
|
||||
|
||||
final String step = "stepName";
|
||||
final JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
@@ -194,7 +190,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
}
|
||||
});
|
||||
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
assertEquals(1, processed.size());
|
||||
|
||||
}
|
||||
@@ -202,13 +198,13 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
public void testRepository() throws Exception {
|
||||
|
||||
SimpleJobRepository repository = new SimpleJobRepository(new MapJobDao(), new MapJobDao(), new MapStepDao());
|
||||
stepExecutor.setRepository(repository);
|
||||
itemOrientedStep.setJobRepository(repository);
|
||||
|
||||
String step = "stepName";
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
assertEquals(1, processed.size());
|
||||
}
|
||||
|
||||
@@ -230,12 +226,12 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
};
|
||||
|
||||
String step = "stepName";
|
||||
stepConfiguration.setItemReader(itemReader);
|
||||
itemOrientedStep.setItemReader(itemReader);
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
|
||||
try {
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
assertEquals(stepExecution.getRollbackCount(), new Integer(1));
|
||||
@@ -261,12 +257,12 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
};
|
||||
|
||||
String step = "stepName";
|
||||
stepConfiguration.setItemReader(itemReader);
|
||||
itemOrientedStep.setItemReader(itemReader);
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
|
||||
try {
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ExitStatus status = stepExecution.getExitStatus();
|
||||
@@ -281,12 +277,12 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
public void testNonRestartedJob() throws Exception {
|
||||
String step = "stepName";
|
||||
MockRestartableItemReader tasklet = new MockRestartableItemReader();
|
||||
stepExecutor.setItemReader(tasklet);
|
||||
stepConfiguration.setSaveExecutionContext(true);
|
||||
itemOrientedStep.setItemReader(tasklet);
|
||||
itemOrientedStep.setSaveExecutionContext(true);
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
|
||||
assertFalse(tasklet.isRestoreFromCalled());
|
||||
assertTrue(tasklet.isGetExecutionAttributesCalled());
|
||||
@@ -324,13 +320,13 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
String step = "stepName";
|
||||
// step.setStepExecutionCount(1);
|
||||
MockRestartableItemReader tasklet = new MockRestartableItemReader();
|
||||
stepConfiguration.setItemReader(tasklet);
|
||||
stepConfiguration.setSaveExecutionContext(false);
|
||||
itemOrientedStep.setItemReader(tasklet);
|
||||
itemOrientedStep.setSaveExecutionContext(false);
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
|
||||
try {
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
fail();
|
||||
@@ -348,28 +344,28 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
public void testRestartJobOnNonRestartableTasklet() throws Exception {
|
||||
String step = "stepName";
|
||||
// step.setStepExecutionCount(1);
|
||||
stepConfiguration.setItemReader(new ItemReader() {
|
||||
itemOrientedStep.setItemReader(new ItemReader() {
|
||||
public Object read() throws Exception {
|
||||
return ExitStatus.FINISHED;
|
||||
return "foo";
|
||||
}
|
||||
});
|
||||
stepConfiguration.setSaveExecutionContext(true);
|
||||
itemOrientedStep.setSaveExecutionContext(true);
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecution);
|
||||
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
}
|
||||
|
||||
public void testApplyConfigurationWithExceptionHandler() throws Exception {
|
||||
AbstractStep stepConfiguration = new SimpleStep("foo");
|
||||
final List list = new ArrayList();
|
||||
stepExecutor.setStepOperations(new RepeatTemplate() {
|
||||
itemOrientedStep.setStepOperations(new RepeatTemplate() {
|
||||
public void setExceptionHandler(ExceptionHandler exceptionHandler) {
|
||||
list.add(exceptionHandler);
|
||||
}
|
||||
});
|
||||
stepConfiguration.setExceptionHandler(new DefaultExceptionHandler());
|
||||
stepExecutor.applyConfiguration(stepConfiguration);
|
||||
itemOrientedStep.applyConfiguration(stepConfiguration);
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
@@ -377,12 +373,12 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
AbstractStep stepConfiguration = new SimpleStep("foo");
|
||||
stepConfiguration.setSkipLimit(0);
|
||||
final List list = new ArrayList();
|
||||
stepExecutor.setStepOperations(new RepeatTemplate() {
|
||||
itemOrientedStep.setStepOperations(new RepeatTemplate() {
|
||||
public void setExceptionHandler(ExceptionHandler exceptionHandler) {
|
||||
list.add(exceptionHandler);
|
||||
}
|
||||
});
|
||||
stepExecutor.applyConfiguration(stepConfiguration);
|
||||
itemOrientedStep.applyConfiguration(stepConfiguration);
|
||||
assertEquals(0, list.size());
|
||||
}
|
||||
|
||||
@@ -390,38 +386,38 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
AbstractStep stepConfiguration = new SimpleStep("foo");
|
||||
stepConfiguration.setSkipLimit(1);
|
||||
final List list = new ArrayList();
|
||||
stepExecutor.setStepOperations(new RepeatTemplate() {
|
||||
itemOrientedStep.setStepOperations(new RepeatTemplate() {
|
||||
public void setExceptionHandler(ExceptionHandler exceptionHandler) {
|
||||
list.add(exceptionHandler);
|
||||
}
|
||||
});
|
||||
stepExecutor.applyConfiguration(stepConfiguration);
|
||||
itemOrientedStep.applyConfiguration(stepConfiguration);
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
public void testStreamManager() throws Exception {
|
||||
String step = "stepName";
|
||||
// step.setStepExecutionCount(1);
|
||||
stepConfiguration.setItemReader(new ItemReader() {
|
||||
itemOrientedStep.setItemReader(new ItemReader() {
|
||||
public Object read() throws Exception {
|
||||
return ExitStatus.FINISHED;
|
||||
return "foo";
|
||||
}
|
||||
});
|
||||
stepConfiguration.setSaveExecutionContext(true);
|
||||
itemOrientedStep.setSaveExecutionContext(true);
|
||||
JobExecution jobExecution = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecution);
|
||||
|
||||
assertEquals(false, stepExecution.getExecutionContext().containsKey("foo"));
|
||||
|
||||
final Map map = new HashMap();
|
||||
stepExecutor.setStreamManager(new SimpleStreamManager(new ResourcelessTransactionManager()) {
|
||||
itemOrientedStep.setStreamManager(new SimpleStreamManager(new ResourcelessTransactionManager()) {
|
||||
public ExecutionContext getExecutionContext(Object key) {
|
||||
// TODO Auto-generated method stub
|
||||
return new ExecutionContext(PropertiesConverter.stringToProperties("foo=bar"));
|
||||
}
|
||||
});
|
||||
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
|
||||
// At least once in that process the statistics service was asked for
|
||||
// statistics...
|
||||
@@ -482,7 +478,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
}
|
||||
};
|
||||
|
||||
stepExecutor.setInterruptionPolicy(interruptionPolicy);
|
||||
itemOrientedStep.setInterruptionPolicy(interruptionPolicy);
|
||||
|
||||
ItemReader itemReader = new ItemReader() {
|
||||
|
||||
@@ -499,7 +495,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
|
||||
};
|
||||
|
||||
stepExecutor.setItemReader(itemReader);
|
||||
itemOrientedStep.setItemReader(itemReader);
|
||||
|
||||
String step = "stepName";
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
@@ -510,7 +506,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
// step.setLastExecution(stepExecution);
|
||||
|
||||
try {
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
fail("Expected StepInterruptedException");
|
||||
}
|
||||
catch (JobInterruptedException ex) {
|
||||
@@ -529,8 +525,8 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
throw new RuntimeException("Foo");
|
||||
}
|
||||
};
|
||||
stepExecutor.setItemReader(itemReader);
|
||||
stepExecutor.setStreamManager(new SimpleStreamManager(transactionManager) {
|
||||
itemOrientedStep.setItemReader(itemReader);
|
||||
itemOrientedStep.setStreamManager(new SimpleStreamManager(transactionManager) {
|
||||
public void rollback(TransactionStatus status) {
|
||||
super.rollback(status);
|
||||
// Simulate failure on rollback when stream resets
|
||||
@@ -547,7 +543,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
// step.setLastExecution(stepExecution);
|
||||
|
||||
try {
|
||||
stepExecutor.execute(stepExecution);
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
fail("Expected ResetFailedException");
|
||||
}
|
||||
catch (ResetFailedException ex) {
|
||||
@@ -20,6 +20,7 @@ import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.domain.ItemFailureHandler;
|
||||
import org.springframework.batch.core.domain.JobExecution;
|
||||
import org.springframework.batch.core.domain.JobInstance;
|
||||
import org.springframework.batch.core.domain.JobParameters;
|
||||
@@ -80,7 +81,7 @@ public class RepeatOperationsStepTests extends TestCase {
|
||||
}
|
||||
});
|
||||
repeatTemplate.setCompletionPolicy(new SimpleCompletionPolicy(2));
|
||||
RepeatOperationsStep configuration = new RepeatOperationsStep();
|
||||
ItemOrientedStep configuration = new ItemOrientedStep();
|
||||
configuration.setItemReader(new ItemReader(){
|
||||
public Object read() throws Exception {
|
||||
throw new NullPointerException();
|
||||
@@ -93,6 +94,7 @@ public class RepeatOperationsStepTests extends TestCase {
|
||||
configuration.setTransactionManager(new ResourcelessTransactionManager());
|
||||
StepExecution stepExecution = new StepExecution("stepName", new JobExecution(new JobInstance(new Long(0L), new JobParameters()),
|
||||
new Long(12)));
|
||||
configuration.afterPropertiesSet();
|
||||
try {
|
||||
configuration.execute(stepExecution);
|
||||
fail("Expected RuntimeException");
|
||||
@@ -133,6 +135,7 @@ public class RepeatOperationsStepTests extends TestCase {
|
||||
configuration.setTransactionManager(new ResourcelessTransactionManager());
|
||||
StepExecution stepExecution = new StepExecution("stepName", new JobExecution(new JobInstance(new Long(0L), new JobParameters()),
|
||||
new Long(12)));
|
||||
configuration.afterPropertiesSet();
|
||||
configuration.execute(stepExecution);
|
||||
assertEquals(2, list.size());
|
||||
assertEquals(1, steps.size());
|
||||
|
||||
@@ -15,77 +15,69 @@
|
||||
*/
|
||||
package org.springframework.batch.execution.step.simple;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.domain.JobExecution;
|
||||
import org.springframework.batch.core.domain.JobInstance;
|
||||
import org.springframework.batch.core.domain.JobParameters;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.item.reader.ItemReaderAdapter;
|
||||
import org.springframework.batch.item.stream.SimpleStreamManager;
|
||||
import org.springframework.batch.item.writer.ItemWriterAdapter;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.exception.handler.ExceptionHandler;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
|
||||
/**
|
||||
* Most of the tests have been commented out, since SimpleStep
|
||||
* will likely be removed soon.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class SimpleStepTests extends TestCase {
|
||||
|
||||
public void testSuccessfulStepExecutor() throws Exception {
|
||||
SimpleStep step = new SimpleStep();
|
||||
step.setJobRepository(new JobRepositorySupport());
|
||||
step.setTransactionManager(new ResourcelessTransactionManager());
|
||||
step.setItemReader(new ItemReaderAdapter());
|
||||
step.setItemWriter(new ItemWriterAdapter());
|
||||
assertNotNull(step.createStepExecutor());
|
||||
}
|
||||
// public void testSuccessfulStepExecutor() throws Exception {
|
||||
// SimpleStep step = new SimpleStep();
|
||||
// step.setJobRepository(new JobRepositorySupport());
|
||||
// step.setTransactionManager(new ResourcelessTransactionManager());
|
||||
// step.setItemReader(new ItemReaderAdapter());
|
||||
// step.setItemWriter(new ItemWriterAdapter());
|
||||
// assertNotNull(step.createStepExecutor());
|
||||
// }
|
||||
//
|
||||
// public void testSuccessfulExceptionHandler() throws Exception {
|
||||
// SimpleStep step = new SimpleStep("foo");
|
||||
// step.setItemReader(new ItemReaderAdapter());
|
||||
// step.setItemWriter(new ItemWriterAdapter());
|
||||
// step.setJobRepository(new JobRepositorySupport());
|
||||
// step.setTransactionManager(new ResourcelessTransactionManager());
|
||||
// final List list = new ArrayList();
|
||||
// step.setExceptionHandler(new ExceptionHandler() {
|
||||
// public void handleException(RepeatContext context, Throwable throwable) throws RuntimeException {
|
||||
// list.add(throwable);
|
||||
// throw new RuntimeException("Oops");
|
||||
// }
|
||||
// });
|
||||
// ItemOrientedStep executor = (ItemOrientedStep) step.createStepExecutor();
|
||||
// StepExecution stepExecution = new StepExecution("stepName", new JobExecution(
|
||||
// new JobInstance(new Long(0L), new JobParameters()), new Long(12)));
|
||||
// try {
|
||||
// executor.execute(stepExecution);
|
||||
// fail("Expected RuntimeException");
|
||||
// }
|
||||
// catch (NullPointerException e) {
|
||||
// throw e;
|
||||
// }
|
||||
// catch (RuntimeException e) {
|
||||
// assertEquals("Oops", e.getMessage());
|
||||
// }
|
||||
// assertEquals(1, list.size());
|
||||
// }
|
||||
|
||||
public void testSuccessfulExceptionHandler() throws Exception {
|
||||
SimpleStep step = new SimpleStep("foo");
|
||||
step.setItemReader(new ItemReaderAdapter());
|
||||
step.setItemWriter(new ItemWriterAdapter());
|
||||
step.setJobRepository(new JobRepositorySupport());
|
||||
step.setTransactionManager(new ResourcelessTransactionManager());
|
||||
final List list = new ArrayList();
|
||||
step.setExceptionHandler(new ExceptionHandler() {
|
||||
public void handleException(RepeatContext context, Throwable throwable) throws RuntimeException {
|
||||
list.add(throwable);
|
||||
throw new RuntimeException("Oops");
|
||||
}
|
||||
});
|
||||
SimpleStepExecutor executor = (SimpleStepExecutor) step.createStepExecutor();
|
||||
StepExecution stepExecution = new StepExecution("stepName", new JobExecution(
|
||||
new JobInstance(new Long(0L), new JobParameters()), new Long(12)));
|
||||
try {
|
||||
executor.execute(stepExecution);
|
||||
fail("Expected RuntimeException");
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
assertEquals("Oops", e.getMessage());
|
||||
}
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
public void testUnsuccessfulNoJobRepository() throws Exception {
|
||||
try {
|
||||
new SimpleStep().createStepExecutor();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
assertTrue("Error message does not contain JobRepository: " + e.getMessage(), e.getMessage().indexOf(
|
||||
"JobRepository") >= 0);
|
||||
}
|
||||
}
|
||||
// public void testUnsuccessfulNoJobRepository() throws Exception {
|
||||
// try {
|
||||
// new SimpleStep().createStepExecutor();
|
||||
// fail("Expected IllegalArgumentException");
|
||||
// }
|
||||
// catch (IllegalArgumentException e) {
|
||||
// // expected
|
||||
// assertTrue("Error message does not contain JobRepository: " + e.getMessage(), e.getMessage().indexOf(
|
||||
// "JobRepository") >= 0);
|
||||
// }
|
||||
// }
|
||||
|
||||
public void testMandatoryProperties() throws Exception {
|
||||
try {
|
||||
@@ -123,15 +115,15 @@ public class SimpleStepTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testMandatoryPropertiesAfterExecution() throws Exception {
|
||||
SimpleStep step = new SimpleStep();
|
||||
step.setItemReader(new ItemReaderAdapter());
|
||||
step.setItemWriter(new ItemWriterAdapter());
|
||||
step.setJobRepository(new JobRepositorySupport());
|
||||
step.setTransactionManager(new ResourcelessTransactionManager());
|
||||
assertNotNull(step.createStepExecutor());
|
||||
// If we do that again, we don't expect a different result (e.g.
|
||||
// mandatory properties test failing).
|
||||
assertNotNull(step.createStepExecutor());
|
||||
}
|
||||
// public void testMandatoryPropertiesAfterExecution() throws Exception {
|
||||
// SimpleStep step = new SimpleStep();
|
||||
// step.setItemReader(new ItemReaderAdapter());
|
||||
// step.setItemWriter(new ItemWriterAdapter());
|
||||
// step.setJobRepository(new JobRepositorySupport());
|
||||
// step.setTransactionManager(new ResourcelessTransactionManager());
|
||||
// assertNotNull(step.createStepExecutor());
|
||||
// // If we do that again, we don't expect a different result (e.g.
|
||||
// // mandatory properties test failing).
|
||||
// assertNotNull(step.createStepExecutor());
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.io.exception.FlatFileParsingException;
|
||||
|
||||
@@ -32,6 +33,7 @@ public class SkipLimitReadFailurePolicyTests extends TestCase {
|
||||
|
||||
LimitCheckingItemSkipPolicy failurePolicy;
|
||||
StepExecution stepExecution;
|
||||
StepContribution stepContribution;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
@@ -42,11 +44,12 @@ public class SkipLimitReadFailurePolicyTests extends TestCase {
|
||||
failurePolicy = new LimitCheckingItemSkipPolicy(1, skippableExceptions);
|
||||
stepExecution = new StepExecution(null, null);
|
||||
stepExecution.setSkipCount(2);
|
||||
stepContribution = stepExecution.createStepContribution();
|
||||
}
|
||||
|
||||
public void testLimitExceed(){
|
||||
try{
|
||||
failurePolicy.shouldSkip(new FlatFileParsingException("", ""), stepExecution);
|
||||
failurePolicy.shouldSkip(new FlatFileParsingException("", ""), stepContribution);
|
||||
fail();
|
||||
}
|
||||
catch(SkipLimitExceededException ex){
|
||||
@@ -55,12 +58,12 @@ public class SkipLimitReadFailurePolicyTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testNonSkippableException(){
|
||||
assertFalse(failurePolicy.shouldSkip(new FileNotFoundException(), stepExecution));
|
||||
assertFalse(failurePolicy.shouldSkip(new FileNotFoundException(), stepContribution));
|
||||
}
|
||||
|
||||
public void testSkip(){
|
||||
stepExecution.setSkipCount(0);
|
||||
assertTrue(failurePolicy.shouldSkip(new FlatFileParsingException("",""), stepExecution));
|
||||
assertTrue(failurePolicy.shouldSkip(new FlatFileParsingException("",""), stepContribution));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ public class StepExecutorInterruptionTests extends TestCase {
|
||||
step.setItemWriter(new ItemWriter(){
|
||||
public void write(Object item) throws Exception {
|
||||
}});
|
||||
step.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public void testInterruptChunk() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user