List of usage examples for org.springframework.batch.core StepExecution getExecutionContext
public ExecutionContext getExecutionContext()
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; } } }