diff --git a/CHANGELOG.md b/CHANGELOG.md index 44c0b887..4a2e0a51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ - [Bugfix: optimize ratelimit actuator](https://github.com/Tencent/spring-cloud-tencent/pull/413) - [Feature: add rate limit filter debug log](https://github.com/Tencent/spring-cloud-tencent/pull/417) - [Feature: Optimized configuration update](https://github.com/Tencent/spring-cloud-tencent/pull/423) +- [[Optimize] improve load-balance ut and support configurable heartbeat interval](https://github.com/Tencent/spring-cloud-tencent/pull/427) - [Feature: add feature-env plugin & add spring cloud gateway staining plugin](https://github.com/Tencent/spring-cloud-tencent/pull/428) - [Optimize: add EncodeTransferMedataRestTemplateInterceptor to RestTemplate](https://github.com/Tencent/spring-cloud-tencent/pull/434) +- [feat:enhance Feign and RestTemplate and support Polaris monitor.](https://github.com/Tencent/spring-cloud-tencent/pull/435) - [Optimize: Specification apollo code reference notes](https://github.com/Tencent/spring-cloud-tencent/pull/442) diff --git a/README-zh.md b/README-zh.md index f2987928..55f701ab 100644 --- a/README-zh.md +++ b/README-zh.md @@ -7,7 +7,7 @@ [![Contributors](https://img.shields.io/github/contributors/Tencent/spring-cloud-tencent)](https://github.com/Tencent/spring-cloud-tencent/graphs/contributors) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) -[English](./README.md) | 简体中文 +[English](./README.md) | 简体中文 --- @@ -29,20 +29,23 @@ Spring Cloud Tencent提供的能力包括但不限于: - 服务注册和发现 - 动态配置管理 - 服务治理 - - 服务限流 - - 服务熔断 - - 服务路由 - - ... + - 服务限流 + - 服务熔断 + - 服务路由 + - ... - 标签透传 ## 体验环境 - 管控台地址: http://14.116.241.63:8080/ - - 账号:polaris - - 密码:polaris + - 账号:polaris + - 密码:polaris - 控制面地址: `grpc://183.47.111.80:8091` -- - `spring-cloud-tencent-example` 下 example 地址都默认指向了体验服务地址(`grpc://183.47.111.80:8091`),如果您只是体验 Spring Cloud Tencent,可直接一键运行任何 example。 +- + +`spring-cloud-tencent-example` 下 example 地址都默认指向了体验服务地址(`grpc://183.47.111.80:8091`),如果您只是体验 Spring Cloud +Tencent,可直接一键运行任何 example。 + ## 管控台 image @@ -51,6 +54,10 @@ Spring Cloud Tencent提供的能力包括但不限于: 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 @@ -88,8 +95,8 @@ Spring Cloud Tencent 所有组件都已上传到 Maven 中央仓库,只需要 - [Spring Cloud Tencent 标签传递](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97) - ### 开发文档 - - [项目概览](https://github.com/Tencent/spring-cloud-tencent/wiki/%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88) - - [参与共建](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%8F%82%E4%B8%8E%E5%85%B1%E5%BB%BA) + - [项目概览](https://github.com/Tencent/spring-cloud-tencent/wiki/%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88) + - [参与共建](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%8F%82%E4%B8%8E%E5%85%B1%E5%BB%BA) ## 交流群 @@ -97,9 +104,10 @@ Spring Cloud Tencent 所有组件都已上传到 Maven 中央仓库,只需要 - ## License -The spring-cloud-tencent is licensed under the BSD 3-Clause License. Copyright and license information can be found in the file [LICENSE](LICENSE) + +The spring-cloud-tencent is licensed under the BSD 3-Clause License. Copyright and license information can be found in +the file [LICENSE](LICENSE) ## Stargazers over time diff --git a/README.md b/README.md index 2c2965a5..ef855dc9 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,11 @@ English | [简体中文](./README-zh.md) Spring Cloud Tencent is a open source one-stop microservice solution from Tencent. -Spring Cloud Tencent implements the Spring Cloud standard microservice SPI, so developers can quickly develop Spring Cloud cloud-native distributed applications based on Spring Cloud Tencent. +Spring Cloud Tencent implements the Spring Cloud standard microservice SPI, so developers can quickly develop Spring +Cloud cloud-native distributed applications based on Spring Cloud Tencent. -The core of Spring Cloud Tencent relies on Tencent's open-source one-stop service discovery and governance platform [Polaris](https://github.com/polarismesh/polaris) to realize various distributed microservice scenarios. +The core of Spring Cloud Tencent relies on Tencent's open-source one-stop service discovery and governance +platform [Polaris](https://github.com/polarismesh/polaris) to realize various distributed microservice scenarios. - [Polaris Github home page](https://github.com/polarismesh/polaris) - [Polaris official website](https://polarismesh.cn/) @@ -28,21 +30,22 @@ The capabilities provided by Spring Cloud Tencent include but are not limited to - Service registration and discovery - Dynamic configuration management - Service Governance - - Service rate limit - - Service circuit breaker - - Service routing - - ... + - Service rate limit + - Service circuit breaker + - Service routing + - ... - Label transparent transmission ## Demo Environment - Console Address : http://14.116.241.63:8080/ - - Username: polaris - - Password: polaris + - Username: polaris + - Password: polaris - Server Address: `grpc://183.47.111.80:8091` -The example addresses under `spring-cloud-tencent-example` all point to the experience service address (`grpc://183.47.111.80:8091`) by default. -If you only experience Spring Cloud Tencent, you can run any example directly with one click. +The example addresses under `spring-cloud-tencent-example` all point to the experience service +address (`grpc://183.47.111.80:8091`) by default. If you only experience Spring Cloud Tencent, you can run any example +directly with one click. ## Screenshots @@ -50,7 +53,12 @@ If you only experience Spring Cloud Tencent, you can run any example directly wi ## Use Guide -All the components of Spring Cloud Tencent have been uploaded to the Maven central repository, just need to introduce dependencies. +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: @@ -79,7 +87,7 @@ For example: ```` - - ### Quick Start +- ### Quick Start - [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) - [Spring Cloud Tencent Discovery](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Discovery-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - [Spring Cloud Tencent Config](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Config-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) @@ -89,9 +97,9 @@ For example: - [Spring Cloud Tencent Metadata Transfer](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97) - ### Development Documentation - - [Project Structure Overview](https://github.com/Tencent/spring-cloud-tencent/wiki/%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88) - - [Participate in co-construction](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%8F%82%E4%B8%8E%E5%85%B1%E5%BB%BA) - + - [Project Structure Overview](https://github.com/Tencent/spring-cloud-tencent/wiki/%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88) + - [Participate in co-construction](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%8F%82%E4%B8%8E%E5%85%B1%E5%BB%BA) + ## Chat Group Please scan the QR code to join the chat group. @@ -99,8 +107,9 @@ Please scan the QR code to join the chat group. ## License -The spring-cloud-tencent is licensed under the BSD 3-Clause License. Copyright and license information can be found in the file [LICENSE](LICENSE) +The spring-cloud-tencent is licensed under the BSD 3-Clause License. Copyright and license information can be found in +the file [LICENSE](LICENSE) ## Stargazers over time diff --git a/changes/changes-1.6.0.md b/changes/changes-1.6.0.md index 24de5fce..81941578 100644 --- a/changes/changes-1.6.0.md +++ b/changes/changes-1.6.0.md @@ -39,4 +39,4 @@ - [docs:optimize example](https://github.com/Tencent/spring-cloud-tencent/pull/385) - [Optimize starters auto-configuration. (main)](https://github.com/Tencent/spring-cloud-tencent/pull/391/files) - [Feature: format code](https://github.com/Tencent/spring-cloud-tencent/pull/394) -- [test: add PostInitPolarisSDKContextTest](https://github.com/Tencent/spring-cloud-tencent/pull/397) \ No newline at end of file +- [test: add PostInitPolarisSDKContextTest](https://github.com/Tencent/spring-cloud-tencent/pull/397) diff --git a/pom.xml b/pom.xml index 0839b719..30d94f42 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 80bb8a22..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,40 +61,10 @@ - - org.springframework.cloud - spring-cloud-loadbalancer - true - - - - org.springframework.cloud - spring-cloud-starter-openfeign - true - - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - test - - - - 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 0fef7fec..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,5 +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 81% 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 e29c4a76..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; @@ -31,15 +30,16 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Haotian Zhang */ public class PolarisCircuitBreakerBootstrapConfigurationTest { - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .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); + 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 ac077bb7..8c41eb25 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 be1ae8d6..4f8f06bc 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 @@ -21,11 +21,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; @@ -42,18 +37,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 1424f98b..c152dc93 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 077ee0c3..bdbe9ce6 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 @@ -73,26 +78,26 @@ com.tencent.cloud spring-cloud-tencent-gateway-plugin - + - - - - 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 02bbd20f..faa4ac31 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -108,6 +108,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 0a36a8df..b063ad07 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 feign: hystrix: enabled: true 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 544193b7..d0f01ffa 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 @@ -15,6 +15,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 @@ -37,4 +40,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 6d7fda24..a1be890e 100644 --- a/spring-cloud-tencent-polaris-context/pom.xml +++ b/spring-cloud-tencent-polaris-context/pom.xml @@ -22,6 +22,41 @@ + + 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.polaris polaris-client 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 51ba3eb6..97722fb0 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 @@ -21,8 +21,11 @@ package com.tencent.cloud.polaris.context.config; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.context.ModifyAddress; 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; @@ -46,6 +49,18 @@ public class PolarisContextAutoConfiguration { return SDKContext.initContextByConfig(properties.configuration()); } + @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..e311cbff --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/pom.xml @@ -0,0 +1,74 @@ + + + + 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-loadbalancer + true + + + + org.springframework.cloud + spring-cloud-starter-openfeign + true + + + + com.tencent.polaris + polaris-test-common + test + + + + org.springframework.cloud + spring-cloud-starter-netflix-ribbon + 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..220d7691 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java @@ -0,0 +1,109 @@ +/* + * 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.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) { + return new EnhancedRestTemplateReporter(consumerAPI); + } + + @Bean + public EnhancedRestTemplateModifier polarisRestTemplateBeanPostProcessor( + EnhancedRestTemplateReporter restTemplateResponseErrorHandler) { + return new EnhancedRestTemplateModifier(restTemplateResponseErrorHandler); + } + } +} 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 ea824258..e9dfa989 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; @@ -35,14 +37,14 @@ import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient; * * @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 @@ -54,14 +56,14 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac if (isNeedWrap(bean)) { if (bean instanceof LoadBalancerFeignClient) { LoadBalancerFeignClient client = ((LoadBalancerFeignClient) bean); - return new PolarisLoadBalancerFeignClient( + return new EnhancedLoadBalancerFeignClient( createPolarisFeignClient(client.getDelegate()), factory(), clientFactory()); } if (bean instanceof FeignBlockingLoadBalancerClient) { FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) bean; - return new PolarisFeignBlockingLoadBalancerClient( + return new EnhancedFeignBlockingLoadBalancerClient( createPolarisFeignClient(client.getDelegate()), factory.getBean(BlockingLoadBalancerClient.class)); } @@ -71,13 +73,13 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac } private boolean isNeedWrap(Object bean) { - return bean instanceof Client && !(bean instanceof PolarisFeignClient) - && !(bean instanceof PolarisFeignBlockingLoadBalancerClient) - && !(bean instanceof PolarisLoadBalancerFeignClient); + return bean instanceof Client && !(bean instanceof EnhancedFeignClient) + && !(bean instanceof EnhancedFeignBlockingLoadBalancerClient) + && !(bean instanceof EnhancedLoadBalancerFeignClient); } - 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 80% 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 feea5124..ba65596d 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; @@ -27,9 +27,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, BlockingLoadBalancerClient loadBalancerClient) { + public EnhancedFeignBlockingLoadBalancerClient(Client delegate, BlockingLoadBalancerClient loadBalancerClient) { super(delegate, loadBalancerClient); } } 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-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedLoadBalancerFeignClient.java similarity index 82% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedLoadBalancerFeignClient.java index f8518470..4dc30234 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedLoadBalancerFeignClient.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.ribbon.LoadBalancerFeignClient; * * @author Haotian Zhang */ -public class PolarisLoadBalancerFeignClient extends LoadBalancerFeignClient { +public class EnhancedLoadBalancerFeignClient extends LoadBalancerFeignClient { - public PolarisLoadBalancerFeignClient(Client delegate, CachingSpringLoadBalancerFactory lbClientFactory, + public EnhancedLoadBalancerFeignClient(Client delegate, CachingSpringLoadBalancerFactory lbClientFactory, SpringClientFactory clientFactory) { super(delegate, lbClientFactory, clientFactory); } 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-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/feign/plugin/EnhancedFeignPluginType.java similarity index 69% 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/feign/plugin/EnhancedFeignPluginType.java index 3c690b1c..fef181d8 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/feign/plugin/EnhancedFeignPluginType.java @@ -15,15 +15,32 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker.resttemplate; - -import org.springframework.web.client.ResponseErrorHandler; +package com.tencent.cloud.rpc.enhancement.feign.plugin; /** - * Polaris Response Error Handler Definition Of {@link ResponseErrorHandler}. + * Type of EnhancedFeignPlugin. * - * @author wh 2022/6/21 + * @author Haotian Zhang */ -public interface PolarisResponseErrorHandler extends ResponseErrorHandler { +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 0c855140..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 @@ -13,71 +13,30 @@ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. - * */ -package com.tencent.cloud.polaris.circuitbreaker.feign; +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); +public final class ReporterUtils { - private final Client delegate; - - private final ConsumerAPI consumerAPI; - - public PolarisFeignClient(Client target, ConsumerAPI consumerAPI) { - this.delegate = checkNotNull(target, "target"); - this.consumerAPI = checkNotNull(consumerAPI, "CircuitBreakAPI"); + private ReporterUtils() { } - @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 ServiceCallResult createServiceCallResult(final Request request) { + public static ServiceCallResult createServiceCallResult(final Request request, RetStatus retStatus) { ServiceCallResult resultRequest = new ServiceCallResult(); resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE); @@ -85,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)) { @@ -96,5 +55,4 @@ public class PolarisFeignClient implements Client { return resultRequest; } - } 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 80% 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 4adf0bac..0113ff49 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,13 +15,12 @@ * 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; import java.net.URI; import java.net.URL; -import java.util.Objects; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.util.ReflectionUtils; @@ -43,21 +42,16 @@ 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 FIELD_NAME = "connection"; private final ConsumerAPI consumerAPI; - private final PolarisResponseErrorHandler polarisResponseErrorHandler; - - - public PolarisRestTemplateResponseErrorHandler(ConsumerAPI consumerAPI, - PolarisResponseErrorHandler polarisResponseErrorHandler) { + public EnhancedRestTemplateReporter(ConsumerAPI consumerAPI) { this.consumerAPI = consumerAPI; - this.polarisResponseErrorHandler = polarisResponseErrorHandler; } @Override @@ -66,12 +60,8 @@ public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHan } @Override - public void handleError(@NonNull ClientHttpResponse response) throws IOException { - if (Objects.nonNull(polarisResponseErrorHandler)) { - if (polarisResponseErrorHandler.hasError(response)) { - polarisResponseErrorHandler.handleError(response); - } - } + public void handleError(@NonNull ClientHttpResponse response) { + } @Override @@ -92,9 +82,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-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 57% 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 4bb4458d..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,31 +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)) + 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 70% 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 252dcc02..0b65ef32 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; @@ -36,19 +35,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 @@ -67,31 +64,31 @@ 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"); + Object bean = enhancedFeignBeanPostProcessor.postProcessBeforeInitialization(bean1, "bean1"); assertThat(bean).isNotInstanceOfAny( - PolarisFeignClient.class, - PolarisLoadBalancerFeignClient.class, - PolarisFeignBlockingLoadBalancerClient.class); + EnhancedFeignClient.class, + EnhancedLoadBalancerFeignClient.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 LoadBalancerFeignClient.class LoadBalancerFeignClient bean3 = mock(LoadBalancerFeignClient.class); doReturn(mock(Client.class)).when(bean3).getDelegate(); - bean = polarisFeignBeanPostProcessor.postProcessBeforeInitialization(bean3, "bean3"); - assertThat(bean).isInstanceOf(PolarisLoadBalancerFeignClient.class); + bean = enhancedFeignBeanPostProcessor.postProcessBeforeInitialization(bean3, "bean3"); + assertThat(bean).isInstanceOf(EnhancedLoadBalancerFeignClient.class); // bean instanceOf FeignBlockingLoadBalancerClient.class FeignBlockingLoadBalancerClient bean4 = mock(FeignBlockingLoadBalancerClient.class); doReturn(mock(Client.class)).when(bean4).getDelegate(); - bean = polarisFeignBeanPostProcessor.postProcessBeforeInitialization(bean4, "bean4"); - assertThat(bean).isInstanceOf(PolarisFeignBlockingLoadBalancerClient.class); + 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 5be8111b..91207e53 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); + new EnhancedFeignBlockingLoadBalancerClient(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 8d21f6a1..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,17 +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); @@ -96,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); @@ -107,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", @@ -131,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-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClientTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedLoadBalancerFeignClientTest.java similarity index 81% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClientTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedLoadBalancerFeignClientTest.java index f0a72684..a6c1ec6e 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClientTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedLoadBalancerFeignClientTest.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 PolarisLoadBalancerFeignClient}. + * Test for {@link EnhancedLoadBalancerFeignClient}. * * @author Haotian Zhang */ -public class PolarisLoadBalancerFeignClientTest { +public class EnhancedLoadBalancerFeignClientTest { @Test public void testConstructor() { try { - new PolarisLoadBalancerFeignClient(null, null, null); + new EnhancedLoadBalancerFeignClient(null, null, null); } catch (Exception e) { Assertions.fail("Exception encountered.", e); 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..dc8a96c8 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); 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