diff --git a/CHANGELOG.md b/CHANGELOG.md index 80df27c4a1..b537903e9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,3 +23,4 @@ - [fix:fix zuul delay circuit breaker.](https://github.com/Tencent/spring-cloud-tencent/pull/1519) - [fix:fix watch tsf config, fix bean refresh with RefreshScope and ConfigurationProperties.](https://github.com/Tencent/spring-cloud-tencent/pull/1520) - [docs:update circuit breaker examples.](https://github.com/Tencent/spring-cloud-tencent/pull/1521) +- [feat:support zuul circuit breaker fallback response.](https://github.com/Tencent/spring-cloud-tencent/pull/1522) diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/zuul/PolarisRibbonRoutingFilter.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/zuul/PolarisRibbonRoutingFilter.java index a36c48b7c8..c8a788e83c 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/zuul/PolarisRibbonRoutingFilter.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/zuul/PolarisRibbonRoutingFilter.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import javax.servlet.http.HttpServletRequest; @@ -38,6 +39,7 @@ import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.spi.ServletRouterLabelResolver; import com.tencent.cloud.rpc.enhancement.zuul.EnhancedZuulPluginRunner; +import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,6 +52,7 @@ import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; import org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter; import org.springframework.core.Ordered; +import org.springframework.http.HttpStatus; import org.springframework.lang.NonNull; import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; @@ -196,7 +199,34 @@ private void init() { @Override public Object run() { - enhancedZuulPluginRunner.run(); - return super.run(); + RequestContext context = RequestContext.getCurrentContext(); + // Run pre enhanced plugins. + try { + enhancedZuulPluginRunner.run(); + } + catch (CallAbortedException e) { + if (e.getFallbackInfo() == null) { + throw e; + } + // circuit breaker fallback, not need to run post/exception enhanced plugins. + // set sendZuulResponse to false + context.setSendZuulResponse(false); + // set response status code + HttpStatus httpStatus = HttpStatus.resolve(e.getFallbackInfo().getCode()); + context.setResponseStatusCode(httpStatus != null ? httpStatus.value() : HttpStatus.INTERNAL_SERVER_ERROR.value()); + // set response body + String body = Optional.of(e.getFallbackInfo().getBody()).orElse(""); + context.setResponseBody(body); + // set response content type + context.getResponse().setContentType("text/plain;charset=UTF-8"); + // set response headers + if (com.tencent.polaris.api.utils.CollectionUtils.isNotEmpty(e.getFallbackInfo().getHeaders())) { + e.getFallbackInfo().getHeaders().forEach(context.getResponse()::addHeader); + } + } + if (context.sendZuulResponse()) { + return super.run(); + } + return null; } }