Example usage for org.springframework.batch.core.step.item Chunk getItems

List of usage examples for org.springframework.batch.core.step.item Chunk getItems

Introduction

In this page you can find the example usage for org.springframework.batch.core.step.item Chunk getItems.

Prototype

public List<W> getItems() 

Source Link

Usage

From source file:es.fcs.batch.integration.chunk.MyRemoteChunkHandlerFactoryBean.java

/**
 * Replace the chunk processor in the tasklet provided with one that can act as a master in the Remote Chunking
 * pattern.//  w  ww . ja  va2  s  .c o  m
 * 
 * @param tasklet a ChunkOrientedTasklet
 * @param chunkWriter an ItemWriter that can send the chunks to remote workers
 * @param stepContributionSource a StepContributionSource used to gather results from the workers
 */
private void replaceChunkProcessor(ChunkOrientedTasklet<?> tasklet, ItemWriter<T> chunkWriter,
        final StepContributionSource stepContributionSource) {
    setField(tasklet, "chunkProcessor",
            new SimpleChunkProcessor<T, T>(new PassThroughItemProcessor<T>(), chunkWriter) {
                /**
                * 
                */
                private static final long serialVersionUID = -8914556774351841413L;

                @Override
                protected void write(StepContribution contribution, Chunk<T> inputs, Chunk<T> outputs)
                        throws Exception {

                    doWrite(outputs.getItems());
                    // Do not update the step contribution until the chunks are
                    // actually processed
                    updateStepContribution(contribution, stepContributionSource);
                }
            });
}

From source file:org.springframework.batch.core.jsr.step.item.JsrChunkProcessor.java

/**
 * Responsible for the writing portion of the chunking loop.  In this implementation, delegates to the
 * {{@link #doPersist(StepContribution, Chunk)}.
 *
 * @param contribution a {@link StepContribution}
 * @param chunk a {@link Chunk}/*w w  w  .  j a  v  a2 s.  com*/
 * @throws Exception
 */
protected void persist(final StepContribution contribution, final Chunk<O> chunk) throws Exception {
    doPersist(contribution, chunk);

    contribution.incrementWriteCount(chunk.getItems().size());
}

From source file:org.springframework.batch.core.jsr.step.item.JsrChunkProcessor.java

/**
 * Implements writing and all related listener calls
 *
 * @param contribution a {@link StepContribution}
 * @param chunk a {@link Chunk}//from w ww  .  j a v a 2 s . co m
 * @throws Exception
 */
protected final void doPersist(final StepContribution contribution, final Chunk<O> chunk) throws Exception {
    try {
        List<O> items = chunk.getItems();
        listener.beforeWrite(items);
        itemWriter.write(items);
        listener.afterWrite(items);
    } catch (Exception e) {
        listener.onWriteError(e, chunk.getItems());
        throw e;
    }
}

From source file:org.springframework.batch.core.jsr.step.item.JsrFaultTolerantChunkProcessor.java

/**
 * Adds retry and skip logic to the write phase of the chunk loop.
 *
 * @param contribution a {@link StepContribution}
 * @param chunk a {@link Chunk}//from w w w  .  jav a2s .com
 * @throws Exception
 */
@Override
protected void persist(final StepContribution contribution, final Chunk<O> chunk) throws Exception {

    RetryCallback<Object, Exception> retryCallback = new RetryCallback<Object, Exception>() {
        @Override
        @SuppressWarnings({ "unchecked", "rawtypes" })
        public Object doWithRetry(RetryContext context) throws Exception {

            chunkMonitor.setChunkSize(chunk.size());
            try {
                doPersist(contribution, chunk);
            } catch (Exception e) {
                if (shouldSkip(skipPolicy, e, contribution.getStepSkipCount())) {
                    // Per section 9.2.7 of JSR-352, the SkipListener receives all the items within the chunk                    
                    ((MulticasterBatchListener) getListener()).onSkipInWrite(chunk.getItems(), e);
                } else {
                    getListener().onRetryWriteException((List<Object>) chunk.getItems(), e);

                    if (rollbackClassifier.classify(e)) {
                        throw e;
                    }
                }
                /*
                 * If the exception is marked as no-rollback, we need to
                 * override that, otherwise there's no way to write the
                 * rest of the chunk or to honour the skip listener
                 * contract.
                 */
                throw new ForceRollbackForWriteSkipException(
                        "Force rollback on skippable exception so that skipped item can be located.", e);
            }
            contribution.incrementWriteCount(chunk.size());
            return null;

        }
    };

    RecoveryCallback<Object> recoveryCallback = new RecoveryCallback<Object>() {

        @Override
        public O recover(RetryContext context) throws Exception {
            Throwable e = context.getLastThrowable();
            if (shouldSkip(skipPolicy, e, contribution.getStepSkipCount())) {
                contribution.incrementWriteSkipCount();
                logger.debug("Skipping after failed write", e);
                return null;
            } else {
                if (rollbackClassifier.classify(e)) {
                    // Default is to rollback unless the classifier
                    // allows us to continue
                    throw new RetryException("Non-skippable exception in recoverer while write", e);
                }
                return null;
            }
        }

    };

    batchRetryTemplate.execute(retryCallback, recoveryCallback);
}

From source file:org.springframework.batch.core.step.item.AlmostStatefulRetryChunkTests.java

/**
 * @param chunk/*from   w  w w  .ja  va 2s  .c o m*/
 * @throws Exception
 */
private void statefulRetry(Chunk<String> chunk) throws Exception {
    if (retryAttempts <= retryLimit) {
        try {
            // N.B. a classic stateful retry goes straight to recovery here
            logger.debug(String.format("Retry (attempts=%d) chunk: %s", retryAttempts, chunk));
            doWrite(chunk.getItems());
            retryAttempts = 0;
        } catch (Exception e) {
            retryAttempts++;
            // stateful retry always rethrow
            throw e;
        }
    } else {
        try {
            logger.debug(String.format("Recover (attempts=%d) chunk: %s", retryAttempts, chunk));
            recover(chunk);
        } finally {
            retryAttempts = 0;
        }
    }
    // recovery
    return;

}

From source file:org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.java

@Override
protected Chunk<O> getAdjustedOutputs(Chunk<I> inputs, Chunk<O> outputs) {

    @SuppressWarnings("unchecked")
    UserData<O> data = (UserData<O>) inputs.getUserData();
    Chunk<O> previous = data.getOutputs();

    Chunk<O> next = new Chunk<O>(outputs.getItems(), previous.getSkips());
    next.setBusy(previous.isBusy());/*from w  w w. j  a  va2s  .  c  om*/

    // Remember for next time if there are skips accumulating
    data.setOutputs(next);

    return next;

}

From source file:org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.java

@Override
protected Chunk<O> transform(final StepContribution contribution, Chunk<I> inputs) throws Exception {

    Chunk<O> outputs = new Chunk<O>();
    @SuppressWarnings("unchecked")
    final UserData<O> data = (UserData<O>) inputs.getUserData();
    final Chunk<O> cache = data.getOutputs();
    final Iterator<O> cacheIterator = cache.isEmpty() ? null : new ArrayList<O>(cache.getItems()).iterator();
    final AtomicInteger count = new AtomicInteger(0);

    // final int scanLimit = processorTransactional && data.scanning() ? 1 :
    // 0;//from   w  ww . j  a v a2  s.c o m

    for (final Chunk<I>.ChunkIterator iterator = inputs.iterator(); iterator.hasNext();) {

        final I item = iterator.next();

        RetryCallback<O, Exception> retryCallback = new RetryCallback<O, Exception>() {

            @Override
            public O doWithRetry(RetryContext context) throws Exception {
                O output = null;
                try {
                    count.incrementAndGet();
                    O cached = (cacheIterator != null && cacheIterator.hasNext()) ? cacheIterator.next() : null;
                    if (cached != null && !processorTransactional) {
                        output = cached;
                    } else {
                        output = doProcess(item);
                        if (output == null) {
                            data.incrementFilterCount();
                        } else if (!processorTransactional && !data.scanning()) {
                            cache.add(output);
                        }
                    }
                } catch (Exception e) {
                    if (rollbackClassifier.classify(e)) {
                        // Default is to rollback unless the classifier
                        // allows us to continue
                        throw e;
                    } else if (shouldSkip(itemProcessSkipPolicy, e, contribution.getStepSkipCount())) {
                        // If we are not re-throwing then we should check if
                        // this is skippable
                        contribution.incrementProcessSkipCount();
                        logger.debug("Skipping after failed process with no rollback", e);
                        // If not re-throwing then the listener will not be
                        // called in next chunk.
                        callProcessSkipListener(item, e);
                    } else {
                        // If it's not skippable that's an error in
                        // configuration - it doesn't make sense to not roll
                        // back if we are also not allowed to skip
                        throw new NonSkippableProcessException(
                                "Non-skippable exception in processor.  Make sure any exceptions that do not cause a rollback are skippable.",
                                e);
                    }
                }
                if (output == null) {
                    // No need to re-process filtered items
                    iterator.remove();
                }
                return output;
            }

        };

        RecoveryCallback<O> recoveryCallback = new RecoveryCallback<O>() {

            @Override
            public O recover(RetryContext context) throws Exception {
                Throwable e = context.getLastThrowable();
                if (shouldSkip(itemProcessSkipPolicy, e, contribution.getStepSkipCount())) {
                    iterator.remove(e);
                    contribution.incrementProcessSkipCount();
                    logger.debug("Skipping after failed process", e);
                    return null;
                } else {
                    if (rollbackClassifier.classify(e)) {
                        // Default is to rollback unless the classifier
                        // allows us to continue
                        throw new RetryException("Non-skippable exception in recoverer while processing", e);
                    }
                    iterator.remove(e);
                    return null;
                }
            }

        };

        O output = batchRetryTemplate.execute(retryCallback, recoveryCallback,
                new DefaultRetryState(getInputKey(item), rollbackClassifier));
        if (output != null) {
            outputs.add(output);
        }

        /*
         * We only want to process the first item if there is a scan for a
         * failed item.
         */
        if (data.scanning()) {
            while (cacheIterator != null && cacheIterator.hasNext()) {
                outputs.add(cacheIterator.next());
            }
            // Only process the first item if scanning
            break;
        }
    }

    return outputs;

}

From source file:org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.java

@Override
protected void write(final StepContribution contribution, final Chunk<I> inputs, final Chunk<O> outputs)
        throws Exception {
    @SuppressWarnings("unchecked")
    final UserData<O> data = (UserData<O>) inputs.getUserData();
    final AtomicReference<RetryContext> contextHolder = new AtomicReference<RetryContext>();

    RetryCallback<Object, Exception> retryCallback = new RetryCallback<Object, Exception>() {
        @Override//from www .j a  v a 2s  .c  o  m
        public Object doWithRetry(RetryContext context) throws Exception {
            contextHolder.set(context);

            if (!data.scanning()) {
                chunkMonitor.setChunkSize(inputs.size());
                try {
                    doWrite(outputs.getItems());
                } catch (Exception e) {
                    if (rollbackClassifier.classify(e)) {
                        throw e;
                    }
                    /*
                     * If the exception is marked as no-rollback, we need to
                     * override that, otherwise there's no way to write the
                     * rest of the chunk or to honour the skip listener
                     * contract.
                     */
                    throw new ForceRollbackForWriteSkipException(
                            "Force rollback on skippable exception so that skipped item can be located.", e);
                }
                contribution.incrementWriteCount(outputs.size());
            } else {
                scan(contribution, inputs, outputs, chunkMonitor, false);
            }
            return null;

        }
    };

    if (!buffering) {

        RecoveryCallback<Object> batchRecoveryCallback = new RecoveryCallback<Object>() {

            @Override
            public Object recover(RetryContext context) throws Exception {

                Throwable e = context.getLastThrowable();
                if (outputs.size() > 1 && !rollbackClassifier.classify(e)) {
                    throw new RetryException("Invalid retry state during write caused by "
                            + "exception that does not classify for rollback: ", e);
                }

                Chunk<I>.ChunkIterator inputIterator = inputs.iterator();
                for (Chunk<O>.ChunkIterator outputIterator = outputs.iterator(); outputIterator.hasNext();) {

                    inputIterator.next();
                    outputIterator.next();

                    checkSkipPolicy(inputIterator, outputIterator, e, contribution, true);
                    if (!rollbackClassifier.classify(e)) {
                        throw new RetryException(
                                "Invalid retry state during recovery caused by exception that does not classify for rollback: ",
                                e);
                    }

                }

                return null;

            }

        };

        batchRetryTemplate.execute(retryCallback, batchRecoveryCallback,
                BatchRetryTemplate.createState(getInputKeys(inputs), rollbackClassifier));

    } else {

        RecoveryCallback<Object> recoveryCallback = new RecoveryCallback<Object>() {

            @Override
            public Object recover(RetryContext context) throws Exception {
                /*
                 * If the last exception was not skippable we don't need to
                 * do any scanning. We can just bomb out with a retry
                 * exhausted.
                 */
                if (!shouldSkip(itemWriteSkipPolicy, context.getLastThrowable(), -1)) {
                    throw new ExhaustedRetryException(
                            "Retry exhausted after last attempt in recovery path, but exception is not skippable.",
                            context.getLastThrowable());
                }

                inputs.setBusy(true);
                data.scanning(true);
                scan(contribution, inputs, outputs, chunkMonitor, true);
                return null;
            }

        };

        if (logger.isDebugEnabled()) {
            logger.debug("Attempting to write: " + inputs);
        }
        try {
            batchRetryTemplate.execute(retryCallback, recoveryCallback,
                    new DefaultRetryState(inputs, rollbackClassifier));
        } catch (Exception e) {
            RetryContext context = contextHolder.get();
            if (!batchRetryTemplate.canRetry(context)) {
                /*
                 * BATCH-1761: we need advance warning of the scan about to
                 * start in the next transaction, so we can change the
                 * processing behaviour.
                 */
                data.scanning(true);
            }
            throw e;
        }

    }

    callSkipListeners(inputs, outputs);

}

From source file:org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.java

private List<?> getInputKeys(final Chunk<I> inputs) {
    if (keyGenerator == null) {
        return inputs.getItems();
    }//from  w w  w  . ja va2  s . c  o m
    List<Object> keys = new ArrayList<Object>();
    for (I item : inputs.getItems()) {
        keys.add(keyGenerator.getKey(item));
    }
    return keys;
}

From source file:org.springframework.batch.integration.chunk.RemoteChunkHandlerFactoryBean.java

/**
 * Replace the chunk processor in the tasklet provided with one that can act as a master in the Remote Chunking
 * pattern.//from  ww w.j a  v a  2s. c  om
 * 
 * @param tasklet a ChunkOrientedTasklet
 * @param chunkWriter an ItemWriter that can send the chunks to remote workers
 * @param stepContributionSource a StepContributionSource used to gather results from the workers
 */
private void replaceChunkProcessor(ChunkOrientedTasklet<?> tasklet, ItemWriter<T> chunkWriter,
        final StepContributionSource stepContributionSource) {
    setField(tasklet, "chunkProcessor",
            new SimpleChunkProcessor<T, T>(new PassThroughItemProcessor<T>(), chunkWriter) {
                @Override
                protected void write(StepContribution contribution, Chunk<T> inputs, Chunk<T> outputs)
                        throws Exception {
                    doWrite(outputs.getItems());
                    // Do not update the step contribution until the chunks are
                    // actually processed
                    updateStepContribution(contribution, stepContributionSource);
                }
            });
}