From 30644858ec42dd4cff0a883f3204c488578cdac7 Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Mon, 18 Jul 2022 20:04:01 +0800 Subject: [PATCH] feat:enhance Feign and RestTemplate and support Polaris monitor. (#447) --- CHANGELOG.md | 1 + README-zh.md | 4 + README.md | 4 + pom.xml | 1 + .../pom.xml | 49 +----- ...olarisCircuitBreakerAutoConfiguration.java | 91 ++++------- ...sCircuitBreakerBootstrapConfiguration.java | 43 +---- .../main/resources/META-INF/spring.factories | 4 +- ...sCircuitBreakerAutoConfigurationTest.java} | 18 +-- ...cuitBreakerBootstrapConfigurationTest.java | 10 +- .../src/test/resources/application.yml | 15 -- .../pom.xml | 39 +---- .../DiscoveryPropertiesAutoConfiguration.java | 17 -- .../pom.xml | 4 + .../common/constant/ContextConstant.java | 5 + spring-cloud-tencent-coverage/pom.xml | 125 +++++++------- spring-cloud-tencent-dependencies/pom.xml | 8 +- .../src/main/resources/bootstrap.yml | 3 + .../src/main/resources/bootstrap.yml | 3 + .../src/main/resources/bootstrap.yml | 3 + .../src/main/resources/bootstrap.yml | 3 + .../src/main/resources/bootstrap.yml | 5 +- spring-cloud-tencent-polaris-context/pom.xml | 38 +++-- .../PolarisContextAutoConfiguration.java | 15 ++ .../PolarisLoggingApplicationListener.java | 56 +++++++ .../main/resources/META-INF/spring.factories | 2 + spring-cloud-tencent-rpc-enhancement/pom.xml | 62 +++++++ .../RpcEnhancementAutoConfiguration.java | 110 +++++++++++++ .../feign/EnhancedFeignBeanPostProcessor.java | 24 +-- ...hancedFeignBlockingLoadBalancerClient.java | 6 +- .../feign/EnhancedFeignClient.java | 153 ++++++++++++++++++ .../feign/plugin/EnhancedFeignContext.java | 69 ++++++++ .../feign/plugin/EnhancedFeignPlugin.java | 62 +++++++ .../feign/plugin/EnhancedFeignPluginType.java | 46 ++++++ .../reporter/ExceptionPolarisReporter.java | 85 ++++++++++ .../feign/plugin/reporter/ReporterUtils.java | 52 +----- .../reporter/SuccessPolarisReporter.java | 82 ++++++++++ .../EnhancedRestTemplateModifier.java | 16 +- .../EnhancedRestTemplateReporter.java | 11 +- .../PolarisResponseErrorHandler.java | 2 +- .../stat/config/PolarisStatProperties.java | 82 ++++++++++ ...olarisStatPropertiesAutoConfiguration.java | 43 +++++ ...sStatPropertiesBootstrapConfiguration.java | 34 ++++ .../stat/config/StatConfigModifier.java | 70 ++++++++ ...itional-spring-configuration-metadata.json | 27 ++++ .../main/resources/META-INF/spring.factories | 5 + .../RpcEnhancementAutoConfigurationTest.java | 44 ++--- .../EnhancedFeignBeanPostProcessorTest.java | 33 ++-- ...edFeignBlockingLoadBalancerClientTest.java | 8 +- .../feign/EnhancedFeignClientTest.java | 128 ++++++++++++--- .../plugin/EnhancedFeignContextTest.java | 46 ++++++ .../ExceptionPolarisReporterTest.java | 101 ++++++++++++ .../plugin/reporter/ReporterUtilsTest.java | 96 +++++++++++ .../reporter/SuccessPolarisReporterTest.java | 103 ++++++++++++ .../EnhancedRestTemplateReporterTest.java | 12 +- .../SimpleClientHttpResponseTest.java | 2 +- ...isStatPropertiesAutoConfigurationTest.java | 45 ++++++ ...tPropertiesBootstrapConfigurationTest.java | 47 ++++++ .../config/PolarisStatPropertiesTest.java | 57 +++++++ .../resources/application-test.properties | 3 + 60 files changed, 1887 insertions(+), 445 deletions(-) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/{PolarisFeignClientAutoConfigurationTest.java => config/PolarisCircuitBreakerAutoConfigurationTest.java} (65%) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/{ => config}/PolarisCircuitBreakerBootstrapConfigurationTest.java (79%) delete mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application.yml create mode 100644 spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingApplicationListener.java create mode 100644 spring-cloud-tencent-rpc-enhancement/pom.xml create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java => spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java (75%) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java => spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBlockingLoadBalancerClient.java (82%) create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPlugin.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPluginType.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java => spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtils.java (51%) create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java => spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateModifier.java (72%) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java => spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java (89%) rename {spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker => spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement}/resttemplate/PolarisResponseErrorHandler.java (94%) create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatProperties.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesAutoConfiguration.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesBootstrapConfiguration.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifier.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/spring.factories rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java => spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java (54%) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessorTest.java => spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessorTest.java (67%) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClientTest.java => spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBlockingLoadBalancerClientTest.java (80%) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java => spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java (58%) create mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContextTest.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtilsTest.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandlerTest.java => spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java (80%) rename {spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker => spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement}/resttemplate/SimpleClientHttpResponseTest.java (97%) create mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesAutoConfigurationTest.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesBootstrapConfigurationTest.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesTest.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/resources/application-test.properties diff --git a/CHANGELOG.md b/CHANGELOG.md index 55f71c8c..8f95d8ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,3 +5,4 @@ - [Optimize: add EncodeTransferMedataRestTemplateInterceptor to RestTemplate](https://github.com/Tencent/spring-cloud-tencent/pull/440) - [Feature: add rate limit filter debug log](https://github.com/Tencent/spring-cloud-tencent/pull/437) - [Add configurable heartbeat interval support](https://github.com/Tencent/spring-cloud-tencent/pull/444) +- [feat:enhance Feign and RestTemplate and support Polaris monitor.](https://github.com/Tencent/spring-cloud-tencent/pull/447) diff --git a/README-zh.md b/README-zh.md index bcda7998..a7c12a03 100644 --- a/README-zh.md +++ b/README-zh.md @@ -54,6 +54,10 @@ Tencent,可直接一键运行任何 example。 Spring Cloud Tencent 所有组件都已上传到 Maven 中央仓库,只需要引入依赖即可。 +> 注意: +> +> Spring Cloud Tencent 的版本列表可以查看 [Spring Cloud Tencent 版本管理](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86) 。 + 例如: ```` xml diff --git a/README.md b/README.md index 946bc8de..0603c500 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,10 @@ directly with one click. All the components of Spring Cloud Tencent have been uploaded to the Maven central repository, just need to introduce dependencies. +> Notice: +> +> The version list of Spring Cloud Tencent can be found in [Spring Cloud Tencent Version Management](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86). + For example: ```` xml diff --git a/pom.xml b/pom.xml index 68b7c014..179477dd 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,7 @@ spring-cloud-tencent-commons spring-cloud-tencent-polaris-context + spring-cloud-tencent-rpc-enhancement spring-cloud-tencent-polaris-loadbalancer spring-cloud-starter-tencent-metadata-transfer spring-cloud-starter-tencent-polaris-config diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml index f79e46aa..f1c42d41 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml @@ -18,36 +18,13 @@ com.tencent.cloud spring-cloud-tencent-polaris-loadbalancer - - - - com.tencent.polaris - polaris-discovery-factory - - - com.tencent.polaris - router-rule - - - com.tencent.polaris - router-nearby - - - com.tencent.polaris - router-metadata - - - com.tencent.polaris - router-canary - - - com.tencent.polaris - router-set - - + com.tencent.cloud + spring-cloud-tencent-rpc-enhancement + + com.tencent.polaris polaris-circuitbreaker-factory @@ -84,28 +61,10 @@ - - org.springframework.cloud - spring-cloud-starter-openfeign - true - - - - org.springframework.boot - spring-boot-starter-web - test - - org.springframework.boot spring-boot-starter-test test - - - org.mockito - mockito-inline - test - diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java index e8e1fa03..cd3f5373 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java @@ -17,84 +17,53 @@ package com.tencent.cloud.polaris.circuitbreaker.config; -import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisFeignBeanPostProcessor; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisResponseErrorHandler; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisRestTemplateModifier; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisRestTemplateResponseErrorHandler; -import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.client.api.SDKContext; -import com.tencent.polaris.factory.api.DiscoveryAPIFactory; +import com.tencent.cloud.common.constant.ContextConstant; +import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; +import com.tencent.cloud.polaris.context.PolarisConfigModifier; +import com.tencent.polaris.api.config.consumer.ServiceRouterConfig; +import com.tencent.polaris.factory.config.ConfigurationImpl; +import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.openfeign.FeignAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.web.client.RestTemplate; - -import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; /** - * Auto Configuration for Polaris {@link feign.Feign} OR {@link RestTemplate} which can automatically bring in the call - * results for reporting. + * Autoconfiguration at bootstrap phase. * - * @author Palmer.Xu 2022-06-29 + * @author lepdou 2022-03-29 */ @Configuration(proxyBeanMethods = false) +@ConditionalOnPolarisEnabled +@ConditionalOnProperty(value = "spring.cloud.polaris.circuitbreaker.enabled", havingValue = "true", matchIfMissing = true) public class PolarisCircuitBreakerAutoConfiguration { - /** - * Configuration for Polaris {@link feign.Feign} which can automatically bring in the call - * results for reporting. - * - * @author Haotian Zhang - */ - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(name = "org.springframework.cloud.openfeign.FeignAutoConfiguration") - @AutoConfigureAfter(PolarisContextAutoConfiguration.class) - @AutoConfigureBefore(FeignAutoConfiguration.class) - @ConditionalOnProperty(value = "spring.cloud.polaris.circuitbreaker.enabled", havingValue = "true", matchIfMissing = true) - protected static class PolarisFeignClientAutoConfiguration { + @Bean + public CircuitBreakerConfigModifier circuitBreakerConfigModifier() { + return new CircuitBreakerConfigModifier(); + } - @Bean - public ConsumerAPI consumerAPI(SDKContext context) { - return DiscoveryAPIFactory.createConsumerAPIByContext(context); - } + public static class CircuitBreakerConfigModifier implements PolarisConfigModifier { - @Bean - @Order(HIGHEST_PRECEDENCE) - public PolarisFeignBeanPostProcessor polarisFeignBeanPostProcessor(ConsumerAPI consumerAPI) { - return new PolarisFeignBeanPostProcessor(consumerAPI); - } - } + @Override + public void modify(ConfigurationImpl configuration) { + // Turn on circuitbreaker configuration + configuration.getConsumer().getCircuitBreaker().setEnable(true); + + // Set excludeCircuitBreakInstances to false + RecoverRouterConfig recoverRouterConfig = configuration.getConsumer().getServiceRouter() + .getPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, RecoverRouterConfig.class); - /** - * Configuration for Polaris {@link RestTemplate} which can automatically bring in the call - * results for reporting. - * - * @author wh 2022/6/21 - */ - @Configuration(proxyBeanMethods = false) - @AutoConfigureAfter(PolarisContextAutoConfiguration.class) - @ConditionalOnClass(RestTemplate.class) - @ConditionalOnProperty(value = "spring.cloud.polaris.circuitbreaker.enabled", havingValue = "true", matchIfMissing = true) - protected static class PolarisRestTemplateAutoConfiguration { + recoverRouterConfig.setExcludeCircuitBreakInstances(true); - @Bean - public PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler( - ConsumerAPI consumerAPI, @Autowired(required = false) PolarisResponseErrorHandler polarisResponseErrorHandler) { - return new PolarisRestTemplateResponseErrorHandler(consumerAPI, polarisResponseErrorHandler); + // Update modified config to source properties + configuration.getConsumer().getServiceRouter() + .setPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, recoverRouterConfig); } - @Bean - public PolarisRestTemplateModifier polarisRestTemplateBeanPostProcessor( - PolarisRestTemplateResponseErrorHandler restTemplateResponseErrorHandler) { - return new PolarisRestTemplateModifier(restTemplateResponseErrorHandler); + @Override + public int getOrder() { + return ContextConstant.ModifierOrder.CIRCUIT_BREAKER_ORDER; } } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java index bc4e022e..9d21fbf0 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java @@ -17,53 +17,18 @@ package com.tencent.cloud.polaris.circuitbreaker.config; -import com.tencent.cloud.common.constant.ContextConstant; -import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; -import com.tencent.cloud.polaris.context.PolarisConfigModifier; -import com.tencent.polaris.api.config.consumer.ServiceRouterConfig; -import com.tencent.polaris.factory.config.ConfigurationImpl; -import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig; - import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; /** - * Auto configuration at bootstrap phase. + * Autoconfiguration at bootstrap phase. * * @author lepdou 2022-03-29 */ @Configuration(proxyBeanMethods = false) -@ConditionalOnPolarisEnabled -@ConditionalOnProperty(value = "spring.cloud.polaris.circuitbreaker.enabled", havingValue = "true", matchIfMissing = true) +@ConditionalOnProperty("spring.cloud.polaris.enabled") +@Import(PolarisCircuitBreakerAutoConfiguration.class) public class PolarisCircuitBreakerBootstrapConfiguration { - @Bean - public CircuitBreakerConfigModifier circuitBreakerConfigModifier() { - return new CircuitBreakerConfigModifier(); - } - - public static class CircuitBreakerConfigModifier implements PolarisConfigModifier { - - @Override - public void modify(ConfigurationImpl configuration) { - // Turn on circuitbreaker configuration - configuration.getConsumer().getCircuitBreaker().setEnable(true); - - // Set excludeCircuitBreakInstances to false - RecoverRouterConfig recoverRouterConfig = configuration.getConsumer().getServiceRouter() - .getPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, RecoverRouterConfig.class); - - recoverRouterConfig.setExcludeCircuitBreakInstances(true); - - // Update modified config to source properties - configuration.getConsumer().getServiceRouter() - .setPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, recoverRouterConfig); - } - - @Override - public int getOrder() { - return ContextConstant.ModifierOrder.CIRCUIT_BREAKER_ORDER; - } - } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories index 2c72cfed..418da24a 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories @@ -1,4 +1,4 @@ -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ - com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration +org.springframework.cloud.bootstrap.BootstrapConfiguration=\ + com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java similarity index 65% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java index 6858a627..433e0bb0 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.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.feign.PolarisFeignBeanPostProcessor; -import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; -import com.tencent.polaris.api.core.ConsumerAPI; import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -33,20 +29,16 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Haotian Zhang */ -public class PolarisFeignClientAutoConfigurationTest { - +public class PolarisCircuitBreakerAutoConfigurationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - PolarisContextAutoConfiguration.class, - PolarisCircuitBreakerAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(PolarisCircuitBreakerAutoConfiguration.class)) .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true"); @Test public void testDefaultInitialization() { this.contextRunner.run(context -> { - assertThat(context).hasSingleBean(ConsumerAPI.class); - assertThat(context).hasSingleBean(PolarisFeignBeanPostProcessor.class); + assertThat(context).hasSingleBean( + PolarisCircuitBreakerAutoConfiguration.CircuitBreakerConfigModifier.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 79% 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 5f5f8601..a4430c1d 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,9 +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.PolarisCircuitBreakerBootstrapConfiguration; import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -32,14 +31,15 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisCircuitBreakerBootstrapConfigurationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisCircuitBreakerBootstrapConfiguration.class)) + .withConfiguration(AutoConfigurations.of(PolarisCircuitBreakerBootstrapConfiguration.class)) + .withPropertyValues("spring.cloud.polaris.enabled=true") .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true"); @Test public void testDefaultInitialization() { this.contextRunner.run(context -> { - assertThat(context).hasSingleBean(PolarisCircuitBreakerBootstrapConfiguration.CircuitBreakerConfigModifier.class); + assertThat(context).hasSingleBean( + PolarisCircuitBreakerAutoConfiguration.CircuitBreakerConfigModifier.class); }); } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application.yml b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application.yml deleted file mode 100644 index 06500ed9..00000000 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application.yml +++ /dev/null @@ -1,15 +0,0 @@ -spring: - cloud: - polaris: - address: grpc://127.0.0.1:8091 - -feign: - polaris: - enable: true - compression: - request: - enabled: false - mime-types: text/xml,application/xml,application/json - min-request-size: 2048 - response: - enabled: false diff --git a/spring-cloud-starter-tencent-polaris-discovery/pom.xml b/spring-cloud-starter-tencent-polaris-discovery/pom.xml index 62ad96fb..a25d2987 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/pom.xml +++ b/spring-cloud-starter-tencent-polaris-discovery/pom.xml @@ -19,44 +19,13 @@ com.tencent.cloud spring-cloud-tencent-polaris-loadbalancer - - - - com.tencent.polaris - polaris-discovery-factory - - - com.tencent.polaris - router-rule - - - com.tencent.polaris - router-nearby - - - com.tencent.polaris - router-metadata - - - com.tencent.polaris - router-canary - - - com.tencent.polaris - router-set - - - com.tencent.polaris - router-isolated - - - com.tencent.polaris - router-healthy - - + com.tencent.cloud + spring-cloud-tencent-rpc-enhancement + + com.tencent.polaris polaris-test-common diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java index 4eb2efd3..6e9f1b23 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java @@ -20,11 +20,6 @@ package com.tencent.cloud.polaris; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.core.ProviderAPI; -import com.tencent.polaris.api.exception.PolarisException; -import com.tencent.polaris.client.api.SDKContext; -import com.tencent.polaris.factory.api.DiscoveryAPIFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; @@ -41,18 +36,6 @@ import org.springframework.context.annotation.Import; @Import({PolarisDiscoveryProperties.class, ConsulContextProperties.class}) public class DiscoveryPropertiesAutoConfiguration { - @Bean - @ConditionalOnMissingBean - public ProviderAPI polarisProvider(SDKContext polarisContext) throws PolarisException { - return DiscoveryAPIFactory.createProviderAPIByContext(polarisContext); - } - - @Bean - @ConditionalOnMissingBean - public ConsumerAPI polarisConsumer(SDKContext polarisContext) throws PolarisException { - return DiscoveryAPIFactory.createConsumerAPIByContext(polarisContext); - } - @Bean @ConditionalOnMissingBean public PolarisDiscoveryHandler polarisDiscoveryHandler() { diff --git a/spring-cloud-starter-tencent-polaris-router/pom.xml b/spring-cloud-starter-tencent-polaris-router/pom.xml index e21ca43f..f8445ef6 100644 --- a/spring-cloud-starter-tencent-polaris-router/pom.xml +++ b/spring-cloud-starter-tencent-polaris-router/pom.xml @@ -19,6 +19,10 @@ com.tencent.cloud spring-cloud-tencent-polaris-loadbalancer + + com.tencent.cloud + spring-cloud-tencent-rpc-enhancement + com.tencent.cloud spring-cloud-starter-tencent-metadata-transfer diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java index 8117ef8f..8fa44f2f 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java @@ -73,5 +73,10 @@ public final class ContextConstant { * Order of configuration modifier. */ public static Integer CONFIG_ORDER = 1; + + /** + * Order of stat reporter configuration modifier. + */ + public static Integer STAT_REPORTER_ORDER = 1; } } diff --git a/spring-cloud-tencent-coverage/pom.xml b/spring-cloud-tencent-coverage/pom.xml index 37903c14..27742575 100644 --- a/spring-cloud-tencent-coverage/pom.xml +++ b/spring-cloud-tencent-coverage/pom.xml @@ -1,63 +1,68 @@ - - spring-cloud-tencent - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + spring-cloud-tencent + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 - spring-cloud-tencent-coverage - Spring Cloud Tencent Coverage - pom + spring-cloud-tencent-coverage + Spring Cloud Tencent Coverage + pom - - true - + + true + - - - com.tencent.cloud - spring-cloud-tencent-commons - + + + com.tencent.cloud + spring-cloud-tencent-commons + com.tencent.cloud spring-cloud-tencent-polaris-context + + com.tencent.cloud + spring-cloud-tencent-rpc-enhancement + + com.tencent.cloud spring-cloud-tencent-polaris-loadbalancer - - com.tencent.cloud - spring-cloud-starter-tencent-polaris-discovery - + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-discovery + - - com.tencent.cloud - spring-cloud-starter-tencent-polaris-ratelimit - + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-ratelimit + - - com.tencent.cloud - spring-cloud-starter-tencent-polaris-circuitbreaker - + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-circuitbreaker + - - com.tencent.cloud - spring-cloud-starter-tencent-metadata-transfer - + + com.tencent.cloud + spring-cloud-starter-tencent-metadata-transfer + - - com.tencent.cloud - spring-cloud-starter-tencent-polaris-router - + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-router + com.tencent.cloud @@ -65,24 +70,24 @@ - - - - org.jacoco - jacoco-maven-plugin - - - report-aggregate - test - - report-aggregate - - - ${basedir}/../target/site/jacoco - - - - - - + + + + org.jacoco + jacoco-maven-plugin + + + report-aggregate + test + + report-aggregate + + + ${basedir}/../target/site/jacoco + + + + + + diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index ee0f7328..056e1215 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -73,7 +73,7 @@ 1.7.0-2021.0.3-SNAPSHOT - 1.7.0 + 1.7.1 31.0.1-jre 1.2.11 4.5.1 @@ -109,6 +109,12 @@ ${revision} + + com.tencent.cloud + spring-cloud-tencent-rpc-enhancement + ${revision} + + com.tencent.cloud spring-cloud-tencent-polaris-loadbalancer diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml index a98ef90a..91a7570c 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml @@ -10,6 +10,9 @@ spring: enabled: true circuitbreaker: enabled: true + stat: + enabled: true + port: 28081 loadbalancer: configurations: polaris feign: diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml index 3805dfa5..d6945b5b 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml @@ -8,3 +8,6 @@ spring: address: grpc://183.47.111.80:8091 namespace: default enabled: true + stat: + enabled: true + port: 28082 diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/resources/bootstrap.yml index f3720f09..5ef89145 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/resources/bootstrap.yml @@ -8,3 +8,6 @@ spring: address: grpc://183.47.111.80:8091 namespace: default enabled: true + stat: + enabled: true + port: 28083 diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml index 75b4e33d..1e42dc34 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml @@ -11,6 +11,9 @@ spring: discovery: enabled: true register: true + stat: + enabled: true + port: 28082 tencent: metadata: content: diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml index fcfdad35..62b94401 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml @@ -19,6 +19,9 @@ spring: heartbeat: enabled: true health-check-url: /discovery/service/caller/healthCheck + stat: + enabled: true + port: 28081 # consul: # port: 8500 # host: 127.0.0.1 @@ -41,4 +44,4 @@ management: web: exposure: include: - - polaris-discovery \ No newline at end of file + - polaris-discovery diff --git a/spring-cloud-tencent-polaris-context/pom.xml b/spring-cloud-tencent-polaris-context/pom.xml index aa9b8523..786f536b 100644 --- a/spring-cloud-tencent-polaris-context/pom.xml +++ b/spring-cloud-tencent-polaris-context/pom.xml @@ -27,6 +27,33 @@ + + com.tencent.polaris + polaris-discovery-factory + + + com.tencent.polaris + router-rule + + + com.tencent.polaris + router-nearby + + + com.tencent.polaris + router-metadata + + + com.tencent.polaris + router-canary + + + com.tencent.polaris + router-set + + + + com.tencent.polaris polaris-client @@ -62,17 +89,6 @@ flow-cache-expired - - - com.tencent.polaris - router-isolated - - - - com.tencent.polaris - router-healthy - - com.tencent.polaris loadbalancer-random diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java index c1e77263..5b66506d 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java @@ -24,8 +24,11 @@ import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.context.ModifyAddress; import com.tencent.cloud.polaris.context.PolarisConfigModifier; import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.api.core.ProviderAPI; import com.tencent.polaris.api.exception.PolarisException; import com.tencent.polaris.client.api.SDKContext; +import com.tencent.polaris.factory.api.DiscoveryAPIFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -48,6 +51,18 @@ public class PolarisContextAutoConfiguration { return SDKContext.initContextByConfig(properties.configuration(environment, modifierList)); } + @Bean + @ConditionalOnMissingBean + public ProviderAPI polarisProvider(SDKContext polarisContext) throws PolarisException { + return DiscoveryAPIFactory.createProviderAPIByContext(polarisContext); + } + + @Bean + @ConditionalOnMissingBean + public ConsumerAPI polarisConsumer(SDKContext polarisContext) throws PolarisException { + return DiscoveryAPIFactory.createConsumerAPIByContext(polarisContext); + } + @Bean @ConditionalOnMissingBean public ModifyAddress polarisConfigModifier() { diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingApplicationListener.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingApplicationListener.java new file mode 100644 index 00000000..52f1948a --- /dev/null +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingApplicationListener.java @@ -0,0 +1,56 @@ +/* + * 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.context.logging; + +import com.tencent.polaris.logging.PolarisLogging; + +import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; +import org.springframework.boot.context.event.ApplicationFailedEvent; +import org.springframework.boot.context.logging.LoggingApplicationListener; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.event.GenericApplicationListener; +import org.springframework.core.ResolvableType; + +/** + * Reload of Polaris logging configuration. + * + * @author Haotian Zhang + */ +public class PolarisLoggingApplicationListener implements GenericApplicationListener { + + private static final int ORDER = LoggingApplicationListener.DEFAULT_ORDER + 2; + + @Override + public boolean supportsEventType(ResolvableType resolvableType) { + Class type = resolvableType.getRawClass(); + if (type == null) { + return false; + } + return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(type) + || ApplicationFailedEvent.class.isAssignableFrom(type); + } + + @Override + public int getOrder() { + return ORDER; + } + + @Override + public void onApplicationEvent(ApplicationEvent applicationEvent) { + PolarisLogging.getInstance().loadConfiguration(); + } +} diff --git a/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories index 723fc1d7..a121e3c2 100644 --- a/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories @@ -3,3 +3,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.polaris.context.config.PolarisContextPostConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.tencent.cloud.polaris.context.config.PolarisContextBootstrapAutoConfiguration +org.springframework.context.ApplicationListener=\ + com.tencent.cloud.polaris.context.logging.PolarisLoggingApplicationListener diff --git a/spring-cloud-tencent-rpc-enhancement/pom.xml b/spring-cloud-tencent-rpc-enhancement/pom.xml new file mode 100644 index 00000000..9709c9c5 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/pom.xml @@ -0,0 +1,62 @@ + + + + spring-cloud-tencent + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + spring-cloud-tencent-rpc-enhancement + Spring Cloud Starter Tencent RPC Enhancement + + + + + com.tencent.cloud + spring-cloud-tencent-polaris-loadbalancer + + + + + + com.tencent.polaris + stat-prometheus + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + true + + + + com.tencent.polaris + polaris-test-common + test + + + + org.springframework.boot + spring-boot-starter-web + test + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.mockito + mockito-inline + test + + + + \ No newline at end of file diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java new file mode 100644 index 00000000..b44400a3 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java @@ -0,0 +1,110 @@ +/* + * 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.config; + +import java.util.List; + +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; +import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignBeanPostProcessor; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; +import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.ExceptionPolarisReporter; +import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.SuccessPolarisReporter; +import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateModifier; +import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateReporter; +import com.tencent.cloud.rpc.enhancement.resttemplate.PolarisResponseErrorHandler; +import com.tencent.polaris.api.core.ConsumerAPI; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.web.client.RestTemplate; + +import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; + +/** + * Auto Configuration for Polaris {@link feign.Feign} OR {@link RestTemplate} which can automatically bring in the call + * results for reporting. + * + * @author Palmer.Xu 2022-06-29 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnProperty(value = "spring.cloud.tencent.rpc-enhancement.enabled", havingValue = "true", matchIfMissing = true) +@AutoConfigureAfter(PolarisContextAutoConfiguration.class) +public class RpcEnhancementAutoConfiguration { + + /** + * Configuration for Polaris {@link feign.Feign} which can automatically bring in the call + * results for reporting. + * + * @author Haotian Zhang + */ + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(name = "org.springframework.cloud.openfeign.FeignAutoConfiguration") + @AutoConfigureBefore(name = "org.springframework.cloud.openfeign.FeignAutoConfiguration") + protected static class PolarisFeignClientAutoConfiguration { + + @Bean + @Order(HIGHEST_PRECEDENCE) + public EnhancedFeignBeanPostProcessor polarisFeignBeanPostProcessor( + @Autowired(required = false) List enhancedFeignPlugins) { + return new EnhancedFeignBeanPostProcessor(enhancedFeignPlugins); + } + + @Configuration + static class PolarisReporterConfig { + + @Bean + public SuccessPolarisReporter successPolarisReporter() { + return new SuccessPolarisReporter(); + } + + @Bean + public ExceptionPolarisReporter exceptionPolarisReporter() { + return new ExceptionPolarisReporter(); + } + } + } + + /** + * Configuration for Polaris {@link RestTemplate} which can automatically bring in the call + * results for reporting. + * + * @author wh 2022/6/21 + */ + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(name = "org.springframework.web.client.RestTemplate") + protected static class PolarisRestTemplateAutoConfiguration { + + @Bean + public EnhancedRestTemplateReporter polarisRestTemplateResponseErrorHandler( + ConsumerAPI consumerAPI, @Autowired(required = false) PolarisResponseErrorHandler polarisResponseErrorHandler) { + return new EnhancedRestTemplateReporter(consumerAPI, polarisResponseErrorHandler); + } + + @Bean + public EnhancedRestTemplateModifier polarisRestTemplateBeanPostProcessor( + EnhancedRestTemplateReporter enhancedRestTemplateReporter) { + return new EnhancedRestTemplateModifier(enhancedRestTemplateReporter); + } + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java similarity index 75% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java index 0470067d..1dc1f9f8 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java @@ -15,9 +15,11 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.feign; +package com.tencent.cloud.rpc.enhancement.feign; -import com.tencent.polaris.api.core.ConsumerAPI; +import java.util.List; + +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; import feign.Client; import org.springframework.beans.BeansException; @@ -34,14 +36,14 @@ import org.springframework.cloud.openfeign.loadbalancer.RetryableFeignBlockingLo * * @author Haotian Zhang */ -public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { +public class EnhancedFeignBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { - private final ConsumerAPI consumerAPI; + private final List enhancedFeignPlugins; private BeanFactory factory; - public PolarisFeignBeanPostProcessor(ConsumerAPI consumerAPI) { - this.consumerAPI = consumerAPI; + public EnhancedFeignBeanPostProcessor(List enhancedFeignPlugins) { + this.enhancedFeignPlugins = enhancedFeignPlugins; } @Override @@ -61,7 +63,7 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac delegate = ((FeignBlockingLoadBalancerClient) bean).getDelegate(); } if (delegate != null) { - return new PolarisFeignBlockingLoadBalancerClient(createPolarisFeignClient(delegate), + return new EnhancedFeignBlockingLoadBalancerClient(createPolarisFeignClient(delegate), factory.getBean(BlockingLoadBalancerClient.class), factory.getBean(LoadBalancerClientFactory.class)); } @@ -72,12 +74,12 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac } private boolean isNeedWrap(Object bean) { - return bean instanceof Client && !(bean instanceof PolarisFeignClient) - && !(bean instanceof PolarisFeignBlockingLoadBalancerClient); + return bean instanceof Client && !(bean instanceof EnhancedFeignClient) + && !(bean instanceof EnhancedFeignBlockingLoadBalancerClient); } - private PolarisFeignClient createPolarisFeignClient(Client delegate) { - return new PolarisFeignClient(delegate, consumerAPI); + private EnhancedFeignClient createPolarisFeignClient(Client delegate) { + return new EnhancedFeignClient(delegate, enhancedFeignPlugins); } @Override diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBlockingLoadBalancerClient.java similarity index 82% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBlockingLoadBalancerClient.java index fe6b4f38..fa545706 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBlockingLoadBalancerClient.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.feign; +package com.tencent.cloud.rpc.enhancement.feign; import feign.Client; @@ -28,9 +28,9 @@ import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalance * * @author Haotian Zhang */ -public class PolarisFeignBlockingLoadBalancerClient extends FeignBlockingLoadBalancerClient { +public class EnhancedFeignBlockingLoadBalancerClient extends FeignBlockingLoadBalancerClient { - public PolarisFeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient, + public EnhancedFeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient, LoadBalancerClientFactory loadBalancerClientFactory) { super(delegate, loadBalancerClient, loadBalancerClientFactory); } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java new file mode 100644 index 00000000..18b06c36 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java @@ -0,0 +1,153 @@ +/* + * 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.feign; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; +import feign.Client; +import feign.Request; +import feign.Request.Options; +import feign.Response; + +import org.springframework.util.CollectionUtils; + +import static feign.Util.checkNotNull; + +/** + * Wrap for {@link Client}. + * + * @author Haotian Zhang + */ +public class EnhancedFeignClient implements Client { + + private final Client delegate; + + private List preEnhancedFeignPlugins; + + private List postEnhancedFeignPlugins; + + private List exceptionEnhancedFeignPlugins; + + private List finallyEnhancedFeignPlugins; + + public EnhancedFeignClient(Client target, List enhancedFeignPlugins) { + this.delegate = checkNotNull(target, "target"); + + // Init the EnhancedFeignPlugins list. + this.preEnhancedFeignPlugins = new ArrayList<>(); + this.postEnhancedFeignPlugins = new ArrayList<>(); + this.exceptionEnhancedFeignPlugins = new ArrayList<>(); + this.finallyEnhancedFeignPlugins = new ArrayList<>(); + if (!CollectionUtils.isEmpty(enhancedFeignPlugins)) { + for (EnhancedFeignPlugin feignPlugin : enhancedFeignPlugins) { + if (feignPlugin.getType().equals(EnhancedFeignPluginType.PRE)) { + this.preEnhancedFeignPlugins.add(feignPlugin); + } + else if (feignPlugin.getType().equals(EnhancedFeignPluginType.POST)) { + this.postEnhancedFeignPlugins.add(feignPlugin); + } + else if (feignPlugin.getType().equals(EnhancedFeignPluginType.EXCEPTION)) { + this.exceptionEnhancedFeignPlugins.add(feignPlugin); + } + else if (feignPlugin.getType().equals(EnhancedFeignPluginType.FINALLY)) { + this.finallyEnhancedFeignPlugins.add(feignPlugin); + } + } + } + // Set the ordered enhanced feign plugins. + this.preEnhancedFeignPlugins = getSortedEnhancedFeignPlugin(this.preEnhancedFeignPlugins); + this.postEnhancedFeignPlugins = getSortedEnhancedFeignPlugin(this.postEnhancedFeignPlugins); + this.exceptionEnhancedFeignPlugins = getSortedEnhancedFeignPlugin(this.exceptionEnhancedFeignPlugins); + this.finallyEnhancedFeignPlugins = getSortedEnhancedFeignPlugin(this.finallyEnhancedFeignPlugins); + } + + @Override + public Response execute(Request request, Options options) throws IOException { + EnhancedFeignContext enhancedFeignContext = new EnhancedFeignContext(); + enhancedFeignContext.setRequest(request); + enhancedFeignContext.setOptions(options); + + // Run pre enhanced feign plugins. + for (EnhancedFeignPlugin plugin : preEnhancedFeignPlugins) { + try { + plugin.run(enhancedFeignContext); + } + catch (Throwable throwable) { + plugin.handlerThrowable(enhancedFeignContext, throwable); + } + } + try { + Response response = delegate.execute(request, options); + enhancedFeignContext.setResponse(response); + + // Run post enhanced feign plugins. + for (EnhancedFeignPlugin plugin : postEnhancedFeignPlugins) { + try { + plugin.run(enhancedFeignContext); + } + catch (Throwable throwable) { + plugin.handlerThrowable(enhancedFeignContext, throwable); + } + } + return response; + } + catch (IOException origin) { + enhancedFeignContext.setException(origin); + // Run exception enhanced feign plugins. + for (EnhancedFeignPlugin plugin : exceptionEnhancedFeignPlugins) { + try { + plugin.run(enhancedFeignContext); + } + catch (Throwable throwable) { + plugin.handlerThrowable(enhancedFeignContext, throwable); + } + } + throw origin; + } + finally { + // Run finally enhanced feign plugins. + for (EnhancedFeignPlugin plugin : finallyEnhancedFeignPlugins) { + try { + plugin.run(enhancedFeignContext); + } + catch (Throwable throwable) { + plugin.handlerThrowable(enhancedFeignContext, throwable); + } + } + } + } + + /** + * Ascending, which means the lower order number, the earlier executing enhanced feign plugin. + * + * @return sorted feign pre plugin list + */ + private List getSortedEnhancedFeignPlugin(List preEnhancedFeignPlugins) { + return new ArrayList<>(preEnhancedFeignPlugins) + .stream() + .sorted(Comparator.comparing(EnhancedFeignPlugin::getOrder)) + .collect(Collectors.toList()); + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java new file mode 100644 index 00000000..e6f3be61 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java @@ -0,0 +1,69 @@ +/* + * 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.feign.plugin; + +import feign.Request; +import feign.Response; + +/** + * Context used by EnhancedFeignPlugin. + * + * @author Haotian Zhang + */ +public class EnhancedFeignContext { + + private Request request; + + private Request.Options options; + + private Response response; + + private Exception exception; + + public Request getRequest() { + return request; + } + + public void setRequest(Request request) { + this.request = request; + } + + public Request.Options getOptions() { + return options; + } + + public void setOptions(Request.Options options) { + this.options = options; + } + + public Response getResponse() { + return response; + } + + public void setResponse(Response response) { + this.response = response; + } + + public Exception getException() { + return exception; + } + + public void setException(Exception exception) { + this.exception = exception; + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPlugin.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPlugin.java new file mode 100644 index 00000000..bfe141d3 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPlugin.java @@ -0,0 +1,62 @@ +/* + * 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.feign.plugin; + +import org.springframework.core.Ordered; + +/** + * Pre plugin used by EnhancedFeignClient. + * + * @author Haotian Zhang + */ +public interface EnhancedFeignPlugin extends Ordered { + + /** + * Get name of plugin. + * + * @return name + */ + default String getName() { + return this.getClass().getName(); + } + + /** + * Get type of plugin. + * + * @return {@link EnhancedFeignPluginType} + */ + EnhancedFeignPluginType getType(); + + /** + * Run the plugin. + * + * @param context context in enhanced feign client. + * @throws Throwable throwable thrown from run method. + */ + void run(EnhancedFeignContext context) throws Throwable; + + /** + * Handler throwable from {@link EnhancedFeignPlugin#run(EnhancedFeignContext)}. + * + * @param context context in enhanced feign client. + * @param throwable throwable thrown from run method. + */ + default void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPluginType.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPluginType.java new file mode 100644 index 00000000..fef181d8 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPluginType.java @@ -0,0 +1,46 @@ +/* + * 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.feign.plugin; + +/** + * Type of EnhancedFeignPlugin. + * + * @author Haotian Zhang + */ +public enum EnhancedFeignPluginType { + + /** + * Pre feign plugin. + */ + PRE, + + /** + * Post feign plugin. + */ + POST, + + /** + * Exception feign plugin. + */ + EXCEPTION, + + /** + * Finally feign plugin. + */ + FINALLY +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java new file mode 100644 index 00000000..bfbec80c --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java @@ -0,0 +1,85 @@ +/* + * 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.feign.plugin.reporter; + +import java.net.SocketTimeoutException; + +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.api.pojo.RetStatus; +import com.tencent.polaris.api.rpc.ServiceCallResult; +import feign.Request; +import feign.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.Ordered; + +/** + * Polaris reporter when feign call is successful. + * + * @author Haotian Zhang + */ +public class ExceptionPolarisReporter implements EnhancedFeignPlugin { + + private static final Logger LOG = LoggerFactory.getLogger(ExceptionPolarisReporter.class); + + @Autowired(required = false) + private ConsumerAPI consumerAPI; + + @Override + public String getName() { + return ExceptionPolarisReporter.class.getName(); + } + + @Override + public EnhancedFeignPluginType getType() { + return EnhancedFeignPluginType.EXCEPTION; + } + + @Override + public void run(EnhancedFeignContext context) { + if (consumerAPI != null) { + Request request = context.getRequest(); + Response response = context.getResponse(); + Exception exception = context.getException(); + RetStatus retStatus = RetStatus.RetFail; + if (exception instanceof SocketTimeoutException) { + retStatus = RetStatus.RetTimeout; + } + LOG.debug("Will report result of {}. Request=[{}]. Response=[{}].", retStatus.name(), request, response); + ServiceCallResult resultRequest = ReporterUtils.createServiceCallResult(request, retStatus); + consumerAPI.updateServiceCallResult(resultRequest); + } + } + + @Override + public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + Request request = context.getRequest(); + Response response = context.getResponse(); + LOG.error("ExceptionPolarisReporter runs failed. Request=[{}]. Response=[{}].", request, response, throwable); + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE + 1; + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtils.java similarity index 51% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtils.java index 48fa3ae8..432b911e 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtils.java @@ -15,68 +15,28 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.feign; +package com.tencent.cloud.rpc.enhancement.feign.plugin.reporter; -import java.io.IOException; import java.net.URI; import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.pojo.RetStatus; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.api.rpc.ServiceCallResult; -import feign.Client; import feign.Request; -import feign.Request.Options; -import feign.Response; import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static feign.Util.checkNotNull; /** - * Wrap for {@link Client}. + * Util for polaris reporter. * * @author Haotian Zhang */ -public class PolarisFeignClient implements Client { - - private static final Logger LOG = LoggerFactory.getLogger(PolarisFeignClient.class); - - private final Client delegate; +public final class ReporterUtils { - private final ConsumerAPI consumerAPI; - - public PolarisFeignClient(Client target, ConsumerAPI consumerAPI) { - this.delegate = checkNotNull(target, "target"); - this.consumerAPI = checkNotNull(consumerAPI, "CircuitBreakAPI"); - } - - @Override - public Response execute(Request request, Options options) throws IOException { - final ServiceCallResult resultRequest = createServiceCallResult(request); - try { - Response response = delegate.execute(request, options); - // HTTP code greater than 500 is an exception - if (response.status() > 500) { - resultRequest.setRetStatus(RetStatus.RetFail); - } - LOG.debug("Will report result of {}. Request=[{}]. Response=[{}].", - resultRequest.getRetStatus().name(), request, response); - return response; - } - catch (IOException origin) { - resultRequest.setRetStatus(RetStatus.RetFail); - LOG.debug("Will report result of {}. Request=[{}].", resultRequest.getRetStatus().name(), request, origin); - throw origin; - } - finally { - consumerAPI.updateServiceCallResult(resultRequest); - } + private ReporterUtils() { } - private ServiceCallResult createServiceCallResult(final Request request) { + public static ServiceCallResult createServiceCallResult(final Request request, RetStatus retStatus) { ServiceCallResult resultRequest = new ServiceCallResult(); resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE); @@ -84,7 +44,7 @@ public class PolarisFeignClient implements Client { resultRequest.setService(serviceName); URI uri = URI.create(request.url()); resultRequest.setMethod(uri.getPath()); - resultRequest.setRetStatus(RetStatus.RetSuccess); + resultRequest.setRetStatus(retStatus); String sourceNamespace = MetadataContext.LOCAL_NAMESPACE; String sourceService = MetadataContext.LOCAL_SERVICE; if (StringUtils.isNotBlank(sourceNamespace) && StringUtils.isNotBlank(sourceService)) { diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java new file mode 100644 index 00000000..332711ea --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java @@ -0,0 +1,82 @@ +/* + * 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.feign.plugin.reporter; + +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.api.pojo.RetStatus; +import com.tencent.polaris.api.rpc.ServiceCallResult; +import feign.Request; +import feign.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.Ordered; + +/** + * Polaris reporter when feign call is successful. + * + * @author Haotian Zhang + */ +public class SuccessPolarisReporter implements EnhancedFeignPlugin { + + private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class); + + @Autowired(required = false) + private ConsumerAPI consumerAPI; + + @Override + public String getName() { + return SuccessPolarisReporter.class.getName(); + } + + @Override + public EnhancedFeignPluginType getType() { + return EnhancedFeignPluginType.POST; + } + + @Override + public void run(EnhancedFeignContext context) { + if (consumerAPI != null) { + Request request = context.getRequest(); + Response response = context.getResponse(); + RetStatus retStatus = RetStatus.RetSuccess; + if (response.status() > 500) { + retStatus = RetStatus.RetFail; + } + LOG.debug("Will report result of {}. Request=[{}]. Response=[{}].", retStatus.name(), request, response); + ServiceCallResult resultRequest = ReporterUtils.createServiceCallResult(request, retStatus); + consumerAPI.updateServiceCallResult(resultRequest); + } + } + + @Override + public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + Request request = context.getRequest(); + Response response = context.getResponse(); + LOG.error("SuccessPolarisReporter runs failed. Request=[{}]. Response=[{}].", request, response, throwable); + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE + 1; + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateModifier.java similarity index 72% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateModifier.java index 6fd56e58..e4cf0211 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateModifier.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.resttemplate; +package com.tencent.cloud.rpc.enhancement.resttemplate; import java.util.Map; @@ -28,19 +28,19 @@ import org.springframework.util.ObjectUtils; import org.springframework.web.client.RestTemplate; /** - * Auto configuration RestTemplate, Find the RestTemplate bean annotated with {@link LoadBalanced}, + * Autoconfiguration RestTemplate, Find the RestTemplate bean annotated with {@link LoadBalanced}, * then replace {@link org.springframework.web.client.ResponseErrorHandler} - * with {@link PolarisRestTemplateResponseErrorHandler} . + * with {@link EnhancedRestTemplateReporter} . * * @author wh 2022/6/21 */ -public class PolarisRestTemplateModifier implements ApplicationContextAware, SmartInitializingSingleton { +public class EnhancedRestTemplateModifier implements ApplicationContextAware, SmartInitializingSingleton { - private final PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler; + private final EnhancedRestTemplateReporter enhancedRestTemplateReporter; private ApplicationContext applicationContext; - public PolarisRestTemplateModifier(PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler) { - this.polarisRestTemplateResponseErrorHandler = polarisRestTemplateResponseErrorHandler; + public EnhancedRestTemplateModifier(EnhancedRestTemplateReporter enhancedRestTemplateReporter) { + this.enhancedRestTemplateReporter = enhancedRestTemplateReporter; } @Override @@ -54,7 +54,7 @@ public class PolarisRestTemplateModifier implements ApplicationContextAware, Sma private void initRestTemplate(String beanName, Object bean) { if (bean instanceof RestTemplate) { RestTemplate restTemplate = (RestTemplate) bean; - restTemplate.setErrorHandler(polarisRestTemplateResponseErrorHandler); + restTemplate.setErrorHandler(enhancedRestTemplateReporter); } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java similarity index 89% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java index dd9a83d8..972e85e1 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.resttemplate; +package com.tencent.cloud.rpc.enhancement.resttemplate; import java.io.IOException; import java.net.HttpURLConnection; @@ -43,9 +43,9 @@ import org.springframework.web.client.ResponseErrorHandler; * * @author wh 2022/6/21 */ -public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHandler { +public class EnhancedRestTemplateReporter implements ResponseErrorHandler { - private static final Logger LOG = LoggerFactory.getLogger(PolarisRestTemplateResponseErrorHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(EnhancedRestTemplateReporter.class); private static final String FILE_NAME = "connection"; @@ -53,7 +53,7 @@ public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHan private final PolarisResponseErrorHandler polarisResponseErrorHandler; - public PolarisRestTemplateResponseErrorHandler( + public EnhancedRestTemplateReporter( ConsumerAPI consumerAPI, PolarisResponseErrorHandler polarisResponseErrorHandler) { this.consumerAPI = consumerAPI; this.polarisResponseErrorHandler = polarisResponseErrorHandler; @@ -91,9 +91,12 @@ public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHan } catch (Exception e) { LOG.error("Will report response of {} url {}", response, url, e); + resultRequest.setRetStatus(RetStatus.RetFail); throw e; } finally { + LOG.debug("Will report result of {}. URL=[{}]. Response=[{}].", resultRequest.getRetStatus().name(), + url, response); consumerAPI.updateServiceCallResult(resultRequest); } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisResponseErrorHandler.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisResponseErrorHandler.java similarity index 94% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisResponseErrorHandler.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisResponseErrorHandler.java index 3c690b1c..fa49521e 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisResponseErrorHandler.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisResponseErrorHandler.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.resttemplate; +package com.tencent.cloud.rpc.enhancement.resttemplate; import org.springframework.web.client.ResponseErrorHandler; diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatProperties.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatProperties.java new file mode 100644 index 00000000..b8b91820 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatProperties.java @@ -0,0 +1,82 @@ +/* + * 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.stat.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * The properties for stat reporter. + * + * @author Haotian Zhang + */ +@ConfigurationProperties("spring.cloud.polaris.stat") +public class PolarisStatProperties { + + /** + * If state reporter enabled. + */ + private boolean enabled = false; + + /** + * Local host for prometheus to pull. + */ + private String host; + + /** + * Port for prometheus to pull. + */ + private int port = 28080; + + /** + * Path for prometheus to pull. + */ + private String path = "/metrics"; + + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesAutoConfiguration.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesAutoConfiguration.java new file mode 100644 index 00000000..d21c21fb --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesAutoConfiguration.java @@ -0,0 +1,43 @@ +/* + * 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.stat.config; + +import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.core.env.Environment; + +/** + * Autoconfiguration of stat reporter. + * + * @author Haotian Zhang + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnPolarisEnabled +@Import({PolarisStatProperties.class}) +public class PolarisStatPropertiesAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public StatConfigModifier statReporterConfigModifier(PolarisStatProperties polarisStatProperties, Environment environment) { + return new StatConfigModifier(polarisStatProperties, environment); + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesBootstrapConfiguration.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesBootstrapConfiguration.java new file mode 100644 index 00000000..d71d9bce --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesBootstrapConfiguration.java @@ -0,0 +1,34 @@ +/* + * 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.stat.config; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +/** + * Autoconfiguration of stat reporter at bootstrap phase. + * + * @author lepdou 2022-03-29 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnProperty("spring.cloud.polaris.enabled") +@Import(PolarisStatPropertiesAutoConfiguration.class) +public class PolarisStatPropertiesBootstrapConfiguration { + +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifier.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifier.java new file mode 100644 index 00000000..6306f68d --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifier.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.stat.config; + +import com.tencent.cloud.common.constant.ContextConstant; +import com.tencent.cloud.polaris.context.PolarisConfigModifier; +import com.tencent.polaris.factory.config.ConfigurationImpl; +import com.tencent.polaris.plugins.stat.prometheus.handler.PrometheusHandlerConfig; + +import org.springframework.core.env.Environment; +import org.springframework.util.StringUtils; + +import static com.tencent.polaris.api.config.global.StatReporterConfig.DEFAULT_REPORTER_PROMETHEUS; + +/** + * Config modifier for stat reporter. + * + * @author Haotian Zhang + */ +public class StatConfigModifier implements PolarisConfigModifier { + + private final PolarisStatProperties polarisStatProperties; + + private final Environment environment; + + public StatConfigModifier(PolarisStatProperties polarisStatProperties, Environment environment) { + this.polarisStatProperties = polarisStatProperties; + this.environment = environment; + } + + @Override + public void modify(ConfigurationImpl configuration) { + // Turn on stat reporter configuration. + configuration.getGlobal().getStatReporter().setEnable(polarisStatProperties.isEnabled()); + + // Set prometheus plugin. + if (polarisStatProperties.isEnabled()) { + PrometheusHandlerConfig prometheusHandlerConfig = configuration.getGlobal().getStatReporter() + .getPluginConfig(DEFAULT_REPORTER_PROMETHEUS, PrometheusHandlerConfig.class); + if (!StringUtils.hasText(polarisStatProperties.getHost())) { + polarisStatProperties.setHost(environment.getProperty("spring.cloud.client.ip-address")); + } + prometheusHandlerConfig.setHost(polarisStatProperties.getHost()); + prometheusHandlerConfig.setPort(polarisStatProperties.getPort()); + prometheusHandlerConfig.setPath(polarisStatProperties.getPath()); + configuration.getGlobal().getStatReporter() + .setPluginConfig(DEFAULT_REPORTER_PROMETHEUS, prometheusHandlerConfig); + } + } + + @Override + public int getOrder() { + return ContextConstant.ModifierOrder.STAT_REPORTER_ORDER; + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 00000000..77baec1e --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,27 @@ +{ + "properties": [ + { + "name": "spring.cloud.polaris.stat.enabled", + "type": "java.lang.Boolean", + "defaultValue": false, + "description": "Enable polaris stat reporter or not." + }, + { + "name": "spring.cloud.polaris.stat.host", + "type": "java.lang.String", + "description": "Local host for prometheus to pull." + }, + { + "name": "spring.cloud.polaris.stat.port", + "type": "java.lang.Integer", + "defaultValue": "28080", + "description": "Port for prometheus to pull." + }, + { + "name": "spring.cloud.polaris.stat.path", + "type": "java.lang.String", + "defaultValue": "/metrics", + "description": "Path for prometheus to pull." + } + ] +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..990b7500 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/spring.factories @@ -0,0 +1,5 @@ +org.springframework.cloud.bootstrap.BootstrapConfiguration=\ + com.tencent.cloud.rpc.enhancement.stat.config.PolarisStatPropertiesBootstrapConfiguration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration,\ + com.tencent.cloud.rpc.enhancement.stat.config.PolarisStatPropertiesAutoConfiguration diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java similarity index 54% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java index b0b1e76e..fd5afc18 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java @@ -13,19 +13,20 @@ * 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; +package com.tencent.cloud.rpc.enhancement.config; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisRestTemplateModifier; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisRestTemplateResponseErrorHandler; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; +import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignBeanPostProcessor; +import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.ExceptionPolarisReporter; +import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.SuccessPolarisReporter; +import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateModifier; +import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateReporter; +import com.tencent.polaris.api.core.ConsumerAPI; import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.annotation.Bean; @@ -35,32 +36,33 @@ import org.springframework.web.client.RestTemplate; import static org.assertj.core.api.Assertions.assertThat; /** - * Test For {@link PolarisCircuitBreakerAutoConfiguration} . + * Test For {@link RpcEnhancementAutoConfiguration}. * - * @author Palmer Xu 2022-06-28 + * @author Haotian Zhang, wh, Palmer Xu */ -public class PolarisRestTemplateAutoConfigurationTest { +public class RpcEnhancementAutoConfigurationTest { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - PolarisRestTemplateAutoConfigurationTester.class, - PolarisContextAutoConfiguration.class, - PolarisCircuitBreakerAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + RpcEnhancementAutoConfiguration.class, + PolarisRestTemplateAutoConfigurationTester.class)) .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true"); @Test - public void testInitialization() { - this.contextRunner - .run(context -> { - assertThat(context).hasSingleBean(PolarisRestTemplateModifier.class); - assertThat(context).hasSingleBean(PolarisRestTemplateResponseErrorHandler.class); - }); + public void testDefaultInitialization() { + this.contextRunner.run(context -> { + assertThat(context).hasSingleBean(ConsumerAPI.class); + assertThat(context).hasSingleBean(EnhancedFeignBeanPostProcessor.class); + assertThat(context).hasSingleBean(SuccessPolarisReporter.class); + assertThat(context).hasSingleBean(ExceptionPolarisReporter.class); + assertThat(context).hasSingleBean(EnhancedRestTemplateModifier.class); + assertThat(context).hasSingleBean(EnhancedRestTemplateReporter.class); + }); } @Configuration @EnableAutoConfiguration - @AutoConfigureBefore(PolarisCircuitBreakerAutoConfiguration.class) static class PolarisRestTemplateAutoConfigurationTester { @Bean diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessorTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessorTest.java similarity index 67% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessorTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessorTest.java index 4107fd17..b22b7c18 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessorTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessorTest.java @@ -15,9 +15,8 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.feign; +package com.tencent.cloud.rpc.enhancement.feign; -import com.tencent.polaris.api.core.ConsumerAPI; import feign.Client; import org.junit.Before; import org.junit.Test; @@ -35,19 +34,17 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; /** - * Test for {@link PolarisFeignBeanPostProcessor}. + * Test for {@link EnhancedFeignBeanPostProcessor}. * * @author Haotian Zhang */ -public class PolarisFeignBeanPostProcessorTest { +public class EnhancedFeignBeanPostProcessorTest { - private PolarisFeignBeanPostProcessor polarisFeignBeanPostProcessor; + private EnhancedFeignBeanPostProcessor enhancedFeignBeanPostProcessor; @Before public void setUp() { - ConsumerAPI consumerAPI = mock(ConsumerAPI.class); - - polarisFeignBeanPostProcessor = new PolarisFeignBeanPostProcessor(consumerAPI); + enhancedFeignBeanPostProcessor = new EnhancedFeignBeanPostProcessor(null); } @Test @@ -66,22 +63,24 @@ public class PolarisFeignBeanPostProcessorTest { } return null; }).when(beanFactory).getBean(any(Class.class)); - polarisFeignBeanPostProcessor.setBeanFactory(beanFactory); + enhancedFeignBeanPostProcessor.setBeanFactory(beanFactory); // isNeedWrap(bean) == false Object bean1 = new Object(); - Object bean = polarisFeignBeanPostProcessor.postProcessBeforeInitialization(bean1, "bean1"); - assertThat(bean).isNotInstanceOfAny(PolarisFeignClient.class, PolarisFeignBlockingLoadBalancerClient.class); + Object bean = enhancedFeignBeanPostProcessor.postProcessBeforeInitialization(bean1, "bean1"); + assertThat(bean).isNotInstanceOfAny( + EnhancedFeignClient.class, + EnhancedFeignBlockingLoadBalancerClient.class); // bean instanceOf Client.class Client bean2 = mock(Client.class); - bean = polarisFeignBeanPostProcessor.postProcessBeforeInitialization(bean2, "bean2"); - assertThat(bean).isInstanceOf(PolarisFeignClient.class); + bean = enhancedFeignBeanPostProcessor.postProcessBeforeInitialization(bean2, "bean2"); + assertThat(bean).isInstanceOf(EnhancedFeignClient.class); // bean instanceOf FeignBlockingLoadBalancerClient.class - FeignBlockingLoadBalancerClient bean3 = mock(FeignBlockingLoadBalancerClient.class); - doReturn(mock(Client.class)).when(bean3).getDelegate(); - bean = polarisFeignBeanPostProcessor.postProcessBeforeInitialization(bean3, "bean3"); - assertThat(bean).isInstanceOf(PolarisFeignBlockingLoadBalancerClient.class); + FeignBlockingLoadBalancerClient bean4 = mock(FeignBlockingLoadBalancerClient.class); + doReturn(mock(Client.class)).when(bean4).getDelegate(); + bean = enhancedFeignBeanPostProcessor.postProcessBeforeInitialization(bean4, "bean4"); + assertThat(bean).isInstanceOf(EnhancedFeignBlockingLoadBalancerClient.class); } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClientTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBlockingLoadBalancerClientTest.java similarity index 80% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClientTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBlockingLoadBalancerClientTest.java index 315cf89f..94cc730d 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClientTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBlockingLoadBalancerClientTest.java @@ -15,22 +15,22 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.feign; +package com.tencent.cloud.rpc.enhancement.feign; import org.assertj.core.api.Assertions; import org.junit.Test; /** - * Test for {@link PolarisFeignBlockingLoadBalancerClient}. + * Test for {@link EnhancedFeignBlockingLoadBalancerClient}. * * @author Haotian Zhang */ -public class PolarisFeignBlockingLoadBalancerClientTest { +public class EnhancedFeignBlockingLoadBalancerClientTest { @Test public void testConstructor() { try { - new PolarisFeignBlockingLoadBalancerClient(null, null, null); + new EnhancedFeignBlockingLoadBalancerClient(null, null, null); } catch (Exception e) { Assertions.fail("Exception encountered.", e); diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java similarity index 58% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java index a3228f77..6f8067be 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java @@ -15,13 +15,16 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.feign; +package com.tencent.cloud.rpc.enhancement.feign; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import com.google.common.collect.Maps; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.rpc.ServiceCallResult; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; import feign.Client; import feign.Request; import feign.RequestTemplate; @@ -39,23 +42,22 @@ import static org.assertj.core.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; /** - * Test for {@link PolarisFeignClient}. + * Test for {@link EnhancedFeignClient}. * * @author Haotian Zhang */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = PolarisFeignClientTest.TestApplication.class, +@SpringBootTest(classes = EnhancedFeignClientTest.TestApplication.class, properties = {"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp"}) -public class PolarisFeignClientTest { +public class EnhancedFeignClientTest { @Test public void testConstructor() { try { - new PolarisFeignClient(null, null); + new EnhancedFeignClient(null, null); fail("NullPointerException should be thrown."); } catch (Throwable e) { @@ -64,16 +66,15 @@ public class PolarisFeignClientTest { } try { - new PolarisFeignClient(mock(Client.class), null); - fail("NullPointerException should be thrown."); + new EnhancedFeignClient(mock(Client.class), null); } catch (Throwable e) { - assertThat(e).isInstanceOf(NullPointerException.class); - assertThat(e.getMessage()).isEqualTo("CircuitBreakAPI"); + fail("Exception encountered.", e); } + List enhancedFeignPlugins = getMockEnhancedFeignPlugins(); try { - assertThat(new PolarisFeignClient(mock(Client.class), mock(ConsumerAPI.class))).isInstanceOf(PolarisFeignClient.class); + new EnhancedFeignClient(mock(Client.class), enhancedFeignPlugins); } catch (Throwable e) { fail("Exception encountered.", e); @@ -95,10 +96,6 @@ public class PolarisFeignClientTest { throw new IOException("Mock exception."); }).when(delegate).execute(any(Request.class), nullable(Request.Options.class)); - // mock ConsumerAPI.class - ConsumerAPI consumerAPI = mock(ConsumerAPI.class); - doNothing().when(consumerAPI).updateServiceCallResult(any(ServiceCallResult.class)); - // mock target Target target = Target.EmptyTarget.create(Object.class); @@ -106,7 +103,7 @@ public class PolarisFeignClientTest { RequestTemplate requestTemplate = new RequestTemplate(); requestTemplate.feignTarget(target); - PolarisFeignClient polarisFeignClient = new PolarisFeignClient(delegate, consumerAPI); + EnhancedFeignClient polarisFeignClient = new EnhancedFeignClient(delegate, getMockEnhancedFeignPlugins()); // 200 Response response = polarisFeignClient.execute(Request.create(Request.HttpMethod.GET, "http://localhost:8080/test", @@ -130,6 +127,101 @@ public class PolarisFeignClientTest { } } + private List getMockEnhancedFeignPlugins() { + List enhancedFeignPlugins = new ArrayList<>(); + + enhancedFeignPlugins.add(new EnhancedFeignPlugin() { + @Override + public EnhancedFeignPluginType getType() { + return EnhancedFeignPluginType.PRE; + } + + @Override + public void run(EnhancedFeignContext context) { + + } + + @Override + public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + + } + + @Override + public int getOrder() { + return 0; + } + }); + + enhancedFeignPlugins.add(new EnhancedFeignPlugin() { + @Override + public EnhancedFeignPluginType getType() { + return EnhancedFeignPluginType.POST; + } + + @Override + public void run(EnhancedFeignContext context) { + + } + + @Override + public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + + } + + @Override + public int getOrder() { + return 0; + } + }); + + enhancedFeignPlugins.add(new EnhancedFeignPlugin() { + @Override + public EnhancedFeignPluginType getType() { + return EnhancedFeignPluginType.EXCEPTION; + } + + @Override + public void run(EnhancedFeignContext context) { + + } + + @Override + public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + + } + + @Override + public int getOrder() { + return 0; + } + }); + + enhancedFeignPlugins.add(new EnhancedFeignPlugin() { + @Override + public EnhancedFeignPluginType getType() { + return EnhancedFeignPluginType.FINALLY; + } + + @Override + public void run(EnhancedFeignContext context) { + + } + + @Override + public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + + } + + @Override + public int getOrder() { + return 0; + } + }); + + return enhancedFeignPlugins; + + } + @SpringBootApplication protected static class TestApplication { diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContextTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContextTest.java new file mode 100644 index 00000000..0d3078a6 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContextTest.java @@ -0,0 +1,46 @@ +/* + * 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.feign.plugin; + +import feign.Request; +import feign.Response; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Test for {@link EnhancedFeignContext}. + * + * @author Haotian Zhang + */ +public class EnhancedFeignContextTest { + + @Test + public void testGetAndSet() { + EnhancedFeignContext enhancedFeignContext = new EnhancedFeignContext(); + enhancedFeignContext.setRequest(mock(Request.class)); + enhancedFeignContext.setOptions(mock(Request.Options.class)); + enhancedFeignContext.setResponse(mock(Response.class)); + enhancedFeignContext.setException(mock(Exception.class)); + assertThat(enhancedFeignContext.getRequest()).isNotNull(); + assertThat(enhancedFeignContext.getOptions()).isNotNull(); + assertThat(enhancedFeignContext.getResponse()).isNotNull(); + assertThat(enhancedFeignContext.getException()).isNotNull(); + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java new file mode 100644 index 00000000..d47c7f2c --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java @@ -0,0 +1,101 @@ +/* + * 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.feign.plugin.reporter; + +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.api.pojo.RetStatus; +import feign.Request; +import feign.Response; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; + +/** + * Test for {@link ExceptionPolarisReporter}. + * + * @author Haotian Zhang + */ +@RunWith(MockitoJUnitRunner.class) +public class ExceptionPolarisReporterTest { + + private static MockedStatic mockedReporterUtils; + @Mock + private ConsumerAPI consumerAPI; + @InjectMocks + private ExceptionPolarisReporter exceptionPolarisReporter; + + @BeforeClass + public static void beforeClass() { + mockedReporterUtils = Mockito.mockStatic(ReporterUtils.class); + mockedReporterUtils.when(() -> ReporterUtils.createServiceCallResult(any(Request.class), any(RetStatus.class))) + .thenReturn(null); + } + + @AfterClass + public static void afterClass() { + mockedReporterUtils.close(); + } + + @Test + public void testGetName() { + assertThat(exceptionPolarisReporter.getName()).isEqualTo(ExceptionPolarisReporter.class.getName()); + } + + @Test + public void testType() { + assertThat(exceptionPolarisReporter.getType()).isEqualTo(EnhancedFeignPluginType.EXCEPTION); + } + + @Test + public void testRun() { + // mock request + Request request = mock(Request.class); + // mock response + Response response = mock(Response.class); + + EnhancedFeignContext context = new EnhancedFeignContext(); + context.setRequest(request); + context.setResponse(response); + exceptionPolarisReporter.run(context); + } + + @Test + public void testHandlerThrowable() { + // mock request + Request request = mock(Request.class); + // mock response + Response response = mock(Response.class); + + EnhancedFeignContext context = new EnhancedFeignContext(); + context.setRequest(request); + context.setResponse(response); + exceptionPolarisReporter.handlerThrowable(context, new RuntimeException("Mock exception.")); + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtilsTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtilsTest.java new file mode 100644 index 00000000..de60c99b --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtilsTest.java @@ -0,0 +1,96 @@ +/* + * 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.feign.plugin.reporter; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.polaris.api.pojo.RetStatus; +import com.tencent.polaris.api.rpc.ServiceCallResult; +import feign.Request; +import feign.RequestTemplate; +import feign.Target; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +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; + +/** + * Test for {@link ReporterUtils}. + * + * @author Haotian Zhang + */ +@RunWith(MockitoJUnitRunner.class) +public class ReporterUtilsTest { + + private static MockedStatic mockedApplicationContextAwareUtils; + + @BeforeClass + public static void beforeClass() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("unit-test"); + } + + @AfterClass + public static void afterClass() { + mockedApplicationContextAwareUtils.close(); + } + + @Before + public void setUp() { + MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; + MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; + } + + @Test + public void testCreateServiceCallResult() { + // mock target + Target target = mock(Target.class); + doReturn(SERVICE_PROVIDER).when(target).name(); + + // mock RequestTemplate.class + RequestTemplate requestTemplate = new RequestTemplate(); + requestTemplate.feignTarget(target); + + // mock request + Request request = mock(Request.class); + doReturn(requestTemplate).when(request).requestTemplate(); + doReturn("http://1.1.1.1:2345/path").when(request).url(); + + ServiceCallResult serviceCallResult = ReporterUtils.createServiceCallResult(request, RetStatus.RetSuccess); + assertThat(serviceCallResult.getNamespace()).isEqualTo(NAMESPACE_TEST); + assertThat(serviceCallResult.getService()).isEqualTo(SERVICE_PROVIDER); + assertThat(serviceCallResult.getHost()).isEqualTo("1.1.1.1"); + assertThat(serviceCallResult.getPort()).isEqualTo(2345); + assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetSuccess); + assertThat(serviceCallResult.getMethod()).isEqualTo("/path"); + assertThat(serviceCallResult.getCallerService().getNamespace()).isEqualTo(NAMESPACE_TEST); + assertThat(serviceCallResult.getCallerService().getService()).isEqualTo(SERVICE_PROVIDER); + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java new file mode 100644 index 00000000..cdcc594f --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java @@ -0,0 +1,103 @@ +/* + * 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.feign.plugin.reporter; + +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; +import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.api.pojo.RetStatus; +import feign.Request; +import feign.Response; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +/** + * Test for {@link SuccessPolarisReporter}. + * + * @author Haotian Zhang + */ +@RunWith(MockitoJUnitRunner.class) +public class SuccessPolarisReporterTest { + + private static MockedStatic mockedReporterUtils; + @Mock + private ConsumerAPI consumerAPI; + @InjectMocks + private SuccessPolarisReporter successPolarisReporter; + + @BeforeClass + public static void beforeClass() { + mockedReporterUtils = Mockito.mockStatic(ReporterUtils.class); + mockedReporterUtils.when(() -> ReporterUtils.createServiceCallResult(any(Request.class), any(RetStatus.class))) + .thenReturn(null); + } + + @AfterClass + public static void afterClass() { + mockedReporterUtils.close(); + } + + @Test + public void testGetName() { + assertThat(successPolarisReporter.getName()).isEqualTo(SuccessPolarisReporter.class.getName()); + } + + @Test + public void testType() { + assertThat(successPolarisReporter.getType()).isEqualTo(EnhancedFeignPluginType.POST); + } + + @Test + public void testRun() { + // mock request + Request request = mock(Request.class); + // mock response + Response response = mock(Response.class); + doReturn(502).when(response).status(); + + EnhancedFeignContext context = new EnhancedFeignContext(); + context.setRequest(request); + context.setResponse(response); + successPolarisReporter.run(context); + } + + @Test + public void testHandlerThrowable() { + // mock request + Request request = mock(Request.class); + // mock response + Response response = mock(Response.class); + + EnhancedFeignContext context = new EnhancedFeignContext(); + context.setRequest(request); + context.setResponse(response); + successPolarisReporter.handlerThrowable(context, new RuntimeException("Mock exception.")); + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandlerTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java similarity index 80% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandlerTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java index 6cb630e3..53e7ef65 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandlerTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.resttemplate; +package com.tencent.cloud.rpc.enhancement.resttemplate; import java.net.HttpURLConnection; @@ -35,19 +35,19 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** - * Test For {@link PolarisRestTemplateResponseErrorHandler}. + * Test For {@link EnhancedRestTemplateReporter}. * * @author wh 2022/6/22 */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = PolarisRestTemplateResponseErrorHandlerTest.TestApplication.class, +@SpringBootTest(classes = EnhancedRestTemplateReporterTest.TestApplication.class, properties = {"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp"}) -public class PolarisRestTemplateResponseErrorHandlerTest { +public class EnhancedRestTemplateReporterTest { @Test public void handleError() throws Exception { ConsumerAPI consumerAPI = mock(ConsumerAPI.class); - PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler = new PolarisRestTemplateResponseErrorHandler(consumerAPI, null); + EnhancedRestTemplateReporter enhancedRestTemplateReporter = new EnhancedRestTemplateReporter(consumerAPI, null); URI uri = mock(URI.class); when(uri.getPath()).thenReturn("/test"); when(uri.getHost()).thenReturn("host"); @@ -58,7 +58,7 @@ public class PolarisRestTemplateResponseErrorHandlerTest { when(url.getPort()).thenReturn(8080); when(httpURLConnection.getResponseCode()).thenReturn(200); SimpleClientHttpResponseTest clientHttpResponse = new SimpleClientHttpResponseTest(httpURLConnection); - polarisRestTemplateResponseErrorHandler.handleError(uri, HttpMethod.GET, clientHttpResponse); + enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, clientHttpResponse); when(consumerAPI.unWatchService(null)).thenReturn(true); } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/SimpleClientHttpResponseTest.java similarity index 97% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/SimpleClientHttpResponseTest.java index d8ac018c..0899da7a 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/SimpleClientHttpResponseTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.resttemplate; +package com.tencent.cloud.rpc.enhancement.resttemplate; import java.io.IOException; import java.io.InputStream; diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesAutoConfigurationTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesAutoConfigurationTest.java new file mode 100644 index 00000000..c6c2ed13 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesAutoConfigurationTest.java @@ -0,0 +1,45 @@ +/* + * 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.stat.config; + +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link PolarisStatPropertiesAutoConfiguration}. + * + * @author Haotian Zhang + */ +public class PolarisStatPropertiesAutoConfigurationTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisStatPropertiesAutoConfiguration.class)); + + @Test + public void testDefaultInitialization() { + this.contextRunner.run(context -> { + assertThat(context).hasSingleBean(PolarisStatPropertiesAutoConfiguration.class); + assertThat(context).hasSingleBean(PolarisStatProperties.class); + assertThat(context).hasSingleBean(StatConfigModifier.class); + }); + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesBootstrapConfigurationTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesBootstrapConfigurationTest.java new file mode 100644 index 00000000..acb8420d --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesBootstrapConfigurationTest.java @@ -0,0 +1,47 @@ +/* + * 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.stat.config; + +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link PolarisStatPropertiesBootstrapConfiguration}. + * + * @author Haotian Zhang + */ +public class PolarisStatPropertiesBootstrapConfigurationTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisStatPropertiesBootstrapConfiguration.class)) + .withPropertyValues("spring.cloud.polaris.enabled=true"); + + @Test + public void testDefaultInitialization() { + this.contextRunner.run(context -> { + assertThat(context).hasSingleBean(PolarisStatPropertiesBootstrapConfiguration.class); + assertThat(context).hasSingleBean(PolarisStatPropertiesAutoConfiguration.class); + assertThat(context).hasSingleBean(PolarisStatProperties.class); + assertThat(context).hasSingleBean(StatConfigModifier.class); + }); + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesTest.java new file mode 100644 index 00000000..9adc4f65 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesTest.java @@ -0,0 +1,57 @@ +/* + * 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.stat.config; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link PolarisStatProperties}. + * + * @author Haotian Zhang + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = PolarisStatPropertiesTest.TestApplication.class) +@ActiveProfiles("test") +public class PolarisStatPropertiesTest { + + @Autowired + private PolarisStatProperties polarisStatProperties; + + @Test + public void testDefaultInitialization() { + assertThat(polarisStatProperties).isNotNull(); + assertThat(polarisStatProperties.isEnabled()).isTrue(); + assertThat(polarisStatProperties.getHost()).isNotBlank(); + assertThat(polarisStatProperties.getPort()).isEqualTo(20000); + assertThat(polarisStatProperties.getPath()).isEqualTo("/xxx"); + } + + @SpringBootApplication + protected static class TestApplication { + + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/resources/application-test.properties b/spring-cloud-tencent-rpc-enhancement/src/test/resources/application-test.properties new file mode 100644 index 00000000..96d94d0d --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/resources/application-test.properties @@ -0,0 +1,3 @@ +spring.cloud.polaris.stat.enabled=true +spring.cloud.polaris.stat.port=20000 +spring.cloud.polaris.stat.path=/xxx