OPEN - issue BATCH-777: Parametrise RetryCallback and related interfaces

RetryCallback and RecoveryCallback done
This commit is contained in:
dsyer
2008-08-25 14:06:57 +00:00
parent 919e9b5489
commit 6e36093b2e
26 changed files with 144 additions and 211 deletions

View File

@@ -86,7 +86,7 @@ public class SimpleRetryExceptionHandler extends RetryListenerSupport implements
* @see org.springframework.batch.retry.RetryListener#close(org.springframework.batch.retry.RetryContext,
* org.springframework.batch.retry.RetryCallback, java.lang.Throwable)
*/
public void close(RetryContext context, RetryCallback callback, Throwable throwable) {
public <T> void close(RetryContext context, RetryCallback<T> callback, Throwable throwable) {
if (!retryPolicy.canRetry(context)) {
getRepeatContext().setAttribute(EXHAUSTED, "true");
}

View File

@@ -432,7 +432,7 @@ public class SkipLimitStepFactoryBean<T, S> extends SimpleStepFactoryBean<T, S>
*/
private void retryChunk(final Chunk<S> chunk, final StepContribution contribution) throws Exception {
RetryCallback retryCallback = new RetryCallback() {
RetryCallback<Object> retryCallback = new RetryCallback<Object>() {
public Object doWithRetry(RetryContext context) throws Exception {
doWrite(chunk.getItems());
// TODO: if there is an exception marked as no rollback it
@@ -441,7 +441,7 @@ public class SkipLimitStepFactoryBean<T, S> extends SimpleStepFactoryBean<T, S>
}
};
RecoveryCallback recoveryCallback = new RecoveryCallback() {
RecoveryCallback<Object> recoveryCallback = new RecoveryCallback<Object>() {
public Object recover(RetryContext context) throws Exception {

View File

@@ -122,14 +122,14 @@ public class BatchMessageListenerContainerIntegrationTests {
container.setMessageListener(new MessageListener() {
public void onMessage(final Message msg) {
try {
RetryCallback callback = new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
RetryCallback<Message> callback = new RetryCallback<Message>() {
public Message doWithRetry(RetryContext context) throws Exception {
count++;
throw new RuntimeException("planned failure: " + msg);
}
};
RecoveryCallback recoveryCallback = new RecoveryCallback() {
public Object recover(RetryContext context) {
RecoveryCallback<Message> recoveryCallback = new RecoveryCallback<Message>() {
public Message recover(RetryContext context) {
recovered++;
return msg;
}

View File

@@ -82,13 +82,13 @@ public class ExternalRetryInBatchTests {
jmsTemplate.convertAndSend("queue", "foo");
jmsTemplate.convertAndSend("queue", "bar");
provider = new ItemReaderRecoverer() {
public Object read() {
public String read() {
String text = (String) jmsTemplate.receiveAndConvert("queue");
list.add(text);
return text;
}
public Object recover(Object data, Throwable cause) {
public String recover(String data, Throwable cause) {
recovered.add(data);
return data;
}
@@ -131,14 +131,14 @@ public class ExternalRetryInBatchTests {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
final Object item = provider.read();
final String item = provider.read();
if (item==null) {
return ExitStatus.FINISHED;
}
RetryCallback callback = new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
RetryCallback<String> callback = new RetryCallback<String>() {
public String doWithRetry(RetryContext context) throws Exception {
// No need for transaction here: the whole batch will roll
// back. When it comes back for recovery this code is not
// executed...
@@ -149,8 +149,8 @@ public class ExternalRetryInBatchTests {
}
};
RecoveryCallback recoveryCallback = new RecoveryCallback() {
public Object recover(RetryContext context) {
RecoveryCallback<String> recoveryCallback = new RecoveryCallback<String>() {
public String recover(RetryContext context) {
// aggressive commit on a recovery
RepeatSynchronizationManager.setCompleteOnly();
return provider.recover(item, context.getLastThrowable());
@@ -212,7 +212,7 @@ public class ExternalRetryInBatchTests {
return msgs;
}
private interface ItemReaderRecoverer extends ItemReader<Object>, ItemRecoverer {
private interface ItemReaderRecoverer extends ItemReader<String>, ItemRecoverer<String,String> {
}
}

View File

@@ -79,7 +79,7 @@ public class ExternalRetryTests {
return text;
}
public Object recover(Object data, Throwable cause) {
public String recover(String data, Throwable cause) {
recovered.add(data);
return data;
}
@@ -126,7 +126,7 @@ public class ExternalRetryTests {
public Object doInTransaction(TransactionStatus status) {
try {
final Object item = provider.read();
RetryCallback callback = new RetryCallback() {
RetryCallback<Object> callback = new RetryCallback<Object>() {
public Object doWithRetry(RetryContext context) throws Exception {
writer.write(Collections.singletonList(item));
return null;
@@ -153,8 +153,8 @@ public class ExternalRetryTests {
new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
try {
final Object item = provider.read();
RetryCallback callback = new RetryCallback() {
final String item = provider.read();
RetryCallback<Object> callback = new RetryCallback<Object>() {
public Object doWithRetry(RetryContext context) throws Exception {
writer.write(Collections.singletonList(item));
return null;
@@ -186,25 +186,25 @@ public class ExternalRetryTests {
assertInitialState();
final Object item = provider.read();
final RetryCallback callback = new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
final String item = provider.read();
final RetryCallback<String> callback = new RetryCallback<String>() {
public String doWithRetry(RetryContext context) throws Exception {
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), item);
throw new RuntimeException("Rollback!");
}
};
final RecoveryCallback recoveryCallback = new RecoveryCallback() {
public Object recover(RetryContext context) {
final RecoveryCallback<String> recoveryCallback = new RecoveryCallback<String>() {
public String recover(RetryContext context) {
return provider.recover(item, context.getLastThrowable());
}
};
Object result = "start";
String result = "start";
for (int i = 0; i < 4; i++) {
try {
result = new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
result = (String) new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
try {
return retryTemplate.execute(callback, recoveryCallback, new RetryState(item));
@@ -254,7 +254,7 @@ public class ExternalRetryTests {
return msgs;
}
private interface ItemReaderRecoverer<T> extends ItemReader<T>, ItemRecoverer {
private interface ItemReaderRecoverer<T> extends ItemReader<T>, ItemRecoverer<T,T> {
}

View File

@@ -124,12 +124,12 @@ public class SynchronousTests {
final String text = (String) jmsTemplate.receiveAndConvert("queue");
assertNotNull(text);
retryTemplate.execute(new RetryCallback() {
public Object doWithRetry(RetryContext status) throws Exception {
retryTemplate.execute(new RetryCallback<String>() {
public String doWithRetry(RetryContext status) throws Exception {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_NESTED);
return transactionTemplate.execute(new TransactionCallback() {
return (String) transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
list.add(text);
@@ -146,7 +146,7 @@ public class SynchronousTests {
}
});
// Verify the state after stransactional processing is complete
// Verify the state after transactional processing is complete
List<String> msgs = getMessages();
@@ -174,12 +174,12 @@ public class SynchronousTests {
final Object item = provider.read();
retryTemplate.execute(new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
retryTemplate.execute(new RetryCallback<String>() {
public String doWithRetry(RetryContext context) throws Exception {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_NESTED);
return transactionTemplate.execute(new TransactionCallback() {
return (String) transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
list.add(item);
@@ -235,12 +235,12 @@ public class SynchronousTests {
final String text = (String) jmsTemplate.receiveAndConvert("queue");
try {
retryTemplate.execute(new RetryCallback() {
public Object doWithRetry(RetryContext status) throws Exception {
retryTemplate.execute(new RetryCallback<String>() {
public String doWithRetry(RetryContext status) throws Exception {
TransactionTemplate nestedTxTemplate = new TransactionTemplate(transactionManager);
nestedTxTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_NESTED);
return nestedTxTemplate.execute(new TransactionCallback() {
return (String) nestedTxTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus nestedStatus) {
list.add(text);
@@ -290,13 +290,13 @@ public class SynchronousTests {
assertInitialState();
retryTemplate.execute(new RetryCallback() {
public Object doWithRetry(RetryContext status) throws Exception {
retryTemplate.execute(new RetryCallback<String>() {
public String doWithRetry(RetryContext status) throws Exception {
// use REQUIRES_NEW so that the retry executes in its own transaction
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
return transactionTemplate.execute(new TransactionCallback() {
return (String) transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
// The receive is inside the retry and the
@@ -338,16 +338,16 @@ public class SynchronousTests {
try {
retryTemplate.execute(new RetryCallback() {
public Object doWithRetry(RetryContext status) throws Exception {
retryTemplate.execute(new RetryCallback<String>() {
public String doWithRetry(RetryContext status) throws Exception {
// use REQUIRES_NEW so that the retry executes in its own transaction
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
return transactionTemplate.execute(new TransactionCallback() {
return (String) transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
// The receieve is inside the retry and the
// The receive is inside the retry and the
// transaction...
final String text = (String) jmsTemplate.receiveAndConvert("queue");
list.add(text);
@@ -372,7 +372,7 @@ public class SynchronousTests {
// expected
}
// Verify the state after stransactional processing is complete
// Verify the state after transactional processing is complete
List<String> msgs = getMessages();

View File

@@ -16,12 +16,13 @@
package org.springframework.batch.item;
/**
* Strategy interface for recovery action when processing of an item fails.<br/>
*
* @author Dave Syer
*/
public interface ItemRecoverer {
public interface ItemRecoverer<T,S> {
/**
* Recover gracefully from an error. Clients can call this if processing of
@@ -33,7 +34,7 @@ public interface ItemRecoverer {
* the item that failed.
* @param cause
* the cause of the failure that led to this recovery.
* @return true if recovery was successful.
* @return the value to be returned to the caller
*/
Object recover(Object data, Throwable cause);
T recover(S data, Throwable cause);
}

View File

@@ -44,7 +44,7 @@ import org.springframework.util.Assert;
* @author Dave Syer
*
*/
public class JmsItemReader<T> implements ItemReader<T>, ItemRecoverer, ItemKeyGenerator,
public class JmsItemReader<T> implements ItemReader<T>, ItemRecoverer<T,T>, ItemKeyGenerator,
NewItemIdentifier {
protected Log logger = LogFactory.getLog(getClass());
@@ -120,7 +120,7 @@ public class JmsItemReader<T> implements ItemReader<T>, ItemRecoverer, ItemKeyGe
* @see org.springframework.batch.item.ItemRecoverer#recover(Object,
* Throwable)
*/
public Object recover(Object item, Throwable cause) {
public T recover(T item, Throwable cause) {
try {
if (errorDestination != null) {
jmsTemplate.convertAndSend(errorDestination, item);

View File

@@ -22,7 +22,7 @@ package org.springframework.batch.retry;
*
* @since 1.1
*/
public interface RecoveryCallback {
public interface RecoveryCallback<T> {
/**
* @param context the current retry context
@@ -30,6 +30,6 @@ public interface RecoveryCallback {
* failed
* @throws Exception
*/
Object recover(RetryContext context) throws Exception;
T recover(RetryContext context) throws Exception;
}

View File

@@ -21,8 +21,9 @@ package org.springframework.batch.retry;
* {@link RetryOperations}.
*
* @author Rob Harrop
* @author Dave Syer
*/
public interface RetryCallback {
public interface RetryCallback<T> {
/**
* Execute an operation with retry semantics. Operations should generally be
@@ -30,7 +31,7 @@ public interface RetryCallback {
* semantics when an operation is retried.
* @param context the current retry context.
* @return the result of the successful operation.
* @throws Exception TODO
* @throws Exception if processing fails
*/
Object doWithRetry(RetryContext context) throws Exception;
T doWithRetry(RetryContext context) throws Exception;
}

View File

@@ -38,7 +38,7 @@ public interface RetryListener {
* @param callback the current {@link RetryCallback}.
* @return true if the retry should proceed.
*/
boolean open(RetryContext context, RetryCallback callback);
<T> boolean open(RetryContext context, RetryCallback<T> callback);
/**
* Called after the final attempt (successful or not). Allow the interceptor
@@ -49,7 +49,7 @@ public interface RetryListener {
* @param callback the current {@link RetryCallback}.
* @param throwable the last exception that was thrown by the callback.
*/
void close(RetryContext context, RetryCallback callback, Throwable throwable);
<T> void close(RetryContext context, RetryCallback<T> callback, Throwable throwable);
/**
* Called after every unsuccessful attempt at a retry.
@@ -58,5 +58,5 @@ public interface RetryListener {
* @param callback the current {@link RetryCallback}.
* @param throwable the last exception that was thrown by the callback.
*/
void onError(RetryContext context, RetryCallback callback, Throwable throwable);
<T> void onError(RetryContext context, RetryCallback<T> callback, Throwable throwable);
}

View File

@@ -34,7 +34,7 @@ public interface RetryOperations {
* @throws Exception any {@link Exception} raised by the
* {@link RetryCallback} upon unsuccessful retry.
*/
Object execute(RetryCallback retryCallback) throws Exception;
<T> T execute(RetryCallback<T> retryCallback) throws Exception;
/**
* Execute the supplied {@link RetryCallback} with a fallback on exhausted
@@ -46,7 +46,7 @@ public interface RetryOperations {
* @throws Exception any {@link Exception} raised by the
* {@link RecoveryCallback} upon unsuccessful retry.
*/
Object execute(RetryCallback retryCallback, RecoveryCallback recoveryCallback) throws Exception;
<T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback) throws Exception;
/**
* A simple stateful retry. Execute the supplied {@link RetryCallback} with
@@ -66,7 +66,7 @@ public interface RetryOperations {
* @throws ExhaustedRetryException if the last attempt for this state has
* already been reached
*/
Object execute(RetryCallback retryCallback, RetryState retryState) throws Exception, ExhaustedRetryException;
<T> T execute(RetryCallback<T> retryCallback, RetryState retryState) throws Exception, ExhaustedRetryException;
/**
* A stateful retry with a recovery path. Execute the supplied
@@ -81,7 +81,7 @@ public interface RetryOperations {
* @throws Exception any {@link Exception} raised by the
* {@link RecoveryCallback} upon unsuccessful retry.
*/
Object execute(RetryCallback retryCallback, RecoveryCallback recoveryCallback, RetryState retryState)
<T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback, RetryState retryState)
throws Exception;
}

View File

@@ -52,7 +52,7 @@ public class RetryOperationsInterceptor implements MethodInterceptor {
public Object invoke(final MethodInvocation invocation) throws Throwable {
return this.retryOperations.execute(new RetryCallback() {
return this.retryOperations.execute(new RetryCallback<Object>() {
public Object doWithRetry(RetryContext context) throws Exception {

View File

@@ -59,7 +59,7 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor {
private ItemKeyGenerator keyGenerator;
private ItemRecoverer recoverer;
private ItemRecoverer<? extends Object,Object[]> recoverer;
private NewItemIdentifier newItemIdentifier;
@@ -84,7 +84,7 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor {
*
* @param recoverer the {@link ItemRecoverer} to set
*/
public void setRecoverer(ItemRecoverer recoverer) {
public void setRecoverer(ItemRecoverer<? extends Object,Object[]> recoverer) {
this.recoverer = recoverer;
}
@@ -143,7 +143,7 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor {
RetryState retryState = new RetryState(keyGenerator != null ? keyGenerator.getKey(item) : item, newItemIdentifier != null ? newItemIdentifier.isNew(item) : false );
Object result = retryTemplate.execute(new MethodInvocationRetryCallback(invocation), new ItemRecovererCallback(item, recoverer), retryState);
Object result = retryTemplate.execute(new MethodInvocationRetryCallback(invocation), new ItemRecovererCallback(args, recoverer), retryState);
logger.debug("Exiting proxied method in stateful retry with result: (" + result + ")");
@@ -155,7 +155,7 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor {
* @author Dave Syer
*
*/
private static final class MethodInvocationRetryCallback implements RetryCallback {
private static final class MethodInvocationRetryCallback implements RetryCallback<Object> {
/**
*
*/
@@ -188,23 +188,23 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor {
* @author Dave Syer
*
*/
private static final class ItemRecovererCallback implements RecoveryCallback {
private static final class ItemRecovererCallback implements RecoveryCallback<Object> {
private final Object item;
private final Object[] args;
private final ItemRecoverer recoverer;
private final ItemRecoverer<? extends Object,Object[]> recoverer;
/**
* @param item the item that failed.
* @param args the item that failed.
*/
private ItemRecovererCallback(Object item, ItemRecoverer recoverer) {
this.item = item;
private ItemRecovererCallback(Object[] args, ItemRecoverer<? extends Object,Object[]> recoverer) {
this.args = args;
this.recoverer = recoverer;
}
public Object recover(RetryContext context) {
if (recoverer != null) {
return recoverer.recover(item, context.getLastThrowable());
return recoverer.recover(args, context.getLastThrowable());
}
throw new ExhaustedRetryException("Retry was exhausted but there was no recovery path.");
}

View File

@@ -28,13 +28,13 @@ import org.springframework.batch.retry.RetryListener;
*/
public class RetryListenerSupport implements RetryListener {
public void close(RetryContext context, RetryCallback callback, Throwable throwable) {
public <T> void close(RetryContext context, RetryCallback<T> callback, Throwable throwable) {
}
public void onError(RetryContext context, RetryCallback callback, Throwable throwable) {
public <T> void onError(RetryContext context, RetryCallback<T> callback, Throwable throwable) {
}
public boolean open(RetryContext context, RetryCallback callback) {
public <T> boolean open(RetryContext context, RetryCallback<T> callback) {
return true;
}

View File

@@ -135,7 +135,7 @@ public class RetryTemplate implements RetryOperations {
* @throws TerminatedRetryException if the retry has been manually
* terminated through the {@link RetryContext}.
*/
public final Object execute(RetryCallback retryCallback) throws Exception {
public final <T> T execute(RetryCallback<T> retryCallback) throws Exception {
return doExecute(retryCallback, null, null);
}
@@ -150,7 +150,7 @@ public class RetryTemplate implements RetryOperations {
* @throws TerminatedRetryException if the retry has been manually
* terminated through the {@link RetryContext}.
*/
public final Object execute(RetryCallback retryCallback, RecoveryCallback recoveryCallback) throws Exception {
public final <T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback) throws Exception {
return doExecute(retryCallback, recoveryCallback, null);
}
@@ -163,7 +163,7 @@ public class RetryTemplate implements RetryOperations {
*
* @throws ExhaustedRetryException if the retry has been exhausted.
*/
public final Object execute(RetryCallback retryCallback, RetryState retryState) throws Exception,
public final <T> T execute(RetryCallback<T> retryCallback, RetryState retryState) throws Exception,
ExhaustedRetryException {
return doExecute(retryCallback, null, retryState);
}
@@ -175,7 +175,7 @@ public class RetryTemplate implements RetryOperations {
* @see org.springframework.batch.retry.RetryOperations#execute(RetryCallback,
* RetryState)
*/
public final Object execute(RetryCallback retryCallback, RecoveryCallback recoveryCallback, RetryState retryState)
public final <T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback, RetryState retryState)
throws Exception, ExhaustedRetryException {
return doExecute(retryCallback, recoveryCallback, retryState);
}
@@ -188,7 +188,7 @@ public class RetryTemplate implements RetryOperations {
* RecoveryCallback, RetryState)
* @throws ExhaustedRetryException if the retry has been exhausted.
*/
protected Object doExecute(RetryCallback retryCallback, RecoveryCallback recoveryCallback, RetryState state)
protected <T> T doExecute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback, RetryState state)
throws Exception, ExhaustedRetryException {
RetryPolicy retryPolicy = this.retryPolicy;
@@ -369,7 +369,7 @@ public class RetryTemplate implements RetryOperations {
* @throws Exception if the callback does, and if there is no callback then
* definitely the last exception from the context
*/
protected Object handleRetryExhausted(RecoveryCallback recoveryCallback, RetryContext context, RetryState state)
protected <T> T handleRetryExhausted(RecoveryCallback<T> recoveryCallback, RetryContext context, RetryState state)
throws Exception {
if (state != null) {
retryContextCache.remove(state.getKey());
@@ -401,7 +401,7 @@ public class RetryTemplate implements RetryOperations {
return state != null;
}
private boolean doOpenInterceptors(RetryCallback callback, RetryContext context) {
private <T> boolean doOpenInterceptors(RetryCallback<T> callback, RetryContext context) {
boolean result = true;
@@ -413,13 +413,13 @@ public class RetryTemplate implements RetryOperations {
}
private void doCloseInterceptors(RetryCallback callback, RetryContext context, Throwable lastException) {
private <T> void doCloseInterceptors(RetryCallback<T> callback, RetryContext context, Throwable lastException) {
for (int i = listeners.length; i-- > 0;) {
listeners[i].close(context, callback, lastException);
}
}
private void doOnErrorInterceptors(RetryCallback callback, RetryContext context, Throwable throwable) {
private <T> void doOnErrorInterceptors(RetryCallback<T> callback, RetryContext context, Throwable throwable) {
for (int i = listeners.length; i-- > 0;) {
listeners[i].onError(context, callback, throwable);
}

View File

@@ -20,8 +20,8 @@ import junit.framework.TestCase;
public class ItemRecoveryHandlerTests extends TestCase {
ItemRecoverer recoverer = new ItemRecoverer() {
public Object recover(Object data, Throwable cause) {
ItemRecoverer<String, String> recoverer = new ItemRecoverer<String,String>() {
public String recover(String data, Throwable cause) {
return null;
}
};

View File

@@ -1,46 +0,0 @@
/*
* Copyright 2006-2007 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.retry;
import org.springframework.batch.item.ItemKeyGenerator;
import org.springframework.batch.item.ItemRecoverer;
public class StubItemKeyGeneratorRecoverer implements ItemRecoverer, ItemKeyGenerator {
/**
* Do nothing and return null. Subclassses should override to implement
* recovery behaviour.
*
* @see org.springframework.batch.item.ItemRecoverer#recover(java.lang.Object,
* Throwable)
*
* @return null.
*/
public Object recover(Object item, Throwable cause) {
return null;
}
/**
* Return the item (assume it is its own key).
*
* @see org.springframework.batch.item.ItemKeyGenerator#getKey(java.lang.Object)
*/
public Object getKey(Object item) {
return item;
}
}

View File

@@ -170,10 +170,10 @@ public class StatefulRetryOperationsInterceptorTests extends TestCase {
assertTrue("Wrong message: " + message, message.startsWith("Not enough calls"));
}
assertEquals(1, count);
interceptor.setRecoverer(new ItemRecoverer() {
public Object recover(Object data, Throwable cause) {
interceptor.setRecoverer(new ItemRecoverer<Object, Object[]>() {
public Object recover(Object[] data, Throwable cause) {
count++;
return data;
return null;
}
});
service.service("foo");
@@ -192,10 +192,10 @@ public class StatefulRetryOperationsInterceptorTests extends TestCase {
assertTrue("Wrong message: " + message, message.startsWith("Not enough calls"));
}
assertEquals(1, count);
interceptor.setRecoverer(new ItemRecoverer() {
public Object recover(Object data, Throwable cause) {
interceptor.setRecoverer(new ItemRecoverer<Collection<String>, Object[]>() {
public Collection<String> recover(Object[] data, Throwable cause) {
count++;
return Collections.singleton(data);
return Collections.singleton((String)data[0]);
}
});
Collection<String> result = transformer.transform("foo");

View File

@@ -38,20 +38,20 @@ public class RetryListenerTests extends TestCase {
public void testOpenInterceptors() throws Exception {
template.setListeners(new RetryListener[] { new RetryListenerSupport() {
public boolean open(RetryContext context, RetryCallback callback) {
public <T> boolean open(RetryContext context, RetryCallback<T> callback) {
count++;
list.add("1:" + count);
return true;
}
}, new RetryListenerSupport() {
public boolean open(RetryContext context, RetryCallback callback) {
public <T> boolean open(RetryContext context, RetryCallback<T> callback) {
count++;
list.add("2:" + count);
return true;
}
} });
template.execute(new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
template.execute(new RetryCallback<String>() {
public String doWithRetry(RetryContext context) throws Exception {
return null;
}
});
@@ -62,14 +62,14 @@ public class RetryListenerTests extends TestCase {
public void testOpenCanVetoRetry() throws Exception {
template.registerListener(new RetryListenerSupport() {
public boolean open(RetryContext context, RetryCallback callback) {
public <T> boolean open(RetryContext context, RetryCallback<T> callback) {
list.add("1");
return false;
}
});
try {
template.execute(new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
template.execute(new RetryCallback<String>() {
public String doWithRetry(RetryContext context) throws Exception {
count++;
return null;
}
@@ -86,18 +86,18 @@ public class RetryListenerTests extends TestCase {
public void testCloseInterceptors() throws Exception {
template.setListeners(new RetryListener[] { new RetryListenerSupport() {
public void close(RetryContext context, RetryCallback callback, Throwable t) {
public <T> void close(RetryContext context, RetryCallback<T> callback, Throwable t) {
count++;
list.add("1:" + count);
}
}, new RetryListenerSupport() {
public void close(RetryContext context, RetryCallback callback, Throwable t) {
public <T> void close(RetryContext context, RetryCallback<T> callback, Throwable t) {
count++;
list.add("2:" + count);
}
} });
template.execute(new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
template.execute(new RetryCallback<String>() {
public String doWithRetry(RetryContext context) throws Exception {
return null;
}
});
@@ -110,17 +110,17 @@ public class RetryListenerTests extends TestCase {
public void testOnError() throws Exception {
template.setRetryPolicy(new NeverRetryPolicy());
template.setListeners(new RetryListener[] { new RetryListenerSupport() {
public void onError(RetryContext context, RetryCallback callback, Throwable throwable) {
public <T> void onError(RetryContext context, RetryCallback<T> callback, Throwable throwable) {
list.add("1");
}
}, new RetryListenerSupport() {
public void onError(RetryContext context, RetryCallback callback, Throwable throwable) {
public <T> void onError(RetryContext context, RetryCallback<T> callback, Throwable throwable) {
list.add("2");
}
} });
try {
template.execute(new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
template.execute(new RetryCallback<String>() {
public String doWithRetry(RetryContext context) throws Exception {
count++;
throw new IllegalStateException("foo");
}
@@ -140,14 +140,14 @@ public class RetryListenerTests extends TestCase {
public void testCloseInterceptorsAfterRetry() throws Exception {
template.registerListener(new RetryListenerSupport() {
public void close(RetryContext context, RetryCallback callback, Throwable t) {
public <T> void close(RetryContext context, RetryCallback<T> callback, Throwable t) {
list.add("" + count);
// The last attempt should have been successful:
assertNull(t);
}
});
template.execute(new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
template.execute(new RetryCallback<String>() {
public String doWithRetry(RetryContext context) throws Exception {
if (count++ < 1)
throw new RuntimeException("Retry!");
return null;

View File

@@ -44,8 +44,8 @@ public class FatalExceptionRetryPolicyTests extends TestCase {
add(IllegalStateException.class);
}
});
RecoveryCallback recoveryCallback = new RecoveryCallback() {
public Object recover(RetryContext context) throws Exception {
RecoveryCallback<String> recoveryCallback = new RecoveryCallback<String>() {
public String recover(RetryContext context) throws Exception {
return "bar";
}
};
@@ -77,8 +77,8 @@ public class FatalExceptionRetryPolicyTests extends TestCase {
add(IllegalStateException.class);
}
});
RecoveryCallback recoveryCallback = new RecoveryCallback() {
public Object recover(RetryContext context) throws Exception {
RecoveryCallback<String>recoveryCallback = new RecoveryCallback<String>() {
public String recover(RetryContext context) throws Exception {
return "bar";
}
};
@@ -98,15 +98,15 @@ public class FatalExceptionRetryPolicyTests extends TestCase {
assertEquals("bar", result);
}
private static class MockRetryCallback implements RetryCallback {
private static class MockRetryCallback implements RetryCallback<String> {
private int attempts;
private Exception exceptionToThrow = new Exception();
public Object doWithRetry(RetryContext context) throws Exception {
public String doWithRetry(RetryContext context) throws Exception {
this.attempts++;
// Otherwise just barf...
// Just barf...
throw this.exceptionToThrow;
}

View File

@@ -113,10 +113,10 @@ public class StatefulRetryIntegrationTests {
* @author Dave Syer
*
*/
private final class MockRetryCallback implements RetryCallback {
private final class MockRetryCallback implements RetryCallback<String> {
int attempts = 0;
public Object doWithRetry(RetryContext context) throws Exception {
public String doWithRetry(RetryContext context) throws Exception {
attempts++;
if (attempts < 2) {
throw new RuntimeException();

View File

@@ -21,8 +21,6 @@ import junit.framework.TestCase;
import org.springframework.batch.retry.RetryCallback;
import org.springframework.batch.retry.RetryContext;
import org.springframework.batch.retry.context.RetryContextSupport;
import org.springframework.batch.retry.support.RetrySynchronizationManager;
import org.springframework.batch.retry.support.RetryTemplate;
/**
* @author Dave Syer
@@ -43,7 +41,7 @@ public class RetrySynchronizationManagerTests extends TestCase {
RetryContext status = RetrySynchronizationManager.getContext();
assertNull(status);
template.execute(new RetryCallback() {
template.execute(new RetryCallback<Object>() {
public Object doWithRetry(RetryContext status) throws Exception {
RetryContext global = RetrySynchronizationManager.getContext();
assertNotNull(status);

View File

@@ -137,7 +137,7 @@ public class RetryTemplateTests extends TestCase {
public void testEarlyTermination() throws Exception {
try {
RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.execute(new RetryCallback() {
retryTemplate.execute(new RetryCallback<Object>() {
public Object doWithRetry(RetryContext status) throws Exception {
status.setExhaustedOnly();
throw new IllegalStateException("Retry this operation");
@@ -155,11 +155,11 @@ public class RetryTemplateTests extends TestCase {
public void testNestedContexts() throws Exception {
RetryTemplate outer = new RetryTemplate();
final RetryTemplate inner = new RetryTemplate();
outer.execute(new RetryCallback() {
outer.execute(new RetryCallback<Object>() {
public Object doWithRetry(RetryContext status) throws Exception {
context = status;
count++;
Object result = inner.execute(new RetryCallback() {
Object result = inner.execute(new RetryCallback<Object>() {
public Object doWithRetry(RetryContext status) throws Exception {
count++;
assertNotNull(context);
@@ -180,7 +180,7 @@ public class RetryTemplateTests extends TestCase {
RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setRetryPolicy(new NeverRetryPolicy());
try {
retryTemplate.execute(new RetryCallback() {
retryTemplate.execute(new RetryCallback<Object>() {
public Object doWithRetry(RetryContext context) throws Exception {
throw new Error("Realllly bad!");
}
@@ -200,7 +200,7 @@ public class RetryTemplateTests extends TestCase {
}
});
try {
retryTemplate.execute(new RetryCallback() {
retryTemplate.execute(new RetryCallback<Object>() {
public Object doWithRetry(RetryContext context) throws Exception {
throw new RuntimeException("Bad!");
}
@@ -212,7 +212,7 @@ public class RetryTemplateTests extends TestCase {
}
}
private static class MockRetryCallback implements RetryCallback {
private static class MockRetryCallback implements RetryCallback<Object> {
private int attempts;

View File

@@ -94,13 +94,13 @@ public class StatefulRecoveryRetryTests {
retryTemplate.setRetryPolicy(new SimpleRetryPolicy(1));
final String input = "foo";
RetryState state = new RetryState(input);
RetryCallback callback = new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
RetryCallback<String> callback = new RetryCallback<String>() {
public String doWithRetry(RetryContext context) throws Exception {
throw new RuntimeException("Barf!");
}
};
RecoveryCallback recoveryCallback = new RecoveryCallback() {
public Object recover(RetryContext context) {
RecoveryCallback<String> recoveryCallback = new RecoveryCallback<String>() {
public String recover(RetryContext context) {
count++;
list.add(input);
return input;
@@ -128,8 +128,8 @@ public class StatefulRecoveryRetryTests {
final String input = "foo";
RetryState state = new RetryState(input);
RetryCallback callback = new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
RetryCallback<String> callback = new RetryCallback<String>() {
public String doWithRetry(RetryContext context) throws Exception {
throw new RuntimeException("Barf!");
}
};
@@ -163,8 +163,8 @@ public class StatefulRecoveryRetryTests {
final StringHolder item = new StringHolder("bar");
RetryState state = new RetryState(item);
RetryCallback callback = new RetryCallback() {
public Object doWithRetry(RetryContext context) throws Exception {
RetryCallback<StringHolder> callback = new RetryCallback<StringHolder>() {
public StringHolder doWithRetry(RetryContext context) throws Exception {
// This simulates what happens if someone uses a primary key
// for hashCode and equals and then relies on default key
// generator
@@ -195,7 +195,7 @@ public class StatefulRecoveryRetryTests {
retryTemplate.setRetryPolicy(new SimpleRetryPolicy(1));
retryTemplate.setRetryContextCache(new MapRetryContextCache(1));
RetryCallback callback = new RetryCallback() {
RetryCallback<Object> callback = new RetryCallback<Object>() {
public Object doWithRetry(RetryContext context) throws Exception {
count++;
throw new RuntimeException("Barf!");
@@ -229,13 +229,13 @@ public class StatefulRecoveryRetryTests {
final StringHolder item = new StringHolder("foo");
RetryState state = new RetryState(item);
RetryCallback callback = new RetryCallback() {
RetryCallback<Object> callback = new RetryCallback<Object>() {
public Object doWithRetry(RetryContext context) throws Exception {
count++;
throw new RuntimeException("Barf!");
}
};
RecoveryCallback recoveryCallback = new RecoveryCallback() {
RecoveryCallback<Object> recoveryCallback = new RecoveryCallback<Object>() {
public Object recover(RetryContext context) throws Exception {
return null;
}
@@ -260,36 +260,18 @@ public class StatefulRecoveryRetryTests {
private String string;
/**
* @param string
*/
public StringHolder(String string) {
this.string = string;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
return string.equals(((StringHolder) obj).string);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return string.hashCode();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
public String toString() {
return "String: " + string + " (hash = " + hashCode() + ")";
}

View File

@@ -403,16 +403,13 @@ public class PollableSourceRetryTests {
*/
private StatefulRetryOperationsInterceptor getRetryOperationsInterceptor(ItemKeyGenerator itemKeyGenerator) {
StatefulRetryOperationsInterceptor advice = new StatefulRetryOperationsInterceptor();
advice.setRecoverer(new ItemRecoverer() {
advice.setRecoverer(new ItemRecoverer<Boolean, Object[]>() {
@SuppressWarnings("unchecked")
public Object recover(Object data, Throwable cause) {
public Boolean recover(Object[] data, Throwable cause) {
if (data == null) {
return false;
}
if (data.getClass().isArray()) {
data = ((Object[]) data)[0];
}
String payload = ((Message<String>) data).getPayload();
String payload = ((Message<String>) data[0]).getPayload();
logger.debug("Recovering: " + payload);
recovered.add(payload);
return true;