Merge pull request #2082 from dlsrb6342/issue-2047

Add resumeWithoutException to CircuitBreakerFilter
This commit is contained in:
Ryan Baxter
2021-06-01 17:05:23 -04:00
committed by GitHub
4 changed files with 45 additions and 5 deletions

View File

@@ -98,8 +98,6 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
return cb.run(chain.filter(exchange).doOnSuccess(v -> {
if (statuses.contains(exchange.getResponse().getStatusCode())) {
HttpStatus status = exchange.getResponse().getStatusCode();
exchange.getResponse().setStatusCode(null);
reset(exchange);
throw new CircuitBreakerStatusCodeException(status);
}
}), t -> {
@@ -107,6 +105,9 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
return Mono.error(t);
}
exchange.getResponse().setStatusCode(null);
reset(exchange);
// TODO: copied from RouteToRequestUrlFilter
URI uri = exchange.getRequest().getURI();
// TODO: assume always?
@@ -121,7 +122,7 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
ServerHttpRequest request = exchange.getRequest().mutate().uri(requestUrl).build();
return getDispatcherHandler().handle(exchange.mutate().request(request).build());
}).onErrorResume(t -> handleErrorWithoutFallback(t));
}).onErrorResume(t -> handleErrorWithoutFallback(t, config.isResumeWithoutError()));
}
@Override
@@ -132,7 +133,7 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
};
}
protected abstract Mono<Void> handleErrorWithoutFallback(Throwable t);
protected abstract Mono<Void> handleErrorWithoutFallback(Throwable t, boolean resumeWithoutError);
private void addExceptionDetails(Throwable t, ServerWebExchange exchange) {
ofNullable(t).ifPresent(
@@ -154,6 +155,8 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
private Set<String> statusCodes = new HashSet<>();
private boolean resumeWithoutError = false;
@Override
public void setRouteId(String routeId) {
this.routeId = routeId;
@@ -206,6 +209,14 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
return this;
}
public boolean isResumeWithoutError() {
return resumeWithoutError;
}
public void setResumeWithoutError(boolean resumeWithoutError) {
this.resumeWithoutError = resumeWithoutError;
}
}
public class CircuitBreakerStatusCodeException extends HttpStatusCodeException {

View File

@@ -38,13 +38,16 @@ public class SpringCloudCircuitBreakerResilience4JFilterFactory extends SpringCl
}
@Override
protected Mono<Void> handleErrorWithoutFallback(Throwable t) {
protected Mono<Void> handleErrorWithoutFallback(Throwable t, boolean resumeWithoutError) {
if (java.util.concurrent.TimeoutException.class.isInstance(t)) {
return Mono.error(new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT, t.getMessage(), t));
}
if (CallNotPermittedException.class.isInstance(t)) {
return Mono.error(new ServiceUnavailableException());
}
if (resumeWithoutError) {
return Mono.empty();
}
return Mono.error(t);
}

View File

@@ -103,4 +103,16 @@ public abstract class SpringCloudCircuitBreakerFilterFactoryTests extends BaseWe
.isOk().expectHeader().valueEquals(ROUTE_ID_HEADER, "circuitbreaker_fallback_test_statuscode");
}
@Test
public void filterStatusCodeResumeWithoutError() {
testClient.get().uri("/status/500").header("Host", "www.circuitbreakerresumewithouterror.org").exchange().expectStatus()
.isEqualTo(500);
testClient.get().uri("/status/404").header("Host", "www.circuitbreakerresumewithouterror.org").exchange().expectStatus()
.isEqualTo(404);
testClient.get().uri("/status/200").header("Host", "www.circuitbreakerresumewithouterror.org").exchange().expectStatus()
.isOk().expectHeader().valueEquals(ROUTE_ID_HEADER, "circuitbreaker_resume_without_error");
}
}

View File

@@ -109,6 +109,20 @@ spring:
- "NOT_FOUND"
fallbackUri: forward:/statusCodeFallbackController
# =====================================
- id: circuitbreaker_resume_without_error
uri: ${test.uri}
predicates:
- Host=**.circuitbreakerresumewithouterror.org
filters:
- name: CircuitBreaker
args:
name: resumewithouterror
statusCodes:
- 500
- "NOT_FOUND"
resume-without-error: true
# =====================================
- id: change_uri_test
uri: ${test.uri}