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:
@@ -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());
|
||||
}
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user