OPEN - issue BATCH-486: Users must choose between skip and retry

Removed itemReader from retry callback - simplifies stateful retry and makes the ugly exception handling problem go away.
This commit is contained in:
dsyer
2008-03-27 15:21:20 +00:00
parent d983eba1c5
commit 0f84d3064a
10 changed files with 128 additions and 163 deletions

View File

@@ -31,7 +31,7 @@ import org.springframework.batch.retry.context.RetryContextSupport;
import org.springframework.batch.retry.policy.NeverRetryPolicy;
import org.springframework.batch.retry.support.RetryTemplate;
public class ItemReaderRetryCallbackTests extends TestCase {
public class ItemWriterRetryCallbackTests extends TestCase {
List calls = new ArrayList();
@@ -41,12 +41,14 @@ public class ItemReaderRetryCallbackTests extends TestCase {
ListItemReaderRecoverer provider;
ItemReaderRetryCallback callback;
ItemWriterRetryCallback callback;
private AbstractItemWriter writer;
protected void setUp() throws Exception {
super.setUp();
template = new RetryTemplate();
provider = new ListItemReaderRecoverer(Arrays.asList(new String[] { "foo", "bar" })) {
provider = new ListItemReaderRecoverer(Arrays.asList(new String[] { "foo" })) {
public boolean recover(Object data, Throwable cause) {
count++;
calls.add(data);
@@ -56,14 +58,15 @@ public class ItemReaderRetryCallbackTests extends TestCase {
return "key" + (count++);
}
};
callback = new ItemReaderRetryCallback(provider, new AbstractItemWriter() {
writer = new AbstractItemWriter() {
public void write(Object data) {
count++;
if (data.equals("bar")) {
throw new IllegalStateException("Bar detected");
}
}
});
};
callback = new ItemWriterRetryCallback("foo", writer);
}
public void testDoWithRetrySuccessfulFirstTime() throws Exception {
@@ -71,30 +74,15 @@ public class ItemReaderRetryCallbackTests extends TestCase {
assertEquals(1, count);
}
public void testDataExhausted() throws Exception {
provider.read();
provider.read(); // line up a null data item...
try {
template.execute(callback);
}
catch (RetryException e) {
fail("Unexpected RetryException");
}
// The item is null, and is not processed:
assertEquals(0, count);
}
public void testContextInitializedWithItemAndCanRetry() throws Exception {
// We can use the policy to intercept the context and do something with
// the item...
provider.read(); // line up an unsuccessful call...
callback = new ItemWriterRetryCallback("bar", writer);
assertEquals(0, calls.size());
template.setRetryPolicy(new NeverRetryPolicy() {
public boolean canRetry(RetryContext context) {
// ...register the failed item
calls.add("item(" + count + ")=" + context.getAttribute(ItemReaderRetryCallback.ITEM));
calls.add("item(" + count + ")=" + context.getAttribute(ItemWriterRetryCallback.ITEM));
// Do not call the base class method - the attempt counts as
// successful now
if (count < 2) // only retry once
@@ -120,12 +108,12 @@ public class ItemReaderRetryCallbackTests extends TestCase {
public void testContextInitializedWithItemAndRegisterThrowable() throws Exception {
// We can use the policy to intercept the context and do something with
// the item...
provider.read(); // line up an unsuccessful call...
callback = new ItemWriterRetryCallback("bar", writer);
assertEquals(0, calls.size());
template.setRetryPolicy(new NeverRetryPolicy() {
public void registerThrowable(RetryContext context, Throwable throwable) throws TerminatedRetryException {
// ...register the failed item
calls.add("item=" + context.getAttribute(ItemReaderRetryCallback.ITEM));
calls.add("item=" + context.getAttribute(ItemWriterRetryCallback.ITEM));
// Call the base class method so that the next attempt is a
// failure.
super.registerThrowable(context, throwable);
@@ -156,11 +144,12 @@ public class ItemReaderRetryCallbackTests extends TestCase {
}
public void testGetKey() throws Exception {
callback.setKeyGenerator(provider);
assertEquals("key0", callback.getKeyGenerator().getKey("foo"));
}
public void testRecoverWithoutSession() throws Exception {
callback.getRecoverer().recover("foo", null);
provider.recover("foo", null);
assertEquals(1, count);
assertEquals(1, calls.size());
}

View File

@@ -33,13 +33,13 @@ import org.springframework.batch.repeat.support.RepeatSynchronizationManager;
import org.springframework.batch.retry.ListItemReaderRecoverer;
import org.springframework.batch.retry.RetryCallback;
import org.springframework.batch.retry.RetryContext;
import org.springframework.batch.retry.callback.ItemReaderRetryCallback;
import org.springframework.batch.retry.callback.ItemWriterRetryCallback;
import org.springframework.batch.retry.context.RetryContextSupport;
import org.springframework.batch.retry.support.RetryTemplate;
public class ItemReaderRetryPolicyTests extends TestCase {
public class ItemWriterRetryPolicyTests extends TestCase {
private ItemReaderRetryPolicy policy = new ItemReaderRetryPolicy();
private ItemWriterRetryPolicy policy = new ItemWriterRetryPolicy();
private ListItemReaderRecoverer reader;
@@ -67,7 +67,7 @@ public class ItemReaderRetryPolicyTests extends TestCase {
}
public void testOpenSunnyDay() throws Exception {
RetryContext context = policy.open(new ItemReaderRetryCallback(reader, new AbstractItemWriter() {
RetryContext context = policy.open(new ItemWriterRetryCallback("foo", new AbstractItemWriter() {
public void write(Object data) {
count++;
list.add(data);
@@ -76,9 +76,6 @@ public class ItemReaderRetryPolicyTests extends TestCase {
assertNotNull(context);
// we haven't called the processor yet...
assertEquals(0, count);
// but the provider has been accessed:
assertEquals("foo", reader.read());
assertEquals("bar", reader.read());
}
public void testOpenWithWrongCallbackType() {
@@ -98,7 +95,7 @@ public class ItemReaderRetryPolicyTests extends TestCase {
public void testCanRetry() {
policy.setDelegate(new AlwaysRetryPolicy());
RetryContext context = policy.open(new ItemReaderRetryCallback(reader, new AbstractItemWriter() {
RetryContext context = policy.open(new ItemWriterRetryCallback("foo", new AbstractItemWriter() {
public void write(Object data) {
count++;
}
@@ -111,7 +108,7 @@ public class ItemReaderRetryPolicyTests extends TestCase {
public void testRegisterThrowable() {
policy.setDelegate(new NeverRetryPolicy());
RetryContext context = policy.open(new ItemReaderRetryCallback(reader, new AbstractItemWriter() {
RetryContext context = policy.open(new ItemWriterRetryCallback("foo", new AbstractItemWriter() {
public void write(Object data) {
count++;
list.add(data);
@@ -124,7 +121,7 @@ public class ItemReaderRetryPolicyTests extends TestCase {
public void testClose() throws Exception {
policy.setDelegate(new NeverRetryPolicy());
RetryContext context = policy.open(new ItemReaderRetryCallback(reader, new AbstractItemWriter() {
RetryContext context = policy.open(new ItemWriterRetryCallback("foo", new AbstractItemWriter() {
public void write(Object data) {
count++;
list.add(data);
@@ -137,13 +134,10 @@ public class ItemReaderRetryPolicyTests extends TestCase {
// still can't retry, even if policy is closed
// (not that this would happen in practice)...
assertFalse(policy.canRetry(context));
// The provider has been accessed only once:
assertEquals("foo", reader.read());
assertEquals("bar", reader.read());
}
public void testOpenTwice() throws Exception {
ItemReaderRetryCallback callback = new ItemReaderRetryCallback(reader, new AbstractItemWriter() {
ItemWriterRetryCallback callback = new ItemWriterRetryCallback("foo", new AbstractItemWriter() {
public void write(Object data) {
count++;
list.add(data);
@@ -165,19 +159,16 @@ public class ItemReaderRetryPolicyTests extends TestCase {
assertFalse(policy.canRetry(context));
policy.close(context);
// The provider has been accessed twice, so this
// mimics a message receive by repeating the value of the first
// message...
assertEquals("bar", reader.read());
}
public void testRecover() throws Exception {
policy = new ItemReaderRetryPolicy();
policy = new ItemWriterRetryPolicy();
policy.setDelegate(new SimpleRetryPolicy(1));
ItemReaderRetryCallback callback = new ItemReaderRetryCallback(reader, new AbstractItemWriter() {
ItemWriterRetryCallback callback = new ItemWriterRetryCallback("foo", new AbstractItemWriter() {
public void write(Object data) {
}
});
callback.setRecoverer(reader);
RetryContext context = policy.open(callback, null);
assertNotNull(context);
assertTrue(policy.canRetry(context));
@@ -202,22 +193,24 @@ public class ItemReaderRetryPolicyTests extends TestCase {
}
public void testFailedItemIdentifier() throws Exception {
policy = new ItemReaderRetryPolicy();
policy = new ItemWriterRetryPolicy();
policy.setDelegate(new SimpleRetryPolicy(1));
MockFailedItemProvider provider = new MockFailedItemProvider(Collections.EMPTY_LIST);
ItemReaderRetryCallback callback = new ItemReaderRetryCallback(provider, null);
ItemWriterRetryCallback callback = new ItemWriterRetryCallback("foo", null);
callback.setFailedItemIdentifier(provider);
policy.open(callback, null);
assertEquals(1, provider.hasFailedCount);
}
public void testRecoverWithTemplate() throws Exception {
policy = new ItemReaderRetryPolicy();
policy = new ItemWriterRetryPolicy();
policy.setDelegate(new SimpleRetryPolicy(1));
ItemReaderRetryCallback callback = new ItemReaderRetryCallback(reader, new AbstractItemWriter() {
ItemWriterRetryCallback callback = new ItemWriterRetryCallback("foo", new AbstractItemWriter() {
public void write(Object data) {
throw new RuntimeException("Barf!");
}
});
callback.setRecoverer(reader);
RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(policy);
Object result = null;
@@ -236,7 +229,7 @@ public class ItemReaderRetryPolicyTests extends TestCase {
}
public void testExhaustedClearsHistoryAfterLastAttempt() throws Exception {
ItemReaderRetryCallback callback = new ItemReaderRetryCallback(reader, new AbstractItemWriter() {
ItemWriterRetryCallback callback = new ItemWriterRetryCallback("foo", new AbstractItemWriter() {
public void write(Object data) {
count++;
list.add(data);
@@ -262,9 +255,9 @@ public class ItemReaderRetryPolicyTests extends TestCase {
}
public void testRetryCount() throws Exception {
policy = new ItemReaderRetryPolicy();
policy = new ItemWriterRetryPolicy();
policy.setDelegate(new SimpleRetryPolicy(1));
RetryContext context = policy.open(new ItemReaderRetryCallback(reader, new AbstractItemWriter() {
RetryContext context = policy.open(new ItemWriterRetryCallback("foo", new AbstractItemWriter() {
public void write(Object data) {
count++;
list.add(data);
@@ -279,14 +272,14 @@ public class ItemReaderRetryPolicyTests extends TestCase {
}
public void testRetryCountPreservedBetweenRetries() throws Exception {
ItemReaderRetryCallback callback = new ItemReaderRetryCallback(reader, new AbstractItemWriter() {
ItemWriterRetryCallback callback = new ItemWriterRetryCallback("bar", new AbstractItemWriter() {
public void write(Object data) {
count++;
list.add(data);
}
});
policy = new ItemReaderRetryPolicy();
policy = new ItemWriterRetryPolicy();
policy.setDelegate(new SimpleRetryPolicy(1));
RetryContext context = policy.open(callback, null);
assertNotNull(context);