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

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

Introduction

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

Prototype

@Override
public ChunkIterator iterator() 

Source Link

Document

Get an unmodifiable iterator for the underlying items.

Usage

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

/**
 * @param chunk//  ww  w  . j av a  2 s  .co m
 * @throws Exception
 */
private void recover(Chunk<String> chunk) throws Exception {
    for (Chunk<String>.ChunkIterator iterator = chunk.iterator(); iterator.hasNext();) {
        String string = iterator.next();
        try {
            doWrite(Collections.singletonList(string));
        } catch (Exception e) {
            iterator.remove(e);
            throw e;
        }
    }
}

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;/*  ww w  . ja  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//w w w.ja  v  a2  s . com
        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 void scan(final StepContribution contribution, final Chunk<I> inputs, final Chunk<O> outputs,
        ChunkMonitor chunkMonitor, boolean recovery) throws Exception {

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

    if (logger.isDebugEnabled()) {
        if (recovery) {
            logger.debug("Scanning for failed item on recovery from write: " + inputs);
        } else {/*w  w w.j  av  a 2 s. c om*/
            logger.debug("Scanning for failed item on write: " + inputs);
        }
    }
    if (outputs.isEmpty() || inputs.isEmpty()) {
        data.scanning(false);
        inputs.setBusy(false);
        chunkMonitor.resetOffset();
        return;
    }

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

    List<O> items = Collections.singletonList(outputIterator.next());
    inputIterator.next();
    try {
        writeItems(items);
        // If successful we are going to return and allow
        // the driver to commit...
        doAfterWrite(items);
        contribution.incrementWriteCount(1);
        inputIterator.remove();
        outputIterator.remove();
    } catch (Exception e) {
        try {
            doOnWriteError(e, items);
        } finally {
            Throwable cause = e;
            if (e instanceof StepListenerFailedException) {
                cause = e.getCause();
            }

            if (!shouldSkip(itemWriteSkipPolicy, cause, -1) && !rollbackClassifier.classify(cause)) {
                inputIterator.remove();
                outputIterator.remove();
            } else {
                checkSkipPolicy(inputIterator, outputIterator, cause, contribution, recovery);
            }
            if (rollbackClassifier.classify(cause)) {
                throw (Exception) cause;
            }
        }
    }
    chunkMonitor.incrementOffset();
    if (outputs.isEmpty()) {
        data.scanning(false);
        inputs.setBusy(false);
        chunkMonitor.resetOffset();
    }
}