diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ExceptionThrowingItemHandlerStub.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ExceptionThrowingItemHandlerStub.java new file mode 100644 index 000000000..e52533b5b --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ExceptionThrowingItemHandlerStub.java @@ -0,0 +1,65 @@ +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.step.item; + +import java.util.Collection; +import java.util.Collections; + +/** + * @author Dan Garrette + * @since 2.0.1 + */ +public abstract class ExceptionThrowingItemHandlerStub { + + private Collection failures = Collections.emptyList(); + + private boolean runtimeException = false; + + public ExceptionThrowingItemHandlerStub() { + } + + public ExceptionThrowingItemHandlerStub(Collection failures) { + this.failures = failures; + } + + public ExceptionThrowingItemHandlerStub(Collection failures, boolean runtimeException) { + this(failures); + this.runtimeException = runtimeException; + } + + public void setFailures(Collection failures) { + this.failures = failures; + } + + public void setRuntimeException(boolean runtimeException) { + this.runtimeException = runtimeException; + } + + protected void checkFailure(T item) throws Exception { + if (isFailure(item)) { + if (runtimeException) { + throw new SkippableRuntimeException("should cause rollback in reader"); + } + else { + throw new SkippableException("shouldn't cause rollback in reader"); + } + } + } + + protected boolean isFailure(T item) { + return this.failures.contains(item); + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java index 5dc9492b1..83b0f80d0 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java @@ -49,6 +49,8 @@ public class FaultTolerantStepFactoryBeanNonBufferingTests { private JobExecution jobExecution; + private static final SkippableRuntimeException exception = new SkippableRuntimeException("exception in writer"); + int count = 0; @Before @@ -74,9 +76,9 @@ public class FaultTolerantStepFactoryBeanNonBufferingTests { public void testSkip() throws Exception { @SuppressWarnings("unchecked") SkipListener skipListener = createStrictMock(SkipListener.class); - skipListener.onSkipInWrite("3", SkipWriterStub.exception); + skipListener.onSkipInWrite("3", exception); expectLastCall().once(); - skipListener.onSkipInWrite("4", SkipWriterStub.exception); + skipListener.onSkipInWrite("4", exception); expectLastCall().once(); replay(skipListener); @@ -114,8 +116,6 @@ public class FaultTolerantStepFactoryBeanNonBufferingTests { protected final Log logger = LogFactory.getLog(getClass()); - private static final SkippableRuntimeException exception = new SkippableRuntimeException("exception in writer"); - // simulate transactional output private List written = TransactionAwareProxyFactory.createTransactionalList(); @@ -145,16 +145,4 @@ public class FaultTolerantStepFactoryBeanNonBufferingTests { } - private static class SkippableException extends Exception { - public SkippableException(String message) { - super(message); - } - } - - private static class SkippableRuntimeException extends RuntimeException { - public SkippableRuntimeException(String message) { - super(message); - } - } - } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanRollbackTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanRollbackTests.java index 52c54c28b..ec7d02ca1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanRollbackTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanRollbackTests.java @@ -4,10 +4,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -22,13 +20,7 @@ import org.springframework.batch.core.Step; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean; -import org.springframework.batch.item.ItemProcessor; -import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.ParseException; -import org.springframework.batch.item.UnexpectedInputException; import org.springframework.batch.support.transaction.ResourcelessTransactionManager; -import org.springframework.batch.support.transaction.TransactionAwareProxyFactory; import org.springframework.transaction.interceptor.RollbackRuleAttribute; import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute; import org.springframework.transaction.interceptor.TransactionAttribute; @@ -44,11 +36,9 @@ public class FaultTolerantStepFactoryBeanRollbackTests { private FaultTolerantStepFactoryBean factory; - private static Collection NO_FAILURES = Collections.emptyList(); + private SkipReaderStub reader = new SkipReaderStub("1", "2", "3", "4", "5"); - private SkipReaderStub reader = new SkipReaderStub(); - - private SkipWriterStub writer = new SkipWriterStub(); + private SkipWriterStub writer = new SkipWriterStub(); private JobExecution jobExecution; @@ -56,19 +46,17 @@ public class FaultTolerantStepFactoryBeanRollbackTests { private JobRepository repository; - private static boolean runtimeException = false; - @Before public void setUp() throws Exception { factory = new FaultTolerantStepFactoryBean(); - + factory.setBeanName("stepName"); factory.setTransactionManager(new ResourcelessTransactionManager()); factory.setCommitInterval(2); factory.setItemReader(reader); factory.setItemWriter(writer); factory.setSkipLimit(2); - + @SuppressWarnings("unchecked") Collection> skippableExceptions = Arrays .> asList(Exception.class); @@ -121,11 +109,11 @@ public class FaultTolerantStepFactoryBeanRollbackTests { */ @Test public void testReaderDefaultNoRollbackOnCheckedException() throws Exception { - factory.setItemReader(new SkipReaderStub(new String[] { "1", "2", "3", "4" }, Arrays.asList("2", "3"))); + factory.setItemReader(new SkipReaderStub(new String[] { "1", "2", "3", "4" }, Arrays.asList("2", "3"), + false)); Step step = (Step) factory.getObject(); - runtimeException = false; step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); @@ -137,7 +125,8 @@ public class FaultTolerantStepFactoryBeanRollbackTests { */ @Test public void testReaderAttributesOverrideSkippableNoRollback() throws Exception { - factory.setItemReader(new SkipReaderStub(new String[] { "1", "2", "3", "4" }, Arrays.asList("2", "3"))); + factory.setItemReader(new SkipReaderStub(new String[] { "1", "2", "3", "4" }, Arrays.asList("2", "3"), + false)); // No skips by default factory.setSkippableExceptionClasses(new HashSet>()); @@ -146,7 +135,6 @@ public class FaultTolerantStepFactoryBeanRollbackTests { Step step = (Step) factory.getObject(); - runtimeException = false; step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); @@ -159,16 +147,14 @@ public class FaultTolerantStepFactoryBeanRollbackTests { */ @Test public void testProcessorDefaultRollbackOnCheckedException() throws Exception { - SkipProcessorStub processor = new SkipProcessorStub(Arrays.asList(StringUtils - .commaDelimitedListToStringArray("1,3"))); + SkipProcessorStub processor = new SkipProcessorStub(false, "1", "3"); factory.setItemProcessor(processor); - factory.setItemReader(new SkipReaderStub(new String[] { "1", "2", "3", "4" }, NO_FAILURES)); - factory.setItemWriter(new SkipWriterStub(NO_FAILURES)); + factory.setItemReader(new SkipReaderStub(new String[] { "1", "2", "3", "4" })); + factory.setItemWriter(new SkipWriterStub()); Step step = (Step) factory.getObject(); - runtimeException = false; step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); @@ -180,16 +166,14 @@ public class FaultTolerantStepFactoryBeanRollbackTests { */ @Test public void testProcessorDefaultRollbackOnRuntimeException() throws Exception { - SkipProcessorStub processor = new SkipProcessorStub(Arrays.asList(StringUtils - .commaDelimitedListToStringArray("1,3"))); + SkipProcessorStub processor = new SkipProcessorStub(true, "1", "3"); factory.setItemProcessor(processor); - factory.setItemReader(new SkipReaderStub(new String[] { "1", "2", "3", "4" }, NO_FAILURES)); - factory.setItemWriter(new SkipWriterStub(NO_FAILURES)); + factory.setItemReader(new SkipReaderStub(new String[] { "1", "2", "3", "4" })); + factory.setItemWriter(new SkipWriterStub()); Step step = (Step) factory.getObject(); - runtimeException = true; step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); @@ -199,14 +183,13 @@ public class FaultTolerantStepFactoryBeanRollbackTests { @Test public void testProcessSkipWithNoRollbackForCheckedException() throws Exception { - reader = new SkipReaderStub(new String[] { "1", "2", "3", "4", "5" }, NO_FAILURES); + reader = new SkipReaderStub(new String[] { "1", "2", "3", "4", "5" }); factory.setItemReader(reader); factory.setNoRollbackExceptionClasses(getExceptionList(SkippableException.class)); - SkipProcessorStub processor = new SkipProcessorStub(Arrays.asList(new String[] { "4" })); + SkipProcessorStub processor = new SkipProcessorStub(false, "4"); factory.setItemProcessor(processor); Step step = (Step) factory.getObject(); - runtimeException = false; step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); @@ -217,11 +200,11 @@ public class FaultTolerantStepFactoryBeanRollbackTests { assertEquals(0, stepExecution.getRollbackCount()); // skips "4" - assertTrue(reader.processed.contains("4")); - assertFalse(writer.written.contains("4")); + assertTrue(reader.getRead().contains("4")); + assertFalse(writer.getCommitted().contains("4")); List expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,2,3,5")); - assertEquals(expectedOutput, writer.written); + assertEquals(expectedOutput, writer.getCommitted()); } @@ -230,11 +213,10 @@ public class FaultTolerantStepFactoryBeanRollbackTests { */ @Test public void testWriterDefaultRollbackOnCheckedException() throws Exception { - factory.setItemWriter(new SkipWriterStub(Arrays.asList("2", "3"))); + factory.setItemWriter(new SkipWriterStub(false, "2", "3")); Step step = (Step) factory.getObject(); - runtimeException = false; step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); @@ -246,11 +228,10 @@ public class FaultTolerantStepFactoryBeanRollbackTests { */ @Test public void testWriterDefaultRollbackOnRuntimeException() throws Exception { - factory.setItemWriter(new SkipWriterStub(Arrays.asList("2", "3"))); + factory.setItemWriter(new SkipWriterStub(true, "2", "3")); Step step = (Step) factory.getObject(); - runtimeException = true; step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); @@ -263,12 +244,11 @@ public class FaultTolerantStepFactoryBeanRollbackTests { */ @Test public void testWriterNoRollbackOnRuntimeException() throws Exception { - factory.setItemWriter(new SkipWriterStub(Arrays.asList("2", "3"))); + factory.setItemWriter(new SkipWriterStub(true, "2", "3")); factory.setNoRollbackExceptionClasses(getExceptionList(SkippableRuntimeException.class)); Step step = (Step) factory.getObject(); - runtimeException = true; step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); @@ -283,12 +263,11 @@ public class FaultTolerantStepFactoryBeanRollbackTests { */ @Test public void testWriterNoRollbackOnCheckedException() throws Exception { - factory.setItemWriter(new SkipWriterStub(Arrays.asList("2", "3"))); + factory.setItemWriter(new SkipWriterStub(false, "2", "3")); factory.setNoRollbackExceptionClasses(getExceptionList(SkippableException.class)); Step step = (Step) factory.getObject(); - runtimeException = false; step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); @@ -303,127 +282,4 @@ public class FaultTolerantStepFactoryBeanRollbackTests { return Arrays.> asList(args); } - private static class SkipProcessorStub implements ItemProcessor { - private final Collection failures; - - public SkipProcessorStub() { - this(NO_FAILURES); - } - - public SkipProcessorStub(Collection failures) { - this.failures = failures; - } - - public String process(String item) throws Exception { - if (failures.contains(item)) { - if (runtimeException) { - throw new SkippableRuntimeException("should cause rollback"); - } - else { - throw new SkippableException("shouldn't cause rollback"); - } - } - return item; - } - } - - /** - * Simple item reader that supports skip functionality. - */ - private static class SkipReaderStub implements ItemReader { - - protected final Log logger = LogFactory.getLog(getClass()); - - private final String[] items; - - private Collection processed = new ArrayList(); - - private int counter = -1; - - private final Collection failures; - - public SkipReaderStub() { - this(new String[] { "1", "2", "3", "4", "5" }, NO_FAILURES); - } - - public SkipReaderStub(String[] items, Collection failures) { - this.items = items; - this.failures = failures; - } - - public String read() throws Exception, UnexpectedInputException, ParseException { - counter++; - if (counter >= items.length) { - logger.debug("Returning null at count=" + counter); - return null; - } - String item = items[counter]; - if (failures.contains(item)) { - logger.debug("Throwing exception for [" + item + "] at count=" + counter); - if (runtimeException) { - throw new SkippableRuntimeException("should cause rollback in reader"); - } - else { - throw new SkippableException("shouldn't cause rollback in reader"); - } - } - processed.add(item); - logger.debug("Returning [" + item + "] at count=" + counter); - return item; - } - - } - - /** - * Simple item writer that supports skip functionality. - */ - private static class SkipWriterStub implements ItemWriter { - - protected final Log logger = LogFactory.getLog(getClass()); - - // simulate transactional output - private List written = TransactionAwareProxyFactory.createTransactionalList(); - - private final Collection failures; - - public SkipWriterStub() { - this(NO_FAILURES); - } - - /** - * @param failures commaDelimitedListToSet - */ - public SkipWriterStub(Collection failures) { - this.failures = failures; - } - - public void write(List items) throws Exception { - for (String item : items) { - if (failures.contains(item)) { - logger.debug("Throwing write exception on [" + item + "]"); - if (runtimeException) { - throw new SkippableRuntimeException("should cause rollback in writer"); - } - else { - throw new SkippableException("shouldn't cause rollback in writer"); - } - } - written.add(item); - } - } - - } - - private static class SkippableException extends Exception { - public SkippableException(String message) { - super(message); - } - } - - private static class SkippableRuntimeException extends RuntimeException { - public SkippableRuntimeException(String message) { - super(message); - } - } - } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanTests.java index 725af9d4e..31cac42a5 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanTests.java @@ -47,7 +47,6 @@ import org.springframework.batch.item.WriteFailedException; import org.springframework.batch.item.WriterNotOpenException; import org.springframework.batch.item.support.ListItemReader; import org.springframework.batch.support.transaction.ResourcelessTransactionManager; -import org.springframework.batch.support.transaction.TransactionAwareProxyFactory; import org.springframework.beans.factory.FactoryBean; import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor; import org.springframework.test.util.ReflectionTestUtils; @@ -62,9 +61,10 @@ public class FaultTolerantStepFactoryBeanTests { private FaultTolerantStepFactoryBean factory; - private SkipReaderStub reader = new SkipReaderStub(); + private SkipReaderStub reader = new SkipReaderStub(new String[] { "1", "2", "3", "4", "5" }, + Collections.singleton("2")); - private SkipWriterStub writer = new SkipWriterStub(); + private SkipWriterStub writer = new SkipWriterStub("4"); private JobExecution jobExecution; @@ -80,8 +80,6 @@ public class FaultTolerantStepFactoryBeanTests { private boolean closed = false; - private Collection NO_FAILURES = Collections.emptyList(); - @Before public void setUp() throws Exception { factory = new FaultTolerantStepFactoryBean(); @@ -147,7 +145,7 @@ public class FaultTolerantStepFactoryBeanTests { factory.setCommitInterval(1); // no failures on read - reader = new SkipReaderStub(new String[] { "1", "2", "3", "4", "5" }, new ArrayList()); + reader = new SkipReaderStub(new String[] { "1", "2", "3", "4", "5" }); factory.setItemReader(reader); factory.setItemWriter(new ItemWriter() { @@ -161,7 +159,7 @@ public class FaultTolerantStepFactoryBeanTests { step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); - assertEquals(1, reader.processed.size()); + assertEquals(1, reader.getRead().size()); assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode()); assertTrue(stepExecution.getExitStatus().getExitDescription().contains("non-skippable exception")); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step @@ -174,13 +172,13 @@ public class FaultTolerantStepFactoryBeanTests { @Test public void testReadSkip() throws Exception { - writer = new SkipWriterStub(NO_FAILURES); + writer = new SkipWriterStub(); factory.setItemWriter(writer); Step step = (Step) factory.getObject(); step.execute(stepExecution); - System.err.println(writer.written); + System.err.println(writer.getWritten()); assertEquals(1, stepExecution.getSkipCount()); assertEquals(1, stepExecution.getReadSkipCount()); @@ -189,11 +187,11 @@ public class FaultTolerantStepFactoryBeanTests { assertEquals(0, stepExecution.getRollbackCount()); // writer did not skip "2" as it never made it to writer, only "4" did - assertTrue(reader.processed.contains("4")); - assertFalse(reader.processed.contains("2")); + assertTrue(reader.getRead().contains("4")); + assertFalse(reader.getRead().contains("2")); List expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,3,4,5")); - assertEquals(expectedOutput, writer.written); + assertEquals(expectedOutput, writer.getWritten()); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step @@ -206,11 +204,11 @@ public class FaultTolerantStepFactoryBeanTests { @Test public void testProcessSkip() throws Exception { - reader = new SkipReaderStub(new String[] { "1", "2", "3", "4", "5" }, NO_FAILURES); + reader = new SkipReaderStub(new String[] { "1", "2", "3", "4", "5" }); factory.setItemReader(reader); - writer = new SkipWriterStub(NO_FAILURES); + writer = new SkipWriterStub(); factory.setItemWriter(writer); - SkipProcessorStub processor = new SkipProcessorStub(Arrays.asList(new String[] { "4" })); + SkipProcessorStub processor = new SkipProcessorStub("4"); factory.setItemProcessor(processor); Step step = (Step) factory.getObject(); @@ -223,11 +221,11 @@ public class FaultTolerantStepFactoryBeanTests { assertEquals(1, stepExecution.getRollbackCount()); // writer skips "4" - assertTrue(reader.processed.contains("4")); - assertFalse(writer.written.contains("4")); + assertTrue(reader.getRead().contains("4")); + assertFalse(writer.getWritten().contains("4")); List expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,2,3,5")); - assertEquals(expectedOutput, writer.written); + assertEquals(expectedOutput, writer.getWritten()); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step @@ -237,9 +235,9 @@ public class FaultTolerantStepFactoryBeanTests { @Test public void testProcessFilter() throws Exception { - reader = new SkipReaderStub(new String[] { "1", "2", "3", "4", "5" }, NO_FAILURES); + reader = new SkipReaderStub(new String[] { "1", "2", "3", "4", "5" }); factory.setItemReader(reader); - writer = new SkipWriterStub(NO_FAILURES); + writer = new SkipWriterStub(); factory.setItemWriter(writer); FilterProcessorStub processor = new FilterProcessorStub(Arrays.asList(new String[] { "4" })); factory.setItemProcessor(processor); @@ -257,11 +255,11 @@ public class FaultTolerantStepFactoryBeanTests { assertTrue(listenerStub.isFilterEncountered()); // writer skips "4" - assertTrue(reader.processed.contains("4")); - assertFalse(writer.written.contains("4")); + assertTrue(reader.getRead().contains("4")); + assertFalse(writer.getWritten().contains("4")); List expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,2,3,5")); - assertEquals(expectedOutput, writer.written); + assertEquals(expectedOutput, writer.getWritten()); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step @@ -274,7 +272,7 @@ public class FaultTolerantStepFactoryBeanTests { @Test public void testWriteSkip() throws Exception { - reader = new SkipReaderStub(new String[] { "1", "2", "3", "4", "5" }, NO_FAILURES); + reader = new SkipReaderStub(new String[] { "1", "2", "3", "4", "5" }); factory.setItemReader(reader); Step step = (Step) factory.getObject(); @@ -287,11 +285,11 @@ public class FaultTolerantStepFactoryBeanTests { assertEquals(2, stepExecution.getRollbackCount()); // writer skips "4" - assertTrue(reader.processed.contains("4")); - assertFalse(writer.written.contains("4")); + assertTrue(reader.getRead().contains("4")); + assertFalse(writer.getCommitted().contains("4")); List expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,2,3,5")); - assertEquals(expectedOutput, writer.written); + assertEquals(expectedOutput, writer.getCommitted()); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step @@ -306,7 +304,7 @@ public class FaultTolerantStepFactoryBeanTests { public void testFatalException() throws Exception { factory.setFatalExceptionClasses(Collections .> singleton(FatalRuntimeException.class)); - factory.setItemWriter(new SkipWriterStub() { + factory.setItemWriter(new SkipWriterStub() { public void write(List items) { throw new FatalRuntimeException("Ouch!"); } @@ -335,12 +333,12 @@ public class FaultTolerantStepFactoryBeanTests { assertEquals(1, stepExecution.getSkipCount()); // writer did not skip "2" as it never made it to writer, only "4" did - assertTrue(reader.processed.contains("4")); - assertFalse(writer.written.contains("4")); + assertTrue(reader.getRead().contains("4")); + assertFalse(writer.getCommitted().contains("4")); // failure on "4" tripped the skip limit so we never got to "5" List expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,3")); - assertEquals(expectedOutput, writer.written); + assertEquals(expectedOutput, writer.getCommitted()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); } @@ -351,7 +349,7 @@ public class FaultTolerantStepFactoryBeanTests { @Test public void testSkipOverLimitOnRead() throws Exception { - reader = new SkipReaderStub(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6"), Arrays + reader = new SkipReaderStub(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6"), Arrays .asList(StringUtils.commaDelimitedListToStringArray("2,3,5"))); factory.setSkipLimit(3); @@ -368,12 +366,12 @@ public class FaultTolerantStepFactoryBeanTests { assertEquals(1, stepExecution.getWriteSkipCount()); // writer did not skip "2" as it never made it to writer, only "4" did - assertFalse(reader.processed.contains("2")); - assertTrue(reader.processed.contains("4")); + assertFalse(reader.getRead().contains("2")); + assertTrue(reader.getRead().contains("4")); // only "1" was ever committed List expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1")); - assertEquals(expectedOutput, writer.written); + assertEquals(expectedOutput, writer.getCommitted()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); } @@ -384,7 +382,7 @@ public class FaultTolerantStepFactoryBeanTests { @Test public void testSkipListenerFailsOnRead() throws Exception { - reader = new SkipReaderStub(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6"), Arrays + reader = new SkipReaderStub(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6"), Arrays .asList(StringUtils.commaDelimitedListToStringArray("2,3,5"))); factory.setSkipLimit(3); @@ -419,8 +417,7 @@ public class FaultTolerantStepFactoryBeanTests { @Test public void testSkipListenerFailsOnWrite() throws Exception { - reader = new SkipReaderStub(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6"), Collections - . emptyList()); + reader = new SkipReaderStub(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6")); factory.setSkipLimit(3); factory.setItemReader(reader); @@ -450,7 +447,7 @@ public class FaultTolerantStepFactoryBeanTests { @Test public void testSkipOnReadNotDoubleCounted() throws Exception { - reader = new SkipReaderStub(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6"), Arrays + reader = new SkipReaderStub(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6"), Arrays .asList(StringUtils.commaDelimitedListToStringArray("2,3,5"))); factory.setSkipLimit(4); @@ -465,7 +462,7 @@ public class FaultTolerantStepFactoryBeanTests { // skipped 2,3,4,5 List expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,6")); - assertEquals(expectedOutput, writer.written); + assertEquals(expectedOutput, writer.getCommitted()); // reader exceptions should not cause rollback, 1 writer exception // causes 2 rollbacks @@ -480,10 +477,10 @@ public class FaultTolerantStepFactoryBeanTests { @Test public void testSkipOnWriteNotDoubleCounted() throws Exception { - reader = new SkipReaderStub(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6,7"), Arrays + reader = new SkipReaderStub(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6,7"), Arrays .asList(StringUtils.commaDelimitedListToStringArray("2,3"))); - writer = new SkipWriterStub(Arrays.asList(StringUtils.commaDelimitedListToStringArray("4,5"))); + writer = new SkipWriterStub("4", "5"); factory.setSkipLimit(4); factory.setItemReader(reader); @@ -499,7 +496,7 @@ public class FaultTolerantStepFactoryBeanTests { // skipped 2,3,4,5 List expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,6,7")); - assertEquals(expectedOutput, writer.written); + assertEquals(expectedOutput, writer.getCommitted()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); } @@ -537,8 +534,9 @@ public class FaultTolerantStepFactoryBeanTests { @Test public void testSkipOverLimitOnReadWithAllSkipsAtEnd() throws Exception { - reader = new SkipReaderStub(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6,7,8,9,10,11,12,13,14,15"), - Arrays.asList(StringUtils.commaDelimitedListToStringArray("6,12,13,14,15"))); + reader = new SkipReaderStub(StringUtils + .commaDelimitedListToStringArray("1,2,3,4,5,6,7,8,9,10,11,12,13,14,15"), Arrays.asList(StringUtils + .commaDelimitedListToStringArray("6,12,13,14,15"))); factory.setCommitInterval(5); factory.setSkipLimit(3); @@ -554,12 +552,12 @@ public class FaultTolerantStepFactoryBeanTests { assertEquals("bad write skip count", 1, stepExecution.getWriteSkipCount()); // writer did not skip "6" as it never made it to writer, only "4" did - assertFalse(reader.processed.contains("6")); - assertTrue(reader.processed.contains("4")); + assertFalse(reader.getRead().contains("6")); + assertTrue(reader.getRead().contains("4")); // only "1" was ever committed List expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,2,3,5,7,8,9,10,11")); - assertEquals(expectedOutput, writer.written); + assertEquals(expectedOutput, writer.getCommitted()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); } @@ -572,7 +570,7 @@ public class FaultTolerantStepFactoryBeanTests { return item; } }); - factory.setItemReader(new SkipReaderStub(new String[] { "1", "2", "3", "4" }, NO_FAILURES)); + factory.setItemReader(new SkipReaderStub(new String[] { "1", "2", "3", "4" })); Step step = (Step) factory.getObject(); step.execute(stepExecution); @@ -795,29 +793,6 @@ public class FaultTolerantStepFactoryBeanTests { assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); } - private static class SkipProcessorStub implements ItemProcessor { - private final Collection failures; - - private boolean runtimeException = false; - - public SkipProcessorStub(Collection failures) { - this.failures = failures; - } - - public String process(String item) throws Exception { - if (failures.contains(item)) { - if (runtimeException) { - throw new SkippableRuntimeException("should cause rollback"); - } - else { - throw new SkippableException("shouldn't cause rollback"); - } - } - return item; - } - - } - private static class FilterProcessorStub implements ItemProcessor { private final Collection failures; @@ -834,48 +809,6 @@ public class FaultTolerantStepFactoryBeanTests { } - /** - * Simple item reader that supports skip functionality. - */ - private static class SkipReaderStub implements ItemReader { - - protected final Log logger = LogFactory.getLog(getClass()); - - private final String[] items; - - private Collection processed = new ArrayList(); - - private int counter = -1; - - private final Collection failures; - - public SkipReaderStub() { - this(new String[] { "1", "2", "3", "4", "5" }, Collections.singleton("2")); - } - - public SkipReaderStub(String[] items, Collection failures) { - this.items = items; - this.failures = failures; - } - - public String read() throws Exception, UnexpectedInputException, ParseException { - counter++; - if (counter >= items.length) { - logger.debug("Returning null at count=" + counter); - return null; - } - String item = items[counter]; - if (failures.contains(item)) { - logger.debug("Throwing exception for [" + item + "] at count=" + counter); - throw new SkippableException("exception in reader"); - } - processed.add(item); - logger.debug("Returning [" + item + "] at count=" + counter); - return item; - } - - } - private static class ItemProcessListenerStub implements ItemProcessListener { private boolean errorEncountered = false; @@ -905,53 +838,6 @@ public class FaultTolerantStepFactoryBeanTests { } } - /** - * Simple item writer that supports skip functionality. - */ - private static class SkipWriterStub implements ItemWriter { - - protected final Log logger = LogFactory.getLog(getClass()); - - // simulate transactional output - private List written = TransactionAwareProxyFactory.createTransactionalList(); - - private final Collection failures; - - public SkipWriterStub() { - this(Arrays.asList("4")); - } - - /** - * @param failures commaDelimitedListToSet - */ - public SkipWriterStub(Collection failures) { - this.failures = failures; - } - - public void write(List items) throws Exception { - for (String item : items) { - if (failures.contains(item)) { - logger.debug("Throwing write exception on [" + item + "]"); - throw new SkippableRuntimeException("exception in writer"); - } - written.add(item); - } - } - - } - - private static class SkippableException extends Exception { - public SkippableException(String message) { - super(message); - } - } - - private static class SkippableRuntimeException extends RuntimeException { - public SkippableRuntimeException(String message) { - super(message); - } - } - private static class FatalRuntimeException extends SkippableRuntimeException { public FatalRuntimeException(String message) { super(message); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipProcessorStub.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipProcessorStub.java new file mode 100644 index 000000000..fab984191 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipProcessorStub.java @@ -0,0 +1,68 @@ +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.step.item; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.support.transaction.TransactionAwareProxyFactory; + +/** + * @author Dan Garrette + * @since 2.0.1 + */ +public class SkipProcessorStub extends ExceptionThrowingItemHandlerStub implements ItemProcessor { + + private List processed = new ArrayList(); + + private List committed = TransactionAwareProxyFactory.createTransactionalList(); + + public SkipProcessorStub() { + super(); + } + + public SkipProcessorStub(T... failures) { + super(Arrays.asList(failures)); + } + + public SkipProcessorStub(boolean runtimeException, T... failures) { + this(failures); + this.setRuntimeException(runtimeException); + } + + public List getProcessed() { + return processed; + } + + public List getCommitted() { + return committed; + } + + public void clear() { + processed = new ArrayList(); + committed = TransactionAwareProxyFactory.createTransactionalList(); + this.setFailures(new ArrayList()); + } + + public T process(T item) throws Exception { + processed.add(item); + committed.add(item); + checkFailure(item); + return item; + } +} \ No newline at end of file diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipReaderStub.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipReaderStub.java new file mode 100644 index 000000000..5522104fb --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipReaderStub.java @@ -0,0 +1,72 @@ +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.step.item; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ParseException; +import org.springframework.batch.item.UnexpectedInputException; + +/** + * @author Dan Garrette + * @since 2.0.1 + */ +public class SkipReaderStub extends ExceptionThrowingItemHandlerStub implements ItemReader { + + private final T[] items; + + private List read = new ArrayList(); + + private int counter = -1; + + public SkipReaderStub(T... items) { + super(); + this.items = items; + } + + public SkipReaderStub(T[] items, Collection failures) { + super(failures); + this.items = items; + } + + public SkipReaderStub(T[] items, Collection failures, boolean runtimeException) { + this(items, failures); + this.setRuntimeException(runtimeException); + } + + public List getRead() { + return read; + } + + public void clear() { + read = new ArrayList(); + this.setFailures(new ArrayList()); + } + + public T read() throws Exception, UnexpectedInputException, ParseException { + counter++; + if (counter >= items.length) { + return null; + } + T item = items[counter]; + checkFailure(item); + read.add(item); + return item; + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipWriterStub.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipWriterStub.java new file mode 100644 index 000000000..e706bed79 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipWriterStub.java @@ -0,0 +1,69 @@ +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.step.item; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.support.transaction.TransactionAwareProxyFactory; + +/** + * @author Dan Garrette + * @since 2.0.1 + */ +public class SkipWriterStub extends ExceptionThrowingItemHandlerStub implements ItemWriter { + + private List written = new ArrayList(); + + private List committed = TransactionAwareProxyFactory.createTransactionalList(); + + public SkipWriterStub() { + super(); + } + + public SkipWriterStub(T... failures) { + super(Arrays.asList(failures)); + } + + public SkipWriterStub(boolean runtimeException, T... failures) { + this(failures); + this.setRuntimeException(runtimeException); + } + + public List getWritten() { + return written; + } + + public List getCommitted() { + return committed; + } + + public void clear() { + written = new ArrayList(); + committed = TransactionAwareProxyFactory.createTransactionalList(); + this.setFailures(new ArrayList()); + } + + public void write(List items) throws Exception { + for (T item : items) { + written.add(item); + committed.add(item); + checkFailure(item); + } + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkippableException.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkippableException.java new file mode 100644 index 000000000..fb4e1290d --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkippableException.java @@ -0,0 +1,26 @@ +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.step.item; + +/** + * @author Dan Garrette + * @since 2.0.1 + */ +public class SkippableException extends Exception { + public SkippableException(String message) { + super(message); + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkippableRuntimeException.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkippableRuntimeException.java new file mode 100644 index 000000000..2ece29799 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkippableRuntimeException.java @@ -0,0 +1,26 @@ +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.step.item; + +/** + * @author Dan Garrette + * @since 2.0.1 + */ +public class SkippableRuntimeException extends RuntimeException { + public SkippableRuntimeException(String message) { + super(message); + } +}