From 0673da78181040d37c9e929643819903bc3a65dd Mon Sep 17 00:00:00 2001 From: "Shanyou Yu (Sean Yu)" Date: Fri, 12 May 2023 10:13:37 +0800 Subject: [PATCH] Refactoring: Refactor Circuitbreaker ut. --- CHANGELOG.md | 1 + .../ExceptionCircuitBreakerReporter.java | 11 +- .../SuccessCircuitBreakerReporter.java | 11 +- .../PolarisCircuitBreakerMockServerTest.java | 8 +- .../PolarisCircuitBreakerTest.java | 7 +- ...sCircuitBreakerAutoConfigurationTest.java} | 10 +- ...cuitBreakerBootstrapConfigurationTest.java | 6 +- ...risCircuitBreakerFeignIntegrationTest.java | 58 +++++--- ...PolarisCircuitBreakerNameResolverTest.java | 125 ++++++++++++++++++ ...olarisFeignCircuitBreakerTargeterTest.java | 89 +++++++++++++ ...sCircuitBreakerGatewayIntegrationTest.java | 54 +++++--- ...itBreakerRestTemplateIntegrationTest.java} | 78 ++++++----- .../util/PolarisCircuitBreakerUtilsTests.java | 8 ++ spring-cloud-tencent-dependencies/pom.xml | 2 +- .../plugin/PluginOrderConstant.java | 70 ++++++++++ .../reporter/ExceptionPolarisReporter.java | 11 +- .../reporter/SuccessPolarisReporter.java | 11 +- 17 files changed, 445 insertions(+), 115 deletions(-) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/{CircuitBreakerPolarisAutoConfigurationTest.java => config/PolarisCircuitBreakerAutoConfigurationTest.java} (86%) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/{ => config}/PolarisCircuitBreakerBootstrapConfigurationTest.java (82%) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/{ => feign}/PolarisCircuitBreakerFeignIntegrationTest.java (88%) create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolverTest.java create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/{ => gateway}/PolarisCircuitBreakerGatewayIntegrationTest.java (88%) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/{PolarisCircuitBreakerIntegrationTest.java => resttemplate/PolarisCircuitBreakerRestTemplateIntegrationTest.java} (87%) create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 090f66c5..9e209b66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,3 +4,4 @@ - feature: support reactive discovery client health indicator. - feature: Enhance default configuration to support `application*.yaml` and `bootstrap*.yaml`. - feat:adapt for nacos instance. +- Refactoring: Refactor Circuitbreaker ut. diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java index b47c1a4a..47fd5098 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java @@ -33,7 +33,8 @@ import org.slf4j.LoggerFactory; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.Ordered; + +import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER; public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { @@ -65,7 +66,8 @@ public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdap } EnhancedRequestContext request = context.getRequest(); - ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); + ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()) + .orElse(new DefaultServiceInstance()); ResourceStat resourceStat = createInstanceResourceStat( serviceInstance.getServiceId(), @@ -78,7 +80,8 @@ public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdap ); LOG.debug("Will report CircuitBreaker ResourceStat of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), context.getThrowable().getMessage(), context.getDelay()); + resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl() + .getPath(), context.getThrowable().getMessage(), context.getDelay()); circuitBreakAPI.report(resourceStat); @@ -92,6 +95,6 @@ public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdap @Override public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE + 2; + return CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER; } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java index ce5fe2a8..affc07d1 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java @@ -35,7 +35,8 @@ import org.slf4j.LoggerFactory; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.Ordered; + +import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER; public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { @@ -68,7 +69,8 @@ public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapte } EnhancedRequestContext request = context.getRequest(); EnhancedResponseContext response = context.getResponse(); - ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); + ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()) + .orElse(new DefaultServiceInstance()); ResourceStat resourceStat = createInstanceResourceStat( serviceInstance.getServiceId(), @@ -81,7 +83,8 @@ public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapte ); LOG.debug("Will report CircuitBreaker ResourceStat of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), response.getHttpStatus(), context.getDelay()); + resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl() + .getPath(), response.getHttpStatus(), context.getDelay()); circuitBreakAPI.report(resourceStat); } @@ -94,6 +97,6 @@ public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapte @Override public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE + 2; + return CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER; } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java index daf977f1..f7c2def9 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java @@ -77,13 +77,9 @@ public class PolarisCircuitBreakerMockServerTest { mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.service")) .thenReturn(SERVICE_CIRCUIT_BREAKER); - try { - namingServer = NamingServer.startNamingServer(-1); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { + namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_CIRCUIT_BREAKER); CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerTest.java index 494ae779..bf35fa8f 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerTest.java @@ -49,7 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat; @ExtendWith(MockitoExtension.class) public class PolarisCircuitBreakerTest { - private static final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + private static ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of( PolarisContextAutoConfiguration.class, RpcEnhancementAutoConfiguration.class, @@ -76,7 +76,7 @@ public class PolarisCircuitBreakerTest { @Test public void run() { - contextRunner.run(context -> { + this.contextRunner.run(context -> { PolarisCircuitBreakerFactory polarisCircuitBreakerFactory = context.getBean(PolarisCircuitBreakerFactory.class); CircuitBreaker cb = polarisCircuitBreakerFactory.create(SERVICE_CIRCUIT_BREAKER); @@ -95,4 +95,7 @@ public class PolarisCircuitBreakerTest { }); } + + + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/CircuitBreakerPolarisAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java similarity index 86% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/CircuitBreakerPolarisAutoConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java index 5b05ab5a..3e5cc8c3 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/CircuitBreakerPolarisAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java @@ -15,15 +15,12 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.config; import com.tencent.cloud.polaris.circuitbreaker.common.CircuitBreakerConfigModifier; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.ReactivePolarisCircuitBreakerAutoConfiguration; import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisCircuitBreakerNameResolver; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -39,12 +36,13 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Haotian Zhang */ -public class CircuitBreakerPolarisAutoConfigurationTest { +public class PolarisCircuitBreakerAutoConfigurationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of( PolarisContextAutoConfiguration.class, RpcEnhancementAutoConfiguration.class, LoadBalancerAutoConfiguration.class, + PolarisCircuitBreakerFeignClientAutoConfiguration.class, PolarisCircuitBreakerAutoConfiguration.class)) .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true"); @@ -62,7 +60,6 @@ public class CircuitBreakerPolarisAutoConfigurationTest { assertThat(context).hasSingleBean(PolarisCircuitBreakerAutoConfiguration.class); assertThat(context).hasSingleBean(CircuitBreakerFactory.class); assertThat(context).hasSingleBean(CircuitBreakerConfigModifier.class); - assertThat(context).hasSingleBean(CircuitBreakAPI.class); assertThat(context).hasSingleBean(PolarisCircuitBreakerNameResolver.class); }); } @@ -73,7 +70,6 @@ public class CircuitBreakerPolarisAutoConfigurationTest { assertThat(context).hasSingleBean(ReactivePolarisCircuitBreakerAutoConfiguration.class); assertThat(context).hasSingleBean(ReactiveCircuitBreakerFactory.class); assertThat(context).hasSingleBean(CircuitBreakerConfigModifier.class); - assertThat(context).hasSingleBean(CircuitBreakAPI.class); }); } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java similarity index 82% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java index c7878430..653ba8ff 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java @@ -15,12 +15,8 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.config; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.ReactivePolarisCircuitBreakerAutoConfiguration; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration; import org.junit.jupiter.api.Test; diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFeignIntegrationTest.java similarity index 88% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFeignIntegrationTest.java index ea24db16..722fcd84 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFeignIntegrationTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.feign; import java.io.BufferedReader; @@ -26,7 +26,6 @@ import java.lang.reflect.InvocationTargetException; import java.nio.charset.StandardCharsets; 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.polaris.api.pojo.ServiceKey; @@ -36,10 +35,10 @@ import com.tencent.polaris.client.util.Utils; import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; import com.tencent.polaris.test.common.TestUtils; import com.tencent.polaris.test.mock.discovery.NamingServer; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -50,7 +49,7 @@ import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; +import org.springframework.context.annotation.Primary; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -75,27 +74,22 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen "spring.cloud.polaris.service=" + SERVICE_CIRCUIT_BREAKER, "spring.cloud.polaris.address=grpc://127.0.0.1:10081" }) -@DirtiesContext public class PolarisCircuitBreakerFeignIntegrationTest { private static final String TEST_SERVICE_NAME = "test-service-callee"; - private static NamingServer namingServer; + @Autowired private EchoService echoService; + @Autowired private FooService fooService; + @Autowired private BarService barService; + @Autowired private BazService bazService; - @AfterAll - public static void afterAll() { - if (null != namingServer) { - namingServer.terminate(); - } - } - @Test public void contextLoads() throws Exception { assertThat(echoService).isNotNull(); @@ -122,6 +116,7 @@ public class PolarisCircuitBreakerFeignIntegrationTest { } @FeignClient(value = TEST_SERVICE_NAME, contextId = "1", fallback = EchoServiceFallback.class) + @Primary public interface EchoService { @RequestMapping(path = "echo/{str}") @@ -174,18 +169,18 @@ public class PolarisCircuitBreakerFeignIntegrationTest { } @Bean - public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException { - try { - namingServer = NamingServer.startNamingServer(10081); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { + public PreDestroy preDestroy(NamingServer namingServer) { + return new PreDestroy(namingServer); + } - } + @Bean + public NamingServer namingServer() throws IOException { + NamingServer namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME); CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); - InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader() + InputStream inputStream = PolarisCircuitBreakerFeignIntegrationTest.class.getClassLoader() .getResourceAsStream("circuitBreakerRule.json"); String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines() .collect(Collectors.joining("")); @@ -194,6 +189,11 @@ public class PolarisCircuitBreakerFeignIntegrationTest { CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() .addRules(circuitBreakerRule).build(); namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker); + return namingServer; + } + + @Bean + public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) { com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress(); return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration); } @@ -205,7 +205,7 @@ public class PolarisCircuitBreakerFeignIntegrationTest { @Override public String echo(@RequestParam("str") String param) throws InvocationTargetException { if (param == null) { - throw new InvocationTargetException(new Exception(), "test InvocationTargetException"); + throw new InvocationTargetException(new Exception()); } return "echo fallback"; } @@ -233,4 +233,18 @@ public class PolarisCircuitBreakerFeignIntegrationTest { } + public static class PreDestroy implements DisposableBean { + + private final NamingServer namingServer; + + public PreDestroy(NamingServer namingServer) { + this.namingServer = namingServer; + } + + @Override + public void destroy() throws Exception { + namingServer.terminate(); + } + } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolverTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolverTest.java new file mode 100644 index 00000000..52e9e465 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolverTest.java @@ -0,0 +1,125 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.circuitbreaker.feign; + +import java.lang.reflect.Method; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.common.util.ReflectionUtils; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import feign.Target; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.context.ApplicationContext; +import org.springframework.web.bind.annotation.RequestMapping; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +/** + * @author sean yu + */ +@ExtendWith(MockitoExtension.class) +public class PolarisCircuitBreakerNameResolverTest { + + private static MockedStatic mockedApplicationContextAwareUtils; + + @BeforeAll + static void beforeAll() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("unit-test"); + ApplicationContext applicationContext = mock(ApplicationContext.class); + RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); + doReturn(reporterProperties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); + } + + @AfterAll + static void afterAll() { + mockedApplicationContextAwareUtils.close(); + } + + @BeforeEach + void setUp() { + MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; + MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; + } + + + @Test + public void test() { + Target target = mock(Target.class); + doReturn("test-svc").when(target).name(); + Method method = ReflectionUtils.findMethod(PolarisCircuitBreakerNameResolverTest.class, "mockRequestMapping"); + PolarisCircuitBreakerNameResolver resolver = new PolarisCircuitBreakerNameResolver(); + String polarisCircuitBreakerName = resolver.resolveCircuitBreakerName("test", target, method); + assertThat(polarisCircuitBreakerName).isEqualTo("Test#test-svc"); + } + + @Test + public void test2() { + Target target = mock(Target.class); + doReturn("test-svc").when(target).name(); + Method method = ReflectionUtils.findMethod(PolarisCircuitBreakerNameResolverTest.class, "mockRequestMapping2"); + PolarisCircuitBreakerNameResolver resolver = new PolarisCircuitBreakerNameResolver(); + String polarisCircuitBreakerName = resolver.resolveCircuitBreakerName("test", target, method); + assertThat(polarisCircuitBreakerName).isEqualTo("Test#test-svc#/"); + } + + @Test + public void test3() { + Target target = mock(Target.class); + doReturn("test-svc").when(target).name(); + Method method = ReflectionUtils.findMethod(PolarisCircuitBreakerNameResolverTest.class, "mockRequestMapping3"); + PolarisCircuitBreakerNameResolver resolver = new PolarisCircuitBreakerNameResolver(); + String polarisCircuitBreakerName = resolver.resolveCircuitBreakerName("test", target, method); + assertThat(polarisCircuitBreakerName).isEqualTo("Test#test-svc#/"); + } + + + @RequestMapping + public void mockRequestMapping() { + + } + + @RequestMapping(path = "/") + public void mockRequestMapping2() { + + } + + @RequestMapping("/") + public void mockRequestMapping3() { + + } + +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java new file mode 100644 index 00000000..9814cb74 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java @@ -0,0 +1,89 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.circuitbreaker.feign; + +import feign.Feign; +import feign.RequestLine; +import feign.Target; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; +import org.springframework.cloud.openfeign.FeignClientFactoryBean; +import org.springframework.cloud.openfeign.FeignContext; +import org.springframework.cloud.openfeign.PolarisFeignCircuitBreakerTargeter; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +/** + * PolarisFeignCircuitBreakerTargeterTest. + * + * @author sean yu + */ +@ExtendWith(MockitoExtension.class) +public class PolarisFeignCircuitBreakerTargeterTest { + + @Mock + CircuitBreakerFactory circuitBreakerFactory; + + @Mock + PolarisCircuitBreakerNameResolver circuitBreakerNameResolver; + + @Test + public void testTarget() { + PolarisFeignCircuitBreakerTargeter targeter = new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver); + targeter.target(new FeignClientFactoryBean(), new Feign.Builder(), new FeignContext(), new Target.HardCodedTarget<>(TestApi.class, "/test")); + } + + @Test + public void testTarget2() { + PolarisFeignCircuitBreakerTargeter targeter = new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver); + FeignClientFactoryBean feignClientFactoryBean = mock(FeignClientFactoryBean.class); + doReturn(TestApi.class).when(feignClientFactoryBean).getFallback(); + doReturn("test").when(feignClientFactoryBean).getName(); + FeignContext feignClientFactory = mock(FeignContext.class); + doReturn(null).when(feignClientFactory).getInstance("test", TestApi.class); + assertThatThrownBy(() -> { + targeter.target(feignClientFactoryBean, new PolarisFeignCircuitBreaker.Builder(), feignClientFactory, new Target.HardCodedTarget<>(TestApi.class, "/test")); + }).isInstanceOf(IllegalStateException.class); + } + + @Test + public void testTarget3() { + PolarisFeignCircuitBreakerTargeter targeter = new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver); + FeignClientFactoryBean feignClientFactoryBean = mock(FeignClientFactoryBean.class); + doReturn(void.class).when(feignClientFactoryBean).getFallback(); + doReturn(TestApi.class).when(feignClientFactoryBean).getFallbackFactory(); + doReturn("test").when(feignClientFactoryBean).getName(); + FeignContext feignClientFactory = mock(FeignContext.class); + doReturn(Object.class).when(feignClientFactory).getInstance("test", TestApi.class); + assertThatThrownBy(() -> { + targeter.target(feignClientFactoryBean, new PolarisFeignCircuitBreaker.Builder(), feignClientFactory, new Target.HardCodedTarget<>(TestApi.class, "/test")); + }).isInstanceOf(IllegalStateException.class); + } + + interface TestApi { + @RequestLine("GET /test") + void test(); + } + +} 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/gateway/PolarisCircuitBreakerGatewayIntegrationTest.java similarity index 88% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerGatewayIntegrationTest.java index cdb81844..265fd2c2 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/gateway/PolarisCircuitBreakerGatewayIntegrationTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.gateway; import java.io.BufferedReader; @@ -28,9 +28,7 @@ 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; @@ -38,11 +36,11 @@ import com.tencent.polaris.client.util.Utils; import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; import com.tencent.polaris.test.common.TestUtils; import com.tencent.polaris.test.mock.discovery.NamingServer; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import reactor.core.publisher.Mono; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; @@ -75,8 +73,7 @@ import static org.assertj.core.api.Assertions.assertThat; "spring.cloud.gateway.enabled=true", "spring.cloud.polaris.namespace=" + NAMESPACE_TEST, "spring.cloud.polaris.service=" + SERVICE_CIRCUIT_BREAKER, - "spring.main.web-application-type=reactive", - "spring.cloud.polaris.address=grpc://127.0.0.1:10081" + "spring.main.web-application-type=reactive" }, classes = PolarisCircuitBreakerGatewayIntegrationTest.TestApplication.class ) @@ -85,19 +82,13 @@ import static org.assertj.core.api.Assertions.assertThat; public class PolarisCircuitBreakerGatewayIntegrationTest { private static final String TEST_SERVICE_NAME = "test-service-callee"; - private static NamingServer namingServer; + @Autowired private WebTestClient webClient; + @Autowired private ApplicationContext applicationContext; - @AfterAll - public static void afterAll() { - if (null != namingServer) { - namingServer.terminate(); - } - } - @Test public void fallback() throws Exception { SpringCloudCircuitBreakerFilterFactory.Config config = new SpringCloudCircuitBreakerFilterFactory.Config(); @@ -160,18 +151,18 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { public static class TestApplication { @Bean - public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException { - try { - namingServer = NamingServer.startNamingServer(10081); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { + public PreDestroy preDestroy(NamingServer namingServer) { + return new PreDestroy(namingServer); + } - } + @Bean + public NamingServer namingServer() throws IOException { + NamingServer namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME); CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); - InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader() + InputStream inputStream = PolarisCircuitBreakerGatewayIntegrationTest.class.getClassLoader() .getResourceAsStream("circuitBreakerRule.json"); String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines() .collect(Collectors.joining("")); @@ -180,6 +171,11 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() .addRules(circuitBreakerRule).build(); namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker); + return namingServer; + } + + @Bean + public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) throws IOException { com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress(); return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration); } @@ -227,4 +223,18 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { } + public static class PreDestroy implements DisposableBean { + + private final NamingServer namingServer; + + public PreDestroy(NamingServer namingServer) { + this.namingServer = namingServer; + } + + @Override + public void destroy() throws Exception { + namingServer.terminate(); + } + } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateIntegrationTest.java similarity index 87% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateIntegrationTest.java index ff90b537..38bacd64 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateIntegrationTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.resttemplate; import java.io.BufferedReader; import java.io.IOException; @@ -27,12 +27,8 @@ import java.nio.charset.StandardCharsets; import java.util.HashMap; 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.polaris.api.pojo.ServiceKey; import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory; @@ -40,10 +36,10 @@ import com.tencent.polaris.client.util.Utils; import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; import com.tencent.polaris.test.common.TestUtils; import com.tencent.polaris.test.mock.discovery.NamingServer; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -57,7 +53,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.client.ExpectedCount; import org.springframework.test.web.client.MockRestServiceServer; @@ -82,47 +77,44 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat */ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = RANDOM_PORT, - classes = PolarisCircuitBreakerIntegrationTest.TestConfig.class, + classes = PolarisCircuitBreakerRestTemplateIntegrationTest.TestConfig.class, properties = { "spring.cloud.gateway.enabled=false", "feign.circuitbreaker.enabled=true", "spring.cloud.polaris.namespace=" + NAMESPACE_TEST, - "spring.cloud.polaris.service=" + SERVICE_CIRCUIT_BREAKER, - "spring.cloud.polaris.address=grpc://127.0.0.1:10081" + "spring.cloud.polaris.service=" + SERVICE_CIRCUIT_BREAKER }) -@DirtiesContext -public class PolarisCircuitBreakerIntegrationTest { +public class PolarisCircuitBreakerRestTemplateIntegrationTest { private static final String TEST_SERVICE_NAME = "test-service-callee"; - private static NamingServer namingServer; @Autowired @Qualifier("defaultRestTemplate") private RestTemplate defaultRestTemplate; + @Autowired @Qualifier("restTemplateFallbackFromPolaris") private RestTemplate restTemplateFallbackFromPolaris; + @Autowired @Qualifier("restTemplateFallbackFromCode") private RestTemplate restTemplateFallbackFromCode; + @Autowired @Qualifier("restTemplateFallbackFromCode2") private RestTemplate restTemplateFallbackFromCode2; + @Autowired @Qualifier("restTemplateFallbackFromCode3") private RestTemplate restTemplateFallbackFromCode3; + @Autowired @Qualifier("restTemplateFallbackFromCode4") private RestTemplate restTemplateFallbackFromCode4; + @Autowired private ApplicationContext applicationContext; - @AfterAll - public static void afterAll() { - if (null != namingServer) { - namingServer.terminate(); - } - } @Test public void testRestTemplate() throws URISyntaxException { @@ -168,14 +160,14 @@ public class PolarisCircuitBreakerIntegrationTest { public static class TestConfig { @Bean - @PolarisCircuitBreaker(fallback = "fallback") + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallback = "fallback") public RestTemplate defaultRestTemplate() { return new RestTemplate(); } @Bean @LoadBalanced - @PolarisCircuitBreaker + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker public RestTemplate restTemplateFallbackFromPolaris() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -185,7 +177,7 @@ public class PolarisCircuitBreakerIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback.class) + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback.class) public RestTemplate restTemplateFallbackFromCode() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -195,7 +187,7 @@ public class PolarisCircuitBreakerIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback2.class) + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback2.class) public RestTemplate restTemplateFallbackFromCode2() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -205,7 +197,7 @@ public class PolarisCircuitBreakerIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback3.class) + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback3.class) public RestTemplate restTemplateFallbackFromCode3() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -239,18 +231,12 @@ public class PolarisCircuitBreakerIntegrationTest { } @Bean - public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException { - try { - namingServer = NamingServer.startNamingServer(10081); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { - - } + public NamingServer namingServer() throws IOException { + NamingServer namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME); - CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); - InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader() + InputStream inputStream = PolarisCircuitBreakerRestTemplateIntegrationTest.class.getClassLoader() .getResourceAsStream("circuitBreakerRule.json"); String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines() .collect(Collectors.joining("")); @@ -259,6 +245,16 @@ public class PolarisCircuitBreakerIntegrationTest { CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() .addRules(circuitBreakerRule).build(); namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker); + return namingServer; + } + + @Bean + public PreDestroy preDestroy(NamingServer namingServer) { + return new PreDestroy(namingServer); + } + + @Bean + public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) { com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress(); return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration); } @@ -312,4 +308,18 @@ public class PolarisCircuitBreakerIntegrationTest { } } + public static class PreDestroy implements DisposableBean { + + private final NamingServer namingServer; + + public PreDestroy(NamingServer namingServer) { + this.namingServer = namingServer; + } + + @Override + public void destroy() throws Exception { + namingServer.terminate(); + } + } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java index e6213dba..d05a0dcc 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java @@ -35,6 +35,7 @@ import org.mockito.Mockito; import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; public class PolarisCircuitBreakerUtilsTests { @@ -68,4 +69,11 @@ public class PolarisCircuitBreakerUtilsTests { PolarisCircuitBreakerUtils.reportStatus(consumerAPI, conf, new CallAbortedException("mock", new CircuitBreakerStatus.FallbackInfo(0, new HashMap<>(), ""))); } + @Test + public void testResolveCircuitBreakerId() { + assertThat(PolarisCircuitBreakerUtils.resolveCircuitBreakerId("test_svc")).isEqualTo(new String[]{NAMESPACE_TEST, "test_svc", ""}); + assertThat(PolarisCircuitBreakerUtils.resolveCircuitBreakerId("test_svc#test_path")).isEqualTo(new String[]{NAMESPACE_TEST, "test_svc", "test_path"}); + assertThat(PolarisCircuitBreakerUtils.resolveCircuitBreakerId("test_ns#test_svc#test_path")).isEqualTo(new String[]{"test_ns", "test_svc", "test_path"}); + } + } diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index a506ecad..31b65766 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -73,7 +73,7 @@ 1.12.0-Hoxton.SR12 - 1.12.11 + 1.13.0 31.0.1-jre 1.2.11 4.5.1 diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java new file mode 100644 index 00000000..95807dba --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java @@ -0,0 +1,70 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.rpc.enhancement.plugin; + +import org.springframework.core.Ordered; + +/** + * PluginOrderConstant. + * + * @author sean yu + */ +public class PluginOrderConstant { + + public static class ClientPluginOrder { + + /** + * order for + * {@link com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter} + * and + * {@link com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter}. + */ + public static final int CONSUMER_REPORTER_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 1; + + /** + * order for + * {@link com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter} + * and + * {@link com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter}. + */ + public static final int CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 2; + + /** + * order for + * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPreHook} + * and + * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPostHook} + * and + * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientExceptionHook}. + */ + public static final int ASSEMBLY_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 3; + } + + public static class ServerPluginOrder { + /** + * order for + * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPreHook} + * and + * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPostHook} + * and + * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerExceptionHook}. + */ + public static final int ASSEMBLY_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 1; + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java index 76c4250b..9fb1cdd4 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java @@ -34,7 +34,8 @@ import org.slf4j.LoggerFactory; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.Ordered; + +import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.CONSUMER_REPORTER_PLUGIN_ORDER; /** * Polaris reporter when feign call fails. @@ -71,7 +72,8 @@ public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter imp } EnhancedRequestContext request = context.getRequest(); - ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); + ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()) + .orElse(new DefaultServiceInstance()); ServiceCallResult resultRequest = createServiceCallResult( serviceInstance.getServiceId(), @@ -86,7 +88,8 @@ public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter imp ); LOG.debug("Will report ServiceCallResult of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), context.getThrowable().getMessage(), context.getDelay()); + resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl() + .getPath(), context.getThrowable().getMessage(), context.getDelay()); consumerAPI.updateServiceCallResult(resultRequest); @@ -100,7 +103,7 @@ public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter imp @Override public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE + 1; + return CONSUMER_REPORTER_PLUGIN_ORDER; } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java index 4b35396d..6fddf0f8 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java @@ -34,7 +34,8 @@ import org.slf4j.LoggerFactory; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.Ordered; + +import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.CONSUMER_REPORTER_PLUGIN_ORDER; /** * Polaris reporter when feign call is successful. @@ -72,7 +73,8 @@ public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter imple EnhancedRequestContext request = context.getRequest(); EnhancedResponseContext response = context.getResponse(); - ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); + ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()) + .orElse(new DefaultServiceInstance()); ServiceCallResult resultRequest = createServiceCallResult( serviceInstance.getServiceId(), @@ -87,7 +89,8 @@ public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter imple ); LOG.debug("Will report ServiceCallResult of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), response.getHttpStatus(), context.getDelay()); + resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl() + .getPath(), response.getHttpStatus(), context.getDelay()); consumerAPI.updateServiceCallResult(resultRequest); @@ -101,6 +104,6 @@ public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter imple @Override public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE + 1; + return CONSUMER_REPORTER_PLUGIN_ORDER; } }