GH-293: Fix Bean Resolver for CBreaker Expressions
Resolves https://github.com/spring-projects/spring-retry/issues/293 **cherry-pick to 1.3.x** # Conflicts: # src/test/java/org/springframework/retry/annotation/CircuitBreakerTests.java
This commit is contained in:
committed by
Artem Bilan
parent
cd43720b66
commit
db0a050f58
@@ -62,7 +62,6 @@ import org.springframework.retry.policy.SimpleRetryPolicy;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.ReflectionUtils.MethodCallback;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -254,8 +253,15 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
|
||||
|
||||
private long getOpenTimeout(CircuitBreaker circuit) {
|
||||
if (StringUtils.hasText(circuit.openTimeoutExpression())) {
|
||||
Long value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression()), PARSER_CONTEXT)
|
||||
.getValue(Long.class);
|
||||
Long value = null;
|
||||
if (isTemplate(circuit.openTimeoutExpression())) {
|
||||
value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression()), PARSER_CONTEXT)
|
||||
.getValue(this.evaluationContext, Long.class);
|
||||
}
|
||||
else {
|
||||
value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression()))
|
||||
.getValue(this.evaluationContext, Long.class);
|
||||
}
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
@@ -265,8 +271,15 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
|
||||
|
||||
private long getResetTimeout(CircuitBreaker circuit) {
|
||||
if (StringUtils.hasText(circuit.resetTimeoutExpression())) {
|
||||
Long value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression()), PARSER_CONTEXT)
|
||||
.getValue(Long.class);
|
||||
Long value = null;
|
||||
if (isTemplate(circuit.openTimeoutExpression())) {
|
||||
value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression()), PARSER_CONTEXT)
|
||||
.getValue(this.evaluationContext, Long.class);
|
||||
}
|
||||
else {
|
||||
value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression()))
|
||||
.getValue(this.evaluationContext, Long.class);
|
||||
}
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
@@ -274,6 +287,11 @@ public class AnnotationAwareRetryOperationsInterceptor implements IntroductionIn
|
||||
return circuit.resetTimeout();
|
||||
}
|
||||
|
||||
private boolean isTemplate(String expression) {
|
||||
return expression.contains(PARSER_CONTEXT.getExpressionPrefix())
|
||||
&& expression.contains(PARSER_CONTEXT.getExpressionSuffix());
|
||||
}
|
||||
|
||||
private RetryTemplate createTemplate(String[] listenersBeanNames) {
|
||||
RetryTemplate template = new RetryTemplate();
|
||||
if (listenersBeanNames.length > 0) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2019 the original author or authors.
|
||||
* Copyright 2015-2022 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.
|
||||
@@ -40,6 +40,7 @@ import static org.junit.Assert.fail;
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
*/
|
||||
public class CircuitBreakerTests {
|
||||
@@ -81,6 +82,8 @@ public class CircuitBreakerTests {
|
||||
assertEquals(3, service.getCount());
|
||||
service.expressionService();
|
||||
assertEquals(4, service.getCount());
|
||||
service.expressionService2();
|
||||
assertEquals(5, service.getCount());
|
||||
Advised advised = (Advised) service;
|
||||
Advisor advisor = advised.getAdvisors()[0];
|
||||
Map<?, ?> delegates = (Map<?, ?>) new DirectFieldAccessor(advisor).getPropertyValue("advice.delegates");
|
||||
@@ -94,6 +97,12 @@ public class CircuitBreakerTests {
|
||||
assertEquals(20000L, accessor.getPropertyValue("retryOperations.retryPolicy.resetTimeout"));
|
||||
assertEquals("#root instanceof RuntimeExpression",
|
||||
accessor.getPropertyValue("retryOperations.retryPolicy.delegate.expression.expression"));
|
||||
|
||||
interceptor = (MethodInterceptor) methodMap.get(Service.class.getDeclaredMethod("expressionService2"));
|
||||
accessor = new DirectFieldAccessor(interceptor);
|
||||
assertEquals(10, accessor.getPropertyValue("retryOperations.retryPolicy.delegate.maxAttempts"));
|
||||
assertEquals(10000L, accessor.getPropertyValue("retryOperations.retryPolicy.openTimeout"));
|
||||
assertEquals(20000L, accessor.getPropertyValue("retryOperations.retryPolicy.resetTimeout"));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@@ -106,6 +115,21 @@ public class CircuitBreakerTests {
|
||||
return new ServiceImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
Configs configs() {
|
||||
return new Configs();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Configs {
|
||||
|
||||
public int maxAttempts = 10;
|
||||
|
||||
public long openTimeout = 10000;
|
||||
|
||||
public long resetTimeout = 20000;
|
||||
|
||||
}
|
||||
|
||||
interface Service {
|
||||
@@ -114,6 +138,8 @@ public class CircuitBreakerTests {
|
||||
|
||||
void expressionService();
|
||||
|
||||
void expressionService2();
|
||||
|
||||
int getCount();
|
||||
|
||||
RetryContext getContext();
|
||||
@@ -143,6 +169,13 @@ public class CircuitBreakerTests {
|
||||
this.count++;
|
||||
}
|
||||
|
||||
@Override
|
||||
@CircuitBreaker(maxAttemptsExpression = "@configs.maxAttempts", openTimeoutExpression = "@configs.openTimeout",
|
||||
resetTimeoutExpression = "@configs.resetTimeout")
|
||||
public void expressionService2() {
|
||||
this.count++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RetryContext getContext() {
|
||||
return this.context;
|
||||
|
||||
Reference in New Issue
Block a user