Example usage for org.springframework.batch.core StepExecution getExecutionContext

List of usage examples for org.springframework.batch.core StepExecution getExecutionContext

Introduction

In this page you can find the example usage for org.springframework.batch.core StepExecution getExecutionContext.

Prototype

public ExecutionContext getExecutionContext() 

Source Link

Document

Returns the ExecutionContext for this execution

Usage

From source file:de.codecentric.batch.metrics.MetricsListener.java

@Override
public ExitStatus afterStep(StepExecution stepExecution) {
    // Calculate step execution time
    // Why is stepExecution.getEndTime().getTime() not available here? (see AbstractStep)
    long stepDuration = System.currentTimeMillis() - stepExecution.getStartTime().getTime();
    gaugeService.submit(TIMER_PREFIX + getStepExecutionIdentifier(stepExecution) + ".duration", stepDuration);
    long itemCount = stepExecution.getWriteCount() + stepExecution.getSkipCount();
    gaugeService.submit(GAUGE_PREFIX + getStepExecutionIdentifier(stepExecution) + ".item.count", itemCount);
    // Calculate execution time per item
    long durationPerItem = 0;
    if (itemCount > 0) {
        durationPerItem = stepDuration / itemCount;
    }/*from  w  w w  . ja  v  a 2s .  c o  m*/
    gaugeService.submit(TIMER_PREFIX + getStepExecutionIdentifier(stepExecution) + ".item.duration",
            durationPerItem);
    // Export metrics from StepExecution to MetricRepositories
    Set<Entry<String, Object>> metrics = stepExecution.getExecutionContext().entrySet();
    for (Entry<String, Object> metric : metrics) {
        if (metric.getValue() instanceof Long) {
            gaugeService.submit(
                    GAUGE_PREFIX + getStepExecutionIdentifier(stepExecution) + "." + metric.getKey(),
                    (Long) metric.getValue());
        } else if (metric.getValue() instanceof Double) {
            gaugeService.submit(
                    GAUGE_PREFIX + getStepExecutionIdentifier(stepExecution) + "." + metric.getKey(),
                    (Double) metric.getValue());
        }
    }
    return null;
}

From source file:org.springframework.batch.core.job.flow.support.SimpleFlow.java

protected boolean isFlowContinued(State state, FlowExecutionStatus status, StepExecution stepExecution) {
    boolean continued = true;

    continued = state != null && status != FlowExecutionStatus.STOPPED;

    if (stepExecution != null) {
        Boolean reRun = (Boolean) stepExecution.getExecutionContext().get("batch.restart");
        Boolean executed = (Boolean) stepExecution.getExecutionContext().get("batch.executed");

        if ((executed == null || !executed) && reRun != null && reRun && status == FlowExecutionStatus.STOPPED
                && !state.getName().endsWith(stepExecution.getStepName())) {
            continued = true;//from w w  w. java2  s.c om
        }
    }

    return continued;
}

From source file:org.springframework.batch.core.job.SimpleStepHandler.java

@Override
public StepExecution handleStep(Step step, JobExecution execution)
        throws JobInterruptedException, JobRestartException, StartLimitExceededException {
    if (execution.isStopping()) {
        throw new JobInterruptedException("JobExecution interrupted.");
    }/*from  ww w.jav a 2  s.c  om*/

    JobInstance jobInstance = execution.getJobInstance();

    StepExecution lastStepExecution = jobRepository.getLastStepExecution(jobInstance, step.getName());
    if (stepExecutionPartOfExistingJobExecution(execution, lastStepExecution)) {
        // If the last execution of this step was in the same job, it's
        // probably intentional so we want to run it again...
        logger.info(String.format(
                "Duplicate step [%s] detected in execution of job=[%s]. "
                        + "If either step fails, both will be executed again on restart.",
                step.getName(), jobInstance.getJobName()));
        lastStepExecution = null;
    }
    StepExecution currentStepExecution = lastStepExecution;

    if (shouldStart(lastStepExecution, execution, step)) {

        currentStepExecution = execution.createStepExecution(step.getName());

        boolean isRestart = (lastStepExecution != null
                && !lastStepExecution.getStatus().equals(BatchStatus.COMPLETED));

        if (isRestart) {
            currentStepExecution.setExecutionContext(lastStepExecution.getExecutionContext());

            if (lastStepExecution.getExecutionContext().containsKey("batch.executed")) {
                currentStepExecution.getExecutionContext().remove("batch.executed");
            }
        } else {
            currentStepExecution.setExecutionContext(new ExecutionContext(executionContext));
        }

        jobRepository.add(currentStepExecution);

        logger.info("Executing step: [" + step.getName() + "]");
        try {
            step.execute(currentStepExecution);
            currentStepExecution.getExecutionContext().put("batch.executed", true);
        } catch (JobInterruptedException e) {
            // Ensure that the job gets the message that it is stopping
            // and can pass it on to other steps that are executing
            // concurrently.
            execution.setStatus(BatchStatus.STOPPING);
            throw e;
        }

        jobRepository.updateExecutionContext(execution);

        if (currentStepExecution.getStatus() == BatchStatus.STOPPING
                || currentStepExecution.getStatus() == BatchStatus.STOPPED) {
            // Ensure that the job gets the message that it is stopping
            execution.setStatus(BatchStatus.STOPPING);
            throw new JobInterruptedException("Job interrupted by step execution");
        }

    }

    return currentStepExecution;
}

From source file:org.springframework.batch.core.scope.AsyncStepScopeIntegrationTests.java

@Test
public void testSimpleProperty() throws Exception {
    StepExecution stepExecution = new StepExecution("step", new JobExecution(0L), 123L);
    ExecutionContext executionContext = stepExecution.getExecutionContext();
    executionContext.put("foo", "bar");
    StepSynchronizationManager.register(stepExecution);
    assertEquals("bar", simple.getName());
}

From source file:org.springframework.batch.core.scope.AsyncStepScopeIntegrationTests.java

@Test
public void testGetMultipleInMultipleThreads() throws Exception {

    List<FutureTask<String>> tasks = new ArrayList<FutureTask<String>>();

    for (int i = 0; i < 12; i++) {
        final String value = "foo" + i;
        final Long id = 123L + i;
        FutureTask<String> task = new FutureTask<String>(new Callable<String>() {
            @Override/*from   w  w w. j ava  2 s.  co m*/
            public String call() throws Exception {
                StepExecution stepExecution = new StepExecution(value, new JobExecution(0L), id);
                ExecutionContext executionContext = stepExecution.getExecutionContext();
                executionContext.put("foo", value);
                StepContext context = StepSynchronizationManager.register(stepExecution);
                logger.debug("Registered: " + context.getStepExecutionContext());
                try {
                    return simple.getName();
                } finally {
                    StepSynchronizationManager.close();
                }
            }
        });
        tasks.add(task);
        taskExecutor.execute(task);
    }

    int i = 0;
    for (FutureTask<String> task : tasks) {
        assertEquals("foo" + i, task.get());
        i++;
    }

}

From source file:org.springframework.batch.core.scope.AsyncStepScopeIntegrationTests.java

@Test
public void testGetSameInMultipleThreads() throws Exception {

    List<FutureTask<String>> tasks = new ArrayList<FutureTask<String>>();
    final StepExecution stepExecution = new StepExecution("foo", new JobExecution(0L), 123L);
    ExecutionContext executionContext = stepExecution.getExecutionContext();
    executionContext.put("foo", "foo");
    StepSynchronizationManager.register(stepExecution);
    assertEquals("foo", simple.getName());

    for (int i = 0; i < 12; i++) {
        final String value = "foo" + i;
        FutureTask<String> task = new FutureTask<String>(new Callable<String>() {
            @Override/*from   w w  w.j a  v a  2  s  .  c  om*/
            public String call() throws Exception {
                ExecutionContext executionContext = stepExecution.getExecutionContext();
                executionContext.put("foo", value);
                StepContext context = StepSynchronizationManager.register(stepExecution);
                logger.debug("Registered: " + context.getStepExecutionContext());
                try {
                    return simple.getName();
                } finally {
                    StepSynchronizationManager.close();
                }
            }
        });
        tasks.add(task);
        taskExecutor.execute(task);
    }

    for (FutureTask<String> task : tasks) {
        assertEquals("foo", task.get());
    }

    // Don't close the outer scope until all tasks are finished. This should
    // always be the case if using an AbstractStep
    StepSynchronizationManager.close();

}

From source file:org.springframework.batch.core.step.AbstractStep.java

/**
 * Template method for step execution logic - calls abstract methods for resource initialization (
 * {@link #open(ExecutionContext)}), execution logic ({@link #doExecute(StepExecution)}) and resource closing (
 * {@link #close(ExecutionContext)})./*from   ww w  .ja  v a  2 s  . c o  m*/
 */
@Override
public final void execute(StepExecution stepExecution)
        throws JobInterruptedException, UnexpectedJobExecutionException {

    if (logger.isDebugEnabled()) {
        logger.debug("Executing: id=" + stepExecution.getId());
    }
    stepExecution.setStartTime(new Date());
    stepExecution.setStatus(BatchStatus.STARTED);
    getJobRepository().update(stepExecution);

    // Start with a default value that will be trumped by anything
    ExitStatus exitStatus = ExitStatus.EXECUTING;

    doExecutionRegistration(stepExecution);

    try {
        getCompositeListener().beforeStep(stepExecution);
        open(stepExecution.getExecutionContext());

        try {
            doExecute(stepExecution);
        } catch (RepeatException e) {
            throw e.getCause();
        }
        exitStatus = ExitStatus.COMPLETED.and(stepExecution.getExitStatus());

        // Check if someone is trying to stop us
        if (stepExecution.isTerminateOnly()) {
            throw new JobInterruptedException("JobExecution interrupted.");
        }

        // Need to upgrade here not set, in case the execution was stopped
        stepExecution.upgradeStatus(BatchStatus.COMPLETED);
        if (logger.isDebugEnabled()) {
            logger.debug("Step execution success: id=" + stepExecution.getId());
        }
    } catch (Throwable e) {
        stepExecution.upgradeStatus(determineBatchStatus(e));
        exitStatus = exitStatus.and(getDefaultExitStatusForFailure(e));
        stepExecution.addFailureException(e);
        if (stepExecution.getStatus() == BatchStatus.STOPPED) {
            logger.info(String.format("Encountered interruption executing step %s in job %s : %s", name,
                    stepExecution.getJobExecution().getJobInstance().getJobName(), e.getMessage()));
            if (logger.isDebugEnabled()) {
                logger.debug("Full exception", e);
            }
        } else {
            logger.error(String.format("Encountered an error executing step %s in job %s", name,
                    stepExecution.getJobExecution().getJobInstance().getJobName()), e);
        }
    } finally {

        try {
            // Update the step execution to the latest known value so the
            // listeners can act on it
            exitStatus = exitStatus.and(stepExecution.getExitStatus());
            stepExecution.setExitStatus(exitStatus);
            exitStatus = exitStatus.and(getCompositeListener().afterStep(stepExecution));
        } catch (Exception e) {
            logger.error(String.format("Exception in afterStep callback in step %s in job %s", name,
                    stepExecution.getJobExecution().getJobInstance().getJobName()), e);
        }

        try {
            getJobRepository().updateExecutionContext(stepExecution);
        } catch (Exception e) {
            stepExecution.setStatus(BatchStatus.UNKNOWN);
            exitStatus = exitStatus.and(ExitStatus.UNKNOWN);
            stepExecution.addFailureException(e);
            logger.error(String.format(
                    "Encountered an error saving batch meta data for step %s in job %s. "
                            + "This job is now in an unknown state and should not be restarted.",
                    name, stepExecution.getJobExecution().getJobInstance().getJobName()), e);
        }

        stepExecution.setEndTime(new Date());
        stepExecution.setExitStatus(exitStatus);

        try {
            getJobRepository().update(stepExecution);
        } catch (Exception e) {
            stepExecution.setStatus(BatchStatus.UNKNOWN);
            stepExecution.setExitStatus(exitStatus.and(ExitStatus.UNKNOWN));
            stepExecution.addFailureException(e);
            logger.error(String.format(
                    "Encountered an error saving batch meta data for step %s in job %s. "
                            + "This job is now in an unknown state and should not be restarted.",
                    name, stepExecution.getJobExecution().getJobInstance().getJobName()), e);
        }

        try {
            close(stepExecution.getExecutionContext());
        } catch (Exception e) {
            logger.error(String.format("Exception while closing step execution resources in step %s in job %s",
                    name, stepExecution.getJobExecution().getJobInstance().getJobName()), e);
            stepExecution.addFailureException(e);
        }

        doExecutionRelease();

        if (logger.isDebugEnabled()) {
            logger.debug("Step execution complete: " + stepExecution.getSummary());
        }
    }
}

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

@Test
public void testRestartAfterFailedWrite() throws Exception {

    factory.setSkipLimit(0);/*  ww  w. j a  v  a 2  s . c om*/
    factory.setCommitInterval(3);
    AbstractItemCountingItemStreamItemReader<String> reader = new AbstractItemCountingItemStreamItemReader<String>() {

        private ItemReader<String> reader;

        @Override
        protected void doClose() throws Exception {
            reader = null;
        }

        @Override
        protected void doOpen() throws Exception {
            reader = new ListItemReader<String>(Arrays.asList("a", "b", "c", "d", "e", "f"));
        }

        @Override
        protected String doRead() throws Exception {
            return reader.read();
        }

    };
    // Need to set name or else reader will fail to open
    reader.setName("foo");
    factory.setItemReader(reader);
    factory.setStreams(new ItemStream[] { reader });
    factory.setItemWriter(new ItemWriter<String>() {
        @Override
        public void write(List<? extends String> items) throws Exception {
            if (fail && items.contains("e")) {
                throw new RuntimeException("Planned failure");
            }
            processed.addAll(items);
        }
    });
    factory.setRetryLimit(0);
    Step step = factory.getObject();

    fail = true;
    StepExecution stepExecution = new StepExecution(step.getName(), jobExecution);
    repository.add(stepExecution);
    step.execute(stepExecution);

    assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
    assertEquals(4, stepExecution.getWriteCount());
    assertEquals(6, stepExecution.getReadCount());

    fail = false;
    ExecutionContext executionContext = stepExecution.getExecutionContext();
    stepExecution = new StepExecution(step.getName(), jobExecution);
    stepExecution.setExecutionContext(executionContext);
    repository.add(stepExecution);
    step.execute(stepExecution);

    assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
    assertEquals(2, stepExecution.getWriteCount());
    assertEquals(2, stepExecution.getReadCount());
}

From source file:org.springframework.batch.core.step.tasklet.TaskletStep.java

/**
 * Process the step and update its context so that progress can be monitored
 * by the caller. The step is broken down into chunks, each one executing in
 * a transaction. The step and its execution and execution context are all
 * given an up to date {@link BatchStatus}, and the {@link JobRepository} is
 * used to store the result. Various reporting information are also added to
 * the current context governing the step execution, which would normally be
 * available to the caller through the step's {@link ExecutionContext}.<br>
 *
 * @throws JobInterruptedException if the step or a chunk is interrupted
 * @throws RuntimeException if there is an exception during a chunk
 * execution//from w  w w .  ja v  a2 s.  c o  m
 *
 */
@Override
protected void doExecute(StepExecution stepExecution) throws Exception {
    stepExecution.getExecutionContext().put(TASKLET_TYPE_KEY, tasklet.getClass().getName());
    stepExecution.getExecutionContext().put(STEP_TYPE_KEY, this.getClass().getName());

    stream.update(stepExecution.getExecutionContext());
    getJobRepository().updateExecutionContext(stepExecution);

    // Shared semaphore per step execution, so other step executions can run
    // in parallel without needing the lock
    final Semaphore semaphore = createSemaphore();

    stepOperations.iterate(new StepContextRepeatCallback(stepExecution) {

        @Override
        public RepeatStatus doInChunkContext(RepeatContext repeatContext, ChunkContext chunkContext)
                throws Exception {

            StepExecution stepExecution = chunkContext.getStepContext().getStepExecution();

            // Before starting a new transaction, check for
            // interruption.
            interruptionPolicy.checkInterrupted(stepExecution);

            RepeatStatus result;
            try {
                result = new TransactionTemplate(transactionManager, transactionAttribute)
                        .execute(new ChunkTransactionCallback(chunkContext, semaphore));
            } catch (UncheckedTransactionException e) {
                // Allow checked exceptions to be thrown inside callback
                throw (Exception) e.getCause();
            }

            chunkListener.afterChunk(chunkContext);

            // Check for interruption after transaction as well, so that
            // the interrupted exception is correctly propagated up to
            // caller
            interruptionPolicy.checkInterrupted(stepExecution);

            return result;
        }

    });

}

From source file:org.springframework.batch.integration.x.IncrementalColumnRangePartitioner.java

@Override
public void beforeStep(StepExecution stepExecution) {
    if (StringUtils.hasText(checkColumn)) {

        if (overrideValue != null && overrideValue >= 0) {
            this.incrementalMin = overrideValue;
        } else {//  w  w w.  j a va2s  . c  o m
            String jobName = stepExecution.getJobExecution().getJobInstance().getJobName();

            // Get the last jobInstance...not the current one
            List<JobInstance> jobInstances = jobExplorer.getJobInstances(jobName, 1, 1);

            if (jobInstances.size() > 0) {
                JobInstance lastInstance = jobInstances.get(jobInstances.size() - 1);

                List<JobExecution> executions = jobExplorer.getJobExecutions(lastInstance);

                JobExecution lastExecution = executions.get(0);

                for (JobExecution execution : executions) {
                    if (lastExecution.getEndTime().getTime() < execution.getEndTime().getTime()) {
                        lastExecution = execution;
                    }
                }

                if (lastExecution.getExecutionContext().containsKey(BATCH_INCREMENTAL_MAX_ID)) {
                    this.incrementalMin = lastExecution.getExecutionContext().getLong(BATCH_INCREMENTAL_MAX_ID);
                } else {
                    this.incrementalMin = Long.MIN_VALUE;
                }
            } else {
                this.incrementalMin = Long.MIN_VALUE;
            }
        }

        long newMin = jdbcTemplate.queryForObject(String.format("select max(%s) from %s", checkColumn, table),
                Integer.class);

        stepExecution.getExecutionContext().put(BATCH_INCREMENTAL_MAX_ID, newMin);
    }

    if (StringUtils.hasText(column) && StringUtils.hasText(table)) {
        if (StringUtils.hasText(checkColumn)) {
            Long minResult = jdbcTemplate.queryForObject("SELECT MIN(" + column + ") from " + table + " where "
                    + checkColumn + " > " + this.incrementalMin, Long.class);
            Long maxResult = jdbcTemplate.queryForObject("SELECT MAX(" + column + ") from " + table + " where "
                    + checkColumn + " > " + this.incrementalMin, Long.class);
            this.partitionMin = minResult != null ? minResult : Long.MIN_VALUE;
            this.partitionMax = maxResult != null ? maxResult : Long.MAX_VALUE;
        } else {
            Long minResult = jdbcTemplate.queryForObject("SELECT MIN(" + column + ") from " + table,
                    Long.class);
            Long maxResult = jdbcTemplate.queryForObject("SELECT MAX(" + column + ") from " + table,
                    Long.class);
            this.partitionMin = minResult != null ? minResult : Long.MIN_VALUE;
            this.partitionMax = maxResult != null ? maxResult : Long.MAX_VALUE;
        }
    }
}