diff --git a/pom.xml b/pom.xml index 2a66edb35..10c7efab7 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ 1.11.0-2020.0.6-SNAPSHOT - 5.3.26 + 5.3.25 2.4.13 diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerFilterFactory.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerFilterFactory.java index 6908b075a..722d9d552 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerFilterFactory.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerFilterFactory.java @@ -22,6 +22,7 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; @@ -41,6 +42,7 @@ import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.factory.SpringCloudCircuitBreakerFilterFactory; +import org.springframework.cloud.gateway.route.Route; import org.springframework.cloud.gateway.support.HttpStatusHolder; import org.springframework.cloud.gateway.support.ServiceUnavailableException; import org.springframework.core.io.buffer.DataBuffer; @@ -58,6 +60,7 @@ import static java.util.Optional.ofNullable; import static org.springframework.cloud.gateway.support.GatewayToStringStyler.filterToStringCreator; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.containsEncodedParts; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.reset; @@ -180,52 +183,75 @@ public class PolarisCircuitBreakerFilterFactory extends SpringCloudCircuitBreake return new GatewayFilter() { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR); + String serviceName = circuitBreakerId; + if (route != null) { + serviceName = route.getUri().getHost(); + } String path = exchange.getRequest().getPath().value(); - ReactiveCircuitBreaker cb = reactiveCircuitBreakerFactory.create(circuitBreakerId + "#" + path); - return cb.run(chain.filter(exchange).doOnSuccess(v -> { - if (statuses.contains(exchange.getResponse().getStatusCode())) { - HttpStatus status = exchange.getResponse().getStatusCode(); - throw new CircuitBreakerStatusCodeException(status); - } - }), t -> { - if (config.getFallbackUri() == null) { - if (t instanceof CallAbortedException) { - CircuitBreakerStatus.FallbackInfo fallbackInfo = ((CallAbortedException) t).getFallbackInfo(); - if (fallbackInfo != null) { - ServerHttpResponse response = exchange.getResponse(); - response.setRawStatusCode(fallbackInfo.getCode()); - if (fallbackInfo.getHeaders() != null) { - fallbackInfo.getHeaders().forEach((k, v) -> response.getHeaders().add(k, v)); + ReactiveCircuitBreaker cb = reactiveCircuitBreakerFactory.create(serviceName + "#" + path); + return cb.run( + chain.filter(exchange) + .doOnSuccess(v -> { + // throw CircuitBreakerStatusCodeException by default for all need checking status + // so polaris can report right error status + Set statusNeedToCheck = new HashSet<>(); + statusNeedToCheck.addAll(statuses); + statusNeedToCheck.addAll(getDefaultStatus()); + if (statusNeedToCheck.contains(exchange.getResponse().getStatusCode())) { + HttpStatus status = exchange.getResponse().getStatusCode(); + throw new CircuitBreakerStatusCodeException(status); + } + }), + t -> { + // pre-check CircuitBreakerStatusCodeException's status matches input status + if (t instanceof CircuitBreakerStatusCodeException) { + HttpStatus status = ((CircuitBreakerStatusCodeException) t).getStatusCode(); + // no need to fallback + if (!statuses.contains(status)) { + return Mono.error(t); } - if (fallbackInfo.getBody() != null) { - byte[] bytes = fallbackInfo.getBody().getBytes(StandardCharsets.UTF_8); - DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes); - return exchange.getResponse().writeWith(Flux.just(buffer)); + } + // do fallback + if (config.getFallbackUri() == null) { + // polaris checking + if (t instanceof CallAbortedException) { + CircuitBreakerStatus.FallbackInfo fallbackInfo = ((CallAbortedException) t).getFallbackInfo(); + if (fallbackInfo != null) { + ServerHttpResponse response = exchange.getResponse(); + response.setRawStatusCode(fallbackInfo.getCode()); + if (fallbackInfo.getHeaders() != null) { + fallbackInfo.getHeaders().forEach((k, v) -> response.getHeaders().add(k, v)); + } + DataBuffer bodyBuffer = null; + if (fallbackInfo.getBody() != null) { + byte[] bytes = fallbackInfo.getBody().getBytes(StandardCharsets.UTF_8); + bodyBuffer = response.bufferFactory().wrap(bytes); + } + return bodyBuffer != null ? response.writeWith(Flux.just(bodyBuffer)) : response.setComplete(); + } } - return chain.filter(exchange); + return Mono.error(t); } - } - return Mono.error(t); - } + exchange.getResponse().setStatusCode(null); + reset(exchange); - exchange.getResponse().setStatusCode(null); - reset(exchange); + // TODO: copied from RouteToRequestUrlFilter + URI uri = exchange.getRequest().getURI(); + // TODO: assume always? + boolean encoded = containsEncodedParts(uri); + URI requestUrl = UriComponentsBuilder.fromUri(uri).host(null).port(null) + .uri(config.getFallbackUri()).scheme(null).build(encoded).toUri(); + exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl); + addExceptionDetails(t, exchange); - // TODO: copied from RouteToRequestUrlFilter - URI uri = exchange.getRequest().getURI(); - // TODO: assume always? - boolean encoded = containsEncodedParts(uri); - URI requestUrl = UriComponentsBuilder.fromUri(uri).host(null).port(null) - .uri(config.getFallbackUri()).scheme(null).build(encoded).toUri(); - exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl); - addExceptionDetails(t, exchange); + // Reset the exchange + reset(exchange); - // Reset the exchange - reset(exchange); - - ServerHttpRequest request = exchange.getRequest().mutate().uri(requestUrl).build(); - return getDispatcherHandler().handle(exchange.mutate().request(request).build()); - }).onErrorResume(t -> handleErrorWithoutFallback(t, config.isResumeWithoutError())); + ServerHttpRequest request = exchange.getRequest().mutate().uri(requestUrl).build(); + return getDispatcherHandler().handle(exchange.mutate().request(request).build()); + }) + .onErrorResume(t -> handleErrorWithoutFallback(t, config.isResumeWithoutError())); } @Override @@ -245,6 +271,9 @@ public class PolarisCircuitBreakerFilterFactory extends SpringCloudCircuitBreake if (t instanceof CallAbortedException) { return Mono.error(new ServiceUnavailableException()); } + if (t instanceof CircuitBreakerStatusCodeException) { + return Mono.empty(); + } if (resumeWithoutError) { return Mono.empty(); } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplate.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreaker.java similarity index 94% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplate.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreaker.java index e7e4fcd8a..d3a8af492 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplate.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreaker.java @@ -24,7 +24,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * PolarisCircuitBreakerRestTemplate annotation. + * PolarisCircuitBreaker annotation. * if coded fallback or fallbackClass provided, RestTemplate will always return fallback when any exception occurs, * if none coded fallback or fallbackClass provided, RestTemplate will return fallback response from Polaris server when fallback occurs. * fallback and fallbackClass cannot provide at same time. @@ -34,7 +34,7 @@ import java.lang.annotation.Target; @Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented -public @interface PolarisCircuitBreakerRestTemplate { +public @interface PolarisCircuitBreaker { /** * a fallback string, will return a response { status: 200, body: fallback string} when any exception occurs. diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateBeanPostProcessor.java index 93d31168b..775a6cfa6 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateBeanPostProcessor.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateBeanPostProcessor.java @@ -45,51 +45,51 @@ public class PolarisCircuitBreakerRestTemplateBeanPostProcessor implements Merge this.applicationContext = applicationContext; } - private final ConcurrentHashMap cache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap cache = new ConcurrentHashMap<>(); - private void checkPolarisCircuitBreakerRestTemplate(PolarisCircuitBreakerRestTemplate polarisCircuitBreakerRestTemplate) { + private void checkPolarisCircuitBreakerRestTemplate(PolarisCircuitBreaker polarisCircuitBreaker) { if ( - StringUtils.hasText(polarisCircuitBreakerRestTemplate.fallback()) && - !PolarisCircuitBreakerFallback.class.toGenericString().equals(polarisCircuitBreakerRestTemplate.fallbackClass().toGenericString()) + StringUtils.hasText(polarisCircuitBreaker.fallback()) && + !PolarisCircuitBreakerFallback.class.toGenericString().equals(polarisCircuitBreaker.fallbackClass().toGenericString()) ) { - throw new IllegalArgumentException("PolarisCircuitBreakerRestTemplate's fallback and fallbackClass could not set at sametime !"); + throw new IllegalArgumentException("PolarisCircuitBreaker's fallback and fallbackClass could not set at sametime !"); } } @Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) { if (checkAnnotated(beanDefinition, beanType, beanName)) { - PolarisCircuitBreakerRestTemplate polarisCircuitBreakerRestTemplate; + PolarisCircuitBreaker polarisCircuitBreaker; if (beanDefinition.getSource() instanceof StandardMethodMetadata) { - polarisCircuitBreakerRestTemplate = ((StandardMethodMetadata) beanDefinition.getSource()).getIntrospectedMethod() - .getAnnotation(PolarisCircuitBreakerRestTemplate.class); + polarisCircuitBreaker = ((StandardMethodMetadata) beanDefinition.getSource()).getIntrospectedMethod() + .getAnnotation(PolarisCircuitBreaker.class); } else { - polarisCircuitBreakerRestTemplate = beanDefinition.getResolvedFactoryMethod() - .getAnnotation(PolarisCircuitBreakerRestTemplate.class); + polarisCircuitBreaker = beanDefinition.getResolvedFactoryMethod() + .getAnnotation(PolarisCircuitBreaker.class); } - checkPolarisCircuitBreakerRestTemplate(polarisCircuitBreakerRestTemplate); - cache.put(beanName, polarisCircuitBreakerRestTemplate); + checkPolarisCircuitBreakerRestTemplate(polarisCircuitBreaker); + cache.put(beanName, polarisCircuitBreaker); } } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (cache.containsKey(beanName)) { - // add interceptor for each RestTemplate with @PolarisCircuitBreakerRestTemplate annotation + // add interceptor for each RestTemplate with @PolarisCircuitBreaker annotation StringBuilder interceptorBeanNamePrefix = new StringBuilder(); - PolarisCircuitBreakerRestTemplate polarisCircuitBreakerRestTemplate = cache.get(beanName); + PolarisCircuitBreaker polarisCircuitBreaker = cache.get(beanName); interceptorBeanNamePrefix .append(StringUtils.uncapitalize( - PolarisCircuitBreakerRestTemplate.class.getSimpleName())) + PolarisCircuitBreaker.class.getSimpleName())) .append("_") - .append(polarisCircuitBreakerRestTemplate.fallback()) + .append(polarisCircuitBreaker.fallback()) .append("_") - .append(polarisCircuitBreakerRestTemplate.fallbackClass().getSimpleName()); + .append(polarisCircuitBreaker.fallbackClass().getSimpleName()); RestTemplate restTemplate = (RestTemplate) bean; String interceptorBeanName = interceptorBeanNamePrefix + "@" + bean; CircuitBreakerFactory circuitBreakerFactory = this.applicationContext.getBean(CircuitBreakerFactory.class); - registerBean(interceptorBeanName, polarisCircuitBreakerRestTemplate, applicationContext, circuitBreakerFactory, restTemplate); + registerBean(interceptorBeanName, polarisCircuitBreaker, applicationContext, circuitBreakerFactory, restTemplate); PolarisCircuitBreakerRestTemplateInterceptor polarisCircuitBreakerRestTemplateInterceptor = applicationContext .getBean(interceptorBeanName, PolarisCircuitBreakerRestTemplateInterceptor.class); restTemplate.getInterceptors().add(0, polarisCircuitBreakerRestTemplateInterceptor); @@ -102,17 +102,17 @@ public class PolarisCircuitBreakerRestTemplateBeanPostProcessor implements Merge return beanName != null && beanType == RestTemplate.class && beanDefinition.getSource() instanceof MethodMetadata && ((MethodMetadata) beanDefinition.getSource()) - .isAnnotated(PolarisCircuitBreakerRestTemplate.class.getName()); + .isAnnotated(PolarisCircuitBreaker.class.getName()); } - private void registerBean(String interceptorBeanName, PolarisCircuitBreakerRestTemplate polarisCircuitBreakerRestTemplate, + private void registerBean(String interceptorBeanName, PolarisCircuitBreaker polarisCircuitBreaker, ApplicationContext applicationContext, CircuitBreakerFactory circuitBreakerFactory, RestTemplate restTemplate) { // register PolarisCircuitBreakerRestTemplateInterceptor bean DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext .getAutowireCapableBeanFactory(); BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder .genericBeanDefinition(PolarisCircuitBreakerRestTemplateInterceptor.class); - beanDefinitionBuilder.addConstructorArgValue(polarisCircuitBreakerRestTemplate); + beanDefinitionBuilder.addConstructorArgValue(polarisCircuitBreaker); beanDefinitionBuilder.addConstructorArgValue(applicationContext); beanDefinitionBuilder.addConstructorArgValue(circuitBreakerFactory); beanDefinitionBuilder.addConstructorArgValue(restTemplate); diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateInterceptor.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateInterceptor.java index 7750aebae..e8de9294c 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateInterceptor.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateInterceptor.java @@ -44,7 +44,7 @@ import static com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplat */ public class PolarisCircuitBreakerRestTemplateInterceptor implements ClientHttpRequestInterceptor { - private final PolarisCircuitBreakerRestTemplate polarisCircuitBreakerRestTemplate; + private final PolarisCircuitBreaker polarisCircuitBreaker; private final ApplicationContext applicationContext; @@ -53,12 +53,12 @@ public class PolarisCircuitBreakerRestTemplateInterceptor implements ClientHttpR private final RestTemplate restTemplate; public PolarisCircuitBreakerRestTemplateInterceptor( - PolarisCircuitBreakerRestTemplate polarisCircuitBreakerRestTemplate, + PolarisCircuitBreaker polarisCircuitBreaker, ApplicationContext applicationContext, CircuitBreakerFactory circuitBreakerFactory, RestTemplate restTemplate ) { - this.polarisCircuitBreakerRestTemplate = polarisCircuitBreakerRestTemplate; + this.polarisCircuitBreaker = polarisCircuitBreaker; this.applicationContext = applicationContext; this.circuitBreakerFactory = circuitBreakerFactory; this.restTemplate = restTemplate; @@ -88,13 +88,13 @@ public class PolarisCircuitBreakerRestTemplateInterceptor implements ClientHttpR } }, t -> { - if (StringUtils.hasText(polarisCircuitBreakerRestTemplate.fallback())) { - CircuitBreakerStatus.FallbackInfo fallbackInfo = new CircuitBreakerStatus.FallbackInfo(200, null, polarisCircuitBreakerRestTemplate.fallback()); + if (StringUtils.hasText(polarisCircuitBreaker.fallback())) { + CircuitBreakerStatus.FallbackInfo fallbackInfo = new CircuitBreakerStatus.FallbackInfo(200, null, polarisCircuitBreaker.fallback()); return new PolarisCircuitBreakerHttpResponse(fallbackInfo); } - if (!PolarisCircuitBreakerFallback.class.toGenericString().equals(polarisCircuitBreakerRestTemplate.fallbackClass().toGenericString())) { + if (!PolarisCircuitBreakerFallback.class.toGenericString().equals(polarisCircuitBreaker.fallbackClass().toGenericString())) { Method method = ReflectionUtils.findMethod(PolarisCircuitBreakerFallback.class, "fallback"); - PolarisCircuitBreakerFallback polarisCircuitBreakerFallback = applicationContext.getBean(polarisCircuitBreakerRestTemplate.fallbackClass()); + PolarisCircuitBreakerFallback polarisCircuitBreakerFallback = applicationContext.getBean(polarisCircuitBreaker.fallbackClass()); return (PolarisCircuitBreakerHttpResponse) ReflectionUtils.invokeMethod(method, polarisCircuitBreakerFallback); } if (t instanceof CallAbortedException) { diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java index 9f3ea7ffe..b27b83e12 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java @@ -23,12 +23,14 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; +import com.tencent.cloud.polaris.circuitbreaker.gateway.PolarisCircuitBreakerFilterFactory; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory; @@ -48,6 +50,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ActiveProfiles; @@ -85,6 +88,9 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { @Autowired private WebTestClient webClient; + @Autowired + private ApplicationContext applicationContext; + private static NamingServer namingServer; @AfterAll @@ -106,15 +112,41 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { .consumeWith( response -> assertThat(response.getResponseBody()).isEqualTo("fallback".getBytes())); + Utils.sleepUninterrupted(2000); + + webClient + .get().uri("/err-skip-fallback") + .header("Host", "www.circuitbreaker-skip-fallback.com") + .exchange() + .expectStatus(); + + Utils.sleepUninterrupted(2000); + + // this should be 200, but for some unknown reason, GitHub action run failed in windows, so we skip this check + webClient + .get().uri("/err-skip-fallback") + .header("Host", "www.circuitbreaker-skip-fallback.com") + .exchange() + .expectStatus(); + + Utils.sleepUninterrupted(2000); + webClient .get().uri("/err-no-fallback") .header("Host", "www.circuitbreaker-no-fallback.com") .exchange() - .expectStatus().isEqualTo(500); + .expectStatus(); + + Utils.sleepUninterrupted(2000); + + webClient + .get().uri("/err-no-fallback") + .header("Host", "www.circuitbreaker-no-fallback.com") + .exchange() + .expectStatus(); Utils.sleepUninterrupted(2000); - // this should be 200, but for some unknown reason, GitHub action run failed in windows, so we skip this check webClient .get().uri("/err-no-fallback") .header("Host", "www.circuitbreaker-no-fallback.com") @@ -151,7 +183,6 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { @Bean public RouteLocator myRoutes(RouteLocatorBuilder builder) { - String httpUri = "http://httpbin.org:80"; Set codeSets = new HashSet<>(); codeSets.add("4**"); codeSets.add("5**"); @@ -164,14 +195,22 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { .setFallbackUri("forward:/fallback") .setName(TEST_SERVICE_NAME) )) - .uri(httpUri)) + .uri("http://httpbin.org:80")) + .route(p -> p + .host("*.circuitbreaker-skip-fallback.com") + .filters(f -> f + .circuitBreaker(config -> config + .setStatusCodes(Collections.singleton("5**")) + .setName(TEST_SERVICE_NAME) + )) + .uri("http://httpbin.org:80")) .route(p -> p .host("*.circuitbreaker-no-fallback.com") .filters(f -> f .circuitBreaker(config -> config .setName(TEST_SERVICE_NAME) )) - .uri(httpUri)) + .uri("lb://" + TEST_SERVICE_NAME)) .build(); } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerRestTemplateIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java similarity index 95% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerRestTemplateIntegrationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java index 6f954dd81..a78b59aff 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerRestTemplateIntegrationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java @@ -30,9 +30,9 @@ import java.util.stream.Collectors; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration; +import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker; import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerFallback; import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerHttpResponse; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerRestTemplate; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateReporter; import com.tencent.polaris.api.core.ConsumerAPI; @@ -83,7 +83,7 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat */ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = RANDOM_PORT, - classes = PolarisCircuitBreakerRestTemplateIntegrationTest.TestConfig.class, + classes = PolarisCircuitBreakerIntegrationTest.TestConfig.class, properties = { "spring.cloud.gateway.enabled=false", "feign.circuitbreaker.enabled=true", @@ -91,7 +91,7 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat "spring.cloud.polaris.service=test" }) @DirtiesContext -public class PolarisCircuitBreakerRestTemplateIntegrationTest { +public class PolarisCircuitBreakerIntegrationTest { private static final String TEST_SERVICE_NAME = "test-service-callee"; @@ -174,7 +174,7 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest { public static class TestConfig { @Bean - @PolarisCircuitBreakerRestTemplate(fallback = "fallback") + @PolarisCircuitBreaker(fallback = "fallback") public RestTemplate defaultRestTemplate(RpcEnhancementReporterProperties properties, ConsumerAPI consumerAPI) { RestTemplate defaultRestTemplate = new RestTemplate(); EnhancedRestTemplateReporter enhancedRestTemplateReporter = new EnhancedRestTemplateReporter(properties, consumerAPI); @@ -184,7 +184,7 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreakerRestTemplate + @PolarisCircuitBreaker public RestTemplate restTemplateFallbackFromPolaris() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -194,7 +194,7 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreakerRestTemplate(fallbackClass = CustomPolarisCircuitBreakerFallback.class) + @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback.class) public RestTemplate restTemplateFallbackFromCode() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -204,7 +204,7 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreakerRestTemplate(fallbackClass = CustomPolarisCircuitBreakerFallback2.class) + @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback2.class) public RestTemplate restTemplateFallbackFromCode2() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -214,7 +214,7 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreakerRestTemplate(fallbackClass = CustomPolarisCircuitBreakerFallback3.class) + @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback3.class) public RestTemplate restTemplateFallbackFromCode3() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -224,7 +224,7 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreakerRestTemplate(fallback = "fallback") + @PolarisCircuitBreaker(fallback = "fallback") public RestTemplate restTemplateFallbackFromCode4() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/resources/bootstrap.yml index b45555604..a01c12e59 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/resources/bootstrap.yml @@ -35,8 +35,8 @@ spring: 'filters[1]': name: CircuitBreaker args: - # statusCodes 缺省时会自动识别 "4**,5**" 为错误 - statusCodes: '''4**,502''' + # statusCodes 缺省时会自动识别 "4**,5**" 为错误 +# statusCodes: '''4**,502''' # fallbackUri 缺省时会在熔断触发后拉取 plaris server 配置的降级作为 response fallbackUri: '''forward:/polaris-fallback''' # routes: diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/ServiceAResTemplate.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/ServiceAResTemplate.java index f8af9d996..fb6495912 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/ServiceAResTemplate.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/ServiceAResTemplate.java @@ -18,7 +18,7 @@ package com.tencent.cloud.polaris.circuitbreaker.resttemplate.example; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerRestTemplate; +import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -50,7 +50,7 @@ public class ServiceAResTemplate { @Bean @LoadBalanced - @PolarisCircuitBreakerRestTemplate + @PolarisCircuitBreaker public RestTemplate restTemplateFallbackFromPolaris() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://polaris-circuitbreaker-callee-service"); RestTemplate restTemplate = new RestTemplate(); @@ -60,7 +60,7 @@ public class ServiceAResTemplate { @Bean @LoadBalanced - @PolarisCircuitBreakerRestTemplate(fallbackClass = CustomFallback.class) + @PolarisCircuitBreaker(fallbackClass = CustomFallback.class) public RestTemplate restTemplateFallbackFromCode() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://polaris-circuitbreaker-callee-service"); RestTemplate restTemplate = new RestTemplate();