Merge branch '2020.0' into 2020_PostInitPolarisSDKContextTest

# Conflicts:
#	CHANGELOG.md
pull/399/head
weihu 3 years ago
commit db27afe540

@ -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

@ -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'

@ -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 <br \/> 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)

@ -1,13 +1,13 @@
# Spring Cloud Tencent
<img src="https://github.com/Tencent/spring-cloud-tencent/raw/2020.0/doc/logo/rectangle-white.png" width="60%" height="60%" alt="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。
## 管控台
<img width="1792" alt="image" src="https://user-images.githubusercontent.com/4991116/163402268-48493802-4555-4b93-8e31-011410f2166b.png">
@ -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 中央仓库,只需要
<img src="https://user-images.githubusercontent.com/24446200/169198148-d4cc3494-3485-4515-9897-c8cb5504f706.png" width="30%" height="30%" />
## 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

@ -1,9 +1,10 @@
# Spring Cloud Tencent
<img src="https://github.com/Tencent/spring-cloud-tencent/raw/2020.0/doc/logo/rectangle-white.png" width="60%" height="60%" alt="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.
<img src="https://user-images.githubusercontent.com/24446200/169198148-d4cc3494-3485-4515-9897-c8cb5504f706.png" width="30%" height="30%" />
## 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

@ -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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="424px" height="82px" viewBox="0 0 424 82" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>长款的 svg格式透明</title>
<g id="长款的-svg格式透明" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="矩形" x="0" y="0" width="424" height="82"></rect>
<text id="Spring-Cloud-Tencent" font-family="TencentSansW7, TencentSans" font-size="34" font-weight="bold" letter-spacing="-0.50303" fill="#000000">
<tspan x="83.8428418" y="49.8255109">Spring Cloud Tencent</tspan>
</text>
<polygon id="路径-2备份-10" fill="#95D2F7" points="43.9206195 11.8255109 43.9206195 21.8255109 52.6095084 16.8255109"></polygon>
<polygon id="矩形备份-25" fill="#7F98FF" points="24.9833459 32.3489782 48.8428418 46.1744891 48.8428418 73.8255109 24.9833459 60"></polygon>
<polygon id="矩形备份-26" fill="#7F98FF" transform="translate(55.772590, 29.412755) scale(-1, 1) translate(-55.772590, -29.412755) " points="43.8428418 8 67.7023376 21.8255109 67.7023376 50.8255109 43.8428418 37"></polygon>
<polygon id="矩形备份-27" fill="#95D2F7" transform="translate(24.983346, 21.523467) scale(-1, 1) translate(-24.983346, -21.523467) " points="24.9833459 10.5234673 43.9666917 21.5234673 24.9833459 32.5234673 6 21.5234673"></polygon>
<polygon id="路径-3" fill="#4065FF" points="43.8428418 43.2977777 43.8428418 50.8255109 48.8428418 47.9799656 48.8428418 46.1744891"></polygon>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="424px" height="82px" viewBox="0 0 424 82" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>长款的 svg 格式的白底</title>
<g id="长款的-svg-格式的白底" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="矩形" fill="#FFFFFF" x="0" y="0" width="424" height="82"></rect>
<rect id="矩形" fill="#FFFFFF" x="6" y="8" width="412" height="66"></rect>
<text id="Spring-Cloud-Tencent" font-family="TencentSansW7, TencentSans" font-size="34" font-weight="bold" letter-spacing="-0.50303" fill="#000000">
<tspan x="83.8428418" y="49.8255109">Spring Cloud Tencent</tspan>
</text>
<polygon id="路径-2备份-10" fill="#95D2F7" points="43.9206195 11.8255109 43.9206195 21.8255109 52.6095084 16.8255109"></polygon>
<polygon id="矩形备份-25" fill="#7F98FF" points="24.9833459 32.3489782 48.8428418 46.1744891 48.8428418 73.8255109 24.9833459 60"></polygon>
<polygon id="矩形备份-26" fill="#7F98FF" transform="translate(55.772590, 29.412755) scale(-1, 1) translate(-55.772590, -29.412755) " points="43.8428418 8 67.7023376 21.8255109 67.7023376 50.8255109 43.8428418 37"></polygon>
<polygon id="矩形备份-27" fill="#95D2F7" transform="translate(24.983346, 21.523467) scale(-1, 1) translate(-24.983346, -21.523467) " points="24.9833459 10.5234673 43.9666917 21.5234673 24.9833459 32.5234673 6 21.5234673"></polygon>
<polygon id="路径-3" fill="#4065FF" points="43.8428418 43.2977777 43.8428418 50.8255109 48.8428418 47.9799656 48.8428418 46.1744891"></polygon>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -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<DecodeTransferMetadataServletFilter> metadataServletFilterRegistrationBean(
DecodeTransferMetadataServletFilter decodeTransferMetadataServletFilter) {
FilterRegistrationBean<DecodeTransferMetadataServletFilter> 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<String, RestTemplate> beans = this.context.getBeansOfType(RestTemplate.class);
Map<String, RestTemplate> 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<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
List<ClientHttpRequestInterceptor> 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<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
List<ClientHttpRequestInterceptor> 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;
}
}
}
}

@ -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<String, String> resolve(ServerWebExchange exchange) {
Map<String, String> result = new HashMap<>();

@ -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);
}
}

@ -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);
}
}

@ -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,
}
}
}
}

@ -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);
}
}

@ -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());
}
}

@ -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);
});
}
}

@ -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<String, String> 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<String, String> resolve = CustomTransitiveMetadataResolver.resolve(request);
Assertions.assertThat(resolve.size()).isEqualTo(1);
Assertions.assertThat(resolve.get("a")).isEqualTo("test");
}
}

@ -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();
}
}

@ -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 {
}
}

@ -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\"}");
}
}
}
}

@ -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");
}
}
}

@ -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<String, String> transitiveMap = JacksonUtils.deserialize2Map(decode);
Assertions.assertThat(transitiveMap.size()).isEqualTo(1);
Assertions.assertThat(transitiveMap.get("b")).isEqualTo("2");
}
@SpringBootApplication
protected static class TestApplication {
}
}

@ -90,6 +90,12 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

@ -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);
}
}

@ -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 <a href="mailto:iskp.me@gmail.com">Palmer.Xu</a> 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);
}
}
}

@ -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;
}
}
}

@ -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;
}
}

@ -35,5 +35,4 @@ public class PolarisFeignBlockingLoadBalancerClient extends FeignBlockingLoadBal
LoadBalancerProperties properties, LoadBalancerClientFactory loadBalancerClientFactory) {
super(delegate, loadBalancerClient, properties, loadBalancerClientFactory);
}
}

@ -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;
}
}

@ -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 {
}

@ -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<String, Object> 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;
}
}

@ -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;
}
}

@ -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

@ -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);
});
}
}

@ -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);
});
}
}

@ -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 <a href="mailto:iskp.me@gmail.com">Palmer Xu</a> 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();
}
}
}

@ -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 {

@ -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 {
}
}

@ -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
}
}
}

@ -71,6 +71,18 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>

@ -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;

@ -57,5 +57,4 @@ public class PolarisConfigAutoConfiguration {
public PolarisConfigChangeEventListener polarisConfigChangeEventListener() {
return new PolarisConfigChangeEventListener();
}
}

@ -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);
}
}

@ -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);
}
}

@ -74,5 +74,4 @@ public class PolarisPropertySource extends MapPropertySource {
return "PolarisPropertySource{" + "namespace='" + namespace + '\'' + ", group='" + group + '\'' + ", fileName='"
+ fileName + '\'' + '}';
}
}

@ -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<ApplicationReadyEvent>, ApplicationContextAware {
public class PolarisPropertySourceAutoRefresher implements ApplicationListener<ApplicationReadyEvent> {
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
});
}
}
}

@ -39,5 +39,4 @@ public class PolarisPropertySourceManager {
public List<PolarisPropertySource> getAllPropertySources() {
return new ArrayList<>(polarisPropertySources.values());
}
}

@ -101,5 +101,4 @@ public class PolarisConfigAnnotationProcessor implements BeanPostProcessor, Prio
addChangeListener(configChangeListener, interestedKeys, interestedKeyPrefixes);
}
}

@ -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.
* <br />
* <p>
* 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.
* <br />
* <p>
* 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 {};
}

@ -56,5 +56,4 @@ public class ConfigFileGroup {
public String toString() {
return "ConfigFileGroup{" + "name='" + name + '\'' + ", file=" + files + '}';
}
}

@ -94,5 +94,4 @@ public class PolarisConfigProperties {
public void setGroups(List<ConfigFileGroup> groups) {
this.groups = groups;
}
}

@ -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<String, Object> polarisConfig() {
Map<String, Object> configInfo = new HashMap<>();
configInfo.put("PolarisConfigProperties", polarisConfigProperties);
List<PolarisPropertySource> propertySourceList = polarisPropertySourceManager.getAllPropertySources();
configInfo.put("PolarisPropertySource", propertySourceList);
return configInfo;
}
}

@ -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);
}
}

@ -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;
}
}

@ -84,5 +84,4 @@ public final class ConfigChangeEvent {
public Set<String> interestedChangedKeys() {
return interestedChangedKeys;
}
}

@ -31,5 +31,4 @@ public interface ConfigChangeListener {
* @param changeEvent the event for this change
*/
void onChange(ConfigChangeEvent changeEvent);
}

@ -107,5 +107,4 @@ public final class PolarisConfigChangeEventListener implements ApplicationListen
});
return ret;
}
}

@ -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<ExecutorService> EAR = new AtomicReference<>();
/**
* All custom {@link ConfigChangeListener} instance defined in application .
*/
private static final List<ConfigChangeListener> listeners = Lists.newCopyOnWriteArrayList();
/**
* All custom interested keys defined in application .
*/
private static final Map<ConfigChangeListener, Set<String>> interestedKeys = Maps.newHashMap();
/**
* All custom interested key prefixes defined in application .
*/
private static final Map<ConfigChangeListener, Set<String>> interestedKeyPrefixes = Maps.newHashMap();
/**
* Cache all latest configuration information for users in the application environment .
*/
private static final Cache<String, Object> 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);
}
}

@ -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

@ -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 {

@ -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,

@ -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();
}
}

@ -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<String, Object> 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<String, Object> info = endpoint.polarisConfig();
assertThat(polarisConfigProperties).isEqualTo(info.get("PolarisConfigProperties"));
assertThat(Lists.newArrayList(polarisPropertySource)).isEqualTo(info.get("PolarisPropertySource"));
}
}

@ -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 {
}
}
}
}

@ -94,6 +94,18 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>

@ -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 {

@ -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;
}
}

@ -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;
}
}
}

@ -46,5 +46,4 @@ public @interface PolarisClient {
* @return namespace
*/
String namespace() default "";
}

@ -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)

@ -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;
}
}

@ -43,5 +43,4 @@ public class PolarisDiscoveryAutoConfiguration {
PolarisDiscoveryHandler polarisDiscoveryHandler) {
return new PolarisServiceDiscovery(polarisDiscoveryHandler);
}
}

@ -54,5 +54,4 @@ public class PolarisDiscoveryClient implements DiscoveryClient {
public List<String> getServices() {
return polarisServiceDiscovery.getServices();
}
}

@ -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);
}
}

@ -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);
}
}

@ -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());
}
}

@ -82,5 +82,4 @@ public class PolarisReactiveDiscoveryClient implements ReactiveDiscoveryClient {
}
}).subscribeOn(Schedulers.boundedElastic());
}
}

@ -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);
}
}

@ -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<ApplicationReadyEvent>, ApplicationEventPublisherAware {
public class PolarisRefreshApplicationReadyEventListener
implements ApplicationListener<ApplicationReadyEvent>, 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();
}
}

@ -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;
}
}

@ -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<String, Object> polarisDiscovery(@Selector String serviceId) {
Map<String, Object> polarisDiscoveryInfo = new HashMap<>();
polarisDiscoveryInfo.put("PolarisDiscoveryProperties", polarisDiscoveryProperties);
List<ServiceInstances> 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;
}
}

@ -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);
}
}

@ -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 {
}
}
}

@ -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 {

@ -93,5 +93,4 @@ public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistrat
String appName = registration.getPolarisProperties().getService();
return StringUtils.isEmpty(appName) ? super.getAppName() : appName;
}
}

@ -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<String, String> 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 +

@ -220,5 +220,4 @@ public class PolarisServiceRegistry implements ServiceRegistry<Registration> {
}
}, ttl, ttl, TimeUnit.SECONDS);
}
}

@ -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

@ -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;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save