Skip to content

Commit db0a050

Browse files
garyrussellartembilan
authored andcommitted
GH-293: Fix Bean Resolver for CBreaker Expressions
Resolves #293 **cherry-pick to 1.3.x** # Conflicts: # src/test/java/org/springframework/retry/annotation/CircuitBreakerTests.java
1 parent cd43720 commit db0a050

File tree

2 files changed

+57
-6
lines changed

2 files changed

+57
-6
lines changed

src/main/java/org/springframework/retry/annotation/AnnotationAwareRetryOperationsInterceptor.java

+23-5
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@
6262
import org.springframework.retry.support.RetryTemplate;
6363
import org.springframework.util.ConcurrentReferenceHashMap;
6464
import org.springframework.util.ReflectionUtils;
65-
import org.springframework.util.ReflectionUtils.MethodCallback;
6665
import org.springframework.util.StringUtils;
6766

6867
/**
@@ -254,8 +253,15 @@ private MethodInterceptor getStatefulInterceptor(Object target, Method method, R
254253

255254
private long getOpenTimeout(CircuitBreaker circuit) {
256255
if (StringUtils.hasText(circuit.openTimeoutExpression())) {
257-
Long value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression()), PARSER_CONTEXT)
258-
.getValue(Long.class);
256+
Long value = null;
257+
if (isTemplate(circuit.openTimeoutExpression())) {
258+
value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression()), PARSER_CONTEXT)
259+
.getValue(this.evaluationContext, Long.class);
260+
}
261+
else {
262+
value = PARSER.parseExpression(resolve(circuit.openTimeoutExpression()))
263+
.getValue(this.evaluationContext, Long.class);
264+
}
259265
if (value != null) {
260266
return value;
261267
}
@@ -265,15 +271,27 @@ private long getOpenTimeout(CircuitBreaker circuit) {
265271

266272
private long getResetTimeout(CircuitBreaker circuit) {
267273
if (StringUtils.hasText(circuit.resetTimeoutExpression())) {
268-
Long value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression()), PARSER_CONTEXT)
269-
.getValue(Long.class);
274+
Long value = null;
275+
if (isTemplate(circuit.openTimeoutExpression())) {
276+
value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression()), PARSER_CONTEXT)
277+
.getValue(this.evaluationContext, Long.class);
278+
}
279+
else {
280+
value = PARSER.parseExpression(resolve(circuit.resetTimeoutExpression()))
281+
.getValue(this.evaluationContext, Long.class);
282+
}
270283
if (value != null) {
271284
return value;
272285
}
273286
}
274287
return circuit.resetTimeout();
275288
}
276289

290+
private boolean isTemplate(String expression) {
291+
return expression.contains(PARSER_CONTEXT.getExpressionPrefix())
292+
&& expression.contains(PARSER_CONTEXT.getExpressionSuffix());
293+
}
294+
277295
private RetryTemplate createTemplate(String[] listenersBeanNames) {
278296
RetryTemplate template = new RetryTemplate();
279297
if (listenersBeanNames.length > 0) {

src/test/java/org/springframework/retry/annotation/CircuitBreakerTests.java

+34-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2019 the original author or authors.
2+
* Copyright 2015-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -40,6 +40,7 @@
4040
/**
4141
* @author Dave Syer
4242
* @author Gary Russell
43+
* @author Artem Bilan
4344
*
4445
*/
4546
public class CircuitBreakerTests {
@@ -81,6 +82,8 @@ public void vanilla() throws Exception {
8182
assertEquals(3, service.getCount());
8283
service.expressionService();
8384
assertEquals(4, service.getCount());
85+
service.expressionService2();
86+
assertEquals(5, service.getCount());
8487
Advised advised = (Advised) service;
8588
Advisor advisor = advised.getAdvisors()[0];
8689
Map<?, ?> delegates = (Map<?, ?>) new DirectFieldAccessor(advisor).getPropertyValue("advice.delegates");
@@ -94,6 +97,12 @@ public void vanilla() throws Exception {
9497
assertEquals(20000L, accessor.getPropertyValue("retryOperations.retryPolicy.resetTimeout"));
9598
assertEquals("#root instanceof RuntimeExpression",
9699
accessor.getPropertyValue("retryOperations.retryPolicy.delegate.expression.expression"));
100+
101+
interceptor = (MethodInterceptor) methodMap.get(Service.class.getDeclaredMethod("expressionService2"));
102+
accessor = new DirectFieldAccessor(interceptor);
103+
assertEquals(10, accessor.getPropertyValue("retryOperations.retryPolicy.delegate.maxAttempts"));
104+
assertEquals(10000L, accessor.getPropertyValue("retryOperations.retryPolicy.openTimeout"));
105+
assertEquals(20000L, accessor.getPropertyValue("retryOperations.retryPolicy.resetTimeout"));
97106
context.close();
98107
}
99108

@@ -106,6 +115,21 @@ public Service service() {
106115
return new ServiceImpl();
107116
}
108117

118+
@Bean
119+
Configs configs() {
120+
return new Configs();
121+
}
122+
123+
}
124+
125+
public static class Configs {
126+
127+
public int maxAttempts = 10;
128+
129+
public long openTimeout = 10000;
130+
131+
public long resetTimeout = 20000;
132+
109133
}
110134

111135
interface Service {
@@ -114,6 +138,8 @@ interface Service {
114138

115139
void expressionService();
116140

141+
void expressionService2();
142+
117143
int getCount();
118144

119145
RetryContext getContext();
@@ -143,6 +169,13 @@ public void expressionService() {
143169
this.count++;
144170
}
145171

172+
@Override
173+
@CircuitBreaker(maxAttemptsExpression = "@configs.maxAttempts", openTimeoutExpression = "@configs.openTimeout",
174+
resetTimeoutExpression = "@configs.resetTimeout")
175+
public void expressionService2() {
176+
this.count++;
177+
}
178+
146179
@Override
147180
public RetryContext getContext() {
148181
return this.context;

0 commit comments

Comments
 (0)