From 4603c4a6b3bd930268adbc0022fc4d79332583da Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Wed, 29 Jun 2022 16:07:36 +0800 Subject: [PATCH 01/14] test:update junit of metadata. (#340) --- .github/workflows/codecov.yml | 15 ++++++++++----- .github/workflows/junit_test.yml | 2 +- CHANGELOG.md | 1 + .../CustomTransitiveMetadataResolverTest.java | 6 +++--- .../DecodeTransferMetadataReactiveFilterTest.java | 6 +++--- .../DecodeTransferMetadataServletFilterTest.java | 6 +++--- .../EncodeTransferMedataFeignInterceptorTest.java | 4 +--- ...TransferMedataRestTemplateInterceptorTest.java | 4 +--- .../EncodeTransferMedataScgFilterTest.java | 9 ++++----- .../EncodeTransferMetadataZuulFilterTest.java | 3 +-- 10 files changed, 28 insertions(+), 28 deletions(-) rename spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/{ => core}/CustomTransitiveMetadataResolverTest.java (94%) rename spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/{ => core}/DecodeTransferMetadataReactiveFilterTest.java (96%) rename spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/{ => core}/DecodeTransferMetadataServletFilterTest.java (96%) rename spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/{intercepter => }/EncodeTransferMedataFeignInterceptorTest.java (96%) rename spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/{intercepter => }/EncodeTransferMedataRestTemplateInterceptorTest.java (95%) rename spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/{filter => }/EncodeTransferMedataScgFilterTest.java (93%) rename spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/{filter => }/EncodeTransferMetadataZuulFilterTest.java (96%) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index c0ef90771..cc452e861 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -5,12 +5,17 @@ name: Codecov on: push: - branches: [ main ] + branches: + - main + - 2021.0 + - 2020.0 + - greenwich pull_request: - branches: [ main ] - -permissions: - contents: write + branches: + - main + - 2021.0 + - 2020.0 + - greenwich jobs: build: diff --git a/.github/workflows/junit_test.yml b/.github/workflows/junit_test.yml index 57cfae035..165255247 100644 --- a/.github/workflows/junit_test.yml +++ b/.github/workflows/junit_test.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: java: [ 8, 11, 17 ] - os: [ 'windows-latest', 'macos-latest', 'ubuntu-latest' ] + os: [ 'windows-latest', 'ubuntu-latest' ] runs-on: ${{ matrix.os }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 5eef473ed..faf2583a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,3 +25,4 @@ - [feat:Add GitHub action of codecov.yml.](https://github.com/Tencent/spring-cloud-tencent/pull/328) - [Feature: add spring cloud tencent logo](https://github.com/Tencent/spring-cloud-tencent/pull/329) - [Feature: Optimize static metadata manager](https://github.com/Tencent/spring-cloud-tencent/pull/327) +- [test:update junit of metadata.](https://github.com/Tencent/spring-cloud-tencent/pull/340) diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/CustomTransitiveMetadataResolverTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolverTest.java similarity index 94% rename from spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/CustomTransitiveMetadataResolverTest.java rename to spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolverTest.java index f3fbfc4e0..9dc83bd51 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/CustomTransitiveMetadataResolverTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolverTest.java @@ -13,14 +13,12 @@ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. - * */ -package com.tencent.cloud.metadata; +package com.tencent.cloud.metadata.core; import java.util.Map; -import com.tencent.cloud.metadata.core.CustomTransitiveMetadataResolver; import org.assertj.core.api.Assertions; import org.junit.Test; @@ -29,6 +27,8 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.server.MockServerWebExchange; /** + * Test for {@link CustomTransitiveMetadataResolver}. + * * @author quan */ public class CustomTransitiveMetadataResolverTest { diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataReactiveFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilterTest.java similarity index 96% rename from spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataReactiveFilterTest.java rename to spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilterTest.java index 48412d443..8edd3400c 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataReactiveFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilterTest.java @@ -13,14 +13,12 @@ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. - * */ -package com.tencent.cloud.metadata; +package com.tencent.cloud.metadata.core; import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; -import com.tencent.cloud.metadata.core.DecodeTransferMetadataReactiveFilter; import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; @@ -38,6 +36,8 @@ import org.springframework.web.server.WebFilterChain; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.MOCK; /** + * Test for {@link DecodeTransferMetadataReactiveFilter}. + * * @author Haotian Zhang */ @RunWith(SpringRunner.class) diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataServletFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilterTest.java similarity index 96% rename from spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataServletFilterTest.java rename to spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilterTest.java index 4f452ffb9..fca418b59 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/DecodeTransferMetadataServletFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilterTest.java @@ -13,10 +13,9 @@ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. - * */ -package com.tencent.cloud.metadata; +package com.tencent.cloud.metadata.core; import java.io.IOException; @@ -25,7 +24,6 @@ import javax.servlet.ServletException; import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; -import com.tencent.cloud.metadata.core.DecodeTransferMetadataServletFilter; import org.assertj.core.api.Assertions; import org.junit.Test; import org.junit.runner.RunWith; @@ -40,6 +38,8 @@ import org.springframework.test.context.junit4.SpringRunner; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** + * Test for {@link DecodeTransferMetadataServletFilter}. + * * @author Haotian Zhang */ @RunWith(SpringRunner.class) diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataFeignInterceptorTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptorTest.java similarity index 96% rename from spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataFeignInterceptorTest.java rename to spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptorTest.java index 9d8c7ea3f..c42629e0c 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataFeignInterceptorTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptorTest.java @@ -13,10 +13,9 @@ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. - * */ -package com.tencent.cloud.metadata.core.intercepter; +package com.tencent.cloud.metadata.core; import java.io.UnsupportedEncodingException; @@ -24,7 +23,6 @@ import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; -import com.tencent.cloud.metadata.core.EncodeTransferMedataFeignInterceptor; import feign.RequestInterceptor; import feign.RequestTemplate; import org.assertj.core.api.Assertions; diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataRestTemplateInterceptorTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptorTest.java similarity index 95% rename from spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataRestTemplateInterceptorTest.java rename to spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptorTest.java index 10626e5a6..b61c42ed2 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/intercepter/EncodeTransferMedataRestTemplateInterceptorTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptorTest.java @@ -13,17 +13,15 @@ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. - * */ -package com.tencent.cloud.metadata.core.intercepter; +package com.tencent.cloud.metadata.core; import java.io.UnsupportedEncodingException; import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContextHolder; -import com.tencent.cloud.metadata.core.EncodeTransferMedataRestTemplateInterceptor; import org.assertj.core.api.Assertions; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/filter/EncodeTransferMedataScgFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java similarity index 93% rename from spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/filter/EncodeTransferMedataScgFilterTest.java rename to spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java index bc8a6277e..09ce46c8f 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/filter/EncodeTransferMedataScgFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java @@ -13,10 +13,9 @@ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. - * */ -package com.tencent.cloud.metadata.core.filter; +package com.tencent.cloud.metadata.core; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; @@ -25,9 +24,7 @@ import java.util.Map; import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.util.JacksonUtils; -import com.tencent.cloud.metadata.core.EncodeTransferMedataScgFilter; import org.assertj.core.api.Assertions; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -44,6 +41,8 @@ import org.springframework.test.context.junit4.SpringRunner; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** + * Test for {@link EncodeTransferMedataScgFilter}. + * * @author quan */ @RunWith(SpringRunner.class) @@ -68,7 +67,7 @@ public class EncodeTransferMedataScgFilterTest { String decode = URLDecoder.decode(metadataStr, StandardCharsets.UTF_8.name()); Map transitiveMap = JacksonUtils.deserialize2Map(decode); Assertions.assertThat(transitiveMap.size()).isEqualTo(1); - Assert.assertEquals(transitiveMap.get("b"), "2"); + Assertions.assertThat(transitiveMap.get("b")).isEqualTo("2"); } @SpringBootApplication diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/filter/EncodeTransferMetadataZuulFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilterTest.java similarity index 96% rename from spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/filter/EncodeTransferMetadataZuulFilterTest.java rename to spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilterTest.java index 7cb159e84..767cc2fbf 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/filter/EncodeTransferMetadataZuulFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilterTest.java @@ -16,7 +16,7 @@ * */ -package com.tencent.cloud.metadata.core.filter; +package com.tencent.cloud.metadata.core; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; @@ -26,7 +26,6 @@ import java.util.Map; import com.netflix.zuul.context.RequestContext; import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.util.JacksonUtils; -import com.tencent.cloud.metadata.core.EncodeTransferMetadataZuulFilter; import org.assertj.core.api.Assertions; import org.junit.Assert; import org.junit.Before; From e5ad87e62e1dd1ba13a5a0a2a2e8c4553a11ef42 Mon Sep 17 00:00:00 2001 From: "VOPEN.XYZ" Date: Wed, 29 Jun 2022 17:22:00 +0800 Subject: [PATCH 02/14] Optimize code style & unit test case (main). (#336) --- CHANGELOG.md | 3 +- .../CustomTransitiveMetadataResolver.java | 4 +- .../EncodeTransferMedataScgFilterTest.java | 12 +++- .../EncodeTransferMetadataZuulFilterTest.java | 15 ++-- .../pom.xml | 6 ++ .../PolarisRestTemplateAutoConfiguration.java | 13 ++-- .../PolarisResponseErrorHandler.java | 6 +- .../PolarisRestTemplateModifier.java | 8 +-- ...larisRestTemplateResponseErrorHandler.java | 42 ++++++----- ...arisRestTemplateAutoConfigurationTest.java | 72 +++++++++++++++++++ ...sRestTemplateResponseErrorHandlerTest.java | 9 ++- .../SimpleClientHttpResponseTest.java | 8 +-- 12 files changed, 146 insertions(+), 52 deletions(-) create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/{ => resttemplate}/PolarisRestTemplateResponseErrorHandlerTest.java (90%) rename spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/{ => resttemplate}/SimpleClientHttpResponseTest.java (93%) diff --git a/CHANGELOG.md b/CHANGELOG.md index faf2583a8..765ac8f67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,8 +21,9 @@ - [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/316) - [Fix config file format misspell](https://github.com/Tencent/spring-cloud-tencent/pull/319) - [UT: improve test coverage for load balancer unit test](https://github.com/Tencent/spring-cloud-tencent/pull/325) -- [Feature: Optimize polaris load balancer test code format](https://github.com/Tencent/spring-cloud-tencent/pull/333) +- [optimize polaris load balancer test code format](https://github.com/Tencent/spring-cloud-tencent/pull/333) - [feat:Add GitHub action of codecov.yml.](https://github.com/Tencent/spring-cloud-tencent/pull/328) - [Feature: add spring cloud tencent logo](https://github.com/Tencent/spring-cloud-tencent/pull/329) - [Feature: Optimize static metadata manager](https://github.com/Tencent/spring-cloud-tencent/pull/327) - [test:update junit of metadata.](https://github.com/Tencent/spring-cloud-tencent/pull/340) +- [Optimize code style & unit test case](https://github.com/Tencent/spring-cloud-tencent/pull/336) diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java index b8645efb2..01be55f2b 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java @@ -32,8 +32,8 @@ 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 { diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java index 09ce46c8f..f6cc2fdcd 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java @@ -48,7 +48,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @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" }) + properties = {"spring.config.location = classpath:application-test.yml", "spring.main.web-application-type = reactive"}) public class EncodeTransferMedataScgFilterTest { @Autowired @@ -60,11 +60,17 @@ public class EncodeTransferMedataScgFilterTest { @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); - String metadataStr = exchange.getRequest().getHeaders().getFirst(MetadataConstant.HeaderName.CUSTOM_METADATA); - String decode = URLDecoder.decode(metadataStr, StandardCharsets.UTF_8.name()); + + // Check metadata str + String metadata = exchange.getRequest().getHeaders().getFirst(MetadataConstant.HeaderName.CUSTOM_METADATA); + Assertions.assertThat(metadata).isNotNull(); + + String decode = URLDecoder.decode(metadata, StandardCharsets.UTF_8.name()); Map transitiveMap = JacksonUtils.deserialize2Map(decode); Assertions.assertThat(transitiveMap.size()).isEqualTo(1); Assertions.assertThat(transitiveMap.get("b")).isEqualTo("2"); diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilterTest.java index 767cc2fbf..adc3e1f7e 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilterTest.java @@ -27,7 +27,6 @@ import com.netflix.zuul.context.RequestContext; import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.util.JacksonUtils; import org.assertj.core.api.Assertions; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,19 +41,21 @@ import org.springframework.test.context.junit4.SpringRunner; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** + * Test for {@link EncodeTransferMetadataZuulFilter}. + * * @author quan */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT, classes = EncodeTransferMetadataZuulFilterTest.TestApplication.class, - properties = { "spring.config.location = classpath:application-test.yml", "spring.main.web-application-type = reactive" }) + properties = {"spring.config.location = classpath:application-test.yml", "spring.main.web-application-type = reactive"}) public class EncodeTransferMetadataZuulFilterTest { @Autowired private ApplicationContext applicationContext; - private MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(); + private final MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(); @Before public void init() { @@ -69,11 +70,13 @@ public class EncodeTransferMetadataZuulFilterTest { filter.run(); final RequestContext ctx = RequestContext.getCurrentContext(); Map zuulRequestHeaders = ctx.getZuulRequestHeaders(); - String metaData = zuulRequestHeaders.get(MetadataConstant.HeaderName.CUSTOM_METADATA.toLowerCase()); - String decode = URLDecoder.decode(metaData, StandardCharsets.UTF_8.name()); + String metadata = zuulRequestHeaders.get(MetadataConstant.HeaderName.CUSTOM_METADATA.toLowerCase()); + Assertions.assertThat(metadata).isNotNull(); + + String decode = URLDecoder.decode(metadata, StandardCharsets.UTF_8.name()); Map transitiveMap = JacksonUtils.deserialize2Map(decode); Assertions.assertThat(transitiveMap.size()).isEqualTo(1); - Assert.assertEquals(transitiveMap.get("b"), "2"); + Assertions.assertThat(transitiveMap.get("b")).isEqualTo("2"); } @SpringBootApplication diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml index 5c8c0d957..80bb8a22a 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml @@ -102,6 +102,12 @@ test + + org.springframework.boot + spring-boot-starter-web + test + + org.springframework.boot spring-boot-starter-test diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisRestTemplateAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisRestTemplateAutoConfiguration.java index d537de32e..a81f1344b 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisRestTemplateAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisRestTemplateAutoConfiguration.java @@ -32,9 +32,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; /** - * @author : wh - * @date : 2022/6/21 21:34 - * @description: Auto configuration PolarisRestTemplateAutoConfiguration + * Auto configuration PolarisRestTemplateAutoConfiguration . + * + * @author wh 2022/6/21 */ @ConditionalOnProperty(value = "spring.cloud.polaris.circuitbreaker.enabled", havingValue = "true", matchIfMissing = true) @@ -44,13 +44,16 @@ public class PolarisRestTemplateAutoConfiguration { @Bean @ConditionalOnBean(RestTemplate.class) - public PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler(ConsumerAPI consumerAPI, @Autowired(required = false) PolarisResponseErrorHandler polarisResponseErrorHandler) { + public PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler( + ConsumerAPI consumerAPI, @Autowired(required = false) PolarisResponseErrorHandler polarisResponseErrorHandler) { return new PolarisRestTemplateResponseErrorHandler(consumerAPI, polarisResponseErrorHandler); } @Bean @ConditionalOnBean(RestTemplate.class) - public PolarisRestTemplateModifier polarisRestTemplateBeanPostProcessor(PolarisRestTemplateResponseErrorHandler restTemplateResponseErrorHandler) { + public PolarisRestTemplateModifier polarisRestTemplateBeanPostProcessor( + PolarisRestTemplateResponseErrorHandler restTemplateResponseErrorHandler) { return new PolarisRestTemplateModifier(restTemplateResponseErrorHandler); } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisResponseErrorHandler.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisResponseErrorHandler.java index 5ddd1e6aa..3c690b1cc 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisResponseErrorHandler.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisResponseErrorHandler.java @@ -20,9 +20,9 @@ package com.tencent.cloud.polaris.circuitbreaker.resttemplate; import org.springframework.web.client.ResponseErrorHandler; /** - * @author : wh - * @date : 2022/6/21 19:12 - * @description: errorHandler {@link ResponseErrorHandler} + * Polaris Response Error Handler Definition Of {@link ResponseErrorHandler}. + * + * @author wh 2022/6/21 */ public interface PolarisResponseErrorHandler extends ResponseErrorHandler { diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java index bd43913f4..aa6eb3cbc 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java @@ -28,10 +28,10 @@ import org.springframework.util.ObjectUtils; import org.springframework.web.client.RestTemplate; /** - * @author : wh - * @date : 2022/6/21 21:20 - * @description: auto configuration RestTemplate Find the RestTemplate bean annotated with {@link LoadBalanced} and replace {@link org.springframework.web.client.ResponseErrorHandler} - * with {@link PolarisRestTemplateResponseErrorHandler} + * 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 { diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java index e6e003d90..8a7dc16ab 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java @@ -29,24 +29,25 @@ 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 com.tencent.polaris.api.utils.StringUtils; +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; /** - * @author : wh - * @date : 2022/6/21 17:25 - * @description: Extend ResponseErrorHandler to get request information + * 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 FileName = "connection"; + private static final String FIELD_NAME = "connection"; private final ConsumerAPI consumerAPI; @@ -59,12 +60,12 @@ public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHan } @Override - public boolean hasError(ClientHttpResponse response) { + public boolean hasError(@NonNull ClientHttpResponse response) { return true; } @Override - public void handleError(ClientHttpResponse response) throws IOException { + public void handleError(@NonNull ClientHttpResponse response) throws IOException { if (Objects.nonNull(polarisResponseErrorHandler)) { if (polarisResponseErrorHandler.hasError(response)) { polarisResponseErrorHandler.handleError(response); @@ -72,12 +73,22 @@ public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHan } } - public void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException { - ServiceCallResult resultRequest = null; + @Override + public void handleError(@NonNull URI url, @NonNull HttpMethod method, @NonNull ClientHttpResponse response) throws IOException { + ServiceCallResult resultRequest = createServiceCallResult(url); try { - resultRequest = builderServiceCallResult(url, response); + 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 (IOException e) { + catch (Exception e) { LOG.error("Will report response of {} url {}", response, url, e); throw e; } @@ -86,7 +97,7 @@ public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHan } } - private ServiceCallResult builderServiceCallResult(URI uri, ClientHttpResponse response) throws IOException { + private ServiceCallResult createServiceCallResult(URI uri) { ServiceCallResult resultRequest = new ServiceCallResult(); String serviceName = uri.getHost(); resultRequest.setService(serviceName); @@ -98,13 +109,6 @@ public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHan if (StringUtils.isNotBlank(sourceNamespace) && StringUtils.isNotBlank(sourceService)) { resultRequest.setCallerService(new ServiceKey(sourceNamespace, sourceService)); } - HttpURLConnection connection = (HttpURLConnection) ReflectionUtils.getFieldValue(response, FileName); - URL url = connection.getURL(); - resultRequest.setHost(url.getHost()); - resultRequest.setPort(url.getPort()); - if (response.getStatusCode().value() > 500) { - resultRequest.setRetStatus(RetStatus.RetFail); - } return resultRequest; } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java new file mode 100644 index 000000000..a3dc9999c --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java @@ -0,0 +1,72 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.circuitbreaker; + +import com.tencent.cloud.polaris.circuitbreaker.config.PolarisRestTemplateAutoConfiguration; +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 PolarisRestTemplateAutoConfiguration} . + * + * @author Palmer Xu 2022-06-28 + */ +public class PolarisRestTemplateAutoConfigurationTest { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of( + PolarisRestTemplateAutoConfigurationTester.class, + PolarisContextAutoConfiguration.class, + PolarisRestTemplateAutoConfiguration.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(PolarisRestTemplateAutoConfiguration.class) + static class PolarisRestTemplateAutoConfigurationTester { + + @Bean + RestTemplate restTemplate() { + return new RestTemplate(); + } + } + +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateResponseErrorHandlerTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandlerTest.java similarity index 90% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateResponseErrorHandlerTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandlerTest.java index 5daf30bc6..6cb630e37 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateResponseErrorHandlerTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandlerTest.java @@ -15,14 +15,13 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.resttemplate; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisRestTemplateResponseErrorHandler; import com.tencent.polaris.api.core.ConsumerAPI; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,9 +35,9 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** - * @author : wh - * @date : 2022/6/22 09:00 - * @description: Test for {@link PolarisRestTemplateResponseErrorHandler}. + * Test For {@link PolarisRestTemplateResponseErrorHandler}. + * + * @author wh 2022/6/22 */ @RunWith(SpringRunner.class) @SpringBootTest(classes = PolarisRestTemplateResponseErrorHandlerTest.TestApplication.class, diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/SimpleClientHttpResponseTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java similarity index 93% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/SimpleClientHttpResponseTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java index ed76da17b..871f39caa 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/SimpleClientHttpResponseTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.resttemplate; import java.io.IOException; import java.io.InputStream; @@ -29,9 +29,9 @@ import org.springframework.util.StringUtils; /** - * @author : wh - * @date : 2022/6/22 09:00 - * @description: mock {@link org.springframework.http.client.SimpleClientHttpResponse} + * Mock Test for {@link AbstractClientHttpResponse}. + * + * @author wh 2022/6/22 */ public class SimpleClientHttpResponseTest extends AbstractClientHttpResponse { From 34e4c70e8f69018db26b0423f593ae18b7f5c949 Mon Sep 17 00:00:00 2001 From: lepdou Date: Wed, 29 Jun 2022 17:47:53 +0800 Subject: [PATCH 03/14] add full size logos (#347) --- doc/logo/1280x640-transparent.png | Bin 0 -> 42360 bytes doc/logo/1280x640-transparent.svg | 17 +++++++++++++++++ doc/logo/1280x640-white.png | Bin 0 -> 42606 bytes doc/logo/1280x640-white.svg | 17 +++++++++++++++++ doc/logo/640x640-transparent.png | Bin 0 -> 32172 bytes doc/logo/640x640-transparent.svg | 17 +++++++++++++++++ doc/logo/640x640-white.png | Bin 0 -> 31855 bytes doc/logo/640x640-white.svg | 17 +++++++++++++++++ doc/logo/logo.png | Bin 16835 -> 0 bytes doc/logo/rectangle-transparent.png | Bin 0 -> 17642 bytes doc/logo/rectangle-transparent.svg | 15 +++++++++++++++ doc/logo/rectangle-white.png | Bin 0 -> 18086 bytes doc/logo/rectangle-white.svg | 16 ++++++++++++++++ 13 files changed, 99 insertions(+) create mode 100644 doc/logo/1280x640-transparent.png create mode 100644 doc/logo/1280x640-transparent.svg create mode 100644 doc/logo/1280x640-white.png create mode 100644 doc/logo/1280x640-white.svg create mode 100644 doc/logo/640x640-transparent.png create mode 100644 doc/logo/640x640-transparent.svg create mode 100644 doc/logo/640x640-white.png create mode 100644 doc/logo/640x640-white.svg delete mode 100644 doc/logo/logo.png create mode 100644 doc/logo/rectangle-transparent.png create mode 100644 doc/logo/rectangle-transparent.svg create mode 100644 doc/logo/rectangle-white.png create mode 100644 doc/logo/rectangle-white.svg diff --git a/doc/logo/1280x640-transparent.png b/doc/logo/1280x640-transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..9e722651cdc331f5c26a4ad5c3bdd25eaf50c048 GIT binary patch literal 42360 zcmeFZ_g7Qf^FItRNE8*2rXWQSkq!bPJzkoEfYOnwT%}3xonS|itJ0LJbSVLqUJ_J5 z>C&YIK?uE<03m#L5`upIf@eKzy?;PGq35h&y#Dqnnw?_AEu(BI(p@@nm!d3 z4fquj20I9Td|By!3w}_0>TCW(RnU5B3VcwzZF=R7jt-R&_#H+?{m6j|O1uR8V+a4J zs1Br3Qyl<5sfpjELMVTwp-MeK`5h8QywF^N-jj+7PIX1?lA#~<>=12YqKUsaVWl

nd&1u<))9{1-AtD;lRdlOufl=~j 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 literal 0 HcmV?d00001 diff --git a/doc/logo/1280x640-transparent.svg b/doc/logo/1280x640-transparent.svg new file mode 100644 index 000000000..ed57761db --- /dev/null +++ b/doc/logo/1280x640-transparent.svg @@ -0,0 +1,17 @@ + + + 1280x640-svg透明 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/logo/1280x640-white.png b/doc/logo/1280x640-white.png new file mode 100644 index 0000000000000000000000000000000000000000..21181cfdafa0cc2f7624645c2ca76709df8edffc GIT binary patch literal 42606 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 literal 0 HcmV?d00001 diff --git a/doc/logo/1280x640-white.svg b/doc/logo/1280x640-white.svg new file mode 100644 index 000000000..e09dba3f9 --- /dev/null +++ b/doc/logo/1280x640-white.svg @@ -0,0 +1,17 @@ + + + 1280x640-svg白底 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/logo/640x640-transparent.png b/doc/logo/640x640-transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..67e0c3f4ff357326a25b4ca256063b10d0fe223f GIT binary patch literal 32172 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 F{|_!RZ=L`E literal 0 HcmV?d00001 diff --git a/doc/logo/640x640-transparent.svg b/doc/logo/640x640-transparent.svg new file mode 100644 index 000000000..bb45e2cd1 --- /dev/null +++ b/doc/logo/640x640-transparent.svg @@ -0,0 +1,17 @@ + + + 640x640-svg透明 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/logo/640x640-white.png b/doc/logo/640x640-white.png new file mode 100644 index 0000000000000000000000000000000000000000..b4cfaab59882b0f97b38c5566207096e78dd51d5 GIT binary patch literal 31855 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 + + 640x640-svg白底 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/logo/logo.png b/doc/logo/logo.png deleted file mode 100644 index 56598b4fc6d9d5683ae386e9e706211e9d182fac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16835 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 B; + + 长款的 svg格式透明 + + + + Spring Cloud Tencent + + + + + + + + \ No newline at end of file diff --git a/doc/logo/rectangle-white.png b/doc/logo/rectangle-white.png new file mode 100644 index 0000000000000000000000000000000000000000..46a1c77d9a264617aaee25147f7ce0e959ef59ae GIT binary patch literal 18086 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 buh3N%WvcAct}(yg5hEogFIp+A=lj0^9tw)t literal 0 HcmV?d00001 diff --git a/doc/logo/rectangle-white.svg b/doc/logo/rectangle-white.svg new file mode 100644 index 000000000..5bc74ffb7 --- /dev/null +++ b/doc/logo/rectangle-white.svg @@ -0,0 +1,16 @@ + + + 长款的 svg 格式的白底 + + + + + Spring Cloud Tencent + + + + + + + + \ No newline at end of file From c0084f489de3c1004a55170541982a7a08b11e26 Mon Sep 17 00:00:00 2001 From: xingducai <836959451@qq.com> Date: Wed, 29 Jun 2022 22:13:58 +0800 Subject: [PATCH 04/14] Condition 'null != interceptors' is always 'true' (#342) --- CHANGELOG.md | 1 + .../config/MetadataTransferAutoConfiguration.java | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 765ac8f67..711ec9f9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,3 +27,4 @@ - [Feature: Optimize static metadata manager](https://github.com/Tencent/spring-cloud-tencent/pull/327) - [test:update junit of metadata.](https://github.com/Tencent/spring-cloud-tencent/pull/340) - [Optimize code style & unit test case](https://github.com/Tencent/spring-cloud-tencent/pull/336) +- [rm code: Condition 'null != interceptors' is always 'true' ](https://github.com/Tencent/spring-cloud-tencent/pull/342) diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java index 589875875..9f7514ae6 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java @@ -168,8 +168,7 @@ public class MetadataTransferAutoConfiguration { List interceptors = restTemplate .getInterceptors(); // Avoid setting interceptor repeatedly. - if (null != interceptors && !interceptors - .contains(encodeTransferMedataRestTemplateInterceptor)) { + if (!interceptors.contains(encodeTransferMedataRestTemplateInterceptor)) { interceptors.add(encodeTransferMedataRestTemplateInterceptor); restTemplate.setInterceptors(interceptors); } @@ -207,10 +206,8 @@ public class MetadataTransferAutoConfiguration { List interceptors = restTemplate .getInterceptors(); // Avoid setting interceptor repeatedly. - if (null != interceptors && !interceptors - .contains(encodeTransferMedataRestTemplateInterceptor)) { - interceptors - .add(this.encodeTransferMedataRestTemplateInterceptor); + if (!interceptors.contains(encodeTransferMedataRestTemplateInterceptor)) { + interceptors.add(this.encodeTransferMedataRestTemplateInterceptor); restTemplate.setInterceptors(interceptors); } } From 81658680398617d15a6b1d4ffbedcdf016941210 Mon Sep 17 00:00:00 2001 From: DerekYRC <44155264+DerekYRC@users.noreply.github.com> Date: Wed, 29 Jun 2022 23:21:09 +0800 Subject: [PATCH 05/14] fix: shutdown thread pool before the container closes (#353) --- CHANGELOG.md | 1 + .../PolarisRefreshApplicationReadyEventListener.java | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 711ec9f9e..5975505cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,3 +28,4 @@ - [test:update junit of metadata.](https://github.com/Tencent/spring-cloud-tencent/pull/340) - [Optimize code style & unit test case](https://github.com/Tencent/spring-cloud-tencent/pull/336) - [rm code: Condition 'null != interceptors' is always 'true' ](https://github.com/Tencent/spring-cloud-tencent/pull/342) +- [fix: shutdown thread pool before the container closes](https://github.com/Tencent/spring-cloud-tencent/pull/353) diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java index 9591cb389..53292e7cf 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java @@ -25,6 +25,7 @@ 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; @@ -38,7 +39,7 @@ import static com.tencent.cloud.polaris.discovery.refresh.PolarisServiceStatusCh * * @author Haotian Zhang */ -public class PolarisRefreshApplicationReadyEventListener implements ApplicationListener, ApplicationEventPublisherAware { +public class PolarisRefreshApplicationReadyEventListener implements ApplicationListener, ApplicationEventPublisherAware, DisposableBean { private static final Logger LOG = LoggerFactory.getLogger(PolarisRefreshApplicationReadyEventListener.class); private static final int DELAY = 60; @@ -83,4 +84,9 @@ public class PolarisRefreshApplicationReadyEventListener implements ApplicationL public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.publisher = applicationEventPublisher; } + + @Override + public void destroy() throws Exception { + refreshExecutor.shutdown(); + } } From c91b5622f09770da79c9a7233a8c930bc5ad0b0f Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Thu, 30 Jun 2022 17:57:51 +0800 Subject: [PATCH 06/14] docs:update logo in README. (#358) --- CHANGELOG.md | 1 + README-zh.md | 2 +- README.md | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5975505cf..8c28e78a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,3 +29,4 @@ - [Optimize code style & unit test case](https://github.com/Tencent/spring-cloud-tencent/pull/336) - [rm code: Condition 'null != interceptors' is always 'true' ](https://github.com/Tencent/spring-cloud-tencent/pull/342) - [fix: shutdown thread pool before the container closes](https://github.com/Tencent/spring-cloud-tencent/pull/353) +- [docs:update logo in README.](https://github.com/Tencent/spring-cloud-tencent/pull/358) diff --git a/README-zh.md b/README-zh.md index 5724154c0..f29879285 100644 --- a/README-zh.md +++ b/README-zh.md @@ -1,4 +1,4 @@ -Spring-Cloud-Tencent-Logo +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) diff --git a/README.md b/README.md index adfa43cf9..2c2965a53 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Spring-Cloud-Tencent-Logo +Spring-Cloud-Tencent-Logo [![Wiki](https://badgen.net/badge/icon/wiki?icon=wiki&label)](https://github.com/Tencent/spring-cloud-tencent/wiki) From 6d324d4dccbb53a0a63400c9bcfe32b82107a37a Mon Sep 17 00:00:00 2001 From: cheese8 Date: Fri, 1 Jul 2022 17:36:12 +0800 Subject: [PATCH 07/14] Refator JacksonUtils and JacksonUtilsTest (#365) --- CHANGELOG.md | 2 ++ .../cloud/common/util/JacksonUtils.java | 4 +-- .../cloud/common/util/JacksonUtilsTest.java | 34 ++++++++----------- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c28e78a1..123a022a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,3 +30,5 @@ - [rm code: Condition 'null != interceptors' is always 'true' ](https://github.com/Tencent/spring-cloud-tencent/pull/342) - [fix: shutdown thread pool before the container closes](https://github.com/Tencent/spring-cloud-tencent/pull/353) - [docs:update logo in README.](https://github.com/Tencent/spring-cloud-tencent/pull/358) +- [Refator JacksonUtils and JacksonUtilsTest](https://github.com/Tencent/spring-cloud-tencent/pull/365) + diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java index a30fc8bc1..2b55f102a 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java @@ -79,9 +79,7 @@ public final class JacksonUtils { return new HashMap<>(); } catch (JsonProcessingException e) { - LOG.error( - "Json to map failed. check if the format of the json string[{}] is correct.", - jsonStr, e); + LOG.error("Json to map failed. check if the format of the json string[{}] is correct.", jsonStr, e); throw new RuntimeException("Json to map failed.", e); } } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java index db0868dff..e07dcceb2 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java @@ -26,12 +26,12 @@ import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Test for {@link JacksonUtils}. * - * @author lepdou, Haotian Zhang + * @author lepdou, Haotian Zhang, cheese8 */ @RunWith(MockitoJUnitRunner.class) public class JacksonUtilsTest { @@ -42,10 +42,7 @@ public class JacksonUtilsTest { sourceMap.put("k1", "v1"); sourceMap.put("k2", "v2"); sourceMap.put("k3", "v3"); - - String jsonStr = JacksonUtils.serialize2Json(sourceMap); - - assertThat(jsonStr).isEqualTo("{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\"}"); + assertThat(JacksonUtils.serialize2Json(sourceMap)).isEqualTo("{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\"}"); } @Test @@ -56,20 +53,19 @@ public class JacksonUtilsTest { assertThat(map.get("k1")).isEqualTo("v1"); assertThat(map.get("k2")).isEqualTo("v2"); assertThat(map.get("k3")).isEqualTo("v3"); + } - assertThat(JacksonUtils.deserialize2Map("")).isNotNull(); - assertThat(JacksonUtils.deserialize2Map("")).isEmpty(); + @Test + public void testDeserializeBlankIntoEmptyMap() { + Map map = JacksonUtils.deserialize2Map(""); + assertThat(map).isNotNull(); + assertThat(map).isEmpty(); + } - jsonStr = "{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\""; - try { - JacksonUtils.deserialize2Map(jsonStr); - fail("RuntimeException should be thrown."); - } - catch (RuntimeException exception) { - assertThat(exception.getMessage()).isEqualTo("Json to map failed."); - } - catch (Throwable throwable) { - fail("RuntimeException should be thrown."); - } + @Test + public void testDeserializeThrowsRuntimeException() { + String jsonStr = "{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\""; + assertThatThrownBy(() -> JacksonUtils.deserialize2Map(jsonStr)) + .isExactlyInstanceOf(RuntimeException.class).hasMessage("Json to map failed."); } } From 45f2512e2021465bc79f4ed081f95943a1d2cca2 Mon Sep 17 00:00:00 2001 From: qingliu Date: Fri, 1 Jul 2022 17:59:21 +0800 Subject: [PATCH 08/14] feat: support actuator for sct core components (#343) * feat: support actuator for sct core components This commit only support actuator of config, metadata, discovery and ratelimit. * add: change log for actuator extension * feat: support actuator for sct core components This commit only support actuator of config, metadata, discovery and ratelimit. * add: change log for actuator extension * fix: unit test failed caused by merge code * fix: code style and design flaws * fix: unit test error caused by code format * fix: change the conditional class of polaris endpoint to endpoint class Co-authored-by: frankjlli --- CHANGELOG.md | 1 + .../pom.xml | 12 ++ .../endpoint/PolarisConfigEndpoint.java | 58 +++++++++ ...olarisConfigEndpointAutoConfiguration.java | 49 ++++++++ .../main/resources/META-INF/spring.factories | 3 +- .../endpoint/PolarisConfigEndpointTest.java | 70 +++++++++++ .../pom.xml | 12 ++ .../endpoint/PolarisDiscoveryEndPoint.java | 82 +++++++++++++ ...risDiscoveryEndpointAutoConfiguration.java | 49 ++++++++ .../main/resources/META-INF/spring.factories | 3 +- .../PolarisDiscoveryEndPointTest.java | 102 ++++++++++++++++ .../pom.xml | 12 ++ .../PolarisRateLimitRuleEndpoint.java | 101 ++++++++++++++++ ...ateLimitRuleEndpointAutoConfiguration.java | 50 ++++++++ .../main/resources/META-INF/spring.factories | 3 +- .../PolarisRateLimitRuleEndpointTests.java | 110 ++++++++++++++++++ spring-cloud-tencent-commons/pom.xml | 12 ++ .../endpoint/PolarisMetadataEndpoint.java | 56 +++++++++ ...arisMetadataEndpointAutoConfiguration.java | 44 +++++++ .../main/resources/META-INF/spring.factories | 3 +- .../PolarisMetadataEndpointTests.java | 58 +++++++++ .../src/main/resources/bootstrap.yml | 6 + .../polaris-config-example/pom.xml | 35 ++++++ .../src/main/resources/bootstrap.yml | 6 + .../src/main/resources/bootstrap.yml | 6 + .../ratelimit-callee-service/pom.xml | 4 + .../src/main/resources/bootstrap.yml | 7 ++ 27 files changed, 950 insertions(+), 4 deletions(-) create mode 100644 spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpoint.java create mode 100644 spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointAutoConfiguration.java create mode 100644 spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointTest.java create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPoint.java create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointAutoConfiguration.java create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPointTest.java create mode 100644 spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpoint.java create mode 100644 spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointAutoConfiguration.java create mode 100644 spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointTests.java create mode 100644 spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpoint.java create mode 100644 spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointAutoConfiguration.java create mode 100644 spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointTests.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 123a022a2..3c6a8fa64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - [feat:Add GitHub action of codecov.yml.](https://github.com/Tencent/spring-cloud-tencent/pull/328) - [Feature: add spring cloud tencent logo](https://github.com/Tencent/spring-cloud-tencent/pull/329) - [Feature: Optimize static metadata manager](https://github.com/Tencent/spring-cloud-tencent/pull/327) +- [Feature: support actuator for sct core components](https://github.com/Tencent/spring-cloud-tencent/pull/343) - [test:update junit of metadata.](https://github.com/Tencent/spring-cloud-tencent/pull/340) - [Optimize code style & unit test case](https://github.com/Tencent/spring-cloud-tencent/pull/336) - [rm code: Condition 'null != interceptors' is always 'true' ](https://github.com/Tencent/spring-cloud-tencent/pull/342) diff --git a/spring-cloud-starter-tencent-polaris-config/pom.xml b/spring-cloud-starter-tencent-polaris-config/pom.xml index a7f0e5894..e7262c29f 100644 --- a/spring-cloud-starter-tencent-polaris-config/pom.xml +++ b/spring-cloud-starter-tencent-polaris-config/pom.xml @@ -71,6 +71,18 @@ test + + org.springframework.boot + spring-boot-actuator + true + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + org.mockito mockito-inline diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpoint.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpoint.java new file mode 100644 index 000000000..eb9e94f5b --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpoint.java @@ -0,0 +1,58 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.config.endpoint; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySource; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; +import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; + +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; + +/** + * Endpoint of polaris config. + * + * @author shuiqingliu + **/ +@Endpoint(id = "polaris-config") +public class PolarisConfigEndpoint { + + private final PolarisConfigProperties polarisConfigProperties; + private final PolarisPropertySourceManager polarisPropertySourceManager; + + public PolarisConfigEndpoint(PolarisConfigProperties polarisConfigProperties, PolarisPropertySourceManager polarisPropertySourceManager) { + this.polarisConfigProperties = polarisConfigProperties; + this.polarisPropertySourceManager = polarisPropertySourceManager; + } + + @ReadOperation + public Map polarisConfig() { + Map configInfo = new HashMap<>(); + configInfo.put("PolarisConfigProperties", polarisConfigProperties); + + List propertySourceList = polarisPropertySourceManager.getAllPropertySources(); + configInfo.put("PolarisPropertySource", propertySourceList); + + return configInfo; + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointAutoConfiguration.java new file mode 100644 index 000000000..cb26462ee --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointAutoConfiguration.java @@ -0,0 +1,49 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.config.endpoint; + +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; +import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * The AutoConfiguration for Polaris Config's endpoint. + * + * @author shuiqingliu + **/ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Endpoint.class) +@ConditionalOnProperty(value = "spring.cloud.polaris.config.enabled", + matchIfMissing = true) +public class PolarisConfigEndpointAutoConfiguration { + + @Bean + @ConditionalOnAvailableEndpoint + @ConditionalOnMissingBean + public PolarisConfigEndpoint polarisConfigEndpoint(PolarisConfigProperties polarisConfigProperties, PolarisPropertySourceManager polarisPropertySourceManager) { + return new PolarisConfigEndpoint(polarisConfigProperties, polarisPropertySourceManager); + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories index a0c33067e..98221a39a 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories @@ -1,4 +1,5 @@ org.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.tencent.cloud.polaris.config.PolarisConfigBootstrapAutoConfiguration org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.tencent.cloud.polaris.config.PolarisConfigAutoConfiguration + com.tencent.cloud.polaris.config.PolarisConfigAutoConfiguration,\ + com.tencent.cloud.polaris.config.endpoint.PolarisConfigEndpointAutoConfiguration diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointTest.java new file mode 100644 index 000000000..93190ee1a --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointTest.java @@ -0,0 +1,70 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.config.endpoint; + +import java.util.HashMap; +import java.util.Map; + +import com.google.common.collect.Lists; +import com.tencent.cloud.polaris.config.adapter.MockedConfigKVFile; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySource; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; +import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +/** + * Test for polaris config endpoint. + * + * @author shuiqingliu + */ +@RunWith(MockitoJUnitRunner.class) +public class PolarisConfigEndpointTest { + + private final String testNamespace = "testNamespace"; + private final String testServiceName = "testServiceName"; + private final String testFileName = "application.properties"; + + @Mock + private PolarisConfigProperties polarisConfigProperties; + @Mock + private PolarisPropertySourceManager polarisPropertySourceManager; + + @Test + public void testPolarisConfigEndpoint() { + Map content = new HashMap<>(); + content.put("k1", "v1"); + content.put("k2", "v2"); + content.put("k3", "v3"); + MockedConfigKVFile file = new MockedConfigKVFile(content); + PolarisPropertySource polarisPropertySource = new PolarisPropertySource(testNamespace, testServiceName, testFileName, + file, content); + when(polarisPropertySourceManager.getAllPropertySources()).thenReturn(Lists.newArrayList(polarisPropertySource)); + + PolarisConfigEndpoint endpoint = new PolarisConfigEndpoint(polarisConfigProperties, polarisPropertySourceManager); + Map info = endpoint.polarisConfig(); + assertThat(polarisConfigProperties).isEqualTo(info.get("PolarisConfigProperties")); + assertThat(Lists.newArrayList(polarisPropertySource)).isEqualTo(info.get("PolarisPropertySource")); + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/pom.xml b/spring-cloud-starter-tencent-polaris-discovery/pom.xml index 39d8d5f83..ac077bb7b 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/pom.xml +++ b/spring-cloud-starter-tencent-polaris-discovery/pom.xml @@ -93,6 +93,18 @@ test + + org.springframework.boot + spring-boot-actuator + true + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + io.projectreactor reactor-test diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPoint.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPoint.java new file mode 100644 index 000000000..5e006ac00 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPoint.java @@ -0,0 +1,82 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.endpoint; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; +import com.tencent.polaris.api.pojo.ServiceInstances; +import com.tencent.polaris.api.rpc.InstancesResponse; +import org.apache.commons.lang.StringUtils; + +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.actuate.endpoint.annotation.Selector; +import org.springframework.cloud.client.discovery.DiscoveryClient; + +/** + * Endpoint of polaris discovery, include discovery properties and service instance. + * + * @author shuiqingliu + */ +@Endpoint(id = "polaris-discovery") +public class PolarisDiscoveryEndPoint { + + private final PolarisDiscoveryProperties polarisDiscoveryProperties; + private final DiscoveryClient polarisDiscoveryClient; + private final PolarisDiscoveryHandler polarisDiscoveryHandler; + + public PolarisDiscoveryEndPoint(PolarisDiscoveryProperties polarisDiscoveryProperties, DiscoveryClient polarisDiscoveryClient, PolarisDiscoveryHandler polarisDiscoveryHandler) { + this.polarisDiscoveryProperties = polarisDiscoveryProperties; + this.polarisDiscoveryClient = polarisDiscoveryClient; + this.polarisDiscoveryHandler = polarisDiscoveryHandler; + } + + @ReadOperation + public Map polarisDiscovery(@Selector String serviceId) { + Map polarisDisConveryInfo = new HashMap<>(); + polarisDisConveryInfo.put("PolarisDiscoveryProperties", polarisDiscoveryProperties); + + List serviceInstancesInfoList = new ArrayList<>(); + + if (StringUtils.isNotEmpty(serviceId)) { + ServiceInstances serviceInstances = getServiceInstances(serviceId); + serviceInstancesInfoList.add(serviceInstances); + polarisDisConveryInfo.put("ServiceInstances", serviceInstancesInfoList); + return polarisDisConveryInfo; + } + + for (String service : polarisDiscoveryClient.getServices()) { + ServiceInstances serviceInstances = getServiceInstances(service); + serviceInstancesInfoList.add(serviceInstances); + } + + polarisDisConveryInfo.put("ServiceInstances", serviceInstancesInfoList); + return polarisDisConveryInfo; + } + + private ServiceInstances getServiceInstances(String serviceId) { + InstancesResponse instancesResponse = polarisDiscoveryHandler.getHealthyInstances(serviceId); + ServiceInstances serviceInstances = instancesResponse.toServiceInstances(); + return serviceInstances; + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointAutoConfiguration.java new file mode 100644 index 000000000..d6b597634 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointAutoConfiguration.java @@ -0,0 +1,49 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.endpoint; + +import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.discovery.ConditionalOnPolarisDiscoveryEnabled; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * The AutoConfiguration for Polaris Discovery's Endpoint. + * + * @author shuiqingliu + **/ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Endpoint.class) +@ConditionalOnPolarisDiscoveryEnabled +public class PolarisDiscoveryEndpointAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + public PolarisDiscoveryEndPoint polarisDiscoveryEndPoint(PolarisDiscoveryProperties polarisDiscoveryProperties, + DiscoveryClient discoveryClient, PolarisDiscoveryHandler polarisDiscoveryHandler) { + return new PolarisDiscoveryEndPoint(polarisDiscoveryProperties, discoveryClient, polarisDiscoveryHandler); + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories index 83b8e001f..e8deb25e8 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories @@ -2,6 +2,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.polaris.DiscoveryPropertiesAutoConfiguration,\ com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration,\ com.tencent.cloud.polaris.ribbon.PolarisDiscoveryRibbonAutoConfiguration,\ - com.tencent.cloud.polaris.registry.PolarisServiceRegistryAutoConfiguration + com.tencent.cloud.polaris.registry.PolarisServiceRegistryAutoConfiguration,\ + com.tencent.cloud.polaris.endpoint.PolarisDiscoveryEndpointAutoConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.tencent.cloud.polaris.DiscoveryPropertiesBootstrapAutoConfiguration diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPointTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPointTest.java new file mode 100644 index 000000000..ea5562d11 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPointTest.java @@ -0,0 +1,102 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.endpoint; + +import java.util.Map; + +import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClient; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; +import com.tencent.polaris.test.mock.discovery.NamingServer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.annotation.Configuration; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.PORT; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for polaris discovery endpoint. + * + * @author shuiqingliu + */ +public class PolarisDiscoveryEndPointTest { + + private static NamingServer namingServer; + + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisDiscoveryEndPointTest.PolarisPropertiesConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisDiscoveryAutoConfiguration.class, + PolarisDiscoveryEndpointAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") + .withPropertyValues( + "spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) + .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); + + @BeforeClass + public static void beforeClass() throws Exception { + namingServer = NamingServer.startNamingServer(10081); + } + + @AfterClass + public static void afterClass() throws Exception { + if (null != namingServer) { + namingServer.terminate(); + } + } + + @Test + public void testPolarisDiscoveryEndpoint() { + this.contextRunner.run(context -> { + PolarisDiscoveryProperties polarisDiscoveryProperties = context + .getBean(PolarisDiscoveryProperties.class); + DiscoveryClient discoveryClient = context + .getBean(PolarisDiscoveryClient.class); + PolarisDiscoveryHandler polarisDiscoveryHandler = context.getBean(PolarisDiscoveryHandler.class); + PolarisDiscoveryEndPoint polarisDiscoveryEndPoint = new PolarisDiscoveryEndPoint(polarisDiscoveryProperties, discoveryClient, polarisDiscoveryHandler); + + Map mapInfo = polarisDiscoveryEndPoint.polarisDiscovery("java_provider_test"); + + assertThat(polarisDiscoveryProperties).isEqualTo(mapInfo.get("PolarisDiscoveryProperties")); + + }); + } + + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + static class PolarisPropertiesConfiguration { + + } + +} diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml index aaccef814..d3499deee 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml +++ b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml @@ -90,6 +90,18 @@ test + + org.springframework.boot + spring-boot-actuator + true + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + org.mockito mockito-inline diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpoint.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpoint.java new file mode 100644 index 000000000..28bbae229 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpoint.java @@ -0,0 +1,101 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.ratelimit.endpoint; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties; +import com.tencent.polaris.client.pb.RateLimitProto; +import com.tencent.polaris.client.pb.RoutingProto; +import org.apache.commons.lang.StringUtils; + +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.actuate.endpoint.annotation.Selector; +import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; + +/** + * Endpoint of Polaris RateLimit rule. + * + * @author shuiqingliu + **/ +@Endpoint(id = "polaris-ratelimit") +public class PolarisRateLimitRuleEndpoint { + + private final ServiceRuleManager serviceRuleManager; + private final PolarisRateLimitProperties polarisRateLimitProperties; + + public PolarisRateLimitRuleEndpoint(ServiceRuleManager serviceRuleManager, PolarisRateLimitProperties polarisRateLimitProperties) { + this.serviceRuleManager = serviceRuleManager; + this.polarisRateLimitProperties = polarisRateLimitProperties; + } + + @ReadOperation + public Map rateLimit(@Selector String namespace, @Selector String service, @Nullable String dstService) { + Map result = new HashMap<>(); + RateLimitProto.RateLimit rateLimit = serviceRuleManager.getServiceRateLimitRule(namespace, service); + result.put("properties", polarisRateLimitProperties); + result.put("namespace", namespace); + result.put("service", service); + result.put("rateLimits", parseRateLimitRule(rateLimit)); + + if (StringUtils.isEmpty(dstService)) { + return result; + } + List routes = serviceRuleManager.getServiceRouterRule(namespace, service, dstService); + result.put("routes", routes); + return result; + } + + private List parseRateLimitRule(RateLimitProto.RateLimit rateLimit) { + List rateLimitRule = new ArrayList<>(); + if (rateLimit == null || CollectionUtils.isEmpty(rateLimit.getRulesList())) { + return rateLimitRule; + } + + for (RateLimitProto.Rule rule : rateLimit.getRulesList()) { + Map ruleMap = new HashMap<>(); + ruleMap.put("id", rule.getId()); + ruleMap.put("priority", rule.getPriority()); + ruleMap.put("resource", rule.getResource()); + ruleMap.put("type", rule.getType()); + ruleMap.put("labels", rule.getLabelsMap()); + ruleMap.put("amounts", rule.getAmountsList()); + ruleMap.put("action", rule.getAction()); + ruleMap.put("disable", rule.getDisable()); + ruleMap.put("report", rule.getReport()); + ruleMap.put("create_time", rule.getCtime()); + ruleMap.put("modify_time", rule.getMtime()); + ruleMap.put("revision", rule.getRevision()); + ruleMap.put("service_token", rule.getServiceToken()); + ruleMap.put("adjuster", rule.getAdjuster()); + ruleMap.put("regex_combine", rule.getRegexCombine()); + ruleMap.put("amount_mode", rule.getAmountMode()); + ruleMap.put("failover", rule.getFailover()); + ruleMap.put("cluster", rule.getCluster()); + rateLimitRule.add(ruleMap); + } + return rateLimitRule; + } + +} diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointAutoConfiguration.java new file mode 100644 index 000000000..d16832989 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointAutoConfiguration.java @@ -0,0 +1,50 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.ratelimit.endpoint; + +import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; +import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * The AutoConfiguration for Polaris RateLimit endpoint. + * + * @author shuiqingliu + **/ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Endpoint.class) +@ConditionalOnPolarisEnabled +@ConditionalOnProperty(name = "spring.cloud.polaris.ratelimit.enabled", matchIfMissing = true) +public class PolarisRateLimitRuleEndpointAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + public PolarisRateLimitRuleEndpoint polarisRateLimitRuleEndpoint(ServiceRuleManager serviceRuleManager, PolarisRateLimitProperties properties) { + return new PolarisRateLimitRuleEndpoint(serviceRuleManager, properties); + } + +} diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories index 4abd34766..563704410 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories @@ -1,5 +1,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitAutoConfiguration,\ - com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitPropertiesAutoConfiguration + com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitPropertiesAutoConfiguration,\ + com.tencent.cloud.polaris.ratelimit.endpoint.PolarisRateLimitRuleEndpointAutoConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitPropertiesBootstrapConfiguration diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointTests.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointTests.java new file mode 100644 index 000000000..d5d7e6fd0 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointTests.java @@ -0,0 +1,110 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.ratelimit.endpoint; + +import java.util.Map; + +import com.google.protobuf.StringValue; +import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties; +import com.tencent.polaris.client.pb.ModelProto; +import com.tencent.polaris.client.pb.RateLimitProto; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Configuration; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.PORT; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Test for polaris rete limit rule endpoint. + * + * @author shuiqingliu + */ +@RunWith(MockitoJUnitRunner.class) +public class PolarisRateLimitRuleEndpointTests { + + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisRateLimitRuleEndpointTests.PolarisRateLimitAutoConfiguration.class, + PolarisRateLimitRuleEndpointAutoConfiguration.class, + PolarisRateLimitAutoConfiguration.class, + PolarisRateLimitAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") + .withPropertyValues( + "spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) + .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); + + private ServiceRuleManager serviceRuleManager; + private PolarisRateLimitProperties polarisRateLimitProperties; + + @Before + public void setUp() { + serviceRuleManager = mock(ServiceRuleManager.class); + when(serviceRuleManager.getServiceRateLimitRule(any(), anyString())).thenAnswer(invocationOnMock -> { + String serviceName = invocationOnMock.getArgument(1).toString(); + if (serviceName.equals("TestApp1")) { + return null; + } + else if (serviceName.equals("TestApp2")) { + return RateLimitProto.RateLimit.newBuilder().build(); + } + else if (serviceName.equals("TestApp3")) { + RateLimitProto.Rule rule = RateLimitProto.Rule.newBuilder().build(); + return RateLimitProto.RateLimit.newBuilder().addRules(rule).build(); + } + else { + ModelProto.MatchString matchString = ModelProto.MatchString.newBuilder() + .setType(ModelProto.MatchString.MatchStringType.EXACT) + .setValue(StringValue.of("value")) + .setValueType(ModelProto.MatchString.ValueType.TEXT).build(); + RateLimitProto.Rule rule = RateLimitProto.Rule.newBuilder() + .putLabels("${http.method}", matchString).build(); + return RateLimitProto.RateLimit.newBuilder().addRules(rule).build(); + } + }); + } + + @Test + public void testPolarisRateLimit() { + this.contextRunner.run(context -> polarisRateLimitProperties = context.getBean(PolarisRateLimitProperties.class)); + PolarisRateLimitRuleEndpoint polarisRateLimitRuleEndpoint = new PolarisRateLimitRuleEndpoint(serviceRuleManager, polarisRateLimitProperties); + Map rateLimit = polarisRateLimitRuleEndpoint.rateLimit("namespaceTest", "TestApp2", "TestApp3"); + assertThat(polarisRateLimitProperties).isEqualTo(rateLimit.get("properties")); + } + + @Configuration + @EnableAutoConfiguration + static class PolarisRateLimitAutoConfiguration { + + } +} diff --git a/spring-cloud-tencent-commons/pom.xml b/spring-cloud-tencent-commons/pom.xml index 1ad46ae56..495fc4a15 100644 --- a/spring-cloud-tencent-commons/pom.xml +++ b/spring-cloud-tencent-commons/pom.xml @@ -93,6 +93,18 @@ spring-boot-starter-test test + + + org.springframework.boot + spring-boot-actuator + true + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpoint.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpoint.java new file mode 100644 index 000000000..360018ea2 --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpoint.java @@ -0,0 +1,56 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.common.metadata.endpoint; + +import java.util.HashMap; +import java.util.Map; + +import com.tencent.cloud.common.metadata.StaticMetadataManager; + +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; + +/** + * Endpoint of polaris's metadata. + * + * @author shuiqingliu + **/ +@Endpoint(id = "polaris-metadata") +public class PolarisMetadataEndpoint { + + private final StaticMetadataManager staticMetadataManager; + + public PolarisMetadataEndpoint(StaticMetadataManager staticMetadataManager) { + this.staticMetadataManager = staticMetadataManager; + } + + @ReadOperation + public Map metadata() { + Map result = new HashMap<>(); + result.put("Env", staticMetadataManager.getAllEnvMetadata()); + result.put("EnvTransitive", staticMetadataManager.getEnvTransitiveMetadata()); + result.put("ConfigTransitive", staticMetadataManager.getConfigTransitiveMetadata()); + result.put("Config", staticMetadataManager.getAllConfigMetadata()); + result.put("MergeStatic", staticMetadataManager.getMergedStaticMetadata()); + result.put("CustomSPI", staticMetadataManager.getCustomSPITransitiveMetadata()); + result.put("zone", staticMetadataManager.getZone()); + result.put("region", staticMetadataManager.getRegion()); + result.put("campus", staticMetadataManager.getCampus()); + return result; + } +} diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointAutoConfiguration.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointAutoConfiguration.java new file mode 100644 index 000000000..9c87587c9 --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointAutoConfiguration.java @@ -0,0 +1,44 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.common.metadata.endpoint; + +import com.tencent.cloud.common.metadata.StaticMetadataManager; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * The AutoConfiguration for metadata endpoint. + * + * @author shuiqingliu + **/ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Endpoint.class) +public class PolarisMetadataEndpointAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + public PolarisMetadataEndpoint metadataEndpoint(StaticMetadataManager staticMetadataManager) { + return new PolarisMetadataEndpoint(staticMetadataManager); + } +} diff --git a/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories index ba9f2b867..4c54d3372 100644 --- a/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories @@ -1,3 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.common.util.ApplicationContextAwareUtils,\ - com.tencent.cloud.common.metadata.config.MetadataAutoConfiguration + com.tencent.cloud.common.metadata.config.MetadataAutoConfiguration,\ + com.tencent.cloud.common.metadata.endpoint.PolarisMetadataEndpointAutoConfiguration diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointTests.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointTests.java new file mode 100644 index 000000000..d20a2fd4f --- /dev/null +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpointTests.java @@ -0,0 +1,58 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + + +package com.tencent.cloud.common.metadata.endpoint; + +import java.util.HashMap; +import java.util.Map; + +import com.tencent.cloud.common.metadata.StaticMetadataManager; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +/** + * Test for polaris metadata endpoint. + * + * @author shuiqingliu + */ +@RunWith(MockitoJUnitRunner.class) +public class PolarisMetadataEndpointTests { + + @Mock + private StaticMetadataManager staticMetadataManager; + + @Test + public void testPolarisMetadataEndpoint() { + Map envMetadata = new HashMap<>(); + envMetadata.put("k1", "v1"); + envMetadata.put("k2", "v2"); + envMetadata.put("k3", "v3"); + + when(staticMetadataManager.getAllEnvMetadata()).thenReturn(envMetadata); + + PolarisMetadataEndpoint polarisMetadataEndpoint = new PolarisMetadataEndpoint(staticMetadataManager); + Map metaMap = polarisMetadataEndpoint.metadata(); + assertThat(envMetadata).isEqualTo(metaMap.get("Env")); + } +} diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/resources/bootstrap.yml index 89d1f233b..a390f51a6 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/resources/bootstrap.yml @@ -24,3 +24,9 @@ spring: # Assigned which metadata key-value will be passed along the link transitive: - CUSTOM-METADATA-KEY-TRANSITIVE +management: + endpoints: + web: + exposure: + include: + - polaris-metadata \ No newline at end of file diff --git a/spring-cloud-tencent-examples/polaris-config-example/pom.xml b/spring-cloud-tencent-examples/polaris-config-example/pom.xml index cef91e5a3..bb7ef026e 100644 --- a/spring-cloud-tencent-examples/polaris-config-example/pom.xml +++ b/spring-cloud-tencent-examples/polaris-config-example/pom.xml @@ -24,6 +24,41 @@ com.tencent.cloud spring-cloud-starter-tencent-polaris-config + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.0 + + + attach-sources + + jar + + + + + + + diff --git a/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml index 38ed7eed0..84e44d4aa 100644 --- a/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml @@ -12,3 +12,9 @@ spring: groups: - name: ${spring.application.name} # group name files: [ "config/application.properties", "config/bootstrap.yml" ] # config/application.properties takes precedence over config/bootstrap.yml +management: + endpoints: + web: + exposure: + include: + - polaris-config \ No newline at end of file diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml index e9ccc1f29..544193b7e 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml @@ -32,3 +32,9 @@ spring: # client: # serviceUrl: # defaultZone: http://127.0.0.1:7654/eureka/ +management: + endpoints: + web: + exposure: + include: + - polaris-discovery \ No newline at end of file diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml index cd9f48757..f7cbb1e6f 100644 --- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml @@ -28,6 +28,10 @@ spring-cloud-starter-tencent-polaris-ratelimit + + org.springframework.boot + spring-boot-starter-actuator + diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml index 37c986394..6741bde11 100644 --- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml @@ -12,3 +12,10 @@ spring: enabled: true rejectRequestTipsFilePath: reject-tips.html maxQueuingTime: 500 + +management: + endpoints: + web: + exposure: + include: + - polaris-ratelimit \ No newline at end of file From f481588c48bab25d0090e74deda739457af03bec Mon Sep 17 00:00:00 2001 From: cheese8 Date: Fri, 1 Jul 2022 22:49:26 +0800 Subject: [PATCH 09/14] Fix javadoc
error (#371) --- CHANGELOG.md | 2 ++ .../config/annotation/PolarisConfigKVFileChangeListener.java | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c6a8fa64..2c0aed5a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,4 +32,6 @@ - [fix: shutdown thread pool before the container closes](https://github.com/Tencent/spring-cloud-tencent/pull/353) - [docs:update logo in README.](https://github.com/Tencent/spring-cloud-tencent/pull/358) - [Refator JacksonUtils and JacksonUtilsTest](https://github.com/Tencent/spring-cloud-tencent/pull/365) +- [docs: Fix javadoc
error](https://github.com/Tencent/spring-cloud-tencent/pull/371) + diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java index 6acbf2336..142b41bed 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java @@ -38,7 +38,7 @@ public @interface PolarisConfigKVFileChangeListener { /** * The keys interested in the listener, will only be notified if any of the interested keys is changed. - *
+ *

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

* If neither of {@code interestedKeys} and {@code interestedKeyPrefixes} is specified then the {@code listener} will be notified when whatever key is changed. * @return interested key-prefixed in the listener */ From 2439ebb0edb05bde5d2a33c01ac2639ca5b56cef Mon Sep 17 00:00:00 2001 From: "lingxiao,wu" <51630311+lingxiao-wu@users.noreply.github.com> Date: Sat, 2 Jul 2022 18:34:17 +0800 Subject: [PATCH 10/14] UT: add Polaris LoadBalancer unit test (#373) --- CHANGELOG.md | 1 + .../pom.xml | 7 ++- ...arisLoadBalancerAutoConfigurationTest.java | 61 ++++++++++++++++++- .../PolarisRibbonClientConfigurationTest.java | 55 +++++++++++++++++ 4 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c0aed5a1..745526838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,5 +33,6 @@ - [docs:update logo in README.](https://github.com/Tencent/spring-cloud-tencent/pull/358) - [Refator JacksonUtils and JacksonUtilsTest](https://github.com/Tencent/spring-cloud-tencent/pull/365) - [docs: Fix javadoc
error](https://github.com/Tencent/spring-cloud-tencent/pull/371) +- [UT: add Polaris LoadBalancer unit test](https://github.com/Tencent/spring-cloud-tencent/pull/373) diff --git a/spring-cloud-tencent-polaris-loadbalancer/pom.xml b/spring-cloud-tencent-polaris-loadbalancer/pom.xml index 7475e83fb..2a26fcd8f 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/pom.xml +++ b/spring-cloud-tencent-polaris-loadbalancer/pom.xml @@ -55,7 +55,12 @@ mockito-inline test + + com.tencent.polaris + polaris-discovery-client + test + - + diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java index eab96ee76..d1111dd02 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java @@ -17,13 +17,32 @@ package com.tencent.cloud.polaris.loadbalancer.config; +import com.netflix.client.config.DefaultClientConfigImpl; +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.ILoadBalancer; +import com.netflix.loadbalancer.IPing; +import com.netflix.loadbalancer.IRule; +import com.netflix.loadbalancer.NoOpPing; +import com.netflix.loadbalancer.RandomRule; +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.loadbalancer.PolarisLoadBalancer; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.client.api.SDKContext; +import com.tencent.polaris.discovery.client.api.DefaultConsumerAPI; import com.tencent.polaris.router.api.core.RouterAPI; import org.junit.Test; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; +import org.springframework.cloud.netflix.ribbon.SpringClientFactory; +import org.springframework.cloud.netflix.ribbon.StaticServerList; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import static com.tencent.polaris.test.common.Consts.PORT; @@ -37,10 +56,11 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisLoadBalancerAutoConfigurationTest { - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(PolarisRibbonTest.class, PolarisLoadBalancerAutoConfiguration.class, - PolarisContextAutoConfiguration.class)) + PolarisContextAutoConfiguration.class, + RibbonAutoConfiguration.class)) .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); @@ -50,13 +70,50 @@ public class PolarisLoadBalancerAutoConfigurationTest { this.contextRunner.run(context -> { assertThat(context).hasSingleBean(RouterAPI.class); assertThat(context).hasSingleBean(PolarisLoadBalancerProperties.class); + assertThat(hasSinglePolarisLoadBalancer(context)).isTrue(); }); } + private boolean hasSinglePolarisLoadBalancer(BeanFactory beanFactory) { + SpringClientFactory contextBean = beanFactory.getBean(SpringClientFactory.class); + ILoadBalancer loadBalancer = contextBean.getLoadBalancer(SERVICE_PROVIDER); + return loadBalancer instanceof PolarisLoadBalancer; + } + @Configuration @EnableAutoConfiguration static class PolarisRibbonTest { + @Autowired + private SDKContext sdkContext; + + @Bean + public IClientConfig iClientConfig() { + DefaultClientConfigImpl config = new DefaultClientConfigImpl(); + config.setClientName(SERVICE_PROVIDER); + return config; + } + + @Bean + public IRule iRule() { + return new RandomRule(); + } + + @Bean + public IPing iPing() { + return new NoOpPing(); + } + + @Bean + public ServerList serverList() { + return new StaticServerList<>(); + } + + @Bean + public ConsumerAPI consumerAPI() { + return new DefaultConsumerAPI(sdkContext); + } + } } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java new file mode 100644 index 000000000..d514af6db --- /dev/null +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java @@ -0,0 +1,55 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.loadbalancer.config; + +import com.tencent.cloud.polaris.loadbalancer.PolarisLoadBalancer; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link PolarisRibbonClientConfiguration}. + * + * @author wlx + * @date 2022/7/2 10:36 上午 + */ +public class PolarisRibbonClientConfigurationTest { + + private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); + + @Test + public void testDefaultInitialization() { + this.applicationContextRunner + .withConfiguration(AutoConfigurations.of( + TestApplication.class, + PolarisRibbonClientConfiguration.class)) + .run(context -> { + assertThat(context).hasSingleBean(PolarisRibbonClientConfiguration.class); + assertThat(context).hasSingleBean(PolarisLoadBalancer.class); + }); + } + + @SpringBootApplication + static class TestApplication { + } + +} From 174f7cce467669d1e34e9b6b2e823cda7d3c9702 Mon Sep 17 00:00:00 2001 From: Xiaojie Wang Date: Mon, 4 Jul 2022 08:00:33 +0800 Subject: [PATCH 11/14] Update README.md (#378) --- spring-cloud-tencent-examples/polaris-gateway-example/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/README.md b/spring-cloud-tencent-examples/polaris-gateway-example/README.md index 43bd680f6..b1bb35671 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/README.md +++ b/spring-cloud-tencent-examples/polaris-gateway-example/README.md @@ -2,7 +2,7 @@ ## Example Introduction -This example shows how to use ```spring-cloud-tencent-polaris-gateway`` in Spring Cloud project for its features. +This example shows how to use ```spring-cloud-tencent-polaris-gateway``` in Spring Cloud project for its features. This example contains ```gateway-zuul-service```, ```gateway-scg-service``` and ```gateway-callee-service```. ```gateway-zuul-service``` and ```gateway-scg-service``` invoke ```gateway-callee-service```. From cffdd56f7c0aa878eeb5aa579793dac8a6173727 Mon Sep 17 00:00:00 2001 From: Xiaojie Wang Date: Mon, 4 Jul 2022 08:00:48 +0800 Subject: [PATCH 12/14] Update CHANGELOG.md (#380) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 745526838..435c85f8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,5 +34,6 @@ - [Refator JacksonUtils and JacksonUtilsTest](https://github.com/Tencent/spring-cloud-tencent/pull/365) - [docs: Fix javadoc
error](https://github.com/Tencent/spring-cloud-tencent/pull/371) - [UT: add Polaris LoadBalancer unit test](https://github.com/Tencent/spring-cloud-tencent/pull/373) +- [docs:update docs](https://github.com/Tencent/spring-cloud-tencent/pull/378) From e5f7a75e099fb840bfdb92eff216efe93a5a0ab0 Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Mon, 4 Jul 2022 12:48:23 +0800 Subject: [PATCH 13/14] refactor:optimize project and code (#368) * refactor:optimize project and code * refactor:optimize project and code * refactor:optimize project and code --- CHANGELOG.md | 3 +- changes/changes-1.5.3.md | 4 + .../MetadataTransferAutoConfiguration.java | 28 +++---- .../CustomTransitiveMetadataResolver.java | 16 ++-- .../DecodeTransferMetadataReactiveFilter.java | 3 +- .../DecodeTransferMetadataServletFilter.java | 7 +- .../EncodeTransferMedataFeignInterceptor.java | 3 +- ...TransferMedataRestTemplateInterceptor.java | 4 +- .../core/EncodeTransferMedataScgFilter.java | 7 +- .../EncodeTransferMetadataZuulFilter.java | 6 +- ...MetadataTransferAutoConfigurationTest.java | 5 +- ...odeTransferMetadataReactiveFilterTest.java | 1 - ...codeTransferMetadataServletFilterTest.java | 7 +- ...odeTransferMedataFeignInterceptorTest.java | 15 +--- ...sferMedataRestTemplateInterceptorTest.java | 14 +--- .../EncodeTransferMedataScgFilterTest.java | 3 +- .../EncodeTransferMetadataZuulFilterTest.java | 7 +- ...sCircuitBreakerBootstrapConfiguration.java | 2 - .../PolarisFeignClientAutoConfiguration.java | 4 +- .../PolarisRestTemplateAutoConfiguration.java | 1 - .../feign/PolarisFeignBeanPostProcessor.java | 4 +- ...olarisFeignBlockingLoadBalancerClient.java | 1 - .../feign/PolarisFeignClient.java | 3 +- .../feign/PolarisLoadBalancerFeignClient.java | 4 +- .../PolarisRestTemplateModifier.java | 6 +- ...larisRestTemplateResponseErrorHandler.java | 7 +- ...cuitBreakerBootstrapConfigurationTest.java | 6 +- ...larisFeignClientAutoConfigurationTest.java | 8 +- ...arisRestTemplateAutoConfigurationTest.java | 10 +-- .../feign/PolarisFeignClientTest.java | 9 ++- .../SimpleClientHttpResponseTest.java | 1 - .../polaris/config/ConfigurationModifier.java | 1 - .../PolarisConfigAutoConfiguration.java | 1 - ...larisConfigBootstrapAutoConfiguration.java | 4 +- .../adapter/PolarisConfigFileLocator.java | 34 ++++---- .../config/adapter/PolarisPropertySource.java | 1 - .../PolarisPropertySourceAutoRefresher.java | 78 ++++++++----------- .../adapter/PolarisPropertySourceManager.java | 4 +- .../PolarisConfigAnnotationProcessor.java | 4 +- .../PolarisConfigKVFileChangeListener.java | 1 - .../config/config/ConfigFileGroup.java | 1 - .../config/PolarisConfigProperties.java | 1 - .../config/enums/ConfigFileFormat.java | 1 - .../config/listener/ConfigChangeEvent.java | 1 - .../config/listener/ConfigChangeListener.java | 1 - .../PolarisConfigChangeEventListener.java | 1 - .../PolarisConfigListenerContext.java | 10 +-- .../config/adapter/MockedConfigKVFile.java | 3 +- .../adapter/PolarisConfigFileLocatorTest.java | 10 +-- ...arisPropertiesSourceAutoRefresherTest.java | 13 ++-- .../listener/ConfigChangeListenerTest.java | 7 +- .../polaris/DiscoveryConfigModifier.java | 4 +- .../DiscoveryPropertiesAutoConfiguration.java | 7 +- .../polaris/PolarisDiscoveryProperties.java | 1 - .../ConditionalOnPolarisDiscoveryEnabled.java | 2 + .../discovery/DiscoveryEnabledCondition.java | 16 ++-- .../PolarisDiscoveryAutoConfiguration.java | 1 - .../discovery/PolarisDiscoveryClient.java | 1 - .../PolarisDiscoveryClientConfiguration.java | 7 +- .../discovery/PolarisDiscoveryHandler.java | 4 +- .../discovery/PolarisServiceDiscovery.java | 6 +- .../PolarisReactiveDiscoveryClient.java | 14 ++-- ...sReactiveDiscoveryClientConfiguration.java | 1 - ...sRefreshApplicationReadyEventListener.java | 8 +- .../PolarisServiceStatusChangeListener.java | 9 ++- .../consul/ConsulContextProperties.java | 2 - .../ConditionalOnPolarisRegisterEnabled.java | 2 + .../PolarisAutoServiceRegistration.java | 9 +-- .../polaris/registry/PolarisRegistration.java | 7 +- .../registry/PolarisServiceRegistry.java | 36 ++++----- ...larisServiceRegistryAutoConfiguration.java | 6 +- .../registry/RegisterEnabledCondition.java | 11 +-- .../PolarisRibbonServerListConfiguration.java | 4 +- .../polaris/ribbon/PolarisServerList.java | 4 +- .../cloud/polaris/util/OkHttpUtil.java | 4 +- ...coveryPropertiesAutoConfigurationTest.java | 9 ++- ...pertiesBootstrapAutoConfigurationTest.java | 3 +- ...PolarisDiscoveryAutoConfigurationTest.java | 17 ++-- ...larisDiscoveryClientConfigurationTest.java | 24 +++--- .../discovery/PolarisDiscoveryClientTest.java | 5 +- .../PolarisServiceDiscoveryTest.java | 19 ++--- ...ctiveDiscoveryClientConfigurationTest.java | 17 ++-- .../PolarisReactiveDiscoveryClientTest.java | 2 - ...olarisServiceStatusChangeListenerTest.java | 10 ++- .../PolarisAutoServiceRegistrationTest.java | 1 - ...sServiceRegistryAutoConfigurationTest.java | 18 ++--- .../registry/PolarisServiceRegistryTest.java | 27 +++---- ...sDiscoveryRibbonAutoConfigurationTest.java | 2 +- ...arisRibbonServerListConfigurationTest.java | 2 +- .../polaris/ribbon/PolarisServerListTest.java | 35 ++++----- .../ratelimit/RateLimitRuleLabelResolver.java | 2 +- .../PolarisRateLimitAutoConfiguration.java | 3 - .../config/RateLimitConfigModifier.java | 4 +- .../ratelimit/constant/RateLimitConstant.java | 1 - .../filter/QuotaCheckReactiveFilter.java | 1 - .../filter/QuotaCheckServletFilter.java | 3 +- ...larisRateLimiterLabelReactiveResolver.java | 1 - ...olarisRateLimiterLabelServletResolver.java | 1 - .../ratelimit/utils/QuotaCheckUtils.java | 1 - .../ratelimit/utils/RateLimitUtils.java | 1 - ...PolarisRateLimitAutoConfigurationTest.java | 22 ++++-- ...eLimitPropertiesAutoConfigurationTest.java | 5 +- ...tPropertiesBootstrapConfigurationTest.java | 5 +- .../controller/CalleeControllerTests.java | 9 +-- .../ratelimit/controller/TestController.java | 3 +- .../filter/QuotaCheckReactiveFilterTest.java | 13 ++-- .../filter/QuotaCheckServletFilterTest.java | 20 ++--- .../polaris/router/PolarisRouterContext.java | 2 +- .../cloud/polaris/router/RouterConstants.java | 7 +- .../router/RouterRuleLabelResolver.java | 1 + .../polaris/router/SimpleLoadBalancer.java | 2 +- ...BalancerClientFilterBeanPostProcessor.java | 3 +- ...dBalancerInterceptorBeanPostProcessor.java | 3 +- .../router/config/FeignAutoConfiguration.java | 4 +- .../FeignLoadBalancerConfiguration.java | 6 +- .../router/config/RibbonConfiguration.java | 1 + .../config/RouterAutoConfiguration.java | 2 +- .../PolarisMetadataRouterProperties.java | 1 + .../feign/FeignExpressionLabelUtils.java | 6 +- ...olarisCachingSpringLoadBalanceFactory.java | 2 +- .../feign/PolarisFeignLoadBalancer.java | 3 +- .../feign/RouterLabelFeignInterceptor.java | 4 +- .../PolarisLoadBalancerInterceptor.java | 2 +- .../scg/PolarisLoadBalancerClientFilter.java | 3 +- .../PolarisLoadBalancerCompositeRuleTest.java | 10 +-- .../router/PolarisRouterContextTest.java | 4 +- .../router/RouterRuleLabelResolverTest.java | 10 +-- .../router/SimpleLoadBalancerTest.java | 5 +- .../feign/FeignExpressionLabelUtilsTest.java | 5 +- ...isCachingSpringLoadBalanceFactoryTest.java | 10 +-- .../feign/PolarisFeignLoadBalancerTest.java | 10 ++- .../RouterLabelFeignInterceptorTest.java | 12 +-- ...arisLoadBalancerBeanPostProcessorTest.java | 3 +- .../PolarisLoadBalancerInterceptorTest.java | 11 ++- .../PolarisLoadBalancerClientFilterTest.java | 15 ++-- .../common/constant/ContextConstant.java | 2 - .../common/constant/MetadataConstant.java | 6 +- .../common/metadata/MetadataContext.java | 10 +-- .../metadata/MetadataContextHolder.java | 4 +- .../metadata/StaticMetadataManager.java | 19 ++--- .../config/MetadataAutoConfiguration.java | 2 - .../config/MetadataLocalProperties.java | 1 - .../gateway/MetadataFirstScgFilter.java | 7 +- .../common/pojo/PolarisServiceInstance.java | 1 - .../common/spi/InstanceMetadataProvider.java | 2 +- .../cloud/common/util/AddressUtils.java | 1 - .../util/ApplicationContextAwareUtils.java | 1 - .../cloud/common/util/BeanFactoryUtils.java | 6 +- .../common/util/ExpressionLabelUtils.java | 4 +- .../cloud/common/util/JacksonUtils.java | 1 - .../cloud/common/util/ReflectionUtils.java | 1 - .../cloud/common/util/ResourceFileUtils.java | 1 - .../metadata/MetadataContextHolderTest.java | 4 +- .../metadata/StaticMetadataManagerTest.java | 1 - .../config/MetadataAutoConfigurationTest.java | 4 +- .../config/MetadataLocalPropertiesTest.java | 4 +- .../cloud/common/util/AddressUtilsTest.java | 5 +- .../common/util/ExpressionLabelUtilsTest.java | 7 +- .../common/util/ResourceFileUtilsTest.java | 5 +- .../service/caller/MetadataCallerService.java | 2 - .../caller/DiscoveryCallerService.java | 2 - .../src/main/resources/bootstrap.yml | 2 +- .../example/RouterCallerApplication.java | 2 - .../front/GrayReleaseFrontApplication.java | 2 - .../GrayReleaseGatewayApplication.java | 2 - .../middle/GrayReleaseMiddleApplication.java | 2 - .../cloud/polaris/context/ModifyAddress.java | 1 - .../context/PolarisConfigModifier.java | 1 - .../context/PostInitPolarisSDKContext.java | 3 +- .../polaris/context/ServiceRuleManager.java | 2 +- .../PolarisContextPostConfiguration.java | 6 +- .../PolarisContextAutoConfigurationTest.java | 3 +- .../context/PolarisContextGetHostTest.java | 1 - .../loadbalancer/LoadBalancerUtils.java | 7 +- .../loadbalancer/PolarisLoadBalancer.java | 1 - .../loadbalancer/PolarisWeightedRule.java | 2 +- .../config/PolarisLoadBalancerProperties.java | 1 - .../PolarisRibbonClientConfiguration.java | 1 - ...arisLoadBalancerAutoConfigurationTest.java | 1 - src/checkstyle/checkstyle-suppressions.xml | 1 - 180 files changed, 465 insertions(+), 654 deletions(-) create mode 100644 changes/changes-1.5.3.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 435c85f8a..e0f181d38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,8 +32,7 @@ - [fix: shutdown thread pool before the container closes](https://github.com/Tencent/spring-cloud-tencent/pull/353) - [docs:update logo in README.](https://github.com/Tencent/spring-cloud-tencent/pull/358) - [Refator JacksonUtils and JacksonUtilsTest](https://github.com/Tencent/spring-cloud-tencent/pull/365) +- [refactor:optimize project and code.](https://github.com/Tencent/spring-cloud-tencent/pull/368) - [docs: Fix javadoc
error](https://github.com/Tencent/spring-cloud-tencent/pull/371) - [UT: add Polaris LoadBalancer unit test](https://github.com/Tencent/spring-cloud-tencent/pull/373) - [docs:update docs](https://github.com/Tencent/spring-cloud-tencent/pull/378) - - diff --git a/changes/changes-1.5.3.md b/changes/changes-1.5.3.md new file mode 100644 index 000000000..59766dc54 --- /dev/null +++ b/changes/changes-1.5.3.md @@ -0,0 +1,4 @@ +# Change Log +--- + +- [fix not load application.yml bug & fix guava version conflict bug](https://github.com/Tencent/spring-cloud-tencent/pull/284) diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java index 9f7514ae6..ecc342288 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java @@ -68,12 +68,10 @@ public class MetadataTransferAutoConfiguration { @Bean public FilterRegistrationBean metadataServletFilterRegistrationBean( DecodeTransferMetadataServletFilter decodeTransferMetadataServletFilter) { - FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>( - decodeTransferMetadataServletFilter); - filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, - REQUEST); - filterRegistrationBean - .setOrder(MetadataConstant.OrderConstant.WEB_FILTER_ORDER); + FilterRegistrationBean filterRegistrationBean = + new FilterRegistrationBean<>(decodeTransferMetadataServletFilter); + filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST); + filterRegistrationBean.setOrder(MetadataConstant.OrderConstant.WEB_FILTER_ORDER); return filterRegistrationBean; } @@ -158,15 +156,13 @@ public class MetadataTransferAutoConfiguration { BeanPostProcessor encodeTransferMetadataRestTemplatePostProcessor( EncodeTransferMedataRestTemplateInterceptor encodeTransferMedataRestTemplateInterceptor) { // Coping with multiple bean injection scenarios - Map beans = this.context - .getBeansOfType(RestTemplate.class); + Map beans = this.context.getBeansOfType(RestTemplate.class); // If the restTemplate has been created when the // MetadataRestTemplatePostProcessor Bean // is initialized, then manually set the interceptor. if (!CollectionUtils.isEmpty(beans)) { for (RestTemplate restTemplate : beans.values()) { - List interceptors = restTemplate - .getInterceptors(); + List interceptors = restTemplate.getInterceptors(); // Avoid setting interceptor repeatedly. if (!interceptors.contains(encodeTransferMedataRestTemplateInterceptor)) { interceptors.add(encodeTransferMedataRestTemplateInterceptor); @@ -174,13 +170,11 @@ public class MetadataTransferAutoConfiguration { } } } - return new EncodeTransferMetadataRestTemplatePostProcessor( - encodeTransferMedataRestTemplateInterceptor); + return new EncodeTransferMetadataRestTemplatePostProcessor(encodeTransferMedataRestTemplateInterceptor); } @Override - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = applicationContext; } @@ -203,8 +197,7 @@ public class MetadataTransferAutoConfiguration { public Object postProcessAfterInitialization(Object bean, String beanName) { if (bean instanceof RestTemplate) { RestTemplate restTemplate = (RestTemplate) bean; - List interceptors = restTemplate - .getInterceptors(); + List interceptors = restTemplate.getInterceptors(); // Avoid setting interceptor repeatedly. if (!interceptors.contains(encodeTransferMedataRestTemplateInterceptor)) { interceptors.add(this.encodeTransferMedataRestTemplateInterceptor); @@ -213,9 +206,6 @@ public class MetadataTransferAutoConfiguration { } return bean; } - } - } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java index 01be55f2b..932c753b7 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/CustomTransitiveMetadataResolver.java @@ -33,12 +33,15 @@ import org.springframework.web.server.ServerWebExchange; /** * Resolve custom transitive metadata from request. + * * @author lepdou 2022-05-20 */ -public class CustomTransitiveMetadataResolver { +public final class CustomTransitiveMetadataResolver { private static final String TRANSITIVE_HEADER_PREFIX = "X-SCT-Metadata-Transitive-"; private static final int TRANSITIVE_HEADER_PREFIX_LENGTH = TRANSITIVE_HEADER_PREFIX.length(); + private CustomTransitiveMetadataResolver() { + } public static Map resolve(ServerWebExchange exchange) { Map result = new HashMap<>(); @@ -46,11 +49,9 @@ public class CustomTransitiveMetadataResolver { HttpHeaders headers = exchange.getRequest().getHeaders(); for (Map.Entry> entry : headers.entrySet()) { String key = entry.getKey(); - - if (StringUtils.isNotBlank(key) && - StringUtils.startsWithIgnoreCase(key, TRANSITIVE_HEADER_PREFIX) + if (StringUtils.isNotBlank(key) + && StringUtils.startsWithIgnoreCase(key, TRANSITIVE_HEADER_PREFIX) && !CollectionUtils.isEmpty(entry.getValue())) { - String sourceKey = StringUtils.substring(key, TRANSITIVE_HEADER_PREFIX_LENGTH); result.put(sourceKey, entry.getValue().get(0)); } @@ -66,10 +67,9 @@ public class CustomTransitiveMetadataResolver { while (headers.hasMoreElements()) { String key = headers.nextElement(); - if (StringUtils.isNotBlank(key) && - StringUtils.startsWithIgnoreCase(key, TRANSITIVE_HEADER_PREFIX) + if (StringUtils.isNotBlank(key) + && StringUtils.startsWithIgnoreCase(key, TRANSITIVE_HEADER_PREFIX) && StringUtils.isNotBlank(request.getHeader(key))) { - String sourceKey = StringUtils.substring(key, TRANSITIVE_HEADER_PREFIX_LENGTH); result.put(sourceKey, request.getHeader(key)); } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java index 3a258560e..5894d2ed7 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java @@ -47,8 +47,7 @@ import org.springframework.web.server.WebFilterChain; */ public class DecodeTransferMetadataReactiveFilter implements WebFilter, Ordered { - private static final Logger LOG = LoggerFactory - .getLogger(DecodeTransferMetadataReactiveFilter.class); + private static final Logger LOG = LoggerFactory.getLogger(DecodeTransferMetadataReactiveFilter.class); @Override public int getOrder() { diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java index 10aa7b60f..2236463be 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java @@ -49,8 +49,7 @@ import org.springframework.web.filter.OncePerRequestFilter; @Order(MetadataConstant.OrderConstant.WEB_FILTER_ORDER) public class DecodeTransferMetadataServletFilter extends OncePerRequestFilter { - private static final Logger LOG = LoggerFactory - .getLogger(DecodeTransferMetadataServletFilter.class); + private static final Logger LOG = LoggerFactory.getLogger(DecodeTransferMetadataServletFilter.class); @Override protected void doFilterInternal(HttpServletRequest httpServletRequest, @@ -75,8 +74,7 @@ public class DecodeTransferMetadataServletFilter extends OncePerRequestFilter { private Map getInternalTransitiveMetadata(HttpServletRequest httpServletRequest) { // Get custom metadata string from http header. - String customMetadataStr = httpServletRequest - .getHeader(MetadataConstant.HeaderName.CUSTOM_METADATA); + String customMetadataStr = httpServletRequest.getHeader(MetadataConstant.HeaderName.CUSTOM_METADATA); try { if (StringUtils.hasText(customMetadataStr)) { customMetadataStr = URLDecoder.decode(customMetadataStr, StandardCharsets.UTF_8.name()); @@ -90,5 +88,4 @@ public class DecodeTransferMetadataServletFilter extends OncePerRequestFilter { // create custom metadata. return JacksonUtils.deserialize2Map(customMetadataStr); } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java index cf889d754..b361ee81b 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java @@ -45,8 +45,7 @@ import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUST */ public class EncodeTransferMedataFeignInterceptor implements RequestInterceptor, Ordered { - private static final Logger LOG = LoggerFactory - .getLogger(EncodeTransferMedataFeignInterceptor.class); + private static final Logger LOG = LoggerFactory.getLogger(EncodeTransferMedataFeignInterceptor.class); @Override public int getOrder() { diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java index 9f3a7940f..92a9c8ec8 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java @@ -42,8 +42,7 @@ import org.springframework.util.CollectionUtils; * * @author Haotian Zhang */ -public class EncodeTransferMedataRestTemplateInterceptor - implements ClientHttpRequestInterceptor, Ordered { +public class EncodeTransferMedataRestTemplateInterceptor implements ClientHttpRequestInterceptor, Ordered { @Override public int getOrder() { @@ -71,5 +70,4 @@ public class EncodeTransferMedataRestTemplateInterceptor return clientHttpRequestExecution.execute(httpRequest, bytes); } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java index cc3aa2aa1..81745459b 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java @@ -45,8 +45,7 @@ import static org.springframework.cloud.gateway.filter.LoadBalancerClientFilter. */ public class EncodeTransferMedataScgFilter implements GlobalFilter, Ordered { - private static final int METADATA_SCG_FILTER_ORDER = LOAD_BALANCER_CLIENT_FILTER_ORDER - + 1; + private static final int METADATA_SCG_FILTER_ORDER = LOAD_BALANCER_CLIENT_FILTER_ORDER + 1; @Override public int getOrder() { @@ -59,8 +58,7 @@ public class EncodeTransferMedataScgFilter implements GlobalFilter, Ordered { ServerHttpRequest.Builder builder = exchange.getRequest().mutate(); // get metadata of current thread - MetadataContext metadataContext = exchange - .getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT); + MetadataContext metadataContext = exchange.getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT); // add new metadata and cover old if (metadataContext == null) { @@ -80,5 +78,4 @@ public class EncodeTransferMedataScgFilter implements GlobalFilter, Ordered { return chain.filter(exchange.mutate().request(builder.build()).build()); } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilter.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilter.java index bb34a96f6..9d18f3e6d 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilter.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilter.java @@ -70,13 +70,11 @@ public class EncodeTransferMetadataZuulFilter extends ZuulFilter { if (!CollectionUtils.isEmpty(customMetadata)) { String metadataStr = JacksonUtils.serialize2Json(customMetadata); try { - requestContext.addZuulRequestHeader( - MetadataConstant.HeaderName.CUSTOM_METADATA, + requestContext.addZuulRequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA, URLEncoder.encode(metadataStr, StandardCharsets.UTF_8.name())); } catch (UnsupportedEncodingException e) { - requestContext.addZuulRequestHeader( - MetadataConstant.HeaderName.CUSTOM_METADATA, metadataStr); + requestContext.addZuulRequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA, metadataStr); } } return null; diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java index 87968b8b3..1e5579f90 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java @@ -55,7 +55,9 @@ public class MetadataTransferAutoConfigurationTest { Assertions.assertThat(context).hasSingleBean( EncodeTransferMedataRestTemplateInterceptor.class); Assertions.assertThat(context).hasSingleBean( - MetadataTransferAutoConfiguration.MetadataTransferRestTemplateConfig.EncodeTransferMetadataRestTemplatePostProcessor.class); + MetadataTransferAutoConfiguration + .MetadataTransferRestTemplateConfig + .EncodeTransferMetadataRestTemplatePostProcessor.class); Assertions.assertThat(context).hasSingleBean( MetadataTransferAutoConfiguration.MetadataTransferZuulFilterConfig.class); Assertions.assertThat(context) @@ -65,5 +67,4 @@ public class MetadataTransferAutoConfigurationTest { Assertions.assertThat(context).hasSingleBean(GlobalFilter.class); }); } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilterTest.java index 8edd3400c..bbe001415 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilterTest.java @@ -80,5 +80,4 @@ public class DecodeTransferMetadataReactiveFilterTest { .isEqualTo("2"); Assertions.assertThat(metadataLocalProperties.getContent().get("c")).isNull(); } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilterTest.java index fca418b59..9e5389ef5 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilterTest.java @@ -68,10 +68,8 @@ public class DecodeTransferMetadataServletFilterTest { request.addHeader(MetadataConstant.HeaderName.CUSTOM_METADATA, "{\"c\": \"3\"}"); MockHttpServletResponse response = new MockHttpServletResponse(); metadataServletFilter.doFilter(request, response, filterChain); - Assertions.assertThat(metadataLocalProperties.getContent().get("a")) - .isEqualTo("1"); - Assertions.assertThat(metadataLocalProperties.getContent().get("b")) - .isEqualTo("2"); + Assertions.assertThat(metadataLocalProperties.getContent().get("a")).isEqualTo("1"); + Assertions.assertThat(metadataLocalProperties.getContent().get("b")).isEqualTo("2"); Assertions.assertThat(metadataLocalProperties.getContent().get("c")).isNull(); } @@ -79,5 +77,4 @@ public class DecodeTransferMetadataServletFilterTest { protected static class TestApplication { } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptorTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptorTest.java index c42629e0c..eef57ee00 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptorTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptorTest.java @@ -36,7 +36,6 @@ import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -66,10 +65,8 @@ public class EncodeTransferMedataFeignInterceptorTest { public void testTransitiveMetadataFromApplicationConfig() { String metadata = testFeign.test(); Assertions.assertThat(metadata).isEqualTo("2"); - Assertions.assertThat(metadataLocalProperties.getContent().get("a")) - .isEqualTo("1"); - Assertions.assertThat(metadataLocalProperties.getContent().get("b")) - .isEqualTo("2"); + Assertions.assertThat(metadataLocalProperties.getContent().get("a")).isEqualTo("1"); + Assertions.assertThat(metadataLocalProperties.getContent().get("b")).isEqualTo("2"); } @SpringBootApplication @@ -78,9 +75,7 @@ public class EncodeTransferMedataFeignInterceptorTest { protected static class TestApplication { @RequestMapping("/test") - public String test( - @RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String customMetadataStr) - throws UnsupportedEncodingException { + public String test() throws UnsupportedEncodingException { return MetadataContextHolder.get().getContext(MetadataContext.FRAGMENT_TRANSITIVE, "b"); } @@ -89,7 +84,6 @@ public class EncodeTransferMedataFeignInterceptorTest { @RequestMapping("/test") String test(); - } @Configuration @@ -100,9 +94,6 @@ public class EncodeTransferMedataFeignInterceptorTest { template.header(MetadataConstant.HeaderName.CUSTOM_METADATA, "{\"a\":\"11\",\"b\":\"22\",\"c\":\"33\"}"); } - } - } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptorTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptorTest.java index b61c42ed2..e5fe24c9c 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptorTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptorTest.java @@ -19,7 +19,6 @@ 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 org.assertj.core.api.Assertions; @@ -35,7 +34,6 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @@ -50,7 +48,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT, classes = EncodeTransferMedataRestTemplateInterceptorTest.TestApplication.class, - properties = { "spring.config.location = classpath:application-test.yml", "spring.main.web-application-type = reactive" }) + properties = {"spring.config.location = classpath:application-test.yml", + "spring.main.web-application-type = reactive"}) public class EncodeTransferMedataRestTemplateInterceptorTest { @Autowired @@ -64,8 +63,7 @@ public class EncodeTransferMedataRestTemplateInterceptorTest { HttpHeaders httpHeaders = new HttpHeaders(); HttpEntity httpEntity = new HttpEntity<>(httpHeaders); String metadata = restTemplate - .exchange("http://localhost:" + localServerPort + "/test", HttpMethod.GET, - httpEntity, String.class) + .exchange("http://localhost:" + localServerPort + "/test", HttpMethod.GET, httpEntity, String.class) .getBody(); Assertions.assertThat(metadata).isEqualTo("2"); } @@ -80,12 +78,8 @@ public class EncodeTransferMedataRestTemplateInterceptorTest { } @RequestMapping("/test") - public String test( - @RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String customMetadataStr) - throws UnsupportedEncodingException { + public String test() throws UnsupportedEncodingException { return MetadataContextHolder.get().getContext(MetadataContext.FRAGMENT_TRANSITIVE, "b"); } - } - } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java index f6cc2fdcd..51a6bd6be 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java @@ -48,7 +48,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @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"}) + properties = {"spring.config.location = classpath:application-test.yml", + "spring.main.web-application-type = reactive"}) public class EncodeTransferMedataScgFilterTest { @Autowired diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilterTest.java index adc3e1f7e..5b36c2693 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMetadataZuulFilterTest.java @@ -48,15 +48,14 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT, classes = EncodeTransferMetadataZuulFilterTest.TestApplication.class, - properties = {"spring.config.location = classpath:application-test.yml", "spring.main.web-application-type = reactive"}) - + properties = {"spring.config.location = classpath:application-test.yml", + "spring.main.web-application-type = reactive"}) public class EncodeTransferMetadataZuulFilterTest { + private final MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(); @Autowired private ApplicationContext applicationContext; - private final MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(); - @Before public void init() { RequestContext ctx = RequestContext.getCurrentContext(); diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java index 393c0ea7d..6fdc71e61 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java @@ -66,7 +66,5 @@ public class PolarisCircuitBreakerBootstrapConfiguration { public int getOrder() { return ContextConstant.ModifierOrder.CIRCUIT_BREAKER_ORDER; } - } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisFeignClientAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisFeignClientAutoConfiguration.java index a1f50a3df..baad28432 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisFeignClientAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisFeignClientAutoConfiguration.java @@ -40,7 +40,8 @@ import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; * * @author Haotian Zhang */ -@ConditionalOnProperty(value = "spring.cloud.polaris.circuitbreaker.enabled", havingValue = "true", matchIfMissing = true) +@ConditionalOnProperty(value = "spring.cloud.polaris.circuitbreaker.enabled", + havingValue = "true", matchIfMissing = true) @Configuration(proxyBeanMethods = false) @ConditionalOnClass(name = "org.springframework.cloud.openfeign.FeignAutoConfiguration") @AutoConfigureAfter(PolarisContextAutoConfiguration.class) @@ -57,5 +58,4 @@ public class PolarisFeignClientAutoConfiguration { public PolarisFeignBeanPostProcessor polarisFeignBeanPostProcessor(ConsumerAPI consumerAPI) { return new PolarisFeignBeanPostProcessor(consumerAPI); } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisRestTemplateAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisRestTemplateAutoConfiguration.java index a81f1344b..207f1651d 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisRestTemplateAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisRestTemplateAutoConfiguration.java @@ -55,5 +55,4 @@ public class PolarisRestTemplateAutoConfiguration { PolarisRestTemplateResponseErrorHandler restTemplateResponseErrorHandler) { return new PolarisRestTemplateModifier(restTemplateResponseErrorHandler); } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java index 619815795..ea8242587 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java @@ -55,7 +55,8 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac if (bean instanceof LoadBalancerFeignClient) { LoadBalancerFeignClient client = ((LoadBalancerFeignClient) bean); return new PolarisLoadBalancerFeignClient( - createPolarisFeignClient(client.getDelegate()), factory(), + createPolarisFeignClient(client.getDelegate()), + factory(), clientFactory()); } if (bean instanceof FeignBlockingLoadBalancerClient) { @@ -91,5 +92,4 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac SpringClientFactory clientFactory() { return this.factory.getBean(SpringClientFactory.class); } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java index 4cf8780c1..feea51242 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java @@ -32,5 +32,4 @@ public class PolarisFeignBlockingLoadBalancerClient extends FeignBlockingLoadBal public PolarisFeignBlockingLoadBalancerClient(Client delegate, BlockingLoadBalancerClient loadBalancerClient) { super(delegate, loadBalancerClient); } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java index dc49566f2..0c8551404 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java @@ -43,7 +43,6 @@ import static feign.Util.checkNotNull; */ public class PolarisFeignClient implements Client { - private static final Logger LOG = LoggerFactory.getLogger(PolarisFeignClient.class); private final Client delegate; @@ -61,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=[{}].", diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java index 41e4a608f..f8518470d 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java @@ -30,10 +30,8 @@ import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient; */ public class PolarisLoadBalancerFeignClient extends LoadBalancerFeignClient { - public PolarisLoadBalancerFeignClient(Client delegate, - CachingSpringLoadBalancerFactory lbClientFactory, + public PolarisLoadBalancerFeignClient(Client delegate, CachingSpringLoadBalancerFactory lbClientFactory, SpringClientFactory clientFactory) { super(delegate, lbClientFactory, clientFactory); } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java index aa6eb3cbc..6fd56e582 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateModifier.java @@ -29,15 +29,15 @@ 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} . + * then replace {@link org.springframework.web.client.ResponseErrorHandler} + * with {@link PolarisRestTemplateResponseErrorHandler} . * * @author wh 2022/6/21 */ public class PolarisRestTemplateModifier implements ApplicationContextAware, SmartInitializingSingleton { - private ApplicationContext applicationContext; - private final PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler; + private ApplicationContext applicationContext; public PolarisRestTemplateModifier(PolarisRestTemplateResponseErrorHandler polarisRestTemplateResponseErrorHandler) { this.polarisRestTemplateResponseErrorHandler = polarisRestTemplateResponseErrorHandler; diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java index 8a7dc16ab..4adf0bac2 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisRestTemplateResponseErrorHandler.java @@ -54,7 +54,8 @@ public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHan private final PolarisResponseErrorHandler polarisResponseErrorHandler; - public PolarisRestTemplateResponseErrorHandler(ConsumerAPI consumerAPI, PolarisResponseErrorHandler polarisResponseErrorHandler) { + public PolarisRestTemplateResponseErrorHandler(ConsumerAPI consumerAPI, + PolarisResponseErrorHandler polarisResponseErrorHandler) { this.consumerAPI = consumerAPI; this.polarisResponseErrorHandler = polarisResponseErrorHandler; } @@ -74,7 +75,8 @@ public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHan } @Override - public void handleError(@NonNull URI url, @NonNull HttpMethod method, @NonNull ClientHttpResponse response) throws IOException { + 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); @@ -111,5 +113,4 @@ public class PolarisRestTemplateResponseErrorHandler implements ResponseErrorHan } return resultRequest; } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java index a5bd4f2e6..e29c4a76f 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java @@ -32,14 +32,14 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisCircuitBreakerBootstrapConfigurationTest { private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisCircuitBreakerBootstrapConfiguration.class)) + .withConfiguration(AutoConfigurations.of(PolarisCircuitBreakerBootstrapConfiguration.class)) .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true"); @Test public void testDefaultInitialization() { this.contextRunner.run(context -> { - assertThat(context).hasSingleBean(PolarisCircuitBreakerBootstrapConfiguration.CircuitBreakerConfigModifier.class); + assertThat(context).hasSingleBean( + PolarisCircuitBreakerBootstrapConfiguration.CircuitBreakerConfigModifier.class); }); } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfigurationTest.java index 682b99522..94a84ed43 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfigurationTest.java @@ -36,10 +36,9 @@ import static org.assertj.core.api.Assertions.assertThat; public class PolarisFeignClientAutoConfigurationTest { private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - PolarisContextAutoConfiguration.class, - PolarisFeignClientAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisFeignClientAutoConfiguration.class)) .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true"); @Test @@ -49,5 +48,4 @@ public class PolarisFeignClientAutoConfigurationTest { assertThat(context).hasSingleBean(PolarisFeignBeanPostProcessor.class); }); } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java index a3dc9999c..2707bc87f 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisRestTemplateAutoConfigurationTest.java @@ -42,11 +42,10 @@ import static org.assertj.core.api.Assertions.assertThat; public class PolarisRestTemplateAutoConfigurationTest { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - PolarisRestTemplateAutoConfigurationTester.class, - PolarisContextAutoConfiguration.class, - PolarisRestTemplateAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of( + PolarisRestTemplateAutoConfigurationTester.class, + PolarisContextAutoConfiguration.class, + PolarisRestTemplateAutoConfiguration.class)) .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true"); @Test @@ -68,5 +67,4 @@ public class PolarisRestTemplateAutoConfigurationTest { return new RestTemplate(); } } - } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java index 993eedc58..8d21f6a1e 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java @@ -73,7 +73,8 @@ public class PolarisFeignClientTest { } try { - assertThat(new PolarisFeignClient(mock(Client.class), mock(ConsumerAPI.class))).isInstanceOf(PolarisFeignClient.class); + assertThat(new PolarisFeignClient(mock(Client.class), mock(ConsumerAPI.class))) + .isInstanceOf(PolarisFeignClient.class); } catch (Throwable e) { fail("Exception encountered.", e); @@ -90,7 +91,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 +114,10 @@ public class PolarisFeignClientTest { Maps.newHashMap(), null, requestTemplate), null); assertThat(response.status()).isEqualTo(200); - // 200 + // 502 response = polarisFeignClient.execute(Request.create(Request.HttpMethod.POST, "http://localhost:8080/test", Maps.newHashMap(), null, requestTemplate), null); - assertThat(response.status()).isEqualTo(500); + assertThat(response.status()).isEqualTo(502); // Exception try { diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java index 871f39caa..d8ac018cf 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/SimpleClientHttpResponseTest.java @@ -102,5 +102,4 @@ public class SimpleClientHttpResponseTest extends AbstractClientHttpResponse { // ignore } } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/ConfigurationModifier.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/ConfigurationModifier.java index 9953b3c67..e6994edb2 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/ConfigurationModifier.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/ConfigurationModifier.java @@ -31,7 +31,6 @@ import org.apache.commons.lang.StringUtils; import org.springframework.util.CollectionUtils; - /** * Read configuration from spring cloud's configuration file and override polaris.yaml. * diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java index cccea11bc..173b9795c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java @@ -59,5 +59,4 @@ public class PolarisConfigAutoConfiguration { public PolarisConfigChangeEventListener polarisConfigChangeEventListener() { return new PolarisConfigChangeEventListener(); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java index e16f1480c..a67c8a89d 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java @@ -40,8 +40,7 @@ import org.springframework.core.env.Environment; */ @Configuration(proxyBeanMethods = false) @ConditionalOnPolarisEnabled -@ConditionalOnProperty(value = "spring.cloud.polaris.config.enabled", - matchIfMissing = true) +@ConditionalOnProperty(value = "spring.cloud.polaris.config.enabled", matchIfMissing = true) @Import(PolarisContextAutoConfiguration.class) public class PolarisConfigBootstrapAutoConfiguration { @@ -80,5 +79,4 @@ public class PolarisConfigBootstrapAutoConfiguration { PolarisContextProperties polarisContextProperties) { return new ConfigurationModifier(polarisConfigProperties, polarisContextProperties); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java index b3b92ce30..091f09beb 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java @@ -52,8 +52,7 @@ import org.springframework.util.StringUtils; @Order(0) public class PolarisConfigFileLocator implements PropertySourceLocator { - private static final Logger LOGGER = LoggerFactory - .getLogger(PolarisConfigFileLocator.class); + private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfigFileLocator.class); private static final String POLARIS_CONFIG_PROPERTY_SOURCE_NAME = "polaris-config"; @@ -115,7 +114,7 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { private List getInternalConfigFiles() { String namespace = polarisContextProperties.getNamespace(); String serviceName = polarisContextProperties.getService(); - if (StringUtils.isEmpty(serviceName)) { + if (!StringUtils.hasText(serviceName)) { serviceName = environment.getProperty("spring.application.name"); } @@ -125,7 +124,7 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { String[] activeProfiles = environment.getActiveProfiles(); for (String activeProfile : activeProfiles) { - if (StringUtils.isEmpty(activeProfile)) { + if (!StringUtils.hasText(activeProfile)) { continue; } @@ -137,7 +136,7 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application.yml")); for (String activeProfile : activeProfiles) { - if (StringUtils.isEmpty(activeProfile)) { + if (!StringUtils.hasText(activeProfile)) { continue; } @@ -160,9 +159,8 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { for (ConfigFileGroup configFileGroup : configFileGroups) { String group = configFileGroup.getName(); - if (StringUtils.isEmpty(group)) { - throw new IllegalArgumentException( - "polaris config group name cannot be empty."); + if (!StringUtils.hasText(group)) { + throw new IllegalArgumentException("polaris config group name cannot be empty."); } List files = configFileGroup.getFiles(); @@ -171,16 +169,14 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { } for (String fileName : files) { - PolarisPropertySource polarisPropertySource = loadPolarisPropertySource( - namespace, group, fileName); + PolarisPropertySource polarisPropertySource = loadPolarisPropertySource(namespace, group, fileName); compositePropertySource.addPropertySource(polarisPropertySource); polarisPropertySourceManager.addPropertySource(polarisPropertySource); - LOGGER.info( - "[SCT Config] Load and inject polaris config file success. namespace = {}, group = {}, fileName = {}", - namespace, group, fileName); + LOGGER.info("[SCT Config] Load and inject polaris config file success." + + " namespace = {}, group = {}, fileName = {}", namespace, group, fileName); } } } @@ -189,21 +185,18 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { String group, String fileName) { ConfigKVFile configKVFile; // unknown extension is resolved as properties file - if (ConfigFileFormat.isPropertyFile(fileName) - || ConfigFileFormat.isUnknownFile(fileName)) { + if (ConfigFileFormat.isPropertyFile(fileName) || ConfigFileFormat.isUnknownFile(fileName)) { configKVFile = configFileService.getConfigPropertiesFile(namespace, group, fileName); } else if (ConfigFileFormat.isYamlFile(fileName)) { configKVFile = configFileService.getConfigYamlFile(namespace, group, fileName); } else { - LOGGER.warn( - "[SCT Config] Unsupported config file. namespace = {}, group = {}, fileName = {}", + LOGGER.warn("[SCT Config] Unsupported config file. namespace = {}, group = {}, fileName = {}", namespace, group, fileName); - throw new IllegalStateException( - "Only configuration files in the format of properties / yaml / yaml" - + " can be injected into the spring context"); + throw new IllegalStateException("Only configuration files in the format of properties / yaml / yaml" + + " can be injected into the spring context"); } Map map = new ConcurrentHashMap<>(); @@ -213,5 +206,4 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { return new PolarisPropertySource(namespace, group, fileName, configKVFile, map); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySource.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySource.java index 76b234e72..7a47fd187 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySource.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySource.java @@ -74,5 +74,4 @@ public class PolarisPropertySource extends MapPropertySource { return "PolarisPropertySource{" + "namespace='" + namespace + '\'' + ", group='" + group + '\'' + ", fileName='" + fileName + '\'' + '}'; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceAutoRefresher.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceAutoRefresher.java index fac3ba255..25af8ff32 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceAutoRefresher.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceAutoRefresher.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; -import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeEvent; import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeListener; import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo; import org.slf4j.Logger; @@ -46,18 +45,14 @@ import org.springframework.util.CollectionUtils; public class PolarisPropertySourceAutoRefresher implements ApplicationListener, ApplicationContextAware { - private static final Logger LOGGER = LoggerFactory - .getLogger(PolarisPropertySourceAutoRefresher.class); + 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); + private ApplicationContext applicationContext; public PolarisPropertySourceAutoRefresher( PolarisConfigProperties polarisConfigProperties, @@ -69,8 +64,7 @@ public class PolarisPropertySourceAutoRefresher } @Override - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @@ -84,8 +78,7 @@ public class PolarisPropertySourceAutoRefresher return; } - List polarisPropertySources = polarisPropertySourceManager - .getAllPropertySources(); + List polarisPropertySources = polarisPropertySourceManager.getAllPropertySources(); if (CollectionUtils.isEmpty(polarisPropertySources)) { return; } @@ -97,45 +90,36 @@ public class PolarisPropertySourceAutoRefresher // register polaris config publish event for (PolarisPropertySource polarisPropertySource : polarisPropertySources) { polarisPropertySource.getConfigKVFile() - .addChangeListener(new ConfigKVFileChangeListener() { - @Override - public void onChange( - ConfigKVFileChangeEvent configKVFileChangeEvent) { - LOGGER.info( - "[SCT Config] received polaris config change event and will refresh spring context." - + "namespace = {}, group = {}, fileName = {}", - polarisPropertySource.getNamespace(), - polarisPropertySource.getGroup(), - polarisPropertySource.getFileName()); - - Map source = polarisPropertySource - .getSource(); - - for (String changedKey : configKVFileChangeEvent - .changedKeys()) { - ConfigPropertyChangeInfo configPropertyChangeInfo = configKVFileChangeEvent - .getChangeInfo(changedKey); - - LOGGER.info("[SCT Config] changed property = {}", - configPropertyChangeInfo); - - switch (configPropertyChangeInfo.getChangeType()) { - case MODIFIED: - case ADDED: - source.put(changedKey, - configPropertyChangeInfo.getNewValue()); - break; - case DELETED: - source.remove(changedKey); - break; - } + .addChangeListener((ConfigKVFileChangeListener) configKVFileChangeEvent -> { + LOGGER.info( + "[SCT Config] received polaris config change event and will refresh spring context." + + "namespace = {}, group = {}, fileName = {}", + polarisPropertySource.getNamespace(), + polarisPropertySource.getGroup(), + polarisPropertySource.getFileName()); + + Map source = polarisPropertySource.getSource(); + + for (String changedKey : configKVFileChangeEvent.changedKeys()) { + ConfigPropertyChangeInfo configPropertyChangeInfo = configKVFileChangeEvent + .getChangeInfo(changedKey); + + LOGGER.info("[SCT Config] changed property = {}", configPropertyChangeInfo); + + switch (configPropertyChangeInfo.getChangeType()) { + case MODIFIED: + case ADDED: + source.put(changedKey, configPropertyChangeInfo.getNewValue()); + break; + case DELETED: + source.remove(changedKey); + break; } - - // rebuild beans with @RefreshScope annotation - contextRefresher.refresh(); } + + // rebuild beans with @RefreshScope annotation + contextRefresher.refresh(); }); } } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceManager.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceManager.java index 6fff49069..f8736e20e 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceManager.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertySourceManager.java @@ -33,12 +33,10 @@ public class PolarisPropertySourceManager { private final Map polarisPropertySources = new ConcurrentHashMap<>(); public void addPropertySource(PolarisPropertySource polarisPropertySource) { - polarisPropertySources.putIfAbsent(polarisPropertySource.getPropertySourceName(), - polarisPropertySource); + polarisPropertySources.putIfAbsent(polarisPropertySource.getPropertySourceName(), polarisPropertySource); } public List getAllPropertySources() { return new ArrayList<>(polarisPropertySources.values()); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigAnnotationProcessor.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigAnnotationProcessor.java index 349799f69..59bbb994c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigAnnotationProcessor.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigAnnotationProcessor.java @@ -96,10 +96,8 @@ public class PolarisConfigAnnotationProcessor implements BeanPostProcessor, Prio Set interestedKeys = annotatedInterestedKeys.length > 0 ? Sets.newHashSet(annotatedInterestedKeys) : null; Set interestedKeyPrefixes = - annotatedInterestedKeyPrefixes.length > 0 ? Sets.newHashSet(annotatedInterestedKeyPrefixes) - : null; + annotatedInterestedKeyPrefixes.length > 0 ? Sets.newHashSet(annotatedInterestedKeyPrefixes) : null; addChangeListener(configChangeListener, interestedKeys, interestedKeyPrefixes); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java index 142b41bed..a324c4d78 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/annotation/PolarisConfigKVFileChangeListener.java @@ -54,5 +54,4 @@ public @interface PolarisConfigKVFileChangeListener { * @return interested key-prefixed in the listener */ String[] interestedKeyPrefixes() default {}; - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/ConfigFileGroup.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/ConfigFileGroup.java index 05f1d7c5d..b52ffd13e 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/ConfigFileGroup.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/ConfigFileGroup.java @@ -56,5 +56,4 @@ public class ConfigFileGroup { public String toString() { return "ConfigFileGroup{" + "name='" + name + '\'' + ", file=" + files + '}'; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java index a2c9032fe..f39c5337f 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java @@ -94,5 +94,4 @@ public class PolarisConfigProperties { public void setGroups(List groups) { this.groups = groups; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/enums/ConfigFileFormat.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/enums/ConfigFileFormat.java index 024ad67d0..d7c7b590c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/enums/ConfigFileFormat.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/enums/ConfigFileFormat.java @@ -80,5 +80,4 @@ public enum ConfigFileFormat { } return true; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeEvent.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeEvent.java index 119a5ce4c..367740d8c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeEvent.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeEvent.java @@ -84,5 +84,4 @@ public final class ConfigChangeEvent { public Set interestedChangedKeys() { return interestedChangedKeys; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListener.java index 14ab64a32..1ff9d139c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListener.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListener.java @@ -31,5 +31,4 @@ public interface ConfigChangeListener { * @param changeEvent the event for this change */ void onChange(ConfigChangeEvent changeEvent); - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigChangeEventListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigChangeEventListener.java index 0a55255d5..378f69628 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigChangeEventListener.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigChangeEventListener.java @@ -107,5 +107,4 @@ public final class PolarisConfigChangeEventListener implements ApplicationListen }); return ret; } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigListenerContext.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigListenerContext.java index 05ac41756..15a9a9336 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigListenerContext.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigListenerContext.java @@ -52,6 +52,7 @@ import static com.tencent.polaris.configuration.api.core.ChangeType.MODIFIED; *

Refer to the Apollo project implementation: * * AbstractConfig + * * @author Palmer Xu 2022-06-06 */ public final class PolarisConfigListenerContext { @@ -60,32 +61,30 @@ public final class PolarisConfigListenerContext { * Logger instance. */ private static final Logger LOG = LoggerFactory.getLogger(PolarisConfigListenerContext.class); - /** * Execute service Atomic Reference Cache . */ private static final AtomicReference EAR = new AtomicReference<>(); - /** * All custom {@link ConfigChangeListener} instance defined in application . */ private static final List listeners = Lists.newCopyOnWriteArrayList(); - /** * All custom interested keys defined in application . */ private static final Map> interestedKeys = Maps.newHashMap(); - /** * All custom interested key prefixes defined in application . */ private static final Map> interestedKeyPrefixes = Maps.newHashMap(); - /** * Cache all latest configuration information for users in the application environment . */ private static final Cache properties = CacheBuilder.newBuilder().build(); + private PolarisConfigListenerContext() { + } + /** * Get or Created new execute server . * @return execute service instance of {@link ExecutorService} @@ -273,5 +272,4 @@ public final class PolarisConfigListenerContext { return Collections.unmodifiableSet(interestedChangedKeys); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java index 026fe4d52..59e89ebcc 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java @@ -31,7 +31,8 @@ import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeListener; /** * Mock config kv file for test. - *@author lepdou 2022-06-11 + * + * @author lepdou 2022-06-11 */ public class MockedConfigKVFile implements ConfigKVFile { diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java index 8c072ef9d..bfe1fc5d2 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java @@ -41,12 +41,15 @@ import org.springframework.core.env.PropertySource; import static org.mockito.Mockito.when; /** - * test for {@link PolarisConfigFileLocator} - *@author lepdou 2022-06-11 + * test for {@link PolarisConfigFileLocator}. + * + * @author lepdou 2022-06-11 */ @RunWith(MockitoJUnitRunner.class) public class PolarisConfigFileLocatorTest { + private final String testNamespace = "testNamespace"; + private final String testServiceName = "testServiceName"; @Mock private PolarisConfigProperties polarisConfigProperties; @Mock @@ -58,9 +61,6 @@ public class PolarisConfigFileLocatorTest { @Mock private Environment environment; - private final String testNamespace = "testNamespace"; - private final String testServiceName = "testServiceName"; - @Test public void testLoadApplicationPropertiesFile() { PolarisConfigFileLocator locator = new PolarisConfigFileLocator(polarisConfigProperties, polarisContextProperties, diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java index 648860f35..779ddfb47 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java @@ -38,12 +38,16 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** - * test for {@link PolarisPropertySourceAutoRefresher} - *@author lepdou 2022-06-11 + * test for {@link PolarisPropertySourceAutoRefresher}. + * + * @author lepdou 2022-06-11 */ @RunWith(MockitoJUnitRunner.class) public class PolarisPropertiesSourceAutoRefresherTest { + private final String testNamespace = "testNamespace"; + private final String testServiceName = "testServiceName"; + private final String testFileName = "application.properties"; @Mock private PolarisConfigProperties polarisConfigProperties; @Mock @@ -51,10 +55,6 @@ public class PolarisPropertiesSourceAutoRefresherTest { @Mock private ContextRefresher contextRefresher; - private final String testNamespace = "testNamespace"; - private final String testServiceName = "testServiceName"; - private final String testFileName = "application.properties"; - @Test public void testConfigFileChanged() { PolarisPropertySourceAutoRefresher refresher = new PolarisPropertySourceAutoRefresher(polarisConfigProperties, @@ -118,5 +118,4 @@ public class PolarisPropertiesSourceAutoRefresherTest { Assert.assertEquals("v1", polarisPropertySource.getProperty("k1")); verify(contextRefresher).refresh(); } - } diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListenerTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListenerTest.java index c408f4f54..58e39c89f 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListenerTest.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/ConfigChangeListenerTest.java @@ -39,13 +39,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 @@ -120,5 +120,4 @@ public class ConfigChangeListenerTest { } } } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java index 67690ef24..0512de81e 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java @@ -27,9 +27,9 @@ import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig; import org.springframework.beans.factory.annotation.Autowired; /** - * Spring Cloud Tencent config Override polaris config. + * Spring Cloud Tencent config Override polaris config. * - *@author lepdou 2022-04-24 + * @author lepdou 2022-04-24 */ public class DiscoveryConfigModifier implements PolarisConfigModifier { diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java index d0129afc0..341b08192 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java @@ -56,15 +56,13 @@ public class DiscoveryPropertiesAutoConfiguration { @Bean @ConditionalOnMissingBean - public ProviderAPI polarisProvider(SDKContext polarisContext) - throws PolarisException { + public ProviderAPI polarisProvider(SDKContext polarisContext) throws PolarisException { return DiscoveryAPIFactory.createProviderAPIByContext(polarisContext); } @Bean @ConditionalOnMissingBean - public ConsumerAPI polarisConsumer(SDKContext polarisContext) - throws PolarisException { + public ConsumerAPI polarisConsumer(SDKContext polarisContext) throws PolarisException { return DiscoveryAPIFactory.createConsumerAPIByContext(polarisContext); } @@ -98,5 +96,4 @@ public class DiscoveryPropertiesAutoConfiguration { public boolean isDiscoveryEnabled() { return discoveryEnabled; } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java index 2de7d0140..495cdc861 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java @@ -258,5 +258,4 @@ public class PolarisDiscoveryProperties { } } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java index 97f478683..78f95ae9a 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java @@ -28,6 +28,8 @@ 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) diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/DiscoveryEnabledCondition.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/DiscoveryEnabledCondition.java index 84041557f..1963537c2 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/DiscoveryEnabledCondition.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/DiscoveryEnabledCondition.java @@ -29,21 +29,17 @@ import org.springframework.core.type.AnnotatedTypeMetadata; public class DiscoveryEnabledCondition implements Condition { @Override - public boolean matches(ConditionContext conditionContext, - AnnotatedTypeMetadata annotatedTypeMetadata) { + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { - boolean isDiscoveryEnabled = Boolean - .parseBoolean(conditionContext.getEnvironment() - .getProperty("spring.cloud.polaris.discovery.enabled", "true")); + 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 isConsulDiscoveryEnabled = Boolean.parseBoolean( + conditionContext.getEnvironment().getProperty("spring.cloud.consul.enabled", "false")) && Boolean.parseBoolean(conditionContext.getEnvironment() - .getProperty("spring.cloud.consul.discovery.enabled", "true")); + .getProperty("spring.cloud.consul.discovery.enabled", "true")); isDiscoveryEnabled |= isConsulDiscoveryEnabled; return isDiscoveryEnabled; } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java index cc8000f44..b92ca6259 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java @@ -43,5 +43,4 @@ public class PolarisDiscoveryAutoConfiguration { PolarisDiscoveryHandler polarisDiscoveryHandler) { return new PolarisServiceDiscovery(polarisDiscoveryHandler); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java index f07469807..80cf3afdf 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java @@ -54,5 +54,4 @@ public class PolarisDiscoveryClient implements DiscoveryClient { public List getServices() { return polarisServiceDiscovery.getServices(); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java index 249685946..6b1ef7118 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java @@ -33,15 +33,12 @@ 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 { @Bean - public DiscoveryClient polarisDiscoveryClient( - PolarisServiceDiscovery polarisServiceDiscovery) { + public DiscoveryClient polarisDiscoveryClient(PolarisServiceDiscovery polarisServiceDiscovery) { return new PolarisDiscoveryClient(polarisServiceDiscovery); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java index a55443561..f96c7d3d9 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java @@ -53,6 +53,7 @@ public class PolarisDiscoveryHandler { /** * Get a list of healthy instances. + * * @param service service name * @return list of healthy instances */ @@ -66,6 +67,7 @@ public class PolarisDiscoveryHandler { /** * Return all instances for the given service. + * * @param service serviceName * @return list of instances */ @@ -87,6 +89,7 @@ public class PolarisDiscoveryHandler { /** * Return all service for given namespace. + * * @return service list */ public ServicesResponse GetServices() { @@ -95,5 +98,4 @@ public class PolarisDiscoveryHandler { request.setNamespace(namespace); return polarisConsumer.getServices(request); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java index 95387ae5c..d05117b72 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java @@ -31,6 +31,8 @@ import com.tencent.polaris.api.rpc.InstancesResponse; import org.springframework.cloud.client.ServiceInstance; /** + * Polaris service discovery service. + * * @author Haotian Zhang, Andrew Shan, Jie Cheng */ public class PolarisServiceDiscovery { @@ -49,8 +51,7 @@ public class PolarisServiceDiscovery { */ public List getInstances(String serviceId) throws PolarisException { List instances = new ArrayList<>(); - InstancesResponse filteredInstances = polarisDiscoveryHandler - .getHealthyInstances(serviceId); + InstancesResponse filteredInstances = polarisDiscoveryHandler.getHealthyInstances(serviceId); ServiceInstances serviceInstances = filteredInstances.toServiceInstances(); for (Instance instance : serviceInstances.getInstances()) { instances.add(new PolarisServiceInstance(instance)); @@ -67,5 +68,4 @@ public class PolarisServiceDiscovery { return polarisDiscoveryHandler.GetServices().getServices().stream() .map(ServiceInfo::getService).collect(Collectors.toList()); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java index 6d3588c6f..09f50f2a7 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java @@ -38,13 +38,11 @@ import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; */ public class PolarisReactiveDiscoveryClient implements ReactiveDiscoveryClient { - private static final Logger log = LoggerFactory - .getLogger(PolarisReactiveDiscoveryClient.class); + private static final Logger LOG = LoggerFactory.getLogger(PolarisReactiveDiscoveryClient.class); - private PolarisServiceDiscovery polarisServiceDiscovery; + private final PolarisServiceDiscovery polarisServiceDiscovery; - public PolarisReactiveDiscoveryClient( - PolarisServiceDiscovery polarisServiceDiscovery) { + public PolarisReactiveDiscoveryClient(PolarisServiceDiscovery polarisServiceDiscovery) { this.polarisServiceDiscovery = polarisServiceDiscovery; } @@ -55,7 +53,6 @@ public class PolarisReactiveDiscoveryClient implements ReactiveDiscoveryClient { @Override public Flux getInstances(String serviceId) { - return Mono.justOrEmpty(serviceId).flatMapMany(loadInstancesFromPolaris()) .subscribeOn(Schedulers.boundedElastic()); } @@ -66,7 +63,7 @@ public class PolarisReactiveDiscoveryClient implements ReactiveDiscoveryClient { return Flux.fromIterable(polarisServiceDiscovery.getInstances(serviceId)); } catch (PolarisException e) { - log.error("get service instance[{}] from polaris error!", serviceId, e); + LOG.error("get service instance[{}] from polaris error!", serviceId, e); return Flux.empty(); } }; @@ -79,10 +76,9 @@ public class PolarisReactiveDiscoveryClient implements ReactiveDiscoveryClient { return Flux.fromIterable(polarisServiceDiscovery.getServices()); } catch (Exception e) { - log.error("get services from polaris server fail,", e); + LOG.error("get services from polaris server fail,", e); return Flux.empty(); } }).subscribeOn(Schedulers.boundedElastic()); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java index 09928e208..2f3d8e201 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java @@ -47,5 +47,4 @@ public class PolarisReactiveDiscoveryClientConfiguration { PolarisServiceDiscovery polarisServiceDiscovery) { return new PolarisReactiveDiscoveryClient(polarisServiceDiscovery); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java index 53292e7cf..d8773ce7f 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java @@ -39,7 +39,8 @@ import static com.tencent.cloud.polaris.discovery.refresh.PolarisServiceStatusCh * * @author Haotian Zhang */ -public class PolarisRefreshApplicationReadyEventListener implements ApplicationListener, ApplicationEventPublisherAware, DisposableBean { +public class PolarisRefreshApplicationReadyEventListener + implements ApplicationListener, ApplicationEventPublisherAware, DisposableBean { private static final Logger LOG = LoggerFactory.getLogger(PolarisRefreshApplicationReadyEventListener.class); private static final int DELAY = 60; @@ -48,7 +49,8 @@ public class PolarisRefreshApplicationReadyEventListener implements ApplicationL private final ScheduledExecutorService refreshExecutor; private ApplicationEventPublisher publisher; - public PolarisRefreshApplicationReadyEventListener(PolarisDiscoveryHandler polarisDiscoveryHandler, PolarisServiceStatusChangeListener polarisServiceStatusChangeListener) { + public PolarisRefreshApplicationReadyEventListener(PolarisDiscoveryHandler polarisDiscoveryHandler, + PolarisServiceStatusChangeListener polarisServiceStatusChangeListener) { this.polarisDiscoveryHandler = polarisDiscoveryHandler; this.polarisServiceStatusChangeListener = polarisServiceStatusChangeListener; this.refreshExecutor = Executors.newSingleThreadScheduledExecutor( @@ -86,7 +88,7 @@ public class PolarisRefreshApplicationReadyEventListener implements ApplicationL } @Override - public void destroy() throws Exception { + public void destroy() { refreshExecutor.shutdown(); } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListener.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListener.java index c923295d5..a5ce70782 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListener.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListener.java @@ -35,7 +35,8 @@ import org.springframework.context.ApplicationEventPublisherAware; 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 */ @@ -78,8 +79,10 @@ public class PolarisServiceStatusChangeListener extends AbstractResourceEventLis LOG.debug("receive service instances={} change event", svcEventKey); ServiceInstancesByProto oldIns = (ServiceInstancesByProto) oldValue; ServiceInstancesByProto newIns = (ServiceInstancesByProto) newValue; - if ((CollectionUtils.isEmpty(oldIns.getInstances()) && !CollectionUtils.isEmpty(newIns.getInstances())) || - (!CollectionUtils.isEmpty(oldIns.getInstances()) && CollectionUtils.isEmpty(newIns.getInstances()))) { + if ((CollectionUtils.isEmpty(oldIns.getInstances()) + && !CollectionUtils.isEmpty(newIns.getInstances())) || + (!CollectionUtils.isEmpty(oldIns.getInstances()) + && CollectionUtils.isEmpty(newIns.getInstances()))) { LOG.info("Service status of {} is update.", newIns.getService()); // Trigger reload of gateway route cache. diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulContextProperties.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulContextProperties.java index 2efbd93d6..bc2ebefc9 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulContextProperties.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulContextProperties.java @@ -164,7 +164,5 @@ public class ConsulContextProperties { public int getOrder() { return ModifierOrder.LAST; } - } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/ConditionalOnPolarisRegisterEnabled.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/ConditionalOnPolarisRegisterEnabled.java index 440312cab..3b186d27a 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/ConditionalOnPolarisRegisterEnabled.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/ConditionalOnPolarisRegisterEnabled.java @@ -27,6 +27,8 @@ 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) diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java index bfba996f7..719eb4e05 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java @@ -31,11 +31,9 @@ import org.springframework.util.StringUtils; * * @author Haotian Zhang, Andrew Shan, Jie Cheng */ -public class PolarisAutoServiceRegistration - extends AbstractAutoServiceRegistration { +public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistration { - private static final Logger log = LoggerFactory - .getLogger(PolarisAutoServiceRegistration.class); + private static final Logger LOG = LoggerFactory.getLogger(PolarisAutoServiceRegistration.class); private final PolarisRegistration registration; @@ -62,7 +60,7 @@ public class PolarisAutoServiceRegistration @Override protected void register() { if (!this.registration.isRegisterEnabled()) { - log.debug("Registration disabled."); + LOG.debug("Registration disabled."); return; } if (this.registration.getPort() <= 0) { @@ -96,5 +94,4 @@ public class PolarisAutoServiceRegistration String appName = registration.getPolarisProperties().getService(); return StringUtils.isEmpty(appName) ? super.getAppName() : appName; } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java index 558a6b5bf..3af44314e 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java @@ -51,10 +51,8 @@ public class PolarisRegistration implements Registration, ServiceInstance { private final SDKContext polarisContext; private final StaticMetadataManager staticMetadataManager; - - private Map metadata; - private final String host; + private Map metadata; public PolarisRegistration( DiscoveryPropertiesAutoConfiguration discoveryPropertiesAutoConfiguration, @@ -89,8 +87,7 @@ public class PolarisRegistration implements Registration, ServiceInstance { @Override public boolean isSecure() { - return StringUtils.equalsIgnoreCase(polarisDiscoveryProperties.getProtocol(), - "https"); + return StringUtils.equalsIgnoreCase(polarisDiscoveryProperties.getProtocol(), "https"); } @Override diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java index b68b2b10f..ce43c8415 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java @@ -51,8 +51,7 @@ import static org.springframework.util.ReflectionUtils.rethrowRuntimeException; */ public class PolarisServiceRegistry implements ServiceRegistry { - private static final Logger log = LoggerFactory - .getLogger(PolarisServiceRegistry.class); + private static final Logger LOG = LoggerFactory.getLogger(PolarisServiceRegistry.class); private static final int ttl = 5; @@ -82,9 +81,8 @@ public class PolarisServiceRegistry implements ServiceRegistry { @Override public void register(Registration registration) { - if (StringUtils.isEmpty(registration.getServiceId())) { - log.warn("No service to register for polaris client..."); + LOG.warn("No service to register for polaris client..."); return; } // Register instance. @@ -107,7 +105,7 @@ public class PolarisServiceRegistry implements ServiceRegistry { try { ProviderAPI providerClient = polarisDiscoveryHandler.getProviderAPI(); providerClient.register(instanceRegisterRequest); - log.info("polaris registry, {} {} {}:{} {} register finished", + LOG.info("polaris registry, {} {} {}:{} {} register finished", polarisDiscoveryProperties.getNamespace(), registration.getServiceId(), registration.getHost(), registration.getPort(), staticMetadataManager.getMergedStaticMetadata()); @@ -120,19 +118,17 @@ public class PolarisServiceRegistry implements ServiceRegistry { } } catch (Exception e) { - log.error("polaris registry, {} register failed...{},", - registration.getServiceId(), registration, e); + LOG.error("polaris registry, {} register failed...{},", registration.getServiceId(), registration, e); rethrowRuntimeException(e); } } @Override public void deregister(Registration registration) { - - log.info("De-registering from Polaris Server now..."); + LOG.info("De-registering from Polaris Server now..."); if (StringUtils.isEmpty(registration.getServiceId())) { - log.warn("No dom to de-register for polaris client..."); + LOG.warn("No dom to de-register for polaris client..."); return; } @@ -148,15 +144,14 @@ public class PolarisServiceRegistry implements ServiceRegistry { providerClient.deRegister(deRegisterRequest); } catch (Exception e) { - log.error("ERR_POLARIS_DEREGISTER, de-register failed...{},", registration, - e); + LOG.error("ERR_POLARIS_DEREGISTER, de-register failed...{},", registration, e); } finally { if (null != heartbeatExecutor) { heartbeatExecutor.shutdown(); } } - log.info("De-registration finished."); + LOG.info("De-registration finished."); } @Override @@ -172,8 +167,7 @@ public class PolarisServiceRegistry implements ServiceRegistry { @Override public Object getStatus(Registration registration) { String serviceName = registration.getServiceId(); - InstancesResponse instancesResponse = polarisDiscoveryHandler - .getInstances(serviceName); + InstancesResponse instancesResponse = polarisDiscoveryHandler.getInstances(serviceName); Instance[] instances = instancesResponse.getInstances(); if (null == instances || instances.length == 0) { return null; @@ -207,13 +201,10 @@ public class PolarisServiceRegistry implements ServiceRegistry { } String healthCheckUrl = String.format("http://%s:%s%s", - heartbeatRequest.getHost(), heartbeatRequest.getPort(), - healthCheckEndpoint); + heartbeatRequest.getHost(), heartbeatRequest.getPort(), healthCheckEndpoint); if (!OkHttpUtil.get(healthCheckUrl, null)) { - log.error( - "backend service health check failed. health check endpoint = {}", - healthCheckEndpoint); + LOG.error("backend service health check failed. health check endpoint = {}", healthCheckEndpoint); return; } } @@ -221,12 +212,11 @@ public class PolarisServiceRegistry implements ServiceRegistry { polarisDiscoveryHandler.getProviderAPI().heartbeat(heartbeatRequest); } catch (PolarisException e) { - log.error("polaris heartbeat[{}]", e.getCode(), e); + LOG.error("polaris heartbeat[{}]", e.getCode(), e); } catch (Exception e) { - log.error("polaris heartbeat runtime error", e); + LOG.error("polaris heartbeat runtime error", e); } }, ttl, ttl, TimeUnit.SECONDS); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java index 5eadee573..13c75aea7 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java @@ -43,8 +43,7 @@ import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties @ConditionalOnPolarisRegisterEnabled -@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", - matchIfMissing = true) +@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) @AutoConfigureAfter({AutoServiceRegistrationConfiguration.class, AutoServiceRegistrationAutoConfiguration.class, PolarisDiscoveryAutoConfiguration.class}) @@ -73,7 +72,6 @@ public class PolarisServiceRegistryAutoConfiguration { PolarisServiceRegistry registry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, PolarisRegistration registration) { - return new PolarisAutoServiceRegistration(registry, - autoServiceRegistrationProperties, registration); + return new PolarisAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration); } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/RegisterEnabledCondition.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/RegisterEnabledCondition.java index c7820fb6a..83ebb1d8b 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/RegisterEnabledCondition.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/RegisterEnabledCondition.java @@ -29,19 +29,16 @@ import org.springframework.core.type.AnnotatedTypeMetadata; public class RegisterEnabledCondition implements Condition { @Override - public boolean matches(ConditionContext conditionContext, - AnnotatedTypeMetadata annotatedTypeMetadata) { + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { boolean isRegisterEnabled = Boolean.parseBoolean(conditionContext.getEnvironment() .getProperty("spring.cloud.polaris.discovery.register", "true")); - boolean isConsulRegisterEnabled = Boolean - .parseBoolean(conditionContext.getEnvironment() - .getProperty("spring.cloud.consul.enabled", "false")) + boolean isConsulRegisterEnabled = Boolean.parseBoolean( + conditionContext.getEnvironment().getProperty("spring.cloud.consul.enabled", "false")) && Boolean.parseBoolean(conditionContext.getEnvironment() - .getProperty("spring.cloud.consul.discovery.register", "true")); + .getProperty("spring.cloud.consul.discovery.register", "true")); isRegisterEnabled |= isConsulRegisterEnabled; return isRegisterEnabled; } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfiguration.java index f79bd2dba..931f387a0 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfiguration.java @@ -36,12 +36,10 @@ public class PolarisRibbonServerListConfiguration { @Bean @ConditionalOnMissingBean - public ServerList ribbonServerList( - PolarisDiscoveryHandler polarisDiscoveryHandler, + public ServerList ribbonServerList(PolarisDiscoveryHandler polarisDiscoveryHandler, IClientConfig iClientConfig) { PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); serverList.initWithNiwsConfig(iClientConfig); return serverList; } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisServerList.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisServerList.java index 71833fde9..6e5b4a006 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisServerList.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisServerList.java @@ -56,8 +56,7 @@ public class PolarisServerList extends AbstractServerList { } private List getServers() { - InstancesResponse allInstances = polarisDiscoveryHandler - .getHealthyInstances(serviceId); + InstancesResponse allInstances = polarisDiscoveryHandler.getHealthyInstances(serviceId); ServiceInstances serviceInstances = allInstances.toServiceInstances(); List polarisServers = new ArrayList<>(); for (Instance instance : serviceInstances.getInstances()) { @@ -74,5 +73,4 @@ public class PolarisServerList extends AbstractServerList { public void initWithNiwsConfig(IClientConfig iClientConfig) { this.serviceId = iClientConfig.getClientName(); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java index 2a1ba0dc4..b5a275c9a 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java @@ -62,8 +62,7 @@ public final class OkHttpUtil { if (response.isSuccessful() && Objects.nonNull(response.body())) { String result = response.body().string(); - logger.debug("exec get request, url: {} success,response data: {}", url, - result); + logger.debug("exec get request, url: {} success,response data: {}", url, result); return true; } } @@ -88,5 +87,4 @@ public final class OkHttpUtil { }); } } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java index 8f89a8313..e1ab77ec2 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java @@ -41,7 +41,8 @@ public class DiscoveryPropertiesAutoConfigurationTest { @Test public void testDefaultInitialization() { ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(PolarisContextAutoConfiguration.class, + AutoConfigurations.of( + PolarisContextAutoConfiguration.class, DiscoveryPropertiesAutoConfiguration.class)); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(DiscoveryPropertiesAutoConfiguration.class); @@ -57,7 +58,8 @@ public class DiscoveryPropertiesAutoConfigurationTest { @Test public void testInit() { ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(PolarisContextAutoConfiguration.class, + AutoConfigurations.of( + PolarisContextAutoConfiguration.class, TestConfiguration.class, DiscoveryPropertiesAutoConfiguration.class)) .withPropertyValues("spring.cloud.polaris.discovery.register=false") @@ -65,7 +67,8 @@ public class DiscoveryPropertiesAutoConfigurationTest { .withPropertyValues("spring.cloud.consul.discovery.enabled=false"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(DiscoveryPropertiesAutoConfiguration.class); - DiscoveryPropertiesAutoConfiguration discoveryPropertiesAutoConfiguration = context.getBean(DiscoveryPropertiesAutoConfiguration.class); + DiscoveryPropertiesAutoConfiguration discoveryPropertiesAutoConfiguration = + context.getBean(DiscoveryPropertiesAutoConfiguration.class); assertThat(discoveryPropertiesAutoConfiguration.isRegisterEnabled()).isFalse(); assertThat(discoveryPropertiesAutoConfiguration.isDiscoveryEnabled()).isFalse(); }); diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesBootstrapAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesBootstrapAutoConfigurationTest.java index 3ef145d0e..74f975a39 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesBootstrapAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesBootstrapAutoConfigurationTest.java @@ -35,7 +35,8 @@ public class DiscoveryPropertiesBootstrapAutoConfigurationTest { @Test public void testDefaultInitialization() { ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(PolarisContextAutoConfiguration.class, + AutoConfigurations.of( + PolarisContextAutoConfiguration.class, DiscoveryPropertiesBootstrapAutoConfiguration.class)) .withPropertyValues("spring.cloud.polaris.enabled=true"); applicationContextRunner.run(context -> { diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java index 644cc4b7d..6966d4f6e 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java @@ -30,7 +30,6 @@ import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import static com.tencent.polaris.test.common.Consts.PORT; @@ -46,12 +45,12 @@ public class PolarisDiscoveryAutoConfigurationTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisContextAutoConfiguration.class, - PolarisDiscoveryAutoConfiguration.class, - PolarisDiscoveryClientConfiguration.class, - PolarisContextAutoConfiguration.class)) + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisDiscoveryAutoConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisContextAutoConfiguration.class)) .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); @@ -62,7 +61,7 @@ public class PolarisDiscoveryAutoConfigurationTest { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -80,9 +79,7 @@ public class PolarisDiscoveryAutoConfigurationTest { @Configuration @EnableAutoConfiguration - @EnableDiscoveryClient static class PolarisDiscoveryAutoConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java index c98000f81..4a0667686 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java @@ -26,7 +26,6 @@ import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import static com.tencent.polaris.test.common.Consts.PORT; @@ -42,11 +41,11 @@ public class PolarisDiscoveryClientConfigurationTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisContextAutoConfiguration.class, - PolarisDiscoveryClientConfiguration.class, - PolarisContextAutoConfiguration.class)) + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisContextAutoConfiguration.class)) .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); @@ -57,7 +56,7 @@ public class PolarisDiscoveryClientConfigurationTest { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -65,23 +64,18 @@ public class PolarisDiscoveryClientConfigurationTest { @Test public void testDefaultInitialization() { - this.contextRunner.run(context -> assertThat(context) - .hasSingleBean(PolarisDiscoveryClient.class)); + this.contextRunner.run(context -> assertThat(context).hasSingleBean(PolarisDiscoveryClient.class)); } @Test public void testDiscoveryBlockingDisabled() { - this.contextRunner - .withPropertyValues("spring.cloud.discovery.blocking.enabled=false") - .run(context -> assertThat(context) - .doesNotHaveBean(PolarisDiscoveryClient.class)); + this.contextRunner.withPropertyValues("spring.cloud.discovery.blocking.enabled=false") + .run(context -> assertThat(context).doesNotHaveBean(PolarisDiscoveryClient.class)); } @Configuration @EnableAutoConfiguration - @EnableDiscoveryClient static class PolarisDiscoveryClientConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java index b678593d9..e4a07de05 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java @@ -51,7 +51,6 @@ public class PolarisDiscoveryClientTest { @Test public void testGetInstances() { - when(polarisServiceDiscovery.getInstances(anyString())) .thenReturn(singletonList(mock(PolarisServiceInstance.class))); @@ -62,9 +61,7 @@ public class PolarisDiscoveryClientTest { @Test public void testGetServices() { - - when(polarisServiceDiscovery.getServices()) - .thenReturn(singletonList(SERVICE_PROVIDER)); + when(polarisServiceDiscovery.getServices()).thenReturn(singletonList(SERVICE_PROVIDER)); List services = client.getServices(); diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java index 4b03882d1..78004f0e8 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java @@ -32,7 +32,6 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; @@ -49,7 +48,7 @@ public class PolarisServiceDiscoveryTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withConfiguration(AutoConfigurations.of( PolarisContextAutoConfiguration.class, PolarisServiceDiscoveryTest.PolarisPropertiesConfiguration.class, @@ -73,12 +72,11 @@ public class PolarisServiceDiscoveryTest { instanceParameter.setIsolated(false); instanceParameter.setWeight(100); ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER); - namingServer.getNamingService().batchAddInstances(serviceKey, PORT, 3, - instanceParameter); + namingServer.getNamingService().batchAddInstances(serviceKey, PORT, 3, instanceParameter); } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -87,10 +85,8 @@ public class PolarisServiceDiscoveryTest { @Test public void testGetInstances() { this.contextRunner.run(context -> { - PolarisServiceDiscovery polarisServiceDiscovery = context - .getBean(PolarisServiceDiscovery.class); - List serviceInstances = polarisServiceDiscovery - .getInstances(SERVICE_PROVIDER); + PolarisServiceDiscovery polarisServiceDiscovery = context.getBean(PolarisServiceDiscovery.class); + List serviceInstances = polarisServiceDiscovery.getInstances(SERVICE_PROVIDER); assertThat(serviceInstances.isEmpty()).isFalse(); assertThat(serviceInstances).hasSize(3); assertThat(serviceInstances.get(0).getPort()).isEqualTo(PORT); @@ -102,8 +98,7 @@ public class PolarisServiceDiscoveryTest { @Test public void testGetServices() throws PolarisException { this.contextRunner.run(context -> { - PolarisServiceDiscovery polarisServiceDiscovery = context - .getBean(PolarisServiceDiscovery.class); + PolarisServiceDiscovery polarisServiceDiscovery = context.getBean(PolarisServiceDiscovery.class); List services = polarisServiceDiscovery.getServices(); assertThat(services.size()).isEqualTo(1); }); @@ -112,9 +107,7 @@ public class PolarisServiceDiscoveryTest { @Configuration @EnableAutoConfiguration - @EnableDiscoveryClient static class PolarisPropertiesConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java index 8588c77af..11a61eb5a 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java @@ -27,7 +27,6 @@ import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Configuration; import static com.tencent.polaris.test.common.Consts.PORT; @@ -43,12 +42,12 @@ public class PolarisReactiveDiscoveryClientConfigurationTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisContextAutoConfiguration.class, - PolarisReactiveDiscoveryClientConfiguration.class, - PolarisDiscoveryClientConfiguration.class, - PolarisContextAutoConfiguration.class)) + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisReactiveDiscoveryClientConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisContextAutoConfiguration.class)) .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); @@ -59,7 +58,7 @@ public class PolarisReactiveDiscoveryClientConfigurationTest { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -73,9 +72,7 @@ public class PolarisReactiveDiscoveryClientConfigurationTest { @Configuration @EnableAutoConfiguration - @EnableDiscoveryClient static class PolarisReactiveDiscoveryClientConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientTest.java index ac5f2088a..65516822f 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientTest.java @@ -57,7 +57,6 @@ public class PolarisReactiveDiscoveryClientTest { @Test public void testGetInstances() throws PolarisException { - when(serviceDiscovery.getInstances(anyString())).thenAnswer(invocation -> { String serviceName = invocation.getArgument(0); if (SERVICE_PROVIDER.equalsIgnoreCase(serviceName)) { @@ -79,7 +78,6 @@ public class PolarisReactiveDiscoveryClientTest { @Test public void testGetServices() throws PolarisException { - when(serviceDiscovery.getServices()).thenAnswer(invocation -> { if (count == 0) { count++; diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListenerTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListenerTest.java index e468a46ed..7366e210a 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListenerTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/refresh/PolarisServiceStatusChangeListenerTest.java @@ -64,7 +64,8 @@ public class PolarisServiceStatusChangeListenerTest { polarisServiceStatusChangeListener.setApplicationEventPublisher(publisher); // Service update event - ServiceEventKey serviceUpdateEventKey = new ServiceEventKey(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER), ServiceEventKey.EventType.SERVICE); + ServiceEventKey serviceUpdateEventKey = new ServiceEventKey( + new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER), ServiceEventKey.EventType.SERVICE); ServiceInfo serviceInfo = new ServiceInfo(); serviceInfo.setNamespace(NAMESPACE_TEST); serviceInfo.setService(SERVICE_PROVIDER); @@ -81,7 +82,8 @@ public class PolarisServiceStatusChangeListenerTest { // Instance update event - ServiceEventKey instanceUpdateEventKey = new ServiceEventKey(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER), ServiceEventKey.EventType.INSTANCE); + ServiceEventKey instanceUpdateEventKey = new ServiceEventKey( + new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER), ServiceEventKey.EventType.INSTANCE); DefaultInstance instance = new DefaultInstance(); instance.setNamespace(NAMESPACE_TEST); instance.setService(SERVICE_PROVIDER); @@ -96,7 +98,7 @@ public class PolarisServiceStatusChangeListenerTest { instances.set(oldInstances, Collections.emptyList()); ServiceInstancesByProto newInstances = new ServiceInstancesByProto(); instances.set(newInstances, Collections.singletonList(instance)); - polarisServiceStatusChangeListener.onResourceUpdated(serviceUpdateEventKey, oldInstances, newInstances); + polarisServiceStatusChangeListener.onResourceUpdated(instanceUpdateEventKey, oldInstances, newInstances); verify(publisher, times(2)).publishEvent(any(ApplicationEvent.class)); // No need update @@ -104,7 +106,7 @@ public class PolarisServiceStatusChangeListenerTest { instances.set(oldInstances, Collections.singletonList(instance)); newInstances = new ServiceInstancesByProto(); instances.set(newInstances, Collections.singletonList(instance)); - polarisServiceStatusChangeListener.onResourceUpdated(serviceUpdateEventKey, oldInstances, newInstances); + polarisServiceStatusChangeListener.onResourceUpdated(instanceUpdateEventKey, oldInstances, newInstances); verify(publisher, times(2)).publishEvent(any(ApplicationEvent.class)); } catch (NoSuchFieldException | IllegalAccessException e) { diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java index 26aaf8efa..1414b3d27 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java @@ -140,5 +140,4 @@ public class PolarisAutoServiceRegistrationTest { doReturn(SERVICE_PROVIDER).when(polarisDiscoveryProperties).getService(); assertThat(polarisAutoServiceRegistration.getAppName()).isEqualTo(SERVICE_PROVIDER); } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java index 96b6b3fe8..9535e4fb4 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java @@ -28,7 +28,6 @@ import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration; import org.springframework.context.annotation.Configuration; @@ -45,11 +44,11 @@ public class PolarisServiceRegistryAutoConfigurationTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisContextAutoConfiguration.class, - PolarisServiceRegistryAutoConfiguration.class, - PolarisDiscoveryClientConfiguration.class)) + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisServiceRegistryAutoConfiguration.class, + PolarisDiscoveryClientConfiguration.class)) .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); @@ -60,7 +59,7 @@ public class PolarisServiceRegistryAutoConfigurationTest { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -70,16 +69,13 @@ public class PolarisServiceRegistryAutoConfigurationTest { public void testDefaultInitialization() { this.contextRunner.run(context -> { assertThat(context).hasSingleBean(PolarisDiscoveryAutoConfiguration.class); - assertThat(context) - .hasSingleBean(AutoServiceRegistrationAutoConfiguration.class); + assertThat(context).hasSingleBean(AutoServiceRegistrationAutoConfiguration.class); }); } @Configuration @EnableAutoConfiguration - @EnableDiscoveryClient static class PolarisServiceRegistryAutoConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java index d6f751d2f..8a6797b7b 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java @@ -49,17 +49,16 @@ public class PolarisServiceRegistryTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisContextAutoConfiguration.class, - PolarisPropertiesConfiguration.class, - PolarisDiscoveryClientConfiguration.class, - PolarisDiscoveryAutoConfiguration.class)) + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisPropertiesConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisDiscoveryAutoConfiguration.class)) .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") - .withPropertyValues( - "spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) + .withPropertyValues("spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); @BeforeClass @@ -67,12 +66,11 @@ public class PolarisServiceRegistryTest { namingServer = NamingServer.startNamingServer(10081); // add service - namingServer.getNamingService() - .addService(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER)); + namingServer.getNamingService().addService(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER)); } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -81,8 +79,7 @@ public class PolarisServiceRegistryTest { @Test public void testRegister() { this.contextRunner.run(context -> { - PolarisServiceRegistry registry = context - .getBean(PolarisServiceRegistry.class); + PolarisServiceRegistry registry = context.getBean(PolarisServiceRegistry.class); PolarisRegistration registration = Mockito.mock(PolarisRegistration.class); when(registration.getHost()).thenReturn("127.0.0.1"); when(registration.getPort()).thenReturn(PORT); @@ -114,8 +111,7 @@ public class PolarisServiceRegistryTest { @Test public void testDeRegister() { this.contextRunner.run(context -> { - PolarisServiceRegistry registry = context - .getBean(PolarisServiceRegistry.class); + PolarisServiceRegistry registry = context.getBean(PolarisServiceRegistry.class); PolarisRegistration registration = Mockito.mock(PolarisRegistration.class); doReturn(null).when(registration).getServiceId(); try { @@ -132,5 +128,4 @@ public class PolarisServiceRegistryTest { static class PolarisPropertiesConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisDiscoveryRibbonAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisDiscoveryRibbonAutoConfigurationTest.java index e14d9be7d..7f9253a09 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisDiscoveryRibbonAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisDiscoveryRibbonAutoConfigurationTest.java @@ -31,7 +31,7 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisDiscoveryRibbonAutoConfigurationTest { - private ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); + private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); @Test public void testDefaultInitialization() { diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java index 277555901..8d2d286fc 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java @@ -37,7 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisRibbonServerListConfigurationTest { - private ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); + private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); @Test public void testDefaultInitialization() { diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java index e441786e6..b617d8579 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java @@ -54,18 +54,17 @@ public class PolarisServerListTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisContextAutoConfiguration.class, - PolarisServerListTest.PolarisPropertiesConfiguration.class, - PolarisDiscoveryClientConfiguration.class, - PolarisDiscoveryAutoConfiguration.class, - PolarisContextAutoConfiguration.class)) + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisServerListTest.PolarisPropertiesConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisDiscoveryAutoConfiguration.class, + PolarisContextAutoConfiguration.class)) .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") - .withPropertyValues( - "spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) + .withPropertyValues("spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); private IClientConfig iClientConfig; @@ -75,12 +74,11 @@ public class PolarisServerListTest { namingServer = NamingServer.startNamingServer(10081); // add service - namingServer.getNamingService() - .addService(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER)); + namingServer.getNamingService().addService(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER)); } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -97,8 +95,7 @@ public class PolarisServerListTest { @Test public void testGetInitialListOfServers() { this.contextRunner.run(context -> { - PolarisDiscoveryHandler polarisDiscoveryHandler = context - .getBean(PolarisDiscoveryHandler.class); + PolarisDiscoveryHandler polarisDiscoveryHandler = context.getBean(PolarisDiscoveryHandler.class); PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); serverList.initWithNiwsConfig(iClientConfig); @@ -110,8 +107,7 @@ public class PolarisServerListTest { @Test public void testGetUpdatedListOfServers() { this.contextRunner.run(context -> { - PolarisDiscoveryHandler polarisDiscoveryHandler = context - .getBean(PolarisDiscoveryHandler.class); + PolarisDiscoveryHandler polarisDiscoveryHandler = context.getBean(PolarisDiscoveryHandler.class); PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); serverList.initWithNiwsConfig(iClientConfig); @@ -121,8 +117,7 @@ public class PolarisServerListTest { instanceParameter.setIsolated(false); instanceParameter.setWeight(100); ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER); - namingServer.getNamingService().batchAddInstances(serviceKey, PORT, 3, - instanceParameter); + namingServer.getNamingService().batchAddInstances(serviceKey, PORT, 3, instanceParameter); List servers = serverList.getUpdatedListOfServers(); assertThat(servers).hasSize(3); @@ -135,8 +130,7 @@ public class PolarisServerListTest { @Test public void testProperties() { this.contextRunner.run(context -> { - PolarisDiscoveryHandler polarisDiscoveryHandler = context - .getBean(PolarisDiscoveryHandler.class); + PolarisDiscoveryHandler polarisDiscoveryHandler = context.getBean(PolarisDiscoveryHandler.class); PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); serverList.initWithNiwsConfig(iClientConfig); @@ -149,5 +143,4 @@ public class PolarisServerListTest { static class PolarisPropertiesConfiguration { } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolver.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolver.java index 4c29cb3ad..bee50dc5c 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolver.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolver.java @@ -34,7 +34,7 @@ import org.springframework.util.CollectionUtils; /** * resolve labels from rate limit rule. * - *@author lepdou 2022-05-13 + * @author lepdou 2022-05-13 */ public class RateLimitRuleLabelResolver { diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java index 83cc00c91..5cd34b9d4 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java @@ -95,7 +95,6 @@ public class PolarisRateLimitAutoConfiguration { registrationBean.setOrder(RateLimitConstant.FILTER_ORDER); return registrationBean; } - } /** @@ -113,7 +112,5 @@ public class PolarisRateLimitAutoConfiguration { return new QuotaCheckReactiveFilter(limitAPI, labelResolver, polarisRateLimitProperties, rateLimitRuleLabelResolver); } - } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/RateLimitConfigModifier.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/RateLimitConfigModifier.java index b0c097a68..a91e9c7c9 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/RateLimitConfigModifier.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/RateLimitConfigModifier.java @@ -37,13 +37,11 @@ public class RateLimitConfigModifier implements PolarisConfigModifier { @Override public void modify(ConfigurationImpl configuration) { // Update MaxQueuingTime. - configuration.getProvider().getRateLimit() - .setMaxQueuingTime(polarisRateLimitProperties.getMaxQueuingTime()); + configuration.getProvider().getRateLimit().setMaxQueuingTime(polarisRateLimitProperties.getMaxQueuingTime()); } @Override public int getOrder() { return ContextConstant.ModifierOrder.CIRCUIT_BREAKER_ORDER; } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java index 814134527..22f11ed04 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java @@ -44,5 +44,4 @@ public final class RateLimitConstant { private RateLimitConstant() { } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java index 31320dda0..fb547bb55 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java @@ -162,5 +162,4 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered { Set expressionLabels = rateLimitRuleLabelResolver.getExpressionLabelKeys(namespace, service); return ExpressionLabelUtils.resolve(exchange, expressionLabels); } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java index f3e4c3b07..766f38b88 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java @@ -144,8 +144,7 @@ public class QuotaCheckServletFilter extends OncePerRequestFilter { return labelResolver.resolve(request); } catch (Throwable e) { - LOG.error("resolve custom label failed. resolver = {}", - labelResolver.getClass().getName(), e); + LOG.error("resolve custom label failed. resolver = {}", labelResolver.getClass().getName(), e); } } return Collections.emptyMap(); diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelReactiveResolver.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelReactiveResolver.java index 4ebcc1921..6f63cbc93 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelReactiveResolver.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelReactiveResolver.java @@ -35,5 +35,4 @@ public interface PolarisRateLimiterLabelReactiveResolver { * @return resolved labels */ Map resolve(ServerWebExchange exchange); - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelServletResolver.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelServletResolver.java index 253b67b5c..1ec3a7a0c 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelServletResolver.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/spi/PolarisRateLimiterLabelServletResolver.java @@ -35,5 +35,4 @@ public interface PolarisRateLimiterLabelServletResolver { * @return resolved labels */ Map resolve(HttpServletRequest request); - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java index bceb49e9a..f0e5ec10a 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java @@ -57,5 +57,4 @@ public final class QuotaCheckUtils { "get quota failed")); } } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java index 4a67aea01..428254e37 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java @@ -63,5 +63,4 @@ public final class RateLimitUtils { return RateLimitConstant.QUOTA_LIMITED_INFO; } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java index 387fe510d..7ba83ee33 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java @@ -39,11 +39,12 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisRateLimitAutoConfigurationTest { - private ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); + private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); - private WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner(); + private final WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner(); - private ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = new ReactiveWebApplicationContextRunner(); + private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = + new ReactiveWebApplicationContextRunner(); @Test public void testNoWebApplication() { @@ -58,7 +59,8 @@ public class PolarisRateLimitAutoConfigurationTest { assertThat(context).doesNotHaveBean(PolarisRateLimitAutoConfiguration.QuotaCheckFilterConfig.class); assertThat(context).doesNotHaveBean(QuotaCheckServletFilter.class); assertThat(context).doesNotHaveBean(FilterRegistrationBean.class); - assertThat(context).doesNotHaveBean(PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class); + assertThat(context).doesNotHaveBean( + PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class); assertThat(context).doesNotHaveBean(QuotaCheckReactiveFilter.class); }); } @@ -66,7 +68,8 @@ public class PolarisRateLimitAutoConfigurationTest { @Test public void testServletWebApplication() { this.webApplicationContextRunner - .withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class, + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, PolarisRateLimitProperties.class, PolarisRateLimitAutoConfiguration.class)) .run(context -> { @@ -75,7 +78,8 @@ public class PolarisRateLimitAutoConfigurationTest { assertThat(context).hasSingleBean(PolarisRateLimitAutoConfiguration.QuotaCheckFilterConfig.class); assertThat(context).hasSingleBean(QuotaCheckServletFilter.class); assertThat(context).hasSingleBean(FilterRegistrationBean.class); - assertThat(context).doesNotHaveBean(PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class); + assertThat(context).doesNotHaveBean( + PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class); assertThat(context).doesNotHaveBean(QuotaCheckReactiveFilter.class); }); } @@ -83,7 +87,8 @@ public class PolarisRateLimitAutoConfigurationTest { @Test public void testReactiveWebApplication() { this.reactiveWebApplicationContextRunner - .withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class, + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, PolarisRateLimitProperties.class, PolarisRateLimitAutoConfiguration.class)) .run(context -> { @@ -92,7 +97,8 @@ public class PolarisRateLimitAutoConfigurationTest { assertThat(context).doesNotHaveBean(PolarisRateLimitAutoConfiguration.QuotaCheckFilterConfig.class); assertThat(context).doesNotHaveBean(QuotaCheckServletFilter.class); assertThat(context).doesNotHaveBean(FilterRegistrationBean.class); - assertThat(context).hasSingleBean(PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class); + assertThat(context).hasSingleBean( + PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class); assertThat(context).hasSingleBean(QuotaCheckReactiveFilter.class); }); } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesAutoConfigurationTest.java index 258dd557b..f3130ed7a 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesAutoConfigurationTest.java @@ -31,9 +31,8 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisRateLimitPropertiesAutoConfigurationTest { - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisRateLimitPropertiesAutoConfiguration.class)); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisRateLimitPropertiesAutoConfiguration.class)); @Test public void testDefaultInitialization() { diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesBootstrapConfigurationTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesBootstrapConfigurationTest.java index 71e7334cc..90c88f98c 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesBootstrapConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesBootstrapConfigurationTest.java @@ -31,9 +31,8 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class PolarisRateLimitPropertiesBootstrapConfigurationTest { - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(PolarisRateLimitPropertiesBootstrapConfiguration.class)) + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisRateLimitPropertiesBootstrapConfiguration.class)) .withPropertyValues("spring.cloud.polaris.enabled=true"); @Test diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java index 4aabf24c2..72ee0c80b 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java @@ -88,7 +88,7 @@ public class CalleeControllerTests { } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { if (null != namingServer) { namingServer.terminate(); } @@ -111,10 +111,8 @@ public class CalleeControllerTests { try { if (i > 9) { QuotaResponse quotaResponse = mock(QuotaResponse.class); - when(quotaResponse.getCode()) - .thenReturn(QuotaResultCode.QuotaResultLimited); - when(quotaResponse.getInfo()) - .thenReturn("Testing rate limit after 10 times success."); + when(quotaResponse.getCode()).thenReturn(QuotaResultCode.QuotaResultLimited); + when(quotaResponse.getInfo()).thenReturn("Testing rate limit after 10 times success."); when(limitAPI.getQuota(any())).thenReturn(quotaResponse); } String result = restTemplate.getForObject(url, String.class); @@ -146,5 +144,4 @@ public class CalleeControllerTests { } } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java index 1ede96b48..1bca56bc0 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java @@ -31,8 +31,7 @@ import org.springframework.web.bind.annotation.RestController; public class TestController { @GetMapping("/info") - public String info() throws Exception { + public String info() { return "hello service info"; } - } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java index 6d3ef804f..b54ffec6f 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java @@ -74,17 +74,17 @@ import static org.mockito.Mockito.when; }) public class QuotaCheckReactiveFilterTest { - private PolarisRateLimiterLabelReactiveResolver labelResolver = exchange -> Collections.singletonMap("ReactiveResolver", "ReactiveResolver"); - - private QuotaCheckReactiveFilter quotaCheckReactiveFilter; - private static MockedStatic mockedApplicationContextAwareUtils; private static MockedStatic expressionLabelUtilsMockedStatic; + private final PolarisRateLimiterLabelReactiveResolver labelResolver = + exchange -> Collections.singletonMap("ReactiveResolver", "ReactiveResolver"); + private QuotaCheckReactiveFilter quotaCheckReactiveFilter; @BeforeClass public static void beforeClass() { expressionLabelUtilsMockedStatic = mockStatic(ExpressionLabelUtils.class); - when(ExpressionLabelUtils.resolve(any(ServerWebExchange.class), anySet())).thenReturn(Collections.singletonMap("RuleLabelResolver", "RuleLabelResolver")); + when(ExpressionLabelUtils.resolve(any(ServerWebExchange.class), anySet())) + .thenReturn(Collections.singletonMap("RuleLabelResolver", "RuleLabelResolver")); mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) @@ -125,7 +125,8 @@ public class QuotaCheckReactiveFilterTest { RateLimitRuleLabelResolver rateLimitRuleLabelResolver = mock(RateLimitRuleLabelResolver.class); when(rateLimitRuleLabelResolver.getExpressionLabelKeys(anyString(), anyString())).thenReturn(Collections.EMPTY_SET); - this.quotaCheckReactiveFilter = new QuotaCheckReactiveFilter(limitAPI, labelResolver, polarisRateLimitProperties, rateLimitRuleLabelResolver); + this.quotaCheckReactiveFilter = new QuotaCheckReactiveFilter( + limitAPI, labelResolver, polarisRateLimitProperties, rateLimitRuleLabelResolver); } @Test diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java index 7ff8e8793..cd68a8fdb 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java @@ -73,27 +73,26 @@ import static org.mockito.Mockito.when; }) public class QuotaCheckServletFilterTest { - private PolarisRateLimiterLabelServletResolver labelResolver = exchange -> Collections.singletonMap("ServletResolver", "ServletResolver"); - + private static MockedStatic mockedApplicationContextAwareUtils; + private static MockedStatic expressionLabelUtilsMockedStatic; + private PolarisRateLimiterLabelServletResolver labelResolver = + exchange -> Collections.singletonMap("ServletResolver", "ServletResolver"); private QuotaCheckServletFilter quotaCheckServletFilter; - private QuotaCheckServletFilter quotaCheckWithHtmlRejectTipsServletFilter; - private static MockedStatic mockedApplicationContextAwareUtils; - private static MockedStatic expressionLabelUtilsMockedStatic; @BeforeClass public static void beforeClass() { expressionLabelUtilsMockedStatic = mockStatic(ExpressionLabelUtils.class); - when(ExpressionLabelUtils.resolve(any(ServerWebExchange.class), anySet())).thenReturn(Collections.singletonMap("RuleLabelResolver", "RuleLabelResolver")); + when(ExpressionLabelUtils.resolve(any(ServerWebExchange.class), anySet())) + .thenReturn(Collections.singletonMap("RuleLabelResolver", "RuleLabelResolver")); mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) .thenReturn("unit-test"); - } @AfterClass - public static void afterClass() throws Exception { + public static void afterClass() { mockedApplicationContextAwareUtils.close(); expressionLabelUtilsMockedStatic.close(); } @@ -128,10 +127,11 @@ public class QuotaCheckServletFilterTest { polarisRateLimitWithHtmlRejectTipsProperties.setRejectHttpCode(419); RateLimitRuleLabelResolver rateLimitRuleLabelResolver = mock(RateLimitRuleLabelResolver.class); - when(rateLimitRuleLabelResolver.getExpressionLabelKeys(anyString(), anyString())).thenReturn(Collections.EMPTY_SET); + when(rateLimitRuleLabelResolver.getExpressionLabelKeys(anyString(), anyString())).thenReturn(Collections.emptySet()); this.quotaCheckServletFilter = new QuotaCheckServletFilter(limitAPI, labelResolver, polarisRateLimitProperties, rateLimitRuleLabelResolver); - this.quotaCheckWithHtmlRejectTipsServletFilter = new QuotaCheckServletFilter(limitAPI, labelResolver, polarisRateLimitWithHtmlRejectTipsProperties, rateLimitRuleLabelResolver); + this.quotaCheckWithHtmlRejectTipsServletFilter = new QuotaCheckServletFilter( + limitAPI, labelResolver, polarisRateLimitWithHtmlRejectTipsProperties, rateLimitRuleLabelResolver); } @Test diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterContext.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterContext.java index 114548722..1e05d2ec6 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterContext.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterContext.java @@ -27,7 +27,7 @@ import org.springframework.util.CollectionUtils; /** * the context for router. * - *@author lepdou 2022-05-17 + * @author lepdou 2022-05-17 */ public class PolarisRouterContext { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConstants.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConstants.java index 6437c83e8..cff733e59 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConstants.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConstants.java @@ -21,12 +21,15 @@ package com.tencent.cloud.polaris.router; /** * Router constants. * - *@author lepdou 2022-05-17 + * @author lepdou 2022-05-17 */ -public class RouterConstants { +public final class RouterConstants { /** * the header of router label. */ public static final String ROUTER_LABEL_HEADER = "internal-router-label"; + + private RouterConstants() { + } } diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolver.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolver.java index 5ab6e549f..ded1784f4 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolver.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolver.java @@ -33,6 +33,7 @@ import org.springframework.util.CollectionUtils; /** * Resolve label expressions from routing rules. + * * @author lepdou 2022-05-19 */ public class RouterRuleLabelResolver { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/SimpleLoadBalancer.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/SimpleLoadBalancer.java index d509c1bbf..3ccaf01a9 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/SimpleLoadBalancer.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/SimpleLoadBalancer.java @@ -27,7 +27,7 @@ import com.netflix.loadbalancer.Server; /** * Simple load balancer only for getting and setting servers. * - *@author lepdou 2022-05-17 + * @author lepdou 2022-05-17 */ public class SimpleLoadBalancer implements ILoadBalancer { private List servers; diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/LoadBalancerClientFilterBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/LoadBalancerClientFilterBeanPostProcessor.java index 5111bda51..5b4c7b71f 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/LoadBalancerClientFilterBeanPostProcessor.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/LoadBalancerClientFilterBeanPostProcessor.java @@ -36,7 +36,8 @@ import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter; /** * Replace LoadBalancerClientFilter with PolarisLoadBalancerClientFilter. - *@author lepdou 2022-06-15 + * + * @author lepdou 2022-06-15 */ public class LoadBalancerClientFilterBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/LoadBalancerInterceptorBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/LoadBalancerInterceptorBeanPostProcessor.java index 0b383a682..05625a2b7 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/LoadBalancerInterceptorBeanPostProcessor.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/LoadBalancerInterceptorBeanPostProcessor.java @@ -37,7 +37,8 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory; /** * Replace LoadBalancerInterceptor with PolarisLoadBalancerInterceptor. * PolarisLoadBalancerInterceptor can pass routing context information. - *@author lepdou 2022-05-18 + * + * @author lepdou 2022-05-18 */ public class LoadBalancerInterceptorBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignAutoConfiguration.java index 5b87668ea..6de5f5399 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignAutoConfiguration.java @@ -36,7 +36,8 @@ import org.springframework.lang.Nullable; /** * configuration for feign singleton components. * Feign-related components need to be loaded only in the feign environment. - *@author lepdou 2022-06-10 + * + * @author lepdou 2022-06-10 */ @Configuration @ConditionalOnClass(name = {"org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer"}) @@ -54,5 +55,4 @@ public class FeignAutoConfiguration { public PolarisCachingSpringLoadBalanceFactory polarisCachingSpringLoadBalanceFactory(SpringClientFactory factory) { return new PolarisCachingSpringLoadBalanceFactory(factory); } - } diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignLoadBalancerConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignLoadBalancerConfiguration.java index e6368cc85..c49ea3a26 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignLoadBalancerConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignLoadBalancerConfiguration.java @@ -27,8 +27,10 @@ import org.springframework.cloud.netflix.ribbon.ServerIntrospector; import org.springframework.context.annotation.Bean; /** - * configuration for feign load balance components. PolarisFeignLoadBalancer is not singleton bean, Each service corresponds to a PolarisFeignLoadBalancer. - *@author lepdou 2022-05-16 + * configuration for feign load balance components. PolarisFeignLoadBalancer is not singleton bean, + * Each service corresponds to a PolarisFeignLoadBalancer. + * + * @author lepdou 2022-05-16 */ public class FeignLoadBalancerConfiguration { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RibbonConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RibbonConfiguration.java index 9bc17b276..e8fe2f06b 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RibbonConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RibbonConfiguration.java @@ -31,6 +31,7 @@ import org.springframework.context.annotation.Bean; /** * Configuration for ribbon components. IRule is not singleton bean, Each service corresponds to an IRule. + * * @author lepdou 2022-05-17 */ public class RibbonConfiguration { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java index 690ba9f0c..c3a3d40cb 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java @@ -38,7 +38,7 @@ import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; /** * configuration for router module singleton beans. * - *@author lepdou 2022-05-11 + * @author lepdou 2022-05-11 */ @Configuration @RibbonClients(defaultConfiguration = {RibbonConfiguration.class}) diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/properties/PolarisMetadataRouterProperties.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/properties/PolarisMetadataRouterProperties.java index 70ded3a8c..949edc54a 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/properties/PolarisMetadataRouterProperties.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/properties/PolarisMetadataRouterProperties.java @@ -22,6 +22,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; /** * the configuration for metadata router. + * * @author lepdou 2022-05-23 */ @ConfigurationProperties(prefix = "spring.cloud.polaris.router.metadata-router") diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtils.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtils.java index 92b8a6608..152ffcc9c 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtils.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtils.java @@ -33,9 +33,13 @@ import org.springframework.util.CollectionUtils; /** * Resolve rule expression label from feign request. + * * @author lepdou 2022-05-20 */ -public class FeignExpressionLabelUtils { +public final class FeignExpressionLabelUtils { + + private FeignExpressionLabelUtils() { + } public static Map resolve(RequestTemplate request, Set labelKeys) { if (CollectionUtils.isEmpty(labelKeys)) { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/PolarisCachingSpringLoadBalanceFactory.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/PolarisCachingSpringLoadBalanceFactory.java index 2c15ce790..59044c3ba 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/PolarisCachingSpringLoadBalanceFactory.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/PolarisCachingSpringLoadBalanceFactory.java @@ -33,7 +33,7 @@ import org.springframework.util.ConcurrentReferenceHashMap; /** * Extends CachingSpringLoadBalancerFactory to be able to create PolarisFeignLoadBalance. * - *@author lepdou 2022-05-16 + * @author lepdou 2022-05-16 */ public class PolarisCachingSpringLoadBalanceFactory extends CachingSpringLoadBalancerFactory { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/PolarisFeignLoadBalancer.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/PolarisFeignLoadBalancer.java index 76c824f62..129e9b2fd 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/PolarisFeignLoadBalancer.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/PolarisFeignLoadBalancer.java @@ -41,8 +41,7 @@ import org.springframework.util.CollectionUtils; /** * In order to pass router context for {@link com.tencent.cloud.polaris.router.PolarisLoadBalancerCompositeRule}. * - * @author lepdou 2022-05-16 - * @author cheese8 2022-06-18 + * @author lepdou, cheese8 */ public class PolarisFeignLoadBalancer extends FeignLoadBalancer { diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java index 4eb59a208..00c4fe392 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java @@ -46,8 +46,7 @@ import org.springframework.util.CollectionUtils; /** * Resolver labels from request. * - * @author lepdou 2022-05-12 - * @author cheese8 2022-06-18 + * @author lepdou, cheese8 */ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered { private static final Logger LOGGER = LoggerFactory.getLogger(RouterLabelFeignInterceptor.class); @@ -131,5 +130,4 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered return FeignExpressionLabelUtils.resolve(requestTemplate, labelKeys); } - } diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java index de474c3f1..ddb215149 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java @@ -52,7 +52,7 @@ import org.springframework.util.CollectionUtils; * PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor capabilities. * Parses the label from the request and puts it into the RouterContext for routing. * - *@author lepdou 2022-05-18 + * @author lepdou 2022-05-18 */ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor { private static final Logger LOGGER = LoggerFactory.getLogger(PolarisLoadBalancerInterceptor.class); diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientFilter.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientFilter.java index 35de57737..c46bc6e55 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientFilter.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientFilter.java @@ -49,7 +49,8 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.G /** * Replaces the default LoadBalancerClientFilter implementation. - *@author lepdou 2022-06-10 + * + * @author lepdou 2022-06-10 */ public class PolarisLoadBalancerClientFilter extends LoadBalancerClientFilter { private final static Logger LOGGER = LoggerFactory.getLogger(PolarisLoadBalancerClientFilter.class); diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisLoadBalancerCompositeRuleTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisLoadBalancerCompositeRuleTest.java index 0d55e9cde..4caf5d08e 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisLoadBalancerCompositeRuleTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisLoadBalancerCompositeRuleTest.java @@ -69,12 +69,14 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; /** - * test for {@link PolarisLoadBalancerCompositeRule} - *@author lepdou 2022-05-26 + * test for {@link PolarisLoadBalancerCompositeRule}. + * + * @author lepdou 2022-05-26 */ @RunWith(MockitoJUnitRunner.class) public class PolarisLoadBalancerCompositeRuleTest { + private static AtomicBoolean initTransitiveMetadata = new AtomicBoolean(false); @Mock private PolarisLoadBalancerProperties polarisLoadBalancerProperties; @Mock @@ -85,11 +87,7 @@ public class PolarisLoadBalancerCompositeRuleTest { private PolarisRuleBasedRouterProperties polarisRuleBasedRouterProperties; @Mock private RouterAPI routerAPI; - private IClientConfig config; - - private static AtomicBoolean initTransitiveMetadata = new AtomicBoolean(false); - private String testNamespace = "testNamespace"; private String testCallerService = "testCallerService"; private String testCalleeService = "testCalleeService"; diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterContextTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterContextTest.java index 2a8d38752..0f2094233 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterContextTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterContextTest.java @@ -25,9 +25,9 @@ import org.junit.Assert; import org.junit.Test; /** - * test for {@link PolarisRouterContext} + * test for {@link PolarisRouterContext}. * - *@author lepdou 2022-05-26 + * @author lepdou 2022-05-26 */ public class PolarisRouterContextTest { diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java index 26c1dfb13..a910473ac 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java @@ -38,18 +38,18 @@ import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.Mockito.when; /** - * test for {@link RouterRuleLabelResolver} - *@author lepdou 2022-05-26 + * test for {@link RouterRuleLabelResolver}. + * + * @author lepdou 2022-05-26 */ @RunWith(MockitoJUnitRunner.class) public class RouterRuleLabelResolverTest { - @Mock - private ServiceRuleManager serviceRuleManager; - private final String testNamespace = "testNamespace"; private final String testSourceService = "sourceService"; private final String testDstService = "dstService"; + @Mock + private ServiceRuleManager serviceRuleManager; @Test public void test() { diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/SimpleLoadBalancerTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/SimpleLoadBalancerTest.java index 36e512b4c..316539095 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/SimpleLoadBalancerTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/SimpleLoadBalancerTest.java @@ -27,8 +27,9 @@ import org.junit.Test; import org.mockito.Mockito; /** - * test for {@link SimpleLoadBalancer} - *@author lepdou 2022-05-26 + * test for {@link SimpleLoadBalancer}. + * + * @author lepdou 2022-05-26 */ public class SimpleLoadBalancerTest { diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtilsTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtilsTest.java index 6078be75c..fa9086d5d 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtilsTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/FeignExpressionLabelUtilsTest.java @@ -30,8 +30,9 @@ import org.junit.Test; import org.springframework.util.StringUtils; /** - * Test for {@link FeignExpressionLabelUtils} - *@author lepdou 2022-05-26 + * Test for {@link FeignExpressionLabelUtils}. + * + * @author lepdou 2022-05-26 */ public class FeignExpressionLabelUtilsTest { diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/PolarisCachingSpringLoadBalanceFactoryTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/PolarisCachingSpringLoadBalanceFactoryTest.java index c259e3b60..f84dec3eb 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/PolarisCachingSpringLoadBalanceFactoryTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/PolarisCachingSpringLoadBalanceFactoryTest.java @@ -37,18 +37,18 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** - * Test for {@link PolarisCachingSpringLoadBalanceFactory} - *@author lepdou 2022-05-26 + * Test for {@link PolarisCachingSpringLoadBalanceFactory}. + * + * @author lepdou 2022-05-26 */ @RunWith(MockitoJUnitRunner.class) public class PolarisCachingSpringLoadBalanceFactoryTest { + private final String service1 = "service1"; + private final String service2 = "service2"; @Mock private SpringClientFactory factory; - private String service1 = "service1"; - private String service2 = "service2"; - @Test public void test() { PolarisCachingSpringLoadBalanceFactory polarisCachingSpringLoadBalanceFactory = diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/PolarisFeignLoadBalancerTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/PolarisFeignLoadBalancerTest.java index 52be650b6..5feda8a90 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/PolarisFeignLoadBalancerTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/PolarisFeignLoadBalancerTest.java @@ -46,7 +46,8 @@ import org.springframework.cloud.netflix.ribbon.ServerIntrospector; import static org.mockito.Mockito.anyString; /** - * test for {@link PolarisFeignLoadBalancer} + * test for {@link PolarisFeignLoadBalancer}. + * * @author lepdou 2022-05-26 */ @RunWith(MockitoJUnitRunner.class) @@ -73,7 +74,8 @@ public class PolarisFeignLoadBalancerTest { // mock ApplicationContextAwareUtils#getProperties try (MockedStatic mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class)) { - mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())).thenReturn("unit-test"); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("unit-test"); MetadataContext metadataContext = Mockito.mock(MetadataContext.class); // mock MetadataContextHolder#get @@ -105,8 +107,8 @@ public class PolarisFeignLoadBalancerTest { // mock ApplicationContextAwareUtils#getProperties try (MockedStatic mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class)) { - mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())).thenReturn("unit-test"); - + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("unit-test"); MetadataContext metadataContext = Mockito.mock(MetadataContext.class); // mock MetadataContextHolder#get try (MockedStatic mockedMetadataContextHolder = Mockito.mockStatic(MetadataContextHolder.class)) { diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java index 16f15c372..f2db4641e 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java @@ -50,9 +50,9 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; /** - * test for {@link RouterLabelFeignInterceptor} - * @author lepdou 2022-05-26 - * @author cheese8 2022-06-18 + * test for {@link RouterLabelFeignInterceptor}. + * + * @author lepdou, cheese8 */ @RunWith(MockitoJUnitRunner.class) public class RouterLabelFeignInterceptorTest { @@ -67,8 +67,7 @@ public class RouterLabelFeignInterceptorTest { @Test public void testResolveRouterLabel() { RouterLabelFeignInterceptor routerLabelFeignInterceptor = new RouterLabelFeignInterceptor( - Collections.singletonList(routerLabelResolver), - metadataLocalProperties, routerRuleLabelResolver); + Collections.singletonList(routerLabelResolver), metadataLocalProperties, routerRuleLabelResolver); // mock request template RequestTemplate requestTemplate = new RequestTemplate(); @@ -122,7 +121,8 @@ public class RouterLabelFeignInterceptorTest { Map routerLabelsMap = new HashMap<>(); try { String routerLabelContent = routerLabels.stream().findFirst().get(); - routerLabelsMap.putAll(JacksonUtils.deserialize2Map(URLDecoder.decode(routerLabelContent, StandardCharsets.UTF_8.name()))); + routerLabelsMap.putAll(JacksonUtils.deserialize2Map( + URLDecoder.decode(routerLabelContent, StandardCharsets.UTF_8.name()))); } catch (UnsupportedEncodingException e) { throw new RuntimeException("unsupported charset exception " + StandardCharsets.UTF_8.name()); diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java index 18229efa6..1bc65659e 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java @@ -39,7 +39,8 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory; import static org.mockito.Mockito.when; /** - * Test for ${@link LoadBalancerInterceptorBeanPostProcessor} + * Test for ${@link LoadBalancerInterceptorBeanPostProcessor}. + * * @author lepdou 2022-05-26 */ @RunWith(MockitoJUnitRunner.class) diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java index edbe8f240..0514c5b6b 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java @@ -59,7 +59,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** - * test for {@link PolarisLoadBalancerInterceptor} + * test for {@link PolarisLoadBalancerInterceptor}. + * * @author lepdou 2022-05-26 */ @RunWith(MockitoJUnitRunner.class) @@ -196,8 +197,10 @@ public class PolarisLoadBalancerInterceptorTest { try (MockedStatic mockedMetadataContextHolder = Mockito.mockStatic(MetadataContextHolder.class)) { mockedMetadataContextHolder.when(MetadataContextHolder::get).thenReturn(metadataContext); - PolarisLoadBalancerInterceptor polarisLoadBalancerInterceptor = new PolarisLoadBalancerInterceptor(loadBalancerClient, - loadBalancerRequestFactory, Collections.singletonList(routerLabelResolver), metadataLocalProperties, routerRuleLabelResolver); + PolarisLoadBalancerInterceptor polarisLoadBalancerInterceptor = + new PolarisLoadBalancerInterceptor(loadBalancerClient, loadBalancerRequestFactory, + Collections.singletonList(routerLabelResolver), metadataLocalProperties, + routerRuleLabelResolver); PolarisRouterContext routerContext = polarisLoadBalancerInterceptor.genRouterContext(request, null, calleeService); @@ -219,7 +222,7 @@ public class PolarisLoadBalancerInterceptorTest { static class MockedLoadBalancerRequest implements LoadBalancerRequest { @Override - public T apply(ServiceInstance instance) throws Exception { + public T apply(ServiceInstance instance) { return null; } } diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientFilterTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientFilterTest.java index 6010689af..b4c22b04f 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientFilterTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientFilterTest.java @@ -57,12 +57,17 @@ import static org.mockito.Mockito.when; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; /** - * test for ${@link PolarisLoadBalancerClientFilter} - *@author lepdou 2022-06-13 + * test for ${@link PolarisLoadBalancerClientFilter}. + * + * @author lepdou 2022-06-13 */ @RunWith(MockitoJUnitRunner.class) public class PolarisLoadBalancerClientFilterTest { + private static final String callerService = "callerService"; + private static final String calleeService = "calleeService"; + private static MockedStatic mockedApplicationContextAwareUtils; + private static MockedStatic mockedMetadataContextHolder; @Mock private MetadataLocalProperties metadataLocalProperties; @Mock @@ -74,12 +79,6 @@ public class PolarisLoadBalancerClientFilterTest { @Mock private LoadBalancerProperties loadBalancerProperties; - private static final String callerService = "callerService"; - private static final String calleeService = "calleeService"; - - private static MockedStatic mockedApplicationContextAwareUtils; - private static MockedStatic mockedMetadataContextHolder; - @BeforeClass public static void beforeClass() { mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java index 71ce1e886..41ed7544a 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java @@ -61,7 +61,5 @@ public final class ContextConstant { * Order of configuration modifier. */ public static Integer CONFIG_ORDER = 1; - } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java index d45c71568..09e17e1e8 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java @@ -39,14 +39,12 @@ public final class MetadataConstant { /** * Order of MetadataFirstFeignInterceptor. */ - public static int METADATA_FIRST_FEIGN_INTERCEPTOR_ORDER = Ordered.HIGHEST_PRECEDENCE - + 1; + public static int METADATA_FIRST_FEIGN_INTERCEPTOR_ORDER = Ordered.HIGHEST_PRECEDENCE + 1; /** * Order of Metadata2HeaderInterceptor. */ public static int METADATA_2_HEADER_INTERCEPTOR_ORDER = Ordered.LOWEST_PRECEDENCE; - } /** @@ -68,7 +66,5 @@ public final class MetadataConstant { * Metadata context. */ public static final String METADATA_CONTEXT = "SCT-METADATA-CONTEXT"; - } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java index 90148cd22..c172e4832 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java @@ -52,30 +52,25 @@ public class MetadataContext { public static String LOCAL_SERVICE; static { - String namespace = ApplicationContextAwareUtils - .getProperties("spring.cloud.polaris.namespace"); + String namespace = ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.namespace"); if (StringUtils.isEmpty(namespace)) { namespace = ApplicationContextAwareUtils .getProperties("spring.cloud.polaris.discovery.namespace", "default"); } - if (StringUtils.isEmpty(namespace)) { LOG.error("namespace should not be blank. please configure spring.cloud.polaris.namespace or " + "spring.cloud.polaris.discovery.namespace"); throw new RuntimeException("namespace should not be blank. please configure spring.cloud.polaris.namespace or " + "spring.cloud.polaris.discovery.namespace"); } - LOCAL_NAMESPACE = namespace; - String serviceName = ApplicationContextAwareUtils - .getProperties("spring.cloud.polaris.service"); + String serviceName = ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.service"); if (StringUtils.isEmpty(serviceName)) { serviceName = ApplicationContextAwareUtils.getProperties( "spring.cloud.polaris.discovery.service", ApplicationContextAwareUtils .getProperties("spring.application.name", null)); } - if (StringUtils.isEmpty(serviceName)) { LOG.error("service name should not be blank. please configure spring.cloud.polaris.service or " + "spring.cloud.polaris.discovery.service or spring.application.name"); @@ -91,7 +86,6 @@ public class MetadataContext { this.fragmentContexts = new ConcurrentHashMap<>(); } - public Map getFragmentContext(String fragment) { Map fragmentContext = fragmentContexts.get(fragment); if (fragmentContext == null) { diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java index b270c368b..e92c526b3 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java @@ -89,7 +89,8 @@ public final class MetadataContextHolder { // Save transitive metadata to ThreadLocal. if (!CollectionUtils.isEmpty(dynamicTransitiveMetadata)) { - Map staticTransitiveMetadata = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + Map staticTransitiveMetadata = + metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); Map mergedTransitiveMetadata = new HashMap<>(); mergedTransitiveMetadata.putAll(staticTransitiveMetadata); mergedTransitiveMetadata.putAll(dynamicTransitiveMetadata); @@ -106,5 +107,4 @@ public final class MetadataContextHolder { public static void remove() { METADATA_CONTEXT.remove(); } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java index 5d4143b73..a717db436 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java @@ -35,18 +35,9 @@ import org.springframework.util.CollectionUtils; /** * manage metadata from env/config file/custom spi. * - *@author lepdou 2022-05-20 + * @author lepdou 2022-05-20 */ public class StaticMetadataManager { - private static final Logger LOGGER = LoggerFactory.getLogger(StaticMetadataManager.class); - - private static final String ENV_METADATA_PREFIX = "SCT_METADATA_CONTENT_"; - private static final int ENV_METADATA_PREFIX_LENGTH = ENV_METADATA_PREFIX.length(); - private static final String ENV_METADATA_CONTENT_TRANSITIVE = "SCT_METADATA_CONTENT_TRANSITIVE"; - private static final String ENV_METADATA_ZONE = "SCT_METADATA_ZONE"; - private static final String ENV_METADATA_REGION = "SCT_METADATA_REGION"; - private static final String ENV_METADATA_CAMPUS = "SCT_METADATA_CAMPUS"; - /** * the metadata key of region. */ @@ -59,7 +50,13 @@ public class StaticMetadataManager { * the metadata key of campus/datacenter. */ public static final String LOCATION_KEY_CAMPUS = "campus"; - + private static final Logger LOGGER = LoggerFactory.getLogger(StaticMetadataManager.class); + private static final String ENV_METADATA_PREFIX = "SCT_METADATA_CONTENT_"; + private static final int ENV_METADATA_PREFIX_LENGTH = ENV_METADATA_PREFIX.length(); + private static final String ENV_METADATA_CONTENT_TRANSITIVE = "SCT_METADATA_CONTENT_TRANSITIVE"; + private static final String ENV_METADATA_ZONE = "SCT_METADATA_ZONE"; + private static final String ENV_METADATA_REGION = "SCT_METADATA_REGION"; + private static final String ENV_METADATA_CAMPUS = "SCT_METADATA_CAMPUS"; private Map envMetadata; private Map envTransitiveMetadata; private Map configMetadata; diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java index 0271297ea..6f815f2ea 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java @@ -62,7 +62,5 @@ public class MetadataAutoConfiguration { public GlobalFilter metadataFirstScgFilter() { return new MetadataFirstScgFilter(); } - } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java index e65a80ccd..0d0039bc3 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java @@ -64,5 +64,4 @@ public class MetadataLocalProperties { public void setTransitive(List transitive) { this.transitive = transitive; } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/filter/gateway/MetadataFirstScgFilter.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/filter/gateway/MetadataFirstScgFilter.java index a79ba5323..e73c2bf70 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/filter/gateway/MetadataFirstScgFilter.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/filter/gateway/MetadataFirstScgFilter.java @@ -50,16 +50,13 @@ public class MetadataFirstScgFilter implements GlobalFilter, Ordered { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { // get metadata of current thread - MetadataContext metadataContext = exchange - .getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT); + MetadataContext metadataContext = exchange.getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT); if (metadataContext == null) { metadataContext = MetadataContextHolder.get(); } - exchange.getAttributes().put(MetadataConstant.HeaderName.METADATA_CONTEXT, - metadataContext); + exchange.getAttributes().put(MetadataConstant.HeaderName.METADATA_CONTEXT, metadataContext); return chain.filter(exchange); } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.java index ce244db00..72693807a 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.java @@ -89,5 +89,4 @@ public class PolarisServiceInstance implements ServiceInstance { public String getScheme() { return this.scheme; } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/InstanceMetadataProvider.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/InstanceMetadataProvider.java index dd5f03e16..5434aa140 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/InstanceMetadataProvider.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/InstanceMetadataProvider.java @@ -23,8 +23,8 @@ import java.util.Map; import java.util.Set; /** - * * Instance's custom metadata, metadata will be register to polaris server. + * * @author lepdou 2022-06-16 */ public interface InstanceMetadataProvider { diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java index 0bda18cde..a27da82e8 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java @@ -50,5 +50,4 @@ public final class AddressUtils { } return addressList; } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java index 9c6aff74d..3ad05568a 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java @@ -63,5 +63,4 @@ public class ApplicationContextAwareUtils implements ApplicationContextAware { public static String getProperties(String key, String defaultValue) { return applicationContext.getEnvironment().getProperty(key, defaultValue); } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java index 715a154fc..a15febe0e 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java @@ -30,7 +30,11 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory; * the utils for bean factory. * @author lepdou 2022-05-23 */ -public class BeanFactoryUtils { +public final class BeanFactoryUtils { + + private BeanFactoryUtils() { + + } public static List getBeans(BeanFactory beanFactory, Class requiredType) { if (!(beanFactory instanceof DefaultListableBeanFactory)) { diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java index a4c53ccc1..dde5bc254 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java @@ -43,7 +43,7 @@ import org.springframework.web.server.ServerWebExchange; * @author lepdou 2022-05-13 * @author cheese8 2022-06-20 */ -public class ExpressionLabelUtils { +public final class ExpressionLabelUtils { /** * the expression prefix of header label. @@ -81,6 +81,8 @@ public class ExpressionLabelUtils { * the suffix of expression. */ public static final String LABEL_SUFFIX = "}"; + private ExpressionLabelUtils() { + } public static boolean isExpressionLabel(String labelKey) { if (StringUtils.isEmpty(labelKey)) { diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java index 2b55f102a..6df2029f4 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java @@ -83,5 +83,4 @@ public final class JacksonUtils { throw new RuntimeException("Json to map failed.", e); } } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java index 6c4a3353e..398fb205b 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java @@ -48,5 +48,4 @@ public final class ReflectionUtils { } return null; } - } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ResourceFileUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ResourceFileUtils.java index b5ea45d5d..66f8ae6c6 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ResourceFileUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ResourceFileUtils.java @@ -46,5 +46,4 @@ public final class ResourceFileUtils { } return ""; } - } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java index 9695b4d48..f2073f21a 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java @@ -37,7 +37,8 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = MetadataContextHolderTest.TestApplication.class, - properties = { "spring.config.location = classpath:application-test.yml", "spring.main.web-application-type = reactive" }) + properties = {"spring.config.location = classpath:application-test.yml", + "spring.main.web-application-type = reactive"}) public class MetadataContextHolderTest { @Test @@ -78,5 +79,4 @@ public class MetadataContextHolderTest { protected static class TestApplication { } - } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java index 3c8ae438d..b2aa08cd4 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java @@ -182,5 +182,4 @@ public class StaticMetadataManagerTest { return null; } } - } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java index fb19efb18..e73ee3a2b 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java @@ -38,7 +38,8 @@ public class MetadataAutoConfigurationTest { private final WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner(); - private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = new ReactiveWebApplicationContextRunner(); + private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = + new ReactiveWebApplicationContextRunner(); /** * No any web application. @@ -84,5 +85,4 @@ public class MetadataAutoConfigurationTest { Assertions.assertThat(context).hasSingleBean(MetadataFirstScgFilter.class); }); } - } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataLocalPropertiesTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataLocalPropertiesTest.java index 3fdb2f441..a4a9a4e29 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataLocalPropertiesTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataLocalPropertiesTest.java @@ -34,7 +34,8 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = MetadataLocalPropertiesTest.TestApplication.class, - properties = { "spring.config.location = classpath:application-test.yml", "spring.main.web-application-type = reactive" }) + properties = {"spring.config.location = classpath:application-test.yml", + "spring.main.web-application-type = reactive"}) public class MetadataLocalPropertiesTest { @Autowired @@ -59,5 +60,4 @@ public class MetadataLocalPropertiesTest { protected static class TestApplication { } - } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/AddressUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/AddressUtilsTest.java index 8040e7add..ca50c3604 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/AddressUtilsTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/AddressUtilsTest.java @@ -26,8 +26,9 @@ import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; /** - * test for {@link AddressUtils} - *@author lepdou 2022-05-27 + * test for {@link AddressUtils}. + * + * @author lepdou 2022-05-27 */ @RunWith(MockitoJUnitRunner.class) public class AddressUtilsTest { diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java index 0dedc4698..76666482b 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java @@ -37,9 +37,9 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.server.MockServerWebExchange; /** - * test for {@link ExpressionLabelUtils} - * @author lepdou 2022-05-27 - * @auther cheese8 2022-06-20 + * test for {@link ExpressionLabelUtils}. + * + * @author lepdou 2022-05-27, cheese8 */ @RunWith(MockitoJUnitRunner.class) public class ExpressionLabelUtilsTest { @@ -210,5 +210,4 @@ public class ExpressionLabelUtilsTest { Assert.assertNull(result.get(invalidLabel8)); Assert.assertNull(result.get(invalidLabel9)); } - } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ResourceFileUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ResourceFileUtilsTest.java index 769d99ce7..a3cb8a96c 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ResourceFileUtilsTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ResourceFileUtilsTest.java @@ -26,8 +26,9 @@ import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; /** - * test for {@link ResourceFileUtils} - *@author lepdou 2022-05-27 + * test for {@link ResourceFileUtils}. + * + * @author lepdou 2022-05-27 */ @RunWith(MockitoJUnitRunner.class) public class ResourceFileUtilsTest { diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCallerService.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCallerService.java index a586c7e72..ae1e49c64 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCallerService.java +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCallerService.java @@ -19,7 +19,6 @@ package com.tencent.cloud.metadata.service.caller; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; @@ -31,7 +30,6 @@ import org.springframework.web.client.RestTemplate; * @author Palmer Xu */ @SpringBootApplication -@EnableDiscoveryClient @EnableFeignClients public class MetadataCallerService { diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerService.java b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerService.java index 55fcf01ac..0eae4b427 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerService.java +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerService.java @@ -19,7 +19,6 @@ package com.tencent.cloud.polaris.discovery.service.caller; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; @@ -31,7 +30,6 @@ import org.springframework.web.client.RestTemplate; * @author Haotian Zhang */ @SpringBootApplication -@EnableDiscoveryClient @EnableFeignClients public class DiscoveryCallerService { diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/resources/bootstrap.yml index 0ed6cb16c..133406e02 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/resources/bootstrap.yml @@ -1,6 +1,6 @@ server: session-timeout: 1800 - port: 48082 + port: 48084 spring: application: name: GatewayZuulService diff --git a/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/java/com/tencent/cloud/polaris/router/example/RouterCallerApplication.java b/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/java/com/tencent/cloud/polaris/router/example/RouterCallerApplication.java index 824a1226f..ac0547a71 100644 --- a/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/java/com/tencent/cloud/polaris/router/example/RouterCallerApplication.java +++ b/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/java/com/tencent/cloud/polaris/router/example/RouterCallerApplication.java @@ -20,7 +20,6 @@ package com.tencent.cloud.polaris.router.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; @@ -32,7 +31,6 @@ import org.springframework.web.client.RestTemplate; * @author lepdou 2022-04-06 */ @SpringBootApplication -@EnableDiscoveryClient @EnableFeignClients public class RouterCallerApplication { diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-frontend/src/main/java/com/tencent/cloud/polaris/router/grayrelease/front/GrayReleaseFrontApplication.java b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-frontend/src/main/java/com/tencent/cloud/polaris/router/grayrelease/front/GrayReleaseFrontApplication.java index 6d8653eeb..79948b3e7 100644 --- a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-frontend/src/main/java/com/tencent/cloud/polaris/router/grayrelease/front/GrayReleaseFrontApplication.java +++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-frontend/src/main/java/com/tencent/cloud/polaris/router/grayrelease/front/GrayReleaseFrontApplication.java @@ -19,11 +19,9 @@ package com.tencent.cloud.polaris.router.grayrelease.front; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication -@EnableDiscoveryClient @EnableFeignClients public class GrayReleaseFrontApplication { diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-gateway/src/main/java/com/tencent/cloud/polaris/router/grayrelease/gateway/GrayReleaseGatewayApplication.java b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-gateway/src/main/java/com/tencent/cloud/polaris/router/grayrelease/gateway/GrayReleaseGatewayApplication.java index a7b5a115e..77819ea41 100644 --- a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-gateway/src/main/java/com/tencent/cloud/polaris/router/grayrelease/gateway/GrayReleaseGatewayApplication.java +++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-gateway/src/main/java/com/tencent/cloud/polaris/router/grayrelease/gateway/GrayReleaseGatewayApplication.java @@ -19,11 +19,9 @@ package com.tencent.cloud.polaris.router.grayrelease.gateway; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication -@EnableDiscoveryClient @EnableFeignClients public class GrayReleaseGatewayApplication { diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-middle/src/main/java/com/tencent/cloud/polaris/router/grayrelease/middle/GrayReleaseMiddleApplication.java b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-middle/src/main/java/com/tencent/cloud/polaris/router/grayrelease/middle/GrayReleaseMiddleApplication.java index 4857030e2..3003093ee 100644 --- a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-middle/src/main/java/com/tencent/cloud/polaris/router/grayrelease/middle/GrayReleaseMiddleApplication.java +++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-middle/src/main/java/com/tencent/cloud/polaris/router/grayrelease/middle/GrayReleaseMiddleApplication.java @@ -19,11 +19,9 @@ package com.tencent.cloud.polaris.router.grayrelease.middle; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication -@EnableDiscoveryClient @EnableFeignClients public class GrayReleaseMiddleApplication { diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ModifyAddress.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ModifyAddress.java index b57cbfe91..a7a1e551c 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ModifyAddress.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ModifyAddress.java @@ -53,5 +53,4 @@ public class ModifyAddress implements PolarisConfigModifier { public int getOrder() { return ContextConstant.ModifierOrder.FIRST; } - } diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java index 0152b7b6b..3cae11cb2 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java @@ -37,5 +37,4 @@ public interface PolarisConfigModifier { * @return order */ int getOrder(); - } diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PostInitPolarisSDKContext.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PostInitPolarisSDKContext.java index 014ca5ba2..bf41c50bd 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PostInitPolarisSDKContext.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PostInitPolarisSDKContext.java @@ -26,7 +26,8 @@ import org.apache.commons.lang.StringUtils; /** * After all configurations are loaded, post-initialize SDKContext. - *@author lepdou 2022-06-28 + * + * @author lepdou 2022-06-28 */ public class PostInitPolarisSDKContext { diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ServiceRuleManager.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ServiceRuleManager.java index 1a0af32b4..06d71f65c 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ServiceRuleManager.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/ServiceRuleManager.java @@ -38,7 +38,7 @@ import com.tencent.polaris.client.pb.RoutingProto; /** * the manager of service governance rules. for example: rate limit rule, router rules. * - *@author lepdou 2022-05-13 + * @author lepdou 2022-05-13 */ public class ServiceRuleManager { diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextPostConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextPostConfiguration.java index f55397462..3ee8de395 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextPostConfiguration.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextPostConfiguration.java @@ -27,13 +27,15 @@ import org.springframework.context.annotation.Configuration; /** * Post-initialization operations after the application initialization phase is completed. - *@author lepdou 2022-06-28 + * + * @author lepdou 2022-06-28 */ @Configuration public class PolarisContextPostConfiguration { @Bean - public PostInitPolarisSDKContext postInitPolarisSDKContext(SDKContext sdkContext, StaticMetadataManager staticMetadataManager) { + public PostInitPolarisSDKContext postInitPolarisSDKContext( + SDKContext sdkContext, StaticMetadataManager staticMetadataManager) { return new PostInitPolarisSDKContext(sdkContext, staticMetadataManager); } } diff --git a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextAutoConfigurationTest.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextAutoConfigurationTest.java index 2a926cc12..21e0868b3 100644 --- a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextAutoConfigurationTest.java +++ b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextAutoConfigurationTest.java @@ -27,6 +27,8 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.cloud.commons.util.UtilAutoConfiguration; /** + * Test for {@link PolarisContextAutoConfiguration}. + * * @author liaochuntao */ public class PolarisContextAutoConfigurationTest { @@ -44,5 +46,4 @@ public class PolarisContextAutoConfigurationTest { Assert.assertNotNull(sdkContext); }); } - } diff --git a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java index 9985113df..1bf745f5c 100644 --- a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java +++ b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java @@ -49,5 +49,4 @@ public class PolarisContextGetHostTest { Assert.assertEquals(bindIP, "192.168.1.1"); Assert.assertEquals(polarisContextProperties.getNamespace(), "dev"); } - } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtils.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtils.java index d7295447e..c30da7cff 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtils.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtils.java @@ -32,9 +32,12 @@ import com.tencent.polaris.api.pojo.ServiceKey; /** * load balancer utils. * - *@author lepdou 2022-05-17 + * @author lepdou 2022-05-17 */ -public class LoadBalancerUtils { +public final class LoadBalancerUtils { + + private LoadBalancerUtils() { + } public static ServiceInstances transferServersToServiceInstances(List servers) { List instances = new ArrayList<>(servers.size()); diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java index 5f83c5aec..d1c4e3ae1 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java @@ -136,5 +136,4 @@ public class PolarisLoadBalancer extends DynamicServerListLoadBalancer { request.setService(serviceName); return consumerAPI.getHealthyInstances(request); } - } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisWeightedRule.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisWeightedRule.java index 124085717..31278f558 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisWeightedRule.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisWeightedRule.java @@ -36,7 +36,7 @@ import org.springframework.util.CollectionUtils; /** * Polaris weighted load balancer. * - *@author lepdou 2022-05-17 + * @author lepdou 2022-05-17 */ public class PolarisWeightedRule extends AbstractLoadBalancerRule { diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerProperties.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerProperties.java index 9d4d06059..00b5fe4f2 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerProperties.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerProperties.java @@ -73,5 +73,4 @@ public class PolarisLoadBalancerProperties { return "PolarisLoadBalancerProperties{" + "loadbalancerEnabled=" + enabled + ", strategy='" + strategy + '\'' + '}'; } - } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java index 3fbc2c76d..75b684da4 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java @@ -45,5 +45,4 @@ public class PolarisRibbonClientConfiguration { return new PolarisLoadBalancer(iClientConfig, iRule, iPing, serverList, consumerAPI, polarisLoadBalancerProperties); } - } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java index d1111dd02..5004959f7 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java @@ -115,5 +115,4 @@ public class PolarisLoadBalancerAutoConfigurationTest { } } - } diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index ace6b329d..452aaa5f7 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -4,6 +4,5 @@ "https://www.puppycrawl.com/dtds/suppressions_1_1.dtd"> - \ No newline at end of file From d10752a70d9a1658cc58bd8445f39eb2a393c51a Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Mon, 4 Jul 2022 16:48:28 +0800 Subject: [PATCH 14/14] docs:optimize example (#385) --- CHANGELOG.md | 1 + .../polaris/circuitbreaker/example/ServiceA.java | 3 +-- .../example/ServiceAController.java | 1 - .../polaris/circuitbreaker/example/ServiceB.java | 3 +-- .../example/ServiceBController.java | 12 +----------- .../src/main/resources/bootstrap.yml | 1 - .../polaris/ciruitbreaker/example/ServiceB2.java | 3 +-- .../ciruitbreaker/example/ServiceBController.java | 15 ++++----------- .../src/main/resources/bootstrap.yml | 1 - .../src/main/resources/bootstrap.yml | 2 +- 10 files changed, 10 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0f181d38..53c7d3354 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,3 +36,4 @@ - [docs: Fix javadoc
error](https://github.com/Tencent/spring-cloud-tencent/pull/371) - [UT: add Polaris LoadBalancer unit test](https://github.com/Tencent/spring-cloud-tencent/pull/373) - [docs:update docs](https://github.com/Tencent/spring-cloud-tencent/pull/378) +- [docs:optimize example](https://github.com/Tencent/spring-cloud-tencent/pull/385) diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java index 1c96db6c9..3db7df8f3 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java @@ -35,7 +35,7 @@ import org.springframework.web.client.RestTemplate; public class ServiceA { public static void main(String[] args) { - SpringApplication.run(ServiceA.class); + SpringApplication.run(ServiceA.class, args); } @Bean @@ -43,5 +43,4 @@ public class ServiceA { public RestTemplate restTemplate() { return new RestTemplate(); } - } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java index 29768d584..79ba2c0ef 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java @@ -64,5 +64,4 @@ public class ServiceAController { String.class); return entity.getBody(); } - } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java index 7354da537..c8c32bf24 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java @@ -29,7 +29,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; public class ServiceB { public static void main(String[] args) { - SpringApplication.run(ServiceB.class); + SpringApplication.run(ServiceB.class, args); } - } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java index 67540c2c9..99b8410d8 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java @@ -18,7 +18,6 @@ package com.tencent.cloud.polaris.circuitbreaker.example; -import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -32,21 +31,12 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/example/service/b") public class ServiceBController { - @Value("${is-throw-runtime-exception:#{false}}") - private boolean isThrowRuntimeException; - /** * Get service information. * @return service information */ @GetMapping("/info") public String info() { - if (isThrowRuntimeException) { - throw new RuntimeException("failed for call my service"); - } - else { - return "hello world ! I'm a service B1"; - } + return "hello world ! I'm a service B1"; } - } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml index 4aba50500..3805dfa5e 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml @@ -8,4 +8,3 @@ spring: address: grpc://183.47.111.80:8091 namespace: default enabled: true -is-throw-runtime-exception: false diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java index 4aacc0d22..fb6bdc687 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java @@ -30,7 +30,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; public class ServiceB2 { public static void main(String[] args) { - SpringApplication.run(ServiceB2.class); + SpringApplication.run(ServiceB2.class, args); } - } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java index 7e4bb9b4c..83dc45303 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java @@ -18,9 +18,10 @@ package com.tencent.cloud.polaris.ciruitbreaker.example; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; /** @@ -32,21 +33,13 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/example/service/b") public class ServiceBController { - @Value("${is-throw-runtime-exception:#{false}}") - private boolean isThrowRuntimeException; - /** * Get service information. * @return service information */ @GetMapping("/info") + @ResponseStatus(value = HttpStatus.BAD_GATEWAY, reason = "failed for call my service") public String info() { - if (isThrowRuntimeException) { - throw new RuntimeException("failed for call my service"); - } - else { - return "hello world ! I'm a service B2"; - } + return "failed for call service B2"; } - } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/resources/bootstrap.yml index b150a5424..f3720f09c 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/resources/bootstrap.yml @@ -8,4 +8,3 @@ spring: address: grpc://183.47.111.80:8091 namespace: default enabled: true -is-throw-runtime-exception: true diff --git a/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml index 84e44d4aa..1f257a787 100644 --- a/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml @@ -17,4 +17,4 @@ management: web: exposure: include: - - polaris-config \ No newline at end of file + - polaris-config