Merge pull request #2082 from dlsrb6342/issue-2047
Add resumeWithoutException to CircuitBreakerFilter
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user