diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml new file mode 100644 index 000000000..cc452e861 --- /dev/null +++ b/.github/workflows/codecov.yml @@ -0,0 +1,37 @@ +# This workflow will build a Java project with Maven +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven + +name: Codecov + +on: + push: + branches: + - main + - 2021.0 + - 2020.0 + - greenwich + pull_request: + branches: + - main + - 2021.0 + - 2020.0 + - greenwich + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout codes + uses: actions/checkout@v3 + - name: Set up JDK 8 + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: 8 + - name: Test with Maven + run: mvn -B test --file pom.xml + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + with: + file: ${{ github.workspace }}/target/site/jacoco/jacoco.xml diff --git a/.github/workflows/junit_test.yml b/.github/workflows/junit_test.yml index 51e9cce15..165255247 100644 --- a/.github/workflows/junit_test.yml +++ b/.github/workflows/junit_test.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: java: [ 8, 11, 17 ] - os: [ 'windows-latest', 'macos-latest', 'ubuntu-latest' ] + os: [ 'windows-latest', 'ubuntu-latest' ] runs-on: ${{ matrix.os }} @@ -41,11 +41,5 @@ jobs: key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven- -# - name: Build with Maven -# run: mvn -B package --file pom.xml - name: Test with Maven run: mvn -B test --file pom.xml - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - with: - file: '**/target/site/jacoco/jacoco.xml' diff --git a/CHANGELOG.md b/CHANGELOG.md index fc379208b..da2bd2990 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,4 +10,27 @@ - [fix:fix ClassNotFoundException while not importing openfeign when using circuit-breaker module.](https://github.com/Tencent/spring-cloud-tencent/pull/270) - [fix:solve the chaos code problem on rejectTips](https://github.com/Tencent/spring-cloud-tencent/pull/283) - [fix:solve ratelimit-callee-service UnknownHostException.](https://github.com/Tencent/spring-cloud-tencent/pull/291) +- [Update GitHub Actions workflow](https://github.com/Tencent/spring-cloud-tencent/pull/295) +- [Feature:add restTemplate Report Polaris](https://github.com/Tencent/spring-cloud-tencent/pull/300) +- [Fix the current limiting effect is that other requests cannot be processed when queuing at a constant speed](https://github.com/Tencent/spring-cloud-tencent/pull/317) +- [Fix config file format misspell](https://github.com/Tencent/spring-cloud-tencent/pull/320) +- [feat:Add GitHub action of codecov.yml.](https://github.com/Tencent/spring-cloud-tencent/pull/330) +- [Feature: add spring cloud tencent logo](https://github.com/Tencent/spring-cloud-tencent/pull/331) +- [UT: add metadata-transfer unit test](https://github.com/Tencent/spring-cloud-tencent/pull/334) +- [Optimize code style & unit test case](https://github.com/Tencent/spring-cloud-tencent/pull/337) +- [test:update junit of metadata.](https://github.com/Tencent/spring-cloud-tencent/pull/338) +- [Feature: Optimize static metadata manager](https://github.com/Tencent/spring-cloud-tencent/pull/341) +- [fix: shutdown thread pool before the container closes](https://github.com/Tencent/spring-cloud-tencent/pull/354) +- [rm code: Condition 'null != interceptors' is always 'true' ](https://github.com/Tencent/spring-cloud-tencent/pull/356) +- [docs:update logo in README.](https://github.com/Tencent/spring-cloud-tencent/pull/359) +- [Use jdk constants instead of magic variables](https://github.com/Tencent/spring-cloud-tencent/pull/362) +- [Refator JacksonUtils and JacksonUtilsTest](https://github.com/Tencent/spring-cloud-tencent/pull/366) +- [Feature: support actuator for sct core components](https://github.com/Tencent/spring-cloud-tencent/pull/370) +- [docs: Fix javadoc
error](https://github.com/Tencent/spring-cloud-tencent/pull/375) +- [docs: Update Readme.md](https://github.com/Tencent/spring-cloud-tencent/pull/381) +- [docs:optimize example](https://github.com/Tencent/spring-cloud-tencent/pull/386) +- [Feature: support spring cloud gateway routers](https://github.com/Tencent/spring-cloud-tencent/pull/388) +- [Optimize:optimize load balancer code and add testcase](https://github.com/Tencent/spring-cloud-tencent/pull/379) +- [refactor:optimize project and code](https://github.com/Tencent/spring-cloud-tencent/pull/392) +- [Optimize starter's auto-configuration](https://github.com/Tencent/spring-cloud-tencent/pull/395) - [test: add PostInitPolarisSDKContextTest](https://github.com/Tencent/spring-cloud-tencent/pull/399) diff --git a/README-zh.md b/README-zh.md index 3efd6c741..999fe31ba 100644 --- a/README-zh.md +++ b/README-zh.md @@ -1,13 +1,13 @@ -# Spring Cloud Tencent +Spring-Cloud-Tencent-Logo [![Wiki](https://badgen.net/badge/icon/wiki?icon=wiki&label)](https://github.com/Tencent/spring-cloud-tencent/wiki) [![Build Status](https://github.com/Tencent/spring-cloud-tencent/actions/workflows/junit_test.yml/badge.svg)](https://github.com/Tencent/spring-cloud-tencent/actions/workflows/junit_test.yml) [![Maven Central](https://img.shields.io/maven-central/v/com.tencent.cloud/spring-cloud-tencent?label=Maven%20Central)](https://search.maven.org/search?q=g:com.tencent.cloud%20AND%20a:spring-cloud-tencent) -[![codecov.io](https://codecov.io/gh/Tencent/spring-cloud-tencent/branch/main/graph/badge.svg)](https://codecov.io/gh/Tencent/spring-cloud-tencent?branch=main) +[![codecov.io](https://codecov.io/gh/Tencent/spring-cloud-tencent/branch/2020.0/graph/badge.svg)](https://codecov.io/gh/Tencent/spring-cloud-tencent?branch=2020.0) [![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,22 @@ 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 @@ -88,8 +90,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 +99,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 d54297d19..4d383a392 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ -# Spring Cloud Tencent +Spring-Cloud-Tencent-Logo + [![Wiki](https://badgen.net/badge/icon/wiki?icon=wiki&label)](https://github.com/Tencent/spring-cloud-tencent/wiki) [![Build Status](https://github.com/Tencent/spring-cloud-tencent/actions/workflows/junit_test.yml/badge.svg)](https://github.com/Tencent/spring-cloud-tencent/actions/workflows/junit_test.yml) [![Maven Central](https://img.shields.io/maven-central/v/com.tencent.cloud/spring-cloud-tencent?label=Maven%20Central)](https://search.maven.org/search?q=g:com.tencent.cloud%20AND%20a:spring-cloud-tencent) -[![codecov.io](https://codecov.io/gh/Tencent/spring-cloud-tencent/branch/main/graph/badge.svg)](https://codecov.io/gh/Tencent/spring-cloud-tencent?branch=main) +[![codecov.io](https://codecov.io/gh/Tencent/spring-cloud-tencent/branch/2020.0/graph/badge.svg)](https://codecov.io/gh/Tencent/spring-cloud-tencent?branch=2020.0) [![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) @@ -13,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/) @@ -27,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 @@ -49,7 +53,8 @@ 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. For example: @@ -78,7 +83,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) @@ -88,9 +93,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. @@ -98,8 +103,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.5.3.md b/changes/changes-1.5.3.md new file mode 100644 index 000000000..67bde42fb --- /dev/null +++ b/changes/changes-1.5.3.md @@ -0,0 +1,4 @@ +# Change Log +--- + +- [fix not load application.yml bug & fix guava version conflict bug](https://github.com/Tencent/spring-cloud-tencent/pull/287) diff --git a/doc/logo/1280x640-transparent.png b/doc/logo/1280x640-transparent.png new file mode 100644 index 000000000..9e722651c Binary files /dev/null and b/doc/logo/1280x640-transparent.png differ diff --git a/doc/logo/1280x640-transparent.svg b/doc/logo/1280x640-transparent.svg new file mode 100644 index 000000000..ed57761db --- /dev/null +++ b/doc/logo/1280x640-transparent.svg @@ -0,0 +1,17 @@ + + + 1280x640-svg透明 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/logo/1280x640-white.png b/doc/logo/1280x640-white.png new file mode 100644 index 000000000..21181cfda Binary files /dev/null and b/doc/logo/1280x640-white.png differ diff --git a/doc/logo/1280x640-white.svg b/doc/logo/1280x640-white.svg new file mode 100644 index 000000000..e09dba3f9 --- /dev/null +++ b/doc/logo/1280x640-white.svg @@ -0,0 +1,17 @@ + + + 1280x640-svg白底 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/logo/640x640-transparent.png b/doc/logo/640x640-transparent.png new file mode 100644 index 000000000..67e0c3f4f Binary files /dev/null and b/doc/logo/640x640-transparent.png differ diff --git a/doc/logo/640x640-transparent.svg b/doc/logo/640x640-transparent.svg new file mode 100644 index 000000000..bb45e2cd1 --- /dev/null +++ b/doc/logo/640x640-transparent.svg @@ -0,0 +1,17 @@ + + + 640x640-svg透明 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/logo/640x640-white.png b/doc/logo/640x640-white.png new file mode 100644 index 000000000..b4cfaab59 Binary files /dev/null and b/doc/logo/640x640-white.png differ diff --git a/doc/logo/640x640-white.svg b/doc/logo/640x640-white.svg new file mode 100644 index 000000000..f5870166a --- /dev/null +++ b/doc/logo/640x640-white.svg @@ -0,0 +1,17 @@ + + + 640x640-svg白底 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/logo/rectangle-transparent.png b/doc/logo/rectangle-transparent.png new file mode 100644 index 000000000..772332df2 Binary files /dev/null and b/doc/logo/rectangle-transparent.png differ diff --git a/doc/logo/rectangle-transparent.svg b/doc/logo/rectangle-transparent.svg new file mode 100644 index 000000000..c4c34ccc3 --- /dev/null +++ b/doc/logo/rectangle-transparent.svg @@ -0,0 +1,15 @@ + + + 长款的 svg格式透明 + + + + Spring Cloud Tencent + + + + + + + + \ No newline at end of file diff --git a/doc/logo/rectangle-white.png b/doc/logo/rectangle-white.png new file mode 100644 index 000000000..46a1c77d9 Binary files /dev/null and b/doc/logo/rectangle-white.png differ diff --git a/doc/logo/rectangle-white.svg b/doc/logo/rectangle-white.svg new file mode 100644 index 000000000..5bc74ffb7 --- /dev/null +++ b/doc/logo/rectangle-white.svg @@ -0,0 +1,16 @@ + + + 长款的 svg 格式的白底 + + + + + Spring Cloud Tencent + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java index 9e725fe90..13ad4258b 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java @@ -39,6 +39,7 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.lang.NonNull; import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; @@ -53,23 +54,25 @@ import static javax.servlet.DispatcherType.REQUEST; * * @author Haotian Zhang */ -@Configuration +@Configuration(proxyBeanMethods = false) public class MetadataTransferAutoConfiguration { /** * Create when web application type is SERVLET. */ - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) - static class MetadataServletFilterConfig { + protected static class MetadataServletFilterConfig { @Bean public FilterRegistrationBean metadataServletFilterRegistrationBean( DecodeTransferMetadataServletFilter decodeTransferMetadataServletFilter) { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>( decodeTransferMetadataServletFilter); - filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST); - filterRegistrationBean.setOrder(MetadataConstant.OrderConstant.WEB_FILTER_ORDER); + filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, + REQUEST); + filterRegistrationBean + .setOrder(MetadataConstant.OrderConstant.WEB_FILTER_ORDER); return filterRegistrationBean; } @@ -77,29 +80,27 @@ public class MetadataTransferAutoConfiguration { public DecodeTransferMetadataServletFilter metadataServletFilter() { return new DecodeTransferMetadataServletFilter(); } - } /** * Create when web application type is REACTIVE. */ - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) - static class MetadataReactiveFilterConfig { + protected static class MetadataReactiveFilterConfig { @Bean public DecodeTransferMetadataReactiveFilter metadataReactiveFilter() { return new DecodeTransferMetadataReactiveFilter(); } - } /** * Create when gateway application is SCG. */ - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnClass(name = "org.springframework.cloud.gateway.filter.GlobalFilter") - static class MetadataTransferScgFilterConfig { + protected static class MetadataTransferScgFilterConfig { @Bean public GlobalFilter encodeTransferMedataScgFilter() { @@ -111,23 +112,22 @@ public class MetadataTransferAutoConfiguration { /** * Create when Feign exists. */ - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnClass(name = "feign.Feign") - static class MetadataTransferFeignInterceptorConfig { + protected static class MetadataTransferFeignInterceptorConfig { @Bean public EncodeTransferMedataFeignInterceptor encodeTransferMedataFeignInterceptor() { return new EncodeTransferMedataFeignInterceptor(); } - } /** * Create when RestTemplate exists. */ - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnClass(name = "org.springframework.web.client.RestTemplate") - static class MetadataTransferRestTemplateConfig implements ApplicationContextAware { + protected static class MetadataTransferRestTemplateConfig implements ApplicationContextAware { private ApplicationContext context; @@ -140,31 +140,36 @@ public class MetadataTransferAutoConfiguration { BeanPostProcessor encodeTransferMetadataRestTemplatePostProcessor( EncodeTransferMedataRestTemplateInterceptor encodeTransferMedataRestTemplateInterceptor) { // Coping with multiple bean injection scenarios - Map beans = this.context.getBeansOfType(RestTemplate.class); + Map beans = this.context + .getBeansOfType(RestTemplate.class); // If the restTemplate has been created when the // MetadataRestTemplatePostProcessor Bean // is initialized, then manually set the interceptor. if (!CollectionUtils.isEmpty(beans)) { for (RestTemplate restTemplate : beans.values()) { - List interceptors = restTemplate.getInterceptors(); + List interceptors = restTemplate + .getInterceptors(); // Avoid setting interceptor repeatedly. - if (null != interceptors && !interceptors.contains(encodeTransferMedataRestTemplateInterceptor)) { + if (!interceptors.contains(encodeTransferMedataRestTemplateInterceptor)) { interceptors.add(encodeTransferMedataRestTemplateInterceptor); restTemplate.setInterceptors(interceptors); } } } - return new EncodeTransferMetadataRestTemplatePostProcessor(encodeTransferMedataRestTemplateInterceptor); + return new EncodeTransferMetadataRestTemplatePostProcessor( + encodeTransferMedataRestTemplateInterceptor); } @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + public void setApplicationContext(@NonNull ApplicationContext applicationContext) + throws BeansException { this.context = applicationContext; } - public static class EncodeTransferMetadataRestTemplatePostProcessor implements BeanPostProcessor { + public static class EncodeTransferMetadataRestTemplatePostProcessor + implements BeanPostProcessor { - private EncodeTransferMedataRestTemplateInterceptor encodeTransferMedataRestTemplateInterceptor; + private final EncodeTransferMedataRestTemplateInterceptor encodeTransferMedataRestTemplateInterceptor; EncodeTransferMetadataRestTemplatePostProcessor( EncodeTransferMedataRestTemplateInterceptor encodeTransferMedataRestTemplateInterceptor) { @@ -172,26 +177,24 @@ public class MetadataTransferAutoConfiguration { } @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) { + public Object postProcessBeforeInitialization(@NonNull Object bean, @NonNull String beanName) { return bean; } @Override - public Object postProcessAfterInitialization(Object bean, String beanName) { + public Object postProcessAfterInitialization(@NonNull Object bean, @NonNull String beanName) { if (bean instanceof RestTemplate) { RestTemplate restTemplate = (RestTemplate) bean; - List interceptors = restTemplate.getInterceptors(); + List interceptors = restTemplate + .getInterceptors(); // Avoid setting interceptor repeatedly. - if (null != interceptors && !interceptors.contains(encodeTransferMedataRestTemplateInterceptor)) { + if (!interceptors.contains(encodeTransferMedataRestTemplateInterceptor)) { interceptors.add(this.encodeTransferMedataRestTemplateInterceptor); restTemplate.setInterceptors(interceptors); } } return bean; } - } - } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java index b8645efb2..f11c39182 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java @@ -32,13 +32,15 @@ import org.springframework.util.CollectionUtils; import org.springframework.web.server.ServerWebExchange; /** - * resolve custom transitive metadata from request. - *@author lepdou 2022-05-20 + * Resolve custom transitive metadata from request. + * + * @author lepdou 2022-05-20 */ -public class CustomTransitiveMetadataResolver { - +public final class CustomTransitiveMetadataResolver { private static final String TRANSITIVE_HEADER_PREFIX = "X-SCT-Metadata-Transitive-"; private static final int TRANSITIVE_HEADER_PREFIX_LENGTH = TRANSITIVE_HEADER_PREFIX.length(); + private CustomTransitiveMetadataResolver() { + } public static Map resolve(ServerWebExchange exchange) { Map result = new HashMap<>(); diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java index 225e3cc5d..7ef89920f 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java @@ -38,6 +38,8 @@ import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; + /** * Filter used for storing the metadata from upstream temporarily when web application is * REACTIVE. @@ -84,7 +86,7 @@ public class DecodeTransferMetadataReactiveFilter implements WebFilter, Ordered .getFirst(MetadataConstant.HeaderName.CUSTOM_METADATA); try { if (StringUtils.hasText(customMetadataStr)) { - customMetadataStr = URLDecoder.decode(customMetadataStr, "UTF-8"); + customMetadataStr = URLDecoder.decode(customMetadataStr, UTF_8); } } catch (UnsupportedEncodingException e) { @@ -94,5 +96,4 @@ public class DecodeTransferMetadataReactiveFilter implements WebFilter, Ordered return JacksonUtils.deserialize2Map(customMetadataStr); } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java index 8ca9e2bc2..3abf391e3 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java @@ -39,6 +39,8 @@ import org.springframework.core.annotation.Order; import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; + /** * Filter used for storing the metadata from upstream temporarily when web application is * SERVLET. @@ -76,7 +78,7 @@ public class DecodeTransferMetadataServletFilter extends OncePerRequestFilter { String customMetadataStr = httpServletRequest.getHeader(MetadataConstant.HeaderName.CUSTOM_METADATA); try { if (StringUtils.hasText(customMetadataStr)) { - customMetadataStr = URLDecoder.decode(customMetadataStr, "UTF-8"); + customMetadataStr = URLDecoder.decode(customMetadataStr, UTF_8); } } catch (UnsupportedEncodingException e) { @@ -87,5 +89,4 @@ public class DecodeTransferMetadataServletFilter extends OncePerRequestFilter { // create custom metadata. return JacksonUtils.deserialize2Map(customMetadataStr); } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java index 0bf97bf0f..a6af9e15e 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java @@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; import org.springframework.util.CollectionUtils; +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_METADATA; /** @@ -61,7 +62,8 @@ public class EncodeTransferMedataFeignInterceptor implements RequestInterceptor, String encodedTransitiveMetadata = JacksonUtils.serialize2Json(customMetadata); requestTemplate.removeHeader(CUSTOM_METADATA); try { - requestTemplate.header(CUSTOM_METADATA, URLEncoder.encode(encodedTransitiveMetadata, "UTF-8")); + requestTemplate.header(CUSTOM_METADATA, + URLEncoder.encode(encodedTransitiveMetadata, UTF_8)); } catch (UnsupportedEncodingException e) { LOG.error("Set header failed.", e); @@ -69,5 +71,4 @@ public class EncodeTransferMedataFeignInterceptor implements RequestInterceptor, } } } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java index 37f94eb2c..75f198193 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java @@ -35,6 +35,8 @@ import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; import org.springframework.util.CollectionUtils; +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; + /** * Interceptor used for adding the metadata in http headers from context when web client * is RestTemplate. @@ -59,7 +61,7 @@ public class EncodeTransferMedataRestTemplateInterceptor implements ClientHttpRe String encodedTransitiveMetadata = JacksonUtils.serialize2Json(customMetadata); try { httpRequest.getHeaders().set(MetadataConstant.HeaderName.CUSTOM_METADATA, - URLEncoder.encode(encodedTransitiveMetadata, "UTF-8")); + URLEncoder.encode(encodedTransitiveMetadata, UTF_8)); } catch (UnsupportedEncodingException e) { httpRequest.getHeaders().set(MetadataConstant.HeaderName.CUSTOM_METADATA, encodedTransitiveMetadata); @@ -67,5 +69,4 @@ public class EncodeTransferMedataRestTemplateInterceptor implements ClientHttpRe } return clientHttpRequestExecution.execute(httpRequest, bytes); } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java index 81b4fba4b..4f6c00103 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java @@ -35,6 +35,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.util.CollectionUtils; import org.springframework.web.server.ServerWebExchange; +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; import static org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER; /** @@ -67,7 +68,7 @@ public class EncodeTransferMedataScgFilter implements GlobalFilter, Ordered { if (!CollectionUtils.isEmpty(customMetadata)) { String metadataStr = JacksonUtils.serialize2Json(customMetadata); try { - builder.header(MetadataConstant.HeaderName.CUSTOM_METADATA, URLEncoder.encode(metadataStr, "UTF-8")); + builder.header(MetadataConstant.HeaderName.CUSTOM_METADATA, URLEncoder.encode(metadataStr, UTF_8)); } catch (UnsupportedEncodingException e) { builder.header(MetadataConstant.HeaderName.CUSTOM_METADATA, metadataStr); @@ -76,5 +77,4 @@ public class EncodeTransferMedataScgFilter implements GlobalFilter, Ordered { return chain.filter(exchange.mutate().request(builder.build()).build()); } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java index 2d1c5e7ce..a6b266431 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java @@ -50,11 +50,11 @@ public class MetadataTransferAutoConfigurationTest { .hasSingleBean(MetadataTransferAutoConfiguration.MetadataTransferRestTemplateConfig.class); Assertions.assertThat(context).hasSingleBean(EncodeTransferMedataRestTemplateInterceptor.class); Assertions.assertThat(context).hasSingleBean( - MetadataTransferAutoConfiguration.MetadataTransferRestTemplateConfig.EncodeTransferMetadataRestTemplatePostProcessor.class); + MetadataTransferAutoConfiguration.MetadataTransferRestTemplateConfig + .EncodeTransferMetadataRestTemplatePostProcessor.class); Assertions.assertThat(context) .hasSingleBean(MetadataTransferAutoConfiguration.MetadataTransferScgFilterConfig.class); Assertions.assertThat(context).hasSingleBean(GlobalFilter.class); }); } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolverTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolverTest.java new file mode 100644 index 000000000..9dc83bd51 --- /dev/null +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolverTest.java @@ -0,0 +1,54 @@ +/* + * 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.metadata.core; + +import java.util.Map; + +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.server.MockServerWebExchange; + +/** + * Test for {@link CustomTransitiveMetadataResolver}. + * + * @author quan + */ +public class CustomTransitiveMetadataResolverTest { + + @Test + public void test() { + MockServerHttpRequest.BaseBuilder builder = MockServerHttpRequest.get(""); + builder.header("X-SCT-Metadata-Transitive-a", "test"); + MockServerWebExchange exchange = MockServerWebExchange.from(builder); + Map resolve = CustomTransitiveMetadataResolver.resolve(exchange); + Assertions.assertThat(resolve.size()).isEqualTo(1); + Assertions.assertThat(resolve.get("a")).isEqualTo("test"); + } + + @Test + public void testServlet() { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader("X-SCT-Metadata-Transitive-a", "test"); + Map resolve = CustomTransitiveMetadataResolver.resolve(request); + Assertions.assertThat(resolve.size()).isEqualTo(1); + Assertions.assertThat(resolve.get("a")).isEqualTo("test"); + } +} diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataReactiveFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilterTest.java similarity index 96% rename from spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataReactiveFilterTest.java rename to spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilterTest.java index 6f6b9cc20..4dbe83f83 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataReactiveFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilterTest.java @@ -13,14 +13,12 @@ * 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.metadata; +package com.tencent.cloud.metadata.core; import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; -import com.tencent.cloud.metadata.core.DecodeTransferMetadataReactiveFilter; import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; @@ -38,6 +36,8 @@ import org.springframework.web.server.WebFilterChain; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.MOCK; /** + * Test for {@link DecodeTransferMetadataReactiveFilter}. + * * @author Haotian Zhang */ @RunWith(SpringRunner.class) @@ -80,5 +80,4 @@ public class DecodeTransferMetadataReactiveFilterTest { .isEqualTo("2"); Assertions.assertThat(metadataLocalProperties.getContent().get("c")).isNull(); } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataServletFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilterTest.java similarity index 96% rename from spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataServletFilterTest.java rename to spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilterTest.java index 41cc512b8..a2292f2f0 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataServletFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilterTest.java @@ -13,10 +13,9 @@ * 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.metadata; +package com.tencent.cloud.metadata.core; import java.io.IOException; @@ -25,7 +24,6 @@ import javax.servlet.ServletException; import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; -import com.tencent.cloud.metadata.core.DecodeTransferMetadataServletFilter; import org.assertj.core.api.Assertions; import org.junit.Test; import org.junit.runner.RunWith; @@ -40,6 +38,8 @@ import org.springframework.test.context.junit4.SpringRunner; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** + * Test for {@link DecodeTransferMetadataServletFilter}. + * * @author Haotian Zhang */ @RunWith(SpringRunner.class) @@ -77,5 +77,4 @@ public class DecodeTransferMetadataServletFilterTest { protected static class TestApplication { } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataFeignInterceptorTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptorTest.java similarity index 96% rename from spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataFeignInterceptorTest.java rename to spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptorTest.java index c4a7338df..67f7edb46 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataFeignInterceptorTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptorTest.java @@ -13,10 +13,9 @@ * 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.metadata.core.intercepter; +package com.tencent.cloud.metadata.core; import java.io.UnsupportedEncodingException; @@ -24,7 +23,6 @@ import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; -import com.tencent.cloud.metadata.core.EncodeTransferMedataFeignInterceptor; import feign.RequestInterceptor; import feign.RequestTemplate; import org.assertj.core.api.Assertions; @@ -99,9 +97,6 @@ public class EncodeTransferMedataFeignInterceptorTest { template.header(MetadataConstant.HeaderName.CUSTOM_METADATA, "{\"a\":\"11\",\"b\":\"22\",\"c\":\"33\"}"); } - } - } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataRestTemplateInterceptorTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptorTest.java similarity index 95% rename from spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataRestTemplateInterceptorTest.java rename to spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptorTest.java index 78abb33ab..da914c0c8 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataRestTemplateInterceptorTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptorTest.java @@ -13,17 +13,15 @@ * 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.metadata.core.intercepter; +package com.tencent.cloud.metadata.core; import java.io.UnsupportedEncodingException; import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContextHolder; -import com.tencent.cloud.metadata.core.EncodeTransferMedataRestTemplateInterceptor; import org.assertj.core.api.Assertions; import org.junit.Test; import org.junit.runner.RunWith; @@ -87,7 +85,5 @@ public class EncodeTransferMedataRestTemplateInterceptorTest { throws UnsupportedEncodingException { return MetadataContextHolder.get().getContext(MetadataContext.FRAGMENT_TRANSITIVE, "b"); } - } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java new file mode 100644 index 000000000..0a37c54dc --- /dev/null +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java @@ -0,0 +1,84 @@ +/* + * 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.metadata.core; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.Map; + +import com.tencent.cloud.common.constant.MetadataConstant; +import com.tencent.cloud.common.util.JacksonUtils; +import org.assertj.core.api.Assertions; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.context.ApplicationContext; +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.web.server.MockServerWebExchange; +import org.springframework.test.context.junit4.SpringRunner; + +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +/** + * Test for {@link EncodeTransferMedataScgFilter}. + * + * @author quan + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = RANDOM_PORT, + classes = EncodeTransferMedataScgFilterTest.TestApplication.class, + properties = {"spring.config.location = classpath:application-test.yml", + "spring.main.web-application-type = reactive"}) +public class EncodeTransferMedataScgFilterTest { + + @Autowired + private ApplicationContext applicationContext; + + @Mock + private GatewayFilterChain chain; + + @Test + public void testTransitiveMetadataFromApplicationConfig() throws UnsupportedEncodingException { + EncodeTransferMedataScgFilter filter = applicationContext.getBean(EncodeTransferMedataScgFilter.class); + + // Mock Server Http Request + MockServerHttpRequest.BaseBuilder builder = MockServerHttpRequest.get(""); + MockServerWebExchange exchange = MockServerWebExchange.from(builder); + filter.filter(exchange, chain); + + // Check metadata str + String metadata = exchange.getRequest().getHeaders().getFirst(MetadataConstant.HeaderName.CUSTOM_METADATA); + Assertions.assertThat(metadata).isNotNull(); + + String decode = URLDecoder.decode(metadata, UTF_8); + Map transitiveMap = JacksonUtils.deserialize2Map(decode); + Assertions.assertThat(transitiveMap.size()).isEqualTo(1); + Assertions.assertThat(transitiveMap.get("b")).isEqualTo("2"); + } + + @SpringBootApplication + protected static class TestApplication { + + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml index 637be20f6..f79e46aab 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml @@ -90,6 +90,12 @@ true + + org.springframework.boot + spring-boot-starter-web + test + + org.springframework.boot spring-boot-starter-test diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfiguration.java deleted file mode 100644 index 5b98172bb..000000000 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfiguration.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.circuitbreaker; - -import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisFeignBeanPostProcessor; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.client.api.SDKContext; -import com.tencent.polaris.factory.api.DiscoveryAPIFactory; - -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 static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; - -/** - * Configuration for Polaris {@link feign.Feign} which can automatically bring in the call - * results for reporting. - * - * @author Haotian Zhang - */ -@ConditionalOnProperty(value = "spring.cloud.polaris.circuitbreaker.enabled", havingValue = "true", - matchIfMissing = true) -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(name = "org.springframework.cloud.openfeign.FeignAutoConfiguration") -@AutoConfigureAfter(PolarisContextAutoConfiguration.class) -@AutoConfigureBefore(FeignAutoConfiguration.class) -public class PolarisFeignClientAutoConfiguration { - - @Bean - public ConsumerAPI consumerAPI(SDKContext context) { - return DiscoveryAPIFactory.createConsumerAPIByContext(context); - } - - @Bean - @Order(HIGHEST_PRECEDENCE) - public PolarisFeignBeanPostProcessor polarisFeignBeanPostProcessor(ConsumerAPI consumerAPI) { - return new PolarisFeignBeanPostProcessor(consumerAPI); - } - -} 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 new file mode 100644 index 000000000..e8e1fa038 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java @@ -0,0 +1,100 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.circuitbreaker.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 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. + * + * @author Palmer.Xu 2022-06-29 + */ +@Configuration(proxyBeanMethods = false) +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 ConsumerAPI consumerAPI(SDKContext context) { + return DiscoveryAPIFactory.createConsumerAPIByContext(context); + } + + @Bean + @Order(HIGHEST_PRECEDENCE) + public PolarisFeignBeanPostProcessor polarisFeignBeanPostProcessor(ConsumerAPI consumerAPI) { + return new PolarisFeignBeanPostProcessor(consumerAPI); + } + } + + /** + * 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 { + + @Bean + public PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler( + ConsumerAPI consumerAPI, @Autowired(required = false) PolarisResponseErrorHandler polarisResponseErrorHandler) { + return new PolarisRestTemplateResponseErrorHandler(consumerAPI, polarisResponseErrorHandler); + } + + @Bean + public PolarisRestTemplateModifier polarisRestTemplateBeanPostProcessor( + PolarisRestTemplateResponseErrorHandler restTemplateResponseErrorHandler) { + return new PolarisRestTemplateModifier(restTemplateResponseErrorHandler); + } + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java similarity index 97% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfiguration.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java index 121ffcf6d..e10387f27 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.config; import com.tencent.cloud.common.constant.ContextConstant; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; @@ -33,10 +33,10 @@ import org.springframework.context.annotation.Configuration; * * @author lepdou 2022-03-29 */ +@Configuration(proxyBeanMethods = false) @ConditionalOnPolarisEnabled @ConditionalOnProperty(value = "spring.cloud.polaris.circuitbreaker.enabled", havingValue = "true", matchIfMissing = true) -@Configuration(proxyBeanMethods = false) public class PolarisCircuitBreakerBootstrapConfiguration { @Bean @@ -66,7 +66,5 @@ public class PolarisCircuitBreakerBootstrapConfiguration { 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/feign/PolarisFeignBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java index 2cd2ce9ec..4b0193800 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java @@ -29,6 +29,7 @@ import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalanc import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; import org.springframework.cloud.openfeign.loadbalancer.RetryableFeignBlockingLoadBalancerClient; +import org.springframework.lang.NonNull; /** * Wrap Spring Bean and decorating proxy for Feign Client. @@ -46,7 +47,7 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac } @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + public Object postProcessBeforeInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException { return wrapper(bean); } @@ -83,8 +84,7 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac } @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + public void setBeanFactory(@NonNull BeanFactory beanFactory) throws BeansException { this.factory = beanFactory; } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java index 7280ecaef..ef2b82bc5 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java @@ -35,5 +35,4 @@ public class PolarisFeignBlockingLoadBalancerClient extends FeignBlockingLoadBal LoadBalancerProperties properties, LoadBalancerClientFactory loadBalancerClientFactory) { super(delegate, loadBalancerClient, properties, loadBalancerClientFactory); } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java index 49f34dcc0..b4b03703a 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java @@ -60,7 +60,7 @@ public class PolarisFeignClient implements Client { try { Response response = delegate.execute(request, options); // HTTP code greater than 500 is an exception - if (response.status() >= 500) { + if (response.status() > 500) { resultRequest.setRetStatus(RetStatus.RetFail); } LOG.debug("Will report result of {}. Request=[{}]. Response=[{}].", @@ -96,5 +96,4 @@ public class PolarisFeignClient implements Client { return resultRequest; } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisResponseErrorHandler.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisResponseErrorHandler.java new file mode 100644 index 000000000..3c690b1cc --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisResponseErrorHandler.java @@ -0,0 +1,29 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.circuitbreaker.resttemplate; + +import org.springframework.web.client.ResponseErrorHandler; + +/** + * Polaris Response Error Handler Definition Of {@link ResponseErrorHandler}. + * + * @author wh 2022/6/21 + */ +public interface PolarisResponseErrorHandler extends ResponseErrorHandler { + +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java new file mode 100644 index 000000000..4ce1701dc --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java @@ -0,0 +1,65 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.circuitbreaker.resttemplate; + +import java.util.Map; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.SmartInitializingSingleton; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.util.ObjectUtils; +import org.springframework.web.client.RestTemplate; + +/** + * Auto configuration RestTemplate, Find the RestTemplate bean annotated with {@link LoadBalanced}, + * then replace {@link org.springframework.web.client.ResponseErrorHandler} + * with {@link PolarisRestTemplateResponseErrorHandler}. + * + * @author wh 2022/6/21 + */ +public class PolarisRestTemplateModifier implements ApplicationContextAware, SmartInitializingSingleton { + + private final PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler; + private ApplicationContext applicationContext; + + public PolarisRestTemplateModifier(PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler) { + this.polarisRestTemplateResponseErrorHandler = polarisRestTemplateResponseErrorHandler; + } + + @Override + public void afterSingletonsInstantiated() { + Map beans = this.applicationContext.getBeansWithAnnotation(LoadBalanced.class); + if (!ObjectUtils.isEmpty(beans)) { + beans.forEach(this::initRestTemplate); + } + } + + private void initRestTemplate(String beanName, Object bean) { + if (bean instanceof RestTemplate) { + RestTemplate restTemplate = (RestTemplate) bean; + restTemplate.setErrorHandler(polarisRestTemplateResponseErrorHandler); + } + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java new file mode 100644 index 000000000..2dfbf2284 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java @@ -0,0 +1,114 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.circuitbreaker.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; +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 org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.http.HttpMethod; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.lang.NonNull; +import org.springframework.web.client.ResponseErrorHandler; + +/** + * Extend ResponseErrorHandler to get request information. + * + * @author wh 2022/6/21 + */ +public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHandler { + + private static final Logger LOG = LoggerFactory.getLogger(PolarisRestTemplateResponseErrorHandler.class); + + private static final String FIELD_NAME = "connection"; + + private final ConsumerAPI consumerAPI; + + private final PolarisResponseErrorHandler polarisResponseErrorHandler; + + public PolarisRestTemplateResponseErrorHandler( + ConsumerAPI consumerAPI, PolarisResponseErrorHandler polarisResponseErrorHandler) { + this.consumerAPI = consumerAPI; + this.polarisResponseErrorHandler = polarisResponseErrorHandler; + } + + @Override + public boolean hasError(@NonNull ClientHttpResponse response) { + return true; + } + + @Override + public void handleError(@NonNull ClientHttpResponse response) throws IOException { + if (Objects.nonNull(polarisResponseErrorHandler)) { + if (polarisResponseErrorHandler.hasError(response)) { + polarisResponseErrorHandler.handleError(response); + } + } + } + + @Override + public void handleError(@NonNull URI url, @NonNull HttpMethod method, @NonNull ClientHttpResponse response) throws IOException { + ServiceCallResult resultRequest = createServiceCallResult(url); + try { + HttpURLConnection connection = (HttpURLConnection) ReflectionUtils.getFieldValue(response, FIELD_NAME); + if (connection != null) { + URL realURL = connection.getURL(); + resultRequest.setHost(realURL.getHost()); + resultRequest.setPort(realURL.getPort()); + } + + if (response.getStatusCode().value() > 500) { + resultRequest.setRetStatus(RetStatus.RetFail); + } + } + catch (Exception e) { + LOG.error("Will report response of {} url {}", response, url, e); + throw e; + } + finally { + consumerAPI.updateServiceCallResult(resultRequest); + } + } + + private ServiceCallResult createServiceCallResult(URI uri) { + ServiceCallResult resultRequest = new ServiceCallResult(); + String serviceName = uri.getHost(); + resultRequest.setService(serviceName); + resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE); + resultRequest.setMethod(uri.getPath()); + resultRequest.setRetStatus(RetStatus.RetSuccess); + String sourceNamespace = MetadataContext.LOCAL_NAMESPACE; + String sourceService = MetadataContext.LOCAL_SERVICE; + if (StringUtils.isNotBlank(sourceNamespace) && StringUtils.isNotBlank(sourceService)) { + resultRequest.setCallerService(new ServiceKey(sourceNamespace, sourceService)); + } + return resultRequest; + } +} 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 04fa47a13..2c72cfed9 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories @@ -1,4 +1,4 @@ org.springframework.cloud.bootstrap.BootstrapConfiguration=\ - com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreakerBootstrapConfiguration + com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.tencent.cloud.polaris.circuitbreaker.PolarisFeignClientAutoConfiguration + com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration 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/PolarisCircuitBreakerBootstrapConfigurationTest.java index 42777a3b6..e29c4a76f 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/PolarisCircuitBreakerBootstrapConfigurationTest.java @@ -17,6 +17,7 @@ package com.tencent.cloud.polaris.circuitbreaker; +import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration; import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -31,14 +32,14 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisCircuitBreakerBootstrapConfigurationTest { private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisCircuitBreakerBootstrapConfiguration.class)) + .withConfiguration(AutoConfigurations.of(PolarisCircuitBreakerBootstrapConfiguration.class)) .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true"); @Test public void testDefaultInitialization() { this.contextRunner.run(context -> { - assertThat(context).hasSingleBean(PolarisCircuitBreakerBootstrapConfiguration.CircuitBreakerConfigModifier.class); + assertThat(context).hasSingleBean( + PolarisCircuitBreakerBootstrapConfiguration.CircuitBreakerConfigModifier.class); }); } } 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/PolarisFeignClientAutoConfigurationTest.java index c83608478..6858a627f 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/PolarisFeignClientAutoConfigurationTest.java @@ -17,8 +17,9 @@ package com.tencent.cloud.polaris.circuitbreaker; +import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration; import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisFeignBeanPostProcessor; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.polaris.api.core.ConsumerAPI; import org.junit.Test; @@ -28,17 +29,17 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; /** - * Test for {@link PolarisFeignClientAutoConfiguration}. + * Test for {@link PolarisCircuitBreakerAutoConfiguration}. * * @author Haotian Zhang */ public class PolarisFeignClientAutoConfigurationTest { - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration( AutoConfigurations.of( PolarisContextAutoConfiguration.class, - PolarisFeignClientAutoConfiguration.class)) + PolarisCircuitBreakerAutoConfiguration.class)) .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true"); @Test @@ -48,5 +49,4 @@ public class PolarisFeignClientAutoConfigurationTest { assertThat(context).hasSingleBean(PolarisFeignBeanPostProcessor.class); }); } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java new file mode 100644 index 000000000..4bb4458de --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.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.polaris.circuitbreaker; + +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 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; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test For {@link PolarisCircuitBreakerAutoConfiguration} . + * + * @author Palmer Xu 2022-06-28 + */ +public class PolarisRestTemplateAutoConfigurationTest { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisRestTemplateAutoConfigurationTester.class, + PolarisContextAutoConfiguration.class, + PolarisCircuitBreakerAutoConfiguration.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); + }); + } + + @Configuration + @EnableAutoConfiguration + @AutoConfigureBefore(PolarisCircuitBreakerAutoConfiguration.class) + static class PolarisRestTemplateAutoConfigurationTester { + + @Bean + RestTemplate restTemplate() { + return new RestTemplate(); + } + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java index 993eedc58..a3228f779 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java @@ -90,7 +90,7 @@ public class PolarisFeignClientTest { return Response.builder().request(request).status(200).build(); } else if (request.httpMethod().equals(Request.HttpMethod.POST)) { - return Response.builder().request(request).status(500).build(); + return Response.builder().request(request).status(502).build(); } throw new IOException("Mock exception."); }).when(delegate).execute(any(Request.class), nullable(Request.Options.class)); @@ -113,10 +113,10 @@ public class PolarisFeignClientTest { Maps.newHashMap(), null, requestTemplate), null); assertThat(response.status()).isEqualTo(200); - // 200 + // 502 response = polarisFeignClient.execute(Request.create(Request.HttpMethod.POST, "http://localhost:8080/test", Maps.newHashMap(), null, requestTemplate), null); - assertThat(response.status()).isEqualTo(500); + assertThat(response.status()).isEqualTo(502); // Exception try { diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandlerTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandlerTest.java new file mode 100644 index 000000000..6cb630e37 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandlerTest.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.polaris.circuitbreaker.resttemplate; + + +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; + +import com.tencent.polaris.api.core.ConsumerAPI; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpMethod; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Test For {@link PolarisRestTemplateResponseErrorHandler}. + * + * @author wh 2022/6/22 + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = PolarisRestTemplateResponseErrorHandlerTest.TestApplication.class, + properties = {"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp"}) +public class PolarisRestTemplateResponseErrorHandlerTest { + + @Test + public void handleError() throws Exception { + ConsumerAPI consumerAPI = mock(ConsumerAPI.class); + PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler = new PolarisRestTemplateResponseErrorHandler(consumerAPI, null); + URI uri = mock(URI.class); + when(uri.getPath()).thenReturn("/test"); + when(uri.getHost()).thenReturn("host"); + HttpURLConnection httpURLConnection = mock(HttpURLConnection.class); + URL url = mock(URL.class); + when(httpURLConnection.getURL()).thenReturn(url); + when(url.getHost()).thenReturn("127.0.0.1"); + when(url.getPort()).thenReturn(8080); + when(httpURLConnection.getResponseCode()).thenReturn(200); + SimpleClientHttpResponseTest clientHttpResponse = new SimpleClientHttpResponseTest(httpURLConnection); + polarisRestTemplateResponseErrorHandler.handleError(uri, HttpMethod.GET, clientHttpResponse); + when(consumerAPI.unWatchService(null)).thenReturn(true); + } + + @SpringBootApplication + protected static class TestApplication { + + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java new file mode 100644 index 000000000..d8ac018cf --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java @@ -0,0 +1,105 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.circuitbreaker.resttemplate; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.client.AbstractClientHttpResponse; +import org.springframework.lang.Nullable; +import org.springframework.util.StreamUtils; +import org.springframework.util.StringUtils; + + +/** + * Mock Test for {@link AbstractClientHttpResponse}. + * + * @author wh 2022/6/22 + */ +public class SimpleClientHttpResponseTest extends AbstractClientHttpResponse { + + private final HttpURLConnection connection; + + @Nullable + private HttpHeaders headers; + + @Nullable + private InputStream responseStream; + + + SimpleClientHttpResponseTest(HttpURLConnection connection) { + this.connection = connection; + } + + + @Override + public int getRawStatusCode() throws IOException { + return this.connection.getResponseCode(); + } + + @Override + public String getStatusText() throws IOException { + String result = this.connection.getResponseMessage(); + return (result != null) ? result : ""; + } + + @Override + public HttpHeaders getHeaders() { + if (this.headers == null) { + this.headers = new HttpHeaders(); + // Header field 0 is the status line for most HttpURLConnections, but not on GAE + String name = this.connection.getHeaderFieldKey(0); + if (StringUtils.hasLength(name)) { + this.headers.add(name, this.connection.getHeaderField(0)); + } + int i = 1; + while (true) { + name = this.connection.getHeaderFieldKey(i); + if (!StringUtils.hasLength(name)) { + break; + } + this.headers.add(name, this.connection.getHeaderField(i)); + i++; + } + } + return this.headers; + } + + @Override + public InputStream getBody() throws IOException { + InputStream errorStream = this.connection.getErrorStream(); + this.responseStream = (errorStream != null ? errorStream : this.connection.getInputStream()); + return this.responseStream; + } + + @Override + public void close() { + try { + if (this.responseStream == null) { + getBody(); + } + StreamUtils.drain(this.responseStream); + this.responseStream.close(); + } + catch (Exception ex) { + // ignore + } + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/pom.xml b/spring-cloud-starter-tencent-polaris-config/pom.xml index a7f0e5894..e7262c29f 100644 --- a/spring-cloud-starter-tencent-polaris-config/pom.xml +++ b/spring-cloud-starter-tencent-polaris-config/pom.xml @@ -71,6 +71,18 @@ test + + org.springframework.boot + spring-boot-actuator + true + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + org.mockito mockito-inline diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/ConfigurationModifier.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/ConfigurationModifier.java index 495d6ec3a..9953b3c67 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/ConfigurationModifier.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/ConfigurationModifier.java @@ -25,7 +25,7 @@ import com.tencent.cloud.common.constant.ContextConstant; import com.tencent.cloud.common.util.AddressUtils; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; import com.tencent.cloud.polaris.context.PolarisConfigModifier; -import com.tencent.cloud.polaris.context.PolarisContextProperties; +import com.tencent.cloud.polaris.context.config.PolarisContextProperties; import com.tencent.polaris.factory.config.ConfigurationImpl; import org.apache.commons.lang.StringUtils; diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java index 2b61b69be..4d8bb496d 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java @@ -57,5 +57,4 @@ public class PolarisConfigAutoConfiguration { public PolarisConfigChangeEventListener polarisConfigChangeEventListener() { return new PolarisConfigChangeEventListener(); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java index 0a87c0e65..a67c8a89d 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java @@ -21,8 +21,8 @@ import com.tencent.cloud.polaris.config.adapter.PolarisConfigFileLocator; import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; -import com.tencent.cloud.polaris.context.PolarisContextProperties; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextProperties; import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.configuration.api.core.ConfigFileService; import com.tencent.polaris.configuration.factory.ConfigFileServiceFactory; @@ -79,5 +79,4 @@ public class PolarisConfigBootstrapAutoConfiguration { PolarisContextProperties polarisContextProperties) { return new ConfigurationModifier(polarisConfigProperties, polarisContextProperties); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java index b23d6a132..7c975f857 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java @@ -25,7 +25,7 @@ import java.util.concurrent.ConcurrentHashMap; import com.tencent.cloud.polaris.config.config.ConfigFileGroup; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; import com.tencent.cloud.polaris.config.enums.ConfigFileFormat; -import com.tencent.cloud.polaris.context.PolarisContextProperties; +import com.tencent.cloud.polaris.context.config.PolarisContextProperties; import com.tencent.polaris.configuration.api.core.ConfigFileMetadata; import com.tencent.polaris.configuration.api.core.ConfigFileService; import com.tencent.polaris.configuration.api.core.ConfigKVFile; @@ -204,5 +204,4 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { return new PolarisPropertySource(namespace, group, fileName, configKVFile, map); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySource.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySource.java index 63c173e75..5a05ce132 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySource.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySource.java @@ -74,5 +74,4 @@ public class PolarisPropertySource extends MapPropertySource { return "PolarisPropertySource{" + "namespace='" + namespace + '\'' + ", group='" + group + '\'' + ", fileName='" + fileName + '\'' + '}'; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceAutoRefresher.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceAutoRefresher.java index de0c474b4..fb673680e 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceAutoRefresher.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceAutoRefresher.java @@ -29,12 +29,10 @@ import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.BeansException; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.cloud.context.refresh.ContextRefresher; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationListener; +import org.springframework.lang.NonNull; import org.springframework.util.CollectionUtils; /** @@ -43,19 +41,14 @@ import org.springframework.util.CollectionUtils; * * @author lepdou 2022-03-28 */ -public class PolarisPropertySourceAutoRefresher - implements ApplicationListener, ApplicationContextAware { +public class PolarisPropertySourceAutoRefresher implements ApplicationListener { private static final Logger LOGGER = LoggerFactory.getLogger(PolarisPropertySourceAutoRefresher.class); private final PolarisConfigProperties polarisConfigProperties; private final PolarisPropertySourceManager polarisPropertySourceManager; - - private ApplicationContext applicationContext; - private final ContextRefresher contextRefresher; - private final AtomicBoolean registered = new AtomicBoolean(false); public PolarisPropertySourceAutoRefresher(PolarisConfigProperties polarisConfigProperties, @@ -66,12 +59,7 @@ public class PolarisPropertySourceAutoRefresher } @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - @Override - public void onApplicationEvent(ApplicationReadyEvent event) { + public void onApplicationEvent(@NonNull ApplicationReadyEvent event) { registerPolarisConfigPublishEvent(); } @@ -125,5 +113,4 @@ public class PolarisPropertySourceAutoRefresher }); } } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceManager.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceManager.java index 01caee959..f8736e20e 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceManager.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceManager.java @@ -39,5 +39,4 @@ public class PolarisPropertySourceManager { public List getAllPropertySources() { return new ArrayList<>(polarisPropertySources.values()); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigAnnotationProcessor.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigAnnotationProcessor.java index 349799f69..b6dbb2916 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigAnnotationProcessor.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigAnnotationProcessor.java @@ -101,5 +101,4 @@ public class PolarisConfigAnnotationProcessor implements BeanPostProcessor, Prio addChangeListener(configChangeListener, interestedKeys, interestedKeyPrefixes); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java index 6acbf2336..a324c4d78 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java @@ -38,7 +38,7 @@ public @interface PolarisConfigKVFileChangeListener { /** * The keys interested in the listener, will only be notified if any of the interested keys is changed. - *
+ *

* If neither of {@code interestedKeys} and {@code interestedKeyPrefixes} is specified then the {@code listener} will be notified when any key is changed. * @return interested keys in the listener */ @@ -49,10 +49,9 @@ public @interface PolarisConfigKVFileChangeListener { * The prefixes will simply be used to determine whether the {@code listener} should be notified or not using {@code changedKey.startsWith(prefix)}. * e.g. "spring." means that {@code listener} is interested in keys that starts with "spring.", such as "spring.banner", "spring.jpa", etc. * and "application" means that {@code listener} is interested in keys that starts with "application", such as "applicationName", "application.port", etc. - *
+ *

* If neither of {@code interestedKeys} and {@code interestedKeyPrefixes} is specified then the {@code listener} will be notified when whatever key is changed. * @return interested key-prefixed in the listener */ String[] interestedKeyPrefixes() default {}; - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/ConfigFileGroup.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/ConfigFileGroup.java index 05f1d7c5d..b52ffd13e 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/ConfigFileGroup.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/ConfigFileGroup.java @@ -56,5 +56,4 @@ public class ConfigFileGroup { public String toString() { return "ConfigFileGroup{" + "name='" + name + '\'' + ", file=" + files + '}'; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java index a2c9032fe..f39c5337f 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java @@ -94,5 +94,4 @@ public class PolarisConfigProperties { public void setGroups(List groups) { this.groups = groups; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpoint.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpoint.java new file mode 100644 index 000000000..ead47900a --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpoint.java @@ -0,0 +1,59 @@ +/* + * 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.config.endpoint; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySource; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; +import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; + +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; + +/** + * Endpoint of polaris config. + * + * @author shuiqingliu + **/ +@Endpoint(id = "polaris-config") +public class PolarisConfigEndpoint { + + private final PolarisConfigProperties polarisConfigProperties; + private final PolarisPropertySourceManager polarisPropertySourceManager; + + public PolarisConfigEndpoint(PolarisConfigProperties polarisConfigProperties, + PolarisPropertySourceManager polarisPropertySourceManager) { + this.polarisConfigProperties = polarisConfigProperties; + this.polarisPropertySourceManager = polarisPropertySourceManager; + } + + @ReadOperation + public Map polarisConfig() { + Map configInfo = new HashMap<>(); + configInfo.put("PolarisConfigProperties", polarisConfigProperties); + + List propertySourceList = polarisPropertySourceManager.getAllPropertySources(); + configInfo.put("PolarisPropertySource", propertySourceList); + + return configInfo; + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointAutoConfiguration.java new file mode 100644 index 000000000..c4d911e3f --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointAutoConfiguration.java @@ -0,0 +1,50 @@ +/* + * 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.config.endpoint; + +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; +import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * The AutoConfiguration for Polaris Config's endpoint. + * + * @author shuiqingliu + **/ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Endpoint.class) +@ConditionalOnProperty(value = "spring.cloud.polaris.config.enabled", + matchIfMissing = true) +public class PolarisConfigEndpointAutoConfiguration { + + @Bean + @ConditionalOnAvailableEndpoint + @ConditionalOnMissingBean + public PolarisConfigEndpoint polarisConfigEndpoint(PolarisConfigProperties polarisConfigProperties, + PolarisPropertySourceManager polarisPropertySourceManager) { + return new PolarisConfigEndpoint(polarisConfigProperties, polarisPropertySourceManager); + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/enums/ConfigFileFormat.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/enums/ConfigFileFormat.java index 2b7be5774..d7c7b590c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/enums/ConfigFileFormat.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/enums/ConfigFileFormat.java @@ -28,7 +28,7 @@ public enum ConfigFileFormat { /** * property format. */ - PROPERTY(".property"), + PROPERTY(".properties"), /** * yaml format. */ @@ -48,7 +48,7 @@ public enum ConfigFileFormat { /** * text format. */ - TEXT(".text"), + TEXT(".txt"), /** * html format. */ @@ -80,5 +80,4 @@ public enum ConfigFileFormat { } return true; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeEvent.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeEvent.java index 119a5ce4c..367740d8c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeEvent.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeEvent.java @@ -84,5 +84,4 @@ public final class ConfigChangeEvent { public Set interestedChangedKeys() { return interestedChangedKeys; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListener.java index 14ab64a32..1ff9d139c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListener.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListener.java @@ -31,5 +31,4 @@ public interface ConfigChangeListener { * @param changeEvent the event for this change */ void onChange(ConfigChangeEvent changeEvent); - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigChangeEventListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigChangeEventListener.java index 0a55255d5..378f69628 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigChangeEventListener.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigChangeEventListener.java @@ -107,5 +107,4 @@ public final class PolarisConfigChangeEventListener implements ApplicationListen }); return ret; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigListenerContext.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigListenerContext.java index 05ac41756..74e20fb9c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigListenerContext.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigListenerContext.java @@ -55,37 +55,34 @@ import static com.tencent.polaris.configuration.api.core.ChangeType.MODIFIED; * @author Palmer Xu 2022-06-06 */ public final class PolarisConfigListenerContext { - /** * Logger instance. */ private static final Logger LOG = LoggerFactory.getLogger(PolarisConfigListenerContext.class); - /** * Execute service Atomic Reference Cache . */ private static final AtomicReference EAR = new AtomicReference<>(); - /** * All custom {@link ConfigChangeListener} instance defined in application . */ private static final List listeners = Lists.newCopyOnWriteArrayList(); - /** * All custom interested keys defined in application . */ private static final Map> interestedKeys = Maps.newHashMap(); - /** * All custom interested key prefixes defined in application . */ private static final Map> interestedKeyPrefixes = Maps.newHashMap(); - /** * Cache all latest configuration information for users in the application environment . */ private static final Cache properties = CacheBuilder.newBuilder().build(); + private PolarisConfigListenerContext() { + } + /** * Get or Created new execute server . * @return execute service instance of {@link ExecutorService} @@ -273,5 +270,4 @@ public final class PolarisConfigListenerContext { return Collections.unmodifiableSet(interestedChangedKeys); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories index a0c33067e..98221a39a 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories @@ -1,4 +1,5 @@ org.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.tencent.cloud.polaris.config.PolarisConfigBootstrapAutoConfiguration org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.tencent.cloud.polaris.config.PolarisConfigAutoConfiguration + com.tencent.cloud.polaris.config.PolarisConfigAutoConfiguration,\ + com.tencent.cloud.polaris.config.endpoint.PolarisConfigEndpointAutoConfiguration diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java index 026fe4d52..59e89ebcc 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java @@ -31,7 +31,8 @@ import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeListener; /** * Mock config kv file for test. - *@author lepdou 2022-06-11 + * + * @author lepdou 2022-06-11 */ public class MockedConfigKVFile implements ConfigKVFile { diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java index 6fe0bfa2a..bfe1fc5d2 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java @@ -26,7 +26,7 @@ import java.util.Map; import com.google.common.collect.Lists; import com.tencent.cloud.polaris.config.config.ConfigFileGroup; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; -import com.tencent.cloud.polaris.context.PolarisContextProperties; +import com.tencent.cloud.polaris.context.config.PolarisContextProperties; import com.tencent.polaris.configuration.api.core.ConfigFileService; import com.tencent.polaris.configuration.api.core.ConfigKVFile; import org.junit.Assert; @@ -41,12 +41,15 @@ import org.springframework.core.env.PropertySource; import static org.mockito.Mockito.when; /** - * test for {@link PolarisConfigFileLocator} - *@author lepdou 2022-06-11 + * test for {@link PolarisConfigFileLocator}. + * + * @author lepdou 2022-06-11 */ @RunWith(MockitoJUnitRunner.class) public class PolarisConfigFileLocatorTest { + private final String testNamespace = "testNamespace"; + private final String testServiceName = "testServiceName"; @Mock private PolarisConfigProperties polarisConfigProperties; @Mock @@ -58,9 +61,6 @@ public class PolarisConfigFileLocatorTest { @Mock private Environment environment; - private final String testNamespace = "testNamespace"; - private final String testServiceName = "testServiceName"; - @Test public void testLoadApplicationPropertiesFile() { PolarisConfigFileLocator locator = new PolarisConfigFileLocator(polarisConfigProperties, polarisContextProperties, diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java index 648860f35..779ddfb47 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java @@ -38,12 +38,16 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** - * test for {@link PolarisPropertySourceAutoRefresher} - *@author lepdou 2022-06-11 + * test for {@link PolarisPropertySourceAutoRefresher}. + * + * @author lepdou 2022-06-11 */ @RunWith(MockitoJUnitRunner.class) public class PolarisPropertiesSourceAutoRefresherTest { + private final String testNamespace = "testNamespace"; + private final String testServiceName = "testServiceName"; + private final String testFileName = "application.properties"; @Mock private PolarisConfigProperties polarisConfigProperties; @Mock @@ -51,10 +55,6 @@ public class PolarisPropertiesSourceAutoRefresherTest { @Mock private ContextRefresher contextRefresher; - private final String testNamespace = "testNamespace"; - private final String testServiceName = "testServiceName"; - private final String testFileName = "application.properties"; - @Test public void testConfigFileChanged() { PolarisPropertySourceAutoRefresher refresher = new PolarisPropertySourceAutoRefresher(polarisConfigProperties, @@ -118,5 +118,4 @@ public class PolarisPropertiesSourceAutoRefresherTest { Assert.assertEquals("v1", polarisPropertySource.getProperty("k1")); verify(contextRefresher).refresh(); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointTest.java new file mode 100644 index 000000000..93190ee1a --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointTest.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.polaris.config.endpoint; + +import java.util.HashMap; +import java.util.Map; + +import com.google.common.collect.Lists; +import com.tencent.cloud.polaris.config.adapter.MockedConfigKVFile; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySource; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; +import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +/** + * Test for polaris config endpoint. + * + * @author shuiqingliu + */ +@RunWith(MockitoJUnitRunner.class) +public class PolarisConfigEndpointTest { + + private final String testNamespace = "testNamespace"; + private final String testServiceName = "testServiceName"; + private final String testFileName = "application.properties"; + + @Mock + private PolarisConfigProperties polarisConfigProperties; + @Mock + private PolarisPropertySourceManager polarisPropertySourceManager; + + @Test + public void testPolarisConfigEndpoint() { + Map content = new HashMap<>(); + content.put("k1", "v1"); + content.put("k2", "v2"); + content.put("k3", "v3"); + MockedConfigKVFile file = new MockedConfigKVFile(content); + PolarisPropertySource polarisPropertySource = new PolarisPropertySource(testNamespace, testServiceName, testFileName, + file, content); + when(polarisPropertySourceManager.getAllPropertySources()).thenReturn(Lists.newArrayList(polarisPropertySource)); + + PolarisConfigEndpoint endpoint = new PolarisConfigEndpoint(polarisConfigProperties, polarisPropertySourceManager); + Map info = endpoint.polarisConfig(); + assertThat(polarisConfigProperties).isEqualTo(info.get("PolarisConfigProperties")); + assertThat(Lists.newArrayList(polarisPropertySource)).isEqualTo(info.get("PolarisPropertySource")); + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListenerTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListenerTest.java index c408f4f54..84b5336d0 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListenerTest.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListenerTest.java @@ -18,10 +18,13 @@ package com.tencent.cloud.polaris.config.listener; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + import com.google.common.collect.Sets; import com.tencent.cloud.polaris.config.annotation.PolarisConfigKVFileChangeListener; import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo; -import org.junit.Assert; +import org.assertj.core.api.Assertions; import org.junit.Test; import org.junit.runner.RunWith; @@ -39,13 +42,13 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen /** * Integration testing for change listener. - *@author lepdou 2022-06-11 + * + * @author lepdou 2022-06-11 */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = DEFINED_PORT, classes = ConfigChangeListenerTest.TestApplication.class, - properties = {"server.port=8081", - "spring.config.location = classpath:application-test.yml"}) + properties = {"server.port=8081", "spring.config.location = classpath:application-test.yml"}) public class ConfigChangeListenerTest { @Autowired @@ -55,10 +58,12 @@ public class ConfigChangeListenerTest { @Autowired private TestApplication.TestConfig testConfig; + private static final CountDownLatch hits = new CountDownLatch(2); + @Test public void test() throws InterruptedException { //before change - Assert.assertEquals(1000, testConfig.getTimeout()); + Assertions.assertThat(testConfig.getTimeout()).isEqualTo(1000); //submit change event System.setProperty("timeout", "2000"); @@ -66,12 +71,14 @@ public class ConfigChangeListenerTest { Sets.newHashSet("timeout")); applicationEventPublisher.publishEvent(event); - Thread.sleep(200); + //after change - Assert.assertEquals(2, testConfig.getChangeCnt()); - Assert.assertEquals(2000, testConfig.getTimeout()); - } + boolean ret = hits.await(2, TimeUnit.SECONDS); + Assertions.assertThat(ret).isEqualTo(true); + Assertions.assertThat(testConfig.getChangeCnt()).isEqualTo(2); + Assertions.assertThat(testConfig.getTimeout()).isEqualTo(2000); + } @SpringBootApplication protected static class TestApplication { @@ -101,6 +108,7 @@ public class ConfigChangeListenerTest { ConfigPropertyChangeInfo changeInfo = event.getChange("timeout"); timeout = Integer.parseInt(changeInfo.getNewValue()); changeCnt++; + hits.countDown(); } @PolarisConfigKVFileChangeListener(interestedKeyPrefixes = {"timeout"}) @@ -108,6 +116,7 @@ public class ConfigChangeListenerTest { ConfigPropertyChangeInfo changeInfo = event.getChange("timeout"); timeout = Integer.parseInt(changeInfo.getNewValue()); changeCnt++; + hits.countDown(); } } @@ -120,5 +129,4 @@ public class ConfigChangeListenerTest { } } } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/pom.xml b/spring-cloud-starter-tencent-polaris-discovery/pom.xml index 523ce1b32..62ad96fb6 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/pom.xml +++ b/spring-cloud-starter-tencent-polaris-discovery/pom.xml @@ -94,6 +94,18 @@ test + + org.springframework.boot + spring-boot-actuator + true + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + io.projectreactor reactor-test diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java index 67690ef24..0512de81e 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java @@ -27,9 +27,9 @@ import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig; import org.springframework.beans.factory.annotation.Autowired; /** - * Spring Cloud Tencent config Override polaris config. + * Spring Cloud Tencent config Override polaris config. * - *@author lepdou 2022-04-24 + * @author lepdou 2022-04-24 */ public class DiscoveryConfigModifier implements PolarisConfigModifier { 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 720b10dd7..4eb2efd30 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 @@ -17,8 +17,6 @@ */ package com.tencent.cloud.polaris; -import javax.annotation.PostConstruct; - import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; @@ -28,7 +26,6 @@ import com.tencent.polaris.api.exception.PolarisException; import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.factory.api.DiscoveryAPIFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -41,19 +38,9 @@ import org.springframework.context.annotation.Import; */ @Configuration(proxyBeanMethods = false) @ConditionalOnPolarisEnabled -@Import({ PolarisDiscoveryProperties.class, ConsulContextProperties.class }) +@Import({PolarisDiscoveryProperties.class, ConsulContextProperties.class}) public class DiscoveryPropertiesAutoConfiguration { - @Autowired(required = false) - private PolarisDiscoveryProperties polarisDiscoveryProperties; - - @Autowired(required = false) - private ConsulContextProperties consulContextProperties; - - private boolean registerEnabled = false; - - private boolean discoveryEnabled = false; - @Bean @ConditionalOnMissingBean public ProviderAPI polarisProvider(SDKContext polarisContext) throws PolarisException { @@ -76,25 +63,4 @@ public class DiscoveryPropertiesAutoConfiguration { public DiscoveryConfigModifier discoveryConfigModifier() { return new DiscoveryConfigModifier(); } - - @PostConstruct - public void init() { - if (null != polarisDiscoveryProperties) { - registerEnabled |= polarisDiscoveryProperties.isRegisterEnabled(); - discoveryEnabled |= polarisDiscoveryProperties.isEnabled(); - } - if (null != consulContextProperties && consulContextProperties.isEnabled()) { - registerEnabled |= consulContextProperties.isRegister(); - discoveryEnabled |= consulContextProperties.isDiscoveryEnabled(); - } - } - - public boolean isRegisterEnabled() { - return registerEnabled; - } - - public boolean isDiscoveryEnabled() { - return discoveryEnabled; - } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java index 2de7d0140..a126a3ad2 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java @@ -29,7 +29,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; -import org.springframework.core.env.Environment; /** * Properties for Polaris. @@ -107,9 +106,6 @@ public class PolarisDiscoveryProperties { */ private Long serviceListRefreshInterval = 60000L; - @Autowired - private Environment environment; - public boolean isHeartbeatEnabled() { return heartbeatEnabled; } @@ -232,7 +228,7 @@ public class PolarisDiscoveryProperties { private static class PolarisDiscoveryConfigModifier implements PolarisConfigModifier { - private final String ID = "polaris"; + private static final String ID = "polaris"; @Autowired(required = false) private PolarisDiscoveryProperties polarisDiscoveryProperties; @@ -256,7 +252,5 @@ public class PolarisDiscoveryProperties { public int getOrder() { return ContextConstant.ModifierOrder.LAST; } - } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/client/PolarisClient.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/client/PolarisClient.java index 6ab0adbfb..dddf5279b 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/client/PolarisClient.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/client/PolarisClient.java @@ -46,5 +46,4 @@ public @interface PolarisClient { * @return namespace */ String namespace() default ""; - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java index 97f478683..82ae9d5d8 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java @@ -28,10 +28,12 @@ import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; import org.springframework.context.annotation.Conditional; /** + * Condition if Polaris discovery is enabled. + * * @author Haotian Zhang, Andrew Shan, Jie Cheng */ @Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE, ElementType.METHOD }) +@Target({ElementType.TYPE, ElementType.METHOD}) @ConditionalOnDiscoveryEnabled @ConditionalOnPolarisEnabled @Conditional(DiscoveryEnabledCondition.class) diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/DiscoveryEnabledCondition.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/DiscoveryEnabledCondition.java index 158673b23..1963537c2 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/DiscoveryEnabledCondition.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/DiscoveryEnabledCondition.java @@ -34,13 +34,12 @@ public class DiscoveryEnabledCondition implements Condition { boolean isDiscoveryEnabled = Boolean.parseBoolean( conditionContext.getEnvironment().getProperty("spring.cloud.polaris.discovery.enabled", "true")); - boolean isConsulDiscoveryEnabled = Boolean - .parseBoolean(conditionContext.getEnvironment().getProperty("spring.cloud.consul.enabled", "false")) - && Boolean.parseBoolean( - conditionContext.getEnvironment().getProperty("spring.cloud.consul.discovery.enabled", "true")); + boolean isConsulDiscoveryEnabled = Boolean.parseBoolean( + conditionContext.getEnvironment().getProperty("spring.cloud.consul.enabled", "false")) + && Boolean.parseBoolean(conditionContext.getEnvironment() + .getProperty("spring.cloud.consul.discovery.enabled", "true")); isDiscoveryEnabled |= isConsulDiscoveryEnabled; return isDiscoveryEnabled; } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java index cc8000f44..b92ca6259 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java @@ -43,5 +43,4 @@ public class PolarisDiscoveryAutoConfiguration { PolarisDiscoveryHandler polarisDiscoveryHandler) { return new PolarisServiceDiscovery(polarisDiscoveryHandler); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java index f07469807..80cf3afdf 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java @@ -54,5 +54,4 @@ public class PolarisDiscoveryClient implements DiscoveryClient { public List getServices() { return polarisServiceDiscovery.getServices(); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java index 3ed9eb60b..6b1ef7118 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java @@ -33,7 +33,7 @@ import org.springframework.context.annotation.Configuration; */ @Configuration(proxyBeanMethods = false) @ConditionalOnBlockingDiscoveryEnabled -@AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class, CommonsClientAutoConfiguration.class }) +@AutoConfigureBefore({SimpleDiscoveryClientAutoConfiguration.class, CommonsClientAutoConfiguration.class}) @AutoConfigureAfter(PolarisDiscoveryAutoConfiguration.class) public class PolarisDiscoveryClientConfiguration { @@ -41,5 +41,4 @@ public class PolarisDiscoveryClientConfiguration { public DiscoveryClient polarisDiscoveryClient(PolarisServiceDiscovery polarisServiceDiscovery) { return new PolarisDiscoveryClient(polarisServiceDiscovery); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java index e1691ea4e..2482c263d 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java @@ -61,7 +61,7 @@ public class PolarisDiscoveryHandler { GetHealthyInstancesRequest getHealthyInstancesRequest = new GetHealthyInstancesRequest(); getHealthyInstancesRequest.setNamespace(namespace); getHealthyInstancesRequest.setService(service); - return polarisConsumer.getHealthyInstancesInstance(getHealthyInstancesRequest); + return polarisConsumer.getHealthyInstances(getHealthyInstancesRequest); } /** @@ -95,5 +95,4 @@ public class PolarisDiscoveryHandler { request.setNamespace(namespace); return polarisConsumer.getServices(request); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java index 044af8634..771a3c57d 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java @@ -31,6 +31,8 @@ import com.tencent.polaris.api.rpc.InstancesResponse; import org.springframework.cloud.client.ServiceInstance; /** + * Polaris service discovery service. + * * @author Haotian Zhang, Andrew Shan, Jie Cheng */ public class PolarisServiceDiscovery { @@ -66,5 +68,4 @@ public class PolarisServiceDiscovery { return polarisDiscoveryHandler.GetServices().getServices().stream().map(ServiceInfo::getService) .collect(Collectors.toList()); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java index a7a0ec099..c5b7c8dfd 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java @@ -82,5 +82,4 @@ public class PolarisReactiveDiscoveryClient implements ReactiveDiscoveryClient { } }).subscribeOn(Schedulers.boundedElastic()); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java index 09928e208..ca3772aa9 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java @@ -36,9 +36,8 @@ import org.springframework.context.annotation.Configuration; */ @Configuration(proxyBeanMethods = false) @ConditionalOnReactiveDiscoveryEnabled -@AutoConfigureAfter({ PolarisDiscoveryAutoConfiguration.class, - ReactiveCompositeDiscoveryClientAutoConfiguration.class }) -@AutoConfigureBefore({ ReactiveCommonsClientAutoConfiguration.class }) +@AutoConfigureAfter({PolarisDiscoveryAutoConfiguration.class, ReactiveCompositeDiscoveryClientAutoConfiguration.class}) +@AutoConfigureBefore({ReactiveCommonsClientAutoConfiguration.class}) public class PolarisReactiveDiscoveryClientConfiguration { @Bean @@ -47,5 +46,4 @@ public class PolarisReactiveDiscoveryClientConfiguration { PolarisServiceDiscovery polarisServiceDiscovery) { return new PolarisReactiveDiscoveryClient(polarisServiceDiscovery); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java index 9591cb389..2acec7ecf 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java @@ -25,11 +25,13 @@ import com.tencent.polaris.client.util.NamedThreadFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.cloud.client.discovery.event.HeartbeatEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.ApplicationListener; +import org.springframework.lang.NonNull; import static com.tencent.cloud.polaris.discovery.refresh.PolarisServiceStatusChangeListener.INDEX; @@ -38,7 +40,8 @@ import static com.tencent.cloud.polaris.discovery.refresh.PolarisServiceStatusCh * * @author Haotian Zhang */ -public class PolarisRefreshApplicationReadyEventListener implements ApplicationListener, ApplicationEventPublisherAware { +public class PolarisRefreshApplicationReadyEventListener + implements ApplicationListener, ApplicationEventPublisherAware, DisposableBean { private static final Logger LOG = LoggerFactory.getLogger(PolarisRefreshApplicationReadyEventListener.class); private static final int DELAY = 60; @@ -80,7 +83,12 @@ public class PolarisRefreshApplicationReadyEventListener implements ApplicationL } @Override - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + public void setApplicationEventPublisher(@NonNull ApplicationEventPublisher applicationEventPublisher) { this.publisher = applicationEventPublisher; } + + @Override + public void destroy() throws Exception { + refreshExecutor.shutdown(); + } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListener.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListener.java index c923295d5..e64bb6b56 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListener.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListener.java @@ -32,10 +32,12 @@ import org.slf4j.LoggerFactory; import org.springframework.cloud.client.discovery.event.HeartbeatEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.lang.NonNull; import org.springframework.util.CollectionUtils; /** - * Change listener of Polaris service info. When service info is created or deleted, or, instance of service is from 0 to + * Change listener of Polaris service info. When service info is created or deleted, or, instance of service is from + * 0 to many. * * @author Haotian Zhang */ @@ -90,7 +92,7 @@ public class PolarisServiceStatusChangeListener extends AbstractResourceEventLis } @Override - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + public void setApplicationEventPublisher(@NonNull ApplicationEventPublisher applicationEventPublisher) { this.publisher = applicationEventPublisher; } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPoint.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPoint.java new file mode 100644 index 000000000..6c86ace33 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPoint.java @@ -0,0 +1,83 @@ +/* + * 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.endpoint; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; +import com.tencent.polaris.api.pojo.ServiceInstances; +import com.tencent.polaris.api.rpc.InstancesResponse; +import org.apache.commons.lang.StringUtils; + +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.actuate.endpoint.annotation.Selector; +import org.springframework.cloud.client.discovery.DiscoveryClient; + +/** + * Endpoint of polaris discovery, include discovery properties and service instance. + * + * @author shuiqingliu + */ +@Endpoint(id = "polaris-discovery") +public class PolarisDiscoveryEndPoint { + + private final PolarisDiscoveryProperties polarisDiscoveryProperties; + private final DiscoveryClient polarisDiscoveryClient; + private final PolarisDiscoveryHandler polarisDiscoveryHandler; + + public PolarisDiscoveryEndPoint(PolarisDiscoveryProperties polarisDiscoveryProperties, + DiscoveryClient polarisDiscoveryClient, PolarisDiscoveryHandler polarisDiscoveryHandler) { + this.polarisDiscoveryProperties = polarisDiscoveryProperties; + this.polarisDiscoveryClient = polarisDiscoveryClient; + this.polarisDiscoveryHandler = polarisDiscoveryHandler; + } + + @ReadOperation + public Map polarisDiscovery(@Selector String serviceId) { + Map polarisDiscoveryInfo = new HashMap<>(); + polarisDiscoveryInfo.put("PolarisDiscoveryProperties", polarisDiscoveryProperties); + + List serviceInstancesInfoList = new ArrayList<>(); + + if (StringUtils.isNotEmpty(serviceId)) { + ServiceInstances serviceInstances = getServiceInstances(serviceId); + serviceInstancesInfoList.add(serviceInstances); + polarisDiscoveryInfo.put("ServiceInstances", serviceInstancesInfoList); + return polarisDiscoveryInfo; + } + + for (String service : polarisDiscoveryClient.getServices()) { + ServiceInstances serviceInstances = getServiceInstances(service); + serviceInstancesInfoList.add(serviceInstances); + } + + polarisDiscoveryInfo.put("ServiceInstances", serviceInstancesInfoList); + return polarisDiscoveryInfo; + } + + private ServiceInstances getServiceInstances(String serviceId) { + InstancesResponse instancesResponse = polarisDiscoveryHandler.getHealthyInstances(serviceId); + ServiceInstances serviceInstances = instancesResponse.toServiceInstances(); + return serviceInstances; + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointAutoConfiguration.java new file mode 100644 index 000000000..d6b597634 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointAutoConfiguration.java @@ -0,0 +1,49 @@ +/* + * 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.endpoint; + +import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.discovery.ConditionalOnPolarisDiscoveryEnabled; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * The AutoConfiguration for Polaris Discovery's Endpoint. + * + * @author shuiqingliu + **/ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Endpoint.class) +@ConditionalOnPolarisDiscoveryEnabled +public class PolarisDiscoveryEndpointAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + public PolarisDiscoveryEndPoint polarisDiscoveryEndPoint(PolarisDiscoveryProperties polarisDiscoveryProperties, + DiscoveryClient discoveryClient, PolarisDiscoveryHandler polarisDiscoveryHandler) { + return new PolarisDiscoveryEndPoint(polarisDiscoveryProperties, discoveryClient, polarisDiscoveryHandler); + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulContextProperties.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulContextProperties.java index efddd036a..7c2e4ec1a 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulContextProperties.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulContextProperties.java @@ -113,7 +113,7 @@ public class ConsulContextProperties { private static class ConsulConfigModifier implements PolarisConfigModifier { - private final String ID = "consul"; + private static final String ID = "consul"; @Autowired(required = false) private ConsulContextProperties consulContextProperties; @@ -166,5 +166,4 @@ public class ConsulContextProperties { } } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/ConditionalOnPolarisRegisterEnabled.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/ConditionalOnPolarisRegisterEnabled.java index 440312cab..2d7391ff8 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/ConditionalOnPolarisRegisterEnabled.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/ConditionalOnPolarisRegisterEnabled.java @@ -27,10 +27,12 @@ import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import org.springframework.context.annotation.Conditional; /** + * Condition if Polaris registry is enabled. + * * @author Haotian Zhang, Andrew Shan, Jie Cheng */ @Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE, ElementType.METHOD }) +@Target({ElementType.TYPE, ElementType.METHOD}) @ConditionalOnPolarisEnabled @Conditional(RegisterEnabledCondition.class) public @interface ConditionalOnPolarisRegisterEnabled { diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java index b0996d9f3..591d4f177 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java @@ -93,5 +93,4 @@ public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistrat String appName = registration.getPolarisProperties().getService(); return StringUtils.isEmpty(appName) ? super.getAppName() : appName; } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java index ba018a658..d893836a6 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java @@ -24,15 +24,15 @@ import java.util.HashMap; import java.util.Map; import com.tencent.cloud.common.metadata.StaticMetadataManager; -import com.tencent.cloud.polaris.DiscoveryPropertiesAutoConfiguration; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; -import com.tencent.cloud.polaris.context.spi.InstanceMetadataProvider; +import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; import com.tencent.polaris.client.api.SDKContext; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; /** @@ -42,33 +42,29 @@ import org.springframework.util.CollectionUtils; */ public class PolarisRegistration implements Registration, ServiceInstance { - private final static String METADATA_KEY_IP = "internal-ip"; - private final static String METADATA_KEY_ADDRESS = "internal-address"; - - private final DiscoveryPropertiesAutoConfiguration discoveryPropertiesAutoConfiguration; + private static final String METADATA_KEY_IP = "internal-ip"; + private static final String METADATA_KEY_ADDRESS = "internal-address"; private final PolarisDiscoveryProperties polarisDiscoveryProperties; + private final ConsulContextProperties consulContextProperties; + private final SDKContext polarisContext; private final StaticMetadataManager staticMetadataManager; - private final InstanceMetadataProvider instanceMetadataProvider; - private Map metadata; private final String host; public PolarisRegistration( - DiscoveryPropertiesAutoConfiguration discoveryPropertiesAutoConfiguration, - PolarisDiscoveryProperties polarisDiscoveryProperties, SDKContext context, - StaticMetadataManager staticMetadataManager, - InstanceMetadataProvider instanceMetadataProvider) { - this.discoveryPropertiesAutoConfiguration = discoveryPropertiesAutoConfiguration; + PolarisDiscoveryProperties polarisDiscoveryProperties, + @Nullable ConsulContextProperties consulContextProperties, + SDKContext context, StaticMetadataManager staticMetadataManager) { this.polarisDiscoveryProperties = polarisDiscoveryProperties; + this.consulContextProperties = consulContextProperties; this.polarisContext = context; this.staticMetadataManager = staticMetadataManager; - this.instanceMetadataProvider = instanceMetadataProvider; host = polarisContext.getConfig().getGlobal().getAPI().getBindIP(); } @@ -116,23 +112,6 @@ public class PolarisRegistration implements Registration, ServiceInstance { // location info will be putted both in metadata and instance's field instanceMetadata.putAll(staticMetadataManager.getLocationMetadata()); - // custom metadata from spi - if (instanceMetadataProvider != null) { - if (StringUtils.isNotBlank(instanceMetadataProvider.getRegion())) { - instanceMetadata.put(StaticMetadataManager.LOCATION_KEY_ZONE, instanceMetadataProvider.getRegion()); - } - if (StringUtils.isNotBlank(instanceMetadataProvider.getZone())) { - instanceMetadata.put(StaticMetadataManager.LOCATION_KEY_ZONE, instanceMetadataProvider.getZone()); - } - if (StringUtils.isNotBlank(instanceMetadataProvider.getCampus())) { - instanceMetadata.put(StaticMetadataManager.LOCATION_KEY_ZONE, instanceMetadataProvider.getCampus()); - } - - if (!CollectionUtils.isEmpty(instanceMetadataProvider.getMetadata())) { - instanceMetadata.putAll(instanceMetadataProvider.getMetadata()); - } - } - this.metadata = Collections.unmodifiableMap(instanceMetadata); } return metadata; @@ -143,14 +122,23 @@ public class PolarisRegistration implements Registration, ServiceInstance { } public boolean isRegisterEnabled() { - return discoveryPropertiesAutoConfiguration.isRegisterEnabled(); + + boolean registerEnabled = false; + + if (null != polarisDiscoveryProperties) { + registerEnabled |= polarisDiscoveryProperties.isRegisterEnabled(); + } + if (null != consulContextProperties && consulContextProperties.isEnabled()) { + registerEnabled |= consulContextProperties.isRegister(); + } + + return registerEnabled; } @Override public String toString() { return "PolarisRegistration{" + - "discoveryPropertiesAutoConfiguration=" + discoveryPropertiesAutoConfiguration + - ", polarisDiscoveryProperties=" + polarisDiscoveryProperties + + "polarisDiscoveryProperties=" + polarisDiscoveryProperties + ", polarisContext=" + polarisContext + ", staticMetadataManager=" + staticMetadataManager + ", metadata=" + metadata + diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java index 69bedfbd8..225c146d8 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java @@ -220,5 +220,4 @@ public class PolarisServiceRegistry implements ServiceRegistry { } }, ttl, ttl, TimeUnit.SECONDS); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java index 01e4f2910..b5203f97c 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java @@ -19,13 +19,13 @@ package com.tencent.cloud.polaris.registry; import com.tencent.cloud.common.metadata.StaticMetadataManager; -import com.tencent.cloud.polaris.DiscoveryPropertiesAutoConfiguration; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; -import com.tencent.cloud.polaris.context.spi.InstanceMetadataProvider; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; +import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; import com.tencent.polaris.client.api.SDKContext; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -35,7 +35,6 @@ import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationC import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.lang.Nullable; /** * Autoconfiguration of service registry of Polaris. @@ -60,11 +59,10 @@ public class PolarisServiceRegistryAutoConfiguration { @Bean @ConditionalOnBean(AutoServiceRegistrationProperties.class) public PolarisRegistration polarisRegistration( - DiscoveryPropertiesAutoConfiguration discoveryPropertiesAutoConfiguration, - PolarisDiscoveryProperties polarisDiscoveryProperties, SDKContext context, - StaticMetadataManager staticMetadataManager, @Nullable InstanceMetadataProvider instanceMetadataProvider) { - return new PolarisRegistration(discoveryPropertiesAutoConfiguration, - polarisDiscoveryProperties, context, staticMetadataManager, instanceMetadataProvider); + PolarisDiscoveryProperties polarisDiscoveryProperties, + @Autowired(required = false) ConsulContextProperties consulContextProperties, + SDKContext context, StaticMetadataManager staticMetadataManager) { + return new PolarisRegistration(polarisDiscoveryProperties, consulContextProperties, context, staticMetadataManager); } @Bean diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/RegisterEnabledCondition.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/RegisterEnabledCondition.java index 2978a1feb..74c57edd4 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/RegisterEnabledCondition.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/RegisterEnabledCondition.java @@ -33,13 +33,12 @@ public class RegisterEnabledCondition implements Condition { boolean isRegisterEnabled = Boolean.parseBoolean( conditionContext.getEnvironment().getProperty("spring.cloud.polaris.discovery.register", "true")); - boolean isConsulRegisterEnabled = Boolean - .parseBoolean(conditionContext.getEnvironment().getProperty("spring.cloud.consul.enabled", "false")) + boolean isConsulRegisterEnabled = Boolean.parseBoolean( + conditionContext.getEnvironment().getProperty("spring.cloud.consul.enabled", "false")) && Boolean.parseBoolean(conditionContext.getEnvironment() - .getProperty("spring.cloud.consul.discovery.register", "true")); + .getProperty("spring.cloud.consul.discovery.register", "true")); isRegisterEnabled |= isConsulRegisterEnabled; return isRegisterEnabled; } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java index b07186839..68b9e335d 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java @@ -86,5 +86,4 @@ public final class OkHttpUtil { }); } } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories index 080de9947..4412276d8 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories @@ -1,6 +1,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.polaris.DiscoveryPropertiesAutoConfiguration,\ com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration,\ - com.tencent.cloud.polaris.registry.PolarisServiceRegistryAutoConfiguration + com.tencent.cloud.polaris.registry.PolarisServiceRegistryAutoConfiguration,\ + com.tencent.cloud.polaris.endpoint.PolarisDiscoveryEndpointAutoConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.tencent.cloud.polaris.DiscoveryPropertiesBootstrapAutoConfiguration diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java index b75d16d93..b053a673e 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java @@ -17,7 +17,7 @@ package com.tencent.cloud.polaris; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; import com.tencent.polaris.api.core.ConsumerAPI; @@ -65,9 +65,6 @@ public class DiscoveryPropertiesAutoConfigurationTest { .withPropertyValues("spring.cloud.consul.discovery.enabled=false"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(DiscoveryPropertiesAutoConfiguration.class); - DiscoveryPropertiesAutoConfiguration discoveryPropertiesAutoConfiguration = context.getBean(DiscoveryPropertiesAutoConfiguration.class); - assertThat(discoveryPropertiesAutoConfiguration.isRegisterEnabled()).isFalse(); - assertThat(discoveryPropertiesAutoConfiguration.isDiscoveryEnabled()).isFalse(); }); } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesBootstrapAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesBootstrapAutoConfigurationTest.java index 729c0a30a..3ef145d0e 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesBootstrapAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesBootstrapAutoConfigurationTest.java @@ -17,7 +17,7 @@ package com.tencent.cloud.polaris; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java index 970466391..6966d4f6e 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java @@ -19,7 +19,7 @@ package com.tencent.cloud.polaris.discovery; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.core.ProviderAPI; import com.tencent.polaris.test.mock.discovery.NamingServer; @@ -30,7 +30,6 @@ import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import static com.tencent.polaris.test.common.Consts.PORT; @@ -46,11 +45,14 @@ public class PolarisDiscoveryAutoConfigurationTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class, - PolarisDiscoveryAutoConfiguration.class, PolarisDiscoveryClientConfiguration.class, + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisDiscoveryAutoConfiguration.class, + PolarisDiscoveryClientConfiguration.class, PolarisContextAutoConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER).withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); @BeforeClass @@ -59,7 +61,7 @@ public class PolarisDiscoveryAutoConfigurationTest { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -77,9 +79,7 @@ public class PolarisDiscoveryAutoConfigurationTest { @Configuration @EnableAutoConfiguration - @EnableDiscoveryClient static class PolarisDiscoveryAutoConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java index 3e7dc0378..4a0667686 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java @@ -17,7 +17,7 @@ package com.tencent.cloud.polaris.discovery; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.polaris.test.mock.discovery.NamingServer; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -26,7 +26,6 @@ import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import static com.tencent.polaris.test.common.Consts.PORT; @@ -42,10 +41,13 @@ public class PolarisDiscoveryClientConfigurationTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class, - PolarisDiscoveryClientConfiguration.class, PolarisContextAutoConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER).withPropertyValues("server.port=" + PORT) + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisContextAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); @BeforeClass @@ -54,7 +56,7 @@ public class PolarisDiscoveryClientConfigurationTest { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -73,9 +75,7 @@ public class PolarisDiscoveryClientConfigurationTest { @Configuration @EnableAutoConfiguration - @EnableDiscoveryClient static class PolarisDiscoveryClientConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java index 78fe10ee6..d9c3eea29 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java @@ -19,7 +19,7 @@ package com.tencent.cloud.polaris.discovery; import java.util.List; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.polaris.api.exception.PolarisException; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.test.mock.discovery.NamingServer; @@ -32,7 +32,6 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; @@ -49,12 +48,15 @@ public class PolarisServiceDiscoveryTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class, + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, PolarisServiceDiscoveryTest.PolarisPropertiesConfiguration.class, - PolarisDiscoveryClientConfiguration.class, PolarisDiscoveryAutoConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisDiscoveryAutoConfiguration.class, PolarisContextAutoConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER).withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") .withPropertyValues("spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); @@ -73,7 +75,7 @@ public class PolarisServiceDiscoveryTest { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -104,9 +106,7 @@ public class PolarisServiceDiscoveryTest { @Configuration @EnableAutoConfiguration - @EnableDiscoveryClient static class PolarisPropertiesConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java index 3bca80f06..ecc67f27d 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java @@ -17,7 +17,7 @@ package com.tencent.cloud.polaris.discovery.reactive; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; import com.tencent.polaris.test.mock.discovery.NamingServer; import org.junit.AfterClass; @@ -27,7 +27,6 @@ import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import static com.tencent.polaris.test.common.Consts.PORT; @@ -43,11 +42,13 @@ public class PolarisReactiveDiscoveryClientConfigurationTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class, + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, PolarisReactiveDiscoveryClientConfiguration.class, PolarisDiscoveryClientConfiguration.class, PolarisContextAutoConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER).withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); @BeforeClass @@ -56,7 +57,7 @@ public class PolarisReactiveDiscoveryClientConfigurationTest { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -69,9 +70,7 @@ public class PolarisReactiveDiscoveryClientConfigurationTest { @Configuration @EnableAutoConfiguration - @EnableDiscoveryClient static class PolarisReactiveDiscoveryClientConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListenerTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListenerTest.java index e468a46ed..7366e210a 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListenerTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListenerTest.java @@ -64,7 +64,8 @@ public class PolarisServiceStatusChangeListenerTest { polarisServiceStatusChangeListener.setApplicationEventPublisher(publisher); // Service update event - ServiceEventKey serviceUpdateEventKey = new ServiceEventKey(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER), ServiceEventKey.EventType.SERVICE); + ServiceEventKey serviceUpdateEventKey = new ServiceEventKey( + new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER), ServiceEventKey.EventType.SERVICE); ServiceInfo serviceInfo = new ServiceInfo(); serviceInfo.setNamespace(NAMESPACE_TEST); serviceInfo.setService(SERVICE_PROVIDER); @@ -81,7 +82,8 @@ public class PolarisServiceStatusChangeListenerTest { // Instance update event - ServiceEventKey instanceUpdateEventKey = new ServiceEventKey(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER), ServiceEventKey.EventType.INSTANCE); + ServiceEventKey instanceUpdateEventKey = new ServiceEventKey( + new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER), ServiceEventKey.EventType.INSTANCE); DefaultInstance instance = new DefaultInstance(); instance.setNamespace(NAMESPACE_TEST); instance.setService(SERVICE_PROVIDER); @@ -96,7 +98,7 @@ public class PolarisServiceStatusChangeListenerTest { instances.set(oldInstances, Collections.emptyList()); ServiceInstancesByProto newInstances = new ServiceInstancesByProto(); instances.set(newInstances, Collections.singletonList(instance)); - polarisServiceStatusChangeListener.onResourceUpdated(serviceUpdateEventKey, oldInstances, newInstances); + polarisServiceStatusChangeListener.onResourceUpdated(instanceUpdateEventKey, oldInstances, newInstances); verify(publisher, times(2)).publishEvent(any(ApplicationEvent.class)); // No need update @@ -104,7 +106,7 @@ public class PolarisServiceStatusChangeListenerTest { instances.set(oldInstances, Collections.singletonList(instance)); newInstances = new ServiceInstancesByProto(); instances.set(newInstances, Collections.singletonList(instance)); - polarisServiceStatusChangeListener.onResourceUpdated(serviceUpdateEventKey, oldInstances, newInstances); + polarisServiceStatusChangeListener.onResourceUpdated(instanceUpdateEventKey, oldInstances, newInstances); verify(publisher, times(2)).publishEvent(any(ApplicationEvent.class)); } catch (NoSuchFieldException | IllegalAccessException e) { diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPointTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPointTest.java new file mode 100644 index 000000000..0fcba6a15 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPointTest.java @@ -0,0 +1,98 @@ +/* + * 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.endpoint; + +import java.util.Map; + +import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClient; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; +import com.tencent.polaris.test.mock.discovery.NamingServer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.context.annotation.Configuration; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.PORT; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for polaris discovery endpoint. + * + * @author shuiqingliu + */ +public class PolarisDiscoveryEndPointTest { + + private static NamingServer namingServer; + + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisDiscoveryEndPointTest.PolarisPropertiesConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisDiscoveryAutoConfiguration.class, + PolarisDiscoveryEndpointAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") + .withPropertyValues("spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) + .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); + + @BeforeClass + public static void beforeClass() throws Exception { + namingServer = NamingServer.startNamingServer(10081); + } + + @AfterClass + public static void afterClass() { + if (null != namingServer) { + namingServer.terminate(); + } + } + + @Test + public void testPolarisDiscoveryEndpoint() { + this.contextRunner.run(context -> { + PolarisDiscoveryProperties polarisDiscoveryProperties = context + .getBean(PolarisDiscoveryProperties.class); + DiscoveryClient discoveryClient = context + .getBean(PolarisDiscoveryClient.class); + PolarisDiscoveryHandler polarisDiscoveryHandler = context.getBean(PolarisDiscoveryHandler.class); + PolarisDiscoveryEndPoint polarisDiscoveryEndPoint = + new PolarisDiscoveryEndPoint(polarisDiscoveryProperties, discoveryClient, polarisDiscoveryHandler); + + Map mapInfo = polarisDiscoveryEndPoint.polarisDiscovery("java_provider_test"); + + assertThat(polarisDiscoveryProperties).isEqualTo(mapInfo.get("PolarisDiscoveryProperties")); + }); + } + + @Configuration + @EnableAutoConfiguration + static class PolarisPropertiesConfiguration { + + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java index 26aaf8efa..1414b3d27 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java @@ -140,5 +140,4 @@ public class PolarisAutoServiceRegistrationTest { doReturn(SERVICE_PROVIDER).when(polarisDiscoveryProperties).getService(); assertThat(polarisAutoServiceRegistration.getAppName()).isEqualTo(SERVICE_PROVIDER); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java index 11d380a75..bcbaa35ce 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java @@ -21,8 +21,8 @@ import java.util.Collections; import java.util.Map; import com.tencent.cloud.common.metadata.StaticMetadataManager; -import com.tencent.cloud.polaris.DiscoveryPropertiesAutoConfiguration; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; import com.tencent.polaris.api.config.Configuration; import com.tencent.polaris.api.config.global.APIConfig; import com.tencent.polaris.api.config.global.GlobalConfig; @@ -51,16 +51,15 @@ public class PolarisRegistrationTest { @Before public void setUp() { - // mock DiscoveryPropertiesAutoConfiguration - DiscoveryPropertiesAutoConfiguration discoveryPropertiesAutoConfiguration = - mock(DiscoveryPropertiesAutoConfiguration.class); - doReturn(true).when(discoveryPropertiesAutoConfiguration).isRegisterEnabled(); - // mock PolarisDiscoveryProperties PolarisDiscoveryProperties polarisDiscoveryProperties = mock(PolarisDiscoveryProperties.class); doReturn(SERVICE_PROVIDER).when(polarisDiscoveryProperties).getService(); doReturn(PORT).when(polarisDiscoveryProperties).getPort(); doReturn("http").when(polarisDiscoveryProperties).getProtocol(); + doReturn(true).when(polarisDiscoveryProperties).isRegisterEnabled(); + + // mock + ConsulContextProperties consulContextProperties = mock(ConsulContextProperties.class); // mock SDKContext APIConfig apiConfig = mock(APIConfig.class); @@ -77,8 +76,8 @@ public class PolarisRegistrationTest { doReturn(Collections.singletonMap("key1", "value1")).when(staticMetadataManager).getMergedStaticMetadata(); doReturn(Collections.singletonMap("key2", "value2")).when(staticMetadataManager).getLocationMetadata(); - polarisRegistration = new PolarisRegistration( - discoveryPropertiesAutoConfiguration, polarisDiscoveryProperties, polarisContext, staticMetadataManager, null); + polarisRegistration = new PolarisRegistration(polarisDiscoveryProperties, consulContextProperties, + polarisContext, staticMetadataManager); } @Test diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java index 7a59e405f..9535e4fb4 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java @@ -17,7 +17,7 @@ package com.tencent.cloud.polaris.registry; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; import com.tencent.polaris.test.mock.discovery.NamingServer; @@ -28,7 +28,6 @@ import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration; import org.springframework.context.annotation.Configuration; @@ -45,10 +44,13 @@ public class PolarisServiceRegistryAutoConfigurationTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class, - PolarisServiceRegistryAutoConfiguration.class, PolarisDiscoveryClientConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER).withPropertyValues("server.port=" + PORT) + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisServiceRegistryAutoConfiguration.class, + PolarisDiscoveryClientConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); @BeforeClass @@ -57,7 +59,7 @@ public class PolarisServiceRegistryAutoConfigurationTest { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -73,9 +75,7 @@ public class PolarisServiceRegistryAutoConfigurationTest { @Configuration @EnableAutoConfiguration - @EnableDiscoveryClient static class PolarisServiceRegistryAutoConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java index 02fff38f4..a37b1ec93 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java @@ -17,7 +17,7 @@ package com.tencent.cloud.polaris.registry; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; import com.tencent.polaris.api.pojo.ServiceKey; @@ -49,11 +49,14 @@ public class PolarisServiceRegistryTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisContextAutoConfiguration.class, PolarisPropertiesConfiguration.class, - PolarisDiscoveryClientConfiguration.class, PolarisDiscoveryAutoConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER).withPropertyValues("server.port=" + PORT) + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisPropertiesConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisDiscoveryAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") .withPropertyValues("spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); @@ -67,7 +70,7 @@ public class PolarisServiceRegistryTest { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -126,5 +129,4 @@ public class PolarisServiceRegistryTest { static class PolarisPropertiesConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml index 5f19b26ef..138eb41a6 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml +++ b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml @@ -84,6 +84,18 @@ test + + org.springframework.boot + spring-boot-actuator + true + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + org.mockito mockito-inline diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java index 01dd591dc..a9dd140e5 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java @@ -19,8 +19,8 @@ package com.tencent.cloud.polaris.ratelimit.config; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.ratelimit.RateLimitRuleLabelResolver; import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant; import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckReactiveFilter; @@ -40,6 +40,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.lang.Nullable; +import static com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter.QUOTA_FILTER_BEAN_NAME; import static javax.servlet.DispatcherType.ASYNC; import static javax.servlet.DispatcherType.ERROR; import static javax.servlet.DispatcherType.FORWARD; @@ -51,7 +52,7 @@ import static javax.servlet.DispatcherType.REQUEST; * * @author Haotian Zhang */ -@Configuration +@Configuration(proxyBeanMethods = false) @ConditionalOnPolarisEnabled @AutoConfigureAfter(PolarisContextAutoConfiguration.class) @ConditionalOnProperty(name = "spring.cloud.polaris.ratelimit.enabled", matchIfMissing = true) @@ -71,9 +72,9 @@ public class PolarisRateLimitAutoConfiguration { /** * Create when web application type is SERVLET. */ - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) - static class QuotaCheckFilterConfig { + protected static class QuotaCheckFilterConfig { @Bean @ConditionalOnMissingBean @@ -91,19 +92,18 @@ public class PolarisRateLimitAutoConfiguration { FilterRegistrationBean registrationBean = new FilterRegistrationBean<>( quotaCheckServletFilter); registrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST); - registrationBean.setName("quotaFilterRegistrationBean"); + registrationBean.setName(QUOTA_FILTER_BEAN_NAME); registrationBean.setOrder(RateLimitConstant.FILTER_ORDER); return registrationBean; } - } /** * Create when web application type is REACTIVE. */ - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) - static class MetadataReactiveFilterConfig { + protected static class MetadataReactiveFilterConfig { @Bean public QuotaCheckReactiveFilter quotaCheckReactiveFilter(LimitAPI limitAPI, @@ -113,7 +113,5 @@ public class PolarisRateLimitAutoConfiguration { return new QuotaCheckReactiveFilter(limitAPI, labelResolver, polarisRateLimitProperties, rateLimitRuleLabelResolver); } - } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/RateLimitConfigModifier.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/RateLimitConfigModifier.java index b0c097a68..9f0223689 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/RateLimitConfigModifier.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/RateLimitConfigModifier.java @@ -28,7 +28,7 @@ import com.tencent.polaris.factory.config.ConfigurationImpl; */ public class RateLimitConfigModifier implements PolarisConfigModifier { - private PolarisRateLimitProperties polarisRateLimitProperties; + private final PolarisRateLimitProperties polarisRateLimitProperties; public RateLimitConfigModifier(PolarisRateLimitProperties polarisRateLimitProperties) { this.polarisRateLimitProperties = polarisRateLimitProperties; diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java index 814134527..22f11ed04 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java @@ -44,5 +44,4 @@ public final class RateLimitConstant { private RateLimitConstant() { } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpoint.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpoint.java new file mode 100644 index 000000000..3ea4f5af8 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpoint.java @@ -0,0 +1,100 @@ +/* + * 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.ratelimit.endpoint; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties; +import com.tencent.polaris.client.pb.RateLimitProto; +import com.tencent.polaris.client.pb.RoutingProto; +import org.apache.commons.lang.StringUtils; + +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.actuate.endpoint.annotation.Selector; +import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; + +/** + * Endpoint of Polaris RateLimit rule. + * + * @author shuiqingliu + **/ +@Endpoint(id = "polaris-ratelimit") +public class PolarisRateLimitRuleEndpoint { + + private final ServiceRuleManager serviceRuleManager; + private final PolarisRateLimitProperties polarisRateLimitProperties; + + public PolarisRateLimitRuleEndpoint(ServiceRuleManager serviceRuleManager, PolarisRateLimitProperties polarisRateLimitProperties) { + this.serviceRuleManager = serviceRuleManager; + this.polarisRateLimitProperties = polarisRateLimitProperties; + } + + @ReadOperation + public Map rateLimit(@Selector String namespace, @Selector String service, @Nullable String dstService) { + Map result = new HashMap<>(); + RateLimitProto.RateLimit rateLimit = serviceRuleManager.getServiceRateLimitRule(namespace, service); + result.put("properties", polarisRateLimitProperties); + result.put("namespace", namespace); + result.put("service", service); + result.put("rateLimits", parseRateLimitRule(rateLimit)); + + if (StringUtils.isEmpty(dstService)) { + return result; + } + List routes = serviceRuleManager.getServiceRouterRule(namespace, service, dstService); + result.put("routes", routes); + return result; + } + + private List parseRateLimitRule(RateLimitProto.RateLimit rateLimit) { + List rateLimitRule = new ArrayList<>(); + if (rateLimit == null || CollectionUtils.isEmpty(rateLimit.getRulesList())) { + return rateLimitRule; + } + + for (RateLimitProto.Rule rule : rateLimit.getRulesList()) { + Map ruleMap = new HashMap<>(); + ruleMap.put("id", rule.getId()); + ruleMap.put("priority", rule.getPriority()); + ruleMap.put("resource", rule.getResource()); + ruleMap.put("type", rule.getType()); + ruleMap.put("labels", rule.getLabelsMap()); + ruleMap.put("amounts", rule.getAmountsList()); + ruleMap.put("action", rule.getAction()); + ruleMap.put("disable", rule.getDisable()); + ruleMap.put("report", rule.getReport()); + ruleMap.put("create_time", rule.getCtime()); + ruleMap.put("modify_time", rule.getMtime()); + ruleMap.put("revision", rule.getRevision()); + ruleMap.put("service_token", rule.getServiceToken()); + ruleMap.put("adjuster", rule.getAdjuster()); + ruleMap.put("regex_combine", rule.getRegexCombine()); + ruleMap.put("amount_mode", rule.getAmountMode()); + ruleMap.put("failover", rule.getFailover()); + ruleMap.put("cluster", rule.getCluster()); + rateLimitRule.add(ruleMap); + } + return rateLimitRule; + } +} diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointAutoConfiguration.java new file mode 100644 index 000000000..de5b6bfe4 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointAutoConfiguration.java @@ -0,0 +1,49 @@ +/* + * 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.ratelimit.endpoint; + +import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; +import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * The AutoConfiguration for Polaris RateLimit endpoint. + * + * @author shuiqingliu + **/ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Endpoint.class) +@ConditionalOnPolarisEnabled +@ConditionalOnProperty(name = "spring.cloud.polaris.ratelimit.enabled", matchIfMissing = true) +public class PolarisRateLimitRuleEndpointAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + public PolarisRateLimitRuleEndpoint polarisRateLimitRuleEndpoint(ServiceRuleManager serviceRuleManager, PolarisRateLimitProperties properties) { + return new PolarisRateLimitRuleEndpoint(serviceRuleManager, properties); + } +} diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java index 8796fc1ab..fb547bb55 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java @@ -19,6 +19,7 @@ package com.tencent.cloud.polaris.ratelimit.filter; import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -55,7 +56,7 @@ import static com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant.LAB /** * Reactive filter to check quota. * - * @author Haotian Zhang, lepdou, cheese8 + * @author Haotian Zhang, lepdou, cheese8, kaiy */ public class QuotaCheckReactiveFilter implements WebFilter, Ordered { @@ -113,7 +114,7 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered { } // Unirate if (quotaResponse.getCode() == QuotaResultCode.QuotaResultOk && quotaResponse.getWaitMs() > 0) { - Thread.sleep(quotaResponse.getWaitMs()); + return Mono.delay(Duration.ofMillis(quotaResponse.getWaitMs())).flatMap(e -> chain.filter(exchange)); } } catch (Throwable t) { @@ -161,5 +162,4 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered { Set expressionLabels = rateLimitRuleLabelResolver.getExpressionLabelKeys(namespace, service); return ExpressionLabelUtils.resolve(exchange, expressionLabels); } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java index f3e4c3b07..efe9e1c67 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java @@ -60,6 +60,11 @@ public class QuotaCheckServletFilter extends OncePerRequestFilter { private static final Logger LOG = LoggerFactory.getLogger(QuotaCheckServletFilter.class); + /** + * Default Filter Registration Bean Name Defined . + */ + public static final String QUOTA_FILTER_BEAN_NAME = "quotaFilterRegistrationBean"; + private final LimitAPI limitAPI; private final PolarisRateLimiterLabelServletResolver labelResolver; @@ -105,6 +110,7 @@ public class QuotaCheckServletFilter extends OncePerRequestFilter { } // Unirate if (quotaResponse.getCode() == QuotaResultCode.QuotaResultOk && quotaResponse.getWaitMs() > 0) { + LOG.debug("Unirate sleep for {}ms.", quotaResponse.getWaitMs()); Thread.sleep(quotaResponse.getWaitMs()); } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelReactiveResolver.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelReactiveResolver.java index 4ebcc1921..818769bfd 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelReactiveResolver.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelReactiveResolver.java @@ -31,9 +31,9 @@ public interface PolarisRateLimiterLabelReactiveResolver { /** * Resolve custom label from request. + * * @param exchange the http request * @return resolved labels */ Map resolve(ServerWebExchange exchange); - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelServletResolver.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelServletResolver.java index 253b67b5c..8fe859092 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelServletResolver.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelServletResolver.java @@ -31,6 +31,7 @@ public interface PolarisRateLimiterLabelServletResolver { /** * Resolve custom label from request. + * * @param request the http request * @return resolved labels */ diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java index 6f18b8586..ff08fe34d 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java @@ -55,5 +55,4 @@ public final class QuotaCheckUtils { return new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultOk, 0, "get quota failed")); } } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java index 334035dc5..f55cea3a6 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java @@ -36,7 +36,6 @@ public final class RateLimitUtils { private static final Logger LOG = LoggerFactory.getLogger(RateLimitUtils.class); private RateLimitUtils() { - } public static String getRejectTips(PolarisRateLimitProperties polarisRateLimitProperties) { @@ -63,5 +62,4 @@ public final class RateLimitUtils { return RateLimitConstant.QUOTA_LIMITED_INFO; } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories index 4abd34766..563704410 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories @@ -1,5 +1,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitAutoConfiguration,\ - com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitPropertiesAutoConfiguration + com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitPropertiesAutoConfiguration,\ + com.tencent.cloud.polaris.ratelimit.endpoint.PolarisRateLimitRuleEndpointAutoConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitPropertiesBootstrapConfiguration diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolverTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolverTest.java index 73d39dade..96b73cea9 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolverTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolverTest.java @@ -42,13 +42,11 @@ import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class RateLimitRuleLabelResolverTest { - private ServiceRuleManager serviceRuleManager; - private RateLimitRuleLabelResolver rateLimitRuleLabelResolver; @Before public void setUp() { - serviceRuleManager = mock(ServiceRuleManager.class); + ServiceRuleManager serviceRuleManager = mock(ServiceRuleManager.class); when(serviceRuleManager.getServiceRateLimitRule(any(), anyString())).thenAnswer(invocationOnMock -> { String serviceName = invocationOnMock.getArgument(1).toString(); if (serviceName.equals("TestApp1")) { diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java index a531d81a8..52ac38b4c 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java @@ -17,7 +17,7 @@ package com.tencent.cloud.polaris.ratelimit.config; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.ratelimit.RateLimitRuleLabelResolver; import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckReactiveFilter; import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter; @@ -39,11 +39,12 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisRateLimitAutoConfigurationTest { - private ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); + private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); - private WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner(); + private final WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner(); - private ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = new ReactiveWebApplicationContextRunner(); + private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = + new ReactiveWebApplicationContextRunner(); @Test public void testNoWebApplication() { diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesAutoConfigurationTest.java index 258dd557b..f3130ed7a 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesAutoConfigurationTest.java @@ -31,9 +31,8 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisRateLimitPropertiesAutoConfigurationTest { - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisRateLimitPropertiesAutoConfiguration.class)); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisRateLimitPropertiesAutoConfiguration.class)); @Test public void testDefaultInitialization() { diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesBootstrapConfigurationTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesBootstrapConfigurationTest.java index 71e7334cc..90c88f98c 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesBootstrapConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesBootstrapConfigurationTest.java @@ -31,9 +31,8 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisRateLimitPropertiesBootstrapConfigurationTest { - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisRateLimitPropertiesBootstrapConfiguration.class)) + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisRateLimitPropertiesBootstrapConfiguration.class)) .withPropertyValues("spring.cloud.polaris.enabled=true"); @Test diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java index 3c1ff283c..3051916b0 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java @@ -56,9 +56,9 @@ import static org.mockito.Mockito.when; */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - classes = { CalleeControllerTests.Config.class, TestController.class }, - properties = { "spring.application.name=java_provider_test", "spring.cloud.polaris.discovery.namespace=Test", - "spring.cloud.polaris.address=grpc://127.0.0.1:10081" }) + classes = {CalleeControllerTests.Config.class, TestController.class}, + properties = {"spring.application.name=java_provider_test", "spring.cloud.polaris.discovery.namespace=Test", + "spring.cloud.polaris.address=grpc://127.0.0.1:10081"}) public class CalleeControllerTests { private static NamingServer namingServer; @@ -86,7 +86,7 @@ public class CalleeControllerTests { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -142,5 +142,4 @@ public class CalleeControllerTests { } } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java index 1ede96b48..234b9507f 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java @@ -34,5 +34,4 @@ public class TestController { public String info() throws Exception { return "hello service info"; } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointTests.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointTests.java new file mode 100644 index 000000000..eda08c489 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointTests.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.polaris.ratelimit.endpoint; + +import java.util.Map; + +import com.google.protobuf.StringValue; +import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties; +import com.tencent.polaris.client.pb.ModelProto; +import com.tencent.polaris.client.pb.RateLimitProto; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Configuration; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.PORT; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Test for polaris rete limit rule endpoint. + * + * @author shuiqingliu + */ +@RunWith(MockitoJUnitRunner.class) +public class PolarisRateLimitRuleEndpointTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisRateLimitRuleEndpointTests.PolarisRateLimitAutoConfiguration.class, + PolarisRateLimitRuleEndpointAutoConfiguration.class, + PolarisRateLimitAutoConfiguration.class, + PolarisRateLimitAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") + .withPropertyValues("spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) + .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); + + private ServiceRuleManager serviceRuleManager; + private PolarisRateLimitProperties polarisRateLimitProperties; + + @Before + public void setUp() { + serviceRuleManager = mock(ServiceRuleManager.class); + when(serviceRuleManager.getServiceRateLimitRule(any(), anyString())).thenAnswer(invocationOnMock -> { + String serviceName = invocationOnMock.getArgument(1).toString(); + if (serviceName.equals("TestApp1")) { + return null; + } + else if (serviceName.equals("TestApp2")) { + return RateLimitProto.RateLimit.newBuilder().build(); + } + else if (serviceName.equals("TestApp3")) { + RateLimitProto.Rule rule = RateLimitProto.Rule.newBuilder().build(); + return RateLimitProto.RateLimit.newBuilder().addRules(rule).build(); + } + else { + ModelProto.MatchString matchString = ModelProto.MatchString.newBuilder() + .setType(ModelProto.MatchString.MatchStringType.EXACT) + .setValue(StringValue.of("value")) + .setValueType(ModelProto.MatchString.ValueType.TEXT).build(); + RateLimitProto.Rule rule = RateLimitProto.Rule.newBuilder() + .putLabels("${http.method}", matchString).build(); + return RateLimitProto.RateLimit.newBuilder().addRules(rule).build(); + } + }); + } + + @Test + public void testPolarisRateLimit() { + this.contextRunner.run(context -> polarisRateLimitProperties = context.getBean(PolarisRateLimitProperties.class)); + PolarisRateLimitRuleEndpoint polarisRateLimitRuleEndpoint = new PolarisRateLimitRuleEndpoint(serviceRuleManager, polarisRateLimitProperties); + Map rateLimit = polarisRateLimitRuleEndpoint.rateLimit("namespaceTest", "TestApp2", "TestApp3"); + assertThat(polarisRateLimitProperties).isEqualTo(rateLimit.get("properties")); + } + + @Configuration + @EnableAutoConfiguration + static class PolarisRateLimitAutoConfiguration { + + } +} diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java index 0a9a4988f..b640ce689 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java @@ -22,6 +22,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collections; import java.util.Map; +import java.util.concurrent.CountDownLatch; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.util.ApplicationContextAwareUtils; @@ -65,7 +66,7 @@ import static org.mockito.Mockito.when; /** * Test for {@link QuotaCheckReactiveFilter}. * - * @author Haotian Zhang, cheese8 + * @author Haotian Zhang, cheese8, kaiy */ @RunWith(MockitoJUnitRunner.class) @SpringBootTest(classes = QuotaCheckReactiveFilterTest.TestApplication.class, properties = { @@ -73,17 +74,17 @@ import static org.mockito.Mockito.when; }) public class QuotaCheckReactiveFilterTest { - private PolarisRateLimiterLabelReactiveResolver labelResolver = exchange -> Collections.singletonMap("ReactiveResolver", "ReactiveResolver"); - - private QuotaCheckReactiveFilter quotaCheckReactiveFilter; - private static MockedStatic mockedApplicationContextAwareUtils; private static MockedStatic expressionLabelUtilsMockedStatic; + private final PolarisRateLimiterLabelReactiveResolver labelResolver = + exchange -> Collections.singletonMap("ReactiveResolver", "ReactiveResolver"); + private QuotaCheckReactiveFilter quotaCheckReactiveFilter; @BeforeClass public static void beforeClass() { expressionLabelUtilsMockedStatic = mockStatic(ExpressionLabelUtils.class); - when(ExpressionLabelUtils.resolve(any(ServerWebExchange.class), anySet())).thenReturn(Collections.singletonMap("RuleLabelResolver", "RuleLabelResolver")); + when(ExpressionLabelUtils.resolve(any(ServerWebExchange.class), anySet())) + .thenReturn(Collections.singletonMap("RuleLabelResolver", "RuleLabelResolver")); mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) @@ -122,7 +123,7 @@ public class QuotaCheckReactiveFilterTest { polarisRateLimitProperties.setRejectHttpCode(419); RateLimitRuleLabelResolver rateLimitRuleLabelResolver = mock(RateLimitRuleLabelResolver.class); - when(rateLimitRuleLabelResolver.getExpressionLabelKeys(anyString(), anyString())).thenReturn(Collections.EMPTY_SET); + when(rateLimitRuleLabelResolver.getExpressionLabelKeys(anyString(), anyString())).thenReturn(Collections.emptySet()); this.quotaCheckReactiveFilter = new QuotaCheckReactiveFilter(limitAPI, labelResolver, polarisRateLimitProperties, rateLimitRuleLabelResolver); } @@ -201,7 +202,16 @@ public class QuotaCheckReactiveFilterTest { // Unirate waiting 1000ms MetadataContext.LOCAL_SERVICE = "TestApp2"; long startTimestamp = System.currentTimeMillis(); - quotaCheckReactiveFilter.filter(exchange, webFilterChain); + CountDownLatch countDownLatch = new CountDownLatch(1); + quotaCheckReactiveFilter.filter(exchange, webFilterChain).subscribe(e -> { + }, t -> { + }, countDownLatch::countDown); + try { + countDownLatch.await(); + } + catch (InterruptedException e) { + fail("Exception encountered.", e); + } assertThat(System.currentTimeMillis() - startTimestamp).isGreaterThanOrEqualTo(1000L); // Rate limited diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java index 3f93f0a3b..b5a0a62fd 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java @@ -73,18 +73,18 @@ import static org.mockito.Mockito.when; }) public class QuotaCheckServletFilterTest { - private PolarisRateLimiterLabelServletResolver labelResolver = exchange -> Collections.singletonMap("ServletResolver", "ServletResolver"); - + private static MockedStatic mockedApplicationContextAwareUtils; + private static MockedStatic expressionLabelUtilsMockedStatic; + private final PolarisRateLimiterLabelServletResolver labelResolver = + exchange -> Collections.singletonMap("ServletResolver", "ServletResolver"); private QuotaCheckServletFilter quotaCheckServletFilter; - private QuotaCheckServletFilter quotaCheckWithHtmlRejectTipsServletFilter; - private static MockedStatic mockedApplicationContextAwareUtils; - private static MockedStatic expressionLabelUtilsMockedStatic; @BeforeClass public static void beforeClass() { expressionLabelUtilsMockedStatic = mockStatic(ExpressionLabelUtils.class); - when(ExpressionLabelUtils.resolve(any(ServerWebExchange.class), anySet())).thenReturn(Collections.singletonMap("RuleLabelResolver", "RuleLabelResolver")); + when(ExpressionLabelUtils.resolve(any(ServerWebExchange.class), anySet())) + .thenReturn(Collections.singletonMap("RuleLabelResolver", "RuleLabelResolver")); mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) @@ -92,7 +92,7 @@ public class QuotaCheckServletFilterTest { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { mockedApplicationContextAwareUtils.close(); expressionLabelUtilsMockedStatic.close(); } @@ -127,10 +127,12 @@ public class QuotaCheckServletFilterTest { polarisRateLimitWithHtmlRejectTipsProperties.setRejectHttpCode(419); RateLimitRuleLabelResolver rateLimitRuleLabelResolver = mock(RateLimitRuleLabelResolver.class); - when(rateLimitRuleLabelResolver.getExpressionLabelKeys(anyString(), anyString())).thenReturn(Collections.EMPTY_SET); + when(rateLimitRuleLabelResolver.getExpressionLabelKeys(anyString(), anyString())).thenReturn(Collections.emptySet()); - this.quotaCheckServletFilter = new QuotaCheckServletFilter(limitAPI, labelResolver, polarisRateLimitProperties, rateLimitRuleLabelResolver); - this.quotaCheckWithHtmlRejectTipsServletFilter = new QuotaCheckServletFilter(limitAPI, labelResolver, polarisRateLimitWithHtmlRejectTipsProperties, rateLimitRuleLabelResolver); + this.quotaCheckServletFilter = + new QuotaCheckServletFilter(limitAPI, labelResolver, polarisRateLimitProperties, rateLimitRuleLabelResolver); + this.quotaCheckWithHtmlRejectTipsServletFilter = + new QuotaCheckServletFilter(limitAPI, labelResolver, polarisRateLimitWithHtmlRejectTipsProperties, rateLimitRuleLabelResolver); } @Test diff --git a/spring-cloud-starter-tencent-polaris-router/pom.xml b/spring-cloud-starter-tencent-polaris-router/pom.xml index 147451b5f..e21ca43f8 100644 --- a/spring-cloud-starter-tencent-polaris-router/pom.xml +++ b/spring-cloud-starter-tencent-polaris-router/pom.xml @@ -52,6 +52,20 @@ true + + + org.springframework.cloud + spring-cloud-gateway-server + true + + + + org.springframework.boot + spring-boot-starter-webflux + true + + + org.springframework.boot spring-boot-starter-test diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterContext.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterContext.java index 114548722..1e05d2ec6 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterContext.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterContext.java @@ -27,7 +27,7 @@ import org.springframework.util.CollectionUtils; /** * the context for router. * - *@author lepdou 2022-05-17 + * @author lepdou 2022-05-17 */ public class PolarisRouterContext { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplier.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplier.java index d2f5e2f4e..1b8152f2a 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplier.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplier.java @@ -19,7 +19,6 @@ package com.tencent.cloud.polaris.router; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -58,6 +57,8 @@ import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import org.springframework.http.HttpHeaders; import org.springframework.util.CollectionUtils; +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; + /** * Service routing entrance. * @@ -128,10 +129,10 @@ public class PolarisRouterServiceInstanceListSupplier extends DelegatingServiceI Map labelHeaderValuesMap = new HashMap<>(); try { String labelHeaderValuesContent = labelHeaderValues.stream().findFirst().get(); - labelHeaderValuesMap.putAll(JacksonUtils.deserialize2Map(URLDecoder.decode(labelHeaderValuesContent, StandardCharsets.UTF_8.name()))); + labelHeaderValuesMap.putAll(JacksonUtils.deserialize2Map(URLDecoder.decode(labelHeaderValuesContent, UTF_8))); } catch (UnsupportedEncodingException e) { - throw new RuntimeException("unsupported charset exception " + StandardCharsets.UTF_8.name()); + throw new RuntimeException("unsupported charset exception " + UTF_8); } routerContext.setLabels(PolarisRouterContext.RULE_ROUTER_LABELS, labelHeaderValuesMap); return routerContext; diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConstants.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConstants.java index 6437c83e8..7dfdc5451 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConstants.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConstants.java @@ -21,12 +21,16 @@ package com.tencent.cloud.polaris.router; /** * Router constants. * - *@author lepdou 2022-05-17 + * @author lepdou 2022-05-17 */ -public class RouterConstants { +public final class RouterConstants { /** * the header of router label. */ public static final String ROUTER_LABEL_HEADER = "internal-router-label"; + + + private RouterConstants() { + } } diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolver.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolver.java index 5ab6e549f..ded1784f4 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolver.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolver.java @@ -33,6 +33,7 @@ import org.springframework.util.CollectionUtils; /** * Resolve label expressions from routing rules. + * * @author lepdou 2022-05-19 */ public class RouterRuleLabelResolver { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignAutoConfiguration.java new file mode 100644 index 000000000..107ea5e8e --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignAutoConfiguration.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.polaris.router.config; + +import java.util.List; + +import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; +import com.tencent.cloud.polaris.router.feign.RouterLabelFeignInterceptor; +import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.lang.Nullable; + +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(name = {"feign.RequestInterceptor"}) +public class FeignAutoConfiguration { + + @Bean + public RouterLabelFeignInterceptor routerLabelInterceptor(@Nullable List routerLabelResolvers, + MetadataLocalProperties metadataLocalProperties, + RouterRuleLabelResolver routerRuleLabelResolver) { + return new RouterLabelFeignInterceptor(routerLabelResolvers, metadataLocalProperties, routerRuleLabelResolver); + } +} diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/LoadBalancerConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/LoadBalancerConfiguration.java index 6d02df9be..0205a74a3 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/LoadBalancerConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/LoadBalancerConfiguration.java @@ -35,6 +35,7 @@ import org.springframework.core.annotation.Order; /** * Auto configuration for ribbon components. + * * @author lepdou 2022-05-17 */ @Configuration(proxyBeanMethods = false) @@ -46,7 +47,7 @@ public class LoadBalancerConfiguration { */ private static final int REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER = 193827465; - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnReactiveDiscoveryEnabled @Order(REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER) static class PolarisReactiveSupportConfiguration { @@ -69,7 +70,7 @@ public class LoadBalancerConfiguration { } - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnBlockingDiscoveryEnabled @Order(REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER + 1) static class PolarisBlockingSupportConfiguration { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisMetadataRouterProperties.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisMetadataRouterProperties.java index 4a20e53f6..2bf700c33 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisMetadataRouterProperties.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisMetadataRouterProperties.java @@ -22,6 +22,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; /** * the configuration for metadata router. + * * @author lepdou 2022-05-23 */ @ConfigurationProperties(prefix = "spring.cloud.polaris.router.metadata-router") diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRuleBasedRouterProperties.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRuleBasedRouterProperties.java index 89b4bead5..8bd4a13cb 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRuleBasedRouterProperties.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRuleBasedRouterProperties.java @@ -44,5 +44,4 @@ public class PolarisRuleBasedRouterProperties { "enabled=" + enabled + '}'; } - } diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java index a9e1a54df..8b43239a8 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java @@ -18,45 +18,42 @@ package com.tencent.cloud.polaris.router.config; -import java.util.List; - -import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.polaris.context.ServiceRuleManager; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; -import com.tencent.cloud.polaris.router.feign.RouterLabelFeignInterceptor; import com.tencent.cloud.polaris.router.resttemplate.PolarisLoadBalancerBeanPostProcessor; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.scg.PolarisLoadBalancerClientBeanPostProcessor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.core.annotation.Order; -import org.springframework.lang.Nullable; import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; /** * router module auto configuration. * - *@author lepdou 2022-05-11 + * @author lepdou 2022-05-11 */ -@Configuration +@Configuration(proxyBeanMethods = false) @LoadBalancerClients(defaultConfiguration = LoadBalancerConfiguration.class) @Import({PolarisNearByRouterProperties.class, PolarisMetadataRouterProperties.class, PolarisRuleBasedRouterProperties.class}) public class RouterAutoConfiguration { @Bean - public RouterLabelFeignInterceptor routerLabelInterceptor(@Nullable List routerLabelResolvers, - MetadataLocalProperties metadataLocalProperties, - RouterRuleLabelResolver routerRuleLabelResolver) { - return new RouterLabelFeignInterceptor(routerLabelResolvers, metadataLocalProperties, routerRuleLabelResolver); + @Order(HIGHEST_PRECEDENCE) + @ConditionalOnClass(name = "org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor") + public PolarisLoadBalancerBeanPostProcessor polarisLoadBalancerBeanPostProcessor() { + return new PolarisLoadBalancerBeanPostProcessor(); } @Bean @Order(HIGHEST_PRECEDENCE) - public PolarisLoadBalancerBeanPostProcessor polarisLoadBalancerBeanPostProcessor() { - return new PolarisLoadBalancerBeanPostProcessor(); + @ConditionalOnClass(name = "org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter") + public PolarisLoadBalancerClientBeanPostProcessor polarisLoadBalancerClientBeanPostProcessor() { + return new PolarisLoadBalancerClientBeanPostProcessor(); } @Bean diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtils.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtils.java index 92b8a6608..c3d19b35e 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtils.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtils.java @@ -33,9 +33,13 @@ import org.springframework.util.CollectionUtils; /** * Resolve rule expression label from feign request. + * * @author lepdou 2022-05-20 */ -public class FeignExpressionLabelUtils { +public final class FeignExpressionLabelUtils { + + private FeignExpressionLabelUtils() { + } public static Map resolve(RequestTemplate request, Set labelKeys) { if (CollectionUtils.isEmpty(labelKeys)) { @@ -74,7 +78,6 @@ public class FeignExpressionLabelUtils { public static String getHeaderValue(RequestTemplate request, String key) { Map> headers = request.headers(); return ExpressionLabelUtils.getFirstValue(headers, key); - } public static String getQueryValue(RequestTemplate request, String key) { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java index c2f339b02..abcd83d1f 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java @@ -20,7 +20,6 @@ package com.tencent.cloud.polaris.router.feign; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -43,11 +42,12 @@ import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; import org.springframework.util.CollectionUtils; +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; + /** * Resolver labels from request. * - * @author lepdou 2022-05-12 - * @author cheese8 2022-06-20 + * @author lepdou, cheese8 */ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered { private static final Logger LOGGER = LoggerFactory.getLogger(RouterLabelFeignInterceptor.class); @@ -113,10 +113,10 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered String encodedLabelsContent; try { - encodedLabelsContent = URLEncoder.encode(JacksonUtils.serialize2Json(labels), StandardCharsets.UTF_8.name()); + encodedLabelsContent = URLEncoder.encode(JacksonUtils.serialize2Json(labels), UTF_8); } catch (UnsupportedEncodingException e) { - throw new RuntimeException("unsupported charset exception " + StandardCharsets.UTF_8.name()); + throw new RuntimeException("unsupported charset exception " + UTF_8); } requestTemplate.header(RouterConstants.ROUTER_LABEL_HEADER, encodedLabelsContent); } @@ -131,5 +131,4 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered return FeignExpressionLabelUtils.resolve(requestTemplate, labelKeys); } - } diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java index 2006a373f..a0155315c 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -51,12 +50,13 @@ import org.springframework.http.client.ClientHttpResponse; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; + /** * PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor capabilities. * Parses the label from the request and puts it into the RouterContext for routing. * - * @author lepdou 2022-05-18 - * @author cheese8 2022-06-20 + * @author lepdou, cheese8 */ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor { private static final Logger LOGGER = LoggerFactory.getLogger(PolarisLoadBalancerInterceptor.class); @@ -137,10 +137,10 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor { } String encodedLabelsContent; try { - encodedLabelsContent = URLEncoder.encode(JacksonUtils.serialize2Json(labels), StandardCharsets.UTF_8.name()); + encodedLabelsContent = URLEncoder.encode(JacksonUtils.serialize2Json(labels), UTF_8); } catch (UnsupportedEncodingException e) { - throw new RuntimeException("unsupported charset exception " + StandardCharsets.UTF_8.name()); + throw new RuntimeException("unsupported charset exception " + UTF_8); } request.getHeaders().set(RouterConstants.ROUTER_LABEL_HEADER, encodedLabelsContent); } diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessor.java new file mode 100644 index 000000000..06d3fad8c --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessor.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.polaris.router.scg; + +import java.util.List; + +import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.common.util.BeanFactoryUtils; +import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; +import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; +import org.springframework.cloud.gateway.config.GatewayLoadBalancerProperties; +import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; + +/** + * Replaced ReactiveLoadBalancerClientFilter with PolarisReactiveLoadBalancerClientFilter during creating bean phase. + * + * @author lepdou 2022-06-20 + */ +public class PolarisLoadBalancerClientBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { + + private BeanFactory factory; + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.factory = beanFactory; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + // Support spring cloud gateway router. + // Replaces the default LoadBalancerClientFilter implementation and returns a custom PolarisLoadBalancerClientFilter + if (bean instanceof ReactiveLoadBalancerClientFilter) { + LoadBalancerClientFactory loadBalancerClientFactory = this.factory.getBean(LoadBalancerClientFactory.class); + GatewayLoadBalancerProperties gatewayLoadBalancerProperties = this.factory.getBean(GatewayLoadBalancerProperties.class); + LoadBalancerProperties loadBalancerProperties = this.factory.getBean(LoadBalancerProperties.class); + List routerLabelResolvers = BeanFactoryUtils.getBeans(factory, RouterLabelResolver.class); + MetadataLocalProperties metadataLocalProperties = this.factory.getBean(MetadataLocalProperties.class); + RouterRuleLabelResolver routerRuleLabelResolver = this.factory.getBean(RouterRuleLabelResolver.class); + + return new PolarisReactiveLoadBalancerClientFilter( + loadBalancerClientFactory, gatewayLoadBalancerProperties, loadBalancerProperties, + metadataLocalProperties, routerRuleLabelResolver, routerLabelResolvers); + } + return bean; + } +} diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilter.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilter.java new file mode 100644 index 000000000..60f27ccfd --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilter.java @@ -0,0 +1,267 @@ +/* + * 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.router.scg; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.metadata.MetadataContextHolder; +import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.common.util.ExpressionLabelUtils; +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.polaris.router.PolarisRouterServiceInstanceListSupplier; +import com.tencent.cloud.polaris.router.RouterConstants; +import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; +import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.CompletionContext; +import org.springframework.cloud.client.loadbalancer.DefaultRequest; +import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle; +import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycleValidator; +import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; +import org.springframework.cloud.client.loadbalancer.LoadBalancerUriTools; +import org.springframework.cloud.client.loadbalancer.Request; +import org.springframework.cloud.client.loadbalancer.RequestData; +import org.springframework.cloud.client.loadbalancer.RequestDataContext; +import org.springframework.cloud.client.loadbalancer.Response; +import org.springframework.cloud.client.loadbalancer.ResponseData; +import org.springframework.cloud.gateway.config.GatewayLoadBalancerProperties; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter; +import org.springframework.cloud.gateway.support.DelegatingServiceInstance; +import org.springframework.cloud.gateway.support.NotFoundException; +import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer; +import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.util.CollectionUtils; +import org.springframework.web.server.ServerWebExchange; + +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_LOADBALANCER_RESPONSE_ATTR; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl; + +/** + * ReactiveLoadBalancerClientFilter does not have the ability to pass route labels, so it is replaced + * with PolarisReactiveLoadBalancerClientFilter. The passed route labels are used in + * {@link PolarisRouterServiceInstanceListSupplier}. + * + * @author lepdou 2022-06-20 + */ +public class PolarisReactiveLoadBalancerClientFilter extends ReactiveLoadBalancerClientFilter { + private static final Logger log = LoggerFactory.getLogger(PolarisReactiveLoadBalancerClientFilter.class); + + private final LoadBalancerClientFactory clientFactory; + private final GatewayLoadBalancerProperties gatewayLoadBalancerProperties; + private final LoadBalancerProperties loadBalancerProperties; + private final MetadataLocalProperties metadataLocalProperties; + private final RouterRuleLabelResolver routerRuleLabelResolver; + private final List routerLabelResolvers; + + public PolarisReactiveLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory, + GatewayLoadBalancerProperties gatewayLoadBalancerProperties, + LoadBalancerProperties loadBalancerProperties, + MetadataLocalProperties metadataLocalProperties, + RouterRuleLabelResolver routerRuleLabelResolver, + List routerLabelResolvers) { + super(clientFactory, gatewayLoadBalancerProperties, loadBalancerProperties); + + this.clientFactory = clientFactory; + this.gatewayLoadBalancerProperties = gatewayLoadBalancerProperties; + this.loadBalancerProperties = loadBalancerProperties; + this.metadataLocalProperties = metadataLocalProperties; + this.routerRuleLabelResolver = routerRuleLabelResolver; + this.routerLabelResolvers = routerLabelResolvers; + } + + /** + * Copied from ReactiveLoadBalancerClientFilter, and create new RequestData for passing router labels. + */ + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR); + String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR); + if (url == null || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) { + return chain.filter(exchange); + } + // preserve the original url + addOriginalRequestUrl(exchange, url); + + if (log.isTraceEnabled()) { + log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() + " url before: " + url); + } + + URI requestUri = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR); + String serviceId = requestUri.getHost(); + Set supportedLifecycleProcessors = LoadBalancerLifecycleValidator + .getSupportedLifecycleProcessors(clientFactory.getInstances(serviceId, LoadBalancerLifecycle.class), + RequestDataContext.class, ResponseData.class, ServiceInstance.class); + + // Pass route tags through http headers + HttpHeaders routerHttpHeaders = genRouterHttpHeaders(exchange, serviceId); + + ServerHttpRequest request = exchange.getRequest(); + RequestData requestData = new RequestData(request.getMethod(), request.getURI(), routerHttpHeaders, + new HttpHeaders(), new HashMap<>()); + DefaultRequest lbRequest = new DefaultRequest<>(new RequestDataContext( + requestData, getHint(serviceId, loadBalancerProperties.getHint()))); + + return choose(lbRequest, serviceId, supportedLifecycleProcessors).doOnNext(response -> { + + if (!response.hasServer()) { + supportedLifecycleProcessors.forEach(lifecycle -> lifecycle + .onComplete(new CompletionContext<>(CompletionContext.Status.DISCARD, lbRequest, response))); + throw NotFoundException.create(gatewayLoadBalancerProperties.isUse404(), + "Unable to find instance for " + url.getHost()); + } + + ServiceInstance retrievedInstance = response.getServer(); + + URI uri = exchange.getRequest().getURI(); + + // if the `lb:` mechanism was used, use `` as the default, + // if the loadbalancer doesn't provide one. + String overrideScheme = retrievedInstance.isSecure() ? "https" : "http"; + if (schemePrefix != null) { + overrideScheme = url.getScheme(); + } + + DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(retrievedInstance, + overrideScheme); + + URI requestUrl = reconstructURI(serviceInstance, uri); + + if (log.isTraceEnabled()) { + log.trace("LoadBalancerClientFilter url chosen: " + requestUrl); + } + exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl); + exchange.getAttributes().put(GATEWAY_LOADBALANCER_RESPONSE_ATTR, response); + supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, response)); + }).then(chain.filter(exchange)) + .doOnError(throwable -> supportedLifecycleProcessors.forEach(lifecycle -> lifecycle + .onComplete(new CompletionContext( + CompletionContext.Status.FAILED, throwable, lbRequest, + exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR))))) + .doOnSuccess(aVoid -> supportedLifecycleProcessors.forEach(lifecycle -> lifecycle + .onComplete(new CompletionContext( + CompletionContext.Status.SUCCESS, lbRequest, + exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR), + new ResponseData(exchange.getResponse(), new RequestData(exchange.getRequest())))))); + } + + protected URI reconstructURI(ServiceInstance serviceInstance, URI original) { + return LoadBalancerUriTools.reconstructURI(serviceInstance, original); + } + + private Mono> choose(Request lbRequest, String serviceId, + Set supportedLifecycleProcessors) { + ReactorLoadBalancer loadBalancer = this.clientFactory.getInstance(serviceId, + ReactorServiceInstanceLoadBalancer.class); + if (loadBalancer == null) { + throw new NotFoundException("No loadbalancer available for " + serviceId); + } + supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest)); + return loadBalancer.choose(lbRequest); + } + + // no actual used + private String getHint(String serviceId, Map hints) { + String defaultHint = hints.getOrDefault("default", "default"); + String hintPropertyValue = hints.get(serviceId); + return hintPropertyValue != null ? hintPropertyValue : defaultHint; + } + + // In order to be consistent with feign and restTemplate, + // the router label is passed through the http header uniformly instead of the original hint mechanism. + HttpHeaders genRouterHttpHeaders(ServerWebExchange exchange, String peerServiceName) { + HttpHeaders headers = new HttpHeaders(); + headers.add(RouterConstants.ROUTER_LABEL_HEADER, genRouterHint(exchange, peerServiceName)); + return headers; + } + + private String genRouterHint(ServerWebExchange exchange, String peerServiceName) { + Map routerLabels = genRouterLabels(exchange, peerServiceName); + String encodedLabelsContent; + try { + encodedLabelsContent = URLEncoder.encode(JacksonUtils.serialize2Json(routerLabels), UTF_8); + } + catch (UnsupportedEncodingException e) { + throw new RuntimeException("unsupported charset exception " + UTF_8); + } + return encodedLabelsContent; + } + + private Map genRouterLabels(ServerWebExchange exchange, String peerServiceName) { + // local service labels + Map labels = new HashMap<>(metadataLocalProperties.getContent()); + + // labels from rule expression + Map ruleExpressionLabels = getExpressionLabels(exchange, peerServiceName); + if (!CollectionUtils.isEmpty(ruleExpressionLabels)) { + labels.putAll(ruleExpressionLabels); + } + + // labels from request + if (!CollectionUtils.isEmpty(routerLabelResolvers)) { + routerLabelResolvers.forEach(resolver -> { + try { + Map customResolvedLabels = resolver.resolve(exchange); + if (!CollectionUtils.isEmpty(customResolvedLabels)) { + labels.putAll(customResolvedLabels); + } + } + catch (Throwable t) { + log.error("[SCT][Router] revoke RouterLabelResolver occur some exception. ", t); + } + }); + } + + // labels from downstream + Map transitiveLabels = MetadataContextHolder.get() + .getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + labels.putAll(transitiveLabels); + + return labels; + } + + private Map getExpressionLabels(ServerWebExchange exchange, String peerServiceName) { + Set labelKeys = routerRuleLabelResolver.getExpressionLabelKeys(MetadataContext.LOCAL_NAMESPACE, + MetadataContext.LOCAL_SERVICE, peerServiceName); + + if (CollectionUtils.isEmpty(labelKeys)) { + return Collections.emptyMap(); + } + + return ExpressionLabelUtils.resolve(exchange, labelKeys); + } +} diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/RouterLabelResolver.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/RouterLabelResolver.java index 49b9ccf4c..d885581ca 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/RouterLabelResolver.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/RouterLabelResolver.java @@ -18,12 +18,14 @@ package com.tencent.cloud.polaris.router.spi; +import java.util.Collections; import java.util.Map; import feign.RequestTemplate; import org.springframework.core.Ordered; import org.springframework.http.HttpRequest; +import org.springframework.web.server.ServerWebExchange; /** * The spi for resolving labels from request. @@ -37,7 +39,9 @@ public interface RouterLabelResolver extends Ordered { * @param requestTemplate the feign request. * @return resolved labels */ - Map resolve(RequestTemplate requestTemplate); + default Map resolve(RequestTemplate requestTemplate) { + return Collections.emptyMap(); + } /** * resolve labels from rest template request. @@ -45,5 +49,16 @@ public interface RouterLabelResolver extends Ordered { * @param body the rest template request body. * @return resolved labels */ - Map resolve(HttpRequest request, byte[] body); + default Map resolve(HttpRequest request, byte[] body) { + return Collections.emptyMap(); + } + + /** + * resolve labels from server web exchange. + * @param exchange the server web exchange. + * @return resolved labels + */ + default Map resolve(ServerWebExchange exchange) { + return Collections.emptyMap(); + } } diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories index d33dcea7f..3b20deb56 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories @@ -1,2 +1,3 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.tencent.cloud.polaris.router.config.RouterAutoConfiguration + com.tencent.cloud.polaris.router.config.RouterAutoConfiguration,\ + com.tencent.cloud.polaris.router.config.FeignAutoConfiguration diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterContextTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterContextTest.java index 2a8d38752..0f2094233 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterContextTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterContextTest.java @@ -25,9 +25,9 @@ import org.junit.Assert; import org.junit.Test; /** - * test for {@link PolarisRouterContext} + * test for {@link PolarisRouterContext}. * - *@author lepdou 2022-05-26 + * @author lepdou 2022-05-26 */ public class PolarisRouterContextTest { diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplierTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplierTest.java index 51a2bab30..afe003b76 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplierTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplierTest.java @@ -62,13 +62,17 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; /** - * test for {@link PolarisRouterServiceInstanceListSupplier} - *@author lepdou 2022-05-26 + * test for {@link PolarisRouterServiceInstanceListSupplier}. + * + * @author lepdou 2022-05-26 */ @RunWith(MockitoJUnitRunner.class) public class PolarisRouterServiceInstanceListSupplierTest { - private static AtomicBoolean initTransitiveMetadata = new AtomicBoolean(false); + private static final AtomicBoolean initTransitiveMetadata = new AtomicBoolean(false); + private final String testNamespace = "testNamespace"; + private final String testCallerService = "testCallerService"; + private final String testCalleeService = "testCalleeService"; @Mock private ServiceInstanceListSupplier delegate; @Mock @@ -81,9 +85,6 @@ public class PolarisRouterServiceInstanceListSupplierTest { private PolarisRuleBasedRouterProperties polarisRuleBasedRouterProperties; @Mock private RouterAPI routerAPI; - private String testNamespace = "testNamespace"; - private String testCallerService = "testCallerService"; - private String testCalleeService = "testCalleeService"; @Test public void testBuildMetadataRouteRequest() { diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java index 26c1dfb13..a910473ac 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java @@ -38,18 +38,18 @@ import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.Mockito.when; /** - * test for {@link RouterRuleLabelResolver} - *@author lepdou 2022-05-26 + * test for {@link RouterRuleLabelResolver}. + * + * @author lepdou 2022-05-26 */ @RunWith(MockitoJUnitRunner.class) public class RouterRuleLabelResolverTest { - @Mock - private ServiceRuleManager serviceRuleManager; - private final String testNamespace = "testNamespace"; private final String testSourceService = "sourceService"; private final String testDstService = "dstService"; + @Mock + private ServiceRuleManager serviceRuleManager; @Test public void test() { diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtilsTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtilsTest.java index 6078be75c..fa9086d5d 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtilsTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtilsTest.java @@ -30,8 +30,9 @@ import org.junit.Test; import org.springframework.util.StringUtils; /** - * Test for {@link FeignExpressionLabelUtils} - *@author lepdou 2022-05-26 + * Test for {@link FeignExpressionLabelUtils}. + * + * @author lepdou 2022-05-26 */ public class FeignExpressionLabelUtilsTest { diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java index b2824b7ea..c0aecea28 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java @@ -20,7 +20,6 @@ package com.tencent.cloud.polaris.router.feign; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -46,13 +45,14 @@ import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; /** - * test for {@link RouterLabelFeignInterceptor} - * @author lepdou 2022-05-26 - * @author cheese8 2022-06-20 + * test for {@link RouterLabelFeignInterceptor}. + * + * @author lepdou, cheese8 */ @RunWith(MockitoJUnitRunner.class) public class RouterLabelFeignInterceptorTest { @@ -123,10 +123,10 @@ public class RouterLabelFeignInterceptorTest { Map routerLabelsMap = new HashMap<>(); try { String routerLabelContent = routerLabels.stream().findFirst().get(); - routerLabelsMap.putAll(JacksonUtils.deserialize2Map(URLDecoder.decode(routerLabelContent, StandardCharsets.UTF_8.name()))); + routerLabelsMap.putAll(JacksonUtils.deserialize2Map(URLDecoder.decode(routerLabelContent, UTF_8))); } catch (UnsupportedEncodingException e) { - throw new RuntimeException("unsupported charset exception " + StandardCharsets.UTF_8.name()); + throw new RuntimeException("unsupported charset exception " + UTF_8); } Assert.assertNotNull(routerLabels); @@ -139,5 +139,4 @@ public class RouterLabelFeignInterceptorTest { } } } - } diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java index e335e83fa..14f61d6c7 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java @@ -38,7 +38,8 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory; import static org.mockito.Mockito.when; /** - * Test for ${@link PolarisLoadBalancerBeanPostProcessor} + * Test for ${@link PolarisLoadBalancerBeanPostProcessor}. + * * @author lepdou 2022-05-26 */ @RunWith(MockitoJUnitRunner.class) diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java index 11319f650..914240a12 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java @@ -20,7 +20,6 @@ package com.tencent.cloud.polaris.router.resttemplate; import java.net.URI; import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -54,14 +53,15 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpResponse; +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** - * test for {@link PolarisLoadBalancerInterceptor} - * @author lepdou 2022-05-26 - * @author cheese8 2022-06-20 + * test for {@link PolarisLoadBalancerInterceptor}. + * + * @author lepdou, cheese8 */ @RunWith(MockitoJUnitRunner.class) public class PolarisLoadBalancerInterceptorTest { @@ -187,7 +187,7 @@ public class PolarisLoadBalancerInterceptorTest { verify(routerLabelResolver).resolve(request, null); Map headers = JacksonUtils.deserialize2Map(URLDecoder.decode(request.getHeaders() - .get(RouterConstants.ROUTER_LABEL_HEADER).get(0), StandardCharsets.UTF_8.name())); + .get(RouterConstants.ROUTER_LABEL_HEADER).get(0), UTF_8)); Assert.assertEquals("v1", headers.get("k1")); Assert.assertEquals("v22", headers.get("k2")); Assert.assertEquals("v4", headers.get("k4")); @@ -198,7 +198,7 @@ public class PolarisLoadBalancerInterceptorTest { static class MockedLoadBalancerRequest implements LoadBalancerRequest { @Override - public T apply(ServiceInstance instance) throws Exception { + public T apply(ServiceInstance instance) { return null; } } diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessorTest.java new file mode 100644 index 000000000..5633d72df --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessorTest.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.polaris.router.scg; + +import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.common.util.BeanFactoryUtils; +import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; +import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; +import org.springframework.cloud.gateway.config.GatewayLoadBalancerProperties; +import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; + +import static org.mockito.Mockito.when; + + +/** + * Test for ${@link PolarisLoadBalancerClientBeanPostProcessor}. + * + * @author lepdou 2022-07-04 + */ +@RunWith(MockitoJUnitRunner.class) +public class PolarisLoadBalancerClientBeanPostProcessorTest { + + @Mock + private BeanFactory beanFactory; + @Mock + private LoadBalancerClientFactory loadBalancerClientFactory; + @Mock + private GatewayLoadBalancerProperties gatewayLoadBalancerProperties; + @Mock + private LoadBalancerProperties loadBalancerProperties; + @Mock + private MetadataLocalProperties metadataLocalProperties; + @Mock + private RouterRuleLabelResolver routerRuleLabelResolver; + + @Test + public void testWrapReactiveLoadBalancerClientFilter() { + when(beanFactory.getBean(LoadBalancerClientFactory.class)).thenReturn(loadBalancerClientFactory); + when(beanFactory.getBean(GatewayLoadBalancerProperties.class)).thenReturn(gatewayLoadBalancerProperties); + when(beanFactory.getBean(LoadBalancerProperties.class)).thenReturn(loadBalancerProperties); + when(beanFactory.getBean(MetadataLocalProperties.class)).thenReturn(metadataLocalProperties); + when(beanFactory.getBean(RouterRuleLabelResolver.class)).thenReturn(routerRuleLabelResolver); + + try (MockedStatic mockedBeanFactoryUtils = Mockito.mockStatic(BeanFactoryUtils.class)) { + mockedBeanFactoryUtils.when(() -> BeanFactoryUtils.getBeans(beanFactory, RouterLabelResolver.class)) + .thenReturn(null); + + ReactiveLoadBalancerClientFilter reactiveLoadBalancerClientFilter = new ReactiveLoadBalancerClientFilter( + loadBalancerClientFactory, gatewayLoadBalancerProperties, loadBalancerProperties); + + PolarisLoadBalancerClientBeanPostProcessor processor = new PolarisLoadBalancerClientBeanPostProcessor(); + processor.setBeanFactory(beanFactory); + + Object bean = processor.postProcessBeforeInitialization(reactiveLoadBalancerClientFilter, ""); + + Assert.assertTrue(bean instanceof PolarisReactiveLoadBalancerClientFilter); + } + } + + @Test + public void testNotWrapLoadBalancerInterceptor() { + PolarisLoadBalancerClientBeanPostProcessor processor = new PolarisLoadBalancerClientBeanPostProcessor(); + processor.setBeanFactory(beanFactory); + + OtherBean otherBean = new OtherBean(); + Object bean = processor.postProcessBeforeInitialization(otherBean, ""); + Assert.assertFalse(bean instanceof PolarisReactiveLoadBalancerClientFilter); + Assert.assertTrue(bean instanceof OtherBean); + } + + static class OtherBean { + + } +} diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilterTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilterTest.java new file mode 100644 index 000000000..b1d29b1cd --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilterTest.java @@ -0,0 +1,146 @@ +/* + * 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.router.scg; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.metadata.MetadataContextHolder; +import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.polaris.router.RouterConstants; +import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; +import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; +import org.springframework.cloud.gateway.config.GatewayLoadBalancerProperties; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.web.server.MockServerWebExchange; +import org.springframework.util.CollectionUtils; + +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +/** + * Test for ${@link PolarisReactiveLoadBalancerClientFilter}. + * + * @author lepdou 2022-07-04 + */ +@RunWith(MockitoJUnitRunner.class) +public class PolarisReactiveLoadBalancerClientFilterTest { + + private static final String callerService = "callerService"; + private static final String calleeService = "calleeService"; + private static MockedStatic mockedApplicationContextAwareUtils; + private static MockedStatic mockedMetadataContextHolder; + + @Mock + private MetadataLocalProperties metadataLocalProperties; + @Mock + private RouterLabelResolver routerLabelResolver; + @Mock + private RouterRuleLabelResolver routerRuleLabelResolver; + @Mock + private LoadBalancerClientFactory loadBalancerClientFactory; + @Mock + private GatewayLoadBalancerProperties gatewayLoadBalancerProperties; + @Mock + private LoadBalancerProperties loadBalancerProperties; + + @BeforeClass + public static void beforeClass() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn(callerService); + + MetadataContext metadataContext = Mockito.mock(MetadataContext.class); + + // mock transitive metadata + Map transitiveLabels = new HashMap<>(); + transitiveLabels.put("t1", "v1"); + transitiveLabels.put("t2", "v2"); + when(metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE)).thenReturn(transitiveLabels); + + mockedMetadataContextHolder = Mockito.mockStatic(MetadataContextHolder.class); + mockedMetadataContextHolder.when(MetadataContextHolder::get).thenReturn(metadataContext); + } + + @AfterClass + public static void afterClass() { + mockedApplicationContextAwareUtils.close(); + mockedMetadataContextHolder.close(); + } + + @Test + public void testGenRouterHttpHeaders() throws UnsupportedEncodingException { + PolarisReactiveLoadBalancerClientFilter filter = new PolarisReactiveLoadBalancerClientFilter(loadBalancerClientFactory, + gatewayLoadBalancerProperties, loadBalancerProperties, metadataLocalProperties, routerRuleLabelResolver, + Lists.newArrayList(routerLabelResolver)); + + Map localMetadata = new HashMap<>(); + localMetadata.put("env", "blue"); + when(metadataLocalProperties.getContent()).thenReturn(localMetadata); + + Set expressionLabelKeys = Sets.newHashSet("${http.header.k1}", "${http.query.userid}"); + when(routerRuleLabelResolver.getExpressionLabelKeys(anyString(), anyString(), anyString())).thenReturn(expressionLabelKeys); + + MockServerHttpRequest request = MockServerHttpRequest.get("/" + calleeService + "/users") + .header("k1", "v1") + .queryParam("userid", "zhangsan") + .build(); + MockServerWebExchange webExchange = new MockServerWebExchange.Builder(request).build(); + + Map customMetadata = new HashMap<>(); + customMetadata.put("k2", "v2"); + when(routerLabelResolver.resolve(webExchange)).thenReturn(customMetadata); + + HttpHeaders headers = filter.genRouterHttpHeaders(webExchange, calleeService); + + Assert.assertNotNull(headers); + List routerHeaders = headers.get(RouterConstants.ROUTER_LABEL_HEADER); + Assert.assertFalse(CollectionUtils.isEmpty(routerHeaders)); + + Map routerLabels = JacksonUtils.deserialize2Map(URLDecoder.decode(routerHeaders.get(0), UTF_8)); + Assert.assertEquals("v1", routerLabels.get("${http.header.k1}")); + Assert.assertEquals("zhangsan", routerLabels.get("${http.query.userid}")); + Assert.assertEquals("blue", routerLabels.get("env")); + Assert.assertEquals("v1", routerLabels.get("t1")); + Assert.assertEquals("v2", routerLabels.get("t2")); + } +} diff --git a/spring-cloud-tencent-commons/pom.xml b/spring-cloud-tencent-commons/pom.xml index e8de59272..6cf993ed3 100644 --- a/spring-cloud-tencent-commons/pom.xml +++ b/spring-cloud-tencent-commons/pom.xml @@ -87,6 +87,18 @@ spring-boot-starter-test test + + + org.springframework.boot + spring-boot-actuator + true + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + 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 71ce1e886..e2b2608b3 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 @@ -17,6 +17,8 @@ package com.tencent.cloud.common.constant; +import java.nio.charset.StandardCharsets; + /** * Constant for Context. * @@ -29,6 +31,11 @@ public final class ContextConstant { */ public static final String POLARIS = "POLARIS"; + /** + * SCT Default Charset . + */ + public static final String UTF_8 = StandardCharsets.UTF_8.name(); + private ContextConstant() { } @@ -61,7 +68,5 @@ public final class ContextConstant { * Order of configuration modifier. */ public static Integer CONFIG_ORDER = 1; - } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java index e28c43043..09e17e1e8 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java @@ -45,7 +45,6 @@ public final class MetadataConstant { * Order of Metadata2HeaderInterceptor. */ public static int METADATA_2_HEADER_INTERCEPTOR_ORDER = Ordered.LOWEST_PRECEDENCE; - } /** @@ -67,7 +66,5 @@ public final class MetadataConstant { * Metadata context. */ public static final String METADATA_CONTEXT = "SCT-METADATA-CONTEXT"; - } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java index 1a48a0b00..3d3064ba0 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java @@ -105,5 +105,4 @@ public final class MetadataContextHolder { public static void remove() { METADATA_CONTEXT.remove(); } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java index 575775bf7..a717db436 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java @@ -22,27 +22,22 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.common.spi.InstanceMetadataProvider; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.util.CollectionUtils; + /** - * manage metadata from env/config file. + * manage metadata from env/config file/custom spi. * - *@author lepdou 2022-05-20 + * @author lepdou 2022-05-20 */ public class StaticMetadataManager { - private static final Logger LOGGER = LoggerFactory.getLogger(StaticMetadataManager.class); - - private static final String ENV_METADATA_PREFIX = "SCT_METADATA_CONTENT_"; - private static final int ENV_METADATA_PREFIX_LENGTH = ENV_METADATA_PREFIX.length(); - private static final String ENV_METADATA_CONTENT_TRANSITIVE = "SCT_METADATA_CONTENT_TRANSITIVE"; - private static final String ENV_METADATA_ZONE = "SCT_METADATA_ZONE"; - private static final String ENV_METADATA_REGION = "SCT_METADATA_REGION"; - private static final String ENV_METADATA_CAMPUS = "SCT_METADATA_CAMPUS"; - /** * the metadata key of region. */ @@ -55,22 +50,37 @@ public class StaticMetadataManager { * the metadata key of campus/datacenter. */ public static final String LOCATION_KEY_CAMPUS = "campus"; - + private static final Logger LOGGER = LoggerFactory.getLogger(StaticMetadataManager.class); + private static final String ENV_METADATA_PREFIX = "SCT_METADATA_CONTENT_"; + private static final int ENV_METADATA_PREFIX_LENGTH = ENV_METADATA_PREFIX.length(); + private static final String ENV_METADATA_CONTENT_TRANSITIVE = "SCT_METADATA_CONTENT_TRANSITIVE"; + private static final String ENV_METADATA_ZONE = "SCT_METADATA_ZONE"; + private static final String ENV_METADATA_REGION = "SCT_METADATA_REGION"; + private static final String ENV_METADATA_CAMPUS = "SCT_METADATA_CAMPUS"; private Map envMetadata; private Map envTransitiveMetadata; private Map configMetadata; private Map configTransitiveMetadata; + private Map customSPIMetadata; + private Map customSPITransitiveMetadata; + private Map mergedStaticMetadata; private Map mergedStaticTransitiveMetadata; private String zone; private String region; private String campus; - public StaticMetadataManager(MetadataLocalProperties metadataLocalProperties) { + public StaticMetadataManager(MetadataLocalProperties metadataLocalProperties, + InstanceMetadataProvider instanceMetadataProvider) { parseConfigMetadata(metadataLocalProperties); + parseEnvMetadata(); + + parseCustomMetadata(instanceMetadataProvider); + + parseLocationMetadata(metadataLocalProperties, instanceMetadataProvider); + merge(); - parseLocationMetadata(); LOGGER.info("[SCT] Loaded static metadata info. {}", this); } @@ -125,26 +135,89 @@ public class StaticMetadataManager { configMetadata = Collections.unmodifiableMap(allMetadata); } + private void parseCustomMetadata(InstanceMetadataProvider instanceMetadataProvider) { + if (instanceMetadataProvider == null) { + customSPIMetadata = Collections.emptyMap(); + customSPITransitiveMetadata = Collections.emptyMap(); + return; + } + + // resolve all metadata + Map allMetadata = instanceMetadataProvider.getMetadata(); + if (allMetadata == null) { + customSPIMetadata = Collections.emptyMap(); + } + else { + customSPIMetadata = Collections.unmodifiableMap(allMetadata); + } + + // resolve transitive metadata + Set transitiveKeys = instanceMetadataProvider.getTransitiveMetadataKeys(); + Map transitiveMetadata = new HashMap<>(); + if (!CollectionUtils.isEmpty(transitiveKeys)) { + for (String key : transitiveKeys) { + if (customSPIMetadata.containsKey(key)) { + transitiveMetadata.put(key, customSPIMetadata.get(key)); + } + } + } + customSPITransitiveMetadata = Collections.unmodifiableMap(transitiveMetadata); + } + private void merge() { - // env priority is bigger than config + // the priority is : custom > env > config Map mergedMetadataResult = new HashMap<>(); mergedMetadataResult.putAll(configMetadata); mergedMetadataResult.putAll(envMetadata); + mergedMetadataResult.putAll(customSPIMetadata); + // set location info as metadata + mergedMetadataResult.putAll(getLocationMetadata()); this.mergedStaticMetadata = Collections.unmodifiableMap(mergedMetadataResult); Map mergedTransitiveMetadataResult = new HashMap<>(); mergedTransitiveMetadataResult.putAll(configTransitiveMetadata); mergedTransitiveMetadataResult.putAll(envTransitiveMetadata); + mergedTransitiveMetadataResult.putAll(customSPITransitiveMetadata); this.mergedStaticTransitiveMetadata = Collections.unmodifiableMap(mergedTransitiveMetadataResult); } - private void parseLocationMetadata() { - zone = System.getenv(ENV_METADATA_ZONE); - region = System.getenv(ENV_METADATA_REGION); - campus = System.getenv(ENV_METADATA_CAMPUS); + private void parseLocationMetadata(MetadataLocalProperties metadataLocalProperties, + InstanceMetadataProvider instanceMetadataProvider) { + // resolve zone info + if (instanceMetadataProvider != null) { + zone = instanceMetadataProvider.getZone(); + } + if (StringUtils.isBlank(zone)) { + zone = System.getenv(ENV_METADATA_ZONE); + } + if (StringUtils.isBlank(zone)) { + zone = metadataLocalProperties.getContent().get(LOCATION_KEY_ZONE); + } + + // resolve region info + if (instanceMetadataProvider != null) { + region = instanceMetadataProvider.getRegion(); + } + if (StringUtils.isBlank(region)) { + region = System.getenv(ENV_METADATA_REGION); + } + if (StringUtils.isBlank(region)) { + region = metadataLocalProperties.getContent().get(LOCATION_KEY_REGION); + } + + // resolve campus info + if (instanceMetadataProvider != null) { + campus = instanceMetadataProvider.getCampus(); + } + if (StringUtils.isBlank(campus)) { + campus = System.getenv(ENV_METADATA_CAMPUS); + } + if (StringUtils.isBlank(campus)) { + campus = metadataLocalProperties.getContent().get(LOCATION_KEY_CAMPUS); + } } public Map getAllEnvMetadata() { @@ -163,6 +236,14 @@ public class StaticMetadataManager { return configTransitiveMetadata; } + public Map getAllCustomMetadata() { + return customSPIMetadata; + } + + public Map getCustomSPITransitiveMetadata() { + return customSPITransitiveMetadata; + } + public Map getMergedStaticMetadata() { return mergedStaticMetadata; } @@ -204,6 +285,8 @@ public class StaticMetadataManager { ", envTransitiveMetadata=" + envTransitiveMetadata + ", configMetadata=" + configMetadata + ", configTransitiveMetadata=" + configTransitiveMetadata + + ", customSPIMetadata=" + customSPIMetadata + + ", customSPITransitiveMetadata=" + customSPITransitiveMetadata + ", mergedStaticMetadata=" + mergedStaticMetadata + ", mergedStaticTransitiveMetadata=" + mergedStaticTransitiveMetadata + ", zone='" + zone + '\'' + diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java index 5bcc0fd34..9874b77d3 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java @@ -20,18 +20,20 @@ package com.tencent.cloud.common.metadata.config; import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.filter.gateway.MetadataFirstScgFilter; +import com.tencent.cloud.common.spi.InstanceMetadataProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.lang.Nullable; /** * Metadata auto configuration. * * @author Haotian Zhang */ -@Configuration +@Configuration(proxyBeanMethods = false) public class MetadataAutoConfiguration { /** @@ -44,22 +46,21 @@ public class MetadataAutoConfiguration { } @Bean - public StaticMetadataManager metadataManager(MetadataLocalProperties metadataLocalProperties) { - return new StaticMetadataManager(metadataLocalProperties); + public StaticMetadataManager metadataManager(MetadataLocalProperties metadataLocalProperties, + @Nullable InstanceMetadataProvider instanceMetadataProvider) { + return new StaticMetadataManager(metadataLocalProperties, instanceMetadataProvider); } /** * Create when gateway application is SCG. */ - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnClass(name = "org.springframework.cloud.gateway.filter.GlobalFilter") - static class MetadataScgFilterConfig { + protected static class MetadataScgFilterConfig { @Bean public GlobalFilter metadataFirstScgFilter() { return new MetadataFirstScgFilter(); } - } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java index e65a80ccd..0d0039bc3 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java @@ -64,5 +64,4 @@ public class MetadataLocalProperties { public void setTransitive(List transitive) { this.transitive = transitive; } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpoint.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpoint.java new file mode 100644 index 000000000..360018ea2 --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpoint.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.common.metadata.endpoint; + +import java.util.HashMap; +import java.util.Map; + +import com.tencent.cloud.common.metadata.StaticMetadataManager; + +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; + +/** + * Endpoint of polaris's metadata. + * + * @author shuiqingliu + **/ +@Endpoint(id = "polaris-metadata") +public class PolarisMetadataEndpoint { + + private final StaticMetadataManager staticMetadataManager; + + public PolarisMetadataEndpoint(StaticMetadataManager staticMetadataManager) { + this.staticMetadataManager = staticMetadataManager; + } + + @ReadOperation + public Map metadata() { + Map result = new HashMap<>(); + result.put("Env", staticMetadataManager.getAllEnvMetadata()); + result.put("EnvTransitive", staticMetadataManager.getEnvTransitiveMetadata()); + result.put("ConfigTransitive", staticMetadataManager.getConfigTransitiveMetadata()); + result.put("Config", staticMetadataManager.getAllConfigMetadata()); + result.put("MergeStatic", staticMetadataManager.getMergedStaticMetadata()); + result.put("CustomSPI", staticMetadataManager.getCustomSPITransitiveMetadata()); + result.put("zone", staticMetadataManager.getZone()); + result.put("region", staticMetadataManager.getRegion()); + result.put("campus", staticMetadataManager.getCampus()); + return result; + } +} diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointAutoConfiguration.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointAutoConfiguration.java new file mode 100644 index 000000000..9c87587c9 --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointAutoConfiguration.java @@ -0,0 +1,44 @@ +/* + * 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.common.metadata.endpoint; + +import com.tencent.cloud.common.metadata.StaticMetadataManager; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * The AutoConfiguration for metadata endpoint. + * + * @author shuiqingliu + **/ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Endpoint.class) +public class PolarisMetadataEndpointAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + public PolarisMetadataEndpoint metadataEndpoint(StaticMetadataManager staticMetadataManager) { + return new PolarisMetadataEndpoint(staticMetadataManager); + } +} diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/filter/gateway/MetadataFirstScgFilter.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/filter/gateway/MetadataFirstScgFilter.java index a79ba5323..6cc17a9c1 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/filter/gateway/MetadataFirstScgFilter.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/filter/gateway/MetadataFirstScgFilter.java @@ -61,5 +61,4 @@ public class MetadataFirstScgFilter implements GlobalFilter, Ordered { return chain.filter(exchange); } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.java index 9318c1ad4..787abe3bf 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.java @@ -93,5 +93,4 @@ public class PolarisServiceInstance implements ServiceInstance { public String getScheme() { return this.scheme; } - } diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/spi/InstanceMetadataProvider.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/InstanceMetadataProvider.java similarity index 73% rename from spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/spi/InstanceMetadataProvider.java rename to spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/InstanceMetadataProvider.java index 6b2b73a6b..5434aa140 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/spi/InstanceMetadataProvider.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/InstanceMetadataProvider.java @@ -16,13 +16,15 @@ * */ -package com.tencent.cloud.polaris.context.spi; +package com.tencent.cloud.common.spi; +import java.util.Collections; import java.util.Map; +import java.util.Set; /** - * * Instance's custom metadata, metadata will be register to polaris server. + * * @author lepdou 2022-06-16 */ public interface InstanceMetadataProvider { @@ -30,26 +32,41 @@ public interface InstanceMetadataProvider { /** * @return the metadata of instance. */ - Map getMetadata(); + default Map getMetadata() { + return Collections.emptyMap(); + } + + /** + * @return the keys of transitive metadata. + */ + default Set getTransitiveMetadataKeys() { + return Collections.emptySet(); + } /** * The region of current instance. * * @return the region info. */ - String getRegion(); + default String getRegion() { + return ""; + } /** * The zone of current instance. * * @return the zone info. */ - String getZone(); + default String getZone() { + return ""; + } /** * The campus/datacenter of current instance. * * @return the campus or datacenter info. */ - String getCampus(); + default String getCampus() { + return ""; + } } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java index 1133bb35c..0faf3d66f 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java @@ -35,7 +35,6 @@ public final class AddressUtils { private static final String ADDRESS_SEPARATOR = ","; private AddressUtils() { - } public static List parseAddressList(String addressInfo) { @@ -50,5 +49,4 @@ public final class AddressUtils { } return addressList; } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java index 9c6aff74d..b611cc04f 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java @@ -20,6 +20,7 @@ package com.tencent.cloud.common.util; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; /** @@ -41,7 +42,7 @@ public class ApplicationContextAwareUtils implements ApplicationContextAware { } @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException { ApplicationContextAwareUtils.applicationContext = applicationContext; } @@ -63,5 +64,4 @@ public class ApplicationContextAwareUtils implements ApplicationContextAware { public static String getProperties(String key, String defaultValue) { return applicationContext.getEnvironment().getProperty(key, defaultValue); } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java index 715a154fc..7bfd0c872 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java @@ -28,9 +28,13 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory; /** * the utils for bean factory. + * * @author lepdou 2022-05-23 */ -public class BeanFactoryUtils { +public final class BeanFactoryUtils { + + private BeanFactoryUtils() { + } public static List getBeans(BeanFactory beanFactory, Class requiredType) { if (!(beanFactory instanceof DefaultListableBeanFactory)) { diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java index a4c53ccc1..4c10b6ab9 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java @@ -40,11 +40,9 @@ import org.springframework.web.server.ServerWebExchange; /** * the utils for parse label expression. * - * @author lepdou 2022-05-13 - * @author cheese8 2022-06-20 + * @author lepdou, cheese8 */ -public class ExpressionLabelUtils { - +public final class ExpressionLabelUtils { /** * the expression prefix of header label. */ @@ -81,6 +79,8 @@ public class ExpressionLabelUtils { * the suffix of expression. */ public static final String LABEL_SUFFIX = "}"; + private ExpressionLabelUtils() { + } public static boolean isExpressionLabel(String labelKey) { if (StringUtils.isEmpty(labelKey)) { diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java index a30fc8bc1..ac7288f61 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java @@ -30,7 +30,7 @@ import org.springframework.util.StringUtils; /** * Utils for Jackson. * - * @author Haotian Zhang + * @author Haotian Zhang, cheese8 */ public final class JacksonUtils { @@ -80,10 +80,8 @@ public final class JacksonUtils { } catch (JsonProcessingException e) { LOG.error( - "Json to map failed. check if the format of the json string[{}] is correct.", - jsonStr, e); + "Json to map failed. check if the format of the json string[{}] is correct.", jsonStr, e); throw new RuntimeException("Json to map failed.", e); } } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java index 6c4a3353e..ef706673f 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java @@ -27,7 +27,6 @@ import java.lang.reflect.Field; public final class ReflectionUtils { private ReflectionUtils() { - } public static Object getFieldValue(Object instance, String fieldName) { @@ -48,5 +47,4 @@ public final class ReflectionUtils { } return null; } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ResourceFileUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ResourceFileUtils.java index b5ea45d5d..66f8ae6c6 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ResourceFileUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ResourceFileUtils.java @@ -46,5 +46,4 @@ public final class ResourceFileUtils { } return ""; } - } diff --git a/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories index ba9f2b867..4c54d3372 100644 --- a/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories @@ -1,3 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.common.util.ApplicationContextAwareUtils,\ - com.tencent.cloud.common.metadata.config.MetadataAutoConfiguration + com.tencent.cloud.common.metadata.config.MetadataAutoConfiguration,\ + com.tencent.cloud.common.metadata.endpoint.PolarisMetadataEndpointAutoConfiguration diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java index 700f75568..811b3c2d5 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java @@ -36,7 +36,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = MetadataContextHolderTest.TestApplication.class, - properties = { "spring.config.location = classpath:application-test.yml" }) + properties = {"spring.config.location = classpath:application-test.yml"}) public class MetadataContextHolderTest { @Test @@ -77,5 +77,4 @@ public class MetadataContextHolderTest { protected static class TestApplication { } - } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java new file mode 100644 index 000000000..085b13e21 --- /dev/null +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java @@ -0,0 +1,186 @@ +/* + * 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.common.metadata; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.common.spi.InstanceMetadataProvider; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.util.CollectionUtils; + +import static org.mockito.Mockito.when; + + +/** + * test for {@link StaticMetadataManager}. + * + * @author lepdou 2022-06-27 + */ +@RunWith(MockitoJUnitRunner.class) +public class StaticMetadataManagerTest { + + @Mock + private MetadataLocalProperties metadataLocalProperties; + + @Test + public void testParseConfigMetadata() { + Map content = new HashMap<>(); + content.put("k1", "v1"); + content.put("k2", "v22"); + content.put("zone", "zone1"); + content.put("region", "region1"); + + when(metadataLocalProperties.getContent()).thenReturn(content); + when(metadataLocalProperties.getTransitive()).thenReturn(Collections.singletonList("k1")); + + StaticMetadataManager metadataManager = new StaticMetadataManager(metadataLocalProperties, null); + + Map metadata = metadataManager.getAllConfigMetadata(); + Assert.assertEquals(4, metadata.size()); + Assert.assertEquals("v1", metadata.get("k1")); + Assert.assertEquals("v22", metadata.get("k2")); + + Map transitiveMetadata = metadataManager.getConfigTransitiveMetadata(); + Assert.assertEquals(1, transitiveMetadata.size()); + Assert.assertEquals("v1", transitiveMetadata.get("k1")); + + Assert.assertEquals("zone1", metadataManager.getZone()); + Assert.assertEquals("region1", metadataManager.getRegion()); + + Map locationInfo = metadataManager.getLocationMetadata(); + Assert.assertEquals("zone1", locationInfo.get("zone")); + Assert.assertEquals("region1", locationInfo.get("region")); + } + + @Test + public void testCustomSPIMetadata() { + Map content = new HashMap<>(); + content.put("k1", "v1"); + content.put("k2", "v2"); + + when(metadataLocalProperties.getContent()).thenReturn(content); + when(metadataLocalProperties.getTransitive()).thenReturn(Collections.singletonList("k1")); + + StaticMetadataManager metadataManager = new StaticMetadataManager(metadataLocalProperties, + new MockedMetadataProvider()); + + Map metadata = metadataManager.getAllCustomMetadata(); + Assert.assertEquals(3, metadata.size()); + Assert.assertEquals("v1", metadata.get("k1")); + Assert.assertEquals("v22", metadata.get("k2")); + Assert.assertEquals("v33", metadata.get("k3")); + + Map transitiveMetadata = metadataManager.getCustomSPITransitiveMetadata(); + Assert.assertEquals(1, transitiveMetadata.size()); + Assert.assertEquals("v22", metadata.get("k2")); + + Assert.assertEquals("zone2", metadataManager.getZone()); + Assert.assertEquals("region1", metadataManager.getRegion()); + + Map locationInfo = metadataManager.getLocationMetadata(); + Assert.assertEquals("zone2", locationInfo.get("zone")); + Assert.assertEquals("region1", locationInfo.get("region")); + } + + @Test + public void testMergedMetadata() { + Map content = new HashMap<>(); + content.put("k1", "v1"); + content.put("k2", "v2"); + content.put("zone", "zone1"); + content.put("region", "region1"); + content.put("campus", "campus1"); + + when(metadataLocalProperties.getContent()).thenReturn(content); + when(metadataLocalProperties.getTransitive()).thenReturn(Collections.singletonList("k1")); + + StaticMetadataManager metadataManager = new StaticMetadataManager(metadataLocalProperties, + new MockedMetadataProvider()); + + Map metadata = metadataManager.getMergedStaticMetadata(); + Assert.assertEquals(6, metadata.size()); + Assert.assertEquals("v1", metadata.get("k1")); + Assert.assertEquals("v22", metadata.get("k2")); + Assert.assertEquals("v33", metadata.get("k3")); + Assert.assertEquals("zone2", metadata.get("zone")); + Assert.assertEquals("region1", metadata.get("region")); + Assert.assertEquals("campus1", metadata.get("campus")); + + Map transitiveMetadata = metadataManager.getMergedStaticTransitiveMetadata(); + Assert.assertEquals(2, transitiveMetadata.size()); + Assert.assertEquals("v1", metadata.get("k1")); + Assert.assertEquals("v22", metadata.get("k2")); + + Assert.assertEquals("zone2", metadataManager.getZone()); + Assert.assertEquals("region1", metadataManager.getRegion()); + + Assert.assertTrue(CollectionUtils.isEmpty(metadataManager.getAllEnvMetadata())); + Assert.assertTrue(CollectionUtils.isEmpty(metadataManager.getEnvTransitiveMetadata())); + + Map locationInfo = metadataManager.getLocationMetadata(); + Assert.assertEquals("zone2", locationInfo.get("zone")); + Assert.assertEquals("region1", locationInfo.get("region")); + Assert.assertEquals("campus1", locationInfo.get("campus")); + + } + + static class MockedMetadataProvider implements InstanceMetadataProvider { + + @Override + public Map getMetadata() { + Map metadata = new HashMap<>(); + metadata.put("k1", "v1"); + metadata.put("k2", "v22"); + metadata.put("k3", "v33"); + return metadata; + } + + @Override + public Set getTransitiveMetadataKeys() { + Set transitiveKeys = new HashSet<>(); + transitiveKeys.add("k2"); + return transitiveKeys; + } + + @Override + public String getRegion() { + return "region1"; + } + + @Override + public String getZone() { + return "zone2"; + } + + @Override + public String getCampus() { + return null; + } + } +} diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java index fb19efb18..5dd740882 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java @@ -84,5 +84,4 @@ public class MetadataAutoConfigurationTest { Assertions.assertThat(context).hasSingleBean(MetadataFirstScgFilter.class); }); } - } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataLocalPropertiesTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataLocalPropertiesTest.java index 815010ce1..94de98e22 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataLocalPropertiesTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataLocalPropertiesTest.java @@ -34,7 +34,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = MetadataLocalPropertiesTest.TestApplication.class, - properties = { "spring.config.location = classpath:application-test.yml" }) + properties = {"spring.config.location = classpath:application-test.yml"}) public class MetadataLocalPropertiesTest { @Autowired @@ -59,5 +59,4 @@ public class MetadataLocalPropertiesTest { protected static class TestApplication { } - } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointTests.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointTests.java new file mode 100644 index 000000000..d20a2fd4f --- /dev/null +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointTests.java @@ -0,0 +1,58 @@ +/* + * 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.common.metadata.endpoint; + +import java.util.HashMap; +import java.util.Map; + +import com.tencent.cloud.common.metadata.StaticMetadataManager; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +/** + * Test for polaris metadata endpoint. + * + * @author shuiqingliu + */ +@RunWith(MockitoJUnitRunner.class) +public class PolarisMetadataEndpointTests { + + @Mock + private StaticMetadataManager staticMetadataManager; + + @Test + public void testPolarisMetadataEndpoint() { + Map envMetadata = new HashMap<>(); + envMetadata.put("k1", "v1"); + envMetadata.put("k2", "v2"); + envMetadata.put("k3", "v3"); + + when(staticMetadataManager.getAllEnvMetadata()).thenReturn(envMetadata); + + PolarisMetadataEndpoint polarisMetadataEndpoint = new PolarisMetadataEndpoint(staticMetadataManager); + Map metaMap = polarisMetadataEndpoint.metadata(); + assertThat(envMetadata).isEqualTo(metaMap.get("Env")); + } +} diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/AddressUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/AddressUtilsTest.java index 8040e7add..ca50c3604 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/AddressUtilsTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/AddressUtilsTest.java @@ -26,8 +26,9 @@ import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; /** - * test for {@link AddressUtils} - *@author lepdou 2022-05-27 + * test for {@link AddressUtils}. + * + * @author lepdou 2022-05-27 */ @RunWith(MockitoJUnitRunner.class) public class AddressUtilsTest { diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java index 46b3fa1fe..cc1eda27d 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java @@ -37,9 +37,9 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.server.MockServerWebExchange; /** - * test for {@link ExpressionLabelUtils} - * @author lepdou 2022-05-27 - * @author cheese8 2022-06-20 + * test for {@link ExpressionLabelUtils}. + * + * @author lepdou, cheese8 */ @RunWith(MockitoJUnitRunner.class) public class ExpressionLabelUtilsTest { @@ -210,5 +210,4 @@ public class ExpressionLabelUtilsTest { Assert.assertNull(result.get(invalidLabel8)); Assert.assertNull(result.get(invalidLabel9)); } - } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java index db0868dff..e07dcceb2 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java @@ -26,12 +26,12 @@ import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Test for {@link JacksonUtils}. * - * @author lepdou, Haotian Zhang + * @author lepdou, Haotian Zhang, cheese8 */ @RunWith(MockitoJUnitRunner.class) public class JacksonUtilsTest { @@ -42,10 +42,7 @@ public class JacksonUtilsTest { sourceMap.put("k1", "v1"); sourceMap.put("k2", "v2"); sourceMap.put("k3", "v3"); - - String jsonStr = JacksonUtils.serialize2Json(sourceMap); - - assertThat(jsonStr).isEqualTo("{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\"}"); + assertThat(JacksonUtils.serialize2Json(sourceMap)).isEqualTo("{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\"}"); } @Test @@ -56,20 +53,19 @@ public class JacksonUtilsTest { assertThat(map.get("k1")).isEqualTo("v1"); assertThat(map.get("k2")).isEqualTo("v2"); assertThat(map.get("k3")).isEqualTo("v3"); + } - assertThat(JacksonUtils.deserialize2Map("")).isNotNull(); - assertThat(JacksonUtils.deserialize2Map("")).isEmpty(); + @Test + public void testDeserializeBlankIntoEmptyMap() { + Map map = JacksonUtils.deserialize2Map(""); + assertThat(map).isNotNull(); + assertThat(map).isEmpty(); + } - jsonStr = "{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\""; - try { - JacksonUtils.deserialize2Map(jsonStr); - fail("RuntimeException should be thrown."); - } - catch (RuntimeException exception) { - assertThat(exception.getMessage()).isEqualTo("Json to map failed."); - } - catch (Throwable throwable) { - fail("RuntimeException should be thrown."); - } + @Test + public void testDeserializeThrowsRuntimeException() { + String jsonStr = "{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\""; + assertThatThrownBy(() -> JacksonUtils.deserialize2Map(jsonStr)) + .isExactlyInstanceOf(RuntimeException.class).hasMessage("Json to map failed."); } } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ResourceFileUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ResourceFileUtilsTest.java index 769d99ce7..a3cb8a96c 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ResourceFileUtilsTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ResourceFileUtilsTest.java @@ -26,8 +26,9 @@ import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; /** - * test for {@link ResourceFileUtils} - *@author lepdou 2022-05-27 + * test for {@link ResourceFileUtils}. + * + * @author lepdou 2022-05-27 */ @RunWith(MockitoJUnitRunner.class) public class ResourceFileUtilsTest { diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 4bcf54c97..af9b3c69c 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -73,7 +73,7 @@ 1.6.0-2020.0.5-SNAPSHOT - 1.6.1 + 1.7.0-SNAPSHOT 1.2.11 4.5.1 1.12.10 diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/resources/bootstrap.yml index 89d1f233b..a390f51a6 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/resources/bootstrap.yml @@ -24,3 +24,9 @@ spring: # Assigned which metadata key-value will be passed along the link transitive: - CUSTOM-METADATA-KEY-TRANSITIVE +management: + endpoints: + web: + exposure: + include: + - polaris-metadata \ No newline at end of file diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java index 1c96db6c9..3db7df8f3 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java @@ -35,7 +35,7 @@ import org.springframework.web.client.RestTemplate; public class ServiceA { public static void main(String[] args) { - SpringApplication.run(ServiceA.class); + SpringApplication.run(ServiceA.class, args); } @Bean @@ -43,5 +43,4 @@ public class ServiceA { public RestTemplate restTemplate() { return new RestTemplate(); } - } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java index ebfea6716..73fc55bd3 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java @@ -48,6 +48,11 @@ public class ServiceAController { return polarisServiceB.info(); } + @GetMapping("/getBServiceInfoByRestTemplate") + public String getBServiceInfoByRestTemplate() { + return restTemplate.getForObject("http://polaris-circuitbreaker-example-b/example/service/b/info", String.class); + } + /** * Get info of Service B by RestTemplate. * @return info of Service B @@ -58,5 +63,4 @@ public class ServiceAController { .getForEntity("http://polaris-circuitbreaker-example-b/example/service/b/info", String.class); return entity.getBody(); } - } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java index 7354da537..c8c32bf24 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java @@ -29,7 +29,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; public class ServiceB { public static void main(String[] args) { - SpringApplication.run(ServiceB.class); + SpringApplication.run(ServiceB.class, args); } - } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java index 67540c2c9..99b8410d8 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java @@ -18,7 +18,6 @@ package com.tencent.cloud.polaris.circuitbreaker.example; -import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -32,21 +31,12 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/example/service/b") public class ServiceBController { - @Value("${is-throw-runtime-exception:#{false}}") - private boolean isThrowRuntimeException; - /** * Get service information. * @return service information */ @GetMapping("/info") public String info() { - if (isThrowRuntimeException) { - throw new RuntimeException("failed for call my service"); - } - else { - return "hello world ! I'm a service B1"; - } + return "hello world ! I'm a service B1"; } - } 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 4aba50500..3805dfa5e 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,4 +8,3 @@ spring: address: grpc://183.47.111.80:8091 namespace: default enabled: true -is-throw-runtime-exception: false diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java index 4aacc0d22..fb6bdc687 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java @@ -30,7 +30,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; public class ServiceB2 { public static void main(String[] args) { - SpringApplication.run(ServiceB2.class); + SpringApplication.run(ServiceB2.class, args); } - } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java index 7e4bb9b4c..83dc45303 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java @@ -18,9 +18,10 @@ package com.tencent.cloud.polaris.ciruitbreaker.example; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; /** @@ -32,21 +33,13 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/example/service/b") public class ServiceBController { - @Value("${is-throw-runtime-exception:#{false}}") - private boolean isThrowRuntimeException; - /** * Get service information. * @return service information */ @GetMapping("/info") + @ResponseStatus(value = HttpStatus.BAD_GATEWAY, reason = "failed for call my service") public String info() { - if (isThrowRuntimeException) { - throw new RuntimeException("failed for call my service"); - } - else { - return "hello world ! I'm a service B2"; - } + return "failed for call service B2"; } - } 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 b150a5424..f3720f09c 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,4 +8,3 @@ spring: address: grpc://183.47.111.80:8091 namespace: default enabled: true -is-throw-runtime-exception: true diff --git a/spring-cloud-tencent-examples/polaris-config-example/pom.xml b/spring-cloud-tencent-examples/polaris-config-example/pom.xml index cef91e5a3..bb7ef026e 100644 --- a/spring-cloud-tencent-examples/polaris-config-example/pom.xml +++ b/spring-cloud-tencent-examples/polaris-config-example/pom.xml @@ -24,6 +24,41 @@ com.tencent.cloud spring-cloud-starter-tencent-polaris-config + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.0 + + + attach-sources + + jar + + + + + + + diff --git a/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml index 38ed7eed0..1f257a787 100644 --- a/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml @@ -12,3 +12,9 @@ spring: groups: - name: ${spring.application.name} # group name files: [ "config/application.properties", "config/bootstrap.yml" ] # config/application.properties takes precedence over config/bootstrap.yml +management: + endpoints: + web: + exposure: + include: + - polaris-config diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/CustomMetadata.java b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/CustomMetadata.java index efe3f8167..9504e9758 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/CustomMetadata.java +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/CustomMetadata.java @@ -21,7 +21,7 @@ package com.tencent.cloud.polaris.discovery.service.callee; import java.util.HashMap; import java.util.Map; -import com.tencent.cloud.polaris.context.spi.InstanceMetadataProvider; +import com.tencent.cloud.common.spi.InstanceMetadataProvider; import org.springframework.stereotype.Component; @@ -39,18 +39,8 @@ public class CustomMetadata implements InstanceMetadataProvider { return metadata; } - @Override - public String getRegion() { - return "shanghai"; - } - @Override public String getZone() { - return null; - } - - @Override - public String getCampus() { - return null; + return "shanghai-zone-1"; } } 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 5461bcc10..75b4e33d9 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,10 @@ spring: discovery: enabled: true register: true + tencent: + metadata: + content: + region: shanghai # consul: # port: 8500 # host: 127.0.0.1 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 e9ccc1f29..fcfdad35b 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 @@ -5,6 +5,10 @@ spring: application: name: DiscoveryCallerService cloud: + tencent: + metadata: + content: + region: shanghai polaris: address: grpc://183.47.111.80:8091 namespace: default @@ -32,3 +36,9 @@ spring: # client: # serviceUrl: # defaultZone: http://127.0.0.1:7654/eureka/ +management: + endpoints: + web: + exposure: + include: + - polaris-discovery \ No newline at end of file diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/README.md b/spring-cloud-tencent-examples/polaris-gateway-example/README.md index 43bd680f6..b1bb35671 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/README.md +++ b/spring-cloud-tencent-examples/polaris-gateway-example/README.md @@ -2,7 +2,7 @@ ## Example Introduction -This example shows how to use ```spring-cloud-tencent-polaris-gateway`` in Spring Cloud project for its features. +This example shows how to use ```spring-cloud-tencent-polaris-gateway``` in Spring Cloud project for its features. This example contains ```gateway-zuul-service```, ```gateway-scg-service``` and ```gateway-callee-service```. ```gateway-zuul-service``` and ```gateway-scg-service``` invoke ```gateway-callee-service```. diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeController.java b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeController.java index e270cdae0..c603c3cea 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeController.java +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeController.java @@ -29,6 +29,8 @@ import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; + /** * Gateway callee controller. * @@ -63,8 +65,8 @@ public class GatewayCalleeController { @RequestMapping("/echo") public String echoHeader(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String metadataStr) throws UnsupportedEncodingException { - LOG.info(URLDecoder.decode(metadataStr, "UTF-8")); - return URLDecoder.decode(metadataStr, "UTF-8"); + LOG.info(URLDecoder.decode(metadataStr, UTF_8)); + return URLDecoder.decode(metadataStr, UTF_8); } } diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/bootstrap.yml index 2d0d75a41..c6d40440f 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/bootstrap.yml @@ -5,6 +5,10 @@ spring: application: name: GatewayCalleeService cloud: + tencent: + metadata: + content: + env: blue polaris: address: grpc://183.47.111.80:8091 namespace: default diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/pom.xml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/pom.xml new file mode 100644 index 000000000..842363af9 --- /dev/null +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/pom.xml @@ -0,0 +1,28 @@ + + + + polaris-gateway-example + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + gateway-callee-service2 + Spring Cloud Starter Tencent Polaris Gateway Callee Example + + + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-discovery + + + + org.springframework.boot + spring-boot-starter-web + + + + diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeApplication.java b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeApplication.java new file mode 100644 index 000000000..4e5e816bd --- /dev/null +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeApplication.java @@ -0,0 +1,35 @@ +/* + * 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.gateway.example.callee; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Gateway callee application. + * + * @author Haotian Zhang + */ +@SpringBootApplication +public class GatewayCalleeApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayCalleeApplication.class, args); + } + +} diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeController.java b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeController.java new file mode 100644 index 000000000..c603c3cea --- /dev/null +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeController.java @@ -0,0 +1,72 @@ +/* + * 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.gateway.example.callee; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; + +import com.tencent.cloud.common.constant.MetadataConstant; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; + +/** + * Gateway callee controller. + * + * @author Haotian Zhang + */ +@RestController +@RequestMapping("/gateway/example/callee") +public class GatewayCalleeController { + + private static Logger LOG = LoggerFactory.getLogger(GatewayCalleeController.class); + + @Value("${server.port:0}") + private int port; + + /** + * Get information of callee. + * @return information of callee + */ + @RequestMapping("/info") + public String info() { + LOG.info("Gateway Example Callee [{}] is called.", port); + return String.format("Gateway Example Callee [%s] is called.", port); + } + + /** + * Get metadata in HTTP header. + * + * @param metadataStr metadata string + * @return metadata in HTTP header + * @throws UnsupportedEncodingException encoding exception + */ + @RequestMapping("/echo") + public String echoHeader(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String metadataStr) + throws UnsupportedEncodingException { + LOG.info(URLDecoder.decode(metadataStr, UTF_8)); + return URLDecoder.decode(metadataStr, UTF_8); + } + +} diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..a0cf12581 --- /dev/null +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/resources/bootstrap.yml @@ -0,0 +1,14 @@ +server: + session-timeout: 1800 + port: 48082 +spring: + application: + name: GatewayCalleeService + cloud: + tencent: + metadata: + content: + env: green + polaris: + address: grpc://183.47.111.80:8091 + namespace: default diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/pom.xml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/pom.xml index 8b8b50bf6..b6643b49d 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/pom.xml @@ -26,7 +26,7 @@ com.tencent.cloud - spring-cloud-starter-tencent-metadata-transfer + spring-cloud-starter-tencent-polaris-router @@ -39,4 +39,4 @@ spring-cloud-loadbalancer - \ No newline at end of file + diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml index 5d949573b..55f03dfa3 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml @@ -9,14 +9,10 @@ spring: metadata: content: a: 1 - transitive: - - a polaris: address: grpc://183.47.111.80:8091 namespace: default enabled: true - discovery: - service-list-refresh-interval: 1000 gateway: discovery: locator: diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/pom.xml b/spring-cloud-tencent-examples/polaris-gateway-example/pom.xml index 2607823df..e67b8a8dd 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/pom.xml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/pom.xml @@ -17,6 +17,7 @@ gateway-scg-service gateway-callee-service + gateway-callee-service2 @@ -34,4 +35,4 @@ - \ No newline at end of file + diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml index bf89b34d6..4bbda499b 100644 --- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml @@ -28,6 +28,10 @@ spring-cloud-starter-tencent-polaris-ratelimit + + org.springframework.boot + spring-boot-starter-actuator + diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java index 92f1354c8..17b14efa9 100644 --- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java @@ -17,6 +17,7 @@ package com.tencent.cloud.ratelimit.example.service.callee; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -64,24 +65,28 @@ public class BusinessController { } @GetMapping("/invoke") - public String invokeInfo() { - StringBuilder builder = new StringBuilder(); + public String invokeInfo() throws InterruptedException { + StringBuffer builder = new StringBuffer(); + CountDownLatch count = new CountDownLatch(30); for (int i = 0; i < 30; i++) { - try { - ResponseEntity entity = restTemplate.getForEntity("http://" + appName + "/business/info", - String.class); - builder.append(entity.getBody()).append("
"); - } - catch (RestClientException e) { - if (e instanceof TooManyRequests) { - builder.append(((TooManyRequests) e).getResponseBodyAsString()).append(index.incrementAndGet()) - .append("
"); + new Thread(() -> { + try { + ResponseEntity entity = restTemplate.getForEntity("http://" + appName + "/business/info", + String.class); + builder.append(entity.getBody() + "\n"); } - else { - throw e; + catch (RestClientException e) { + if (e instanceof TooManyRequests) { + builder.append("TooManyRequests " + index.incrementAndGet() + "\n"); + } + else { + throw e; + } } - } + count.countDown(); + }).start(); } + count.await(); return builder.toString(); } diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml index 37c986394..ebf385deb 100644 --- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml @@ -11,4 +11,14 @@ spring: ratelimit: enabled: true rejectRequestTipsFilePath: reject-tips.html - maxQueuingTime: 500 + maxQueuingTime: 1000 + +management: + endpoints: + web: + exposure: + include: + - polaris-ratelimit +logging: + level: + com.tencent.cloud.polaris: debug diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ModifyAddress.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ModifyAddress.java index 565849774..a7a1e551c 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ModifyAddress.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ModifyAddress.java @@ -22,6 +22,7 @@ import java.util.List; import com.tencent.cloud.common.constant.ContextConstant; import com.tencent.cloud.common.util.AddressUtils; +import com.tencent.cloud.polaris.context.config.PolarisContextProperties; import com.tencent.polaris.factory.config.ConfigurationImpl; import org.apache.commons.lang.StringUtils; @@ -52,5 +53,4 @@ public class ModifyAddress implements PolarisConfigModifier { public int getOrder() { return ContextConstant.ModifierOrder.FIRST; } - } diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java index 0152b7b6b..3cae11cb2 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java @@ -37,5 +37,4 @@ public interface PolarisConfigModifier { * @return order */ int getOrder(); - } diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PostInitPolarisSDKContext.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PostInitPolarisSDKContext.java new file mode 100644 index 000000000..bf41c50bd --- /dev/null +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PostInitPolarisSDKContext.java @@ -0,0 +1,51 @@ +/* + * 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; + +import com.tencent.cloud.common.metadata.StaticMetadataManager; +import com.tencent.polaris.api.plugin.common.ValueContext; +import com.tencent.polaris.api.plugin.route.LocationLevel; +import com.tencent.polaris.client.api.SDKContext; +import org.apache.commons.lang.StringUtils; + +/** + * After all configurations are loaded, post-initialize SDKContext. + * + * @author lepdou 2022-06-28 + */ +public class PostInitPolarisSDKContext { + + public PostInitPolarisSDKContext(SDKContext sdkContext, StaticMetadataManager staticMetadataManager) { + // set instance's location info + String region = staticMetadataManager.getRegion(); + String zone = staticMetadataManager.getZone(); + String campus = staticMetadataManager.getCampus(); + + ValueContext valueContext = sdkContext.getValueContext(); + if (StringUtils.isNotBlank(region)) { + valueContext.setValue(LocationLevel.region.name(), region); + } + if (StringUtils.isNotBlank(zone)) { + valueContext.setValue(LocationLevel.zone.name(), zone); + } + if (StringUtils.isNotBlank(campus)) { + valueContext.setValue(LocationLevel.campus.name(), campus); + } + } +} diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ServiceRuleManager.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ServiceRuleManager.java index 1a0af32b4..06d71f65c 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ServiceRuleManager.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ServiceRuleManager.java @@ -38,7 +38,7 @@ import com.tencent.polaris.client.pb.RoutingProto; /** * the manager of service governance rules. for example: rate limit rule, router rules. * - *@author lepdou 2022-05-13 + * @author lepdou 2022-05-13 */ public class ServiceRuleManager { diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextAutoConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java similarity index 58% rename from spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextAutoConfiguration.java rename to spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java index 5ead163dd..51ba3eb6c 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextAutoConfiguration.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java @@ -16,54 +16,34 @@ * */ -package com.tencent.cloud.polaris.context; +package com.tencent.cloud.polaris.context.config; -import com.tencent.cloud.common.metadata.StaticMetadataManager; -import com.tencent.cloud.common.metadata.config.MetadataAutoConfiguration; +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.exception.PolarisException; -import com.tencent.polaris.api.plugin.common.ValueContext; -import com.tencent.polaris.api.plugin.route.LocationLevel; import com.tencent.polaris.client.api.SDKContext; -import org.apache.commons.lang.StringUtils; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; /** * Autoconfiguration for Polaris {@link SDKContext}. * * @author Haotian Zhang */ +@Configuration(proxyBeanMethods = false) @ConditionalOnPolarisEnabled @EnableConfigurationProperties({PolarisContextProperties.class}) -@ImportAutoConfiguration(MetadataAutoConfiguration.class) public class PolarisContextAutoConfiguration { @Bean(name = "polarisContext", initMethod = "init", destroyMethod = "destroy") @ConditionalOnMissingBean - public SDKContext polarisContext(PolarisContextProperties properties, StaticMetadataManager staticMetadataManager) + public SDKContext polarisContext(PolarisContextProperties properties) throws PolarisException { - SDKContext sdkContext = SDKContext.initContextByConfig(properties.configuration()); - - // init current instance location info from environment - ValueContext valueContext = sdkContext.getValueContext(); - String region = staticMetadataManager.getRegion(); - String zone = staticMetadataManager.getZone(); - String campus = staticMetadataManager.getCampus(); - - if (StringUtils.isNotBlank(region)) { - valueContext.setValue(LocationLevel.region.name(), region); - } - if (StringUtils.isNotBlank(zone)) { - valueContext.setValue(LocationLevel.zone.name(), zone); - } - if (StringUtils.isNotBlank(campus)) { - valueContext.setValue(LocationLevel.campus.name(), campus); - } - - return sdkContext; + return SDKContext.initContextByConfig(properties.configuration()); } @Bean @@ -73,6 +53,7 @@ public class PolarisContextAutoConfiguration { } @Bean + @ConditionalOnMissingBean public ServiceRuleManager serviceRuleManager(SDKContext sdkContext) { return new ServiceRuleManager(sdkContext); } diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextBootstrapAutoConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextBootstrapAutoConfiguration.java similarity index 88% rename from spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextBootstrapAutoConfiguration.java rename to spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextBootstrapAutoConfiguration.java index c5b4efbd9..cc80454f4 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextBootstrapAutoConfiguration.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextBootstrapAutoConfiguration.java @@ -16,11 +16,12 @@ * */ -package com.tencent.cloud.polaris.context; +package com.tencent.cloud.polaris.context.config; import com.tencent.polaris.client.api.SDKContext; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; /** @@ -28,6 +29,7 @@ import org.springframework.context.annotation.Import; * * @author Haotian Zhang */ +@Configuration(proxyBeanMethods = false) @ConditionalOnProperty("spring.cloud.polaris.enabled") @Import(PolarisContextAutoConfiguration.class) public class PolarisContextBootstrapAutoConfiguration { diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextPostConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextPostConfiguration.java new file mode 100644 index 000000000..85ea11727 --- /dev/null +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextPostConfiguration.java @@ -0,0 +1,40 @@ +/* + * 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.config; + +import com.tencent.cloud.common.metadata.StaticMetadataManager; +import com.tencent.cloud.polaris.context.PostInitPolarisSDKContext; +import com.tencent.polaris.client.api.SDKContext; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Post-initialization operations after the application initialization phase is completed. + * + * @author lepdou 2022-06-28 + */ +@Configuration(proxyBeanMethods = false) +public class PolarisContextPostConfiguration { + + @Bean + public PostInitPolarisSDKContext postInitPolarisSDKContext(SDKContext sdkContext, StaticMetadataManager staticMetadataManager) { + return new PostInitPolarisSDKContext(sdkContext, staticMetadataManager); + } +} diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextProperties.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextProperties.java similarity index 96% rename from spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextProperties.java rename to spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextProperties.java index 3df1731b5..87a076e21 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextProperties.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextProperties.java @@ -16,13 +16,14 @@ * */ -package com.tencent.cloud.polaris.context; +package com.tencent.cloud.polaris.context.config; import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; +import com.tencent.cloud.polaris.context.PolarisConfigModifier; import com.tencent.polaris.api.config.ConfigProvider; import com.tencent.polaris.api.config.Configuration; import com.tencent.polaris.factory.ConfigAPIFactory; diff --git a/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 52c48aa8b..7bb1d6596 100644 --- a/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -2,8 +2,8 @@ "groups": [ { "name": "spring.cloud.polaris", - "type": "com.tencent.cloud.polaris.context.PolarisContextProperties", - "sourceType": "com.tencent.cloud.polaris.context.PolarisContextProperties" + "type": "com.tencent.cloud.polaris.context.config.PolarisContextProperties", + "sourceType": "com.tencent.cloud.polaris.context.config.PolarisContextProperties" } ], "properties": [ @@ -11,28 +11,28 @@ "name": "spring.cloud.polaris.address", "type": "java.lang.String", "description": "polaris server address list that can be separated by \",\"", - "sourceType": "com.tencent.cloud.polaris.context.PolarisContextProperties" + "sourceType": "com.tencent.cloud.polaris.context.config.PolarisContextProperties" }, { "name": "spring.cloud.polaris.namespace", "type": "java.lang.String", "description": "polaris namespace", "default": "default", - "sourceType": "com.tencent.cloud.polaris.context.PolarisContextProperties" + "sourceType": "com.tencent.cloud.polaris.context.config.PolarisContextProperties" }, { "name": "spring.cloud.polaris.service", "type": "java.lang.String", "description": "polaris service name", "default": "${spring.application.name}", - "sourceType": "com.tencent.cloud.polaris.context.PolarisContextProperties" + "sourceType": "com.tencent.cloud.polaris.context.config.PolarisContextProperties" }, { "name": "spring.cloud.polaris.enabled", "type": "java.lang.Boolean", "description": "polaris enabled", "default": "true", - "sourceType": "com.tencent.cloud.polaris.context.PolarisContextProperties" + "sourceType": "com.tencent.cloud.polaris.context.config.PolarisContextProperties" }, { "name": "spring.cloud.polaris.local-ip-address", 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 b53316b9a..723fc1d78 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 @@ -1,4 +1,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration + com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration,\ + com.tencent.cloud.polaris.context.config.PolarisContextPostConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ - com.tencent.cloud.polaris.context.PolarisContextBootstrapAutoConfiguration + com.tencent.cloud.polaris.context.config.PolarisContextBootstrapAutoConfiguration diff --git a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextAutoConfigurationTest.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextAutoConfigurationTest.java index 0f8ca746d..b31a34096 100644 --- a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextAutoConfigurationTest.java +++ b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextAutoConfigurationTest.java @@ -17,6 +17,7 @@ package com.tencent.cloud.polaris.context; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.polaris.client.api.SDKContext; import org.junit.Assert; import org.junit.Test; @@ -26,14 +27,15 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.cloud.commons.util.UtilAutoConfiguration; /** + * Test for {@link PolarisContextAutoConfiguration}. + * * @author liaochuntao */ public class PolarisContextAutoConfigurationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(UtilAutoConfiguration.class)) - .withConfiguration( - AutoConfigurations.of(PolarisContextAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class)) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:8083"); @Test @@ -43,5 +45,4 @@ public class PolarisContextAutoConfigurationTest { Assert.assertNotNull(sdkContext); }); } - } diff --git a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java index 3069c5aa9..71a332cba 100644 --- a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java +++ b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java @@ -17,6 +17,8 @@ package com.tencent.cloud.polaris.context; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextProperties; import com.tencent.polaris.client.api.SDKContext; import org.junit.Assert; import org.junit.Test; @@ -30,8 +32,8 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = PolarisContextApplication.class, - properties = { "spring.config.location = classpath:bootstrap.yml" }) -@ImportAutoConfiguration({ PolarisContextAutoConfiguration.class }) + properties = {"spring.config.location = classpath:bootstrap.yml"}) +@ImportAutoConfiguration({PolarisContextAutoConfiguration.class}) public class PolarisContextGetHostTest { @Autowired @@ -47,5 +49,4 @@ public class PolarisContextGetHostTest { Assert.assertEquals(bindIP, "192.168.1.1"); Assert.assertEquals(polarisContextProperties.getNamespace(), "dev"); } - } diff --git a/spring-cloud-tencent-polaris-loadbalancer/pom.xml b/spring-cloud-tencent-polaris-loadbalancer/pom.xml index cfec39a05..da560c430 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/pom.xml +++ b/spring-cloud-tencent-polaris-loadbalancer/pom.xml @@ -49,6 +49,24 @@ spring-boot-starter-test test + + + org.mockito + mockito-inline + test + + + + org.mockito + mockito-core + test + + + + net.bytebuddy + byte-buddy + test + - \ No newline at end of file + diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtils.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtils.java index 0a6816ba0..997c276f5 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtils.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtils.java @@ -18,7 +18,9 @@ package com.tencent.cloud.polaris.loadbalancer; +import java.util.Collections; import java.util.List; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import com.tencent.cloud.common.metadata.MetadataContext; @@ -35,31 +37,53 @@ import org.springframework.util.CollectionUtils; /** * load balancer utils. * - *@author lepdou 2022-05-17 + * @author lepdou 2022-05-17 */ -public class LoadBalancerUtils { +public final class LoadBalancerUtils { - public static ServiceInstances transferServersToServiceInstances(Flux> servers) { - List instances = servers.toStream().flatMap(List::stream).map(serviceInstance -> { - DefaultInstance instance = new DefaultInstance(); - instance.setNamespace(MetadataContext.LOCAL_NAMESPACE); - instance.setService(serviceInstance.getServiceId()); - instance.setProtocol(serviceInstance.getScheme()); - instance.setId(serviceInstance.getInstanceId()); - instance.setHost(serviceInstance.getHost()); - instance.setPort(serviceInstance.getPort()); - instance.setWeight(100); - instance.setMetadata(serviceInstance.getMetadata()); - return instance; - }).collect(Collectors.toList()); + private static final int DEFAULT_WEIGHT = 100; + + private LoadBalancerUtils() { + } + /** + * transfer servers to ServiceInstances. + * + * @param servers servers + * @return ServiceInstances + */ + public static ServiceInstances transferServersToServiceInstances(Flux> servers) { + AtomicReference> instances = new AtomicReference<>(); + servers.subscribe(serviceInstances -> instances.set(serviceInstances.stream() + .map(LoadBalancerUtils::transferServerToServiceInstance) + .collect(Collectors.toList()))); String serviceName = null; - if (!CollectionUtils.isEmpty(instances)) { - serviceName = instances.get(0).getService(); + if (CollectionUtils.isEmpty(instances.get())) { + instances.set(Collections.emptyList()); + } + else { + serviceName = instances.get().get(0).getService(); } - ServiceKey serviceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE, serviceName); + return new DefaultServiceInstances(serviceKey, instances.get()); + } - return new DefaultServiceInstances(serviceKey, instances); + /** + * transfer ServiceInstance to DefaultInstance. + * + * @param serviceInstance serviceInstance + * @return defaultInstance + */ + public static DefaultInstance transferServerToServiceInstance(ServiceInstance serviceInstance) { + DefaultInstance instance = new DefaultInstance(); + instance.setNamespace(MetadataContext.LOCAL_NAMESPACE); + instance.setService(serviceInstance.getServiceId()); + instance.setProtocol(serviceInstance.getScheme()); + instance.setId(serviceInstance.getInstanceId()); + instance.setHost(serviceInstance.getHost()); + instance.setPort(serviceInstance.getPort()); + instance.setWeight(DEFAULT_WEIGHT); + instance.setMetadata(serviceInstance.getMetadata()); + return instance; } } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java index 737b465f3..ab3771940 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java @@ -72,6 +72,14 @@ public class PolarisLoadBalancer extends RoundRobinLoadBalancer { this.routerAPI = routerAPI; } + private static ServiceInstances convertToPolarisServiceInstances(List serviceInstances) { + ServiceKey serviceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE, serviceInstances.get(0).getServiceId()); + List polarisInstances = serviceInstances.stream() + .map(serviceInstance -> ((PolarisServiceInstance) serviceInstance).getPolarisInstance()) + .collect(Collectors.toList()); + return new DefaultServiceInstances(serviceKey, polarisInstances); + } + @Override public Mono> choose(Request request) { if (!loadBalancerProperties.getEnabled()) { @@ -102,13 +110,4 @@ public class PolarisLoadBalancer extends RoundRobinLoadBalancer { return new EmptyResponse(); } } - - private static ServiceInstances convertToPolarisServiceInstances(List serviceInstances) { - ServiceKey serviceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE, serviceInstances.get(0).getServiceId()); - List polarisInstances = serviceInstances.stream() - .map(serviceInstance -> ((PolarisServiceInstance) serviceInstance).getPolarisInstance()) - .collect(Collectors.toList()); - return new DefaultServiceInstances(serviceKey, polarisInstances); - } - } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisServiceInstanceListSupplier.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisServiceInstanceListSupplier.java index b0119932f..a0d370d20 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisServiceInstanceListSupplier.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisServiceInstanceListSupplier.java @@ -17,10 +17,9 @@ package com.tencent.cloud.polaris.loadbalancer; -import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; -import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.pojo.PolarisServiceInstance; import com.tencent.polaris.api.pojo.DefaultInstance; import org.apache.commons.lang.StringUtils; @@ -63,20 +62,9 @@ public class PolarisServiceInstanceListSupplier extends DelegatingServiceInstanc throw new IllegalStateException( "PolarisRoutingLoadBalancer only Server with AppName or ServiceIdForDiscovery attribute"); } - List serviceInstances = new ArrayList<>(allServers.size()); - for (ServiceInstance server : allServers) { - DefaultInstance instance = new DefaultInstance(); - instance.setNamespace(MetadataContext.LOCAL_NAMESPACE); - instance.setService(serviceName); - instance.setProtocol(server.getScheme()); - instance.setId(server.getInstanceId()); - instance.setHost(server.getHost()); - instance.setPort(server.getPort()); - instance.setWeight(100); - instance.setMetadata(server.getMetadata()); - serviceInstances.add(new PolarisServiceInstance(instance)); - } - return serviceInstances; + return allServers.stream().map(server -> { + DefaultInstance instance = LoadBalancerUtils.transferServerToServiceInstance(server); + return new PolarisServiceInstance(instance); + }).collect(Collectors.toList()); } - } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerClientConfiguration.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerClientConfiguration.java index 600f87f4d..1169c9be2 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerClientConfiguration.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerClientConfiguration.java @@ -67,10 +67,10 @@ public class PolarisLoadBalancerClientConfiguration { loadBalancerProperties, routerAPI); } - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnReactiveDiscoveryEnabled @Order(REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER) - static class PolarisReactiveSupportConfiguration { + protected static class PolarisReactiveSupportConfiguration { @Bean @ConditionalOnMissingBean @@ -84,10 +84,10 @@ public class PolarisLoadBalancerClientConfiguration { } - @Configuration + @Configuration(proxyBeanMethods = false) @ConditionalOnBlockingDiscoveryEnabled @Order(REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER + 1) - static class PolarisBlockingSupportConfiguration { + protected static class PolarisBlockingSupportConfiguration { @Bean @ConditionalOnMissingBean @@ -100,5 +100,4 @@ public class PolarisLoadBalancerClientConfiguration { } } - } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerProperties.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerProperties.java index 90d82e07e..be592ac1d 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerProperties.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerProperties.java @@ -73,5 +73,4 @@ public class PolarisLoadBalancerProperties { return "PolarisLoadBalancerProperties{" + "loadbalancerEnabled=" + enabled + ", strategy='" + strategy + '\'' + '}'; } - } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtilsTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtilsTest.java new file mode 100644 index 000000000..d4a894de3 --- /dev/null +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtilsTest.java @@ -0,0 +1,106 @@ +/* + * 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.loadbalancer; + +import java.util.ArrayList; +import java.util.List; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.metadata.MetadataContextHolder; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.polaris.api.pojo.Instance; +import com.tencent.polaris.api.pojo.ServiceInstances; +import org.junit.AfterClass; +import org.junit.Assert; +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 reactor.core.publisher.Flux; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; + +import static org.mockito.ArgumentMatchers.anyString; + +/** + * Test for ${@link LoadBalancerUtils}. + * + * @author lepdou 2022-07-04 + */ +@RunWith(MockitoJUnitRunner.class) +public class LoadBalancerUtilsTest { + + private static final String testNamespaceAndService = "testNamespaceAndService"; + private static MockedStatic mockedApplicationContextAwareUtils; + private static MockedStatic mockedMetadataContextHolder; + + @BeforeClass + public static void beforeClass() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn(testNamespaceAndService); + + MetadataContext metadataContext = Mockito.mock(MetadataContext.class); + mockedMetadataContextHolder = Mockito.mockStatic(MetadataContextHolder.class); + mockedMetadataContextHolder.when(MetadataContextHolder::get).thenReturn(metadataContext); + } + + @AfterClass + public static void afterClass() { + mockedApplicationContextAwareUtils.close(); + mockedMetadataContextHolder.close(); + } + + @Test + public void testTransferEmptyInstances() { + ServiceInstances serviceInstances = LoadBalancerUtils.transferServersToServiceInstances(Flux.empty()); + Assert.assertNotNull(serviceInstances.getInstances()); + Assert.assertEquals(0, serviceInstances.getInstances().size()); + } + + @Test + public void testTransferNotEmptyInstances() { + int instanceSize = 100; + + List instances = new ArrayList<>(); + for (int i = 0; i < instanceSize; i++) { + instances.add(new DefaultServiceInstance("ins" + i, testNamespaceAndService, "127.0.0." + i, + 8080, false)); + } + + ServiceInstances serviceInstances = LoadBalancerUtils.transferServersToServiceInstances(Flux.just(instances)); + + Assert.assertNotNull(serviceInstances.getInstances()); + Assert.assertEquals(instanceSize, serviceInstances.getInstances().size()); + + List polarisInstances = serviceInstances.getInstances(); + for (int i = 0; i < instanceSize; i++) { + Instance instance = polarisInstances.get(i); + Assert.assertEquals(testNamespaceAndService, instance.getNamespace()); + Assert.assertEquals(testNamespaceAndService, instance.getService()); + Assert.assertEquals("ins" + i, instance.getId()); + Assert.assertEquals("127.0.0." + i, instance.getHost()); + Assert.assertEquals(8080, instance.getPort()); + Assert.assertEquals(100, instance.getWeight()); + } + } +} diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java index b0e9d6a30..94795c5ad 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java @@ -17,13 +17,19 @@ package com.tencent.cloud.polaris.loadbalancer.config; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.loadbalancer.PolarisLoadBalancer; import com.tencent.polaris.router.api.core.RouterAPI; import org.junit.Test; +import org.springframework.beans.factory.BeanFactory; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; +import org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.context.annotation.Configuration; import static com.tencent.polaris.test.common.Consts.PORT; @@ -37,12 +43,22 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisLoadBalancerAutoConfigurationTest { - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(PolarisRibbonTest.class, PolarisLoadBalancerAutoConfiguration.class, PolarisContextAutoConfiguration.class)) .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER).withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); + private final ApplicationContextRunner polarisLoadbalancerContextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisRibbonTest.class, + PolarisLoadBalancerAutoConfiguration.class, + PolarisContextAutoConfiguration.class, + LoadBalancerAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER).withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") + .withPropertyValues("spring.cloud.polaris.loadbalancer.strategy=polarisWeighted"); + + @Test public void testDefaultInitialization() { this.contextRunner.run(context -> { @@ -51,10 +67,23 @@ public class PolarisLoadBalancerAutoConfigurationTest { }); } + @Test + public void testPolarisLoadbalancerInitialization() { + this.polarisLoadbalancerContextRunner.run(context -> { + assertThat(context).hasSingleBean(RouterAPI.class); + assertThat(context).hasSingleBean(PolarisLoadBalancerProperties.class); + assertThat(hasPolarisLoadBalancer(context)).isTrue(); + }); + } + + private boolean hasPolarisLoadBalancer(BeanFactory beanFactory) { + LoadBalancerClientFactory loadBalancerClientFactory = beanFactory.getBean(LoadBalancerClientFactory.class); + ReactiveLoadBalancer instance = loadBalancerClientFactory.getInstance(SERVICE_PROVIDER); + return instance instanceof PolarisLoadBalancer; + } + @Configuration @EnableAutoConfiguration static class PolarisRibbonTest { - } - } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRouterAutoConfigurationTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRouterAutoConfigurationTest.java index 2593095a8..3dce8fec3 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRouterAutoConfigurationTest.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRouterAutoConfigurationTest.java @@ -17,7 +17,7 @@ package com.tencent.cloud.polaris.loadbalancer.config; -import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.loadbalancer.PolarisServiceInstanceListSupplier; import com.tencent.polaris.router.api.core.RouterAPI; import org.junit.Test; @@ -30,7 +30,7 @@ import org.springframework.context.annotation.Configuration; import static org.assertj.core.api.Assertions.assertThat; /** - * Test for {@link PolarisLoadBalancerAutoConfiguration} + * Test for {@link PolarisLoadBalancerAutoConfiguration}. * * @author Haotian Zhang */ @@ -84,5 +84,4 @@ public class PolarisRouterAutoConfigurationTest { static class PolarisLoadBalancerTest { } - } diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index ace6b329d..452aaa5f7 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -4,6 +4,5 @@ "https://www.puppycrawl.com/dtds/suppressions_1_1.dtd"> - \ No newline at end of file