If includes is empty and excludes is not, retry not excluded exceptions

Close #108
This commit is contained in:
maciekwiso
2018-03-11 13:41:18 +01:00
committed by Dave Syer
parent 3080803aa4
commit 31586df0a8
5 changed files with 56 additions and 6 deletions

View File

@@ -348,12 +348,13 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
for (Class<? extends Throwable> type : excludes) {
policyMap.put(type, false);
}
boolean retryNotExcluded = includes.length == 0;
if (hasExpression) {
return new ExpressionRetryPolicy(maxAttempts, policyMap, true, exceptionExpression)
return new ExpressionRetryPolicy(maxAttempts, policyMap, true, exceptionExpression, retryNotExcluded)
.withBeanFactory(this.beanFactory);
}
else {
return new SimpleRetryPolicy(maxAttempts, policyMap, true);
return new SimpleRetryPolicy(maxAttempts, policyMap, true, retryNotExcluded);
}
}

View File

@@ -54,7 +54,8 @@ public @interface CircuitBreaker {
/**
* Exception types that are not retryable. Defaults to empty (and if includes is also
* empty all exceptions are retried).
* @return exception types to retry
* If includes is empty but excludes is not, all not excluded exceptions are retried
* @return exception types not to retry
*/
Class<? extends Throwable>[] exclude() default {};

View File

@@ -60,7 +60,8 @@ public @interface Retryable {
/**
* Exception types that are not retryable. Defaults to empty (and if includes is also
* empty all exceptions are retried).
* @return exception types to retry
* If includes is empty but excludes is not, all not excluded exceptions are retried
* @return exception types not to retry
*/
Class<? extends Throwable>[] exclude() default {};

View File

@@ -83,10 +83,11 @@ public class ExpressionRetryPolicy extends SimpleRetryPolicy implements BeanFact
* @param retryableExceptions the exceptions
* @param traverseCauses true to examine causes
* @param expressionString the expression.
* @param defaultValue the default action
*/
public ExpressionRetryPolicy(int maxAttempts, Map<Class<? extends Throwable>, Boolean> retryableExceptions,
boolean traverseCauses, String expressionString) {
super(maxAttempts, retryableExceptions, traverseCauses);
boolean traverseCauses, String expressionString, boolean defaultValue) {
super(maxAttempts, retryableExceptions, traverseCauses, defaultValue);
Assert.notNull(expressionString, "'expressionString' cannot be null");
this.expression = new SpelExpressionParser().parseExpression(expressionString, PARSER_CONTEXT);
}

View File

@@ -130,6 +130,26 @@ public class EnableRetryTests {
context.close();
}
@Test
public void excludesOnly() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
TestConfiguration.class);
ExcludesOnlyService service = context.getBean(ExcludesOnlyService.class);
service.setExceptionToThrow(new IllegalStateException());
try {
service.service();
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
}
assertEquals(1, service.getCount());
service.setExceptionToThrow(new IllegalArgumentException());
service.service();
assertEquals(3, service.getCount());
context.close();
}
@Test
public void stateful() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
@@ -297,6 +317,11 @@ public class EnableRetryTests {
return new ExcludesService();
}
@Bean
public ExcludesOnlyService excludesOnly() {
return new ExcludesOnlyService();
}
@Bean
public MethodInterceptor retryInterceptor() {
return RetryInterceptorBuilder.stateless().maxAttempts(5).build();
@@ -441,6 +466,27 @@ public class EnableRetryTests {
}
protected static class ExcludesOnlyService {
private int count = 0;
private RuntimeException exceptionToThrow;
@Retryable(exclude = IllegalStateException.class)
public void service() {
if (count++ < 2) {
throw exceptionToThrow;
}
}
public int getCount() {
return count;
}
public void setExceptionToThrow(RuntimeException exceptionToThrow) {
this.exceptionToThrow = exceptionToThrow;
}
}
protected static class StatefulService {
private int count = 0;