From 7c5f3d1cff6c52c0b38e2d65341970b35903178d Mon Sep 17 00:00:00 2001 From: qingliu Date: Wed, 20 Sep 2023 10:57:32 +0800 Subject: [PATCH 01/10] fix: change the timing of sdk context destruction. (#1123) --- .../PolarisConfigAutoConfiguration.java | 7 ------ .../PolarisContextAutoConfiguration.java | 6 +++++ ...olarisContextApplicationEventListener.java | 23 ++++++------------- 3 files changed, 13 insertions(+), 23 deletions(-) rename spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigApplicationEventListener.java => spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/listener/PolarisContextApplicationEventListener.java (66%) 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 779e29751..b0c212a14 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 @@ -27,14 +27,12 @@ import com.tencent.cloud.polaris.config.annotation.PolarisConfigAnnotationProcessor; import com.tencent.cloud.polaris.config.condition.ConditionalOnReflectRefreshType; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; -import com.tencent.cloud.polaris.config.listener.PolarisConfigApplicationEventListener; import com.tencent.cloud.polaris.config.listener.PolarisConfigChangeEventListener; import com.tencent.cloud.polaris.config.listener.PolarisConfigRefreshOptimizationListener; import com.tencent.cloud.polaris.config.logger.PolarisConfigLoggerApplicationListener; import com.tencent.cloud.polaris.config.spring.annotation.SpringValueProcessor; import com.tencent.cloud.polaris.config.spring.property.PlaceholderHelper; import com.tencent.cloud.polaris.config.spring.property.SpringValueRegistry; -import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -122,10 +120,5 @@ public PolarisConfigRefreshScopeAnnotationDetector polarisConfigRefreshScopeAnno public PolarisConfigRefreshOptimizationListener polarisConfigRefreshOptimizationListener() { return new PolarisConfigRefreshOptimizationListener(); } - - @Bean - public PolarisConfigApplicationEventListener polarisContextApplicationEventListener(PolarisSDKContextManager polarisSDKContextManager) { - return new PolarisConfigApplicationEventListener(polarisSDKContextManager); - } } } diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java index 1593fdd5f..080b0bf4f 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java @@ -25,6 +25,7 @@ import com.tencent.cloud.polaris.context.PolarisConfigModifier; import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.cloud.polaris.context.listener.PolarisContextApplicationEventListener; import com.tencent.polaris.api.exception.PolarisException; import com.tencent.polaris.client.api.SDKContext; @@ -58,4 +59,9 @@ public ModifyAddress polarisConfigModifier(PolarisContextProperties properties) public ServiceRuleManager serviceRuleManager(PolarisSDKContextManager polarisSDKContextManager) { return new ServiceRuleManager(polarisSDKContextManager.getSDKContext(), polarisSDKContextManager.getConsumerAPI()); } + + @Bean + public PolarisContextApplicationEventListener contextApplicationEventListener(PolarisSDKContextManager polarisSDKContextManager) { + return new PolarisContextApplicationEventListener(polarisSDKContextManager); + } } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigApplicationEventListener.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/listener/PolarisContextApplicationEventListener.java similarity index 66% rename from spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigApplicationEventListener.java rename to spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/listener/PolarisContextApplicationEventListener.java index 68106382c..ae753045c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigApplicationEventListener.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/listener/PolarisContextApplicationEventListener.java @@ -16,42 +16,33 @@ * */ -package com.tencent.cloud.polaris.config.listener; +package com.tencent.cloud.polaris.context.listener; import com.tencent.cloud.polaris.context.PolarisSDKContextManager; -import com.tencent.polaris.configuration.client.internal.RemoteConfigFileRepo; import org.springframework.boot.context.event.ApplicationFailedEvent; -import org.springframework.boot.context.event.ApplicationPreparedEvent; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.lang.NonNull; -/* - * Polaris config non-daemon thread stop listener - * - * @author shuiqingliu - * @since 2023/8/29 +/** + * @author frankjlli + * @since 2023/9/18 **/ -public class PolarisConfigApplicationEventListener implements ApplicationListener { + +public class PolarisContextApplicationEventListener implements ApplicationListener { private final PolarisSDKContextManager polarisSDKContextManager; - public PolarisConfigApplicationEventListener(PolarisSDKContextManager polarisSDKContextManager) { + public PolarisContextApplicationEventListener(PolarisSDKContextManager polarisSDKContextManager) { this.polarisSDKContextManager = polarisSDKContextManager; } @Override public void onApplicationEvent(@NonNull ApplicationEvent event) { - if (event instanceof ApplicationPreparedEvent) { - RemoteConfigFileRepo.registerRepoDestroyHook(polarisSDKContextManager.getSDKContext()); - } - if (event instanceof ApplicationFailedEvent) { - RemoteConfigFileRepo.registerRepoDestroyHook(polarisSDKContextManager.getSDKContext()); //implicit invoke 'destroy' when the spring application fails to start, in order to stop non-daemon threads. polarisSDKContextManager.getSDKContext().destroy(); } } - } From e51d9d2b528a5d99cbae4076269589cb11e52cae Mon Sep 17 00:00:00 2001 From: wenxuan70 <625559305@qq.com> Date: Wed, 20 Sep 2023 17:12:55 +0800 Subject: [PATCH 02/10] feat: support log path configuration parameters (#1128) Co-authored-by: Haotian Zhang <928016560@qq.com> --- CHANGELOG.md | 1 + .../PolarisLoggingApplicationListener.java | 19 ++++++++ ...itional-spring-configuration-metadata.json | 6 +++ .../PolarisLoggingPathPropertyTest.java | 43 ++++++++++++++++++ .../PolarisLoggingPathSystemPropertyTest.java | 44 +++++++++++++++++++ .../src/test/resources/bootstrap.yml | 2 + 6 files changed, 115 insertions(+) create mode 100644 spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingPathPropertyTest.java create mode 100644 spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingPathSystemPropertyTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 239001d40..c48d269d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,3 +5,4 @@ - [fix:fix feign url bug when using sleuth.](https://github.com/Tencent/spring-cloud-tencent/pull/1096) - [fix: dynamic routing using cookies.](https://github.com/Tencent/spring-cloud-tencent/pull/1097) - [Refactoring:remove invalid @AutoConfigureAfter and @AutoConfigureBefore from discovery client automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1115) +- [feat: support log path configuration parameters.](https://github.com/Tencent/spring-cloud-tencent/pull/1128) diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingApplicationListener.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingApplicationListener.java index a75087ec7..0d2c1b6f9 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingApplicationListener.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingApplicationListener.java @@ -16,7 +16,9 @@ */ package com.tencent.cloud.polaris.context.logging; +import com.tencent.polaris.logging.LoggingConsts; import com.tencent.polaris.logging.PolarisLogging; +import org.apache.commons.lang.StringUtils; import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; import org.springframework.boot.context.event.ApplicationFailedEvent; @@ -24,6 +26,7 @@ import org.springframework.context.ApplicationEvent; import org.springframework.context.event.GenericApplicationListener; import org.springframework.core.ResolvableType; +import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.lang.NonNull; /** @@ -52,6 +55,22 @@ public int getOrder() { @Override public void onApplicationEvent(@NonNull ApplicationEvent applicationEvent) { + ConfigurableEnvironment environment = null; + + if (ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(applicationEvent.getClass())) { + environment = ((ApplicationEnvironmentPreparedEvent) applicationEvent).getEnvironment(); + } + else if (ApplicationFailedEvent.class.isAssignableFrom(applicationEvent.getClass())) { + environment = ((ApplicationFailedEvent) applicationEvent).getApplicationContext().getEnvironment(); + } + + if (environment != null) { + String loggingPath = environment.getProperty("spring.cloud.polaris.logging.path"); + if (StringUtils.isNotBlank(loggingPath)) { + System.setProperty(LoggingConsts.LOGGING_PATH_PROPERTY, loggingPath); + } + } + PolarisLogging.getInstance().loadConfiguration(); } } diff --git a/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 5c0ddb2da..f3244d1fd 100644 --- a/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -45,6 +45,12 @@ "type": "java.lang.Integer", "defaultValue": "", "description": "current server local port to be registered." + }, + { + "name": "spring.cloud.polaris.logging.path", + "type": "java.lang.String", + "defaultValue": "./polaris/logs", + "description": "polaris log storage path." } ], "hints": [] diff --git a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingPathPropertyTest.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingPathPropertyTest.java new file mode 100644 index 000000000..c936f1e42 --- /dev/null +++ b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingPathPropertyTest.java @@ -0,0 +1,43 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.context.logging; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test to get spring.cloud.polaris.logging.path from environment. + * + * @author wenxuan70 + */ +public class PolarisLoggingPathPropertyTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("spring.cloud.polaris.logging.path=/tmp/polaris/logs"); + + @Test + public void testGetPropertyFromEnvironment() { + contextRunner.run(context -> { + String loggingPath = context.getEnvironment().getProperty("spring.cloud.polaris.logging.path"); + assertThat(loggingPath).isEqualTo("/tmp/polaris/logs"); + }); + } +} diff --git a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingPathSystemPropertyTest.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingPathSystemPropertyTest.java new file mode 100644 index 000000000..039c5c661 --- /dev/null +++ b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/logging/PolarisLoggingPathSystemPropertyTest.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.polaris.context.logging; + +import com.tencent.cloud.polaris.context.PolarisContextApplication; +import com.tencent.polaris.logging.LoggingConsts; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link PolarisLoggingApplicationListener} + * + * @author wenxuan70 + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PolarisContextApplication.class, + properties = {"spring.config.location=classpath:bootstrap.yml"}) +public class PolarisLoggingPathSystemPropertyTest { + + @Test + public void testSystemProperty() { + assertThat(System.getProperty(LoggingConsts.LOGGING_PATH_PROPERTY)).isEqualTo("/tmp/polaris/logs"); + } +} diff --git a/spring-cloud-tencent-polaris-context/src/test/resources/bootstrap.yml b/spring-cloud-tencent-polaris-context/src/test/resources/bootstrap.yml index c445dd227..de73a15d7 100644 --- a/spring-cloud-tencent-polaris-context/src/test/resources/bootstrap.yml +++ b/spring-cloud-tencent-polaris-context/src/test/resources/bootstrap.yml @@ -7,3 +7,5 @@ spring: service: TestApp enabled: true local-port: 9090 + logging: + path: /tmp/polaris/logs From 2c0428810571a065ba922a8f3065a48685c38c68 Mon Sep 17 00:00:00 2001 From: Hligaty <1970316213@qq.com> Date: Fri, 22 Sep 2023 10:02:31 +0800 Subject: [PATCH 03/10] refactor:optimize the order and condition matching of service registration automatic configuration. (#1129) --- CHANGELOG.md | 1 + .../PolarisServiceRegistryAutoConfiguration.java | 12 +++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c48d269d1..95aa1263e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,3 +6,4 @@ - [fix: dynamic routing using cookies.](https://github.com/Tencent/spring-cloud-tencent/pull/1097) - [Refactoring:remove invalid @AutoConfigureAfter and @AutoConfigureBefore from discovery client automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1115) - [feat: support log path configuration parameters.](https://github.com/Tencent/spring-cloud-tencent/pull/1128) +- [refactor:optimize the order and condition matching of service registration automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1129) 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 7a94378fb..1cf7a83a9 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 @@ -31,14 +31,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext; import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration; -import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; +import org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -49,10 +49,10 @@ */ @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties +@ConditionalOnBean(AutoServiceRegistrationProperties.class) @ConditionalOnPolarisRegisterEnabled -@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) -@AutoConfigureAfter({AutoServiceRegistrationConfiguration.class, AutoServiceRegistrationAutoConfiguration.class, - PolarisDiscoveryAutoConfiguration.class}) +@AutoConfigureBefore(ServiceRegistryAutoConfiguration.class) +@AutoConfigureAfter({AutoServiceRegistrationAutoConfiguration.class, PolarisDiscoveryAutoConfiguration.class}) public class PolarisServiceRegistryAutoConfiguration { @Bean @@ -65,7 +65,6 @@ public PolarisServiceRegistry polarisServiceRegistry( } @Bean - @ConditionalOnBean(AutoServiceRegistrationProperties.class) public PolarisRegistration polarisRegistration( PolarisDiscoveryProperties polarisDiscoveryProperties, PolarisContextProperties polarisContextProperties, @@ -81,7 +80,6 @@ public PolarisRegistration polarisRegistration( } @Bean - @ConditionalOnBean(AutoServiceRegistrationProperties.class) public PolarisAutoServiceRegistration polarisAutoServiceRegistration( PolarisServiceRegistry registry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, From fa88a50daecffe5b511019cc91598ab70a462500 Mon Sep 17 00:00:00 2001 From: wenxuan70 Date: Mon, 25 Sep 2023 10:17:08 +0800 Subject: [PATCH 04/10] feat: add circuit breaker actuator (#1136) --- CHANGELOG.md | 1 + .../pom.xml | 12 +++ .../PolarisCircuitBreakerEndpoint.java | 86 +++++++++++++++++++ ...rcuitBreakerEndpointAutoConfiguration.java | 49 +++++++++++ .../main/resources/META-INF/spring.factories | 3 +- .../PolarisCircuitBreakerEndpointTest.java | 84 ++++++++++++++++++ .../polaris/context/ServiceRuleManager.java | 17 +++- 7 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpoint.java create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpointAutoConfiguration.java create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpointTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 95aa1263e..241575198 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,3 +7,4 @@ - [Refactoring:remove invalid @AutoConfigureAfter and @AutoConfigureBefore from discovery client automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1115) - [feat: support log path configuration parameters.](https://github.com/Tencent/spring-cloud-tencent/pull/1128) - [refactor:optimize the order and condition matching of service registration automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1129) +- [feat: add circuit breaker actuator.](https://github.com/Tencent/spring-cloud-tencent/pull/1136) \ No newline at end of file diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml index 58a68a422..230e50a82 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml @@ -96,6 +96,18 @@ + + org.springframework.boot + spring-boot-actuator + true + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + org.springframework.boot spring-boot-starter-test diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpoint.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpoint.java new file mode 100644 index 000000000..b2ff0eeff --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpoint.java @@ -0,0 +1,86 @@ +/* + * 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.endpoint; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.util.JsonFormat; +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; + +/** + * Endpoint of polaris circuit breaker, include circuit breaker rules. + * + * @author wenxuan70 + */ +@Endpoint(id = "polaris-circuit-breaker") +public class PolarisCircuitBreakerEndpoint { + + private static final Logger LOG = LoggerFactory.getLogger(PolarisCircuitBreakerEndpoint.class); + + private final ServiceRuleManager serviceRuleManager; + + public PolarisCircuitBreakerEndpoint(ServiceRuleManager serviceRuleManager) { + this.serviceRuleManager = serviceRuleManager; + } + + @ReadOperation + public Map circuitBreaker() { + CircuitBreakerProto.CircuitBreaker circuitBreaker = serviceRuleManager.getServiceCircuitBreakerRule( + MetadataContext.LOCAL_NAMESPACE, + MetadataContext.LOCAL_SERVICE + ); + + Map polarisCircuitBreakerInfo = new HashMap<>(); + + polarisCircuitBreakerInfo.put("namespace", MetadataContext.LOCAL_NAMESPACE); + polarisCircuitBreakerInfo.put("service", MetadataContext.LOCAL_SERVICE); + polarisCircuitBreakerInfo.put("circuitBreakerRules", parseCircuitBreakerRule(circuitBreaker)); + + return polarisCircuitBreakerInfo; + } + + private List parseCircuitBreakerRule(CircuitBreakerProto.CircuitBreaker circuitBreaker) { + List circuitBreakerRuleList = new ArrayList<>(); + + for (CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule : circuitBreaker.getRulesList()) { + String ruleJson; + try { + ruleJson = JsonFormat.printer().print(circuitBreakerRule); + } + catch (InvalidProtocolBufferException e) { + LOG.error("rule to Json failed. check rule {}.", circuitBreakerRule, e); + throw new RuntimeException("Json failed.", e); + } + circuitBreakerRuleList.add(JacksonUtils.deserialize2Map(ruleJson)); + } + + return circuitBreakerRuleList; + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpointAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpointAutoConfiguration.java new file mode 100644 index 000000000..6c9073925 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpointAutoConfiguration.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.circuitbreaker.endpoint; + +import com.tencent.cloud.polaris.circuitbreaker.config.ConditionalOnPolarisCircuitBreakerEnabled; +import com.tencent.cloud.polaris.context.ServiceRuleManager; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +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 Polaris CircuitBreaker's Endpoint. + * + * @author wenxuan70 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Endpoint.class) +@ConditionalOnPolarisCircuitBreakerEnabled +public class PolarisCircuitBreakerEndpointAutoConfiguration { + + @Bean + @ConditionalOnBean(ServiceRuleManager.class) + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + public PolarisCircuitBreakerEndpoint polarisCircuitBreakerEndpoint(ServiceRuleManager serviceRuleManager) { + return new PolarisCircuitBreakerEndpoint(serviceRuleManager); + } + +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories index a873ed563..07972a65c 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories @@ -2,6 +2,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration,\ com.tencent.cloud.polaris.circuitbreaker.config.ReactivePolarisCircuitBreakerAutoConfiguration,\ com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration,\ - com.tencent.cloud.polaris.circuitbreaker.config.GatewayPolarisCircuitBreakerAutoConfiguration + com.tencent.cloud.polaris.circuitbreaker.config.GatewayPolarisCircuitBreakerAutoConfiguration,\ + com.tencent.cloud.polaris.circuitbreaker.endpoint.PolarisCircuitBreakerEndpointAutoConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpointTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpointTest.java new file mode 100644 index 000000000..23913957e --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/endpoint/PolarisCircuitBreakerEndpointTest.java @@ -0,0 +1,84 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.circuitbreaker.endpoint; + +import java.util.Map; + +import com.google.protobuf.StringValue; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; +import com.tencent.polaris.specification.api.v1.model.ModelProto; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Test for {@link PolarisCircuitBreakerEndpoint}. + * + * @author wenxuan70 + */ +@ExtendWith(MockitoExtension.class) +public class PolarisCircuitBreakerEndpointTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withBean(ApplicationContextAwareUtils.class) + .withPropertyValues("spring.cloud.polaris.namespace=" + NAMESPACE_TEST) + .withPropertyValues("spring.cloud.polaris.service=" + SERVICE_PROVIDER); + + private ServiceRuleManager serviceRuleManager; + + @BeforeEach + void setUp() { + serviceRuleManager = mock(ServiceRuleManager.class); + when(serviceRuleManager.getServiceCircuitBreakerRule(anyString(), anyString())).thenAnswer(invocation -> { + CircuitBreakerProto.CircuitBreakerRule.Builder ruleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); + ruleBuilder.setName("test_for_circuit_breaker"); + ruleBuilder.setEnable(true); + ruleBuilder.setLevel(CircuitBreakerProto.Level.METHOD); + CircuitBreakerProto.RuleMatcher.Builder rmBuilder = CircuitBreakerProto.RuleMatcher.newBuilder(); + rmBuilder.setDestination(CircuitBreakerProto.RuleMatcher.DestinationService.newBuilder().setNamespace("default").setService("svc2").setMethod( + ModelProto.MatchString.newBuilder().setValue(StringValue.newBuilder().setValue("*").build()).build()).build()); + rmBuilder.setSource(CircuitBreakerProto.RuleMatcher.SourceService.newBuilder().setNamespace("*").setService("*").build()); + ruleBuilder.setRuleMatcher(rmBuilder.build()); + return CircuitBreakerProto.CircuitBreaker.newBuilder().addRules(ruleBuilder.build()).build(); + }); + } + + @Test + public void testPolarisCircuitBreaker() { + contextRunner.run(context -> { + PolarisCircuitBreakerEndpoint endpoint = new PolarisCircuitBreakerEndpoint(serviceRuleManager); + Map circuitBreakerInfo = endpoint.circuitBreaker(); + assertThat(circuitBreakerInfo).isNotNull(); + assertThat(circuitBreakerInfo.get("namespace")).isNotNull(); + assertThat(circuitBreakerInfo.get("service")).isNotNull(); + assertThat(circuitBreakerInfo.get("circuitBreakerRules")).asList().isNotEmpty(); + }); + } +} 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 128899491..826d4fbe2 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 @@ -27,13 +27,14 @@ import com.tencent.polaris.api.rpc.GetServiceRuleRequest; import com.tencent.polaris.api.rpc.ServiceRuleResponse; import com.tencent.polaris.client.api.SDKContext; +import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; import com.tencent.polaris.specification.api.v1.traffic.manage.RateLimitProto; import com.tencent.polaris.specification.api.v1.traffic.manage.RoutingProto; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * the manager of service governance rules. for example: rate limit rule, router rules. + * the manager of service governance rules. for example: rate limit rule, router rules, circuit breaker rules. * * @author lepdou 2022-05-13 */ @@ -88,6 +89,20 @@ public List getServiceRouterRule(String namespace, String so return rules; } + public CircuitBreakerProto.CircuitBreaker getServiceCircuitBreakerRule(String namespace, String service) { + LOG.debug("Get service circuit breaker rules with namespace:{} and service:{}.", namespace, service); + + ServiceRule serviceRule = getServiceRule(namespace, service, ServiceEventKey.EventType.CIRCUIT_BREAKING); + if (serviceRule != null) { + Object rule = serviceRule.getRule(); + if (rule instanceof CircuitBreakerProto.CircuitBreaker) { + return (CircuitBreakerProto.CircuitBreaker) rule; + } + } + + return null; + } + private ServiceRule getServiceRule(String namespace, String service, ServiceEventKey.EventType eventType) { GetServiceRuleRequest getServiceRuleRequest = new GetServiceRuleRequest(); getServiceRuleRequest.setRuleType(eventType); From e4ac09c8d6b4ec58700bc923c851df60bbe43bd6 Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Mon, 25 Sep 2023 11:34:51 +0800 Subject: [PATCH 05/10] docs:update PR template. --- .github/PULL_REQUEST_TEMPLATE.md | 1 + .../tencent/cloud/common/pojo/PolarisServiceInstance.java | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e516afb42..a56dd0d4b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -28,3 +28,4 @@ fixes # - [ ] Will pull request to branch of 2020.0. - [ ] Will pull request to branch of 2022.0. +- [ ] Will pull request to branch of hoxton. 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 e4fc2934c..d5f28e597 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 @@ -95,6 +95,11 @@ public String getScheme() { return this.scheme; } + /** + * To fix loadbalancer not working bug when importing spring-retry. + * @param o object + * @return if equals + */ @Override public boolean equals(Object o) { if (this == o) { From 5cf364086790196007404028ee0013fff7b9170a Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Mon, 25 Sep 2023 15:44:57 +0800 Subject: [PATCH 06/10] feat:support service contract reporting. (#1139) --- .licenserc.yaml | 2 +- CHANGELOG.md | 3 +- pom.xml | 1 + spring-cloud-starter-tencent-all/pom.xml | 22 +- .../adapter/PolarisConfigFileLocator.java | 4 +- .../PolarisConfigPropertyAutoRefresher.java | 4 +- .../pom.xml | 69 ++++++ .../contract/PolarisContractReporter.java | 150 ++++++++++++ .../PolarisSwaggerApplicationListener.java | 35 +++ .../polaris/contract/SwaggerContext.java | 36 +++ .../contract/config/ContractProperties.java | 46 ++++ .../config/ExtendedContractProperties.java | 26 +++ .../config/PolarisContractModifier.java | 52 +++++ .../config/PolarisContractProperties.java | 122 ++++++++++ ...isContractPropertiesAutoConfiguration.java | 48 ++++ ...tractPropertiesBootstrapConfiguration.java | 34 +++ .../PolarisSwaggerAutoConfiguration.java | 147 ++++++++++++ .../polaris/contract/utils/PackageUtil.java | 214 ++++++++++++++++++ ...WebMvcPatternsRequestConditionWrapper.java | 90 ++++++++ .../spring/web/WebMvcRequestHandler.java | 175 ++++++++++++++ .../main/resources/META-INF/spring.factories | 7 + .../polaris/PolarisDiscoveryProperties.java | 2 +- .../cloud/common/constant/OrderConstant.java | 5 + spring-cloud-tencent-coverage/pom.xml | 6 +- spring-cloud-tencent-dependencies/pom.xml | 26 +++ .../discovery-caller-service/pom.xml | 5 + .../caller/DiscoveryCallerController.java | 2 +- .../RpcEnhancementAutoConfiguration.java | 36 --- .../plugin/PluginOrderConstant.java | 22 -- .../assembly/AssemblyMetadataProvider.java | 56 ----- .../assembly/AssemblyRequestContext.java | 126 ----------- .../assembly/AssemblyResponseContext.java | 87 ------- .../client/AssemblyClientExceptionHook.java | 82 ------- .../client/AssemblyClientPostHook.java | 83 ------- .../client/AssemblyClientPreHook.java | 73 ------ .../server/AssemblyServerExceptionHook.java | 76 ------- .../server/AssemblyServerPostHook.java | 75 ------ .../server/AssemblyServerPreHook.java | 70 ------ .../AssemblyClientExceptionHookTest.java | 146 ------------ .../plugin/AssemblyClientPostHookTest.java | 146 ------------ .../plugin/AssemblyClientPreHookTest.java | 143 ------------ .../plugin/AssemblyMetadataProviderTest.java | 57 ----- .../plugin/AssemblyRequestContextTest.java | 83 ------- .../plugin/AssemblyResponseContextTest.java | 101 --------- .../AssemblyServerExceptionHookTest.java | 143 ------------ .../plugin/AssemblyServerPostHookTest.java | 143 ------------ .../plugin/AssemblyServerPreHookTest.java | 143 ------------ 47 files changed, 1319 insertions(+), 1905 deletions(-) create mode 100644 spring-cloud-starter-tencent-polaris-contract/pom.xml create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisSwaggerApplicationListener.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/SwaggerContext.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ContractProperties.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ExtendedContractProperties.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractModifier.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractProperties.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractPropertiesAutoConfiguration.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractPropertiesBootstrapConfiguration.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisSwaggerAutoConfiguration.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/springfox/documentation/spring/web/WebMvcPatternsRequestConditionWrapper.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/springfox/documentation/spring/web/WebMvcRequestHandler.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyMetadataProvider.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyRequestContext.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyResponseContext.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientExceptionHook.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientPostHook.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientPreHook.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerExceptionHook.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerPostHook.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerPreHook.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientExceptionHookTest.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientPostHookTest.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientPreHookTest.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyMetadataProviderTest.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyRequestContextTest.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyResponseContextTest.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerExceptionHookTest.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerPostHookTest.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerPreHookTest.java diff --git a/.licenserc.yaml b/.licenserc.yaml index 32266c414..04f07307a 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -16,7 +16,7 @@ header: CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. paths: - - "**/java/**" + - "**/tencent/**" language: Java: extensions: diff --git a/CHANGELOG.md b/CHANGELOG.md index 241575198..d61a882fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,4 +7,5 @@ - [Refactoring:remove invalid @AutoConfigureAfter and @AutoConfigureBefore from discovery client automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1115) - [feat: support log path configuration parameters.](https://github.com/Tencent/spring-cloud-tencent/pull/1128) - [refactor:optimize the order and condition matching of service registration automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1129) -- [feat: add circuit breaker actuator.](https://github.com/Tencent/spring-cloud-tencent/pull/1136) \ No newline at end of file +- [feat: add circuit breaker actuator.](https://github.com/Tencent/spring-cloud-tencent/pull/1136) +- [feat:support service contract reporting.](https://github.com/Tencent/spring-cloud-tencent/pull/1139) \ No newline at end of file diff --git a/pom.xml b/pom.xml index dab311801..09ad0369b 100644 --- a/pom.xml +++ b/pom.xml @@ -47,6 +47,7 @@ spring-cloud-starter-tencent-polaris-ratelimit spring-cloud-starter-tencent-polaris-circuitbreaker spring-cloud-starter-tencent-polaris-router + spring-cloud-starter-tencent-polaris-contract spring-cloud-tencent-plugin-starters spring-cloud-tencent-dependencies spring-cloud-starter-tencent-all diff --git a/spring-cloud-starter-tencent-all/pom.xml b/spring-cloud-starter-tencent-all/pom.xml index 1c45b11d7..fc6470e9a 100644 --- a/spring-cloud-starter-tencent-all/pom.xml +++ b/spring-cloud-starter-tencent-all/pom.xml @@ -45,6 +45,11 @@ spring-cloud-starter-tencent-metadata-transfer + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-contract + + org.springframework.cloud @@ -88,12 +93,19 @@ true - - - META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports + + + + META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports + - - META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports + + + META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports + 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 21f4f5a78..47e149873 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 @@ -101,7 +101,7 @@ public PropertySource locate(Environment environment) { private void initCustomPolarisConfigExtensionFiles(CompositePropertySource compositePropertySource) { if (polarisConfigCustomExtensionLayer == null) { - LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps"); + LOGGER.debug("[SCT Config] PolarisConfigCustomExtensionLayer is not init, ignore the following execution steps"); return; } polarisConfigCustomExtensionLayer.initConfigFiles(environment, compositePropertySource, polarisPropertySourceManager, configFileService); @@ -109,7 +109,7 @@ private void initCustomPolarisConfigExtensionFiles(CompositePropertySource compo private void afterLocatePolarisConfigExtension(CompositePropertySource compositePropertySource) { if (polarisConfigCustomExtensionLayer == null) { - LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps"); + LOGGER.debug("[SCT Config] PolarisConfigCustomExtensionLayer is not init, ignore the following execution steps"); return; } polarisConfigCustomExtensionLayer.executeAfterLocateConfigReturning(compositePropertySource); diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java index bdd9e21e2..c698cb6db 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java @@ -89,7 +89,7 @@ private void registerPolarisConfigPublishEvent() { private void customInitRegisterPolarisConfig(PolarisConfigPropertyAutoRefresher polarisConfigPropertyAutoRefresher) { if (polarisConfigCustomExtensionLayer == null) { - LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps"); + LOGGER.debug("[SCT Config] PolarisConfigCustomExtensionLayer is not init, ignore the following execution steps"); return; } polarisConfigCustomExtensionLayer.initRegisterConfig(polarisConfigPropertyAutoRefresher); @@ -139,7 +139,7 @@ public void registerPolarisConfigPublishChangeListener(PolarisPropertySource pol private void customRegisterPolarisConfigPublishChangeListener(PolarisPropertySource polarisPropertySource) { if (polarisConfigCustomExtensionLayer == null) { - LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps"); + LOGGER.debug("[SCT Config] PolarisConfigCustomExtensionLayer is not init, ignore the following execution steps"); return; } polarisConfigCustomExtensionLayer.executeRegisterPublishChangeListener(polarisPropertySource); diff --git a/spring-cloud-starter-tencent-polaris-contract/pom.xml b/spring-cloud-starter-tencent-polaris-contract/pom.xml new file mode 100644 index 000000000..c17c92b32 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/pom.xml @@ -0,0 +1,69 @@ + + + + spring-cloud-tencent + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + spring-cloud-starter-tencent-polaris-contract + Spring Cloud Starter Tencent Polaris Contract + + + + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-discovery + + + + + + org.springframework.boot + spring-boot-starter-webflux + true + + + + org.springframework.boot + spring-boot-starter-web + true + + + + + io.springfox + springfox-boot-starter + + + swagger-models + io.swagger + + + swagger-annotations + io.swagger + + + + + + io.swagger + swagger-models + + + + io.swagger + swagger-annotations + + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java new file mode 100644 index 000000000..dd421b45b --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java @@ -0,0 +1,150 @@ +/* + * 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.contract; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.polaris.api.core.ProviderAPI; +import com.tencent.polaris.api.plugin.server.InterfaceDescriptor; +import com.tencent.polaris.api.plugin.server.ReportServiceContractRequest; +import com.tencent.polaris.api.plugin.server.ReportServiceContractResponse; +import io.swagger.models.HttpMethod; +import io.swagger.models.Operation; +import io.swagger.models.Path; +import io.swagger.models.Swagger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import springfox.documentation.service.Documentation; +import springfox.documentation.spring.web.DocumentationCache; +import springfox.documentation.spring.web.json.JsonSerializer; +import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper; + +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.lang.NonNull; +import org.springframework.util.CollectionUtils; + +public class PolarisContractReporter implements ApplicationListener { + + private final Logger LOG = LoggerFactory.getLogger(PolarisContractReporter.class); + private final ServiceModelToSwagger2Mapper swagger2Mapper; + private final DocumentationCache documentationCache; + private final JsonSerializer jsonSerializer; + private final String groupName; + + private final ProviderAPI providerAPI; + + private final PolarisDiscoveryProperties polarisDiscoveryProperties; + + public PolarisContractReporter(DocumentationCache documentationCache, ServiceModelToSwagger2Mapper swagger2Mapper, + JsonSerializer jsonSerializer, String groupName, ProviderAPI providerAPI, + PolarisDiscoveryProperties polarisDiscoveryProperties) { + this.swagger2Mapper = swagger2Mapper; + this.documentationCache = documentationCache; + this.jsonSerializer = jsonSerializer; + this.groupName = groupName; + this.providerAPI = providerAPI; + this.polarisDiscoveryProperties = polarisDiscoveryProperties; + } + + @Override + public void onApplicationEvent(@NonNull ApplicationReadyEvent applicationReadyEvent) { + try { + Documentation documentation = documentationCache.documentationByGroup(groupName); + Swagger swagger = swagger2Mapper.mapDocumentation(documentation); + if (swagger != null) { + ReportServiceContractRequest request = new ReportServiceContractRequest(); + request.setName(polarisDiscoveryProperties.getService()); + request.setNamespace(polarisDiscoveryProperties.getNamespace()); + request.setService(polarisDiscoveryProperties.getService()); + request.setProtocol("http"); + request.setVersion(polarisDiscoveryProperties.getVersion()); + List interfaceDescriptorList = getInterfaceDescriptorFromSwagger(swagger); + request.setInterfaceDescriptors(interfaceDescriptorList); + ReportServiceContractResponse response = providerAPI.reportServiceContract(request); + LOG.info("Service contract [Namespace: {}. Name: {}. Service: {}. Protocol:{}. Version: {}. API counter: {}] is reported.", + request.getNamespace(), request.getName(), request.getService(), request.getProtocol(), + request.getVersion(), request.getInterfaceDescriptors().size()); + if (LOG.isDebugEnabled()) { + String jsonValue = JacksonUtils.serialize2Json(swagger); + LOG.debug("OpenApi json data: {}", jsonValue); + } + } + else { + LOG.warn("Swagger or json is null, documentationCache keys:{}, group:{}", documentationCache.all() + .keySet(), groupName); + } + } + catch (Throwable t) { + LOG.error("Report contract failed.", t); + } + } + + private List getInterfaceDescriptorFromSwagger(Swagger swagger) { + List interfaceDescriptorList = new ArrayList<>(); + Map paths = swagger.getPaths(); + for (Map.Entry p : paths.entrySet()) { + Path path = p.getValue(); + Map operationMap = getOperationMapFromPath(path); + if (CollectionUtils.isEmpty(operationMap)) { + continue; + } + for (Map.Entry o : operationMap.entrySet()) { + InterfaceDescriptor interfaceDescriptor = new InterfaceDescriptor(); + interfaceDescriptor.setPath(p.getKey()); + interfaceDescriptor.setMethod(o.getKey()); + interfaceDescriptor.setContent(JacksonUtils.serialize2Json(p.getValue())); + interfaceDescriptorList.add(interfaceDescriptor); + } + } + return interfaceDescriptorList; + } + + private Map getOperationMapFromPath(Path path) { + Map operationMap = new HashMap<>(); + + if (path.getGet() != null) { + operationMap.put(HttpMethod.GET.name(), path.getGet()); + } + if (path.getPut() != null) { + operationMap.put(HttpMethod.PUT.name(), path.getPut()); + } + if (path.getPost() != null) { + operationMap.put(HttpMethod.POST.name(), path.getPost()); + } + if (path.getHead() != null) { + operationMap.put(HttpMethod.HEAD.name(), path.getHead()); + } + if (path.getDelete() != null) { + operationMap.put(HttpMethod.DELETE.name(), path.getDelete()); + } + if (path.getPatch() != null) { + operationMap.put(HttpMethod.PATCH.name(), path.getPatch()); + } + if (path.getOptions() != null) { + operationMap.put(HttpMethod.OPTIONS.name(), path.getOptions()); + } + + return operationMap; + } +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisSwaggerApplicationListener.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisSwaggerApplicationListener.java new file mode 100644 index 000000000..76d4259f0 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisSwaggerApplicationListener.java @@ -0,0 +1,35 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.contract; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; +import org.springframework.context.ApplicationListener; + +public class PolarisSwaggerApplicationListener implements ApplicationListener { + + @Override + public void onApplicationEvent(ApplicationEnvironmentPreparedEvent startingEvent) { + SpringApplication application = startingEvent.getSpringApplication(); + Class mainClass = application.getMainApplicationClass(); + if (mainClass == null) { + return; + } + SwaggerContext.setAttribute(String.format("$%s", "MainClass"), mainClass); + } +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/SwaggerContext.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/SwaggerContext.java new file mode 100644 index 000000000..b4f247944 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/SwaggerContext.java @@ -0,0 +1,36 @@ +/* + * 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.contract; + +import java.util.concurrent.ConcurrentHashMap; + +public final class SwaggerContext { + private static final ConcurrentHashMap attribute = new ConcurrentHashMap<>(); + + private SwaggerContext() { + + } + + public static void setAttribute(String key, Object value) { + attribute.put(key, value); + } + + public static Object getAttribute(String key) { + return attribute.get(key); + } +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ContractProperties.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ContractProperties.java new file mode 100644 index 000000000..32970b067 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ContractProperties.java @@ -0,0 +1,46 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.contract.config; + +/** + * Interface for contract properties. + * + * @author Haotian Zhang + */ +public interface ContractProperties { + + boolean isEnabled(); + + void setEnabled(boolean enabled); + + String getBasePackage(); + + void setBasePackage(String basePackage); + + String getExcludePath(); + + void setExcludePath(String excludePath); + + String getGroup(); + + void setGroup(String group); + + String getBasePath(); + + void setBasePath(String basePath); +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ExtendedContractProperties.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ExtendedContractProperties.java new file mode 100644 index 000000000..22830fa81 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ExtendedContractProperties.java @@ -0,0 +1,26 @@ +/* + * 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.contract.config; + +/** + * Extend contract properties. + * + * @author Haotian Zhang + */ +public interface ExtendedContractProperties extends ContractProperties { +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractModifier.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractModifier.java new file mode 100644 index 000000000..f48a01d24 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractModifier.java @@ -0,0 +1,52 @@ +/* + * 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.contract.config; + +import java.util.List; + +import com.tencent.cloud.common.constant.OrderConstant; +import com.tencent.cloud.polaris.context.PolarisConfigModifier; +import com.tencent.polaris.factory.config.ConfigurationImpl; +import com.tencent.polaris.factory.config.provider.RegisterConfigImpl; + +/** + * Modifier of service contract. + * + * @author Haotian Zhang + */ +public class PolarisContractModifier implements PolarisConfigModifier { + + private final PolarisContractProperties polarisContractProperties; + + public PolarisContractModifier(PolarisContractProperties polarisContractProperties) { + this.polarisContractProperties = polarisContractProperties; + } + + @Override + public void modify(ConfigurationImpl configuration) { + List registerConfigs = configuration.getProvider().getRegisters(); + for (RegisterConfigImpl registerConfig : registerConfigs) { + registerConfig.setReportServiceContractEnable(polarisContractProperties.isEnabled()); + } + } + + @Override + public int getOrder() { + return OrderConstant.Modifier.SERVICE_CONTRACT_ORDER; + } +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractProperties.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractProperties.java new file mode 100644 index 000000000..edafa77fc --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractProperties.java @@ -0,0 +1,122 @@ +/* + * 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.contract.config; + +import java.util.Objects; + +import javax.annotation.Nullable; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Properties for Polaris contract. + * + * @author Haotian Zhang + */ +@ConfigurationProperties("spring.cloud.polaris.contract") +public class PolarisContractProperties implements ContractProperties { + + private final ExtendedContractProperties extendContractProperties; + + private boolean enabled = true; + /** + * Packages to be scanned. Split by ",". + */ + private String basePackage; + /** + * Paths to be excluded. Split by ",". + */ + private String excludePath; + /** + * Group to create swagger docket. + */ + private String group = "default"; + /** + * Base paths to be scanned. Split by ",". + */ + private String basePath = "/**"; + + public PolarisContractProperties(@Nullable ExtendedContractProperties extendContractProperties) { + this.extendContractProperties = extendContractProperties; + } + + @Override + public boolean isEnabled() { + if (Objects.nonNull(extendContractProperties)) { + return extendContractProperties.isEnabled(); + } + return enabled; + } + + @Override + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @Override + public String getBasePackage() { + if (Objects.nonNull(extendContractProperties)) { + return extendContractProperties.getBasePackage(); + } + return basePackage; + } + + @Override + public void setBasePackage(String basePackage) { + this.basePackage = basePackage; + } + + @Override + public String getExcludePath() { + if (Objects.nonNull(extendContractProperties)) { + return extendContractProperties.getExcludePath(); + } + return excludePath; + } + + @Override + public void setExcludePath(String excludePath) { + this.excludePath = excludePath; + } + + @Override + public String getGroup() { + if (Objects.nonNull(extendContractProperties)) { + return extendContractProperties.getGroup(); + } + return group; + } + + @Override + public void setGroup(String group) { + this.group = group; + } + + @Override + public String getBasePath() { + if (Objects.nonNull(extendContractProperties)) { + return extendContractProperties.getBasePath(); + } + return basePath; + } + + @Override + public void setBasePath(String basePath) { + this.basePath = basePath; + } +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractPropertiesAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractPropertiesAutoConfiguration.java new file mode 100644 index 000000000..d3e0edb35 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractPropertiesAutoConfiguration.java @@ -0,0 +1,48 @@ +/* + * 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.contract.config; + +import javax.annotation.Nullable; + +import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Auto configuration for Polaris contract properties. + * + * @author Haotian Zhang + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnPolarisEnabled +public class PolarisContractPropertiesAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public PolarisContractProperties polarisContractProperties(@Nullable ExtendedContractProperties extendedContractProperties) { + return new PolarisContractProperties(extendedContractProperties); + } + + @Bean + @ConditionalOnMissingBean + public PolarisContractModifier polarisContractModifier(PolarisContractProperties polarisContractProperties) { + return new PolarisContractModifier(polarisContractProperties); + } +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractPropertiesBootstrapConfiguration.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractPropertiesBootstrapConfiguration.java new file mode 100644 index 000000000..ceb2d102e --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractPropertiesBootstrapConfiguration.java @@ -0,0 +1,34 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.contract.config; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +/** + * Bootstrap configuration for Polaris contract properties. + * + * @author Haotian Zhang + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnProperty("spring.cloud.polaris.enabled") +@Import(PolarisContractPropertiesAutoConfiguration.class) +public class PolarisContractPropertiesBootstrapConfiguration { + +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisSwaggerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisSwaggerAutoConfiguration.java new file mode 100644 index 000000000..c4c720ea9 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisSwaggerAutoConfiguration.java @@ -0,0 +1,147 @@ +/* + * 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.contract.config; + +import java.time.LocalDate; +import java.util.Date; +import java.util.List; +import java.util.function.Predicate; + +import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; +import com.tencent.cloud.polaris.contract.PolarisContractReporter; +import com.tencent.cloud.polaris.contract.PolarisSwaggerApplicationListener; +import com.tencent.cloud.polaris.contract.utils.PackageUtil; +import springfox.boot.starter.autoconfigure.OpenApiAutoConfiguration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.DocumentationCache; +import springfox.documentation.spring.web.json.JsonSerializer; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +@Configuration(proxyBeanMethods = false) +@ConditionalOnPolarisEnabled +@ConditionalOnProperty(name = "spring.cloud.polaris.contract.enabled", havingValue = "true", matchIfMissing = true) +@Import(OpenApiAutoConfiguration.class) +public class PolarisSwaggerAutoConfiguration { + + static { + // After springboot2.6.x, the default path matching strategy of spring MVC is changed from ANT_PATH_MATCHER + // mode to PATH_PATTERN_PARSER mode, causing an error. The solution is to switch to the original ANT_PATH_MATCHER mode. + System.setProperty("spring.mvc.pathmatch.matching-strategy", "ant-path-matcher"); + } + + @Bean + public Docket polarisDocket(PolarisContractProperties polarisContractProperties) { + List> excludePathList = PackageUtil.getExcludePathPredicates(polarisContractProperties.getExcludePath()); + List> basePathList = PackageUtil.getBasePathPredicates(polarisContractProperties.getBasePath()); + String basePackage = PackageUtil.scanPackage(polarisContractProperties.getBasePackage()); + + Predicate basePathListOr = null; + for (Predicate basePathPredicate : basePathList) { + if (basePathListOr == null) { + basePathListOr = basePathPredicate; + } + else { + basePathListOr = basePathListOr.or(basePathPredicate); + } + } + + Predicate excludePathListOr = null; + for (Predicate excludePathPredicate : excludePathList) { + if (excludePathListOr == null) { + excludePathListOr = excludePathPredicate; + } + else { + excludePathListOr = excludePathListOr.or(excludePathPredicate); + } + } + + Predicate pathsPredicate = basePathListOr; + + if (excludePathListOr != null) { + excludePathListOr = excludePathListOr.negate(); + pathsPredicate = pathsPredicate.and(excludePathListOr); + } + + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(PackageUtil.basePackage(basePackage)) + .paths(pathsPredicate) + .build() + .groupName(polarisContractProperties.getGroup()) + .enable(polarisContractProperties.isEnabled()) + .directModelSubstitute(LocalDate.class, Date.class) + .apiInfo(new ApiInfoBuilder() + .title("Polaris Swagger API") + .description("This is to show polaris api description.") + .license("BSD-3-Clause") + .licenseUrl("https://opensource.org/licenses/BSD-3-Clause") + .termsOfServiceUrl("") + .version("1.0.0") + .contact(new Contact("", "", "")) + .build()); + } + + @Bean + @ConditionalOnBean(Docket.class) + @ConditionalOnMissingBean + public PolarisContractReporter polarisApiMetadataGrapher(DocumentationCache documentationCache, + ServiceModelToSwagger2Mapper swagger2Mapper, JsonSerializer jsonSerializer, + PolarisContractProperties polarisContractProperties, PolarisSDKContextManager polarisSDKContextManager, + PolarisDiscoveryProperties polarisDiscoveryProperties) { + return new PolarisContractReporter(documentationCache, swagger2Mapper, jsonSerializer, + polarisContractProperties.getGroup(), polarisSDKContextManager.getProviderAPI(), polarisDiscoveryProperties); + } + + @Bean + @ConditionalOnMissingBean + public PolarisSwaggerApplicationListener polarisSwaggerApplicationListener() { + return new PolarisSwaggerApplicationListener(); + } + + /** + * Create when web application type is SERVLET. + */ + @Configuration(proxyBeanMethods = false) + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) + protected static class SwaggerServletConfig { + + } + + /** + * Create when web application type is REACTIVE. + */ + @Configuration(proxyBeanMethods = false) + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) + protected static class SwaggerReactiveConfig { + + + } +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java new file mode 100644 index 000000000..7ce8a7ec2 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java @@ -0,0 +1,214 @@ +/* + * 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.contract.utils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.tencent.cloud.polaris.contract.SwaggerContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import springfox.documentation.RequestHandler; +import springfox.documentation.builders.PathSelectors; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.util.StringUtils; + +import static com.google.common.base.Optional.fromNullable; + +/** + * Util for package processing. + * + * @author Haotian Zhang + */ +public final class PackageUtil { + + private static final Logger LOG = LoggerFactory.getLogger(PackageUtil.class); + + private static final String SPLITTER = ","; + + + private PackageUtil() { + } + + public static Predicate basePackage(String basePackage) { + return input -> declaringClass(input).transform(handlerPackage(basePackage, SPLITTER)).or(false); + } + + public static Optional> declaringClass(RequestHandler input) { + if (input == null) { + return Optional.absent(); + } + return fromNullable(input.declaringClass()); + } + + public static Function, Boolean> handlerPackage(String basePackage, String splitter) { + return input -> { + try { + if (StringUtils.isEmpty(basePackage)) { + return false; + } + String[] packages = basePackage.trim().split(splitter); + // Loop to determine matching + for (String strPackage : packages) { + if (input == null) { + continue; + } + Package pkg = input.getPackage(); + if (pkg == null) { + continue; + } + String name = pkg.getName(); + if (StringUtils.isEmpty(name)) { + continue; + } + boolean isMatch = name.startsWith(strPackage); + if (isMatch) { + return true; + } + } + } + catch (Exception e) { + LOG.error("handler package error", e); + } + return false; + }; + } + + public static List> getExcludePathPredicates(String excludePath) { + List> excludePathList = new ArrayList<>(); + if (StringUtils.isEmpty(excludePath)) { + return excludePathList; + } + String[] exs = excludePath.split(SPLITTER); + for (String ex : exs) { + if (!StringUtils.isEmpty(ex)) { + excludePathList.add(PathSelectors.ant(ex)); + } + } + return excludePathList; + } + + public static List> getBasePathPredicates(String basePath) { + List> basePathList = new ArrayList<>(); + if (!StringUtils.isEmpty(basePath)) { + String[] bps = basePath.split(SPLITTER); + for (String bp : bps) { + if (!StringUtils.isEmpty(bp)) { + basePathList.add(PathSelectors.ant(bp)); + } + } + } + if (basePathList.isEmpty()) { + basePathList.add(PathSelectors.ant("/**")); + } + return basePathList; + } + + public static String scanPackage(String configBasePackage) { + String validScanPackage; + // Externally configured scan package + Set configPackageSet = new HashSet<>(); + if (!StringUtils.isEmpty(configBasePackage)) { + configPackageSet.addAll(Arrays.asList(configBasePackage.split(SPLITTER))); + } + Object mainClz = SwaggerContext.getAttribute(String.format("$%s", "MainClass")); + // Verification of the valid path of MainClass + if (mainClz != null) { + Set autoDetectPackageSet = parseDefaultScanPackage((Class) mainClz); + if (LOG.isInfoEnabled() && !autoDetectPackageSet.isEmpty()) { + LOG.info("Auto detect default swagger scan packages: {}", + String.join(SPLITTER, autoDetectPackageSet).trim()); + } + Set validScanPackageSet = merge(configPackageSet, autoDetectPackageSet); + validScanPackage = String.join(SPLITTER, validScanPackageSet).trim(); + if (LOG.isInfoEnabled() && !StringUtils.isEmpty(validScanPackage)) { + LOG.info("Swagger scan valid packages: {}", validScanPackage); + } + } + else { + // If there is no MainClass, the configured path is used for scanning + validScanPackage = String.join(SPLITTER, configPackageSet); + if (LOG.isWarnEnabled()) { + LOG.warn("Cannot detect main class, swagger scanning packages is set to: {}", + validScanPackage); + } + } + return validScanPackage; + } + + public static Set merge(Set configPackageSet, Set autoDetectPackageSet) { + if (configPackageSet == null || configPackageSet.size() == 0) { + return autoDetectPackageSet; + } + return configPackageSet; + } + + + public static Set parseDefaultScanPackage(Class mainClass) { + Set packageSets = new HashSet<>(); + String defaultPackage = mainClass.getPackage().getName(); + try { + boolean springBootEnv = true; + try { + Class.forName("org.springframework.boot.autoconfigure.SpringBootApplication"); + } + catch (Throwable t) { + LOG.info("Can not load annotation @SpringBootApplication, " + + "current environment is not in spring boot framework. "); + springBootEnv = false; + } + if (!springBootEnv) { + packageSets.add(defaultPackage); + return packageSets; + } + SpringBootApplication bootAnnotation = mainClass.getAnnotation(SpringBootApplication.class); + Class[] baseClassPackages; + String[] basePackages; + if (bootAnnotation == null) { + packageSets.add(defaultPackage); + } + else { + // baseClassPackages annotation + baseClassPackages = bootAnnotation.scanBasePackageClasses(); + for (Class clz : baseClassPackages) { + packageSets.add(clz.getPackage().getName()); + } + // basePackage annotation + basePackages = bootAnnotation.scanBasePackages(); + packageSets.addAll(Arrays.asList(basePackages)); + // When basePackage and baseClassPackages are both empty, the package path where the MainClass class is located is used by default. + if (packageSets.isEmpty()) { + packageSets.add(defaultPackage); + } + } + } + catch (Throwable t) { + LOG.warn("Swagger scan package is empty and auto detect main class occur exception: {}", + t.getMessage()); + + } + return packageSets; + } +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/springfox/documentation/spring/web/WebMvcPatternsRequestConditionWrapper.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/springfox/documentation/spring/web/WebMvcPatternsRequestConditionWrapper.java new file mode 100644 index 000000000..d2be96b42 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/springfox/documentation/spring/web/WebMvcPatternsRequestConditionWrapper.java @@ -0,0 +1,90 @@ +/* + * + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 springfox.documentation.spring.web; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; + +import static springfox.documentation.spring.web.paths.Paths.maybeChompLeadingSlash; +import static springfox.documentation.spring.web.paths.Paths.maybeChompTrailingSlash; + +/** + * Modified to be compatible with spring-boot-actuator. + */ +public class WebMvcPatternsRequestConditionWrapper + implements springfox.documentation.spring.wrapper.PatternsRequestCondition { + private final String contextPath; + private final PatternsRequestCondition condition; + + public WebMvcPatternsRequestConditionWrapper( + String contextPath, + PatternsRequestCondition condition) { + + this.contextPath = contextPath; + this.condition = condition; + } + + @Override + public springfox.documentation.spring.wrapper.PatternsRequestCondition combine( + springfox.documentation.spring.wrapper.PatternsRequestCondition other) { + if (other instanceof WebMvcPatternsRequestConditionWrapper && !this.equals(other)) { + return new WebMvcPatternsRequestConditionWrapper( + contextPath, + condition.combine(((WebMvcPatternsRequestConditionWrapper) other).condition)); + } + return this; + } + + @Override + public Set getPatterns() { + // polaris add start + if (this.condition == null) { + return new HashSet<>(); + } + // polaris add end + return this.condition.getPatterns().stream() + .map(p -> String.format("%s/%s", maybeChompTrailingSlash(contextPath), maybeChompLeadingSlash(p))) + .collect(Collectors.toSet()); + } + + + @Override + public boolean equals(Object o) { + if (o instanceof WebMvcPatternsRequestConditionWrapper) { + return this.condition.equals(((WebMvcPatternsRequestConditionWrapper) o).condition); + } + return false; + } + + @Override + public int hashCode() { + return this.condition.hashCode(); + } + + + @Override + public String toString() { + return this.condition.toString(); + } +} + diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/springfox/documentation/spring/web/WebMvcRequestHandler.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/springfox/documentation/spring/web/WebMvcRequestHandler.java new file mode 100644 index 000000000..3f58ddcdb --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/springfox/documentation/spring/web/WebMvcRequestHandler.java @@ -0,0 +1,175 @@ +/* + * + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 springfox.documentation.spring.web; + +import java.lang.annotation.Annotation; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.StringJoiner; + +import com.fasterxml.classmate.ResolvedType; +import springfox.documentation.RequestHandler; +import springfox.documentation.RequestHandlerKey; +import springfox.documentation.service.ResolvedMethodParameter; +import springfox.documentation.spring.web.readers.operation.HandlerMethodResolver; +import springfox.documentation.spring.wrapper.NameValueExpression; +import springfox.documentation.spring.wrapper.PatternsRequestCondition; + +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; + +import static java.util.Optional.ofNullable; + +/** + * Modified to be compatible with spring-boot-actuator. + */ +public class WebMvcRequestHandler implements RequestHandler { + private final String contextPath; + private final HandlerMethodResolver methodResolver; + private final RequestMappingInfo requestMapping; + private final HandlerMethod handlerMethod; + + public WebMvcRequestHandler( + String contextPath, + HandlerMethodResolver methodResolver, + RequestMappingInfo requestMapping, + HandlerMethod handlerMethod) { + this.contextPath = contextPath; + this.methodResolver = methodResolver; + this.requestMapping = requestMapping; + this.handlerMethod = handlerMethod; + } + + @Override + public HandlerMethod getHandlerMethod() { + return handlerMethod; + } + + @Override + public RequestHandler combine(RequestHandler other) { + return this; + } + + @Override + public Class declaringClass() { + return handlerMethod.getBeanType(); + } + + @Override + public boolean isAnnotatedWith(Class annotation) { + return null != AnnotationUtils.findAnnotation(handlerMethod.getMethod(), annotation); + } + + @Override + public PatternsRequestCondition getPatternsCondition() { + return new WebMvcPatternsRequestConditionWrapper( + contextPath, + requestMapping.getPatternsCondition()); + } + + @Override + public String groupName() { + return ControllerNamingUtils.controllerNameAsGroup(handlerMethod); + } + + @Override + public String getName() { + return handlerMethod.getMethod().getName(); + } + + @Override + public Set supportedMethods() { + return requestMapping.getMethodsCondition().getMethods(); + } + + @Override + public Set produces() { + return requestMapping.getProducesCondition().getProducibleMediaTypes(); + } + + @Override + public Set consumes() { + return requestMapping.getConsumesCondition().getConsumableMediaTypes(); + } + + @Override + public Set> headers() { + return WebMvcNameValueExpressionWrapper.from(requestMapping.getHeadersCondition().getExpressions()); + } + + @Override + public Set> params() { + return WebMvcNameValueExpressionWrapper.from(requestMapping.getParamsCondition().getExpressions()); + } + + @Override + public Optional findAnnotation(Class annotation) { + return ofNullable(AnnotationUtils.findAnnotation(handlerMethod.getMethod(), annotation)); + } + + @Override + public RequestHandlerKey key() { + // polaris add start + Set patterns = new HashSet<>(); + if (requestMapping.getPatternsCondition() != null && requestMapping.getPatternsCondition() + .getPatterns() != null) { + patterns = requestMapping.getPatternsCondition().getPatterns(); + } + // polaris add end + return new RequestHandlerKey( + patterns, + requestMapping.getMethodsCondition().getMethods(), + requestMapping.getConsumesCondition().getConsumableMediaTypes(), + requestMapping.getProducesCondition().getProducibleMediaTypes()); + } + + @Override + public springfox.documentation.spring.wrapper.RequestMappingInfo getRequestMapping() { + return new WebMvcRequestMappingInfoWrapper(requestMapping); + } + + @Override + public List getParameters() { + return methodResolver.methodParameters(handlerMethod); + } + + @Override + public ResolvedType getReturnType() { + return methodResolver.methodReturnType(handlerMethod); + } + + @Override + public Optional findControllerAnnotation(Class annotation) { + return ofNullable(AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), annotation)); + } + + @Override + public String toString() { + return new StringJoiner(", ", WebMvcRequestHandler.class.getSimpleName() + "{", "}") + .add("requestMapping=" + requestMapping) + .add("handlerMethod=" + handlerMethod) + .add("key=" + key()) + .toString(); + } +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..86a23f5be --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/spring.factories @@ -0,0 +1,7 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.tencent.cloud.polaris.contract.config.PolarisSwaggerAutoConfiguration,\ + com.tencent.cloud.polaris.contract.config.PolarisContractProperties +org.springframework.cloud.bootstrap.BootstrapConfiguration=\ + com.tencent.cloud.polaris.contract.config.PolarisContractPropertiesAutoConfiguration +org.springframework.context.ApplicationListener=\ + com.tencent.cloud.polaris.contract.PolarisSwaggerApplicationListener 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 3f83bfd44..0477ebfb9 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 @@ -64,7 +64,7 @@ public class PolarisDiscoveryProperties { /** * Version number. */ - private String version; + private String version = "1.0.0"; /** * Protocol name such as http, https. diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/OrderConstant.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/OrderConstant.java index 67c67c0fe..ac7aa169f 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/OrderConstant.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/OrderConstant.java @@ -171,5 +171,10 @@ public static final class Modifier { * Order of stat reporter configuration modifier. */ public static Integer STAT_REPORTER_ORDER = 1; + + /** + * Order of service contract configuration modifier. + */ + public static Integer SERVICE_CONTRACT_ORDER = Integer.MAX_VALUE - 9; } } diff --git a/spring-cloud-tencent-coverage/pom.xml b/spring-cloud-tencent-coverage/pom.xml index 433df7c72..15aef4a4e 100644 --- a/spring-cloud-tencent-coverage/pom.xml +++ b/spring-cloud-tencent-coverage/pom.xml @@ -64,10 +64,14 @@ spring-cloud-starter-tencent-polaris-config + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-contract + + com.tencent.cloud spring-cloud-starter-tencent-discovery-adapter-plugin - ${revision} diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 6cce1e8c6..80852a9dd 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -76,6 +76,8 @@ 1.15.0-SNAPSHOT 32.0.1-jre 1.2.11 + 3.0.0 + 1.5.24 4.5.1 1.12.10 3.21.7 @@ -154,6 +156,12 @@ ${revision} + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-contract + ${revision} + + com.tencent.cloud spring-cloud-starter-tencent-all @@ -212,6 +220,24 @@ ${logback.version} + + io.springfox + springfox-boot-starter + ${springfox.swagger2.version} + + + + io.swagger + swagger-models + ${io.swagger.version} + + + + io.swagger + swagger-annotations + ${io.swagger.version} + + com.google.protobuf protobuf-java diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml index aadcea9ee..69e5c1e64 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml @@ -28,6 +28,11 @@ spring-cloud-starter-tencent-polaris-discovery + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-contract + + diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java index f2ecaf5e4..166441cd6 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java @@ -45,7 +45,7 @@ public class DiscoveryCallerController { * @param value2 value 2 * @return sum */ - @GetMapping("/feign") + @RequestMapping("/feign") public int feign(@RequestParam int value1, @RequestParam int value2) { return discoveryCalleeService.sum(value1, value2); } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java index 968d8a0e2..3b52a6ade 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java @@ -30,12 +30,6 @@ import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientExceptionHook; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPostHook; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPreHook; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerExceptionHook; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPostHook; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPreHook; import com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter; import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter; import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateInterceptor; @@ -115,36 +109,6 @@ public ExceptionPolarisReporter exceptionPolarisReporter(RpcEnhancementReporterP return new ExceptionPolarisReporter(properties, polarisSDKContextManager.getConsumerAPI()); } - @Bean - public AssemblyClientExceptionHook assemblyClientExceptionHook(PolarisSDKContextManager polarisSDKContextManager, InstanceTransformer instanceTransformer) { - return new AssemblyClientExceptionHook(polarisSDKContextManager.getAssemblyAPI(), instanceTransformer); - } - - @Bean - public AssemblyClientPostHook assemblyClientPostHook(PolarisSDKContextManager polarisSDKContextManager, InstanceTransformer instanceTransformer) { - return new AssemblyClientPostHook(polarisSDKContextManager.getAssemblyAPI(), instanceTransformer); - } - - @Bean - public AssemblyClientPreHook assemblyClientPreHook(PolarisSDKContextManager polarisSDKContextManager) { - return new AssemblyClientPreHook(polarisSDKContextManager.getAssemblyAPI()); - } - - @Bean - public AssemblyServerExceptionHook assemblyServerExceptionHook(PolarisSDKContextManager polarisSDKContextManager) { - return new AssemblyServerExceptionHook(polarisSDKContextManager.getAssemblyAPI()); - } - - @Bean - public AssemblyServerPostHook assemblyServerPostHook(PolarisSDKContextManager polarisSDKContextManager) { - return new AssemblyServerPostHook(polarisSDKContextManager.getAssemblyAPI()); - } - - @Bean - public AssemblyServerPreHook assemblyServerPreHook(PolarisSDKContextManager polarisSDKContextManager) { - return new AssemblyServerPreHook(polarisSDKContextManager.getAssemblyAPI()); - } - @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) protected static class RpcEnhancementServletFilterConfig { diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java index 95807dbab..6677dac0a 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java @@ -44,27 +44,5 @@ public static class ClientPluginOrder { * {@link com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter}. */ public static final int CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 2; - - /** - * order for - * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPreHook} - * and - * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPostHook} - * and - * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientExceptionHook}. - */ - public static final int ASSEMBLY_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 3; - } - - public static class ServerPluginOrder { - /** - * order for - * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPreHook} - * and - * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPostHook} - * and - * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerExceptionHook}. - */ - public static final int ASSEMBLY_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 1; } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyMetadataProvider.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyMetadataProvider.java deleted file mode 100644 index e937f244b..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyMetadataProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin.assembly; - -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.api.rpc.MetadataProvider; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * AssemblyMetadataProvider. - * - * @author sean yu - */ -public class AssemblyMetadataProvider implements MetadataProvider { - - private final ServiceInstance serviceInstance; - - private final String namespace; - - public AssemblyMetadataProvider(ServiceInstance localServiceInstance, String namespace) { - this.serviceInstance = localServiceInstance; - this.namespace = namespace; - } - - @Override - public String getMetadata(String key) { - return serviceInstance.getMetadata().get(key); - } - - @Override - public ServiceKey getLocalService() { - return new ServiceKey(namespace, serviceInstance.getServiceId()); - } - - @Override - public String getLocalIp() { - return serviceInstance.getHost(); - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyRequestContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyRequestContext.java deleted file mode 100644 index dfcaa2ed8..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyRequestContext.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin.assembly; - -import java.net.URI; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; - -import com.google.common.net.HttpHeaders; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.api.rpc.RequestContext; - -import org.springframework.http.HttpMethod; - -/** - * AssemblyRequestContext. - * - * @author sean yu - */ -public class AssemblyRequestContext implements RequestContext { - - private final EnhancedRequestContext requestContext; - - private final ServiceKey callerService; - - private final String callerIp; - - private final Map cookies; - - public AssemblyRequestContext(EnhancedRequestContext requestContext, ServiceKey callerService, String callerIp) { - this.requestContext = requestContext; - this.callerService = callerService; - this.callerIp = callerIp; - this.cookies = new HashMap<>(); - List allCookies = - Optional.ofNullable(requestContext.getHttpHeaders().get(HttpHeaders.COOKIE)) - .orElse(new ArrayList<>()) - .stream() - .flatMap(it -> Arrays.stream(it.split(";"))) - .collect(Collectors.toList()); - allCookies.forEach(cookie -> { - String[] cookieKV = cookie.split("="); - if (cookieKV.length == 2) { - cookies.put(cookieKV[0], cookieKV[1]); - } - }); - } - - @Override - public String getMethod() { - return requestContext.getHttpMethod().name(); - } - - @Override - public void setMethod(String method) { - requestContext.setHttpMethod(HttpMethod.valueOf(method)); - } - - @Override - public String getHeader(String key) { - return requestContext.getHttpHeaders().getFirst(key); - } - - @Override - public void setHeader(String key, String value) { - requestContext.getHttpHeaders().set(key, value); - } - - @Override - public Collection listHeaderKeys() { - return requestContext.getHttpHeaders().keySet(); - } - - @Override - public String getCookie(String key) { - return this.cookies.get(key); - } - - @Override - public void setCookie(String key, String value) { - this.cookies.put(key, value); - } - - @Override - public Collection listCookieKeys() { - return this.cookies.keySet(); - } - - @Override - public String getCallerIp() { - return callerIp; - } - - @Override - public ServiceKey getCallerService() { - return callerService; - } - - @Override - public URI getURI() { - return requestContext.getUrl(); - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyResponseContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyResponseContext.java deleted file mode 100644 index 4dbfa81d7..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/AssemblyResponseContext.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin.assembly; - -import java.util.Collection; - -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; -import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils; -import com.tencent.polaris.api.pojo.RetStatus; -import com.tencent.polaris.api.rpc.ResponseContext; - -import org.springframework.lang.Nullable; - -/** - * AssemblyResponseContext. - * - * @author sean yu - */ -public class AssemblyResponseContext implements ResponseContext { - - private final EnhancedResponseContext responseContext; - - private final Throwable throwable; - - private final RetStatus retStatus; - - public AssemblyResponseContext(@Nullable EnhancedResponseContext responseContext, @Nullable Throwable throwable) { - this.responseContext = responseContext; - this.throwable = throwable; - if (responseContext == null) { - this.retStatus = PolarisEnhancedPluginUtils.getRetStatusFromRequest(null, null, throwable); - } - else { - this.retStatus = PolarisEnhancedPluginUtils.getRetStatusFromRequest(responseContext.getHttpHeaders(), responseContext.getHttpStatus(), throwable); - } - } - - @Override - public Object getRetCode() { - if (responseContext == null) { - return null; - } - return this.responseContext.getHttpStatus(); - } - - @Override - public String getHeader(String key) { - if (responseContext == null) { - return null; - } - return this.responseContext.getHttpHeaders().getFirst(key); - } - - @Override - public Collection listHeaders() { - if (responseContext == null) { - return null; - } - return this.responseContext.getHttpHeaders().keySet(); - } - - @Override - public Throwable getThrowable() { - return this.throwable; - } - - @Override - public RetStatus getRetStatus() { - return this.retStatus; - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientExceptionHook.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientExceptionHook.java deleted file mode 100644 index 398485b59..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientExceptionHook.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin.assembly.client; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; -import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyResponseContext; -import com.tencent.cloud.rpc.enhancement.transformer.InstanceTransformer; -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import com.tencent.polaris.assembly.api.pojo.AfterRequest; -import com.tencent.polaris.assembly.api.pojo.Capability; - -import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.ASSEMBLY_PLUGIN_ORDER; - -/** - * AssemblyClientExceptionHook. - * - * @author sean yu - */ -public class AssemblyClientExceptionHook implements EnhancedPlugin { - - private final AssemblyAPI assemblyAPI; - - private final InstanceTransformer instanceTransformer; - - public AssemblyClientExceptionHook(AssemblyAPI assemblyAPI, InstanceTransformer instanceTransformer) { - this.assemblyAPI = assemblyAPI; - this.instanceTransformer = instanceTransformer; - } - - @Override - public EnhancedPluginType getType() { - return EnhancedPluginType.Client.EXCEPTION; - } - - @Override - public void run(EnhancedPluginContext context) { - - AfterRequest afterRequest = new AfterRequest(); - afterRequest.setCapabilities(new Capability[]{Capability.ALL}); - afterRequest.setRequestContext(new AssemblyRequestContext( - context.getRequest(), - new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()), - context.getLocalServiceInstance().getHost() - )); - afterRequest.setResponseContext(new AssemblyResponseContext(null, context.getThrowable())); - afterRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE)); - afterRequest.setDelay(context.getDelay()); - afterRequest.setRouteLabels(PolarisEnhancedPluginUtils.getLabelMap(context.getRequest().getHttpHeaders())); - // TargetService and TargetInstance only exist in client side - afterRequest.setTargetService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getTargetServiceInstance().getServiceId())); - afterRequest.setTargetInstance(instanceTransformer.transform(context.getTargetServiceInstance())); - - assemblyAPI.afterCallService(afterRequest); - } - - @Override - public int getOrder() { - return ASSEMBLY_PLUGIN_ORDER; - } -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientPostHook.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientPostHook.java deleted file mode 100644 index 9148a0de9..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientPostHook.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin.assembly.client; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; -import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyResponseContext; -import com.tencent.cloud.rpc.enhancement.transformer.InstanceTransformer; -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import com.tencent.polaris.assembly.api.pojo.AfterRequest; -import com.tencent.polaris.assembly.api.pojo.Capability; - -import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.ASSEMBLY_PLUGIN_ORDER; - -/** - * AssemblyClientPostHook. - * - * @author sean yu - */ -public class AssemblyClientPostHook implements EnhancedPlugin { - - private final AssemblyAPI assemblyAPI; - - private final InstanceTransformer instanceTransformer; - - public AssemblyClientPostHook(AssemblyAPI assemblyAPI, InstanceTransformer instanceTransformer) { - this.assemblyAPI = assemblyAPI; - this.instanceTransformer = instanceTransformer; - } - - @Override - public EnhancedPluginType getType() { - return EnhancedPluginType.Client.POST; - } - - @Override - public void run(EnhancedPluginContext context) { - - AfterRequest afterRequest = new AfterRequest(); - afterRequest.setCapabilities(new Capability[]{Capability.ALL}); - afterRequest.setRequestContext(new AssemblyRequestContext( - context.getRequest(), - new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()), - context.getLocalServiceInstance().getHost() - )); - afterRequest.setResponseContext(new AssemblyResponseContext(context.getResponse(), null)); - afterRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE)); - afterRequest.setDelay(context.getDelay()); - afterRequest.setRouteLabels(PolarisEnhancedPluginUtils.getLabelMap(context.getRequest().getHttpHeaders())); - // TargetService and TargetInstance only exist in client side - afterRequest.setTargetService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getTargetServiceInstance().getServiceId())); - afterRequest.setTargetInstance(instanceTransformer.transform(context.getTargetServiceInstance())); - - assemblyAPI.afterCallService(afterRequest); - } - - @Override - public int getOrder() { - return ASSEMBLY_PLUGIN_ORDER; - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientPreHook.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientPreHook.java deleted file mode 100644 index fde540277..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/client/AssemblyClientPreHook.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin.assembly.client; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext; -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import com.tencent.polaris.assembly.api.pojo.BeforeRequest; -import com.tencent.polaris.assembly.api.pojo.Capability; - -import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.ASSEMBLY_PLUGIN_ORDER; - -/** - * AssemblyClientPreHook. - * - * @author sean yu - */ -public class AssemblyClientPreHook implements EnhancedPlugin { - - private final AssemblyAPI assemblyAPI; - - public AssemblyClientPreHook(AssemblyAPI assemblyAPI) { - this.assemblyAPI = assemblyAPI; - } - - @Override - public EnhancedPluginType getType() { - return EnhancedPluginType.Client.PRE; - } - - @Override - public void run(EnhancedPluginContext context) { - - BeforeRequest beforeRequest = new BeforeRequest(); - beforeRequest.setCapabilities(new Capability[]{Capability.ALL}); - beforeRequest.setRequestContext(new AssemblyRequestContext( - context.getRequest(), - new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()), - context.getLocalServiceInstance().getHost() - )); - beforeRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE)); - // TargetService only exist in client side - beforeRequest.setTargetService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getTargetServiceInstance().getServiceId())); - - assemblyAPI.beforeCallService(beforeRequest); - } - - @Override - public int getOrder() { - return ASSEMBLY_PLUGIN_ORDER; - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerExceptionHook.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerExceptionHook.java deleted file mode 100644 index bde03d0d7..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerExceptionHook.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin.assembly.server; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; -import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyResponseContext; -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import com.tencent.polaris.assembly.api.pojo.AfterRequest; -import com.tencent.polaris.assembly.api.pojo.Capability; - -import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ServerPluginOrder.ASSEMBLY_PLUGIN_ORDER; - - -/** - * AssemblyServerExceptionHook. - * - * @author sean yu - */ -public class AssemblyServerExceptionHook implements EnhancedPlugin { - - private final AssemblyAPI assemblyAPI; - - public AssemblyServerExceptionHook(AssemblyAPI assemblyAPI) { - this.assemblyAPI = assemblyAPI; - } - - @Override - public EnhancedPluginType getType() { - return EnhancedPluginType.Server.EXCEPTION; - } - - @Override - public void run(EnhancedPluginContext context) { - AfterRequest afterRequest = new AfterRequest(); - afterRequest.setCapabilities(new Capability[]{Capability.ALL}); - afterRequest.setRequestContext(new AssemblyRequestContext( - context.getRequest(), - new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()), - context.getLocalServiceInstance().getHost() - )); - afterRequest.setResponseContext(new AssemblyResponseContext(null, context.getThrowable())); - afterRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE)); - afterRequest.setDelay(context.getDelay()); - afterRequest.setRouteLabels(PolarisEnhancedPluginUtils.getLabelMap(context.getRequest().getHttpHeaders())); - - assemblyAPI.afterProcess(afterRequest); - } - - @Override - public int getOrder() { - return ASSEMBLY_PLUGIN_ORDER; - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerPostHook.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerPostHook.java deleted file mode 100644 index 855994eb1..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerPostHook.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin.assembly.server; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; -import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyResponseContext; -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import com.tencent.polaris.assembly.api.pojo.AfterRequest; -import com.tencent.polaris.assembly.api.pojo.Capability; - -import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ServerPluginOrder.ASSEMBLY_PLUGIN_ORDER; - -/** - * AssemblyServerPostHook. - * - * @author sean yu - */ -public class AssemblyServerPostHook implements EnhancedPlugin { - - private final AssemblyAPI assemblyAPI; - - public AssemblyServerPostHook(AssemblyAPI assemblyAPI) { - this.assemblyAPI = assemblyAPI; - } - - @Override - public EnhancedPluginType getType() { - return EnhancedPluginType.Server.POST; - } - - @Override - public void run(EnhancedPluginContext context) { - AfterRequest afterRequest = new AfterRequest(); - afterRequest.setCapabilities(new Capability[]{Capability.ALL}); - afterRequest.setRequestContext(new AssemblyRequestContext( - context.getRequest(), - new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()), - context.getLocalServiceInstance().getHost() - )); - afterRequest.setResponseContext(new AssemblyResponseContext(context.getResponse(), null)); - afterRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE)); - afterRequest.setDelay(context.getDelay()); - afterRequest.setRouteLabels(PolarisEnhancedPluginUtils.getLabelMap(context.getRequest().getHttpHeaders())); - - assemblyAPI.afterProcess(afterRequest); - } - - @Override - public int getOrder() { - return ASSEMBLY_PLUGIN_ORDER; - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerPreHook.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerPreHook.java deleted file mode 100644 index 5b279b80d..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/assembly/server/AssemblyServerPreHook.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin.assembly.server; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; -import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext; -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import com.tencent.polaris.assembly.api.pojo.BeforeRequest; -import com.tencent.polaris.assembly.api.pojo.Capability; - -import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ServerPluginOrder.ASSEMBLY_PLUGIN_ORDER; - -/** - * AssemblyServerPreHook. - * - * @author sean yu - */ -public class AssemblyServerPreHook implements EnhancedPlugin { - - private final AssemblyAPI assemblyAPI; - - public AssemblyServerPreHook(AssemblyAPI assemblyAPI) { - this.assemblyAPI = assemblyAPI; - } - - @Override - public EnhancedPluginType getType() { - return EnhancedPluginType.Server.PRE; - } - - @Override - public void run(EnhancedPluginContext context) { - BeforeRequest beforeRequest = new BeforeRequest(); - beforeRequest.setCapabilities(new Capability[]{Capability.ALL}); - beforeRequest.setRequestContext(new AssemblyRequestContext( - context.getRequest(), - new ServiceKey(MetadataContext.LOCAL_NAMESPACE, context.getLocalServiceInstance().getServiceId()), - context.getLocalServiceInstance().getHost() - )); - beforeRequest.setMetadataProvider(new AssemblyMetadataProvider(context.getLocalServiceInstance(), MetadataContext.LOCAL_NAMESPACE)); - - assemblyAPI.beforeProcess(beforeRequest); - } - - @Override - public int getOrder() { - return ASSEMBLY_PLUGIN_ORDER; - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientExceptionHookTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientExceptionHookTest.java deleted file mode 100644 index d89006ccd..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientExceptionHookTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin; - -import java.net.URI; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.common.util.ApplicationContextAwareUtils; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientExceptionHook; -import com.tencent.cloud.rpc.enhancement.transformer.InstanceTransformer; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.context.ApplicationContext; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; - -import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; -import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * AssemblyClientExceptionHookTest. - * - * @author sean yu - */ -@ExtendWith(MockitoExtension.class) -public class AssemblyClientExceptionHookTest { - - private static MockedStatic mockedApplicationContextAwareUtils; - @InjectMocks - private AssemblyClientExceptionHook assemblyClientExceptionHook; - @Mock - private AssemblyAPI assemblyAPI; - @Mock - private InstanceTransformer instanceTransformer; - - @BeforeAll - static void beforeAll() { - mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); - mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) - .thenReturn("unit-test"); - ApplicationContext applicationContext = mock(ApplicationContext.class); - RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); - doReturn(reporterProperties) - .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); - mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) - .thenReturn(applicationContext); - } - - @AfterAll - static void afterAll() { - mockedApplicationContextAwareUtils.close(); - } - - @BeforeEach - void setUp() { - MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; - MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; - } - - @Test - public void testGetName() { - assertThat(assemblyClientExceptionHook.getName()).isEqualTo(AssemblyClientExceptionHook.class.getName()); - } - - @Test - public void testType() { - assertThat(assemblyClientExceptionHook.getType()).isEqualTo(EnhancedPluginType.Client.EXCEPTION); - } - - @Test - public void testRun() { - EnhancedPluginContext pluginContext = new EnhancedPluginContext(); - EnhancedRequestContext request = EnhancedRequestContext.builder() - .httpMethod(HttpMethod.GET) - .url(URI.create("http://0.0.0.0/")) - .httpHeaders(new HttpHeaders()) - .build(); - request.toString(); - EnhancedResponseContext response = EnhancedResponseContext.builder() - .httpStatus(200) - .build(); - response.toString(); - - DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance(); - targetServiceInstance.setServiceId(SERVICE_PROVIDER); - - DefaultServiceInstance localServiceInstance = new DefaultServiceInstance(); - localServiceInstance.setServiceId(SERVICE_PROVIDER); - - pluginContext.setRequest(request); - pluginContext.setResponse(response); - pluginContext.setTargetServiceInstance(targetServiceInstance, null); - pluginContext.setLocalServiceInstance(localServiceInstance); - pluginContext.setThrowable(new RuntimeException()); - - assemblyClientExceptionHook.run(pluginContext); - assemblyClientExceptionHook.getOrder(); - assemblyClientExceptionHook.getName(); - assemblyClientExceptionHook.getType(); - } - - @Test - public void testHandlerThrowable() { - // mock request - EnhancedRequestContext request = mock(EnhancedRequestContext.class); - // mock response - EnhancedResponseContext response = mock(EnhancedResponseContext.class); - - EnhancedPluginContext context = new EnhancedPluginContext(); - context.setRequest(request); - context.setResponse(response); - assemblyClientExceptionHook.handlerThrowable(context, new RuntimeException("Mock exception.")); - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientPostHookTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientPostHookTest.java deleted file mode 100644 index 9aa3f0d8e..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientPostHookTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin; - -import java.net.URI; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.common.util.ApplicationContextAwareUtils; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPostHook; -import com.tencent.cloud.rpc.enhancement.transformer.InstanceTransformer; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.context.ApplicationContext; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; - -import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; -import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * AssemblyClientPostHookTest. - * - * @author sean yu - */ -@ExtendWith(MockitoExtension.class) -public class AssemblyClientPostHookTest { - - private static MockedStatic mockedApplicationContextAwareUtils; - @InjectMocks - private AssemblyClientPostHook assemblyClientPostHook; - @Mock - private AssemblyAPI assemblyAPI; - @Mock - private InstanceTransformer instanceTransformer; - - @BeforeAll - static void beforeAll() { - mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); - mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) - .thenReturn("unit-test"); - ApplicationContext applicationContext = mock(ApplicationContext.class); - RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); - doReturn(reporterProperties) - .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); - mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) - .thenReturn(applicationContext); - } - - @AfterAll - static void afterAll() { - mockedApplicationContextAwareUtils.close(); - } - - @BeforeEach - void setUp() { - MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; - MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; - } - - @Test - public void testGetName() { - assertThat(assemblyClientPostHook.getName()).isEqualTo(AssemblyClientPostHook.class.getName()); - } - - @Test - public void testType() { - assertThat(assemblyClientPostHook.getType()).isEqualTo(EnhancedPluginType.Client.POST); - } - - @Test - public void testRun() { - EnhancedPluginContext pluginContext = new EnhancedPluginContext(); - EnhancedRequestContext request = EnhancedRequestContext.builder() - .httpMethod(HttpMethod.GET) - .url(URI.create("http://0.0.0.0/")) - .httpHeaders(new HttpHeaders()) - .build(); - request.toString(); - EnhancedResponseContext response = EnhancedResponseContext.builder() - .httpStatus(200) - .build(); - response.toString(); - - DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance(); - targetServiceInstance.setServiceId(SERVICE_PROVIDER); - - DefaultServiceInstance localServiceInstance = new DefaultServiceInstance(); - localServiceInstance.setServiceId(SERVICE_PROVIDER); - - pluginContext.setRequest(request); - pluginContext.setResponse(response); - pluginContext.setTargetServiceInstance(targetServiceInstance, null); - pluginContext.setLocalServiceInstance(localServiceInstance); - pluginContext.setThrowable(new RuntimeException()); - - assemblyClientPostHook.run(pluginContext); - assemblyClientPostHook.getOrder(); - assemblyClientPostHook.getName(); - assemblyClientPostHook.getType(); - } - - @Test - public void testHandlerThrowable() { - // mock request - EnhancedRequestContext request = mock(EnhancedRequestContext.class); - // mock response - EnhancedResponseContext response = mock(EnhancedResponseContext.class); - - EnhancedPluginContext context = new EnhancedPluginContext(); - context.setRequest(request); - context.setResponse(response); - assemblyClientPostHook.handlerThrowable(context, new RuntimeException("Mock exception.")); - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientPreHookTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientPreHookTest.java deleted file mode 100644 index f597c1026..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyClientPreHookTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin; - -import java.net.URI; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.common.util.ApplicationContextAwareUtils; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPreHook; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.context.ApplicationContext; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; - -import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; -import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * AssemblyClientPreHookTest. - * - * @author sean yu - */ -@ExtendWith(MockitoExtension.class) -public class AssemblyClientPreHookTest { - - private static MockedStatic mockedApplicationContextAwareUtils; - @InjectMocks - private AssemblyClientPreHook assemblyClientPreHook; - @Mock - private AssemblyAPI assemblyAPI; - - @BeforeAll - static void beforeAll() { - mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); - mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) - .thenReturn("unit-test"); - ApplicationContext applicationContext = mock(ApplicationContext.class); - RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); - doReturn(reporterProperties) - .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); - mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) - .thenReturn(applicationContext); - } - - @AfterAll - static void afterAll() { - mockedApplicationContextAwareUtils.close(); - } - - @BeforeEach - void setUp() { - MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; - MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; - } - - @Test - public void testGetName() { - assertThat(assemblyClientPreHook.getName()).isEqualTo(AssemblyClientPreHook.class.getName()); - } - - @Test - public void testType() { - assertThat(assemblyClientPreHook.getType()).isEqualTo(EnhancedPluginType.Client.PRE); - } - - @Test - public void testRun() { - EnhancedPluginContext pluginContext = new EnhancedPluginContext(); - EnhancedRequestContext request = EnhancedRequestContext.builder() - .httpMethod(HttpMethod.GET) - .url(URI.create("http://0.0.0.0/")) - .httpHeaders(new HttpHeaders()) - .build(); - request.toString(); - EnhancedResponseContext response = EnhancedResponseContext.builder() - .httpStatus(200) - .build(); - response.toString(); - - DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance(); - targetServiceInstance.setServiceId(SERVICE_PROVIDER); - - DefaultServiceInstance localServiceInstance = new DefaultServiceInstance(); - localServiceInstance.setServiceId(SERVICE_PROVIDER); - - pluginContext.setRequest(request); - pluginContext.setResponse(response); - pluginContext.setTargetServiceInstance(targetServiceInstance, null); - pluginContext.setLocalServiceInstance(localServiceInstance); - pluginContext.setThrowable(new RuntimeException()); - - assemblyClientPreHook.run(pluginContext); - assemblyClientPreHook.getOrder(); - assemblyClientPreHook.getName(); - assemblyClientPreHook.getType(); - } - - @Test - public void testHandlerThrowable() { - // mock request - EnhancedRequestContext request = mock(EnhancedRequestContext.class); - // mock response - EnhancedResponseContext response = mock(EnhancedResponseContext.class); - - EnhancedPluginContext context = new EnhancedPluginContext(); - context.setRequest(request); - context.setResponse(response); - assemblyClientPreHook.handlerThrowable(context, new RuntimeException("Mock exception.")); - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyMetadataProviderTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyMetadataProviderTest.java deleted file mode 100644 index 8a216977e..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyMetadataProviderTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin; - -import java.util.HashMap; -import java.util.Map; - -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyMetadataProvider; -import com.tencent.polaris.api.pojo.ServiceKey; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.ServiceInstance; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doReturn; - -/** - * AssemblyMetadataProviderTest. - * - * @author sean yu - */ -@ExtendWith(MockitoExtension.class) -public class AssemblyMetadataProviderTest { - - @Test - public void testAssemblyMetadataProvider() { - ServiceInstance serviceInstance = Mockito.mock(ServiceInstance.class); - Map metadata = new HashMap() {{ - put("k", "v"); - }}; - doReturn(metadata).when(serviceInstance).getMetadata(); - doReturn("0.0.0.0").when(serviceInstance).getHost(); - doReturn("test").when(serviceInstance).getServiceId(); - AssemblyMetadataProvider assemblyMetadataProvider = new AssemblyMetadataProvider(serviceInstance, "test"); - assertThat(assemblyMetadataProvider.getMetadata("k")).isEqualTo("v"); - assertThat(assemblyMetadataProvider.getLocalIp()).isEqualTo("0.0.0.0"); - assertThat(assemblyMetadataProvider.getLocalService()).isEqualTo(new ServiceKey("test", "test")); - } -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyRequestContextTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyRequestContextTest.java deleted file mode 100644 index de8f7f17f..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyRequestContextTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin; - -import java.net.URI; -import java.util.Arrays; -import java.util.HashSet; - -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyRequestContext; -import com.tencent.polaris.api.pojo.ServiceKey; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * AssemblyRequestContextTest. - * - * @author sean yu - */ -@ExtendWith(MockitoExtension.class) -public class AssemblyRequestContextTest { - - @Test - public void testAssemblyRequestContext() { - URI uri = URI.create("http://0.0.0.0/"); - - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.add("a", "a"); - httpHeaders.add(HttpHeaders.COOKIE, "cookies-k1=cookies-v1;cookies-k2=cookies-v2"); - - EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder() - .httpMethod(HttpMethod.GET) - .url(uri) - .httpHeaders(httpHeaders) - .build(); - - ServiceKey callerService = new ServiceKey("test", "test"); - AssemblyRequestContext assemblyRequestContext = new AssemblyRequestContext( - enhancedRequestContext, - callerService, - "0.0.0.0" - ); - - assertThat(assemblyRequestContext.getURI()).isEqualTo(uri); - - assertThat(assemblyRequestContext.getHeader("a")).isEqualTo("a"); - assemblyRequestContext.setHeader("b", "b"); - assertThat(assemblyRequestContext.listHeaderKeys()).isEqualTo(new HashSet<>(Arrays.asList(HttpHeaders.COOKIE, "a", "b"))); - - assertThat(assemblyRequestContext.getMethod()).isEqualTo(HttpMethod.GET.toString()); - assemblyRequestContext.setMethod(HttpMethod.OPTIONS.name()); - assertThat(assemblyRequestContext.getMethod()).isEqualTo(HttpMethod.OPTIONS.toString()); - - assertThat(assemblyRequestContext.getCookie("cookies-k1")).isEqualTo("cookies-v1"); - assertThat(assemblyRequestContext.getCookie("cookies-k2")).isEqualTo("cookies-v2"); - assemblyRequestContext.setCookie("cookies-k3", "cookies-v3"); - assertThat(assemblyRequestContext.listCookieKeys()).isEqualTo(new HashSet<>(Arrays.asList("cookies-k1", "cookies-k2", "cookies-k3"))); - - assertThat(assemblyRequestContext.getCallerService()).isEqualTo(callerService); - assertThat(assemblyRequestContext.getCallerIp()).isEqualTo("0.0.0.0"); - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyResponseContextTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyResponseContextTest.java deleted file mode 100644 index d3c96e899..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyResponseContextTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin; - -import java.net.SocketTimeoutException; -import java.util.Arrays; -import java.util.HashSet; - -import com.tencent.cloud.common.util.ApplicationContextAwareUtils; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.AssemblyResponseContext; -import com.tencent.polaris.api.pojo.RetStatus; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.context.ApplicationContext; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * AssemblyResponseContextTest. - * - * @author sean yu - */ -@ExtendWith(MockitoExtension.class) -public class AssemblyResponseContextTest { - - private static MockedStatic mockedApplicationContextAwareUtils; - - @BeforeAll - static void beforeAll() { - mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); - mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) - .thenReturn("unit-test"); - ApplicationContext applicationContext = mock(ApplicationContext.class); - RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); - doReturn(reporterProperties) - .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); - mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) - .thenReturn(applicationContext); - } - - @AfterAll - static void afterAll() { - mockedApplicationContextAwareUtils.close(); - } - - @Test - public void testAssemblyResponseContext() { - - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.add("a", "a"); - - EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder() - .httpHeaders(httpHeaders) - .httpStatus(HttpStatus.OK.value()) - .build(); - - AssemblyResponseContext assemblyResponseContext = new AssemblyResponseContext(enhancedResponseContext, null); - assertThat(assemblyResponseContext.getHeader("a")).isEqualTo("a"); - assertThat(assemblyResponseContext.getRetCode()).isEqualTo(HttpStatus.OK.value()); - assertThat(assemblyResponseContext.getThrowable()).isEqualTo(null); - assertThat(assemblyResponseContext.getRetStatus()).isEqualTo(RetStatus.RetSuccess); - assertThat(assemblyResponseContext.listHeaders()).isEqualTo(new HashSet<>(Arrays.asList("a"))); - - Throwable e = new SocketTimeoutException(); - assemblyResponseContext = new AssemblyResponseContext(null, e); - assertThat(assemblyResponseContext.getHeader("a")).isEqualTo(null); - assertThat(assemblyResponseContext.getRetCode()).isEqualTo(null); - assertThat(assemblyResponseContext.getThrowable()).isEqualTo(e); - assertThat(assemblyResponseContext.getRetStatus()).isEqualTo(RetStatus.RetTimeout); - assertThat(assemblyResponseContext.listHeaders()).isEqualTo(null); - - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerExceptionHookTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerExceptionHookTest.java deleted file mode 100644 index ff04c578a..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerExceptionHookTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin; - -import java.net.URI; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.common.util.ApplicationContextAwareUtils; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerExceptionHook; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.context.ApplicationContext; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; - -import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; -import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * AssemblyServerExceptionHookTest. - * - * @author sean yu - */ -@ExtendWith(MockitoExtension.class) -public class AssemblyServerExceptionHookTest { - - private static MockedStatic mockedApplicationContextAwareUtils; - @InjectMocks - private AssemblyServerExceptionHook assemblyServerExceptionHook; - @Mock - private AssemblyAPI assemblyAPI; - - @BeforeAll - static void beforeAll() { - mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); - mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) - .thenReturn("unit-test"); - ApplicationContext applicationContext = mock(ApplicationContext.class); - RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); - doReturn(reporterProperties) - .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); - mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) - .thenReturn(applicationContext); - } - - @AfterAll - static void afterAll() { - mockedApplicationContextAwareUtils.close(); - } - - @BeforeEach - void setUp() { - MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; - MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; - } - - @Test - public void testGetName() { - assertThat(assemblyServerExceptionHook.getName()).isEqualTo(AssemblyServerExceptionHook.class.getName()); - } - - @Test - public void testType() { - assertThat(assemblyServerExceptionHook.getType()).isEqualTo(EnhancedPluginType.Server.EXCEPTION); - } - - @Test - public void testRun() { - EnhancedPluginContext pluginContext = new EnhancedPluginContext(); - EnhancedRequestContext request = EnhancedRequestContext.builder() - .httpMethod(HttpMethod.GET) - .url(URI.create("http://0.0.0.0/")) - .httpHeaders(new HttpHeaders()) - .build(); - request.toString(); - EnhancedResponseContext response = EnhancedResponseContext.builder() - .httpStatus(200) - .build(); - response.toString(); - - DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance(); - targetServiceInstance.setServiceId(SERVICE_PROVIDER); - - DefaultServiceInstance localServiceInstance = new DefaultServiceInstance(); - localServiceInstance.setServiceId(SERVICE_PROVIDER); - - pluginContext.setRequest(request); - pluginContext.setResponse(response); - pluginContext.setTargetServiceInstance(targetServiceInstance, null); - pluginContext.setLocalServiceInstance(localServiceInstance); - pluginContext.setThrowable(new RuntimeException()); - - assemblyServerExceptionHook.run(pluginContext); - assemblyServerExceptionHook.getOrder(); - assemblyServerExceptionHook.getName(); - assemblyServerExceptionHook.getType(); - } - - @Test - public void testHandlerThrowable() { - // mock request - EnhancedRequestContext request = mock(EnhancedRequestContext.class); - // mock response - EnhancedResponseContext response = mock(EnhancedResponseContext.class); - - EnhancedPluginContext context = new EnhancedPluginContext(); - context.setRequest(request); - context.setResponse(response); - assemblyServerExceptionHook.handlerThrowable(context, new RuntimeException("Mock exception.")); - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerPostHookTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerPostHookTest.java deleted file mode 100644 index a15cd5796..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerPostHookTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin; - -import java.net.URI; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.common.util.ApplicationContextAwareUtils; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPostHook; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.context.ApplicationContext; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; - -import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; -import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * AssemblyServerPostHookTest. - * - * @author sean yu - */ -@ExtendWith(MockitoExtension.class) -public class AssemblyServerPostHookTest { - - private static MockedStatic mockedApplicationContextAwareUtils; - @InjectMocks - private AssemblyServerPostHook assemblyServerPostHook; - @Mock - private AssemblyAPI assemblyAPI; - - @BeforeAll - static void beforeAll() { - mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); - mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) - .thenReturn("unit-test"); - ApplicationContext applicationContext = mock(ApplicationContext.class); - RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); - doReturn(reporterProperties) - .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); - mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) - .thenReturn(applicationContext); - } - - @AfterAll - static void afterAll() { - mockedApplicationContextAwareUtils.close(); - } - - @BeforeEach - void setUp() { - MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; - MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; - } - - @Test - public void testGetName() { - assertThat(assemblyServerPostHook.getName()).isEqualTo(AssemblyServerPostHook.class.getName()); - } - - @Test - public void testType() { - assertThat(assemblyServerPostHook.getType()).isEqualTo(EnhancedPluginType.Server.POST); - } - - @Test - public void testRun() { - EnhancedPluginContext pluginContext = new EnhancedPluginContext(); - EnhancedRequestContext request = EnhancedRequestContext.builder() - .httpMethod(HttpMethod.GET) - .url(URI.create("http://0.0.0.0/")) - .httpHeaders(new HttpHeaders()) - .build(); - request.toString(); - EnhancedResponseContext response = EnhancedResponseContext.builder() - .httpStatus(200) - .build(); - response.toString(); - - DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance(); - targetServiceInstance.setServiceId(SERVICE_PROVIDER); - - DefaultServiceInstance localServiceInstance = new DefaultServiceInstance(); - localServiceInstance.setServiceId(SERVICE_PROVIDER); - - pluginContext.setRequest(request); - pluginContext.setResponse(response); - pluginContext.setTargetServiceInstance(targetServiceInstance, null); - pluginContext.setLocalServiceInstance(localServiceInstance); - pluginContext.setThrowable(new RuntimeException()); - - assemblyServerPostHook.run(pluginContext); - assemblyServerPostHook.getOrder(); - assemblyServerPostHook.getName(); - assemblyServerPostHook.getType(); - } - - @Test - public void testHandlerThrowable() { - // mock request - EnhancedRequestContext request = mock(EnhancedRequestContext.class); - // mock response - EnhancedResponseContext response = mock(EnhancedResponseContext.class); - - EnhancedPluginContext context = new EnhancedPluginContext(); - context.setRequest(request); - context.setResponse(response); - assemblyServerPostHook.handlerThrowable(context, new RuntimeException("Mock exception.")); - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerPreHookTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerPreHookTest.java deleted file mode 100644 index 8bfe4c9a0..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/AssemblyServerPreHookTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.rpc.enhancement.plugin; - -import java.net.URI; - -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.common.util.ApplicationContextAwareUtils; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.cloud.rpc.enhancement.plugin.assembly.server.AssemblyServerPreHook; -import com.tencent.polaris.assembly.api.AssemblyAPI; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.context.ApplicationContext; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; - -import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; -import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * AssemblyServerPreHookTest. - * - * @author sean yu - */ -@ExtendWith(MockitoExtension.class) -public class AssemblyServerPreHookTest { - - private static MockedStatic mockedApplicationContextAwareUtils; - @InjectMocks - private AssemblyServerPreHook assemblyServerPreHook; - @Mock - private AssemblyAPI assemblyAPI; - - @BeforeAll - static void beforeAll() { - mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); - mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) - .thenReturn("unit-test"); - ApplicationContext applicationContext = mock(ApplicationContext.class); - RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); - doReturn(reporterProperties) - .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); - mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) - .thenReturn(applicationContext); - } - - @AfterAll - static void afterAll() { - mockedApplicationContextAwareUtils.close(); - } - - @BeforeEach - void setUp() { - MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; - MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; - } - - @Test - public void testGetName() { - assertThat(assemblyServerPreHook.getName()).isEqualTo(AssemblyServerPreHook.class.getName()); - } - - @Test - public void testType() { - assertThat(assemblyServerPreHook.getType()).isEqualTo(EnhancedPluginType.Server.PRE); - } - - @Test - public void testRun() { - EnhancedPluginContext pluginContext = new EnhancedPluginContext(); - EnhancedRequestContext request = EnhancedRequestContext.builder() - .httpMethod(HttpMethod.GET) - .url(URI.create("http://0.0.0.0/")) - .httpHeaders(new HttpHeaders()) - .build(); - request.toString(); - EnhancedResponseContext response = EnhancedResponseContext.builder() - .httpStatus(200) - .build(); - response.toString(); - - DefaultServiceInstance targetServiceInstance = new DefaultServiceInstance(); - targetServiceInstance.setServiceId(SERVICE_PROVIDER); - - DefaultServiceInstance localServiceInstance = new DefaultServiceInstance(); - localServiceInstance.setServiceId(SERVICE_PROVIDER); - - pluginContext.setRequest(request); - pluginContext.setResponse(response); - pluginContext.setTargetServiceInstance(targetServiceInstance, null); - pluginContext.setLocalServiceInstance(localServiceInstance); - pluginContext.setThrowable(new RuntimeException()); - - assemblyServerPreHook.run(pluginContext); - assemblyServerPreHook.getOrder(); - assemblyServerPreHook.getName(); - assemblyServerPreHook.getType(); - } - - @Test - public void testHandlerThrowable() { - // mock request - EnhancedRequestContext request = mock(EnhancedRequestContext.class); - // mock response - EnhancedResponseContext response = mock(EnhancedResponseContext.class); - - EnhancedPluginContext context = new EnhancedPluginContext(); - context.setRequest(request); - context.setResponse(response); - assemblyServerPreHook.handlerThrowable(context, new RuntimeException("Mock exception.")); - } - -} From edfb7a73885d39f501200bb6da3f25eef8a5fcaa Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Tue, 26 Sep 2023 18:55:34 +0800 Subject: [PATCH 07/10] feat:add swagger exposure filters. (#1146) --- CHANGELOG.md | 3 +- README-zh.md | 2 +- README.md | 2 +- pom.xml | 2 +- .../contract/PolarisContractReporter.java | 11 +-- .../contract/config/ContractProperties.java | 4 + .../config/PolarisContractProperties.java | 15 ++++ .../PolarisSwaggerAutoConfiguration.java | 68 +++++++++++++++-- .../contract/filter/ApiDocServletFilter.java | 73 +++++++++++++++++++ .../contract/filter/ApiDocWebFluxFilter.java | 71 ++++++++++++++++++ .../contract/filter/FilterConstant.java | 64 ++++++++++++++++ .../polaris/contract/utils/PackageUtil.java | 1 - ...itional-spring-configuration-metadata.json | 40 ++++++++++ .../discovery-callee-service/pom.xml | 8 +- .../src/main/resources/bootstrap.yml | 2 + .../src/main/resources/bootstrap.yml | 2 + 16 files changed, 346 insertions(+), 22 deletions(-) create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocServletFilter.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocWebFluxFilter.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/FilterConstant.java create mode 100644 spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json diff --git a/CHANGELOG.md b/CHANGELOG.md index d61a882fa..6c9822955 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,4 +8,5 @@ - [feat: support log path configuration parameters.](https://github.com/Tencent/spring-cloud-tencent/pull/1128) - [refactor:optimize the order and condition matching of service registration automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1129) - [feat: add circuit breaker actuator.](https://github.com/Tencent/spring-cloud-tencent/pull/1136) -- [feat:support service contract reporting.](https://github.com/Tencent/spring-cloud-tencent/pull/1139) \ No newline at end of file +- [feat:support service contract reporting.](https://github.com/Tencent/spring-cloud-tencent/pull/1139) +- [feat:add swagger exposure filters.](https://github.com/Tencent/spring-cloud-tencent/pull/1146) diff --git a/README-zh.md b/README-zh.md index 548c7ff73..b4447195a 100644 --- a/README-zh.md +++ b/README-zh.md @@ -78,7 +78,7 @@ Spring Cloud Tencent 所有组件都已上传到 Maven 中央仓库,只需要 com.tencent.cloud spring-cloud-tencent-dependencies - 1.12.0-2021.0.8 + 1.12.1-2021.0.8 pom import diff --git a/README.md b/README.md index 17092db54..2cb1f52e7 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ For example: com.tencent.cloud spring-cloud-tencent-dependencies - 1.12.0-2021.0.8 + 1.12.1-2021.0.8 pom import diff --git a/pom.xml b/pom.xml index 09ad0369b..2b46501a1 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ 1.13.0-2021.0.8-SNAPSHOT - 5.3.29 + 5.3.25 2.6.15 diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java index dd421b45b..2321c0c90 100644 --- a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java @@ -36,7 +36,6 @@ import org.slf4j.LoggerFactory; import springfox.documentation.service.Documentation; import springfox.documentation.spring.web.DocumentationCache; -import springfox.documentation.spring.web.json.JsonSerializer; import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper; import org.springframework.boot.context.event.ApplicationReadyEvent; @@ -44,12 +43,16 @@ import org.springframework.lang.NonNull; import org.springframework.util.CollectionUtils; +/** + * Polaris contract reporter. + * + * @author Haotian Zhang + */ public class PolarisContractReporter implements ApplicationListener { private final Logger LOG = LoggerFactory.getLogger(PolarisContractReporter.class); private final ServiceModelToSwagger2Mapper swagger2Mapper; private final DocumentationCache documentationCache; - private final JsonSerializer jsonSerializer; private final String groupName; private final ProviderAPI providerAPI; @@ -57,11 +60,9 @@ public class PolarisContractReporter implements ApplicationListener void customizeSpringfoxHandlerMappings(List mappings) { + List copy = mappings.stream() + .filter(mapping -> mapping.getPatternParser() == null) + .collect(Collectors.toList()); + mappings.clear(); + mappings.addAll(copy); + } + + @SuppressWarnings("unchecked") + private List getHandlerMappings(Object bean) { + try { + Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); + field.setAccessible(true); + return (List) field.get(bean); + } + catch (IllegalArgumentException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + } + }; + } + @Bean + public ApiDocServletFilter apiDocServletFilter(PolarisContractProperties polarisContractProperties) { + return new ApiDocServletFilter(polarisContractProperties); + } } /** @@ -142,6 +191,9 @@ protected static class SwaggerServletConfig { @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) protected static class SwaggerReactiveConfig { - + @Bean + public ApiDocWebFluxFilter apiDocWebFluxFilter(PolarisContractProperties polarisContractProperties) { + return new ApiDocWebFluxFilter(polarisContractProperties); + } } } diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocServletFilter.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocServletFilter.java new file mode 100644 index 000000000..38aa3d7c9 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocServletFilter.java @@ -0,0 +1,73 @@ +/* + * 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.contract.filter; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.tencent.cloud.polaris.contract.config.PolarisContractProperties; + +import org.springframework.lang.NonNull; +import org.springframework.web.filter.OncePerRequestFilter; + +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_RESOURCE_PREFIX; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_UI_V2_URL; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_UI_V3_URL; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_V2_API_DOC_URL; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_V3_API_DOC_URL; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_WEBJARS_V2_PREFIX; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_WEBJARS_V3_PREFIX; + +/** + * Filter to disable api doc controller. + * + * @author Haotian Zhang + */ +public class ApiDocServletFilter extends OncePerRequestFilter { + + private final PolarisContractProperties polarisContractProperties; + + public ApiDocServletFilter(PolarisContractProperties polarisContractProperties) { + this.polarisContractProperties = polarisContractProperties; + } + + @Override + public void doFilterInternal(@NonNull HttpServletRequest httpServletRequest, + @NonNull HttpServletResponse httpServletResponse, @NonNull FilterChain filterChain) + throws ServletException, IOException { + if (!polarisContractProperties.isExposure()) { + String path = httpServletRequest.getServletPath(); + if (path.startsWith(SWAGGER_V2_API_DOC_URL) || + path.startsWith(SWAGGER_V3_API_DOC_URL) || + path.startsWith(SWAGGER_UI_V2_URL) || + path.startsWith(SWAGGER_UI_V3_URL) || + path.startsWith(SWAGGER_RESOURCE_PREFIX) || + path.startsWith(SWAGGER_WEBJARS_V2_PREFIX) || + path.startsWith(SWAGGER_WEBJARS_V3_PREFIX)) { + httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); + return; + } + } + filterChain.doFilter(httpServletRequest, httpServletResponse); + } +} + diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocWebFluxFilter.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocWebFluxFilter.java new file mode 100644 index 000000000..7e7ea199a --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/ApiDocWebFluxFilter.java @@ -0,0 +1,71 @@ +/* + * 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.contract.filter; + + +import com.tencent.cloud.polaris.contract.config.PolarisContractProperties; +import reactor.core.publisher.Mono; + +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; + +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_RESOURCE_PREFIX; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_UI_V2_URL; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_UI_V3_URL; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_V2_API_DOC_URL; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_V3_API_DOC_URL; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_WEBJARS_V2_PREFIX; +import static com.tencent.cloud.polaris.contract.filter.FilterConstant.SWAGGER_WEBJARS_V3_PREFIX; + +/** + * Filter to disable api doc controller. + * + * @author Haotian Zhang + */ +public class ApiDocWebFluxFilter implements WebFilter { + private final PolarisContractProperties polarisContractProperties; + + public ApiDocWebFluxFilter(PolarisContractProperties polarisContractProperties) { + this.polarisContractProperties = polarisContractProperties; + } + + @Override + public Mono filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) { + if (!polarisContractProperties.isExposure()) { + String path = serverWebExchange.getRequest().getURI().getPath(); + if (path.startsWith(SWAGGER_V2_API_DOC_URL) || + path.startsWith(SWAGGER_V3_API_DOC_URL) || + path.startsWith(SWAGGER_UI_V2_URL) || + path.startsWith(SWAGGER_UI_V3_URL) || + path.startsWith(SWAGGER_RESOURCE_PREFIX) || + path.startsWith(SWAGGER_WEBJARS_V2_PREFIX) || + path.startsWith(SWAGGER_WEBJARS_V3_PREFIX)) { + ServerHttpResponse response = serverWebExchange.getResponse(); + response.setRawStatusCode(HttpStatus.FORBIDDEN.value()); + DataBuffer dataBuffer = response.bufferFactory().allocateBuffer(); + return response.writeWith(Mono.just(dataBuffer)); + } + } + return webFilterChain.filter(serverWebExchange); + } +} + diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/FilterConstant.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/FilterConstant.java new file mode 100644 index 000000000..d95ae14fa --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/filter/FilterConstant.java @@ -0,0 +1,64 @@ +/* + * 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.contract.filter; + +/** + * Constant for filter. + * + * @author Haotian Zhang + */ +public final class FilterConstant { + + /** + * Swagger api doc V2 url. + */ + public static final String SWAGGER_V2_API_DOC_URL = "/v2/api-docs"; + + /** + * Swagger api doc V3 url. + */ + public static final String SWAGGER_V3_API_DOC_URL = "/v3/api-docs"; + + /** + * Swagger UI V2 url. + */ + public static final String SWAGGER_UI_V2_URL = "/swagger-ui.html"; + + /** + * Swagger UI V3 url. + */ + public static final String SWAGGER_UI_V3_URL = "/swagger-ui/index.html"; + + /** + * Swagger resource url prefix. + */ + public static final String SWAGGER_RESOURCE_PREFIX = "/swagger-resource/"; + + /** + * Swagger webjars V2 url prefix. + */ + public static final String SWAGGER_WEBJARS_V2_PREFIX = "/webjars/springfox-swagger-ui/"; + + /** + * Swagger webjars V3 url prefix. + */ + public static final String SWAGGER_WEBJARS_V3_PREFIX = "/webjars/swagger-ui/"; + + private FilterConstant() { + } +} diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java index 7ce8a7ec2..1ce380cf5 100644 --- a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/utils/PackageUtil.java @@ -48,7 +48,6 @@ public final class PackageUtil { private static final String SPLITTER = ","; - private PackageUtil() { } diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000..4e5e4b72d --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,40 @@ +{ + "properties": [ + { + "name": "spring.cloud.polaris.contract.enabled", + "type": "java.lang.Boolean", + "defaultValue": true, + "description": "Enable polaris record contract or not." + }, + { + "name": "spring.cloud.polaris.contract.basePackage", + "type": "java.lang.String", + "defaultValue": "", + "description": "Packages to be scanned. Split by \",\"." + }, + { + "name": "spring.cloud.polaris.contract.excludePath", + "type": "java.lang.String", + "defaultValue": "", + "description": "Paths to be excluded. Split by \",\"." + }, + { + "name": "spring.cloud.polaris.contract.group", + "type": "java.lang.String", + "defaultValue": "default", + "description": "Group to create swagger docket." + }, + { + "name": "spring.cloud.polaris.contract.basePath", + "type": "java.lang.String", + "defaultValue": "/**", + "description": "Base paths to be scanned. Split by \",\"." + }, + { + "name": "spring.cloud.polaris.contract.exposure", + "type": "java.lang.Boolean", + "defaultValue": "true", + "description": "Enable polaris contract exposure or not." + } + ] +} diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml index 9b974df4c..312b45c1a 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml @@ -19,10 +19,10 @@ spring-boot-starter-webflux - - - - + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-contract + com.tencent.cloud diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml index ec34c0c35..1f3a5b9e5 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml @@ -11,6 +11,8 @@ spring: discovery: enabled: true register: true + contract: + exposure: true stat: enabled: true port: 28082 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 71f388051..bcd78ef70 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 @@ -22,6 +22,8 @@ spring: heartbeat: enabled: true health-check-url: /discovery/service/caller/healthCheck + contract: + exposure: true stat: enabled: true port: 28081 From d7d9a75b63564c86ed04b33bd77edd4d142a8363 Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Tue, 26 Sep 2023 20:11:27 +0800 Subject: [PATCH 08/10] feat:add swagger report switch. (#1148) --- CHANGELOG.md | 1 + .../contract/PolarisContractReporter.java | 59 ++++++++++--------- .../contract/config/ContractProperties.java | 4 ++ .../config/PolarisContractProperties.java | 14 +++++ .../PolarisSwaggerAutoConfiguration.java | 2 +- ...itional-spring-configuration-metadata.json | 6 ++ .../src/main/resources/bootstrap.yml | 2 + 7 files changed, 59 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c9822955..4e9baac6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,3 +10,4 @@ - [feat: add circuit breaker actuator.](https://github.com/Tencent/spring-cloud-tencent/pull/1136) - [feat:support service contract reporting.](https://github.com/Tencent/spring-cloud-tencent/pull/1139) - [feat:add swagger exposure filters.](https://github.com/Tencent/spring-cloud-tencent/pull/1146) +- [feat:add swagger report switch.](https://github.com/Tencent/spring-cloud-tencent/pull/1148) diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java index 2321c0c90..1470136e8 100644 --- a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/PolarisContractReporter.java @@ -24,6 +24,7 @@ import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.contract.config.PolarisContractProperties; import com.tencent.polaris.api.core.ProviderAPI; import com.tencent.polaris.api.plugin.server.InterfaceDescriptor; import com.tencent.polaris.api.plugin.server.ReportServiceContractRequest; @@ -53,52 +54,54 @@ public class PolarisContractReporter implements ApplicationListener interfaceDescriptorList = getInterfaceDescriptorFromSwagger(swagger); - request.setInterfaceDescriptors(interfaceDescriptorList); - ReportServiceContractResponse response = providerAPI.reportServiceContract(request); - LOG.info("Service contract [Namespace: {}. Name: {}. Service: {}. Protocol:{}. Version: {}. API counter: {}] is reported.", - request.getNamespace(), request.getName(), request.getService(), request.getProtocol(), - request.getVersion(), request.getInterfaceDescriptors().size()); - if (LOG.isDebugEnabled()) { - String jsonValue = JacksonUtils.serialize2Json(swagger); - LOG.debug("OpenApi json data: {}", jsonValue); + if (polarisContractProperties.isReportEnabled()) { + try { + Documentation documentation = documentationCache.documentationByGroup(polarisContractProperties.getGroup()); + Swagger swagger = swagger2Mapper.mapDocumentation(documentation); + if (swagger != null) { + ReportServiceContractRequest request = new ReportServiceContractRequest(); + request.setName(polarisDiscoveryProperties.getService()); + request.setNamespace(polarisDiscoveryProperties.getNamespace()); + request.setService(polarisDiscoveryProperties.getService()); + request.setProtocol("http"); + request.setVersion(polarisDiscoveryProperties.getVersion()); + List interfaceDescriptorList = getInterfaceDescriptorFromSwagger(swagger); + request.setInterfaceDescriptors(interfaceDescriptorList); + ReportServiceContractResponse response = providerAPI.reportServiceContract(request); + LOG.info("Service contract [Namespace: {}. Name: {}. Service: {}. Protocol:{}. Version: {}. API counter: {}] is reported.", + request.getNamespace(), request.getName(), request.getService(), request.getProtocol(), + request.getVersion(), request.getInterfaceDescriptors().size()); + if (LOG.isDebugEnabled()) { + String jsonValue = JacksonUtils.serialize2Json(swagger); + LOG.debug("OpenApi json data: {}", jsonValue); + } + } + else { + LOG.warn("Swagger or json is null, documentationCache keys:{}, group:{}", documentationCache.all() + .keySet(), polarisContractProperties.getGroup()); } } - else { - LOG.warn("Swagger or json is null, documentationCache keys:{}, group:{}", documentationCache.all() - .keySet(), groupName); + catch (Throwable t) { + LOG.error("Report contract failed.", t); } } - catch (Throwable t) { - LOG.error("Report contract failed.", t); - } } private List getInterfaceDescriptorFromSwagger(Swagger swagger) { diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ContractProperties.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ContractProperties.java index 3e915f5d4..7a34c8360 100644 --- a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ContractProperties.java +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/ContractProperties.java @@ -47,4 +47,8 @@ public interface ContractProperties { boolean isExposure(); void setExposure(boolean exposure); + + boolean isReportEnabled(); + + void setReportEnabled(boolean reportEnabled); } diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractProperties.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractProperties.java index 68681ae36..2b43226a5 100644 --- a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractProperties.java +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisContractProperties.java @@ -21,6 +21,7 @@ import javax.annotation.Nullable; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -53,6 +54,9 @@ public class PolarisContractProperties implements ContractProperties { private boolean exposure = true; + @Value("${spring.cloud.polaris.contract.report.enabled:true}") + private boolean reportEnabled = true; + public PolarisContractProperties(@Nullable ExtendedContractProperties extendContractProperties) { this.extendContractProperties = extendContractProperties; } @@ -134,4 +138,14 @@ public boolean isExposure() { public void setExposure(boolean exposure) { this.exposure = exposure; } + + @Override + public boolean isReportEnabled() { + return reportEnabled; + } + + @Override + public void setReportEnabled(boolean reportEnabled) { + this.reportEnabled = reportEnabled; + } } diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisSwaggerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisSwaggerAutoConfiguration.java index 7bb8a5673..858fd9565 100644 --- a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisSwaggerAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/config/PolarisSwaggerAutoConfiguration.java @@ -128,7 +128,7 @@ public Docket polarisDocket(PolarisContractProperties polarisContractProperties) public PolarisContractReporter polarisContractReporter(DocumentationCache documentationCache, ServiceModelToSwagger2Mapper swagger2Mapper, PolarisContractProperties polarisContractProperties, PolarisSDKContextManager polarisSDKContextManager, PolarisDiscoveryProperties polarisDiscoveryProperties) { - return new PolarisContractReporter(documentationCache, swagger2Mapper, polarisContractProperties.getGroup(), + return new PolarisContractReporter(documentationCache, swagger2Mapper, polarisContractProperties, polarisSDKContextManager.getProviderAPI(), polarisDiscoveryProperties); } diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 4e5e4b72d..0ef878076 100644 --- a/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -35,6 +35,12 @@ "type": "java.lang.Boolean", "defaultValue": "true", "description": "Enable polaris contract exposure or not." + }, + { + "name": "spring.cloud.polaris.contract.report.enabled", + "type": "java.lang.Boolean", + "defaultValue": "true", + "description": "Enable polaris contract report or not." } ] } 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 bcd78ef70..f75a5c4a6 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 @@ -24,6 +24,8 @@ spring: health-check-url: /discovery/service/caller/healthCheck contract: exposure: true + report: + enabled: true stat: enabled: true port: 28081 From 4dc7ab9218a657815b1d8693cd48e33d96299aa9 Mon Sep 17 00:00:00 2001 From: wenxuan70 Date: Wed, 27 Sep 2023 09:55:38 +0800 Subject: [PATCH 09/10] feat: add metadata transfer for http header via spring.cloud.tencent.metadata.headers (#1137) --- CHANGELOG.md | 1 + .../metadata/MetadataContextHolder.java | 4 +-- .../metadata/StaticMetadataManager.java | 30 +++++++++++++++++++ .../config/MetadataLocalProperties.java | 16 ++++++++++ ...itional-spring-configuration-metadata.json | 5 ++++ .../metadata/MetadataContextHolderTest.java | 8 +++++ .../metadata/StaticMetadataManagerTest.java | 11 +++++++ .../config/MetadataLocalPropertiesTest.java | 6 ++++ .../src/test/resources/application-test.yml | 3 ++ 9 files changed, 82 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e9baac6d..afd75ffba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - [feat: support log path configuration parameters.](https://github.com/Tencent/spring-cloud-tencent/pull/1128) - [refactor:optimize the order and condition matching of service registration automatic configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1129) - [feat: add circuit breaker actuator.](https://github.com/Tencent/spring-cloud-tencent/pull/1136) +- [feat: add metadata transfer for http header via spring.cloud.tencent.metadata.headers.](https://github.com/Tencent/spring-cloud-tencent/pull/1137) - [feat:support service contract reporting.](https://github.com/Tencent/spring-cloud-tencent/pull/1139) - [feat:add swagger exposure filters.](https://github.com/Tencent/spring-cloud-tencent/pull/1146) - [feat:add swagger report switch.](https://github.com/Tencent/spring-cloud-tencent/pull/1148) 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 f6307ae32..db9d1e5b2 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 @@ -68,8 +68,8 @@ public static MetadataContext get() { metadataContext.setTransitiveMetadata(staticMetadataManager.getMergedStaticTransitiveMetadata()); metadataContext.setDisposableMetadata(staticMetadataManager.getMergedStaticDisposableMetadata()); - if (StringUtils.hasText(staticMetadataManager.getTransHeaderFromEnv())) { - metadataContext.setTransHeaders(staticMetadataManager.getTransHeaderFromEnv(), ""); + if (StringUtils.hasText(staticMetadataManager.getTransHeader())) { + metadataContext.setTransHeaders(staticMetadataManager.getTransHeader(), ""); } METADATA_CONTEXT.set(metadataContext); 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 d37deb006..f0171cebb 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 @@ -17,8 +17,11 @@ package com.tencent.cloud.common.metadata; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -71,6 +74,7 @@ public class StaticMetadataManager { private Map configMetadata; private Map configTransitiveMetadata; private Map configDisposableMetadata; + private String configTransHeaders; private Map customSPIMetadata; private Map customSPITransitiveMetadata; private Map customSPIDisposableMetadata; @@ -162,6 +166,7 @@ private void parseConfigMetadata(MetadataLocalProperties metadataLocalProperties Map allMetadata = metadataLocalProperties.getContent(); List transitiveKeys = metadataLocalProperties.getTransitive(); List disposableKeys = metadataLocalProperties.getDisposable(); + List headers = metadataLocalProperties.getHeaders(); Map transitiveResult = new HashMap<>(); for (String key : transitiveKeys) { @@ -179,6 +184,7 @@ private void parseConfigMetadata(MetadataLocalProperties metadataLocalProperties configTransitiveMetadata = Collections.unmodifiableMap(transitiveResult); configDisposableMetadata = Collections.unmodifiableMap(disposableResult); + configTransHeaders = CollectionUtils.isEmpty(headers) ? null : String.join(",", headers); configMetadata = Collections.unmodifiableMap(allMetadata); } @@ -313,6 +319,29 @@ public String getTransHeaderFromEnv() { return envNotReportMetadata.get(ENV_TRAFFIC_CONTENT_RAW_TRANSHEADERS); } + public String getTransHeaderFromConfig() { + return configTransHeaders; + } + + public String getTransHeader() { + Set transHeaderSet = new HashSet<>(); + + String transHeaderFromEnv = getTransHeaderFromEnv(); + String transHeaderFromConfig = getTransHeaderFromConfig(); + + Set transHeaderFromEnvSet = StringUtils.isNotBlank(transHeaderFromEnv) + ? Arrays.stream(transHeaderFromEnv.split(",")).collect(Collectors.toSet()) + : Collections.emptySet(); + Set transHeaderFromConfigSet = StringUtils.isNotBlank(transHeaderFromConfig) + ? Arrays.stream(transHeaderFromConfig.split(",")).collect(Collectors.toSet()) + : Collections.emptySet(); + + transHeaderSet.addAll(transHeaderFromEnvSet); + transHeaderSet.addAll(transHeaderFromConfigSet); + + return new ArrayList<>(transHeaderSet).stream().sorted().collect(Collectors.joining(",")); + } + public Map getEnvTransitiveMetadata() { return envTransitiveMetadata; } @@ -390,6 +419,7 @@ public String toString() { ", envTransitiveMetadata=" + envTransitiveMetadata + ", configMetadata=" + configMetadata + ", configTransitiveMetadata=" + configTransitiveMetadata + + ", configTransHeaders='" + configTransHeaders + '\'' + ", customSPIMetadata=" + customSPIMetadata + ", customSPITransitiveMetadata=" + customSPITransitiveMetadata + ", mergedStaticMetadata=" + mergedStaticMetadata + 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 2964e0178..64ba52cb8 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 @@ -48,6 +48,11 @@ public class MetadataLocalProperties { */ private List disposable; + /** + * A transitive http header key list. + */ + private List headers; + public Map getContent() { if (CollectionUtils.isEmpty(content)) { content = new HashMap<>(); @@ -80,4 +85,15 @@ public List getDisposable() { public void setDisposable(List disposable) { this.disposable = disposable; } + + public List getHeaders() { + if (CollectionUtils.isEmpty(headers)) { + headers = new ArrayList<>(); + } + return headers; + } + + public void setHeaders(List headers) { + this.headers = headers; + } } diff --git a/spring-cloud-tencent-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-tencent-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 575ca9738..291e26dbe 100644 --- a/spring-cloud-tencent-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-tencent-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -14,6 +14,11 @@ "name": "spring.cloud.tencent.metadata.disposable", "type": "java.util.List", "description": "Custom disposable metadata key list." + }, + { + "name": "spring.cloud.tencent.metadata.headers", + "type": "java.util.List", + "description": "Custom transitive http header key list." } ] } 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 d405b52a0..fd12133d0 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 @@ -52,6 +52,10 @@ public void test1() { Assertions.assertThat(customMetadata.get("a")).isEqualTo("1"); Assertions.assertThat(customMetadata.get("b")).isEqualTo("2"); + Map transHeaders = MetadataContextHolder.get().getTransHeaders(); + Assertions.assertThat(transHeaders.size()).isEqualTo(1); + Assertions.assertThat(transHeaders.keySet().iterator().next()).isEqualTo("c,d"); + MetadataContextHolder.remove(); customMetadata = new HashMap<>(); @@ -65,6 +69,10 @@ public void test1() { Assertions.assertThat(customMetadata.get("b")).isEqualTo("22"); Assertions.assertThat(customMetadata.get("c")).isEqualTo("3"); Assertions.assertThat(MetadataContext.LOCAL_NAMESPACE).isEqualTo("default"); + + transHeaders = MetadataContextHolder.get().getTransHeaders(); + Assertions.assertThat(transHeaders.size()).isEqualTo(1); + Assertions.assertThat(transHeaders.keySet().iterator().next()).isEqualTo("c,d"); } @Test 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 784213c57..f6fddcea5 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 @@ -97,6 +97,7 @@ public void testParseConfigMetadata() { when(metadataLocalProperties.getContent()).thenReturn(content); when(metadataLocalProperties.getTransitive()).thenReturn(Collections.singletonList("k1")); when(metadataLocalProperties.getDisposable()).thenReturn(Collections.singletonList("k1")); + when(metadataLocalProperties.getHeaders()).thenReturn(Arrays.asList("a", "d")); StaticMetadataManager metadataManager = new StaticMetadataManager(metadataLocalProperties, null); @@ -119,6 +120,9 @@ public void testParseConfigMetadata() { Map locationInfo = metadataManager.getLocationMetadata(); assertThat(locationInfo.get("zone")).isEqualTo("zone1"); assertThat(locationInfo.get("region")).isEqualTo("region1"); + + String transHeaderFromConfig = metadataManager.getTransHeaderFromConfig(); + assertThat(transHeaderFromConfig).isEqualTo("a,d"); } @Test @@ -161,6 +165,9 @@ public void testCustomSPIMetadata() { @Test public void testMergedMetadata() { + // set environment variables + environmentVariables.set("SCT_TRAFFIC_CONTENT_RAW_TRANSHEADERS", "a,b,c,e"); + Map content = new HashMap<>(); content.put("k1", "v1"); content.put("k2", "v2"); @@ -170,6 +177,7 @@ public void testMergedMetadata() { when(metadataLocalProperties.getContent()).thenReturn(content); when(metadataLocalProperties.getTransitive()).thenReturn(Collections.singletonList("k1")); + when(metadataLocalProperties.getHeaders()).thenReturn(Arrays.asList("b", "d")); StaticMetadataManager metadataManager = new StaticMetadataManager(metadataLocalProperties, Arrays.asList(new MockedMetadataProvider(), new DefaultInstanceMetadataProvider(null))); @@ -204,6 +212,9 @@ public void testMergedMetadata() { assertThat(locationInfo.get("zone")).isEqualTo("zone2"); assertThat(locationInfo.get("region")).isEqualTo("region1"); assertThat(locationInfo.get("campus")).isEqualTo("campus2"); + + String transHeader = metadataManager.getTransHeader(); + assertThat(transHeader).isEqualTo("a,b,c,d,e"); } @Test 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 b88b0b823..c35d9daf2 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 @@ -52,6 +52,12 @@ public void test2() { Assertions.assertThat(metadataLocalProperties.getTransitive().contains("b")).isTrue(); } + @Test + public void test3() { + Assertions.assertThat(metadataLocalProperties.getHeaders().contains("c")).isTrue(); + Assertions.assertThat(metadataLocalProperties.getHeaders().contains("d")).isTrue(); + } + @SpringBootApplication protected static class TestApplication { diff --git a/spring-cloud-tencent-commons/src/test/resources/application-test.yml b/spring-cloud-tencent-commons/src/test/resources/application-test.yml index f49524602..569c1aa81 100644 --- a/spring-cloud-tencent-commons/src/test/resources/application-test.yml +++ b/spring-cloud-tencent-commons/src/test/resources/application-test.yml @@ -14,3 +14,6 @@ spring: b: 2 transitive: - b + headers: + - c + - d From abad0c32ced3dcd68f86af0d434dae72deb38da4 Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Wed, 27 Sep 2023 11:45:56 +0800 Subject: [PATCH 10/10] fix:fix retry loadbalancer not working bug. (#1154) --- CHANGELOG.md | 1 + .../PolarisLoadBalancerAutoConfiguration.java | 14 +++++++++----- .../discovery-caller-service/pom.xml | 5 +++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afd75ffba..857e2af72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,3 +12,4 @@ - [feat:support service contract reporting.](https://github.com/Tencent/spring-cloud-tencent/pull/1139) - [feat:add swagger exposure filters.](https://github.com/Tencent/spring-cloud-tencent/pull/1146) - [feat:add swagger report switch.](https://github.com/Tencent/spring-cloud-tencent/pull/1148) +- [fix:fix retry loadbalancer not working bug.](https://github.com/Tencent/spring-cloud-tencent/pull/1154) diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerAutoConfiguration.java index 8ee742d6a..df296cd5b 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerAutoConfiguration.java @@ -25,12 +25,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor; import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer; +import org.springframework.cloud.client.loadbalancer.RetryLoadBalancerInterceptor; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; import org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration; import org.springframework.context.annotation.Bean; @@ -52,19 +52,23 @@ public class PolarisLoadBalancerAutoConfiguration { @Bean - @ConditionalOnMissingBean - public RestTemplateCustomizer restTemplateCustomizer(@Autowired(required = false) LoadBalancerInterceptor loadBalancerInterceptor) { + public RestTemplateCustomizer restTemplateCustomizer( + @Autowired(required = false) RetryLoadBalancerInterceptor retryLoadBalancerInterceptor, + @Autowired(required = false) LoadBalancerInterceptor loadBalancerInterceptor) { return restTemplate -> { List list = new ArrayList<>(restTemplate.getInterceptors()); // LoadBalancerInterceptor must invoke before EnhancedRestTemplateInterceptor - if (loadBalancerInterceptor != null) { + if (retryLoadBalancerInterceptor != null || loadBalancerInterceptor != null) { int addIndex = list.size(); for (int i = 0; i < list.size(); i++) { if (list.get(i) instanceof EnhancedRestTemplateInterceptor) { addIndex = i; } } - list.add(addIndex, loadBalancerInterceptor); + list.add(addIndex, + retryLoadBalancerInterceptor != null + ? retryLoadBalancerInterceptor + : loadBalancerInterceptor); } restTemplate.setInterceptors(list); }; diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml index 69e5c1e64..f6a28f36e 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml @@ -33,6 +33,11 @@ spring-cloud-starter-tencent-polaris-contract + + + + +