OPEN - issue BATCH-777: Parametrise RetryCallback and related interfaces
RetryCallback and RecoveryCallback done
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user