/** * @param execution {@link StepExecution} the stepExecution used to initialize * {@code skipCount}. */ public StepContribution(StepExecution execution) { this.parentSkipCount = execution.getSkipCount(); }
/** * @return */ private int getSkipCount() { if (stepExecution == null || stepName == null) { return 0; } for (StepExecution execution : stepExecution.getJobExecution().getStepExecutions()) { if (execution.getStepName().equals(stepName)) { return execution.getSkipCount(); } } return 0; }
@AfterStep public ExitStatus checkForSkips(StepExecution stepExecution) { if (!stepExecution.getExitStatus().getExitCode().equals(ExitStatus.FAILED.getExitCode()) && stepExecution.getSkipCount() > 0) { return new ExitStatus("COMPLETED WITH SKIPS"); } else { return null; } }
@Override public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) { if (!stepExecution.getExitStatus().getExitCode().equals( ExitStatus.FAILED.getExitCode()) && stepExecution.getSkipCount() > 0) { return new FlowExecutionStatus("COMPLETED WITH SKIPS"); } else { return new FlowExecutionStatus(ExitStatus.COMPLETED.getExitCode()); } } }
@Test public void testMultithreadedSkipInWriter() throws Exception { writer.setFailures("1", "2", "3", "4", "5"); factory.setCommitInterval(3); factory.setSkipLimit(10); factory.setTaskExecutor(new SimpleAsyncTaskExecutor()); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals("[]", writer.getCommitted().toString()); assertEquals("[]", processor.getCommitted().toString()); assertEquals(5, stepExecution.getSkipCount()); }
/** * Scenario: Exception in writer that should not cause rollback and scan */ @Test public void testWriterDefaultRollbackOnRuntimeException() throws Exception { writer.setFailures("2", "3"); writer.setExceptionType(SkippableRuntimeException.class); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); assertEquals(4, stepExecution.getRollbackCount()); }
@Test public void testReprocessingAfterWriterRollback() throws Exception { reader.setItems("1", "2", "3", "4"); writer.setFailures("4"); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(1, stepExecution.getSkipCount()); assertEquals(2, stepExecution.getRollbackCount()); // 1,2,3,4,3,4 - one scan until the item is // identified and finally skipped on the second attempt assertEquals("[1, 2, 3, 4, 3, 4]", processor.getProcessed().toString()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }
/** * Scenario: Exception in writer that should not cause rollback and scan */ @Test public void testWriterDefaultRollbackOnCheckedException() throws Exception { writer.setFailures("2", "3"); writer.setExceptionType(SkippableException.class); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); assertEquals(4, stepExecution.getRollbackCount()); }
/** * Scenario: Exception in writer that should not cause rollback and scan */ @Test public void testWriterDefaultRollbackOnError() throws Exception { writer.setFailures("2", "3"); writer.setExceptionType(AssertionError.class); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(0, stepExecution.getSkipCount()); assertEquals(1, stepExecution.getRollbackCount()); }
@SuppressWarnings("unchecked") @Test public void testDefaultSkipPolicy() throws Exception { reader.setItems("a", "b", "c"); reader.setFailures("b"); factory.setSkippableExceptionClasses(getExceptionMap(Exception.class)); factory.setSkipLimit(1); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(1, stepExecution.getSkipCount()); assertEquals("[a, c]", reader.getRead().toString()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }
/** * Scenario: Exception in reader that should not cause rollback */ @Test public void testReaderDefaultNoRollbackOnCheckedException() throws Exception { reader.setItems("1", "2", "3", "4"); reader.setFailures("2", "3"); reader.setExceptionType(SkippableException.class); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); assertEquals(0, stepExecution.getRollbackCount()); }
/** * Scenario: Exception in processor that should cause rollback */ @Test public void testProcessorDefaultRollbackOnRuntimeException() throws Exception { reader.setItems("1", "2", "3", "4"); processor.setFailures("1", "3"); processor.setExceptionType(SkippableRuntimeException.class); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); assertEquals(2, stepExecution.getRollbackCount()); }
@Test public void testNoInputNoListeners() throws Exception{ reader = new FailingListItemReader(new ArrayList<>()); Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener<String>) readListener).build(); runStep(step); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(0, processor.count); assertEquals(0, writer.results.size()); assertEquals(0, stepExecution.getProcessSkipCount()); assertEquals(0, stepExecution.getReadCount()); assertEquals(0, stepExecution.getReadSkipCount()); assertEquals(0, stepExecution.getSkipCount()); assertEquals(0, stepExecution.getWriteCount()); assertEquals(0, stepExecution.getFilterCount()); assertEquals(0, stepExecution.getWriteSkipCount()); }
@Test public void testNoInputNoListeners() throws Exception{ reader = new FailingListItemReader(new ArrayList<>()); Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).listener((ItemReadListener<String>) listener).build(); runStep(step); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(0, processor.count); assertEquals(0, writer.results.size()); assertEquals(0, stepExecution.getProcessSkipCount()); assertEquals(0, stepExecution.getReadCount()); assertEquals(0, stepExecution.getReadSkipCount()); assertEquals(0, stepExecution.getSkipCount()); assertEquals(0, stepExecution.getWriteCount()); assertEquals(0, stepExecution.getFilterCount()); assertEquals(0, stepExecution.getWriteSkipCount()); }
/** * Scenario: Exception in processor that should cause rollback because of * checked exception */ @Test public void testProcessorDefaultRollbackOnCheckedException() throws Exception { reader.setItems("1", "2", "3", "4"); processor.setFailures("1", "3"); processor.setExceptionType(SkippableException.class); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); assertEquals(2, stepExecution.getRollbackCount()); }
/** * Scenario: Exception in writer that should not cause rollback and scan */ @Test public void testWriterNoRollbackOnRuntimeException() throws Exception { writer.setFailures("2", "3"); writer.setExceptionType(SkippableRuntimeException.class); factory.setNoRollbackExceptionClasses(getExceptionList(SkippableRuntimeException.class)); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); // Two multi-item chunks rolled back. When the item was encountered on // its own it can proceed assertEquals(2, stepExecution.getRollbackCount()); }
/** * Scenario: Exception in writer that should not cause rollback and scan */ @Test public void testWriterNoRollbackOnCheckedException() throws Exception { writer.setFailures("2", "3"); writer.setExceptionType(SkippableException.class); factory.setNoRollbackExceptionClasses(getExceptionList(SkippableException.class)); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); // Two multi-item chunks rolled back. When the item was encountered on // its own it can proceed assertEquals(2, stepExecution.getRollbackCount()); }
/** * Scenario: Exception in reader that should not cause rollback */ @SuppressWarnings("unchecked") @Test public void testReaderAttributesOverrideSkippableNoRollback() throws Exception { reader.setFailures("2", "3"); reader.setItems("1", "2", "3", "4"); reader.setExceptionType(SkippableException.class); // No skips by default factory.setSkippableExceptionClasses(getExceptionMap(RuntimeException.class)); // But this one is explicit in the tx-attrs so it should be skipped factory.setNoRollbackExceptionClasses(getExceptionList(SkippableException.class)); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(0, stepExecution.getSkipCount()); assertEquals(0, stepExecution.getRollbackCount()); }
@Test public void testSimpleScenarioNoListeners() throws Exception{ Step step = builder.chunk(25).reader(reader).processor(processor).writer(writer).build(); runStep(step); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(0, stepExecution.getProcessSkipCount()); assertEquals(25, stepExecution.getReadCount()); assertEquals(0, stepExecution.getReadSkipCount()); assertEquals(0, stepExecution.getSkipCount()); assertEquals(25, stepExecution.getWriteCount()); assertEquals(0, stepExecution.getFilterCount()); assertEquals(0, stepExecution.getWriteSkipCount()); assertEquals(25, writer.results.size()); assertEquals(25, processor.count); int count = 0; for (String curItem : writer.results) { assertEquals("item " + count, curItem); count++; } }
private void assertStepExecutionsAreEqual(StepExecution expected, StepExecution actual) { assertEquals(expected.getId(), actual.getId()); assertEquals(expected.getStartTime(), actual.getStartTime()); assertEquals(expected.getEndTime(), actual.getEndTime()); assertEquals(expected.getSkipCount(), actual.getSkipCount()); assertEquals(expected.getCommitCount(), actual.getCommitCount()); assertEquals(expected.getReadCount(), actual.getReadCount()); assertEquals(expected.getWriteCount(), actual.getWriteCount()); assertEquals(expected.getFilterCount(), actual.getFilterCount()); assertEquals(expected.getWriteSkipCount(), actual.getWriteSkipCount()); assertEquals(expected.getReadSkipCount(), actual.getReadSkipCount()); assertEquals(expected.getProcessSkipCount(), actual.getProcessSkipCount()); assertEquals(expected.getRollbackCount(), actual.getRollbackCount()); assertEquals(expected.getExitStatus(), actual.getExitStatus()); assertEquals(expected.getLastUpdated(), actual.getLastUpdated()); assertEquals(expected.getExitStatus(), actual.getExitStatus()); assertEquals(expected.getJobExecutionId(), actual.getJobExecutionId()); }