diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..49f492d07 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,27 @@ +name: Release + +on: + release: + types: [ published ] + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + server-id: nexus-releases + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + + - name: Publish package + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + run: | + cat <(echo -e "${{ secrets.OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import; + mvn clean deploy -U -P release -Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} -DskipTests \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 06c1f8175..d119dcd79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ # Change Log --- +- feature: support reactive discovery client health indicator. +- feature: Enhance default configuration to support `application*.yaml` and `bootstrap*.yaml`. +- feat:adapt for nacos instance. +- Refactoring: Refactor Circuitbreaker ut. +- refactor:refactor rpc enhancement. +- feat:refactor SDKContext as static. +- docs:add release GitHub Action. +- docs:update Polaris test environment ip. +- fix:fix custom fallback exception. +- feat:sct-all package is now available as a shaded uber-jar. +- fix:use path parameter in `@FeignClient` for circuit-breaker. +- build(deps): bump guava in /spring-cloud-tencent-dependencies +- fix:fix reporting bug when port is -1. +- fix:update guava version. +- fix:fix circuit breaker bean load order bug when using Nacos discovery. +- refactor:refactor Polaris registration. +- feat:added automatic optimization for dynamic config refresh type. diff --git a/README-zh.md b/README-zh.md index 62a0f2aab..a168614b9 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.11.7-Hoxton.SR12 + 1.11.8-Hoxton.SR12 pom import diff --git a/README.md b/README.md index 30c6b8b92..b87b5cf3b 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ For example: com.tencent.cloud spring-cloud-tencent-dependencies - 1.11.7-Hoxton.SR12 + 1.11.8-Hoxton.SR12 pom import diff --git a/pom.xml b/pom.xml index de42aac5f..69d9b1295 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ - 1.11.7-Hoxton.SR12 + 1.12.0-Hoxton.SR12-SNAPSHOT 5.2.22.RELEASE @@ -105,6 +105,7 @@ 3.2.0 1.2.7 3.0.1 + 3.4.1 true @@ -161,6 +162,11 @@ jacoco-maven-plugin ${jacoco.version} + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin.version} + diff --git a/spring-cloud-starter-tencent-all/pom.xml b/spring-cloud-starter-tencent-all/pom.xml index f6fb8b38f..1c45b11d7 100644 --- a/spring-cloud-starter-tencent-all/pom.xml +++ b/spring-cloud-starter-tencent-all/pom.xml @@ -57,4 +57,49 @@ spring-boot-starter-actuator + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + package + + jar + + + + + + org.apache.maven.plugins + maven-shade-plugin + + false + + + + sct-all-shade + + shade + + + true + + + + META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports + + + META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports + + + + + + + + diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml index 5cc0cff59..31743b0c3 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml @@ -109,12 +109,6 @@ test - - org.springframework.cloud - spring-cloud-starter-contract-stub-runner - test - - com.tencent.polaris polaris-test-common diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java index 7dd7bf0b0..6ba7d4435 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java @@ -30,26 +30,20 @@ import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreak import com.tencent.cloud.polaris.circuitbreaker.zuul.PolarisCircuitBreakerPostZuulFilter; import com.tencent.cloud.polaris.circuitbreaker.zuul.PolarisCircuitBreakerZuulFilter; import com.tencent.cloud.polaris.circuitbreaker.zuul.PolarisZuulFallbackFactory; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; -import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory; -import com.tencent.polaris.client.api.SDKContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; import org.springframework.cloud.client.circuitbreaker.Customizer; import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.openfeign.PolarisFeignCircuitBreakerTargeterAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; import org.springframework.core.env.Environment; @@ -61,12 +55,6 @@ import org.springframework.core.env.Environment; @Configuration(proxyBeanMethods = false) @ConditionalOnPolarisCircuitBreakerEnabled @AutoConfigureAfter(RpcEnhancementAutoConfiguration.class) -@Import({ - ReactivePolarisCircuitBreakerAutoConfiguration.class, - PolarisFeignCircuitBreakerTargeterAutoConfiguration.class, - PolarisCircuitBreakerFeignClientAutoConfiguration.class, - GatewayPolarisCircuitBreakerAutoConfiguration.class -}) public class PolarisCircuitBreakerAutoConfiguration { @Autowired(required = false) @@ -85,36 +73,30 @@ public class PolarisCircuitBreakerAutoConfiguration { return new PolarisCircuitBreakerRestTemplateBeanPostProcessor(applicationContext); } - @Bean - @ConditionalOnMissingBean(CircuitBreakAPI.class) - public CircuitBreakAPI circuitBreakAPI(SDKContext polarisContext) { - return CircuitBreakAPIFactory.createCircuitBreakAPIByContext(polarisContext); - } - @Bean @ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class) public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties, - SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { - return new SuccessCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + PolarisSDKContextManager polarisSDKContextManager) { + return new SuccessCircuitBreakerReporter(properties, polarisSDKContextManager.getCircuitBreakAPI()); } @Bean @ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class) public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties, - SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { - return new ExceptionCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + PolarisSDKContextManager polarisSDKContextManager) { + return new ExceptionCircuitBreakerReporter(properties, polarisSDKContextManager.getCircuitBreakAPI()); } @Bean @ConditionalOnMissingBean(CircuitBreakerFactory.class) - public CircuitBreakerFactory polarisCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, ConsumerAPI consumerAPI) { - PolarisCircuitBreakerFactory factory = new PolarisCircuitBreakerFactory(circuitBreakAPI, consumerAPI); + public CircuitBreakerFactory polarisCircuitBreakerFactory(PolarisSDKContextManager polarisSDKContextManager) { + PolarisCircuitBreakerFactory factory = new PolarisCircuitBreakerFactory( + polarisSDKContextManager.getCircuitBreakAPI(), polarisSDKContextManager.getConsumerAPI()); customizers.forEach(customizer -> customizer.customize(factory)); return factory; } @Bean - @ConditionalOnBean(RpcEnhancementReporterProperties.class) @ConditionalOnMissingBean(CircuitBreakerConfigModifier.class) public CircuitBreakerConfigModifier circuitBreakerConfigModifier(RpcEnhancementReporterProperties properties) { return new CircuitBreakerConfigModifier(properties); diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java index abf1e8e65..6d6274253 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java @@ -17,10 +17,7 @@ package com.tencent.cloud.polaris.circuitbreaker.config; -import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; -import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration; - +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -30,8 +27,13 @@ import org.springframework.context.annotation.Import; * @author lepdou 2022-03-29 */ @Configuration(proxyBeanMethods = false) -@ConditionalOnPolarisEnabled -@Import({PolarisContextAutoConfiguration.class, RpcEnhancementAutoConfiguration.class, PolarisCircuitBreakerAutoConfiguration.class}) +@ConditionalOnProperty("spring.cloud.polaris.enabled") +@Import({ + PolarisCircuitBreakerAutoConfiguration.class, + ReactivePolarisCircuitBreakerAutoConfiguration.class, + PolarisCircuitBreakerFeignClientAutoConfiguration.class, + GatewayPolarisCircuitBreakerAutoConfiguration.class +}) public class PolarisCircuitBreakerBootstrapConfiguration { } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/ReactivePolarisCircuitBreakerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/ReactivePolarisCircuitBreakerAutoConfiguration.java index f2f509218..23c3f281d 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/ReactivePolarisCircuitBreakerAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/ReactivePolarisCircuitBreakerAutoConfiguration.java @@ -24,16 +24,12 @@ import com.tencent.cloud.polaris.circuitbreaker.ReactivePolarisCircuitBreakerFac import com.tencent.cloud.polaris.circuitbreaker.common.CircuitBreakerConfigModifier; import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter; import com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; -import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory; -import com.tencent.polaris.client.api.SDKContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cloud.client.circuitbreaker.Customizer; @@ -47,7 +43,7 @@ import org.springframework.context.annotation.Configuration; * @author seanyu 2023-02-27 */ @Configuration(proxyBeanMethods = false) -@ConditionalOnClass(name = { "reactor.core.publisher.Mono", "reactor.core.publisher.Flux" }) +@ConditionalOnClass(name = {"reactor.core.publisher.Mono", "reactor.core.publisher.Flux"}) @ConditionalOnPolarisCircuitBreakerEnabled @AutoConfigureAfter(RpcEnhancementAutoConfiguration.class) public class ReactivePolarisCircuitBreakerAutoConfiguration { @@ -55,36 +51,30 @@ public class ReactivePolarisCircuitBreakerAutoConfiguration { @Autowired(required = false) private List> customizers = new ArrayList<>(); - @Bean - @ConditionalOnMissingBean(CircuitBreakAPI.class) - public CircuitBreakAPI circuitBreakAPI(SDKContext polarisContext) { - return CircuitBreakAPIFactory.createCircuitBreakAPIByContext(polarisContext); - } - @Bean @ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class) public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties, - SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { - return new SuccessCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + PolarisSDKContextManager polarisSDKContextManager) { + return new SuccessCircuitBreakerReporter(properties, polarisSDKContextManager.getCircuitBreakAPI()); } @Bean @ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class) public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties, - SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { - return new ExceptionCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + PolarisSDKContextManager polarisSDKContextManager) { + return new ExceptionCircuitBreakerReporter(properties, polarisSDKContextManager.getCircuitBreakAPI()); } @Bean @ConditionalOnMissingBean(ReactiveCircuitBreakerFactory.class) - public ReactiveCircuitBreakerFactory polarisReactiveCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, ConsumerAPI consumerAPI) { - ReactivePolarisCircuitBreakerFactory factory = new ReactivePolarisCircuitBreakerFactory(circuitBreakAPI, consumerAPI); + public ReactiveCircuitBreakerFactory polarisReactiveCircuitBreakerFactory(PolarisSDKContextManager polarisSDKContextManager) { + ReactivePolarisCircuitBreakerFactory factory = new ReactivePolarisCircuitBreakerFactory( + polarisSDKContextManager.getCircuitBreakAPI(), polarisSDKContextManager.getConsumerAPI()); customizers.forEach(customizer -> customizer.customize(factory)); return factory; } @Bean - @ConditionalOnBean(RpcEnhancementReporterProperties.class) @ConditionalOnMissingBean(CircuitBreakerConfigModifier.class) public CircuitBreakerConfigModifier reactiveCircuitBreakerConfigModifier(RpcEnhancementReporterProperties properties) { return new CircuitBreakerConfigModifier(properties); diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolver.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolver.java index e627ed09a..28539cd6b 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolver.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolver.java @@ -18,10 +18,15 @@ package com.tencent.cloud.polaris.circuitbreaker.feign; import java.lang.reflect.Method; +import java.net.URI; +import java.net.URISyntaxException; import com.tencent.cloud.common.metadata.MetadataContext; import feign.Target; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation; @@ -33,12 +38,30 @@ import static org.springframework.core.annotation.AnnotatedElementUtils.findMerg */ public class PolarisCircuitBreakerNameResolver { + private static final Logger LOG = LoggerFactory.getLogger(PolarisCircuitBreakerNameResolver.class); + public String resolveCircuitBreakerName(String feignClientName, Target target, Method method) { String serviceName = target.name(); - RequestMapping requestMapping = findMergedAnnotation(method, RequestMapping.class); String path = ""; + + // Get path in @FeignClient. + if (StringUtils.hasText(target.url())) { + URI uri = null; + try { + uri = new URI(target.url()); + } + catch (URISyntaxException e) { + LOG.warn("Generate URI from url({}) in @FeignClient. failed.", target.url()); + } + if (uri != null) { + path += uri.getPath(); + } + } + + // Get path in @RequestMapping. + RequestMapping requestMapping = findMergedAnnotation(method, RequestMapping.class); if (requestMapping != null) { - path = requestMapping.path().length == 0 ? + path += requestMapping.path().length == 0 ? requestMapping.value().length == 0 ? "" : requestMapping.value()[0] : requestMapping.path()[0]; } @@ -46,4 +69,5 @@ public class PolarisCircuitBreakerNameResolver { MetadataContext.LOCAL_NAMESPACE + "#" + serviceName : MetadataContext.LOCAL_NAMESPACE + "#" + serviceName + "#" + path; } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java index b47c1a4a2..293b8433a 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java @@ -19,32 +19,38 @@ package com.tencent.cloud.polaris.circuitbreaker.reporter; import java.util.Optional; -import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; 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.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils; import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; -import com.tencent.polaris.client.api.SDKContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.Ordered; -public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { +import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER; + +/** + * ExceptionCircuitBreakerReporter. + * + * @author sean yu + */ +public class ExceptionCircuitBreakerReporter implements EnhancedPlugin { private static final Logger LOG = LoggerFactory.getLogger(ExceptionCircuitBreakerReporter.class); private final CircuitBreakAPI circuitBreakAPI; + private final RpcEnhancementReporterProperties reportProperties; + public ExceptionCircuitBreakerReporter(RpcEnhancementReporterProperties reportProperties, - SDKContext context, CircuitBreakAPI circuitBreakAPI) { - super(reportProperties, context); + this.reportProperties = reportProperties; this.circuitBreakAPI = circuitBreakAPI; } @@ -55,19 +61,20 @@ public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdap @Override public EnhancedPluginType getType() { - return EnhancedPluginType.EXCEPTION; + return EnhancedPluginType.Client.EXCEPTION; } @Override public void run(EnhancedPluginContext context) throws Throwable { - if (!super.reportProperties.isEnabled()) { + if (!this.reportProperties.isEnabled()) { return; } EnhancedRequestContext request = context.getRequest(); - ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); + ServiceInstance serviceInstance = Optional.ofNullable(context.getTargetServiceInstance()) + .orElse(new DefaultServiceInstance()); - ResourceStat resourceStat = createInstanceResourceStat( + ResourceStat resourceStat = PolarisEnhancedPluginUtils.createInstanceResourceStat( serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort(), @@ -78,7 +85,8 @@ public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdap ); LOG.debug("Will report CircuitBreaker ResourceStat of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), context.getThrowable().getMessage(), context.getDelay()); + resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl() + .getPath(), context.getThrowable().getMessage(), context.getDelay()); circuitBreakAPI.report(resourceStat); @@ -92,6 +100,6 @@ public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdap @Override public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE + 2; + return CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER; } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java index ce5fe2a81..e11d71288 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java @@ -19,35 +19,40 @@ package com.tencent.cloud.polaris.circuitbreaker.reporter; import java.util.Optional; -import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; 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.EnhancedRequestContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; +import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils; import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter; import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; -import com.tencent.polaris.client.api.SDKContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.Ordered; +import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER; -public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { +/** + * SuccessCircuitBreakerReporter. + * + * @author sean yu + */ +public class SuccessCircuitBreakerReporter implements EnhancedPlugin { private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class); private final CircuitBreakAPI circuitBreakAPI; + private final RpcEnhancementReporterProperties reportProperties; + public SuccessCircuitBreakerReporter(RpcEnhancementReporterProperties reportProperties, - SDKContext context, CircuitBreakAPI circuitBreakAPI) { - super(reportProperties, context); + this.reportProperties = reportProperties; this.circuitBreakAPI = circuitBreakAPI; } @@ -58,19 +63,20 @@ public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapte @Override public EnhancedPluginType getType() { - return EnhancedPluginType.POST; + return EnhancedPluginType.Client.POST; } @Override public void run(EnhancedPluginContext context) throws Throwable { - if (!super.reportProperties.isEnabled()) { + if (!this.reportProperties.isEnabled()) { return; } EnhancedRequestContext request = context.getRequest(); EnhancedResponseContext response = context.getResponse(); - ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); + ServiceInstance serviceInstance = Optional.ofNullable(context.getTargetServiceInstance()) + .orElse(new DefaultServiceInstance()); - ResourceStat resourceStat = createInstanceResourceStat( + ResourceStat resourceStat = PolarisEnhancedPluginUtils.createInstanceResourceStat( serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort(), @@ -81,7 +87,8 @@ public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapte ); LOG.debug("Will report CircuitBreaker ResourceStat of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), response.getHttpStatus(), context.getDelay()); + resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl() + .getPath(), response.getHttpStatus(), context.getDelay()); circuitBreakAPI.report(resourceStat); } @@ -94,6 +101,6 @@ public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapte @Override public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE + 2; + return CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER; } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/org/springframework/cloud/openfeign/PolarisFeignCircuitBreakerTargeterAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/org/springframework/cloud/openfeign/PolarisFeignCircuitBreakerTargeterAutoConfiguration.java index 63b25fe2c..33754e6f3 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/org/springframework/cloud/openfeign/PolarisFeignCircuitBreakerTargeterAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/org/springframework/cloud/openfeign/PolarisFeignCircuitBreakerTargeterAutoConfiguration.java @@ -23,6 +23,7 @@ import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisCircuitBreakerNameR import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; import org.springframework.context.annotation.Bean; @@ -36,7 +37,7 @@ import org.springframework.context.annotation.Primary; */ @Configuration(proxyBeanMethods = false) @ConditionalOnClass({Targeter.class}) -@ConditionalOnProperty(value = "feign.circuitbreaker.enabled", havingValue = "true") +@ConditionalOnProperty(value = "feign.hystrix.enabled", havingValue = "true") @AutoConfigureBefore(FeignAutoConfiguration.class) @ConditionalOnPolarisCircuitBreakerEnabled public class PolarisFeignCircuitBreakerTargeterAutoConfiguration { @@ -44,6 +45,7 @@ public class PolarisFeignCircuitBreakerTargeterAutoConfiguration { @Bean @Primary @ConditionalOnBean(CircuitBreakerFactory.class) + @ConditionalOnMissingBean(Targeter.class) public Targeter polarisFeignCircuitBreakerTargeter(CircuitBreakerFactory circuitBreakerFactory, PolarisCircuitBreakerNameResolver circuitBreakerNameResolver) { return new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver); } 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 41da60a9e..3f7eb9744 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 @@ -5,4 +5,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration,\ org.springframework.cloud.openfeign.PolarisFeignCircuitBreakerTargeterAutoConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ - com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration + com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration,\ + org.springframework.cloud.openfeign.PolarisFeignCircuitBreakerTargeterAutoConfiguration diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java index 5058a8a22..fcde4e4f9 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java @@ -30,6 +30,7 @@ import java.util.stream.Collectors; import com.google.protobuf.util.JsonFormat; import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.polaris.api.config.Configuration; import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.pojo.ServiceKey; @@ -76,22 +77,21 @@ public class PolarisCircuitBreakerMockServerTest { .thenReturn(NAMESPACE_TEST); mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.service")) .thenReturn(SERVICE_CIRCUIT_BREAKER); + PolarisSDKContextManager.innerDestroy(); + namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - try { - namingServer = NamingServer.startNamingServer(-1); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { - - } ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_CIRCUIT_BREAKER); - CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); - InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader().getResourceAsStream("circuitBreakerRule.json"); - String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("")); + CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); + InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader() + .getResourceAsStream("circuitBreakerRule.json"); + String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines() + .collect(Collectors.joining("")); JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder); CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build(); - CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder().addRules(circuitBreakerRule).build(); + CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() + .addRules(circuitBreakerRule).build(); namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker); } @@ -100,6 +100,9 @@ public class PolarisCircuitBreakerMockServerTest { if (null != namingServer) { namingServer.terminate(); } + if (null != mockedApplicationContextAwareUtils) { + mockedApplicationContextAwareUtils.close(); + } } @Test @@ -138,7 +141,8 @@ public class PolarisCircuitBreakerMockServerTest { assertThat(Mono.error(new RuntimeException("boom")).transform(it -> rcb.run(it, t -> Mono.just("fallback"))) .block()).isEqualTo("fallback"); - assertThat(Flux.just("foobar", "hello world").transform(it -> rcb.run(it, t -> Flux.just("fallback", "fallback"))) + assertThat(Flux.just("foobar", "hello world") + .transform(it -> rcb.run(it, t -> Flux.just("fallback", "fallback"))) .collectList().block()) .isEqualTo(Arrays.asList("fallback", "fallback")); @@ -146,7 +150,6 @@ public class PolarisCircuitBreakerMockServerTest { .collectList().block()) .isEqualTo(Collections.singletonList("fallback")); - } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerTest.java index 494ae7798..bf35fa8f9 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerTest.java @@ -49,7 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat; @ExtendWith(MockitoExtension.class) public class PolarisCircuitBreakerTest { - private static final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + private static ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of( PolarisContextAutoConfiguration.class, RpcEnhancementAutoConfiguration.class, @@ -76,7 +76,7 @@ public class PolarisCircuitBreakerTest { @Test public void run() { - contextRunner.run(context -> { + this.contextRunner.run(context -> { PolarisCircuitBreakerFactory polarisCircuitBreakerFactory = context.getBean(PolarisCircuitBreakerFactory.class); CircuitBreaker cb = polarisCircuitBreakerFactory.create(SERVICE_CIRCUIT_BREAKER); @@ -95,4 +95,7 @@ public class PolarisCircuitBreakerTest { }); } + + + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/CircuitBreakerPolarisAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java similarity index 86% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/CircuitBreakerPolarisAutoConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java index 5b05ab5ad..3e5cc8c3f 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/CircuitBreakerPolarisAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java @@ -15,15 +15,12 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.config; import com.tencent.cloud.polaris.circuitbreaker.common.CircuitBreakerConfigModifier; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.ReactivePolarisCircuitBreakerAutoConfiguration; import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisCircuitBreakerNameResolver; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -39,12 +36,13 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Haotian Zhang */ -public class CircuitBreakerPolarisAutoConfigurationTest { +public class PolarisCircuitBreakerAutoConfigurationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of( PolarisContextAutoConfiguration.class, RpcEnhancementAutoConfiguration.class, LoadBalancerAutoConfiguration.class, + PolarisCircuitBreakerFeignClientAutoConfiguration.class, PolarisCircuitBreakerAutoConfiguration.class)) .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true"); @@ -62,7 +60,6 @@ public class CircuitBreakerPolarisAutoConfigurationTest { assertThat(context).hasSingleBean(PolarisCircuitBreakerAutoConfiguration.class); assertThat(context).hasSingleBean(CircuitBreakerFactory.class); assertThat(context).hasSingleBean(CircuitBreakerConfigModifier.class); - assertThat(context).hasSingleBean(CircuitBreakAPI.class); assertThat(context).hasSingleBean(PolarisCircuitBreakerNameResolver.class); }); } @@ -73,7 +70,6 @@ public class CircuitBreakerPolarisAutoConfigurationTest { assertThat(context).hasSingleBean(ReactivePolarisCircuitBreakerAutoConfiguration.class); assertThat(context).hasSingleBean(ReactiveCircuitBreakerFactory.class); assertThat(context).hasSingleBean(CircuitBreakerConfigModifier.class); - assertThat(context).hasSingleBean(CircuitBreakAPI.class); }); } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java similarity index 82% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java index c78784308..653ba8ffe 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java @@ -15,12 +15,8 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.config; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.ReactivePolarisCircuitBreakerAutoConfiguration; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration; import org.junit.jupiter.api.Test; diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFeignIntegrationTest.java similarity index 66% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFeignIntegrationTest.java index fd85ef41f..a37ccd786 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFeignIntegrationTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.feign; import java.io.BufferedReader; @@ -24,37 +24,49 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; import java.util.stream.Collectors; -import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; +import com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreakerFactory; import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration; +import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter; +import com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory; import com.tencent.polaris.client.util.Utils; +import com.tencent.polaris.factory.api.DiscoveryAPIFactory; import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; import com.tencent.polaris.test.common.TestUtils; import com.tencent.polaris.test.mock.discovery.NamingServer; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; +import org.springframework.cloud.client.circuitbreaker.Customizer; import org.springframework.cloud.client.circuitbreaker.NoFallbackAvailableException; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.cloud.openfeign.PolarisFeignCircuitBreakerTargeter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; +import org.springframework.context.annotation.Primary; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -69,33 +81,27 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen properties = { "spring.cloud.gateway.enabled=false", "feign.circuitbreaker.enabled=true", - "spring.cloud.polaris.namespace=default", - "spring.cloud.polaris.service=Test", - "spring.cloud.polaris.address=grpc://127.0.0.1:10081" + "spring.cloud.polaris.namespace=" + NAMESPACE_TEST, + "spring.cloud.polaris.service=test" }) -@DirtiesContext public class PolarisCircuitBreakerFeignIntegrationTest { private static final String TEST_SERVICE_NAME = "test-service-callee"; - private static NamingServer namingServer; + @Autowired private EchoService echoService; + @Autowired private FooService fooService; + @Autowired private BarService barService; + @Autowired private BazService bazService; - @AfterAll - public static void afterAll() { - if (null != namingServer) { - namingServer.terminate(); - } - } - @Test - public void contextLoads() throws Exception { + public void contextLoads() { assertThat(echoService).isNotNull(); assertThat(fooService).isNotNull(); } @@ -120,6 +126,7 @@ public class PolarisCircuitBreakerFeignIntegrationTest { } @FeignClient(value = TEST_SERVICE_NAME, contextId = "1", fallback = EchoServiceFallback.class) + @Primary public interface EchoService { @RequestMapping(path = "echo/{str}") @@ -161,6 +168,9 @@ public class PolarisCircuitBreakerFeignIntegrationTest { @EnableFeignClients public static class TestConfig { + @Autowired(required = false) + private List> customizers = new ArrayList<>(); + @Bean public EchoServiceFallback echoServiceFallback() { return new EchoServiceFallback(); @@ -172,18 +182,18 @@ public class PolarisCircuitBreakerFeignIntegrationTest { } @Bean - public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException { - try { - namingServer = NamingServer.startNamingServer(10081); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { + public PreDestroy preDestroy(NamingServer namingServer) { + return new PreDestroy(namingServer); + } - } - ServiceKey serviceKey = new ServiceKey("default", TEST_SERVICE_NAME); + @Bean + public NamingServer namingServer() throws IOException { + NamingServer namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); + ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME); CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); - InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader() + InputStream inputStream = PolarisCircuitBreakerFeignIntegrationTest.class.getClassLoader() .getResourceAsStream("circuitBreakerRule.json"); String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines() .collect(Collectors.joining("")); @@ -192,10 +202,51 @@ public class PolarisCircuitBreakerFeignIntegrationTest { CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() .addRules(circuitBreakerRule).build(); namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker); + return namingServer; + } + + @Bean + public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) { com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress(); return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration); } + @Bean + public ConsumerAPI consumerAPI(NamingServer namingServer) { + com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress(); + return DiscoveryAPIFactory.createConsumerAPIByConfig(configuration); + } + + @Bean + public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties, + CircuitBreakAPI circuitBreakAPI) { + return new SuccessCircuitBreakerReporter(properties, circuitBreakAPI); + } + + @Bean + public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties, + CircuitBreakAPI circuitBreakAPI) { + return new ExceptionCircuitBreakerReporter(properties, circuitBreakAPI); + } + + @Bean + public CircuitBreakerFactory polarisCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, ConsumerAPI consumerAPI) { + PolarisCircuitBreakerFactory factory = new PolarisCircuitBreakerFactory(circuitBreakAPI, consumerAPI); + customizers.forEach(customizer -> customizer.customize(factory)); + return factory; + } + + @Bean + public PolarisCircuitBreakerNameResolver polarisCircuitBreakerNameResolver() { + return new PolarisCircuitBreakerNameResolver(); + } + + @Bean + @Primary + @ConditionalOnBean(CircuitBreakerFactory.class) + public PolarisFeignCircuitBreakerTargeter polarisFeignCircuitBreakerTargeter(CircuitBreakerFactory circuitBreakerFactory, PolarisCircuitBreakerNameResolver circuitBreakerNameResolver) { + return new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver); + } } public static class EchoServiceFallback implements EchoService { @@ -231,4 +282,18 @@ public class PolarisCircuitBreakerFeignIntegrationTest { } + public static class PreDestroy implements DisposableBean { + + private final NamingServer namingServer; + + public PreDestroy(NamingServer namingServer) { + this.namingServer = namingServer; + } + + @Override + public void destroy() throws Exception { + namingServer.terminate(); + } + } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolverTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolverTest.java new file mode 100644 index 000000000..52e9e4650 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolverTest.java @@ -0,0 +1,125 @@ +/* + * 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.feign; + +import java.lang.reflect.Method; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.common.util.ReflectionUtils; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import feign.Target; +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.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.context.ApplicationContext; +import org.springframework.web.bind.annotation.RequestMapping; + +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; + +/** + * @author sean yu + */ +@ExtendWith(MockitoExtension.class) +public class PolarisCircuitBreakerNameResolverTest { + + 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(); + } + + @BeforeEach + void setUp() { + MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; + MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; + } + + + @Test + public void test() { + Target target = mock(Target.class); + doReturn("test-svc").when(target).name(); + Method method = ReflectionUtils.findMethod(PolarisCircuitBreakerNameResolverTest.class, "mockRequestMapping"); + PolarisCircuitBreakerNameResolver resolver = new PolarisCircuitBreakerNameResolver(); + String polarisCircuitBreakerName = resolver.resolveCircuitBreakerName("test", target, method); + assertThat(polarisCircuitBreakerName).isEqualTo("Test#test-svc"); + } + + @Test + public void test2() { + Target target = mock(Target.class); + doReturn("test-svc").when(target).name(); + Method method = ReflectionUtils.findMethod(PolarisCircuitBreakerNameResolverTest.class, "mockRequestMapping2"); + PolarisCircuitBreakerNameResolver resolver = new PolarisCircuitBreakerNameResolver(); + String polarisCircuitBreakerName = resolver.resolveCircuitBreakerName("test", target, method); + assertThat(polarisCircuitBreakerName).isEqualTo("Test#test-svc#/"); + } + + @Test + public void test3() { + Target target = mock(Target.class); + doReturn("test-svc").when(target).name(); + Method method = ReflectionUtils.findMethod(PolarisCircuitBreakerNameResolverTest.class, "mockRequestMapping3"); + PolarisCircuitBreakerNameResolver resolver = new PolarisCircuitBreakerNameResolver(); + String polarisCircuitBreakerName = resolver.resolveCircuitBreakerName("test", target, method); + assertThat(polarisCircuitBreakerName).isEqualTo("Test#test-svc#/"); + } + + + @RequestMapping + public void mockRequestMapping() { + + } + + @RequestMapping(path = "/") + public void mockRequestMapping2() { + + } + + @RequestMapping("/") + public void mockRequestMapping3() { + + } + +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java new file mode 100644 index 000000000..9814cb74b --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java @@ -0,0 +1,89 @@ +/* + * 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.feign; + +import feign.Feign; +import feign.RequestLine; +import feign.Target; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; +import org.springframework.cloud.openfeign.FeignClientFactoryBean; +import org.springframework.cloud.openfeign.FeignContext; +import org.springframework.cloud.openfeign.PolarisFeignCircuitBreakerTargeter; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +/** + * PolarisFeignCircuitBreakerTargeterTest. + * + * @author sean yu + */ +@ExtendWith(MockitoExtension.class) +public class PolarisFeignCircuitBreakerTargeterTest { + + @Mock + CircuitBreakerFactory circuitBreakerFactory; + + @Mock + PolarisCircuitBreakerNameResolver circuitBreakerNameResolver; + + @Test + public void testTarget() { + PolarisFeignCircuitBreakerTargeter targeter = new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver); + targeter.target(new FeignClientFactoryBean(), new Feign.Builder(), new FeignContext(), new Target.HardCodedTarget<>(TestApi.class, "/test")); + } + + @Test + public void testTarget2() { + PolarisFeignCircuitBreakerTargeter targeter = new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver); + FeignClientFactoryBean feignClientFactoryBean = mock(FeignClientFactoryBean.class); + doReturn(TestApi.class).when(feignClientFactoryBean).getFallback(); + doReturn("test").when(feignClientFactoryBean).getName(); + FeignContext feignClientFactory = mock(FeignContext.class); + doReturn(null).when(feignClientFactory).getInstance("test", TestApi.class); + assertThatThrownBy(() -> { + targeter.target(feignClientFactoryBean, new PolarisFeignCircuitBreaker.Builder(), feignClientFactory, new Target.HardCodedTarget<>(TestApi.class, "/test")); + }).isInstanceOf(IllegalStateException.class); + } + + @Test + public void testTarget3() { + PolarisFeignCircuitBreakerTargeter targeter = new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver); + FeignClientFactoryBean feignClientFactoryBean = mock(FeignClientFactoryBean.class); + doReturn(void.class).when(feignClientFactoryBean).getFallback(); + doReturn(TestApi.class).when(feignClientFactoryBean).getFallbackFactory(); + doReturn("test").when(feignClientFactoryBean).getName(); + FeignContext feignClientFactory = mock(FeignContext.class); + doReturn(Object.class).when(feignClientFactory).getInstance("test", TestApi.class); + assertThatThrownBy(() -> { + targeter.target(feignClientFactoryBean, new PolarisFeignCircuitBreaker.Builder(), feignClientFactory, new Target.HardCodedTarget<>(TestApi.class, "/test")); + }).isInstanceOf(IllegalStateException.class); + } + + interface TestApi { + @RequestLine("GET /test") + void test(); + } + +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerGatewayIntegrationTest.java similarity index 67% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerGatewayIntegrationTest.java index af254508f..2511722bc 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerGatewayIntegrationTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.gateway; import java.io.BufferedReader; @@ -23,31 +23,39 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; -import com.tencent.cloud.polaris.circuitbreaker.gateway.PolarisCircuitBreakerFilterFactory; +import com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreakerFactory; +import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter; +import com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory; import com.tencent.polaris.client.util.Utils; +import com.tencent.polaris.factory.api.DiscoveryAPIFactory; import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; import com.tencent.polaris.test.common.TestUtils; import com.tencent.polaris.test.mock.discovery.NamingServer; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import reactor.core.publisher.Mono; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; +import org.springframework.cloud.client.circuitbreaker.Customizer; import org.springframework.cloud.gateway.filter.factory.SpringCloudCircuitBreakerFilterFactory; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; @@ -60,6 +68,8 @@ import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.SERVICE_CIRCUIT_BREAKER; import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV; import static org.assertj.core.api.Assertions.assertThat; @@ -72,33 +82,24 @@ import static org.assertj.core.api.Assertions.assertThat; webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { "spring.cloud.gateway.enabled=true", - "spring.cloud.polaris.namespace=default", - "spring.cloud.polaris.service=Test", - "spring.main.web-application-type=reactive", - "httpbin=http://localhost:${wiremock.server.port}", - "spring.cloud.polaris.address=grpc://127.0.0.1:10081" + "spring.cloud.polaris.namespace=" + NAMESPACE_TEST, + "spring.cloud.polaris.service=" + SERVICE_CIRCUIT_BREAKER, + "spring.main.web-application-type=reactive" }, classes = PolarisCircuitBreakerGatewayIntegrationTest.TestApplication.class ) -@AutoConfigureWireMock(port = 0) @ActiveProfiles("test-gateway") @AutoConfigureWebTestClient(timeout = "1000000") public class PolarisCircuitBreakerGatewayIntegrationTest { private static final String TEST_SERVICE_NAME = "test-service-callee"; - private static NamingServer namingServer; + @Autowired private WebTestClient webClient; + @Autowired private ApplicationContext applicationContext; - @AfterAll - public static void afterAll() { - if (null != namingServer) { - namingServer.terminate(); - } - } - @Test public void fallback() throws Exception { SpringCloudCircuitBreakerFilterFactory.Config config = new SpringCloudCircuitBreakerFilterFactory.Config(); @@ -160,19 +161,22 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { @EnableAutoConfiguration public static class TestApplication { + @Autowired(required = false) + private List> customizers = new ArrayList<>(); + @Bean - public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException { - try { - namingServer = NamingServer.startNamingServer(10081); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { + public PreDestroy preDestroy(NamingServer namingServer) { + return new PreDestroy(namingServer); + } - } - ServiceKey serviceKey = new ServiceKey("default", TEST_SERVICE_NAME); + @Bean + public NamingServer namingServer() throws IOException { + NamingServer namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); + ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME); CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); - InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader() + InputStream inputStream = PolarisCircuitBreakerGatewayIntegrationTest.class.getClassLoader() .getResourceAsStream("circuitBreakerRule.json"); String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines() .collect(Collectors.joining("")); @@ -181,10 +185,43 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() .addRules(circuitBreakerRule).build(); namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker); + return namingServer; + } + + @Bean + public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) throws IOException { com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress(); return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration); } + @Bean + public ConsumerAPI consumerAPI(NamingServer namingServer) { + com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress(); + return DiscoveryAPIFactory.createConsumerAPIByConfig(configuration); + } + + @Bean + @ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class) + public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties, + CircuitBreakAPI circuitBreakAPI) { + return new SuccessCircuitBreakerReporter(properties, circuitBreakAPI); + } + + @Bean + @ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class) + public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties, + CircuitBreakAPI circuitBreakAPI) { + return new ExceptionCircuitBreakerReporter(properties, circuitBreakAPI); + } + + @Bean + @ConditionalOnMissingBean(CircuitBreakerFactory.class) + public CircuitBreakerFactory polarisCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, ConsumerAPI consumerAPI) { + PolarisCircuitBreakerFactory factory = new PolarisCircuitBreakerFactory(circuitBreakAPI, consumerAPI); + customizers.forEach(customizer -> customizer.customize(factory)); + return factory; + } + @Bean public RouteLocator myRoutes(RouteLocatorBuilder builder) { Set codeSets = new HashSet<>(); @@ -228,4 +265,18 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { } + public static class PreDestroy implements DisposableBean { + + private final NamingServer namingServer; + + public PreDestroy(NamingServer namingServer) { + this.namingServer = namingServer; + } + + @Override + public void destroy() throws Exception { + namingServer.terminate(); + } + } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporterTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporterTest.java index 53e38c9d2..ec882022e 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporterTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporterTest.java @@ -95,7 +95,7 @@ public class ExceptionCircuitBreakerReporterTest { @Test public void testType() { - assertThat(exceptionCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.EXCEPTION); + assertThat(exceptionCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.Client.EXCEPTION); } @Test @@ -121,7 +121,7 @@ public class ExceptionCircuitBreakerReporterTest { pluginContext.setRequest(request); pluginContext.setResponse(response); - pluginContext.setServiceInstance(serviceInstance); + pluginContext.setTargetServiceInstance(serviceInstance, null); pluginContext.setThrowable(new RuntimeException()); exceptionCircuitBreakerReporter.run(pluginContext); diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporterTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporterTest.java index 4dcd3d19e..86707c237 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporterTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporterTest.java @@ -40,6 +40,7 @@ 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.HttpMethod; import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; @@ -74,6 +75,12 @@ public class SuccessCircuitBreakerReporterTest { 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 @@ -94,7 +101,7 @@ public class SuccessCircuitBreakerReporterTest { @Test public void testType() { - assertThat(successCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.POST); + assertThat(successCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.Client.POST); } @Test @@ -120,7 +127,7 @@ public class SuccessCircuitBreakerReporterTest { pluginContext.setRequest(request); pluginContext.setResponse(response); - pluginContext.setServiceInstance(serviceInstance); + pluginContext.setTargetServiceInstance(serviceInstance, null); successCircuitBreakerReporter.run(pluginContext); successCircuitBreakerReporter.getOrder(); diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateIntegrationTest.java similarity index 76% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateIntegrationTest.java index 97b82f086..1be0a170c 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateIntegrationTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.resttemplate; import java.io.BufferedReader; import java.io.IOException; @@ -24,15 +24,18 @@ import java.io.InputStreamReader; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.stream.Collectors; -import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; +import com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreakerFactory; import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerFallback; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerHttpResponse; +import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter; +import com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory; @@ -40,15 +43,17 @@ import com.tencent.polaris.client.util.Utils; import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; import com.tencent.polaris.test.common.TestUtils; import com.tencent.polaris.test.mock.discovery.NamingServer; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; +import org.springframework.cloud.client.circuitbreaker.Customizer; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.ApplicationContext; @@ -57,7 +62,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.client.ExpectedCount; import org.springframework.test.web.client.MockRestServiceServer; @@ -67,6 +71,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.DefaultUriBuilderFactory; +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -80,47 +85,44 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat */ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = RANDOM_PORT, - classes = PolarisCircuitBreakerIntegrationTest.TestConfig.class, + classes = PolarisCircuitBreakerRestTemplateIntegrationTest.TestConfig.class, properties = { "spring.cloud.gateway.enabled=false", "feign.circuitbreaker.enabled=true", - "spring.cloud.polaris.namespace=default", - "spring.cloud.polaris.service=test", - "spring.cloud.polaris.address=grpc://127.0.0.1:10081" + "spring.cloud.polaris.namespace=" + NAMESPACE_TEST, + "spring.cloud.polaris.service=test" }) -@DirtiesContext -public class PolarisCircuitBreakerIntegrationTest { +public class PolarisCircuitBreakerRestTemplateIntegrationTest { private static final String TEST_SERVICE_NAME = "test-service-callee"; - private static NamingServer namingServer; @Autowired @Qualifier("defaultRestTemplate") private RestTemplate defaultRestTemplate; + @Autowired @Qualifier("restTemplateFallbackFromPolaris") private RestTemplate restTemplateFallbackFromPolaris; + @Autowired @Qualifier("restTemplateFallbackFromCode") private RestTemplate restTemplateFallbackFromCode; + @Autowired @Qualifier("restTemplateFallbackFromCode2") private RestTemplate restTemplateFallbackFromCode2; + @Autowired @Qualifier("restTemplateFallbackFromCode3") private RestTemplate restTemplateFallbackFromCode3; + @Autowired @Qualifier("restTemplateFallbackFromCode4") private RestTemplate restTemplateFallbackFromCode4; + @Autowired private ApplicationContext applicationContext; - @AfterAll - public static void afterAll() { - if (null != namingServer) { - namingServer.terminate(); - } - } @Test public void testRestTemplate() throws URISyntaxException { @@ -164,15 +166,22 @@ public class PolarisCircuitBreakerIntegrationTest { @EnableFeignClients public static class TestConfig { + @Autowired(required = false) + private List> customizers = new ArrayList<>(); + + { + PolarisSDKContextManager.innerDestroy(); + } + @Bean - @PolarisCircuitBreaker(fallback = "fallback") + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallback = "fallback") public RestTemplate defaultRestTemplate() { return new RestTemplate(); } @Bean @LoadBalanced - @PolarisCircuitBreaker + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker public RestTemplate restTemplateFallbackFromPolaris() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -182,7 +191,7 @@ public class PolarisCircuitBreakerIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback.class) + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback.class) public RestTemplate restTemplateFallbackFromCode() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -192,7 +201,7 @@ public class PolarisCircuitBreakerIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback2.class) + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback2.class) public RestTemplate restTemplateFallbackFromCode2() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -202,7 +211,7 @@ public class PolarisCircuitBreakerIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback3.class) + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback3.class) public RestTemplate restTemplateFallbackFromCode3() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -236,18 +245,12 @@ public class PolarisCircuitBreakerIntegrationTest { } @Bean - public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException { - try { - namingServer = NamingServer.startNamingServer(10081); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { - - } - ServiceKey serviceKey = new ServiceKey("default", TEST_SERVICE_NAME); - + public NamingServer namingServer() throws IOException { + NamingServer namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); + ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME); CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); - InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader() + InputStream inputStream = PolarisCircuitBreakerRestTemplateIntegrationTest.class.getClassLoader() .getResourceAsStream("circuitBreakerRule.json"); String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines() .collect(Collectors.joining("")); @@ -256,10 +259,41 @@ public class PolarisCircuitBreakerIntegrationTest { CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() .addRules(circuitBreakerRule).build(); namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker); + return namingServer; + } + + @Bean + public PreDestroy preDestroy(NamingServer namingServer) { + return new PreDestroy(namingServer); + } + + @Bean + public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) { com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress(); return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration); } + @Bean + public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties, + CircuitBreakAPI circuitBreakAPI) { + return new SuccessCircuitBreakerReporter(properties, circuitBreakAPI); + } + + @Bean + public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties, + CircuitBreakAPI circuitBreakAPI) { + return new ExceptionCircuitBreakerReporter(properties, circuitBreakAPI); + } + + @Bean + public CircuitBreakerFactory polarisCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, + PolarisSDKContextManager polarisSDKContextManager) { + PolarisCircuitBreakerFactory factory = new PolarisCircuitBreakerFactory( + circuitBreakAPI, polarisSDKContextManager.getConsumerAPI()); + customizers.forEach(customizer -> customizer.customize(factory)); + return factory; + } + @RestController @RequestMapping("/example/service/b") public class ServiceBController { @@ -309,4 +343,18 @@ public class PolarisCircuitBreakerIntegrationTest { } } + public static class PreDestroy implements DisposableBean { + + private final NamingServer namingServer; + + public PreDestroy(NamingServer namingServer) { + this.namingServer = namingServer; + } + + @Override + public void destroy() throws Exception { + namingServer.terminate(); + } + } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java index e6213dbab..d05a0dcc2 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java @@ -35,6 +35,7 @@ import org.mockito.Mockito; 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; public class PolarisCircuitBreakerUtilsTests { @@ -68,4 +69,11 @@ public class PolarisCircuitBreakerUtilsTests { PolarisCircuitBreakerUtils.reportStatus(consumerAPI, conf, new CallAbortedException("mock", new CircuitBreakerStatus.FallbackInfo(0, new HashMap<>(), ""))); } + @Test + public void testResolveCircuitBreakerId() { + assertThat(PolarisCircuitBreakerUtils.resolveCircuitBreakerId("test_svc")).isEqualTo(new String[]{NAMESPACE_TEST, "test_svc", ""}); + assertThat(PolarisCircuitBreakerUtils.resolveCircuitBreakerId("test_svc#test_path")).isEqualTo(new String[]{NAMESPACE_TEST, "test_svc", "test_path"}); + assertThat(PolarisCircuitBreakerUtils.resolveCircuitBreakerId("test_ns#test_svc#test_path")).isEqualTo(new String[]{"test_ns", "test_svc", "test_path"}); + } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application-test-gateway.yml b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application-test-gateway.yml index 6094b46e5..06481f254 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application-test-gateway.yml +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application-test-gateway.yml @@ -13,7 +13,7 @@ spring: feature-env: enabled: true polaris: - address: grpc://127.0.0.1:8091 + address: grpc://127.0.0.1:10081 namespace: default enabled: true gateway: 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 f336be29c..0d5855b86 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 @@ -20,6 +20,7 @@ package com.tencent.cloud.polaris.config; import com.tencent.cloud.polaris.config.adapter.AffectedConfigurationPropertiesRebinder; import com.tencent.cloud.polaris.config.adapter.PolarisConfigPropertyRefresher; +import com.tencent.cloud.polaris.config.adapter.PolarisConfigRefreshScopeAnnotationDetector; import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; import com.tencent.cloud.polaris.config.adapter.PolarisRefreshAffectedContextRefresher; import com.tencent.cloud.polaris.config.adapter.PolarisRefreshEntireContextRefresher; @@ -27,6 +28,8 @@ import com.tencent.cloud.polaris.config.annotation.PolarisConfigAnnotationProces import com.tencent.cloud.polaris.config.condition.ConditionalOnReflectRefreshType; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; 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; @@ -60,6 +63,12 @@ public class PolarisConfigAutoConfiguration { return new PolarisConfigChangeEventListener(); } + @Bean + public PolarisConfigLoggerApplicationListener polarisConfigLoggerApplicationListener() { + return new PolarisConfigLoggerApplicationListener(); + } + + @Bean @Primary @ConditionalOnReflectRefreshType @@ -102,5 +111,15 @@ public class PolarisConfigAutoConfiguration { return new PolarisRefreshAffectedContextRefresher(polarisConfigProperties, polarisPropertySourceManager, springValueRegistry, placeholderHelper); } + + @Bean + public PolarisConfigRefreshScopeAnnotationDetector polarisConfigRefreshScopeAnnotationDetector() { + return new PolarisConfigRefreshScopeAnnotationDetector(); + } + + @Bean + public PolarisConfigRefreshOptimizationListener polarisConfigRefreshOptimizationListener() { + return new PolarisConfigRefreshOptimizationListener(); + } } } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java index 237533c64..925342f9c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigBootstrapAutoConfiguration.java @@ -23,9 +23,9 @@ import com.tencent.cloud.polaris.config.adapter.PolarisConfigFileLocator; import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; import com.tencent.cloud.polaris.config.condition.ConditionalOnReflectRefreshType; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.context.config.PolarisContextProperties; -import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.configuration.api.core.ConfigFileService; import com.tencent.polaris.configuration.factory.ConfigFileServiceFactory; @@ -60,8 +60,8 @@ public class PolarisConfigBootstrapAutoConfiguration { @Bean @ConditionalOnConnectRemoteServerEnabled - public ConfigFileService configFileService(SDKContext sdkContext) { - return ConfigFileServiceFactory.createConfigFileService(sdkContext); + public ConfigFileService configFileService(PolarisSDKContextManager polarisSDKContextManager) { + return ConfigFileServiceFactory.createConfigFileService(polarisSDKContextManager.getSDKContext()); } @Bean diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigCustomExtensionLayer.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigCustomExtensionLayer.java new file mode 100644 index 000000000..9996abbd0 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigCustomExtensionLayer.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 www.tencent.com. + * All Rights Reserved. + * This program is the confidential and proprietary information of + * www.tencent.com ("Confidential Information"). You shall not disclose such + * Confidential Information and shall use it only in accordance with + * the terms of the license agreement you entered into with www.tencent.com. + * + */ + +package com.tencent.cloud.polaris.config.adapter; + +import com.tencent.polaris.configuration.api.core.ConfigFileService; + +import org.springframework.core.env.CompositePropertySource; +import org.springframework.core.env.Environment; + + +/** + * @Date Jul 23, 2023 2:57:49 PM + * @author juanyinyang + */ +public interface PolarisConfigCustomExtensionLayer { + void execute(String namespace, Environment environment, CompositePropertySource compositePropertySource, PolarisPropertySourceManager polarisPropertySourceManager, ConfigFileService configFileService); + +} 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 f71079ac6..740f697bc 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 @@ -20,9 +20,11 @@ package com.tencent.cloud.polaris.config.adapter; import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.ServiceLoader; import java.util.concurrent.ConcurrentHashMap; import com.tencent.cloud.polaris.config.config.ConfigFileGroup; @@ -68,12 +70,20 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { private final PolarisPropertySourceManager polarisPropertySourceManager; private final Environment environment; + // 此类给一些客户定制化逻辑做一些特殊业务分组文件的配置处理 + private PolarisConfigCustomExtensionLayer polarisConfigCustomExtensionLayer; + + { + ServiceLoader polarisConfigCustomExtensionLayerLoader = ServiceLoader.load(PolarisConfigCustomExtensionLayer.class); + Iterator polarisConfigCustomExtensionLayerIterator = polarisConfigCustomExtensionLayerLoader.iterator(); + // 一般就一个实现类,如果有多个,那么加载的是最后一个 + while (polarisConfigCustomExtensionLayerIterator.hasNext()) { + polarisConfigCustomExtensionLayer = polarisConfigCustomExtensionLayerIterator.next(); + LOGGER.info("[SCT Config] PolarisConfigFileLocator init polarisConfigCustomExtensionLayer:{}", polarisConfigCustomExtensionLayer); + } + } - public PolarisConfigFileLocator(PolarisConfigProperties polarisConfigProperties, - PolarisContextProperties polarisContextProperties, - ConfigFileService configFileService, - PolarisPropertySourceManager polarisPropertySourceManager, - Environment environment) { + public PolarisConfigFileLocator(PolarisConfigProperties polarisConfigProperties, PolarisContextProperties polarisContextProperties, ConfigFileService configFileService, PolarisPropertySourceManager polarisPropertySourceManager, Environment environment) { this.polarisConfigProperties = polarisConfigProperties; this.polarisContextProperties = polarisContextProperties; this.configFileService = configFileService; @@ -83,9 +93,10 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { @Override public PropertySource locate(Environment environment) { - CompositePropertySource compositePropertySource = new CompositePropertySource( - POLARIS_CONFIG_PROPERTY_SOURCE_NAME); + CompositePropertySource compositePropertySource = new CompositePropertySource(POLARIS_CONFIG_PROPERTY_SOURCE_NAME); + // load custom config extension files + initCustomPolarisConfigExtensionFiles(compositePropertySource); // load spring boot default config files initInternalConfigFiles(compositePropertySource); @@ -99,12 +110,21 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { return compositePropertySource; } + private void initCustomPolarisConfigExtensionFiles(CompositePropertySource compositePropertySource) { + if (polarisConfigCustomExtensionLayer == null) { + LOGGER.info("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps"); + return; + } + String namespace = polarisContextProperties.getNamespace(); + polarisConfigCustomExtensionLayer.execute(namespace, environment, compositePropertySource, polarisPropertySourceManager, configFileService); + LOGGER.info("[SCT Config] InitCustomPolarisConfigExtensionFiles finished, namespace:{}", namespace); + } + private void initInternalConfigFiles(CompositePropertySource compositePropertySource) { List internalConfigFiles = getInternalConfigFiles(); for (ConfigFileMetadata configFile : internalConfigFiles) { - PolarisPropertySource polarisPropertySource = loadPolarisPropertySource( - configFile.getNamespace(), configFile.getFileGroup(), configFile.getFileName()); + PolarisPropertySource polarisPropertySource = loadPolarisPropertySource(configFile.getNamespace(), configFile.getFileGroup(), configFile.getFileName()); compositePropertySource.addPropertySource(polarisPropertySource); @@ -141,36 +161,37 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { return internalConfigFiles; } - private void buildInternalApplicationConfigFiles( - List internalConfigFiles, String namespace, String serviceName, List profileList) { + private void buildInternalApplicationConfigFiles(List internalConfigFiles, String namespace, String serviceName, List profileList) { for (String profile : profileList) { if (!StringUtils.hasText(profile)) { continue; } internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application-" + profile + ".properties")); internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application-" + profile + ".yml")); + internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application-" + profile + ".yaml")); } // build default config properties files. internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application.properties")); internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application.yml")); + internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application.yaml")); } - private void buildInternalBootstrapConfigFiles( - List internalConfigFiles, String namespace, String serviceName, List profileList) { + private void buildInternalBootstrapConfigFiles(List internalConfigFiles, String namespace, String serviceName, List profileList) { for (String profile : profileList) { if (!StringUtils.hasText(profile)) { continue; } internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap-" + profile + ".properties")); internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap-" + profile + ".yml")); + internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap-" + profile + ".yaml")); } // build default config properties files. internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap.properties")); internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap.yml")); + internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap.yaml")); } - private void initCustomPolarisConfigFiles(CompositePropertySource compositePropertySource, - List configFileGroups) { + private void initCustomPolarisConfigFiles(CompositePropertySource compositePropertySource, List configFileGroups) { String namespace = polarisContextProperties.getNamespace(); for (ConfigFileGroup configFileGroup : configFileGroups) { @@ -192,14 +213,12 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { polarisPropertySourceManager.addPropertySource(polarisPropertySource); - LOGGER.info("[SCT Config] Load and inject polaris config file success." - + " namespace = {}, group = {}, fileName = {}", namespace, group, fileName); + LOGGER.info("[SCT Config] Load and inject polaris config file success. namespace = {}, group = {}, fileName = {}", namespace, group, fileName); } } } - private PolarisPropertySource loadPolarisPropertySource(String namespace, - String group, String fileName) { + private PolarisPropertySource loadPolarisPropertySource(String namespace, String group, String fileName) { ConfigKVFile configKVFile; // unknown extension is resolved as properties file if (ConfigFileFormat.isPropertyFile(fileName) || ConfigFileFormat.isUnknownFile(fileName)) { @@ -209,11 +228,9 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { configKVFile = configFileService.getConfigYamlFile(namespace, group, fileName); } else { - LOGGER.warn("[SCT Config] Unsupported config file. namespace = {}, group = {}, fileName = {}", - namespace, group, fileName); + LOGGER.warn("[SCT Config] Unsupported config file. namespace = {}, group = {}, fileName = {}", namespace, group, fileName); - throw new IllegalStateException("Only configuration files in the format of properties / yaml / yaml" - + " can be injected into the spring context"); + throw new IllegalStateException("Only configuration files in the format of properties / yaml / yaml" + " can be injected into the spring context"); } Map map = new ConcurrentHashMap<>(); 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 7dead1773..f79c01fd6 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 @@ -23,6 +23,7 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; +import com.tencent.cloud.polaris.config.logger.PolarisConfigLoggerContext; import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeListener; import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo; import org.slf4j.Logger; @@ -33,6 +34,8 @@ import org.springframework.context.ApplicationListener; import org.springframework.lang.NonNull; import org.springframework.util.CollectionUtils; + + /** * 1. Listen to the Polaris server configuration publishing event 2. Write the changed * configuration content to propertySource 3. Refresh the context through contextRefresher @@ -96,6 +99,18 @@ public abstract class PolarisConfigPropertyAutoRefresher LOGGER.info("[SCT Config] changed property = {}", configPropertyChangeInfo); + // 新增动态改变日志级别的能力 + try { + if (changedKey.startsWith("logging.level") && changedKey.length() >= 14) { + String loggerName = changedKey.substring(14); + String newValue = configPropertyChangeInfo.getNewValue(); + LOGGER.info("[SCT Config] set logging.level loggerName:{}, newValue:{}", loggerName, newValue); + PolarisConfigLoggerContext.setLevel(loggerName, newValue); + } + } + catch (Exception e) { + LOGGER.error("[SCT Config] set logging.level exception,", e); + } switch (configPropertyChangeInfo.getChangeType()) { case MODIFIED: case ADDED: diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigRefreshScopeAnnotationDetector.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigRefreshScopeAnnotationDetector.java new file mode 100644 index 000000000..5c26342ce --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigRefreshScopeAnnotationDetector.java @@ -0,0 +1,94 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.config.adapter; + +import java.lang.annotation.Annotation; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.core.Ordered; +import org.springframework.core.PriorityOrdered; +import org.springframework.lang.NonNull; + +/** + * Mainly used to detect whether the annotation class {@link org.springframework.cloud.context.config.annotation.RefreshScope} + * exists, and whether the user has configured beans using this annotation in their business system. + * If the annotation {@code @RefreshScope} exists and is used, the auto-optimization will be triggered + * in listener {@link com.tencent.cloud.polaris.config.listener.PolarisConfigRefreshOptimizationListener}. + * + *

This bean will only be created and initialized when the config refresh type is {@code RefreshType.REFLECT}. + * + * @author jarvisxiong + */ +@SuppressWarnings({"unchecked", "rawtypes"}) +public class PolarisConfigRefreshScopeAnnotationDetector implements BeanPostProcessor, InitializingBean, PriorityOrdered { + + private final AtomicBoolean isRefreshScopeAnnotationUsed = new AtomicBoolean(false); + + private Class refreshScopeAnnotationClass; + + private String annotatedRefreshScopeBeanName; + + @Override + public Object postProcessBeforeInitialization(@NonNull Object bean, @NonNull String beanName) + throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(@NonNull Object bean, @NonNull String beanName) + throws BeansException { + if (isRefreshScopeAnnotationUsed() || refreshScopeAnnotationClass == null) { + return bean; + } + Annotation[] refreshScopeAnnotations = bean.getClass().getAnnotationsByType(refreshScopeAnnotationClass); + if (refreshScopeAnnotations.length > 0) { + if (isRefreshScopeAnnotationUsed.compareAndSet(false, true)) { + annotatedRefreshScopeBeanName = beanName; + } + } + return bean; + } + + @Override + public void afterPropertiesSet() { + try { + refreshScopeAnnotationClass = Class.forName( + "org.springframework.cloud.context.config.annotation.RefreshScope", + false, + getClass().getClassLoader()); + } + catch (ClassNotFoundException ignored) { + } + } + + @Override + public int getOrder() { + return Ordered.LOWEST_PRECEDENCE; + } + + public boolean isRefreshScopeAnnotationUsed() { + return isRefreshScopeAnnotationUsed.get(); + } + + public String getAnnotatedRefreshScopeBeanName() { + return annotatedRefreshScopeBeanName; + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java index 50e8fde54..6a014aa04 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/config/PolarisConfigProperties.java @@ -15,15 +15,16 @@ * specific language governing permissions and limitations under the License. * */ - package com.tencent.cloud.polaris.config.config; import java.util.List; import com.tencent.cloud.polaris.config.enums.RefreshType; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; + /** * polaris config module bootstrap configs. * @@ -31,26 +32,29 @@ import org.springframework.boot.context.properties.ConfigurationProperties; */ @ConfigurationProperties("spring.cloud.polaris.config") public class PolarisConfigProperties { - /** * Whether to open the configuration center. */ + @Value("${spring.cloud.polaris.config.enabled:#{'true'}}") private boolean enabled = true; /** * Configuration center service address list. */ + @Value("${spring.cloud.polaris.config.address:}") private String address; /** * Polaris config grpc port. */ + @Value("${spring.cloud.polaris.config.port:#{'8093'}}") private int port = 8093; /** * Whether to automatically update to the spring context when the configuration file. * is updated */ + @Value("${spring.cloud.polaris.config.autoRefresh:#{'true'}}") private boolean autoRefresh = true; private boolean shutdownIfConnectToConfigServerFailed = true; diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListener.java new file mode 100644 index 000000000..30e256dca --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListener.java @@ -0,0 +1,132 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.config.listener; + +import java.util.Collections; + +import com.tencent.cloud.polaris.config.adapter.PolarisConfigRefreshScopeAnnotationDetector; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; +import com.tencent.cloud.polaris.config.adapter.PolarisRefreshEntireContextRefresher; +import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; +import com.tencent.cloud.polaris.config.enums.RefreshType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.config.ConstructorArgumentValues; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.cloud.context.refresh.ContextRefresher; +import org.springframework.context.ApplicationListener; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.lang.NonNull; + +import static com.tencent.cloud.polaris.config.condition.ReflectRefreshTypeCondition.POLARIS_CONFIG_REFRESH_TYPE; + +/** + * When {@link com.tencent.cloud.polaris.config.adapter.PolarisConfigRefreshScopeAnnotationDetector} detects that + * the annotation {@code @RefreshScope} exists and is used, but the config refresh type + * {@code spring.cloud.polaris.config.refresh-type} is still {@code RefreshType.REFLECT}, then the framework will + * automatically switch the config refresh type to {@code RefreshType.REFRESH_CONTEXT}. + * + *

The purpose of this optimization is to omit additional configuration, and facilitate for users to use the + * dynamic configuration refresh strategy of Spring Cloud Context.

+ * + * @author jarvisxiong + */ +public class PolarisConfigRefreshOptimizationListener implements ApplicationListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfigRefreshOptimizationListener.class); + + private static final String CONFIG_REFRESH_TYPE_PROPERTY = "configRefreshTypeProperty"; + + private static final String REFLECT_REBINDER_BEAN_NAME = "affectedConfigurationPropertiesRebinder"; + + private static final String REFLECT_REFRESHER_BEAN_NAME = "polarisReflectPropertySourceAutoRefresher"; + + private static final String REFRESH_CONTEXT_REFRESHER_BEAN_NAME = "polarisRefreshContextPropertySourceAutoRefresher"; + + + @Override + public void onApplicationEvent(@NonNull ContextRefreshedEvent event) { + ConfigurableApplicationContext applicationContext = (ConfigurableApplicationContext) event.getApplicationContext(); + PolarisConfigRefreshScopeAnnotationDetector detector = applicationContext.getBean(PolarisConfigRefreshScopeAnnotationDetector.class); + boolean isRefreshScopeAnnotationUsed = detector.isRefreshScopeAnnotationUsed(); + String annotatedRefreshScopeBeanName = detector.getAnnotatedRefreshScopeBeanName(); + // using System.setProperty to set spring.cloud.polaris.config.refresh-type + String value = System.getProperty("spring.cloud.polaris.config.refresh-type"); + boolean isSystemSetRefreshType = RefreshType.REFRESH_CONTEXT.toString().equalsIgnoreCase(value); + // a bean is using @RefreshScope, but the config refresh type is still [reflect], switch automatically + if (isRefreshScopeAnnotationUsed || isSystemSetRefreshType) { + if (isRefreshScopeAnnotationUsed) { + LOGGER.warn("Detected that the bean [{}] is using @RefreshScope annotation, but the config refresh type is still [reflect]. " + "[SCT] will automatically switch to [refresh_context].", annotatedRefreshScopeBeanName); + } + if (isSystemSetRefreshType) { + LOGGER.warn("Detected that using System.setProperty to set spring.cloud.polaris.config.refresh-type = refresh_context, but the config refresh type is still [reflect]. " + "[SCT] will automatically switch to [refresh_context]."); + } + switchConfigRefreshTypeProperty(applicationContext); + modifyPolarisConfigPropertiesBean(applicationContext); + // remove related bean of type [reflect] + removeRelatedBeansOfReflect(applicationContext); + // register a new refresher bean of type [refresh_context] + registerRefresherBeanOfRefreshContext(applicationContext); + // add the new refresher to context as a listener + addRefresherBeanAsListener(applicationContext); + } + } + + private void switchConfigRefreshTypeProperty(ConfigurableApplicationContext applicationContext) { + MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources(); + propertySources.addFirst(new MapPropertySource(CONFIG_REFRESH_TYPE_PROPERTY, Collections.singletonMap(POLARIS_CONFIG_REFRESH_TYPE, RefreshType.REFRESH_CONTEXT))); + } + + private void modifyPolarisConfigPropertiesBean(ConfigurableApplicationContext applicationContext) { + PolarisConfigProperties polarisConfigProperties = applicationContext.getBean(PolarisConfigProperties.class); + polarisConfigProperties.setRefreshType(RefreshType.REFRESH_CONTEXT); + } + + private void removeRelatedBeansOfReflect(ConfigurableApplicationContext applicationContext) { + DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory(); + beanFactory.removeBeanDefinition(REFLECT_REFRESHER_BEAN_NAME); + beanFactory.removeBeanDefinition(REFLECT_REBINDER_BEAN_NAME); + } + + private void registerRefresherBeanOfRefreshContext(ConfigurableApplicationContext applicationContext) { + DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory(); + AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition(); + beanDefinition.setBeanClass(PolarisRefreshEntireContextRefresher.class); + PolarisConfigProperties polarisConfigProperties = beanFactory.getBean(PolarisConfigProperties.class); + PolarisPropertySourceManager polarisPropertySourceManager = beanFactory.getBean(PolarisPropertySourceManager.class); + ContextRefresher contextRefresher = beanFactory.getBean(ContextRefresher.class); + ConstructorArgumentValues constructorArgumentValues = beanDefinition.getConstructorArgumentValues(); + constructorArgumentValues.addIndexedArgumentValue(0, polarisConfigProperties); + constructorArgumentValues.addIndexedArgumentValue(1, polarisPropertySourceManager); + constructorArgumentValues.addIndexedArgumentValue(2, contextRefresher); + beanFactory.registerBeanDefinition(REFRESH_CONTEXT_REFRESHER_BEAN_NAME, beanDefinition); + } + + + private void addRefresherBeanAsListener(ConfigurableApplicationContext applicationContext) { + PolarisRefreshEntireContextRefresher refresher = (PolarisRefreshEntireContextRefresher) applicationContext.getBean(REFRESH_CONTEXT_REFRESHER_BEAN_NAME); + applicationContext.addApplicationListener(refresher); + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/Level.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/Level.java new file mode 100644 index 000000000..17babf0a7 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/Level.java @@ -0,0 +1,28 @@ +package com.tencent.cloud.polaris.config.logger; + +/** + * @author juanyinyang + */ +public enum Level { + + /** 日志级别. */ + TRACE("TRACE"), DEBUG("DEBUG"), INFO("INFO"), WARN("WARN"), ERROR("ERROR"), FATAL("FATAL"), OFF("OFF"); + + private String level; + + Level(String level) { + this.level = level; + } + public String getLevel() { + return level; + } + + public static Level levelOf(String level) { + for (Level l : Level.values()) { + if (l.level.equalsIgnoreCase(level)) { + return l; + } + } + return null; + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerApplicationListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerApplicationListener.java new file mode 100644 index 000000000..f834b2c50 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerApplicationListener.java @@ -0,0 +1,35 @@ +package com.tencent.cloud.polaris.config.logger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.boot.logging.LoggingSystem; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; + +/** + * @author juanyinyang + */ +public class PolarisConfigLoggerApplicationListener implements ApplicationListener { + private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfigLoggerApplicationListener.class); + /** + * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) + */ + @Override + public void onApplicationEvent(ApplicationEvent event) { + try { + // Initialize application loggingSystem. + if (event instanceof ApplicationStartedEvent) { + ApplicationStartedEvent startedEvent = (ApplicationStartedEvent) event; + ClassLoader classLoader = startedEvent.getSpringApplication().getClassLoader(); + LoggingSystem loggingSystem = LoggingSystem.get(classLoader); + LOGGER.info("PolarisConfigLoggerApplicationListener onApplicationEvent init loggingSystem:{}", loggingSystem); + PolarisConfigLoggerContext.setLogSystem(loggingSystem); + } + } + catch (Exception e) { + LOGGER.error("PolarisConfigLoggerApplicationListener onApplicationEvent exception:", e); + } + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerContext.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerContext.java new file mode 100644 index 000000000..9bda215f8 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerContext.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2018 www.tencent.com. + * All Rights Reserved. + * This program is the confidential and proprietary information of + * www.tencent.com ("Confidential Information"). You shall not disclose such + * Confidential Information and shall use it only in accordance with + * the terms of the license agreement you entered into with www.tencent.com. + */ + +package com.tencent.cloud.polaris.config.logger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.boot.logging.LogLevel; +import org.springframework.boot.logging.LoggingSystem; +import org.springframework.util.Assert; + +import static org.springframework.boot.logging.LoggingSystem.ROOT_LOGGER_NAME; + +/** + * @author juanyinyang + */ +public final class PolarisConfigLoggerContext { + + private static LoggingSystem loggingSystem; + + private PolarisConfigLoggerContext() { + + } + protected static void setLogSystem(LoggingSystem logSystem) { + Assert.notNull(logSystem, "Logging System should not be null"); + PolarisConfigLoggerContext.loggingSystem = logSystem; + } + + public static void setLevel(String loggerName, String level) { + if (loggingSystem == null) { + printLog("[SCT Config] PolarisConfigLoggerContext logger: [" + loggerName + "] change to target level fail. caused by internal exception:" + level, Level.WARN); + return; + } + Level loggerLevel = Level.levelOf(level); + if (loggerLevel == null) { + printLog("[SCT Config] PolarisConfigLoggerContext logger: [" + loggerName + "] change to target level fail. caused by level is not support, level:" + level, Level.WARN); + return; + } + LogLevel logLevel = null; + switch (loggerLevel) { + case TRACE: + logLevel = LogLevel.TRACE; + break; + case DEBUG: + logLevel = LogLevel.DEBUG; + break; + case OFF: + logLevel = LogLevel.OFF; + break; + case INFO: + logLevel = LogLevel.INFO; + break; + case WARN: + logLevel = LogLevel.WARN; + break; + case ERROR: + logLevel = LogLevel.ERROR; + break; + case FATAL: + logLevel = LogLevel.FATAL; + break; + default: + printLog("[SCT Config] PolarisConfigLoggerContext logger: [" + loggerName + "] setLevel fail. caused by level is not support, level: " + level, Level.WARN); + } + loggingSystem.setLogLevel(loggerName, logLevel); + printLog("[SCT Config] PolarisConfigLoggerContext logger: [" + loggerName + "] changed to level:" + level, Level.INFO); + } + /** + * 打印日志. + */ + private static void printLog(String message, Level level) { + Logger logger = LoggerFactory.getLogger(ROOT_LOGGER_NAME); + if (level.ordinal() <= Level.INFO.ordinal()) { + if (logger != null) { + logger.info(message); + } + else { + StdLog.info(message); + } + } + else { + if (logger != null) { + logger.warn(message); + } + else { + StdLog.warn(message); + } + } + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/StdLog.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/StdLog.java new file mode 100644 index 000000000..df9eddafd --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/StdLog.java @@ -0,0 +1,79 @@ +package com.tencent.cloud.polaris.config.logger; + +import java.io.PrintStream; +import java.util.Calendar; + +/** + * internal output logger. + * @author juanyinyang + */ +public final class StdLog { + + private static final String CLASS_INFO = StdLog.class.getName(); + + + protected static boolean debugEnabled = false; + + /** + * *enable info level log. + */ + protected static boolean infoEnabled = true; + + /** + * quite mode will out put nothing. + */ + protected static boolean quietMode = false; + + private static final String DEBUG_FIX = "StdLog:DEBUG: "; + + private static final String INFO_FIX = "StdLog:INFO: "; + + private static final String WARN_FIX = "StdLog:WARN: "; + + private StdLog() { + } + + public static void setQuietMode(boolean quietMode) { + StdLog.quietMode = quietMode; + } + + public static void setInfoEnabled(boolean infoEnabled) { + StdLog.infoEnabled = infoEnabled; + } + + public static void setDebugEnabled(boolean debugEnabled) { + StdLog.debugEnabled = debugEnabled; + } + + public static void debug(String msg) { + if (debugEnabled && !quietMode) { + println(System.out, DEBUG_FIX + msg); + } + } + + public static void info(String msg) { + if (infoEnabled && !quietMode) { + println(System.out, INFO_FIX + msg); + } + } + + public static void warn(String msg) { + if (infoEnabled && !quietMode) { + println(System.err, WARN_FIX + msg); + } + } + + public static void warn(String msg, Throwable t) { + if (quietMode) { + return; + } + println(System.err, WARN_FIX + msg); + if (t != null) { + t.printStackTrace(); + } + } + + private static void println(PrintStream out, String msg) { + out.println(Calendar.getInstance().getTime().toString() + " " + CLASS_INFO + " " + msg); + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java index 61e6706dc..acdeb050c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java @@ -81,8 +81,10 @@ public class PolarisConfigFileLocatorTest { Map emptyMap = new HashMap<>(); ConfigKVFile emptyConfigFile = new MockedConfigKVFile(emptyMap); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application.yml")).thenReturn(emptyConfigFile); + when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application.yaml")).thenReturn(emptyConfigFile); when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "bootstrap.properties")).thenReturn(emptyConfigFile); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yml")).thenReturn(emptyConfigFile); + when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yaml")).thenReturn(emptyConfigFile); when(polarisConfigProperties.getGroups()).thenReturn(null); when(environment.getActiveProfiles()).thenReturn(new String[] {}); @@ -121,11 +123,15 @@ public class PolarisConfigFileLocatorTest { Map emptyMap = new HashMap<>(); ConfigKVFile emptyConfigFile = new MockedConfigKVFile(emptyMap); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application.yml")).thenReturn(emptyConfigFile); + when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application.yaml")).thenReturn(emptyConfigFile); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application-dev.yml")).thenReturn(emptyConfigFile); + when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application-dev.yaml")).thenReturn(emptyConfigFile); when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "bootstrap.properties")).thenReturn(emptyConfigFile); when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "bootstrap-dev.properties")).thenReturn(emptyConfigFile); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yml")).thenReturn(emptyConfigFile); + when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yaml")).thenReturn(emptyConfigFile); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap-dev.yml")).thenReturn(emptyConfigFile); + when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap-dev.yaml")).thenReturn(emptyConfigFile); when(polarisConfigProperties.getGroups()).thenReturn(null); when(environment.getActiveProfiles()).thenReturn(new String[] {"dev"}); @@ -150,8 +156,10 @@ public class PolarisConfigFileLocatorTest { when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "application.properties")).thenReturn(emptyConfigFile); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application.yml")).thenReturn(emptyConfigFile); + when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application.yaml")).thenReturn(emptyConfigFile); when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "bootstrap.properties")).thenReturn(emptyConfigFile); when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yml")).thenReturn(emptyConfigFile); + when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yaml")).thenReturn(emptyConfigFile); List customFiles = new LinkedList<>(); ConfigFileGroup configFileGroup = new ConfigFileGroup(); diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigRefreshScopeAnnotationDetectorTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigRefreshScopeAnnotationDetectorTest.java new file mode 100644 index 000000000..31e3c1d57 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigRefreshScopeAnnotationDetectorTest.java @@ -0,0 +1,101 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.config.adapter; + +import com.tencent.cloud.polaris.config.PolarisConfigAutoConfiguration; +import com.tencent.cloud.polaris.config.PolarisConfigBootstrapAutoConfiguration; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration; +import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; +import org.springframework.cloud.context.config.annotation.RefreshScope; + +import static org.assertj.core.api.Assertions.as; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * test for {@link PolarisConfigRefreshScopeAnnotationDetector}. + */ +@SuppressWarnings("rawtypes") +public class PolarisConfigRefreshScopeAnnotationDetectorTest { + + private static Class refreshScopeAnnotationClass = null; + + static { + try { + refreshScopeAnnotationClass = Class.forName( + "org.springframework.cloud.context.config.annotation.RefreshScope", + false, + PolarisConfigRefreshScopeAnnotationDetectorTest.class.getClassLoader()); + } + catch (ClassNotFoundException ignored) { + } + } + + @Test + public void testUseRefreshScope() { + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisConfigBootstrapAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(PolarisConfigAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(RefreshAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(ConfigurationPropertiesRebinderAutoConfiguration.class)) + .withBean("testBeanWithRefreshScope", TestBeanWithRefreshScope.class) + .withPropertyValues("spring.application.name=" + "polarisConfigRefreshScopeAnnotationDetectorTest") + .withPropertyValues("server.port=" + 8080) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") + .withPropertyValues("spring.cloud.polaris.config.connect-remote-server=false"); + contextRunner.run(context -> { + assertThat(context).hasSingleBean(PolarisConfigRefreshScopeAnnotationDetector.class); + PolarisConfigRefreshScopeAnnotationDetector detector = context.getBean(PolarisConfigRefreshScopeAnnotationDetector.class); + assertThat(detector.isRefreshScopeAnnotationUsed()).isTrue(); + assertThat(detector.getAnnotatedRefreshScopeBeanName()).isEqualTo("scopedTarget.testBeanWithRefreshScope"); + assertThat(detector).extracting("refreshScopeAnnotationClass", as(InstanceOfAssertFactories.type(Class.class))) + .isEqualTo(refreshScopeAnnotationClass); + }); + } + + @Test + public void testNotUseRefreshScope() { + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisConfigBootstrapAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(PolarisConfigAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(RefreshAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(ConfigurationPropertiesRebinderAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + "polarisConfigRefreshScopeAnnotationDetectorTest") + .withPropertyValues("server.port=" + 8080) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") + .withPropertyValues("spring.cloud.polaris.config.connect-remote-server=false"); + contextRunner.run(context -> { + assertThat(context).hasSingleBean(PolarisConfigRefreshScopeAnnotationDetector.class); + PolarisConfigRefreshScopeAnnotationDetector detector = context.getBean(PolarisConfigRefreshScopeAnnotationDetector.class); + assertThat(detector.isRefreshScopeAnnotationUsed()).isFalse(); + assertThat(detector.getAnnotatedRefreshScopeBeanName()).isNull(); + assertThat(detector).extracting("refreshScopeAnnotationClass", as(InstanceOfAssertFactories.type(Class.class))) + .isEqualTo(refreshScopeAnnotationClass); + }); + } + + @RefreshScope + protected static class TestBeanWithRefreshScope { + + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListenerNotTriggeredTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListenerNotTriggeredTest.java new file mode 100644 index 000000000..2a0444a01 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListenerNotTriggeredTest.java @@ -0,0 +1,154 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.config.listener; + +import java.util.HashMap; +import java.util.Map; + +import com.google.common.collect.Lists; +import com.tencent.cloud.polaris.config.adapter.MockedConfigKVFile; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySource; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; +import com.tencent.cloud.polaris.config.adapter.PolarisRefreshAffectedContextRefresher; +import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; +import com.tencent.cloud.polaris.config.enums.RefreshType; +import com.tencent.polaris.configuration.api.core.ChangeType; +import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeEvent; +import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.context.refresh.ContextRefresher; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.stereotype.Component; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static com.tencent.cloud.polaris.config.condition.ReflectRefreshTypeCondition.POLARIS_CONFIG_REFRESH_TYPE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; + +/** + * test for {@link PolarisConfigRefreshOptimizationListener}. + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = DEFINED_PORT, classes = PolarisConfigRefreshOptimizationListenerNotTriggeredTest.TestApplication.class, + properties = { + "server.port=8081", + "spring.cloud.polaris.address=grpc://127.0.0.1:10081", + "spring.cloud.polaris.config.connect-remote-server=false", + "spring.cloud.polaris.config.refresh-type=reflect", + "spring.config.location = classpath:application-test.yml" + }) +public class PolarisConfigRefreshOptimizationListenerNotTriggeredTest { + + private static final String REFLECT_REFRESHER_BEAN_NAME = "polarisReflectPropertySourceAutoRefresher"; + + private static final String TEST_NAMESPACE = "testNamespace"; + + private static final String TEST_SERVICE_NAME = "testServiceName"; + + private static final String TEST_FILE_NAME = "application.properties"; + + @Autowired + private ConfigurableApplicationContext context; + + @Test + public void testNotSwitchConfigRefreshType() { + RefreshType actualRefreshType = context.getEnvironment() + .getProperty(POLARIS_CONFIG_REFRESH_TYPE, RefreshType.class); + assertThat(actualRefreshType).isEqualTo(RefreshType.REFLECT); + PolarisConfigProperties polarisConfigProperties = context.getBean(PolarisConfigProperties.class); + assertThat(polarisConfigProperties.getRefreshType()).isEqualTo(RefreshType.REFLECT); + assertThat(context.containsBean(REFLECT_REFRESHER_BEAN_NAME)).isTrue(); + PolarisRefreshAffectedContextRefresher refresher = context + .getBean(REFLECT_REFRESHER_BEAN_NAME, PolarisRefreshAffectedContextRefresher.class); + assertThat(((AbstractApplicationContext) context).getApplicationListeners().contains(refresher)).isTrue(); + } + + @Test + public void testConfigFileChanged() { + Map content = new HashMap<>(); + content.put("k1", "v1"); + content.put("k2", "v2"); + content.put("k3", "v3"); + MockedConfigKVFile file = new MockedConfigKVFile(content); + + PolarisPropertySource polarisPropertySource = new PolarisPropertySource(TEST_NAMESPACE, TEST_SERVICE_NAME, TEST_FILE_NAME, + file, content); + PolarisPropertySourceManager manager = context.getBean(PolarisPropertySourceManager.class); + when(manager.getAllPropertySources()).thenReturn(Lists.newArrayList(polarisPropertySource)); + + PolarisRefreshAffectedContextRefresher refresher = context.getBean(PolarisRefreshAffectedContextRefresher.class); + PolarisRefreshAffectedContextRefresher spyRefresher = Mockito.spy(refresher); + + spyRefresher.onApplicationEvent(null); + + ConfigPropertyChangeInfo changeInfo = new ConfigPropertyChangeInfo("k1", "v1", "v11", ChangeType.MODIFIED); + ConfigPropertyChangeInfo changeInfo2 = new ConfigPropertyChangeInfo("k4", null, "v4", ChangeType.ADDED); + ConfigPropertyChangeInfo changeInfo3 = new ConfigPropertyChangeInfo("k2", "v2", null, ChangeType.DELETED); + Map changeInfos = new HashMap<>(); + changeInfos.put("k1", changeInfo); + changeInfos.put("k2", changeInfo3); + changeInfos.put("k4", changeInfo2); + ConfigKVFileChangeEvent event = new ConfigKVFileChangeEvent(changeInfos); + file.fireChangeListener(event); + + ContextRefresher mockContextRefresher = context.getBean(ContextRefresher.class); + when(mockContextRefresher.refresh()).thenReturn(event.changedKeys()); + + Mockito.verify(spyRefresher, Mockito.times(1)) + .refreshSpringValue("k1"); + Mockito.verify(spyRefresher, Mockito.times(1)) + .refreshSpringValue("k2"); + Mockito.verify(spyRefresher, Mockito.times(1)) + .refreshSpringValue("k4"); + Mockito.verify(spyRefresher, Mockito.times(1)) + .refreshConfigurationProperties(event.changedKeys()); + } + + @SpringBootApplication + protected static class TestApplication { + + @Primary + @Bean + public PolarisPropertySourceManager polarisPropertySourceManager() { + return mock(PolarisPropertySourceManager.class); + } + + @Primary + @Bean + public ContextRefresher contextRefresher() { + return mock(ContextRefresher.class); + } + + @Component + protected static class TestBeanWithoutRefreshScope { + + } + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListenerTriggeredTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListenerTriggeredTest.java new file mode 100644 index 000000000..e62937326 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListenerTriggeredTest.java @@ -0,0 +1,156 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.config.listener; + +import java.util.HashMap; +import java.util.Map; + +import com.google.common.collect.Lists; +import com.tencent.cloud.polaris.config.adapter.MockedConfigKVFile; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySource; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; +import com.tencent.cloud.polaris.config.adapter.PolarisRefreshEntireContextRefresher; +import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; +import com.tencent.cloud.polaris.config.enums.RefreshType; +import com.tencent.polaris.configuration.api.core.ChangeType; +import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeEvent; +import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.cloud.context.refresh.ContextRefresher; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.stereotype.Component; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static com.tencent.cloud.polaris.config.condition.ReflectRefreshTypeCondition.POLARIS_CONFIG_REFRESH_TYPE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; + +/** + * test for {@link PolarisConfigRefreshOptimizationListener}. + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = DEFINED_PORT, classes = PolarisConfigRefreshOptimizationListenerTriggeredTest.TestApplication.class, + properties = { + "server.port=8081", + "spring.cloud.polaris.address=grpc://127.0.0.1:10081", + "spring.cloud.polaris.config.connect-remote-server=false", + "spring.cloud.polaris.config.refresh-type=reflect", + "spring.config.location = classpath:application-test.yml" + }) +public class PolarisConfigRefreshOptimizationListenerTriggeredTest { + + private static final String REFRESH_CONTEXT_REFRESHER_BEAN_NAME = "polarisRefreshContextPropertySourceAutoRefresher"; + + private static final String TEST_NAMESPACE = "testNamespace"; + + private static final String TEST_SERVICE_NAME = "testServiceName"; + + private static final String TEST_FILE_NAME = "application.properties"; + + @Autowired + private ConfigurableApplicationContext context; + + @Test + public void testSwitchConfigRefreshType() { + RefreshType actualRefreshType = context.getEnvironment() + .getProperty(POLARIS_CONFIG_REFRESH_TYPE, RefreshType.class); + assertThat(actualRefreshType).isEqualTo(RefreshType.REFRESH_CONTEXT); + PolarisConfigProperties polarisConfigProperties = context.getBean(PolarisConfigProperties.class); + assertThat(polarisConfigProperties.getRefreshType()).isEqualTo(RefreshType.REFRESH_CONTEXT); + assertThat(context.containsBean(REFRESH_CONTEXT_REFRESHER_BEAN_NAME)).isTrue(); + PolarisRefreshEntireContextRefresher refresher = context + .getBean(REFRESH_CONTEXT_REFRESHER_BEAN_NAME, PolarisRefreshEntireContextRefresher.class); + assertThat(((AbstractApplicationContext) context).getApplicationListeners().contains(refresher)).isTrue(); + } + + @Test + public void testConfigFileChanged() { + Map content = new HashMap<>(); + content.put("k1", "v1"); + content.put("k2", "v2"); + content.put("k3", "v3"); + MockedConfigKVFile file = new MockedConfigKVFile(content); + + PolarisPropertySource polarisPropertySource = new PolarisPropertySource(TEST_NAMESPACE, TEST_SERVICE_NAME, TEST_FILE_NAME, + file, content); + PolarisPropertySourceManager manager = context.getBean(PolarisPropertySourceManager.class); + when(manager.getAllPropertySources()).thenReturn(Lists.newArrayList(polarisPropertySource)); + + PolarisRefreshEntireContextRefresher refresher = context.getBean(PolarisRefreshEntireContextRefresher.class); + PolarisRefreshEntireContextRefresher spyRefresher = Mockito.spy(refresher); + + spyRefresher.onApplicationEvent(null); + + ConfigPropertyChangeInfo changeInfo = new ConfigPropertyChangeInfo("k1", "v1", "v11", ChangeType.MODIFIED); + ConfigPropertyChangeInfo changeInfo2 = new ConfigPropertyChangeInfo("k4", null, "v4", ChangeType.ADDED); + ConfigPropertyChangeInfo changeInfo3 = new ConfigPropertyChangeInfo("k2", "v2", null, ChangeType.DELETED); + Map changeInfos = new HashMap<>(); + changeInfos.put("k1", changeInfo); + changeInfos.put("k2", changeInfo3); + changeInfos.put("k4", changeInfo2); + ConfigKVFileChangeEvent event = new ConfigKVFileChangeEvent(changeInfos); + file.fireChangeListener(event); + + ContextRefresher mockContextRefresher = context.getBean(ContextRefresher.class); + when(mockContextRefresher.refresh()).thenReturn(event.changedKeys()); + + Mockito.verify(spyRefresher, Mockito.times(1)) + .refreshSpringValue("k1"); + Mockito.verify(spyRefresher, Mockito.times(1)) + .refreshSpringValue("k2"); + Mockito.verify(spyRefresher, Mockito.times(1)) + .refreshSpringValue("k4"); + Mockito.verify(spyRefresher, Mockito.times(1)) + .refreshConfigurationProperties(event.changedKeys()); + } + + @SpringBootApplication + protected static class TestApplication { + + @Primary + @Bean + public PolarisPropertySourceManager polarisPropertySourceManager() { + return mock(PolarisPropertySourceManager.class); + } + + @Primary + @Bean + public ContextRefresher contextRefresher() { + return mock(ContextRefresher.class); + } + + @Component + @RefreshScope + protected static class TestBeanWithRefreshScope { + + } + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java index 258ba7799..8d4a751b6 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java @@ -18,14 +18,12 @@ package com.tencent.cloud.polaris; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import com.tencent.cloud.polaris.extend.consul.ConsulConfigModifier; import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; import com.tencent.cloud.polaris.extend.nacos.NacosConfigModifier; import com.tencent.cloud.polaris.extend.nacos.NacosContextProperties; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.core.ProviderAPI; -import com.tencent.polaris.client.api.SDKContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -46,9 +44,8 @@ public class DiscoveryPropertiesAutoConfiguration { @Bean @ConditionalOnMissingBean public PolarisDiscoveryHandler polarisDiscoveryHandler(PolarisDiscoveryProperties polarisDiscoveryProperties, - ProviderAPI providerAPI, SDKContext sdkContext, - ConsumerAPI polarisConsumer) { - return new PolarisDiscoveryHandler(polarisDiscoveryProperties, providerAPI, sdkContext, polarisConsumer); + PolarisSDKContextManager polarisSDKContextManager) { + return new PolarisDiscoveryHandler(polarisDiscoveryProperties, polarisSDKContextManager); } @Bean @@ -65,13 +62,13 @@ public class DiscoveryPropertiesAutoConfiguration { @Bean @ConditionalOnMissingBean - public NacosConfigModifier nacosConfigModifier(@Autowired(required = false) NacosContextProperties nacosContextProperties) { - return new NacosConfigModifier(nacosContextProperties); + public PolarisDiscoveryConfigModifier polarisDiscoveryConfigModifier(PolarisDiscoveryProperties polarisDiscoveryProperties) { + return new PolarisDiscoveryConfigModifier(polarisDiscoveryProperties); } @Bean @ConditionalOnMissingBean - public PolarisDiscoveryConfigModifier polarisDiscoveryConfigModifier(PolarisDiscoveryProperties polarisDiscoveryProperties) { - return new PolarisDiscoveryConfigModifier(polarisDiscoveryProperties); + public NacosConfigModifier nacosConfigModifier(@Autowired(required = false) NacosContextProperties nacosContextProperties) { + return new NacosConfigModifier(nacosContextProperties); } } 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 ea480d406..3f83bfd44 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 @@ -45,6 +45,11 @@ public class PolarisDiscoveryProperties { @Value("${spring.cloud.polaris.discovery.service:${spring.cloud.polaris.service:${spring.application.name:}}}") private String service; + /** + * Service instance id. + */ + private String instanceId; + /** * The polaris authentication token. */ @@ -96,6 +101,14 @@ public class PolarisDiscoveryProperties { */ private Long serviceListRefreshInterval = 60000L; + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + public String getNamespace() { return namespace; } @@ -204,6 +217,7 @@ public class PolarisDiscoveryProperties { return "PolarisDiscoveryProperties{" + "namespace='" + namespace + '\'' + ", service='" + service + '\'' + + ", instanceId='" + instanceId + '\'' + ", token='" + token + '\'' + ", weight=" + weight + ", version='" + version + '\'' + diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java index 688562d76..cce659d14 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java @@ -19,14 +19,13 @@ package com.tencent.cloud.polaris.discovery; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.core.ProviderAPI; import com.tencent.polaris.api.rpc.GetAllInstancesRequest; import com.tencent.polaris.api.rpc.GetHealthyInstancesRequest; import com.tencent.polaris.api.rpc.GetServicesRequest; import com.tencent.polaris.api.rpc.InstancesResponse; import com.tencent.polaris.api.rpc.ServicesResponse; -import com.tencent.polaris.client.api.SDKContext; /** * Discovery Handler for Polaris. @@ -37,18 +36,12 @@ public class PolarisDiscoveryHandler { private final PolarisDiscoveryProperties polarisDiscoveryProperties; - private final ProviderAPI providerAPI; - - private final SDKContext sdkContext; - private final ConsumerAPI polarisConsumer; public PolarisDiscoveryHandler(PolarisDiscoveryProperties polarisDiscoveryProperties, - ProviderAPI providerAPI, SDKContext sdkContext, ConsumerAPI polarisConsumer) { + PolarisSDKContextManager polarisSDKContextManager) { this.polarisDiscoveryProperties = polarisDiscoveryProperties; - this.providerAPI = providerAPI; - this.sdkContext = sdkContext; - this.polarisConsumer = polarisConsumer; + this.polarisConsumer = polarisSDKContextManager.getConsumerAPI(); } /** @@ -75,15 +68,7 @@ public class PolarisDiscoveryHandler { GetAllInstancesRequest request = new GetAllInstancesRequest(); request.setNamespace(namespace); request.setService(service); - return polarisConsumer.getAllInstance(request); - } - - public ProviderAPI getProviderAPI() { - return providerAPI; - } - - public SDKContext getSdkContext() { - return sdkContext; + return polarisConsumer.getAllInstances(request); } /** diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java index 09f50f2a7..70140f1bc 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java @@ -48,7 +48,7 @@ public class PolarisReactiveDiscoveryClient implements ReactiveDiscoveryClient { @Override public String description() { - return "Spring Cloud Tencent Polaris Reactive Discovery Client."; + return "Spring Cloud Tencent Polaris Reactive Discovery Client"; } @Override diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java index 2f3d8e201..47302b50c 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java @@ -22,23 +22,28 @@ import com.tencent.cloud.polaris.discovery.PolarisServiceDiscovery; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.ConditionalOnDiscoveryHealthIndicatorEnabled; import org.springframework.cloud.client.ConditionalOnReactiveDiscoveryEnabled; import org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration; import org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration; +import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicatorProperties; +import org.springframework.cloud.client.discovery.health.reactive.ReactiveDiscoveryClientHealthIndicator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Reactive Discovery Client Configuration for Polaris. * - * @author Haotian Zhang, Andrew Shan, Jie Cheng + * @author Haotian Zhang, Andrew Shan, Jie Cheng, youta */ @Configuration(proxyBeanMethods = false) @ConditionalOnReactiveDiscoveryEnabled -@AutoConfigureAfter({ PolarisDiscoveryAutoConfiguration.class, - ReactiveCompositeDiscoveryClientAutoConfiguration.class }) -@AutoConfigureBefore({ ReactiveCommonsClientAutoConfiguration.class }) +@EnableConfigurationProperties(DiscoveryClientHealthIndicatorProperties.class) +@AutoConfigureAfter({PolarisDiscoveryAutoConfiguration.class, ReactiveCompositeDiscoveryClientAutoConfiguration.class}) +@AutoConfigureBefore({ReactiveCommonsClientAutoConfiguration.class}) public class PolarisReactiveDiscoveryClientConfiguration { @Bean @@ -47,4 +52,12 @@ public class PolarisReactiveDiscoveryClientConfiguration { PolarisServiceDiscovery polarisServiceDiscovery) { return new PolarisReactiveDiscoveryClient(polarisServiceDiscovery); } + + @Bean + @ConditionalOnClass(name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator") + @ConditionalOnDiscoveryHealthIndicatorEnabled + public ReactiveDiscoveryClientHealthIndicator polarisReactiveDiscoveryClientHealthIndicator( + PolarisReactiveDiscoveryClient client, DiscoveryClientHealthIndicatorProperties properties) { + return new ReactiveDiscoveryClientHealthIndicator(client, properties); + } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java index cab572985..6bbe9b2db 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshApplicationReadyEventListener.java @@ -21,7 +21,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.polaris.client.util.NamedThreadFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,14 +45,14 @@ public class PolarisRefreshApplicationReadyEventListener private static final Logger LOG = LoggerFactory.getLogger(PolarisRefreshApplicationReadyEventListener.class); private static final int DELAY = 60; - private final PolarisDiscoveryHandler polarisDiscoveryHandler; + private final PolarisSDKContextManager polarisSDKContextManager; private final PolarisServiceStatusChangeListener polarisServiceStatusChangeListener; private final ScheduledExecutorService refreshExecutor; private ApplicationEventPublisher publisher; - public PolarisRefreshApplicationReadyEventListener(PolarisDiscoveryHandler polarisDiscoveryHandler, + public PolarisRefreshApplicationReadyEventListener(PolarisSDKContextManager polarisSDKContextManager, PolarisServiceStatusChangeListener polarisServiceStatusChangeListener) { - this.polarisDiscoveryHandler = polarisDiscoveryHandler; + this.polarisSDKContextManager = polarisSDKContextManager; this.polarisServiceStatusChangeListener = polarisServiceStatusChangeListener; this.refreshExecutor = Executors.newSingleThreadScheduledExecutor( new NamedThreadFactory("polaris-service-refresh")); @@ -61,7 +61,7 @@ public class PolarisRefreshApplicationReadyEventListener @Override public void onApplicationEvent(ApplicationReadyEvent event) { // Register service change listener. - polarisDiscoveryHandler.getSdkContext().getExtensions().getLocalRegistry() + polarisSDKContextManager.getSDKContext().getExtensions().getLocalRegistry() .registerResourceListener(polarisServiceStatusChangeListener); // Begin scheduled refresh thread. diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshConfiguration.java index c0523fa51..d8abf683c 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/PolarisRefreshConfiguration.java @@ -18,7 +18,7 @@ package com.tencent.cloud.polaris.discovery.refresh; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; -import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; @@ -42,8 +42,8 @@ public class PolarisRefreshConfiguration { @Bean @ConditionalOnMissingBean public PolarisRefreshApplicationReadyEventListener polarisServiceStatusApplicationReadyEventListener( - PolarisDiscoveryHandler polarisDiscoveryHandler, + PolarisSDKContextManager polarisSDKContextManager, PolarisServiceStatusChangeListener polarisServiceStatusChangeListener) { - return new PolarisRefreshApplicationReadyEventListener(polarisDiscoveryHandler, polarisServiceStatusChangeListener); + return new PolarisRefreshApplicationReadyEventListener(polarisSDKContextManager, polarisServiceStatusChangeListener); } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java index 772956882..ade24e792 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java @@ -17,6 +17,10 @@ package com.tencent.cloud.polaris.registry; +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.polaris.api.pojo.ServiceKey; +import com.tencent.polaris.assembly.api.AssemblyAPI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,15 +36,25 @@ import org.springframework.util.StringUtils; */ public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistration { - private static final Logger LOG = LoggerFactory.getLogger(PolarisAutoServiceRegistration.class); + private static final Logger log = LoggerFactory.getLogger(PolarisAutoServiceRegistration.class); private final PolarisRegistration registration; - public PolarisAutoServiceRegistration(ServiceRegistry serviceRegistry, + private final PolarisDiscoveryProperties polarisDiscoveryProperties; + + private final AssemblyAPI assemblyAPI; + + public PolarisAutoServiceRegistration( + ServiceRegistry serviceRegistry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, - PolarisRegistration registration) { + PolarisRegistration registration, + PolarisDiscoveryProperties polarisDiscoveryProperties, + AssemblyAPI assemblyAPI + ) { super(serviceRegistry, autoServiceRegistrationProperties); this.registration = registration; + this.polarisDiscoveryProperties = polarisDiscoveryProperties; + this.assemblyAPI = assemblyAPI; } @Override @@ -56,9 +70,12 @@ public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistrat @Override protected void register() { if (!this.registration.isRegisterEnabled()) { - LOG.debug("Registration disabled."); + log.debug("Registration disabled."); return; } + if (assemblyAPI != null) { + assemblyAPI.initService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE)); + } super.register(); } @@ -73,7 +90,7 @@ public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistrat @Override protected Object getConfiguration() { - return this.registration.getPolarisProperties(); + return this.polarisDiscoveryProperties; } @Override @@ -84,7 +101,7 @@ public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistrat @Override @SuppressWarnings("deprecation") protected String getAppName() { - String appName = registration.getPolarisProperties().getService(); + String appName = registration.getServiceId(); return StringUtils.isEmpty(appName) ? super.getAppName() : appName; } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java index a37b159ee..b0c33cce3 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java @@ -13,13 +13,13 @@ * 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.registry; import java.net.URI; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -55,24 +55,18 @@ public class PolarisRegistration implements Registration { private final PolarisDiscoveryProperties polarisDiscoveryProperties; - private final ConsulContextProperties consulContextProperties; - private final SDKContext polarisContext; private final StaticMetadataManager staticMetadataManager; - private final NacosContextProperties nacosContextProperties; - + private final String serviceId; + private final String host; + private final boolean isSecure; private final ServletWebServerApplicationContext servletWebServerApplicationContext; - private final ReactiveWebServerApplicationContext reactiveWebServerApplicationContext; - + private boolean registerEnabled = false; private Map metadata; - - private String host; - private int port; - private String instanceId; public PolarisRegistration( @@ -84,32 +78,95 @@ public class PolarisRegistration implements Registration { @Nullable ServletWebServerApplicationContext servletWebServerApplicationContext, @Nullable ReactiveWebServerApplicationContext reactiveWebServerApplicationContext) { this.polarisDiscoveryProperties = polarisDiscoveryProperties; - this.consulContextProperties = consulContextProperties; this.polarisContext = context; this.staticMetadataManager = staticMetadataManager; - this.nacosContextProperties = nacosContextProperties; this.servletWebServerApplicationContext = servletWebServerApplicationContext; this.reactiveWebServerApplicationContext = reactiveWebServerApplicationContext; - host = polarisContext.getConfig().getGlobal().getAPI().getBindIP(); - if (polarisContextProperties != null) { - port = polarisContextProperties.getLocalPort(); - } - } - @Override - public String getServiceId() { + // generate serviceId if (Objects.isNull(nacosContextProperties)) { - return polarisDiscoveryProperties.getService(); + serviceId = polarisDiscoveryProperties.getService(); } else { String group = nacosContextProperties.getGroup(); if (StringUtils.isNotBlank(group) && !DEFAULT_GROUP.equals(group)) { - return String.format(GROUP_SERVER_ID_FORMAT, group, polarisDiscoveryProperties.getService()); + serviceId = String.format(GROUP_SERVER_ID_FORMAT, group, polarisDiscoveryProperties.getService()); } else { - return polarisDiscoveryProperties.getService(); + serviceId = polarisDiscoveryProperties.getService(); } } + + // generate host + host = polarisContext.getConfig().getGlobal().getAPI().getBindIP(); + + // generate port + if (polarisContextProperties != null) { + port = polarisContextProperties.getLocalPort(); + } + + // generate isSecure + isSecure = StringUtils.equalsIgnoreCase(polarisDiscoveryProperties.getProtocol(), "https"); + + // generate metadata + if (CollectionUtils.isEmpty(metadata)) { + Map instanceMetadata = new HashMap<>(); + + // put internal metadata + instanceMetadata.put(METADATA_KEY_IP, host); + instanceMetadata.put(METADATA_KEY_ADDRESS, host + ":" + port); + + // put internal-nacos-cluster if necessary + if (Objects.nonNull(nacosContextProperties)) { + String clusterName = nacosContextProperties.getClusterName(); + if (StringUtils.isNotBlank(clusterName) && !DEFAULT_CLUSTER.equals(clusterName)) { + instanceMetadata.put(NACOS_CLUSTER, clusterName); + } + } + + instanceMetadata.putAll(staticMetadataManager.getMergedStaticMetadata()); + + this.metadata = instanceMetadata; + } + + // generate registerEnabled + if (null != polarisDiscoveryProperties) { + registerEnabled = polarisDiscoveryProperties.isRegisterEnabled(); + } + if (null != consulContextProperties && consulContextProperties.isEnabled()) { + registerEnabled |= consulContextProperties.isRegister(); + } + if (null != nacosContextProperties && nacosContextProperties.isEnabled()) { + registerEnabled |= nacosContextProperties.isRegisterEnabled(); + } + } + + public static PolarisRegistration registration(PolarisDiscoveryProperties polarisDiscoveryProperties, + @Nullable PolarisContextProperties polarisContextProperties, + @Nullable ConsulContextProperties consulContextProperties, + SDKContext context, StaticMetadataManager staticMetadataManager, + @Nullable NacosContextProperties nacosContextProperties, + @Nullable ServletWebServerApplicationContext servletWebServerApplicationContext, + @Nullable ReactiveWebServerApplicationContext reactiveWebServerApplicationContext, + @Nullable List registrationCustomizers) { + PolarisRegistration polarisRegistration = new PolarisRegistration(polarisDiscoveryProperties, + polarisContextProperties, consulContextProperties, context, staticMetadataManager, + nacosContextProperties, servletWebServerApplicationContext, reactiveWebServerApplicationContext); + customize(registrationCustomizers, polarisRegistration); + return polarisRegistration; + } + + public static void customize(List registrationCustomizers, PolarisRegistration registration) { + if (registrationCustomizers != null) { + for (PolarisRegistrationCustomizer customizer : registrationCustomizers) { + customizer.customize(registration); + } + } + } + + @Override + public String getServiceId() { + return serviceId; } @Override @@ -139,7 +196,7 @@ public class PolarisRegistration implements Registration { @Override public boolean isSecure() { - return StringUtils.equalsIgnoreCase(polarisDiscoveryProperties.getProtocol(), "https"); + return isSecure; } @Override @@ -149,30 +206,9 @@ public class PolarisRegistration implements Registration { @Override public Map getMetadata() { - if (CollectionUtils.isEmpty(metadata)) { - Map instanceMetadata = new HashMap<>(); - - // put internal metadata - instanceMetadata.put(METADATA_KEY_IP, host); - instanceMetadata.put(METADATA_KEY_ADDRESS, host + ":" + port); - - // put internal-nacos-cluster if necessary - String clusterName = nacosContextProperties.getClusterName(); - if (StringUtils.isNotBlank(clusterName) && !DEFAULT_CLUSTER.equals(clusterName)) { - instanceMetadata.put(NACOS_CLUSTER, clusterName); - } - - instanceMetadata.putAll(staticMetadataManager.getMergedStaticMetadata()); - - this.metadata = instanceMetadata; - } return metadata; } - public PolarisDiscoveryProperties getPolarisProperties() { - return polarisDiscoveryProperties; - } - @Override public String getInstanceId() { return instanceId; @@ -183,18 +219,6 @@ public class PolarisRegistration implements Registration { } public boolean isRegisterEnabled() { - - boolean registerEnabled = false; - - if (null != polarisDiscoveryProperties) { - registerEnabled = polarisDiscoveryProperties.isRegisterEnabled(); - } - if (null != consulContextProperties && consulContextProperties.isEnabled()) { - registerEnabled |= consulContextProperties.isRegister(); - } - if (null != nacosContextProperties && nacosContextProperties.isEnabled()) { - registerEnabled |= nacosContextProperties.isRegisterEnabled(); - } return registerEnabled; } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistrationCustomizer.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistrationCustomizer.java new file mode 100644 index 000000000..76df55f47 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistrationCustomizer.java @@ -0,0 +1,27 @@ +/* + * 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.registry; + +/** + * Customizer for {@link PolarisRegistration}. + * + * @author Haotian Zhang + */ +public interface PolarisRegistrationCustomizer { + void customize(PolarisRegistration registration); +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java index e320ed531..87509c641 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java @@ -26,6 +26,7 @@ import java.util.concurrent.ScheduledExecutorService; import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import com.tencent.cloud.polaris.util.OkHttpUtil; import com.tencent.cloud.rpc.enhancement.stat.config.PolarisStatProperties; @@ -33,6 +34,7 @@ import com.tencent.polaris.api.config.global.StatReporterConfig; import com.tencent.polaris.api.core.ProviderAPI; import com.tencent.polaris.api.exception.PolarisException; import com.tencent.polaris.api.plugin.common.PluginTypes; +import com.tencent.polaris.api.plugin.stat.ReporterMetaInfo; import com.tencent.polaris.api.plugin.stat.StatReporter; import com.tencent.polaris.api.pojo.Instance; import com.tencent.polaris.api.rpc.InstanceDeregisterRequest; @@ -47,6 +49,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.DisposableBean; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.http.HttpHeaders; @@ -58,24 +61,25 @@ import static org.springframework.util.ReflectionUtils.rethrowRuntimeException; * * @author Haotian Zhang, Andrew Shan, Jie Cheng, changjin wei(魏昌进) */ -public class PolarisServiceRegistry implements ServiceRegistry { +public class PolarisServiceRegistry implements ServiceRegistry, DisposableBean { private static final Logger LOGGER = LoggerFactory.getLogger(PolarisServiceRegistry.class); private final PolarisDiscoveryProperties polarisDiscoveryProperties; + private final PolarisSDKContextManager polarisSDKContextManager; + private final PolarisDiscoveryHandler polarisDiscoveryHandler; private final StaticMetadataManager staticMetadataManager; - - private final ScheduledExecutorService heartbeatExecutor; - private final PolarisStatProperties polarisStatProperties; + private final ScheduledExecutorService heartbeatExecutor; public PolarisServiceRegistry(PolarisDiscoveryProperties polarisDiscoveryProperties, - PolarisDiscoveryHandler polarisDiscoveryHandler, + PolarisSDKContextManager polarisSDKContextManager, PolarisDiscoveryHandler polarisDiscoveryHandler, StaticMetadataManager staticMetadataManager, PolarisStatProperties polarisStatProperties) { this.polarisDiscoveryProperties = polarisDiscoveryProperties; + this.polarisSDKContextManager = polarisSDKContextManager; this.polarisDiscoveryHandler = polarisDiscoveryHandler; this.staticMetadataManager = staticMetadataManager; @@ -113,8 +117,9 @@ public class PolarisServiceRegistry implements ServiceRegistry registrationCustomizers) { + return PolarisRegistration.registration(polarisDiscoveryProperties, polarisContextProperties, consulContextProperties, + polarisSDKContextManager.getSDKContext(), staticMetadataManager, nacosContextProperties, + servletWebServerApplicationContext, reactiveWebServerApplicationContext, registrationCustomizers); } @Bean @@ -82,8 +85,12 @@ public class PolarisServiceRegistryAutoConfiguration { public PolarisAutoServiceRegistration polarisAutoServiceRegistration( PolarisServiceRegistry registry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, - PolarisRegistration registration) { - return new PolarisAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration); + PolarisRegistration registration, + PolarisDiscoveryProperties polarisDiscoveryProperties, + PolarisSDKContextManager polarisSDKContextManager + ) { + return new PolarisAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration, + polarisDiscoveryProperties, polarisSDKContextManager.getAssemblyAPI()); } @Bean diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java index 5fde947d1..d77e36c6f 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfigurationTest.java @@ -20,8 +20,6 @@ package com.tencent.cloud.polaris; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.core.ProviderAPI; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -48,8 +46,6 @@ public class DiscoveryPropertiesAutoConfigurationTest { assertThat(context).hasSingleBean(DiscoveryPropertiesAutoConfiguration.class); assertThat(context).hasSingleBean(PolarisDiscoveryProperties.class); assertThat(context).hasSingleBean(ConsulContextProperties.class); - assertThat(context).hasSingleBean(ProviderAPI.class); - assertThat(context).hasSingleBean(ConsumerAPI.class); assertThat(context).hasSingleBean(PolarisDiscoveryHandler.class); assertThat(context).hasSingleBean(DiscoveryConfigModifier.class); }); diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisDiscoveryPropertiesTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisDiscoveryPropertiesTest.java index 5e7b958a4..1a5e875dc 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisDiscoveryPropertiesTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisDiscoveryPropertiesTest.java @@ -85,10 +85,15 @@ public class PolarisDiscoveryPropertiesTest { polarisDiscoveryProperties.setServiceListRefreshInterval(1000L); assertThat(polarisDiscoveryProperties.getServiceListRefreshInterval()).isEqualTo(1000L); + // InstanceId + polarisDiscoveryProperties.setInstanceId("test-ins-id"); + assertThat(polarisDiscoveryProperties.getInstanceId()).isEqualTo("test-ins-id"); + assertThat(polarisDiscoveryProperties.toString()) .isEqualTo("PolarisDiscoveryProperties{" + "namespace='Test'" + ", service='java_provider_test'" + + ", instanceId='test-ins-id'" + ", token='19485a7674294e3c88dba293373c1534'" + ", weight=10, version='1.0.0'" + ", protocol='HTTP'" diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java index 53cc72930..895fd05a8 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java @@ -19,12 +19,12 @@ package com.tencent.cloud.polaris.discovery; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.core.ProviderAPI; import com.tencent.polaris.test.mock.discovery.NamingServer; 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.springframework.boot.autoconfigure.AutoConfigurations; @@ -49,8 +49,7 @@ public class PolarisDiscoveryAutoConfigurationTest { .withConfiguration(AutoConfigurations.of( PolarisContextAutoConfiguration.class, PolarisDiscoveryAutoConfiguration.class, - PolarisDiscoveryClientConfiguration.class, - PolarisContextAutoConfiguration.class)) + PolarisDiscoveryClientConfiguration.class)) .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); @@ -67,11 +66,14 @@ public class PolarisDiscoveryAutoConfigurationTest { } } + @BeforeEach + void setUp() { + PolarisSDKContextManager.innerDestroy(); + } + @Test public void testDefaultInitialization() { this.contextRunner.run(context -> { - assertThat(context).hasSingleBean(ProviderAPI.class); - assertThat(context).hasSingleBean(ConsumerAPI.class); assertThat(context).hasSingleBean(PolarisDiscoveryProperties.class); assertThat(context).hasSingleBean(PolarisServiceDiscovery.class); }); diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java index b53fce9f2..b33dc8c52 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java @@ -17,10 +17,12 @@ package com.tencent.cloud.polaris.discovery; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.polaris.test.mock.discovery.NamingServer; 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.springframework.boot.autoconfigure.AutoConfigurations; @@ -62,6 +64,11 @@ public class PolarisDiscoveryClientConfigurationTest { } } + @BeforeEach + void setUp() { + PolarisSDKContextManager.innerDestroy(); + } + @Test public void testDefaultInitialization() { this.contextRunner.run(context -> assertThat(context).hasSingleBean(PolarisDiscoveryClient.class)); diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandlerTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandlerTest.java new file mode 100644 index 000000000..821e366e9 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandlerTest.java @@ -0,0 +1,65 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.discovery; + +import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.api.exception.PolarisException; +import com.tencent.polaris.api.rpc.ServicesResponse; +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 static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +/** + * Test for {@link PolarisDiscoveryHandler}. + * + * @author Haotian Zhang + */ +@ExtendWith(MockitoExtension.class) +public class PolarisDiscoveryHandlerTest { + + private PolarisDiscoveryHandler polarisDiscoveryHandler; + + @BeforeEach + void setUp() { + PolarisDiscoveryProperties polarisDiscoveryProperties = mock(PolarisDiscoveryProperties.class); + doReturn(NAMESPACE_TEST).when(polarisDiscoveryProperties).getNamespace(); + + ConsumerAPI consumerAPI = mock(ConsumerAPI.class); + ServicesResponse servicesResponse = mock(ServicesResponse.class); + doReturn(servicesResponse).when(consumerAPI).getServices(any()); + + PolarisSDKContextManager polarisSDKContextManager = mock(PolarisSDKContextManager.class); + doReturn(consumerAPI).when(polarisSDKContextManager).getConsumerAPI(); + polarisDiscoveryHandler = new PolarisDiscoveryHandler(polarisDiscoveryProperties, polarisSDKContextManager); + } + + @Test + public void testGetServices() throws PolarisException { + ServicesResponse servicesResponse = polarisDiscoveryHandler.getServices(); + assertThat(servicesResponse).isNotNull(); + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java index 138e2357e..3c0156cbc 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java @@ -17,11 +17,13 @@ package com.tencent.cloud.polaris.discovery.reactive; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; import com.tencent.polaris.test.mock.discovery.NamingServer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -36,7 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * Test for {@link PolarisReactiveDiscoveryClientConfiguration}. * - * @author Haotian Zhang + * @author Haotian Zhang, youta */ public class PolarisReactiveDiscoveryClientConfigurationTest { @@ -65,12 +67,23 @@ public class PolarisReactiveDiscoveryClientConfigurationTest { } } + @BeforeEach + void setUp() { + PolarisSDKContextManager.innerDestroy(); + } + @Test public void testDefaultInitialization() { this.contextRunner.run(context -> assertThat(context) .hasSingleBean(PolarisReactiveDiscoveryClient.class)); } + @Test + public void shouldWorkWithDefaults() { + contextRunner.run(context -> assertThat(context).hasBean("polarisReactiveDiscoveryClientHealthIndicator")); + } + + @Configuration @EnableAutoConfiguration static class PolarisReactiveDiscoveryClientConfiguration { diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientTest.java index e475c66bc..95724e79c 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientTest.java @@ -99,6 +99,6 @@ public class PolarisReactiveDiscoveryClientTest { @Test public void testDescription() { - assertThat(client.description()).isEqualTo("Spring Cloud Tencent Polaris Reactive Discovery Client."); + assertThat(client.description()).isEqualTo("Spring Cloud Tencent Polaris Reactive Discovery Client"); } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointTest.java index 14152df62..dc9b41d9d 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointTest.java @@ -16,9 +16,11 @@ */ package com.tencent.cloud.polaris.endpoint; +import java.util.Collections; import java.util.Map; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClient; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; @@ -26,6 +28,7 @@ import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import com.tencent.polaris.test.mock.discovery.NamingServer; 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.springframework.boot.autoconfigure.AutoConfigurations; @@ -38,6 +41,8 @@ import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.Consts.PORT; import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; /** * Test for polaris discovery endpoint. @@ -48,7 +53,7 @@ public class PolarisDiscoveryEndpointTest { private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withConfiguration(AutoConfigurations.of( PolarisPropertiesConfiguration.class, PolarisDiscoveryClientConfiguration.class, @@ -72,6 +77,11 @@ public class PolarisDiscoveryEndpointTest { } } + @BeforeEach + void setUp() { + PolarisSDKContextManager.innerDestroy(); + } + @Test public void testPolarisDiscoveryEndpoint() { this.contextRunner.run(context -> { @@ -79,12 +89,17 @@ public class PolarisDiscoveryEndpointTest { .getBean(PolarisDiscoveryProperties.class); DiscoveryClient discoveryClient = context .getBean(PolarisDiscoveryClient.class); + PolarisDiscoveryHandler polarisDiscoveryHandler = context.getBean(PolarisDiscoveryHandler.class); PolarisDiscoveryEndpoint polarisDiscoveryEndpoint = new PolarisDiscoveryEndpoint(polarisDiscoveryProperties, discoveryClient, polarisDiscoveryHandler); - Map mapInfo = polarisDiscoveryEndpoint.polarisDiscovery("java_provider_test"); - assertThat(polarisDiscoveryProperties).isEqualTo(mapInfo.get("PolarisDiscoveryProperties")); + + DiscoveryClient discoveryClient1 = mock(DiscoveryClient.class); + doReturn(Collections.singletonList("xx")).when(discoveryClient1).getServices(); + PolarisDiscoveryEndpoint polarisDiscoveryEndpoint1 = new PolarisDiscoveryEndpoint(polarisDiscoveryProperties, discoveryClient1, polarisDiscoveryHandler); + Map mapInfo2 = polarisDiscoveryEndpoint1.polarisDiscovery(null); + assertThat(polarisDiscoveryProperties).isEqualTo(mapInfo2.get("PolarisDiscoveryProperties")); }); } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/extend/consul/ConsulContextPropertiesTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/extend/consul/ConsulContextPropertiesTest.java index ec5580159..1d545b4e5 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/extend/consul/ConsulContextPropertiesTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/extend/consul/ConsulContextPropertiesTest.java @@ -20,8 +20,9 @@ package com.tencent.cloud.polaris.extend.consul; import java.util.List; import java.util.Map; -import com.tencent.polaris.client.api.SDKContext; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -53,7 +54,12 @@ public class ConsulContextPropertiesTest { private ConsulContextProperties consulContextProperties; @Autowired - private SDKContext sdkContext; + private PolarisSDKContextManager polarisSDKContextManager; + + @BeforeEach + void setUp() { + PolarisSDKContextManager.innerDestroy(); + } @Test public void testDefaultInitialization() { @@ -67,8 +73,9 @@ public class ConsulContextPropertiesTest { @Test public void testModify() { - assertThat(sdkContext).isNotNull(); - com.tencent.polaris.api.config.Configuration configuration = sdkContext.getConfig(); + assertThat(polarisSDKContextManager).isNotNull(); + com.tencent.polaris.api.config.Configuration configuration = polarisSDKContextManager.getSDKContext() + .getConfig(); List serverConnectorConfigs = configuration.getGlobal().getServerConnectors(); Map metadata = null; for (ServerConnectorConfigImpl serverConnectorConfig : serverConnectorConfigs) { @@ -86,5 +93,8 @@ public class ConsulContextPropertiesTest { @SpringBootApplication protected static class TestApplication { + static { + PolarisSDKContextManager.innerDestroy(); + } } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/extend/nacos/NacosContextPropertiesTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/extend/nacos/NacosContextPropertiesTest.java index 7c1bc2db6..acdf55d58 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/extend/nacos/NacosContextPropertiesTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/extend/nacos/NacosContextPropertiesTest.java @@ -21,8 +21,8 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.polaris.api.config.plugin.DefaultPlugins; -import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -50,7 +50,7 @@ public class NacosContextPropertiesTest { private NacosContextProperties nacosContextProperties; @Autowired - private SDKContext sdkContext; + private PolarisSDKContextManager polarisSDKContextManager; @Test public void testDefaultInitialization() { @@ -65,8 +65,9 @@ public class NacosContextPropertiesTest { @Test public void testModify() { - assertThat(sdkContext).isNotNull(); - com.tencent.polaris.api.config.Configuration configuration = sdkContext.getConfig(); + assertThat(polarisSDKContextManager).isNotNull(); + com.tencent.polaris.api.config.Configuration configuration = polarisSDKContextManager.getSDKContext() + .getConfig(); List serverConnectorConfigs = configuration.getGlobal().getServerConnectors(); Optional optionalServerConnectorConfig = serverConnectorConfigs.stream().filter( item -> "nacos".equals(item.getId()) @@ -87,5 +88,9 @@ public class NacosContextPropertiesTest { @SpringBootApplication protected static class TestApplication { + + static { + PolarisSDKContextManager.innerDestroy(); + } } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java index 867a990ec..9d78c9033 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistrationTest.java @@ -70,12 +70,11 @@ public class PolarisAutoServiceRegistrationTest { @BeforeEach void setUp() { - doReturn(polarisDiscoveryProperties).when(registration).getPolarisProperties(); - doNothing().when(serviceRegistry).register(nullable(PolarisRegistration.class)); polarisAutoServiceRegistration = - new PolarisAutoServiceRegistration(serviceRegistry, autoServiceRegistrationProperties, registration); + new PolarisAutoServiceRegistration(serviceRegistry, autoServiceRegistrationProperties, registration, + polarisDiscoveryProperties, null); doReturn(environment).when(applicationContext).getEnvironment(); polarisAutoServiceRegistration.setApplicationContext(applicationContext); @@ -117,7 +116,7 @@ public class PolarisAutoServiceRegistrationTest { doReturn("application").when(environment).getProperty(anyString(), anyString()); assertThat(polarisAutoServiceRegistration.getAppName()).isEqualTo("application"); - doReturn(SERVICE_PROVIDER).when(polarisDiscoveryProperties).getService(); + doReturn(SERVICE_PROVIDER).when(registration).getServiceId(); assertThat(polarisAutoServiceRegistration.getAppName()).isEqualTo(SERVICE_PROVIDER); } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationCustomizerTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationCustomizerTest.java new file mode 100644 index 000000000..4961d2b3c --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationCustomizerTest.java @@ -0,0 +1,76 @@ +/* + * 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.registry; + +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static com.tencent.polaris.test.common.Consts.PORT; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * Test for {@link PolarisRegistrationCustomizer}. + * + * @author Haotian Zhang + */ +public class PolarisRegistrationCustomizerTest { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, + PolarisServiceRegistryAutoConfiguration.class, + PolarisDiscoveryClientConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); + + @BeforeEach + public void setUp() { + PolarisSDKContextManager.innerDestroy(); + } + + @Test + public void testCustomize() { + this.contextRunner.run(context -> { + PolarisRegistrationCustomizer customizer = context.getBean(PolarisRegistrationCustomizer.class); + verify(customizer, times(1)).customize(any(PolarisRegistration.class)); + }); + } + + @Configuration + @EnableAutoConfiguration + static class PolarisServiceRegistryAutoConfiguration { + @Bean + public PolarisRegistrationCustomizer polarisRegistrationCustomizer() { + return mock(PolarisRegistrationCustomizer.class); + } + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java index b0b7daa96..cd60b31b6 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java @@ -57,16 +57,13 @@ import static org.mockito.Mockito.when; @MockitoSettings(strictness = Strictness.LENIENT) public class PolarisRegistrationTest { + private static final int testLocalPort = 10086; private NacosContextProperties nacosContextProperties; private PolarisRegistration polarisRegistration1; private PolarisRegistration polarisRegistration2; - private PolarisRegistration polarisRegistration3; - private PolarisRegistration polarisRegistration4; - private static int testLocalPort = 10086; - @BeforeEach void setUp() { // mock PolarisDiscoveryProperties @@ -122,21 +119,21 @@ public class PolarisRegistrationTest { ReactiveWebServerApplicationContext reactiveWebServerApplicationContext = mock(ReactiveWebServerApplicationContext.class); doReturn(reactiveWebServer).when(reactiveWebServerApplicationContext).getWebServer(); - polarisRegistration1 = new PolarisRegistration(polarisDiscoveryProperties, null, consulContextProperties, + polarisRegistration1 = PolarisRegistration.registration(polarisDiscoveryProperties, null, consulContextProperties, polarisContext, staticMetadataManager, nacosContextProperties, - servletWebServerApplicationContext, null); + servletWebServerApplicationContext, null, null); - polarisRegistration2 = new PolarisRegistration(polarisDiscoveryProperties, null, consulContextProperties, + polarisRegistration2 = PolarisRegistration.registration(polarisDiscoveryProperties, null, consulContextProperties, polarisContext, staticMetadataManager, nacosContextProperties, - null, reactiveWebServerApplicationContext); + null, reactiveWebServerApplicationContext, null); - polarisRegistration3 = new PolarisRegistration(polarisDiscoveryProperties, null, consulContextProperties, + polarisRegistration3 = PolarisRegistration.registration(polarisDiscoveryProperties, null, consulContextProperties, polarisContext, staticMetadataManager, nacosContextProperties, - null, null); + null, null, null); - polarisRegistration4 = new PolarisRegistration(polarisDiscoveryProperties, polarisContextProperties, consulContextProperties, + polarisRegistration4 = PolarisRegistration.registration(polarisDiscoveryProperties, polarisContextProperties, consulContextProperties, polarisContext, staticMetadataManager, nacosContextProperties, - null, null); + null, null, null); } @Test @@ -187,11 +184,6 @@ public class PolarisRegistrationTest { assertThat(metadata.get("key1")).isEqualTo("value1"); } - @Test - public void testGetPolarisProperties() { - assertThat(polarisRegistration1.getPolarisProperties()).isNotNull(); - } - @Test public void testIsRegisterEnabled() { assertThat(polarisRegistration1.isRegisterEnabled()).isTrue(); diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java index 77a0ef49c..9aae14ceb 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java @@ -17,12 +17,14 @@ package com.tencent.cloud.polaris.registry; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; import com.tencent.polaris.test.mock.discovery.NamingServer; 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.springframework.boot.autoconfigure.AutoConfigurations; @@ -65,6 +67,11 @@ public class PolarisServiceRegistryAutoConfigurationTest { } } + @BeforeEach + void setUp() { + PolarisSDKContextManager.innerDestroy(); + } + @Test public void testDefaultInitialization() { this.contextRunner.run(context -> { diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java index 0fbdf050c..2d96a9904 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java @@ -17,6 +17,7 @@ package com.tencent.cloud.polaris.registry; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; @@ -24,6 +25,7 @@ import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.test.mock.discovery.NamingServer; 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.mockito.Mockito; @@ -89,6 +91,11 @@ public class PolarisServiceRegistryTest { } } + @BeforeEach + void setUp() { + PolarisSDKContextManager.innerDestroy(); + } + @Test public void testRegister() { this.contextRunner.run(context -> { diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java index 715ab2f39..f1488fda2 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java @@ -20,6 +20,8 @@ package com.tencent.cloud.polaris.ribbon; import com.netflix.client.config.DefaultClientConfigImpl; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.ServerList; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -40,6 +42,11 @@ public class PolarisRibbonServerListConfigurationTest { private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); + @BeforeAll + static void beforeAll() { + PolarisSDKContextManager.innerDestroy(); + } + @Test public void testDefaultInitialization() { this.applicationContextRunner diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java index b01e8b2b8..88d1cff58 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java @@ -22,6 +22,7 @@ import java.util.List; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.Server; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; @@ -60,8 +61,7 @@ public class PolarisServerListTest { PolarisContextAutoConfiguration.class, PolarisServerListTest.PolarisPropertiesConfiguration.class, PolarisDiscoveryClientConfiguration.class, - PolarisDiscoveryAutoConfiguration.class, - PolarisContextAutoConfiguration.class)) + PolarisDiscoveryAutoConfiguration.class)) .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") @@ -78,6 +78,7 @@ public class PolarisServerListTest { namingServer.getNamingService().addService(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER)); } + @AfterAll static void afterAll() { if (null != namingServer) { @@ -91,6 +92,7 @@ public class PolarisServerListTest { iClientConfig = mock(IClientConfig.class); when(iClientConfig.getClientName()).thenReturn(SERVICE_PROVIDER); + PolarisSDKContextManager.innerDestroy(); } @Test diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java index 1a20a298f..cce3b9bca 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java @@ -18,6 +18,7 @@ package com.tencent.cloud.polaris.ratelimit.config; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.ServiceRuleManager; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckReactiveFilter; @@ -27,9 +28,6 @@ import com.tencent.cloud.polaris.ratelimit.resolver.RateLimitRuleArgumentServlet import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelReactiveResolver; import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelServletResolver; import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLimitedFallback; -import com.tencent.polaris.client.api.SDKContext; -import com.tencent.polaris.ratelimit.api.core.LimitAPI; -import com.tencent.polaris.ratelimit.factory.LimitAPIFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -58,12 +56,6 @@ import static javax.servlet.DispatcherType.REQUEST; @ConditionalOnPolarisRateLimitEnabled public class PolarisRateLimitAutoConfiguration { - @Bean - @ConditionalOnMissingBean - public LimitAPI limitAPI(SDKContext polarisContext) { - return LimitAPIFactory.createLimitAPIByContext(polarisContext); - } - /** * Create when web application type is SERVLET. */ @@ -79,11 +71,12 @@ public class PolarisRateLimitAutoConfiguration { @Bean @ConditionalOnMissingBean - public QuotaCheckServletFilter quotaCheckFilter(LimitAPI limitAPI, + public QuotaCheckServletFilter quotaCheckFilter(PolarisSDKContextManager polarisSDKContextManager, PolarisRateLimitProperties polarisRateLimitProperties, RateLimitRuleArgumentServletResolver rateLimitRuleArgumentResolver, @Autowired(required = false) PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback) { - return new QuotaCheckServletFilter(limitAPI, polarisRateLimitProperties, rateLimitRuleArgumentResolver, polarisRateLimiterLimitedFallback); + return new QuotaCheckServletFilter(polarisSDKContextManager.getLimitAPI(), polarisRateLimitProperties, + rateLimitRuleArgumentResolver, polarisRateLimiterLimitedFallback); } @Bean @@ -113,11 +106,12 @@ public class PolarisRateLimitAutoConfiguration { } @Bean - public QuotaCheckReactiveFilter quotaCheckReactiveFilter(LimitAPI limitAPI, + public QuotaCheckReactiveFilter quotaCheckReactiveFilter(PolarisSDKContextManager polarisSDKContextManager, PolarisRateLimitProperties polarisRateLimitProperties, RateLimitRuleArgumentReactiveResolver rateLimitRuleArgumentResolver, @Nullable PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback) { - return new QuotaCheckReactiveFilter(limitAPI, polarisRateLimitProperties, rateLimitRuleArgumentResolver, polarisRateLimiterLimitedFallback); + return new QuotaCheckReactiveFilter(polarisSDKContextManager.getLimitAPI(), polarisRateLimitProperties, + rateLimitRuleArgumentResolver, polarisRateLimiterLimitedFallback); } } } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/context/CalleeControllerTests.java similarity index 81% rename from spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java rename to spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/context/CalleeControllerTests.java index 220f882fd..d4296c770 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/context/CalleeControllerTests.java @@ -15,12 +15,17 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.ratelimit.controller; +package com.tencent.cloud.polaris.context; +import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties; +import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter; +import com.tencent.cloud.polaris.ratelimit.resolver.RateLimitRuleArgumentServletResolver; +import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLimitedFallback; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.ratelimit.api.core.LimitAPI; import com.tencent.polaris.ratelimit.api.rpc.QuotaResponse; import com.tencent.polaris.ratelimit.api.rpc.QuotaResultCode; +import com.tencent.polaris.ratelimit.factory.LimitAPIFactory; import com.tencent.polaris.test.mock.discovery.NamingServer; import com.tencent.polaris.test.mock.discovery.NamingService; import org.junit.jupiter.api.AfterAll; @@ -36,6 +41,7 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.client.HttpClientErrorException.TooManyRequests; import org.springframework.web.client.RestClientException; @@ -144,5 +150,19 @@ public class CalleeControllerTests { return new RestTemplate(); } + @Bean + public LimitAPI limitAPI(PolarisSDKContextManager polarisSDKContextManager) { + return LimitAPIFactory.createLimitAPIByContext(polarisSDKContextManager.getSDKContext()); + } + + @Bean + @Primary + public QuotaCheckServletFilter quotaCheckFilter(LimitAPI limitAPI, + PolarisRateLimitProperties polarisRateLimitProperties, + RateLimitRuleArgumentServletResolver rateLimitRuleArgumentResolver, + @Autowired(required = false) PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback) { + return new QuotaCheckServletFilter(limitAPI, polarisRateLimitProperties, + rateLimitRuleArgumentResolver, polarisRateLimiterLimitedFallback); + } } } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/context/TestController.java similarity index 95% rename from spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java rename to spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/context/TestController.java index 1bca56bc0..c4e99a4d5 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/context/TestController.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.ratelimit.controller; +package com.tencent.cloud.polaris.context; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java index c21a71f3e..9a959e511 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java @@ -22,7 +22,6 @@ import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckReactiveFilter; import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter; import com.tencent.cloud.polaris.ratelimit.resolver.RateLimitRuleArgumentReactiveResolver; import com.tencent.cloud.polaris.ratelimit.resolver.RateLimitRuleArgumentServletResolver; -import com.tencent.polaris.ratelimit.api.core.LimitAPI; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -55,7 +54,6 @@ public class PolarisRateLimitAutoConfigurationTest { PolarisRateLimitProperties.class, PolarisRateLimitAutoConfiguration.class)) .run(context -> { - assertThat(context).hasSingleBean(LimitAPI.class); assertThat(context).doesNotHaveBean(RateLimitRuleArgumentServletResolver.class); assertThat(context).doesNotHaveBean(RateLimitRuleArgumentReactiveResolver.class); assertThat(context).doesNotHaveBean(PolarisRateLimitAutoConfiguration.QuotaCheckFilterConfig.class); @@ -73,7 +71,6 @@ public class PolarisRateLimitAutoConfigurationTest { PolarisRateLimitProperties.class, PolarisRateLimitAutoConfiguration.class)) .run(context -> { - assertThat(context).hasSingleBean(LimitAPI.class); assertThat(context).hasSingleBean(RateLimitRuleArgumentServletResolver.class); assertThat(context).hasSingleBean(PolarisRateLimitAutoConfiguration.QuotaCheckFilterConfig.class); assertThat(context).hasSingleBean(QuotaCheckServletFilter.class); @@ -91,7 +88,6 @@ public class PolarisRateLimitAutoConfigurationTest { PolarisRateLimitProperties.class, PolarisRateLimitAutoConfiguration.class)) .run(context -> { - assertThat(context).hasSingleBean(LimitAPI.class); assertThat(context).doesNotHaveBean(RateLimitRuleArgumentServletResolver.class); assertThat(context).hasSingleBean(RateLimitRuleArgumentReactiveResolver.class); assertThat(context).doesNotHaveBean(PolarisRateLimitAutoConfiguration.QuotaCheckFilterConfig.class); diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/PolarisLoadBalancerCompositeRuleBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/PolarisLoadBalancerCompositeRuleBeanPostProcessor.java index 7b9e8dc6d..66f4119f9 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/PolarisLoadBalancerCompositeRuleBeanPostProcessor.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/beanprocessor/PolarisLoadBalancerCompositeRuleBeanPostProcessor.java @@ -23,6 +23,7 @@ import java.util.List; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.tencent.cloud.common.util.BeanFactoryUtils; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.loadbalancer.config.PolarisLoadBalancerProperties; import com.tencent.cloud.polaris.router.PolarisLoadBalancerCompositeRule; import com.tencent.cloud.polaris.router.spi.RouterRequestInterceptor; @@ -47,7 +48,8 @@ public class PolarisLoadBalancerCompositeRuleBeanPostProcessor implements BeanPo @Override public Object postProcessBeforeInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException { if (bean instanceof AbstractLoadBalancerRule) { - RouterAPI routerAPI = beanFactory.getBean(RouterAPI.class); + PolarisSDKContextManager polarisSDKContextManager = beanFactory.getBean(PolarisSDKContextManager.class); + RouterAPI routerAPI = polarisSDKContextManager.getRouterAPI(); PolarisLoadBalancerProperties polarisLoadBalancerProperties = beanFactory.getBean(PolarisLoadBalancerProperties.class); IClientConfig iClientConfig = beanFactory.getBean(IClientConfig.class); List requestInterceptors = BeanFactoryUtils.getBeans(beanFactory, RouterRequestInterceptor.class); diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/beanprocessor/PolarisLoadBalancerCompositeRuleBeanPostProcessorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/beanprocessor/PolarisLoadBalancerCompositeRuleBeanPostProcessorTest.java index 1dc95c50d..f40d91a34 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/beanprocessor/PolarisLoadBalancerCompositeRuleBeanPostProcessorTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/beanprocessor/PolarisLoadBalancerCompositeRuleBeanPostProcessorTest.java @@ -27,6 +27,8 @@ import com.netflix.loadbalancer.RandomRule; import com.netflix.loadbalancer.RoundRobinRule; import com.netflix.loadbalancer.ZoneAvoidanceRule; import com.tencent.cloud.common.util.ReflectionUtils; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; +import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.loadbalancer.config.PolarisLoadBalancerProperties; import com.tencent.cloud.polaris.router.PolarisLoadBalancerCompositeRule; import com.tencent.cloud.polaris.router.config.RibbonConfiguration; @@ -36,6 +38,7 @@ import com.tencent.cloud.polaris.router.spi.RouterRequestInterceptor; import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.router.api.core.RouterAPI; import com.tencent.polaris.router.client.api.DefaultRouterAPI; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -62,10 +65,16 @@ public class PolarisLoadBalancerCompositeRuleBeanPostProcessorTest { private static final String SERVICE_2 = "service2"; + @BeforeEach + void setUp() { + PolarisSDKContextManager.innerDestroy(); + } + @Test public void test1() { ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of( + PolarisContextAutoConfiguration.class, RibbonDefaultConfig.class, PolarisRibbonTest.class, RibbonAutoConfiguration.class, @@ -86,7 +95,8 @@ public class PolarisLoadBalancerCompositeRuleBeanPostProcessorTest { @Test public void test2() { ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(RibbonDefaultConfig.class, PolarisRibbonTest.class, RibbonAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class, + RibbonDefaultConfig.class, PolarisRibbonTest.class, RibbonAutoConfiguration.class)) .withPropertyValues("spring.cloud.polaris.loadbalancer.strategy = random"); contextRunner.run(context -> { SpringClientFactory springClientFactory = context.getBean(SpringClientFactory.class); @@ -102,7 +112,8 @@ public class PolarisLoadBalancerCompositeRuleBeanPostProcessorTest { @Test public void test3() { ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(RibbonDefaultConfig.class, PolarisRibbonTest.class, RibbonAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class, + RibbonDefaultConfig.class, PolarisRibbonTest.class, RibbonAutoConfiguration.class)) .withPropertyValues("service1.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule"); contextRunner.run(context -> { SpringClientFactory springClientFactory = context.getBean(SpringClientFactory.class); @@ -125,7 +136,8 @@ public class PolarisLoadBalancerCompositeRuleBeanPostProcessorTest { @Test public void test4() { ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(CustomRibbonConfig.class, PolarisRibbonTest.class, RibbonAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class, + CustomRibbonConfig.class, PolarisRibbonTest.class, RibbonAutoConfiguration.class)); contextRunner.run(context -> { SpringClientFactory springClientFactory = context.getBean(SpringClientFactory.class); diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java index badbd5d3f..75481aa5a 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java @@ -48,11 +48,6 @@ public class MetadataContext { */ public static final String FRAGMENT_DISPOSABLE = "disposable"; - /** - * load balancer context. - */ - public static final String FRAGMENT_LOAD_BALANCER = "loadbalancer"; - /** * upstream disposable Context. */ @@ -115,8 +110,12 @@ public class MetadataContext { private final Map> fragmentContexts; + private final Map loadbalancerMetadata; + + public MetadataContext() { this.fragmentContexts = new ConcurrentHashMap<>(); + this.loadbalancerMetadata = new ConcurrentHashMap<>(); } public Map getDisposableMetadata() { @@ -148,8 +147,8 @@ public class MetadataContext { return this.getFragmentContext(MetadataContext.FRAGMENT_RAW_TRANSHEADERS_KV); } - public Map getLoadbalancerMetadata() { - return this.getFragmentContext(FRAGMENT_LOAD_BALANCER); + public Map getLoadbalancerMetadata() { + return this.loadbalancerMetadata; } public void setTransitiveMetadata(Map transitiveMetadata) { @@ -172,8 +171,8 @@ public class MetadataContext { this.putContext(FRAGMENT_RAW_TRANSHEADERS, key, value); } - public void setLoadbalancer(String key, String value) { - this.putContext(FRAGMENT_LOAD_BALANCER, key, value); + public void setLoadbalancer(String key, Object value) { + this.loadbalancerMetadata.put(key, value); } public Map getFragmentContext(String fragment) { diff --git a/spring-cloud-tencent-coverage/pom.xml b/spring-cloud-tencent-coverage/pom.xml index bc873aae6..ee44f02f6 100644 --- a/spring-cloud-tencent-coverage/pom.xml +++ b/spring-cloud-tencent-coverage/pom.xml @@ -78,6 +78,11 @@ com.tencent.cloud spring-cloud-tencent-gateway-plugin
+ + + com.tencent.cloud + spring-cloud-starter-tencent-discovery-adapter-plugin + diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 63f617789..e49d7c556 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -70,11 +70,11 @@ - 1.11.7-Hoxton.SR12 + 1.12.0-Hoxton.SR12-SNAPSHOT - 1.12.9 - 31.0.1-jre + 1.14.0-SNAPSHOT + 32.0.1-jre 1.2.11 4.5.1 1.12.10 @@ -168,6 +168,12 @@ + + com.tencent.cloud + spring-cloud-starter-tencent-discovery-adapter-plugin + ${revision} + + com.tencent.cloud spring-cloud-tencent-featureenv-plugin @@ -269,6 +275,7 @@ ${system-stubs-jupiter.version} test + diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/resources/bootstrap.yml index b854ea342..d33f1500b 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/resources/bootstrap.yml @@ -5,7 +5,7 @@ spring: name: MetadataBackendService cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true discovery: diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/resources/bootstrap.yml index a2f71d74f..806f5040c 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/resources/bootstrap.yml @@ -5,7 +5,7 @@ spring: name: MetadataFrontendService cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true discovery: diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/resources/bootstrap.yml index 36dfc0703..ed92677ba 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/resources/bootstrap.yml @@ -5,7 +5,7 @@ spring: name: MetadataMiddleService cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true discovery: diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/pom.xml b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/pom.xml new file mode 100644 index 000000000..d15b8dca7 --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/pom.xml @@ -0,0 +1,50 @@ + + + + multiple-discovery-nacos-example + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + nacos-callee-service-a + + + + org.springframework.boot + spring-boot-starter-web + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.0 + + + attach-sources + + jar + + + + + + + \ No newline at end of file diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceA.java b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceA.java new file mode 100644 index 000000000..3e2152dd6 --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceA.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.multiple.discovery.nacos; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Circuit breaker example callee application. + * + * @author Haotian Zhang + */ +@SpringBootApplication +public class NacosCalleeServiceA { + + public static void main(String[] args) { + SpringApplication.run(NacosCalleeServiceA.class, args); + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspect.java b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceAController.java similarity index 50% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspect.java rename to spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceAController.java index 418ce4846..f325e14e1 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspect.java +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceAController.java @@ -13,31 +13,38 @@ * 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.resttemplate; +package com.tencent.cloud.multiple.discovery.nacos; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; /** - * Intercept for BlockingLoadBalancerClient, put host and port to thread local. + * Service B Controller. * - * @author lepdou 2022-09-05 + * @author Haotian Zhang */ -@Aspect -public class BlockingLoadBalancerClientAspect { - - @Pointcut("execution(public * org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient.reconstructURI(..)) ") - public void pointcut() { +@RestController +@RequestMapping("/example/service/b") +public class NacosCalleeServiceAController { + /** + * Get service information. + * + * @return service information + */ + @GetMapping("/info") + public String info() { + return "hello world ! I'm a service B1"; } - @Around("pointcut()") - public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable { - LoadBalancerClientAspectUtils.extractLoadBalancerResult(joinPoint); - return joinPoint.proceed(); + @GetMapping("/health") + public String health() { + System.out.println("health check: 200 instance"); + return "hello world ! I'm a service B1"; } + } diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..23d44a7d0 --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-a/src/main/resources/bootstrap.yml @@ -0,0 +1,16 @@ +server: + port: 48082 +spring: + application: + name: NacosCalleeService + cloud: + polaris: + address: grpc://119.91.66.223:8091 + namespace: default + enabled: true + stat: + enabled: true + port: 28083 + nacos: + discovery: + server-addr: 127.0.0.1:8848 diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/pom.xml b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/pom.xml new file mode 100644 index 000000000..ce0cd96c1 --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/pom.xml @@ -0,0 +1,51 @@ + + + + multiple-discovery-nacos-example + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + nacos-callee-service-b + + + + org.springframework.boot + spring-boot-starter-web + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.0 + + + attach-sources + + jar + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceB.java b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceB.java new file mode 100644 index 000000000..8e4aa86d4 --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceB.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.multiple.discovery.nacos; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Circuit breaker example callee application. + * + * @author Haotian Zhang + */ +@SpringBootApplication +public class NacosCalleeServiceB { + + public static void main(String[] args) { + SpringApplication.run(NacosCalleeServiceB.class, args); + } +} diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceBController.java b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceBController.java new file mode 100644 index 000000000..cae686fbe --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCalleeServiceBController.java @@ -0,0 +1,54 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.multiple.discovery.nacos; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +/** + * Service B Controller. + * + * @author Haotian Zhang + */ +@RestController +@RequestMapping("/example/service/b") +public class NacosCalleeServiceBController { + + /** + * Get service information. + * + * @return service information + */ + @GetMapping("/info") + @ResponseStatus(code = HttpStatus.BAD_GATEWAY) + public String info() { + return "BAD_GATEWAY ! from service B2"; + } + + @GetMapping("/health") + @ResponseStatus(value = HttpStatus.BAD_GATEWAY, reason = "failed for call my service") + public String health() { + System.out.println("health check: 502 instance"); + return "hello world ! I'm a service B1"; + } + +} diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..e176c5b93 --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-callee-service-b/src/main/resources/bootstrap.yml @@ -0,0 +1,17 @@ +server: + port: 48081 +spring: + application: + name: NacosCalleeService + cloud: + polaris: + address: grpc://119.91.66.223:8091 + namespace: default + enabled: true + stat: + enabled: true + port: 28083 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/pom.xml b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/pom.xml new file mode 100644 index 000000000..ff82b5d9a --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/pom.xml @@ -0,0 +1,71 @@ + + + + multiple-discovery-nacos-example + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + nacos-discovery-caller + + + + org.springframework.boot + spring-boot-starter-web + + + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-router + + + + com.tencent.cloud + spring-cloud-starter-tencent-discovery-adapter-plugin + + + + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-circuitbreaker + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.0 + + + attach-sources + + jar + + + + + + + \ No newline at end of file diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCallerService.java b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCallerService.java new file mode 100644 index 000000000..dabb5ac98 --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCallerService.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.multiple.discovery.nacos; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * Circuit breaker example callee application. + * + * @author Haotian Zhang + */ +@SpringBootApplication +@EnableFeignClients +public class NacosCallerService { + + public static void main(String[] args) { + SpringApplication.run(NacosCallerService.class, args); + } +} diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCallerServiceController.java b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCallerServiceController.java new file mode 100644 index 000000000..f2d6bc9a8 --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/java/com/tencent/cloud/multiple/discovery/nacos/NacosCallerServiceController.java @@ -0,0 +1,42 @@ +/* + * 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.multiple.discovery.nacos; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * NacosCallerServiceController. + * + * @author Haotian Zhang + */ +@RestController +@RequestMapping("/example/service/a") +public class NacosCallerServiceController { + + @Autowired + private ProviderB polarisServiceB; + + @GetMapping("/getBServiceInfo") + public String getBServiceInfoFallbackFromCode() { + return polarisServiceB.info(); + } + +} diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/java/com/tencent/cloud/multiple/discovery/nacos/ProviderB.java b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/java/com/tencent/cloud/multiple/discovery/nacos/ProviderB.java new file mode 100644 index 000000000..6b83a7151 --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/java/com/tencent/cloud/multiple/discovery/nacos/ProviderB.java @@ -0,0 +1,38 @@ +/* + * 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.multiple.discovery.nacos; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * Circuit breaker example callee provider. + * + * @author Haotian Zhang + */ +@FeignClient(name = "NacosCalleeService") +public interface ProviderB { + + /** + * Get info of service B. + * + * @return info of service B + */ + @GetMapping("/example/service/b/info") + String info(); +} diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..ddc71f85f --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/nacos-discovery-caller/src/main/resources/bootstrap.yml @@ -0,0 +1,27 @@ +server: + port: 48080 +spring: + application: + name: NacosCallerService + cloud: + polaris: + address: grpc://119.91.66.223:8091 + namespace: default + enabled: true + loadbalancer: + enabled: true + discoveryType: Nacos + circuitbreaker: + enabled: true + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +feign: + hystrix: + enabled: true + +logging: + level: + root: info + com.tencent.cloud: debug \ No newline at end of file diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/pom.xml b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/pom.xml new file mode 100644 index 000000000..5a4ab6135 --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/multiple-discovery-nacos-example/pom.xml @@ -0,0 +1,29 @@ + + + + multiple-discovery-example + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + multiple-discovery-nacos-example + + pom + + nacos-callee-service-a + nacos-callee-service-b + nacos-discovery-caller + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + 2.2.9.RELEASE + + + \ No newline at end of file diff --git a/spring-cloud-tencent-examples/multiple-discovery-example/pom.xml b/spring-cloud-tencent-examples/multiple-discovery-example/pom.xml new file mode 100644 index 000000000..7586bb6d7 --- /dev/null +++ b/spring-cloud-tencent-examples/multiple-discovery-example/pom.xml @@ -0,0 +1,20 @@ + + + + spring-cloud-tencent-examples + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + multiple-discovery-example + Spring Cloud Starter Tencent Multiple Discovery Example + pom + + + multiple-discovery-nacos-example + + \ No newline at end of file diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/resources/bootstrap.yml index 5fa99c252..ffed6a22c 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/resources/bootstrap.yml @@ -5,7 +5,7 @@ spring: name: polaris-circuitbreaker-callee-service cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true stat: diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/resources/bootstrap.yml index 54cb21355..4909643f7 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/resources/bootstrap.yml @@ -5,7 +5,7 @@ spring: name: polaris-circuitbreaker-callee-service cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true stat: diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/resources/application.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/resources/bootstrap.yml similarity index 83% rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/resources/application.yml rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/resources/bootstrap.yml index bf20a3b2b..f71696fc2 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/resources/application.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/resources/bootstrap.yml @@ -5,14 +5,14 @@ spring: name: polaris-circuitbreaker-feign-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true loadbalancer: enabled: true feign: - circuitbreaker: + hystrix: enabled: true logging: diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/resources/bootstrap.yml index a7bdb3f4b..3ea326fab 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/resources/bootstrap.yml @@ -16,7 +16,7 @@ spring: feature-env: enabled: true polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true gateway: @@ -36,7 +36,7 @@ spring: name: CircuitBreaker args: # statusCodes 缺省时会自动识别 "5**" 为错误 -# statusCodes: '''404,5**''' + # statusCodes: '''404,5**''' # fallbackUri 缺省时会在熔断触发后拉取 plaris server 配置的降级作为 response fallbackUri: '''forward:/polaris-fallback''' # routes: diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/resources/bootstrap.yml index 720c3df80..4687ea9da 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/resources/bootstrap.yml @@ -5,7 +5,7 @@ spring: name: polaris-circuitbreaker-resttemplate-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true loadbalancer: diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/resources/bootstrap.yml index 7e75556f3..a6b162df9 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/resources/bootstrap.yml @@ -5,7 +5,7 @@ spring: name: polaris-circuitbreaker-webclient-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true loadbalancer: diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/resources/bootstrap.yml index c7d746e8e..c32d61bf8 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: polaris-circuitbreaker-zuul-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default circuitbreaker: enabled: true diff --git a/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml index 88ffbba8a..94afb2b7e 100644 --- a/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-config-example/src/main/resources/bootstrap.yml @@ -5,7 +5,7 @@ spring: name: polaris-config-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default config: auto-refresh: true # auto refresh when config file changed 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 87b751a43..ec34c0c35 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 @@ -5,7 +5,7 @@ spring: name: DiscoveryCalleeService cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true discovery: 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 cea3a922c..801100678 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 @@ -6,7 +6,7 @@ spring: name: DiscoveryCallerService cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true discovery: diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/bootstrap.yml index c6d40440f..9bf39bb82 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/bootstrap.yml @@ -10,5 +10,5 @@ spring: content: env: blue polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/resources/bootstrap.yml index a0cf12581..83f98b12f 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service2/src/main/resources/bootstrap.yml @@ -10,5 +10,5 @@ spring: content: env: green polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml index b0890b999..e915a92b2 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml @@ -21,7 +21,7 @@ spring: transitive: - a polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true gateway: @@ -61,7 +61,7 @@ spring: basedOnPreviousValue: false routes: - id: GatewayCalleeService - uri: lb://GatewayCalleeService + uri: http://www.baidu.com predicates: - Path=/GatewayCalleeService/** filters: diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/resources/bootstrap.yml index 133406e02..c80785ecf 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: GatewayZuulService cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default tencent: metadata: @@ -17,5 +17,6 @@ spring: zuul: routes: GatewayCalleeService: - serviceId: GatewayCalleeService + # serviceId: GatewayCalleeService + url: http://www.baidu.com path: /GatewayCalleeService/** diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml index a001fe02c..414287027 100644 --- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml @@ -5,7 +5,7 @@ spring: name: RateLimitCalleeService cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true ratelimit: diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/polaris.yml b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/polaris.yml new file mode 100644 index 000000000..489ff609f --- /dev/null +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/polaris.yml @@ -0,0 +1,3 @@ +provider: + rateLimit: + reportMetrics: true diff --git a/spring-cloud-tencent-examples/polaris-router-example/router-callee-service1/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-example/router-callee-service1/src/main/resources/bootstrap.yml index fdd9f2774..e3248f4da 100644 --- a/spring-cloud-tencent-examples/polaris-router-example/router-callee-service1/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-example/router-callee-service1/src/main/resources/bootstrap.yml @@ -9,6 +9,6 @@ spring: content: label1: value1 polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true diff --git a/spring-cloud-tencent-examples/polaris-router-example/router-callee-service2/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-example/router-callee-service2/src/main/resources/bootstrap.yml index d4b54a582..ff4805761 100644 --- a/spring-cloud-tencent-examples/polaris-router-example/router-callee-service2/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-example/router-callee-service2/src/main/resources/bootstrap.yml @@ -9,6 +9,6 @@ spring: content: label1: value2 polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true diff --git a/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/resources/bootstrap.yml index 47d4b1d10..e18c5f58a 100644 --- a/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/resources/bootstrap.yml @@ -9,7 +9,7 @@ spring: content: k1: v1 polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true loadbalancer: diff --git a/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-backend/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-backend/src/main/resources/bootstrap.yml index 34267f03e..4ee62a478 100644 --- a/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-backend/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-backend/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: featureenv-backend-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true logging: diff --git a/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-front/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-front/src/main/resources/bootstrap.yml index aab4e3e1d..f97f3cc87 100644 --- a/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-front/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-front/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: featureenv-front-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true logging: diff --git a/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-middle/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-middle/src/main/resources/bootstrap.yml index d4a9b9312..dc245a379 100644 --- a/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-middle/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-featureenv-example/base/base-middle/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: featureenv-middle-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true logging: diff --git a/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature1/feature1-backend/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature1/feature1-backend/src/main/resources/bootstrap.yml index 04b3ca3a8..f5d64a10e 100644 --- a/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature1/feature1-backend/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature1/feature1-backend/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: featureenv-backend-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true tencent: diff --git a/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature1/feature1-middle/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature1/feature1-middle/src/main/resources/bootstrap.yml index 1a46790a3..ddf1b5394 100644 --- a/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature1/feature1-middle/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature1/feature1-middle/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: featureenv-middle-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true tencent: diff --git a/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature2/feature2-backend/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature2/feature2-backend/src/main/resources/bootstrap.yml index aece1f3f8..2803ce6bb 100644 --- a/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature2/feature2-backend/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature2/feature2-backend/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: featureenv-backend-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true tencent: diff --git a/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature2/feature2-front/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature2/feature2-front/src/main/resources/bootstrap.yml index 9fdaa2add..6937fc89f 100644 --- a/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature2/feature2-front/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-featureenv-example/feature2/feature2-front/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: featureenv-front-example cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true tencent: diff --git a/spring-cloud-tencent-examples/polaris-router-featureenv-example/featureenv-gateway/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-featureenv-example/featureenv-gateway/src/main/resources/bootstrap.yml index 6e1972557..9326f11e9 100644 --- a/spring-cloud-tencent-examples/polaris-router-featureenv-example/featureenv-gateway/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-featureenv-example/featureenv-gateway/src/main/resources/bootstrap.yml @@ -7,7 +7,7 @@ spring: cloud: tencent: plugin: - scg: + scg: staining: enabled: true rule-staining: @@ -16,7 +16,7 @@ spring: feature-env: enabled: true polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true gateway: diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-backend/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-backend/src/main/resources/bootstrap.yml index a6715a57d..c17eae033 100644 --- a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-backend/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-backend/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: gray-release-back cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true logging: diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-frontend/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-frontend/src/main/resources/bootstrap.yml index cb7232d12..aa51b849a 100644 --- a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-frontend/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-frontend/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: gray-release-front cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true logging: diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-gateway/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-gateway/src/main/resources/bootstrap.yml index 44041c268..0c40d14be 100644 --- a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-gateway/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-gateway/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: gray-release-gateway cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true logging: diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-middle/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-middle/src/main/resources/bootstrap.yml index 9638411e8..878c783dc 100644 --- a/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-middle/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-example/router-grayrelease-middle/src/main/resources/bootstrap.yml @@ -6,7 +6,7 @@ spring: name: gray-release-middle cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true logging: diff --git a/spring-cloud-tencent-examples/pom.xml b/spring-cloud-tencent-examples/pom.xml index d2219c191..175b40bf9 100644 --- a/spring-cloud-tencent-examples/pom.xml +++ b/spring-cloud-tencent-examples/pom.xml @@ -26,6 +26,7 @@ polaris-router-grayrelease-example polaris-router-featureenv-example quickstart-example + multiple-discovery-example diff --git a/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-a/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-a/src/main/resources/bootstrap.yml index 2f1bd923f..9acadf522 100644 --- a/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-a/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-a/src/main/resources/bootstrap.yml @@ -5,14 +5,14 @@ spring: name: QuickstartCalleeService cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true discovery: enabled: true register: true config: - address: grpc://183.47.111.80:8093 + address: grpc://119.91.66.223:8093 auto-refresh: true groups: - name: ${spring.application.name} diff --git a/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-b/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-b/src/main/resources/bootstrap.yml index 60442040b..467fc5a00 100644 --- a/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-b/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-b/src/main/resources/bootstrap.yml @@ -5,14 +5,14 @@ spring: name: QuickstartCalleeService cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true discovery: enabled: true register: true config: - address: grpc://183.47.111.80:8093 + address: grpc://119.91.66.223:8093 auto-refresh: true groups: - name: ${spring.application.name} diff --git a/spring-cloud-tencent-examples/quickstart-example/quickstart-caller-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/quickstart-example/quickstart-caller-service/src/main/resources/bootstrap.yml index 33425c081..d2d1347f4 100644 --- a/spring-cloud-tencent-examples/quickstart-example/quickstart-caller-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/quickstart-example/quickstart-caller-service/src/main/resources/bootstrap.yml @@ -5,7 +5,7 @@ spring: name: QuickstartCallerService cloud: polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true discovery: diff --git a/spring-cloud-tencent-examples/quickstart-example/quickstart-gateway-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/quickstart-example/quickstart-gateway-service/src/main/resources/bootstrap.yml index fa49aa665..2f0b00cc2 100644 --- a/spring-cloud-tencent-examples/quickstart-example/quickstart-gateway-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/quickstart-example/quickstart-gateway-service/src/main/resources/bootstrap.yml @@ -15,7 +15,7 @@ spring: feature-env: enabled: true polaris: - address: grpc://183.47.111.80:8091 + address: grpc://119.91.66.223:8091 namespace: default enabled: true gateway: diff --git a/spring-cloud-tencent-plugin-starters/pom.xml b/spring-cloud-tencent-plugin-starters/pom.xml index 6487f9a89..bc2f153b9 100644 --- a/spring-cloud-tencent-plugin-starters/pom.xml +++ b/spring-cloud-tencent-plugin-starters/pom.xml @@ -17,6 +17,7 @@ spring-cloud-tencent-featureenv-plugin spring-cloud-tencent-gateway-plugin + spring-cloud-starter-tencent-discovery-adapter-plugin diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/pom.xml b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/pom.xml new file mode 100644 index 000000000..5638897e4 --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/pom.xml @@ -0,0 +1,42 @@ + + + + spring-cloud-tencent-plugin-starters + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + spring-cloud-starter-tencent-discovery-adapter-plugin + Spring Cloud Starter Tencent Discovery Adapter Plugin + + + + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-router + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + 2.2.9.RELEASE + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.mockito + mockito-inline + test + + + diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/main/java/com/tencent/cloud/plugin/discovery/adapter/config/NacosDiscoveryAdapterAutoConfiguration.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/main/java/com/tencent/cloud/plugin/discovery/adapter/config/NacosDiscoveryAdapterAutoConfiguration.java new file mode 100644 index 000000000..d1332926b --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/main/java/com/tencent/cloud/plugin/discovery/adapter/config/NacosDiscoveryAdapterAutoConfiguration.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.plugin.discovery.adapter.config; + +import com.tencent.cloud.plugin.discovery.adapter.transformer.NacosInstanceTransformer; +import com.tencent.cloud.polaris.loadbalancer.config.PolarisLoadBalancerAutoConfiguration; +import com.tencent.cloud.polaris.loadbalancer.transformer.InstanceTransformer; + +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * NacosDiscoveryAdapterAutoConfiguration. + * + * @author Haotian Zhang + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnDiscoveryEnabled +@AutoConfigureBefore(PolarisLoadBalancerAutoConfiguration.class) +public class NacosDiscoveryAdapterAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnClass(name = "com.alibaba.cloud.nacos.ribbon.NacosServer") + public InstanceTransformer instanceTransformer() { + return new NacosInstanceTransformer(); + } + +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/main/java/com/tencent/cloud/plugin/discovery/adapter/transformer/NacosInstanceTransformer.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/main/java/com/tencent/cloud/plugin/discovery/adapter/transformer/NacosInstanceTransformer.java new file mode 100644 index 000000000..db1047296 --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/main/java/com/tencent/cloud/plugin/discovery/adapter/transformer/NacosInstanceTransformer.java @@ -0,0 +1,42 @@ +/* + * 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.plugin.discovery.adapter.transformer; + +import com.alibaba.cloud.nacos.ribbon.NacosServer; +import com.netflix.loadbalancer.Server; +import com.tencent.cloud.polaris.loadbalancer.transformer.InstanceTransformer; +import com.tencent.polaris.api.pojo.DefaultInstance; + +/** + * NacosInstanceTransformer. + * + * @author Haotian Zhang + */ +public class NacosInstanceTransformer implements InstanceTransformer { + + @Override + public void transformCustom(DefaultInstance instance, Server server) { + if ("com.alibaba.cloud.nacos.ribbon.NacosServer".equals(server.getClass().getName())) { + NacosServer nacosServer = (NacosServer) server; + instance.setWeight((int) (nacosServer.getInstance().getWeight() * 100)); + instance.setHealthy(nacosServer.getInstance().isHealthy()); + instance.setMetadata(nacosServer.getMetadata()); + } + } +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..5bce5c869 --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.tencent.cloud.plugin.discovery.adapter.config.NacosDiscoveryAdapterAutoConfiguration +org.springframework.cloud.bootstrap.BootstrapConfiguration=\ + com.tencent.cloud.plugin.discovery.adapter.config.NacosDiscoveryAdapterAutoConfiguration diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/test/java/com/tencent/cloud/plugin/discovery/adapter/config/NacosDiscoveryAdapterAutoConfigurationTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/test/java/com/tencent/cloud/plugin/discovery/adapter/config/NacosDiscoveryAdapterAutoConfigurationTest.java new file mode 100644 index 000000000..8689cb2f0 --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/test/java/com/tencent/cloud/plugin/discovery/adapter/config/NacosDiscoveryAdapterAutoConfigurationTest.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.plugin.discovery.adapter.config; + +import com.tencent.cloud.plugin.discovery.adapter.transformer.NacosInstanceTransformer; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * NacosDiscoveryAdapterAutoConfigurationTest. + * + * @author Haotian Zhang + */ +public class NacosDiscoveryAdapterAutoConfigurationTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + NacosDiscoveryAdapterAutoConfiguration.class, + LoadBalancerAutoConfiguration.class + )); + + @Test + public void testDefaultInitialization() { + this.contextRunner.run(context -> { + assertThat(context).hasSingleBean(NacosInstanceTransformer.class); + }); + } +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/test/java/com/tencent/cloud/plugin/discovery/adapter/config/NacosInstanceTransformerTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/test/java/com/tencent/cloud/plugin/discovery/adapter/config/NacosInstanceTransformerTest.java new file mode 100644 index 000000000..00dd8be77 --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-discovery-adapter-plugin/src/test/java/com/tencent/cloud/plugin/discovery/adapter/config/NacosInstanceTransformerTest.java @@ -0,0 +1,65 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.plugin.discovery.adapter.config; + +import com.alibaba.cloud.nacos.ribbon.NacosServer; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.plugin.discovery.adapter.transformer.NacosInstanceTransformer; +import com.tencent.polaris.api.pojo.DefaultInstance; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * NacosInstanceTransformerTest. + * + * @author Haotian Zhang + */ +public class NacosInstanceTransformerTest { + + private static MockedStatic mockedApplicationContextAwareUtils; + + @BeforeAll + public static void beforeAll() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.namespace")) + .thenReturn("default"); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.service")) + .thenReturn("test"); + } + + + @Test + public void test() { + NacosInstanceTransformer nacosInstanceTransformer = new NacosInstanceTransformer(); + + com.alibaba.nacos.api.naming.pojo.Instance nacosInstance = new com.alibaba.nacos.api.naming.pojo.Instance(); + nacosInstance.setHealthy(true); + NacosServer nacosServer = new NacosServer(nacosInstance); + + + DefaultInstance instance = new DefaultInstance(); + nacosInstanceTransformer.transformCustom(instance, nacosServer); + assertThat(instance.isHealthy()).isEqualTo(true); + } + +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/java/com/tencent/cloud/tsf/adapter/config/TsfCircuitBreakerFlow.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/java/com/tencent/cloud/tsf/adapter/config/TsfCircuitBreakerFlow.java new file mode 100644 index 000000000..e01d3af4e --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/java/com/tencent/cloud/tsf/adapter/config/TsfCircuitBreakerFlow.java @@ -0,0 +1,39 @@ +/* + * 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.tsf.adapter.config; + +import com.tencent.polaris.circuitbreak.api.flow.CircuitBreakerFlow; +import com.tencent.polaris.client.api.SDKContext; + +/** + * TsfRouterFlow. + * + * @author sean yu + */ +public class TsfCircuitBreakerFlow implements CircuitBreakerFlow { + + @Override + public String getName() { + return PolarisTsfFlowConfigModifier.TSF_FLOW_NAME; + } + + @Override + public void setSDKContext(SDKContext sdkContext) { + + } +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/java/com/tencent/cloud/tsf/adapter/config/TsfLimitFlow.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/java/com/tencent/cloud/tsf/adapter/config/TsfLimitFlow.java new file mode 100644 index 000000000..3ac9b4b1e --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/java/com/tencent/cloud/tsf/adapter/config/TsfLimitFlow.java @@ -0,0 +1,39 @@ +/* + * 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.tsf.adapter.config; + +import com.tencent.polaris.client.api.SDKContext; +import com.tencent.polaris.ratelimit.api.flow.LimitFlow; + +/** + * TsfRouterFlow. + * + * @author sean yu + */ +public class TsfLimitFlow implements LimitFlow { + + @Override + public String getName() { + return PolarisTsfFlowConfigModifier.TSF_FLOW_NAME; + } + + @Override + public void setSDKContext(SDKContext sdkContext) { + + } +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/resources/META-INF/services/com.tencent.polaris.circuitbreak.api.flow.CircuitBreakerFlow b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/resources/META-INF/services/com.tencent.polaris.circuitbreak.api.flow.CircuitBreakerFlow new file mode 100644 index 000000000..92c38e742 --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/resources/META-INF/services/com.tencent.polaris.circuitbreak.api.flow.CircuitBreakerFlow @@ -0,0 +1 @@ +com.tencent.cloud.tsf.adapter.config.TsfCircuitBreakerFlow \ No newline at end of file diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/resources/META-INF/services/com.tencent.polaris.ratelimit.api.flow.LimitFlow b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/resources/META-INF/services/com.tencent.polaris.ratelimit.api.flow.LimitFlow new file mode 100644 index 000000000..54507bb07 --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-tsf-adapter-plugin/src/test/resources/META-INF/services/com.tencent.polaris.ratelimit.api.flow.LimitFlow @@ -0,0 +1 @@ +com.tencent.cloud.tsf.adapter.config.TsfLimitFlow \ No newline at end of file diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-featureenv-plugin/src/test/java/com/tencent/cloud/plugin/featureenv/FeatureEnvAutoConfigurationTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-featureenv-plugin/src/test/java/com/tencent/cloud/plugin/featureenv/FeatureEnvAutoConfigurationTest.java new file mode 100644 index 000000000..c90ab28da --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-featureenv-plugin/src/test/java/com/tencent/cloud/plugin/featureenv/FeatureEnvAutoConfigurationTest.java @@ -0,0 +1,59 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.plugin.featureenv; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link FeatureEnvAutoConfiguration}. + * + * @author Hoatian Zhang + */ +@ExtendWith(MockitoExtension.class) +public class FeatureEnvAutoConfigurationTest { + + private final ApplicationContextRunner enabledApplicationContextRunner = new ApplicationContextRunner(); + private final ApplicationContextRunner disabledApplicationContextRunner = new ApplicationContextRunner(); + + @Test + public void testEnabled() { + this.enabledApplicationContextRunner.withConfiguration(AutoConfigurations.of(FeatureEnvAutoConfiguration.class)) + .run(context -> { + assertThat(context).hasSingleBean(FeatureEnvProperties.class); + assertThat(context).hasSingleBean(FeatureEnvRouterRequestInterceptor.class); + }); + } + + @Test + public void testDisabled() { + this.disabledApplicationContextRunner.withConfiguration(AutoConfigurations.of(FeatureEnvAutoConfiguration.class)) + .withPropertyValues("spring.cloud.tencent.plugin.router.feature-env.enabled=false") + .run(context -> { + assertThat(context).doesNotHaveBean(FeatureEnvProperties.class); + assertThat(context).doesNotHaveBean(FeatureEnvRouterRequestInterceptor.class); + }); + } +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/SCGPluginsAutoConfigurationTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/SCGPluginsAutoConfigurationTest.java index 363450c6c..125867a18 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/SCGPluginsAutoConfigurationTest.java +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/SCGPluginsAutoConfigurationTest.java @@ -23,7 +23,7 @@ import com.tencent.cloud.plugin.gateway.staining.rule.RuleStainingExecutor; import com.tencent.cloud.plugin.gateway.staining.rule.RuleStainingProperties; import com.tencent.cloud.plugin.gateway.staining.rule.RuleTrafficStainer; import com.tencent.cloud.plugin.gateway.staining.rule.StainingRuleManager; -import com.tencent.polaris.client.api.SDKContext; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.polaris.configuration.api.core.ConfigFileService; import com.tencent.polaris.configuration.factory.ConfigFileServiceFactory; import org.junit.jupiter.api.Test; @@ -65,8 +65,8 @@ public class SCGPluginsAutoConfigurationTest { public static class TestApplication { @Bean - public ConfigFileService configFileService(SDKContext sdkContext) { - return ConfigFileServiceFactory.createConfigFileService(sdkContext); + public ConfigFileService configFileService(PolarisSDKContextManager polarisSDKContextManager) { + return ConfigFileServiceFactory.createConfigFileService(polarisSDKContextManager.getSDKContext()); } } } diff --git a/spring-cloud-tencent-polaris-context/pom.xml b/spring-cloud-tencent-polaris-context/pom.xml index be6fbd904..f525ce672 100644 --- a/spring-cloud-tencent-polaris-context/pom.xml +++ b/spring-cloud-tencent-polaris-context/pom.xml @@ -94,7 +94,7 @@ com.tencent.polaris flow-cache-expired - + com.tencent.polaris polaris-router-factory @@ -110,6 +110,11 @@ com.tencent.polaris loadbalancer-ringhash + + + com.tencent.polaris + polaris-assembly-factory + diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisSDKContextManager.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisSDKContextManager.java new file mode 100644 index 000000000..e28a60770 --- /dev/null +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisSDKContextManager.java @@ -0,0 +1,209 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.context; + +import java.util.List; +import java.util.Objects; + +import com.tencent.cloud.polaris.context.config.PolarisContextProperties; +import com.tencent.polaris.api.control.Destroyable; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.api.core.ProviderAPI; +import com.tencent.polaris.assembly.api.AssemblyAPI; +import com.tencent.polaris.assembly.factory.AssemblyAPIFactory; +import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; +import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory; +import com.tencent.polaris.client.api.SDKContext; +import com.tencent.polaris.factory.api.DiscoveryAPIFactory; +import com.tencent.polaris.factory.api.RouterAPIFactory; +import com.tencent.polaris.ratelimit.api.core.LimitAPI; +import com.tencent.polaris.ratelimit.factory.LimitAPIFactory; +import com.tencent.polaris.router.api.core.RouterAPI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.core.env.Environment; + +/** + * Manager for static Polaris SDK context. + * + * @author Haotian Zhang + */ +public class PolarisSDKContextManager { + + private static final Logger LOG = LoggerFactory.getLogger(PolarisSDKContextManager.class); + + /** + * Constant for checking before destroy SDK context. + */ + public volatile static boolean isRegistered = false; + private volatile static SDKContext sdkContext; + private volatile static ProviderAPI providerAPI; + private volatile static ConsumerAPI consumerAPI; + private volatile static RouterAPI routerAPI; + private volatile static CircuitBreakAPI circuitBreakAPI; + private volatile static LimitAPI limitAPI; + private volatile static AssemblyAPI assemblyAPI; + private final PolarisContextProperties properties; + private final Environment environment; + private final List modifierList; + + public PolarisSDKContextManager(PolarisContextProperties properties, Environment environment, List modifierList) { + this.properties = properties; + this.environment = environment; + this.modifierList = modifierList; + } + + /** + * Don't call this method directly. + */ + public static void innerDestroy() { + if (Objects.nonNull(sdkContext)) { + try { + // destroy ProviderAPI + if (Objects.nonNull(providerAPI)) { + ((AutoCloseable) providerAPI).close(); + providerAPI = null; + } + + // destroy ConsumerAPI + if (Objects.nonNull(consumerAPI)) { + ((AutoCloseable) consumerAPI).close(); + consumerAPI = null; + } + + // destroy RouterAPI + if (Objects.nonNull(routerAPI)) { + ((Destroyable) routerAPI).destroy(); + routerAPI = null; + } + + // destroy CircuitBreakAPI + if (Objects.nonNull(circuitBreakAPI)) { + ((Destroyable) circuitBreakAPI).destroy(); + circuitBreakAPI = null; + } + + // destroy LimitAPI + if (Objects.nonNull(limitAPI)) { + ((AutoCloseable) limitAPI).close(); + limitAPI = null; + } + + // destroy AssemblyAPI + if (Objects.nonNull(assemblyAPI)) { + ((Destroyable) assemblyAPI).destroy(); + assemblyAPI = null; + } + + if (Objects.nonNull(sdkContext)) { + sdkContext.destroy(); + sdkContext = null; + } + LOG.info("Polaris SDK context is destroyed."); + } + catch (Throwable throwable) { + LOG.error("destroy Polaris SDK context failed.", throwable); + } + } + } + + public void init() { + if (null == sdkContext) { + try { + // init SDKContext + sdkContext = SDKContext.initContextByConfig(properties.configuration(modifierList, + () -> environment.getProperty("spring.cloud.client.ip-address"), + () -> environment.getProperty("spring.cloud.polaris.local-port", Integer.class, 0))); + sdkContext.init(); + + // init ProviderAPI + providerAPI = DiscoveryAPIFactory.createProviderAPIByContext(sdkContext); + + // init ConsumerAPI + consumerAPI = DiscoveryAPIFactory.createConsumerAPIByContext(sdkContext); + + // init RouterAPI + routerAPI = RouterAPIFactory.createRouterAPIByContext(sdkContext); + + // init CircuitBreakAPI + circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByContext(sdkContext); + + // init LimitAPI + limitAPI = LimitAPIFactory.createLimitAPIByContext(sdkContext); + + // init AssemblyAPI + assemblyAPI = AssemblyAPIFactory.createAssemblyAPIByContext(sdkContext); + + // add shutdown hook + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + long startTimestamp = System.currentTimeMillis(); + long delay = 0; + while (true) { + if (!isRegistered || delay >= 60000) { + innerDestroy(); + break; + } + else { + delay = System.currentTimeMillis() - startTimestamp; + } + } + })); + LOG.info("create Polaris SDK context successfully. properties: {}", properties); + } + catch (Throwable throwable) { + LOG.error("create Polaris SDK context failed. properties: {}", properties, throwable); + throw throwable; + } + } + } + + public SDKContext getSDKContext() { + init(); + return sdkContext; + } + + public ProviderAPI getProviderAPI() { + init(); + return providerAPI; + } + + public ConsumerAPI getConsumerAPI() { + init(); + return consumerAPI; + } + + public RouterAPI getRouterAPI() { + init(); + return routerAPI; + } + + public CircuitBreakAPI getCircuitBreakAPI() { + init(); + return circuitBreakAPI; + } + + public LimitAPI getLimitAPI() { + init(); + return limitAPI; + } + + public AssemblyAPI getAssemblyAPI() { + return assemblyAPI; + } +} 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 298d89fa4..1593fdd5f 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 @@ -23,19 +23,14 @@ import java.util.List; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.context.ModifyAddress; import com.tencent.cloud.polaris.context.PolarisConfigModifier; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.ServiceRuleManager; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.core.ProviderAPI; import com.tencent.polaris.api.exception.PolarisException; import com.tencent.polaris.client.api.SDKContext; -import com.tencent.polaris.factory.api.DiscoveryAPIFactory; -import com.tencent.polaris.factory.api.RouterAPIFactory; -import com.tencent.polaris.router.api.core.RouterAPI; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; /** @@ -43,34 +38,14 @@ import org.springframework.core.env.Environment; * * @author Haotian Zhang */ -@Configuration(proxyBeanMethods = false) @ConditionalOnPolarisEnabled @EnableConfigurationProperties({PolarisContextProperties.class}) public class PolarisContextAutoConfiguration { - @Bean(name = "polarisContext", initMethod = "init", destroyMethod = "destroy") + @Bean(initMethod = "init") @ConditionalOnMissingBean - public SDKContext polarisContext(PolarisContextProperties properties, Environment environment, List modifierList) throws PolarisException { - return SDKContext.initContextByConfig(properties.configuration(modifierList, - () -> environment.getProperty("spring.cloud.client.ip-address"), - () -> environment.getProperty("spring.cloud.polaris.local-port", Integer.class, 0))); - } - - @Bean - @ConditionalOnMissingBean - public ProviderAPI polarisProvider(SDKContext polarisContext) throws PolarisException { - return DiscoveryAPIFactory.createProviderAPIByContext(polarisContext); - } - - @Bean - @ConditionalOnMissingBean - public ConsumerAPI polarisConsumer(SDKContext polarisContext) throws PolarisException { - return DiscoveryAPIFactory.createConsumerAPIByContext(polarisContext); - } - - @Bean - public RouterAPI polarisRouter(SDKContext polarisContext) throws PolarisException { - return RouterAPIFactory.createRouterAPIByContext(polarisContext); + public PolarisSDKContextManager polarisSDKContextManager(PolarisContextProperties properties, Environment environment, List modifierList) throws PolarisException { + return new PolarisSDKContextManager(properties, environment, modifierList); } @Bean @@ -80,8 +55,7 @@ public class PolarisContextAutoConfiguration { } @Bean - @ConditionalOnMissingBean - public ServiceRuleManager serviceRuleManager(SDKContext sdkContext, ConsumerAPI consumerAPI) { - return new ServiceRuleManager(sdkContext, consumerAPI); + public ServiceRuleManager serviceRuleManager(PolarisSDKContextManager polarisSDKContextManager) { + return new ServiceRuleManager(polarisSDKContextManager.getSDKContext(), polarisSDKContextManager.getConsumerAPI()); } } diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextPostConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextPostConfiguration.java index 4354c7d28..319ad40d2 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextPostConfiguration.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextPostConfiguration.java @@ -20,8 +20,8 @@ package com.tencent.cloud.polaris.context.config; import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.PostInitPolarisSDKContext; -import com.tencent.polaris.client.api.SDKContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -31,13 +31,13 @@ import org.springframework.context.annotation.Configuration; * * @author lepdou 2022-06-28 */ -@Configuration +@Configuration(proxyBeanMethods = false) @ConditionalOnPolarisEnabled public class PolarisContextPostConfiguration { @Bean public PostInitPolarisSDKContext postInitPolarisSDKContext( - SDKContext sdkContext, StaticMetadataManager staticMetadataManager) { - return new PostInitPolarisSDKContext(sdkContext, staticMetadataManager); + PolarisSDKContextManager polarisSDKContextManager, StaticMetadataManager staticMetadataManager) { + return new PostInitPolarisSDKContext(polarisSDKContextManager.getSDKContext(), staticMetadataManager); } } diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextProperties.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextProperties.java index f77eaa4f5..498af60d1 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextProperties.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextProperties.java @@ -31,6 +31,7 @@ import com.tencent.polaris.factory.ConfigAPIFactory; import com.tencent.polaris.factory.config.ConfigurationImpl; import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.util.CollectionUtils; @@ -45,26 +46,31 @@ public class PolarisContextProperties { /** * polaris server address. */ + @Value("${spring.cloud.polaris.address:}") private String address; /** * current server local ip address. */ + @Value("${spring.cloud.polaris.localIpAddress:}") private String localIpAddress; /** * current server local port. */ + @Value("${spring.cloud.polaris.localPort:}") private Integer localPort; /** * If polaris enabled. */ + @Value("${spring.cloud.polaris.enabled:#{'true'}}") private Boolean enabled; /** * polaris namespace. */ + @Value("${spring.cloud.polaris.namespace:#{'default'}}") private String namespace = "default"; /** @@ -149,4 +155,16 @@ public class PolarisContextProperties { public void setService(String service) { this.service = service; } + + @Override + public String toString() { + return "PolarisContextProperties{" + + "address='" + address + '\'' + + ", localIpAddress='" + localIpAddress + '\'' + + ((this.localPort == null || this.localPort <= 0) ? "" : ", localPort=" + localPort) + + ", enabled=" + enabled + + ", namespace='" + namespace + '\'' + + ((StringUtils.isBlank(this.service)) ? "" : ", service='" + service + '\'') + + '}'; + } } diff --git a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java index 7d70d5867..e2d33f049 100644 --- a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java +++ b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java @@ -43,14 +43,14 @@ import static org.assertj.core.api.Assertions.assertThat; public class PolarisContextGetHostTest { @Autowired - private SDKContext polarisContext; + private PolarisSDKContextManager polarisSDKContextManager; @Autowired private PolarisContextProperties polarisContextProperties; @Test public void testGetConfigHost() { - String bindIP = polarisContext.getConfig().getGlobal().getAPI().getBindIP(); + String bindIP = polarisSDKContextManager.getSDKContext().getConfig().getGlobal().getAPI().getBindIP(); assertThat(StringUtils.isBlank(bindIP)).isFalse(); assertThat(bindIP).isEqualTo("192.168.1.1"); assertThat(polarisContextProperties.getAddress()).isEqualTo("grpc://127.0.0.1:8091"); diff --git a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfigurationTest.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfigurationTest.java index 4b20bcd17..e5d05b6a3 100644 --- a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfigurationTest.java +++ b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfigurationTest.java @@ -17,7 +17,7 @@ package com.tencent.cloud.polaris.context.config; -import com.tencent.polaris.client.api.SDKContext; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -42,8 +42,8 @@ public class PolarisContextAutoConfigurationTest { @Test public void testProperties() { contextRunner.run(context -> { - final SDKContext sdkContext = context.getBean(SDKContext.class); - assertThat(sdkContext).isNotNull(); + PolarisSDKContextManager polarisSDKContextManager = context.getBean(PolarisSDKContextManager.class); + assertThat(polarisSDKContextManager).isNotNull(); }); } } diff --git a/spring-cloud-tencent-polaris-loadbalancer/pom.xml b/spring-cloud-tencent-polaris-loadbalancer/pom.xml index a66c3ec9d..0c884bc7e 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/pom.xml +++ b/spring-cloud-tencent-polaris-loadbalancer/pom.xml @@ -17,7 +17,7 @@ com.tencent.cloud - spring-cloud-tencent-polaris-context + spring-cloud-tencent-rpc-enhancement diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java index 58c4dc7d4..07335adf5 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancer.java @@ -34,6 +34,7 @@ import com.tencent.cloud.common.constant.ContextConstant; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.pojo.PolarisServer; import com.tencent.cloud.polaris.loadbalancer.config.PolarisLoadBalancerProperties; +import com.tencent.cloud.polaris.loadbalancer.transformer.InstanceTransformer; import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.pojo.DefaultInstance; import com.tencent.polaris.api.pojo.DefaultServiceInstances; @@ -58,11 +59,14 @@ public class PolarisLoadBalancer extends DynamicServerListLoadBalancer { private final PolarisLoadBalancerProperties polarisLoadBalancerProperties; + private final InstanceTransformer instanceTransformer; + public PolarisLoadBalancer(IClientConfig config, IRule rule, IPing ping, ServerList serverList, - ConsumerAPI consumerAPI, PolarisLoadBalancerProperties properties) { + ConsumerAPI consumerAPI, PolarisLoadBalancerProperties properties, InstanceTransformer instanceTransformer) { super(config, rule, ping, serverList, null, new PollingServerListUpdater()); this.consumerAPI = consumerAPI; this.polarisLoadBalancerProperties = properties; + this.instanceTransformer = instanceTransformer; } @Override @@ -114,6 +118,7 @@ public class PolarisLoadBalancer extends DynamicServerListLoadBalancer { throw new IllegalStateException( "PolarisLoadBalancer only Server with AppName or ServiceIdForDiscovery attribute"); } + ServiceKey serviceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE, name); List instances = new ArrayList<>(8); for (Server server : allServers) { @@ -127,6 +132,9 @@ public class PolarisLoadBalancer extends DynamicServerListLoadBalancer { instance.setPort(server.getPort()); instance.setZone(server.getZone()); instance.setWeight(100); + if (instanceTransformer != null) { + instanceTransformer.transformCustom(instance, server); + } instances.add(instance); } serviceInstances = new DefaultServiceInstances(serviceKey, instances); diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerRingHashKeyProvider.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerRingHashKeyProvider.java index 8a94f799b..e07d57dcc 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerRingHashKeyProvider.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerRingHashKeyProvider.java @@ -36,7 +36,7 @@ public final class PolarisLoadBalancerRingHashKeyProvider { } static String getHashKey() { - return MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_HASH_KEY); + return (String) MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_HASH_KEY); } } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfiguration.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfiguration.java index bed78f179..571afe5a2 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfiguration.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfiguration.java @@ -17,15 +17,24 @@ package com.tencent.cloud.polaris.loadbalancer.config; +import java.util.ArrayList; +import java.util.List; + import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; +import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateInterceptor; +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.loadbalancer.LoadBalancerInterceptor; +import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer; import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonClients; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestInterceptor; /** * Auto-configuration Ribbon for Polaris. @@ -44,4 +53,24 @@ public class PolarisLoadBalancerAutoConfiguration { public PolarisLoadBalancerProperties polarisLoadBalancerProperties() { return new PolarisLoadBalancerProperties(); } + + @Bean + @ConditionalOnMissingBean + public RestTemplateCustomizer restTemplateCustomizer(@Autowired(required = false) LoadBalancerInterceptor loadBalancerInterceptor) { + return restTemplate -> { + List list = new ArrayList<>(restTemplate.getInterceptors()); + // LoadBalancerInterceptor must invoke before EnhancedRestTemplateInterceptor + if (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); + } + restTemplate.setInterceptors(list); + }; + } + } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java index c41d9a4a3..ac2643b24 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java @@ -26,12 +26,13 @@ import com.netflix.loadbalancer.RandomRule; import com.netflix.loadbalancer.RoundRobinRule; import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ServerList; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.loadbalancer.PolarisLoadBalancer; import com.tencent.cloud.polaris.loadbalancer.PolarisRingHashRule; import com.tencent.cloud.polaris.loadbalancer.PolarisWeightedRandomRule; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.router.api.core.RouterAPI; +import com.tencent.cloud.polaris.loadbalancer.transformer.InstanceTransformer; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; @@ -46,9 +47,10 @@ public class PolarisRibbonClientConfiguration { @Bean public ILoadBalancer polarisLoadBalancer(IClientConfig iClientConfig, IRule iRule, IPing iPing, ServerList serverList, - ConsumerAPI consumerAPI, PolarisLoadBalancerProperties polarisLoadBalancerProperties) { + PolarisSDKContextManager polarisSDKContextManager, PolarisLoadBalancerProperties polarisLoadBalancerProperties, + @Autowired(required = false) InstanceTransformer instanceTransformer) { return new PolarisLoadBalancer(iClientConfig, iRule, iPing, serverList, - consumerAPI, polarisLoadBalancerProperties); + polarisSDKContextManager.getConsumerAPI(), polarisLoadBalancerProperties, instanceTransformer); } @Bean @@ -68,14 +70,14 @@ public class PolarisRibbonClientConfiguration { @Bean @ConditionalOnMissingBean @ConditionalOnProperty(value = "spring.cloud.polaris.loadbalancer.strategy", havingValue = "polarisWeightedRandom") - public IRule polarisWeightedRandomRule(RouterAPI routerAPI) { - return new PolarisWeightedRandomRule(routerAPI); + public IRule polarisWeightedRandomRule(PolarisSDKContextManager polarisSDKContextManager) { + return new PolarisWeightedRandomRule(polarisSDKContextManager.getRouterAPI()); } @Bean @ConditionalOnMissingBean @ConditionalOnProperty(value = "spring.cloud.polaris.loadbalancer.strategy", havingValue = "polarisRingHash") - public IRule polarisRingHashRule(RouterAPI routerAPI) { - return new PolarisRingHashRule(routerAPI); + public IRule polarisRingHashRule(PolarisSDKContextManager polarisSDKContextManager) { + return new PolarisRingHashRule(polarisSDKContextManager.getRouterAPI()); } } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/transformer/InstanceTransformer.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/transformer/InstanceTransformer.java new file mode 100644 index 000000000..7b12c31ee --- /dev/null +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/transformer/InstanceTransformer.java @@ -0,0 +1,32 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.loadbalancer.transformer; + +import com.netflix.loadbalancer.Server; +import com.tencent.polaris.api.pojo.DefaultInstance; + +/** + * InstanceTransformer. + * + * @author Haotian Zhang + */ +public interface InstanceTransformer { + + void transformCustom(DefaultInstance instance, Server server); + +} diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtilsTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtilsTest.java index c4438475f..e667c715f 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtilsTest.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtilsTest.java @@ -22,6 +22,7 @@ import java.util.LinkedList; import java.util.List; import com.netflix.loadbalancer.Server; +import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.pojo.PolarisServer; import com.tencent.polaris.api.pojo.DefaultInstance; import com.tencent.polaris.api.pojo.DefaultServiceInstances; @@ -29,6 +30,7 @@ import com.tencent.polaris.api.pojo.Instance; import com.tencent.polaris.api.pojo.ServiceInstances; import com.tencent.polaris.api.pojo.ServiceKey; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -52,6 +54,12 @@ public class LoadBalancerUtilsTest { private static final String TEST_NAMESPACE = "testNamespace"; private static final String TEST_SERVICE = "testService"; + @BeforeEach + void setUp() { + MetadataContext.LOCAL_NAMESPACE = TEST_NAMESPACE; + MetadataContext.LOCAL_SERVICE = TEST_SERVICE; + } + @Test public void testTransferServersToServiceInstances() { ServiceInstances serviceInstances = LoadBalancerUtils.transferServersToServiceInstances(assembleServers()); diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerTest.java index e633f553c..4bbf896a0 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerTest.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerTest.java @@ -98,7 +98,7 @@ public class PolarisLoadBalancerTest { ServerList emptyServerList = new StaticServerList<>(); PolarisLoadBalancer balancer = new PolarisLoadBalancer(config, rule, new DummyPing(), emptyServerList, - consumerAPI, properties); + consumerAPI, properties, null); String host = balancer.choose(null); @@ -132,7 +132,7 @@ public class PolarisLoadBalancerTest { ServerList staticServerList = assembleServerList(); PolarisLoadBalancer balancer = new PolarisLoadBalancer(config, rule, new DummyPing(), staticServerList, - consumerAPI, properties); + consumerAPI, properties, null); String host = balancer.choose(null); Assertions.assertThat(host).isEqualTo("127.0.0.1:8080"); diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java index 2a2a0a941..9cc9915d3 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java @@ -26,12 +26,9 @@ import com.netflix.loadbalancer.NoOpPing; import com.netflix.loadbalancer.RandomRule; import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ServerList; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.loadbalancer.PolarisLoadBalancer; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.client.api.SDKContext; -import com.tencent.polaris.discovery.client.api.DefaultConsumerAPI; -import com.tencent.polaris.router.api.core.RouterAPI; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanFactory; @@ -68,7 +65,6 @@ public class PolarisLoadBalancerAutoConfigurationTest { @Test public void testDefaultInitialization() { this.contextRunner.run(context -> { - assertThat(context).hasSingleBean(RouterAPI.class); assertThat(context).hasSingleBean(PolarisLoadBalancerProperties.class); assertThat(hasSinglePolarisLoadBalancer(context)).isTrue(); }); @@ -85,7 +81,7 @@ public class PolarisLoadBalancerAutoConfigurationTest { static class PolarisRibbonTest { @Autowired - private SDKContext sdkContext; + private PolarisSDKContextManager polarisSDKContextManager; @Bean public IClientConfig iClientConfig() { @@ -108,10 +104,5 @@ public class PolarisLoadBalancerAutoConfigurationTest { public ServerList serverList() { return new StaticServerList<>(); } - - @Bean - public ConsumerAPI consumerAPI() { - return new DefaultConsumerAPI(sdkContext); - } } } 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 582292807..9886eaa13 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 @@ -22,24 +22,25 @@ import java.util.List; import com.netflix.zuul.ZuulFilter; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignBeanPostProcessor; +import com.tencent.cloud.rpc.enhancement.filter.EnhancedReactiveFilter; +import com.tencent.cloud.rpc.enhancement.filter.EnhancedServletFilter; 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.reporter.ExceptionPolarisReporter; import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter; -import com.tencent.cloud.rpc.enhancement.resttemplate.BlockingLoadBalancerClientAspect; import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateInterceptor; -import com.tencent.cloud.rpc.enhancement.resttemplate.RibbonLoadBalancerClientAspect; +import com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer; import com.tencent.cloud.rpc.enhancement.scg.EnhancedGatewayGlobalFilter; -import com.tencent.cloud.rpc.enhancement.webclient.EnhancedWebClientReporter; +import com.tencent.cloud.rpc.enhancement.webclient.EnhancedWebClientExchangeFilterFunction; import com.tencent.cloud.rpc.enhancement.webclient.PolarisLoadBalancerClientRequestTransformer; +import com.tencent.cloud.rpc.enhancement.webclient.RibbonLoadBalancerClientAspect; import com.tencent.cloud.rpc.enhancement.zuul.EnhancedErrorZuulFilter; import com.tencent.cloud.rpc.enhancement.zuul.EnhancedPostZuulFilter; -import com.tencent.cloud.rpc.enhancement.zuul.EnhancedPreZuulFilter; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.client.api.SDKContext; +import com.tencent.cloud.rpc.enhancement.zuul.EnhancedRouteZuulFilter; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.annotation.Autowired; @@ -49,16 +50,26 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Role; +import org.springframework.core.annotation.Order; import org.springframework.core.env.Environment; import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.function.client.WebClient; +import static javax.servlet.DispatcherType.ASYNC; +import static javax.servlet.DispatcherType.ERROR; +import static javax.servlet.DispatcherType.FORWARD; +import static javax.servlet.DispatcherType.INCLUDE; +import static javax.servlet.DispatcherType.REQUEST; + /** * Auto Configuration for Polaris {@link feign.Feign} OR {@link RestTemplate} which can automatically bring in the call * results for reporting. @@ -73,23 +84,55 @@ import org.springframework.web.reactive.function.client.WebClient; public class RpcEnhancementAutoConfiguration { @Bean + @Lazy public EnhancedPluginRunner enhancedFeignPluginRunner( - @Autowired(required = false) List enhancedPlugins) { - return new DefaultEnhancedPluginRunner(enhancedPlugins); + @Autowired(required = false) List enhancedPlugins, + @Autowired(required = false) Registration registration, + PolarisSDKContextManager polarisSDKContextManager) { + return new DefaultEnhancedPluginRunner(enhancedPlugins, registration, polarisSDKContextManager.getSDKContext()); } @Bean public SuccessPolarisReporter successPolarisReporter(RpcEnhancementReporterProperties properties, - SDKContext context, - ConsumerAPI consumerAPI) { - return new SuccessPolarisReporter(properties, context, consumerAPI); + PolarisSDKContextManager polarisSDKContextManager) { + return new SuccessPolarisReporter(properties, polarisSDKContextManager.getConsumerAPI()); } @Bean public ExceptionPolarisReporter exceptionPolarisReporter(RpcEnhancementReporterProperties properties, - SDKContext context, - ConsumerAPI consumerAPI) { - return new ExceptionPolarisReporter(properties, context, consumerAPI); + PolarisSDKContextManager polarisSDKContextManager) { + return new ExceptionPolarisReporter(properties, polarisSDKContextManager.getConsumerAPI()); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) + protected static class RpcEnhancementServletFilterConfig { + + @Bean + public FilterRegistrationBean enhancedServletFilterRegistrationBean( + EnhancedServletFilter enhancedServletFilter) { + FilterRegistrationBean filterRegistrationBean = + new FilterRegistrationBean<>(enhancedServletFilter); + filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST); + filterRegistrationBean.setOrder(enhancedServletFilter.getClass().getAnnotation(Order.class).value()); + return filterRegistrationBean; + } + + @Bean + public EnhancedServletFilter enhancedServletFilter(@Lazy EnhancedPluginRunner pluginRunner) { + return new EnhancedServletFilter(pluginRunner); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) + protected static class RpcEnhancementReactiveFilterConfig { + + @Bean + public EnhancedReactiveFilter enhancedReactiveFilter(@Lazy EnhancedPluginRunner pluginRunner) { + return new EnhancedReactiveFilter(pluginRunner); + } } /** @@ -141,17 +184,11 @@ public class RpcEnhancementAutoConfiguration { @Bean @ConditionalOnMissingBean - @ConditionalOnClass(name = {"org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient"}) - public BlockingLoadBalancerClientAspect blockingLoadBalancerClientAspect() { - return new BlockingLoadBalancerClientAspect(); + @ConditionalOnClass(name = {"org.springframework.cloud.client.loadbalancer.LoadBalancerRequestTransformer"}) + public PolarisLoadBalancerRequestTransformer polarisLoadBalancerRequestTransformer() { + return new PolarisLoadBalancerRequestTransformer(); } - @Bean - @ConditionalOnMissingBean - @ConditionalOnClass(name = {"org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient"}) - public RibbonLoadBalancerClientAspect ribbonLoadBalancerClientAspect() { - return new RibbonLoadBalancerClientAspect(); - } } /** @@ -166,12 +203,12 @@ public class RpcEnhancementAutoConfiguration { private List webClientBuilder = Collections.emptyList(); @Bean - public EnhancedWebClientReporter exchangeFilterFunction(@Lazy EnhancedPluginRunner pluginRunner) { - return new EnhancedWebClientReporter(pluginRunner); + public EnhancedWebClientExchangeFilterFunction exchangeFilterFunction(@Lazy EnhancedPluginRunner pluginRunner) { + return new EnhancedWebClientExchangeFilterFunction(pluginRunner); } @Bean - public SmartInitializingSingleton addEnhancedWebClientReporterForWebClient(EnhancedWebClientReporter reporter) { + public SmartInitializingSingleton addEnhancedWebClientReporterForWebClient(EnhancedWebClientExchangeFilterFunction reporter) { return () -> webClientBuilder.forEach(webClient -> { webClient.filter(reporter); }); @@ -184,6 +221,12 @@ public class RpcEnhancementAutoConfiguration { return new PolarisLoadBalancerClientRequestTransformer(); } + @Bean + @ConditionalOnMissingBean + @ConditionalOnClass(name = {"org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient"}) + public RibbonLoadBalancerClientAspect ribbonLoadBalancerClientAspect() { + return new RibbonLoadBalancerClientAspect(); + } } /** @@ -200,7 +243,6 @@ public class RpcEnhancementAutoConfiguration { public EnhancedGatewayGlobalFilter enhancedPolarisGatewayReporter(@Lazy EnhancedPluginRunner pluginRunner) { return new EnhancedGatewayGlobalFilter(pluginRunner); } - } /** @@ -211,8 +253,8 @@ public class RpcEnhancementAutoConfiguration { @ConditionalOnClass(name = "com.netflix.zuul.http.ZuulServlet") protected static class PolarisCircuitBreakerZuulFilterConfig { @Bean - public EnhancedPreZuulFilter enhancedZuulPreFilter(@Lazy EnhancedPluginRunner pluginRunner, Environment environment) { - return new EnhancedPreZuulFilter(pluginRunner, environment); + public EnhancedRouteZuulFilter enhancedZuulRouteFilter(@Lazy EnhancedPluginRunner pluginRunner, Environment environment) { + return new EnhancedRouteZuulFilter(pluginRunner, environment); } @Bean diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java index 003dc5f65..d09f77ae2 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; import feign.Client; @@ -34,10 +35,6 @@ import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE; import static feign.Util.checkNotNull; /** @@ -66,13 +63,19 @@ public class EnhancedFeignClient implements Client { EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder() .httpHeaders(requestHeaders) - .httpMethod(HttpMethod.resolve(request.httpMethod().name())) + .httpMethod(HttpMethod.valueOf(request.httpMethod().name())) .url(url) .build(); enhancedPluginContext.setRequest(enhancedRequestContext); + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(request.requestTemplate().feignTarget() + .name(), url.getHost(), url.getPort(), url.getScheme().equals("https")); + enhancedPluginContext.setTargetServiceInstance(serviceInstance, url); + // Run pre enhanced plugins. - pluginRunner.run(PRE, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.PRE, enhancedPluginContext); + long startMillis = System.currentTimeMillis(); try { Response response = delegate.execute(request, options); @@ -87,24 +90,20 @@ public class EnhancedFeignClient implements Client { .build(); enhancedPluginContext.setResponse(enhancedResponseContext); - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(request.requestTemplate().feignTarget() - .name(), url.getHost(), url.getPort(), url.getScheme().equals("https")); - enhancedPluginContext.setServiceInstance(serviceInstance); - // Run post enhanced plugins. - pluginRunner.run(POST, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); return response; } catch (IOException origin) { enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); enhancedPluginContext.setThrowable(origin); // Run exception enhanced feign plugins. - pluginRunner.run(EXCEPTION, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.EXCEPTION, enhancedPluginContext); throw origin; } finally { // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); } } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedReactiveFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedReactiveFilter.java new file mode 100644 index 000000000..4fa6899ce --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedReactiveFilter.java @@ -0,0 +1,93 @@ +/* + * 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.filter; + +import com.tencent.cloud.common.constant.MetadataConstant; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; +import reactor.core.publisher.Mono; + +import org.springframework.core.Ordered; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; + +/** + * EnhancedReactiveFilter. + * + * @author sean yu + */ +public class EnhancedReactiveFilter implements WebFilter, Ordered { + + private final EnhancedPluginRunner pluginRunner; + + public EnhancedReactiveFilter(EnhancedPluginRunner pluginRunner) { + this.pluginRunner = pluginRunner; + } + + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext(); + + EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder() + .httpHeaders(exchange.getRequest().getHeaders()) + .httpMethod(exchange.getRequest().getMethod()) + .url(exchange.getRequest().getURI()) + .build(); + enhancedPluginContext.setRequest(enhancedRequestContext); + + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + + // Run pre enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.PRE, enhancedPluginContext); + + long startMillis = System.currentTimeMillis(); + return chain.filter(exchange) + .doOnSuccess(v -> { + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + + EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder() + .httpStatus(exchange.getResponse().getRawStatusCode()) + .httpHeaders(exchange.getResponse().getHeaders()) + .build(); + enhancedPluginContext.setResponse(enhancedResponseContext); + + // Run post enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.POST, enhancedPluginContext); + }) + .doOnError(e -> { + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + enhancedPluginContext.setThrowable(e); + // Run exception enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.EXCEPTION, enhancedPluginContext); + }) + .doFinally(v -> { + // Run finally enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.FINALLY, enhancedPluginContext); + }); + } + + @Override + public int getOrder() { + return MetadataConstant.OrderConstant.WEB_FILTER_ORDER + 1; + } + +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedServletFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedServletFilter.java new file mode 100644 index 000000000..9d404281c --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedServletFilter.java @@ -0,0 +1,116 @@ +/* + * 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.filter; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.tencent.cloud.common.constant.MetadataConstant; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; + +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.web.filter.OncePerRequestFilter; + +/** + * EnhancedServletFilter. + * + * @author sean yu + */ +@Order(MetadataConstant.OrderConstant.WEB_FILTER_ORDER + 1) +public class EnhancedServletFilter extends OncePerRequestFilter { + + private final EnhancedPluginRunner pluginRunner; + + public EnhancedServletFilter(EnhancedPluginRunner pluginRunner) { + this.pluginRunner = pluginRunner; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext(); + + HttpHeaders requestHeaders = new HttpHeaders(); + Enumeration requestHeaderNames = request.getHeaderNames(); + if (requestHeaderNames != null) { + while (requestHeaderNames.hasMoreElements()) { + String requestHeaderName = requestHeaderNames.nextElement(); + requestHeaders.addAll(requestHeaderName, Collections.list(request.getHeaders(requestHeaderName))); + } + } + EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder() + .httpHeaders(requestHeaders) + .httpMethod(HttpMethod.valueOf(request.getMethod())) + .url(URI.create(request.getRequestURL().toString())) + .build(); + enhancedPluginContext.setRequest(enhancedRequestContext); + + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + + // Run pre enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.PRE, enhancedPluginContext); + + long startMillis = System.currentTimeMillis(); + try { + filterChain.doFilter(request, response); + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + + HttpHeaders responseHeaders = new HttpHeaders(); + Collection responseHeaderNames = response.getHeaderNames(); + if (responseHeaderNames != null) { + for (String responseHeaderName : responseHeaderNames) { + responseHeaders.addAll(responseHeaderName, new ArrayList<>(response.getHeaders(responseHeaderName))); + } + } + EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder() + .httpStatus(response.getStatus()) + .httpHeaders(responseHeaders) + .build(); + enhancedPluginContext.setResponse(enhancedResponseContext); + + // Run post enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.POST, enhancedPluginContext); + } + catch (ServletException | IOException e) { + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + enhancedPluginContext.setThrowable(e); + // Run exception enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.EXCEPTION, enhancedPluginContext); + throw e; + } + finally { + // Run finally enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.FINALLY, enhancedPluginContext); + } + } + +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java index ca34b2af1..fe88923f6 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java @@ -23,7 +23,12 @@ import java.util.List; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.polaris.client.api.SDKContext; +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.util.CollectionUtils; /** @@ -33,13 +38,28 @@ import org.springframework.util.CollectionUtils; */ public class DefaultEnhancedPluginRunner implements EnhancedPluginRunner { - private final Multimap pluginMap = ArrayListMultimap.create(); + private final Multimap pluginMap = ArrayListMultimap.create(); - public DefaultEnhancedPluginRunner(List enhancedPlugins) { + private final ServiceInstance localServiceInstance; + + public DefaultEnhancedPluginRunner( + List enhancedPlugins, + Registration registration, + SDKContext sdkContext + ) { if (!CollectionUtils.isEmpty(enhancedPlugins)) { enhancedPlugins.stream() .sorted(Comparator.comparing(EnhancedPlugin::getOrder)) - .forEach(plugin -> pluginMap.put(plugin.getType().name(), plugin)); + .forEach(plugin -> pluginMap.put(plugin.getType(), plugin)); + } + if (registration != null) { + localServiceInstance = registration; + } + else { + DefaultServiceInstance defaultServiceInstance = new DefaultServiceInstance(); + defaultServiceInstance.setServiceId(MetadataContext.LOCAL_SERVICE); + defaultServiceInstance.setHost(sdkContext.getConfig().getGlobal().getAPI().getBindIP()); + localServiceInstance = defaultServiceInstance; } } @@ -51,7 +71,7 @@ public class DefaultEnhancedPluginRunner implements EnhancedPluginRunner { */ @Override public void run(EnhancedPluginType pluginType, EnhancedPluginContext context) { - for (EnhancedPlugin plugin : pluginMap.get(pluginType.name())) { + for (EnhancedPlugin plugin : pluginMap.get(pluginType)) { try { plugin.run(context); } @@ -60,4 +80,10 @@ public class DefaultEnhancedPluginRunner implements EnhancedPluginRunner { } } } + + @Override + public ServiceInstance getLocalServiceInstance() { + return this.localServiceInstance; + } + } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java index fa4e891d0..7eb14ae89 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java @@ -18,6 +18,13 @@ package com.tencent.cloud.rpc.enhancement.plugin; +import java.net.URI; +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; /** @@ -27,6 +34,8 @@ import org.springframework.cloud.client.ServiceInstance; */ public class EnhancedPluginContext { + private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedPluginContext.class); + private EnhancedRequestContext request; private EnhancedResponseContext response; @@ -35,7 +44,12 @@ public class EnhancedPluginContext { private long delay; - private ServiceInstance serviceInstance; + private ServiceInstance localServiceInstance; + + /** + * targetServiceInstance only exist in a client runner type. + */ + private ServiceInstance targetServiceInstance; public EnhancedRequestContext getRequest() { return request; @@ -69,12 +83,37 @@ public class EnhancedPluginContext { this.delay = delay; } - public ServiceInstance getServiceInstance() { - return serviceInstance; + public ServiceInstance getLocalServiceInstance() { + return localServiceInstance; } - public void setServiceInstance(ServiceInstance serviceInstance) { - this.serviceInstance = serviceInstance; + public void setLocalServiceInstance(ServiceInstance localServiceInstance) { + this.localServiceInstance = localServiceInstance; + } + + public ServiceInstance getTargetServiceInstance() { + return targetServiceInstance; + } + + public void setTargetServiceInstance(ServiceInstance targetServiceInstance, URI url) { + if (Objects.nonNull(targetServiceInstance)) { + this.targetServiceInstance = targetServiceInstance; + } + else if (Objects.nonNull(url)) { + DefaultServiceInstance defaultServiceInstance = new DefaultServiceInstance(); + defaultServiceInstance.setUri(url); + if (defaultServiceInstance.isSecure()) { + defaultServiceInstance.setPort(443); + } + else { + defaultServiceInstance.setPort(80); + } + this.targetServiceInstance = defaultServiceInstance; + } + else { + this.targetServiceInstance = new DefaultServiceInstance(); + LOGGER.warn("TargetServiceInstance is empty."); + } } @Override @@ -84,7 +123,9 @@ public class EnhancedPluginContext { ", response=" + response + ", throwable=" + throwable + ", delay=" + delay + - ", serviceInstance=" + serviceInstance + + ", localServiceInstance=" + localServiceInstance + + ", targetServiceInstance=" + targetServiceInstance + '}'; } + } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java index e15af39e5..5ff7d1bf6 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java @@ -18,6 +18,8 @@ package com.tencent.cloud.rpc.enhancement.plugin; +import org.springframework.cloud.client.ServiceInstance; + /** * Plugin runner. * @@ -32,4 +34,7 @@ public interface EnhancedPluginRunner { * @param context context in enhanced feign client. */ void run(EnhancedPluginType pluginType, EnhancedPluginContext context); + + ServiceInstance getLocalServiceInstance(); + } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java index 64dc2ecb9..996af00bb 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java @@ -22,25 +22,52 @@ package com.tencent.cloud.rpc.enhancement.plugin; * * @author Haotian Zhang */ -public enum EnhancedPluginType { - - /** - * Pre feign plugin. - */ - PRE, - - /** - * Post feign plugin. - */ - POST, - - /** - * Exception feign plugin. - */ - EXCEPTION, - - /** - * Finally feign plugin. - */ - FINALLY +public interface EnhancedPluginType { + + enum Client implements EnhancedPluginType { + /** + * Pre Client plugin. + */ + PRE, + + /** + * Post Client plugin. + */ + POST, + + /** + * Exception Client plugin. + */ + EXCEPTION, + + /** + * Finally Client plugin. + */ + FINALLY + + } + + enum Server implements EnhancedPluginType { + /** + * Pre Server plugin. + */ + PRE, + + /** + * Post Server plugin. + */ + POST, + + /** + * Exception Server plugin. + */ + EXCEPTION, + + /** + * Finally Server plugin. + */ + FINALLY + + } + } 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 new file mode 100644 index 000000000..95807dbab --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java @@ -0,0 +1,70 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.rpc.enhancement.plugin; + +import org.springframework.core.Ordered; + +/** + * PluginOrderConstant. + * + * @author sean yu + */ +public class PluginOrderConstant { + + public static class ClientPluginOrder { + + /** + * order for + * {@link com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter} + * and + * {@link com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter}. + */ + public static final int CONSUMER_REPORTER_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 1; + + /** + * order for + * {@link com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter} + * and + * {@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/AbstractPolarisReporterAdapter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PolarisEnhancedPluginUtils.java similarity index 73% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PolarisEnhancedPluginUtils.java index d177aad8b..e1556c82d 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PolarisEnhancedPluginUtils.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.rpc.enhancement; +package com.tencent.cloud.rpc.enhancement.plugin; import java.io.UnsupportedEncodingException; import java.net.SocketTimeoutException; @@ -24,12 +24,18 @@ import java.net.URLDecoder; 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.Objects; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.constant.RouterConstant; import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.RequestLabelUtils; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; @@ -39,11 +45,11 @@ import com.tencent.polaris.api.pojo.RetStatus; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.api.rpc.ServiceCallResult; import com.tencent.polaris.api.utils.CollectionUtils; -import com.tencent.polaris.client.api.SDKContext; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.lang.Nullable; @@ -63,30 +69,21 @@ import static org.springframework.http.HttpStatus.SERVICE_UNAVAILABLE; import static org.springframework.http.HttpStatus.VARIANT_ALSO_NEGOTIATES; /** - * Abstract Polaris Reporter Adapter . + * Abstract Polaris Plugin Adapter . * * @author Elve.Xu 2022-07-11 */ -public abstract class AbstractPolarisReporterAdapter { - private static final Logger LOG = LoggerFactory.getLogger(AbstractPolarisReporterAdapter.class); - private static final List HTTP_STATUSES = toList(NOT_IMPLEMENTED, BAD_GATEWAY, - SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, HTTP_VERSION_NOT_SUPPORTED, VARIANT_ALSO_NEGOTIATES, - INSUFFICIENT_STORAGE, LOOP_DETECTED, BANDWIDTH_LIMIT_EXCEEDED, NOT_EXTENDED, NETWORK_AUTHENTICATION_REQUIRED); +public final class PolarisEnhancedPluginUtils { - protected final RpcEnhancementReporterProperties reportProperties; + private PolarisEnhancedPluginUtils() { - protected final SDKContext context; - - /** - * Constructor With {@link RpcEnhancementReporterProperties} . - * - * @param reportProperties instance of {@link RpcEnhancementReporterProperties}. - */ - protected AbstractPolarisReporterAdapter(RpcEnhancementReporterProperties reportProperties, SDKContext context) { - this.reportProperties = reportProperties; - this.context = context; } + private static final Logger LOG = LoggerFactory.getLogger(PolarisEnhancedPluginUtils.class); + private static final List HTTP_STATUSES = toList(NOT_IMPLEMENTED, BAD_GATEWAY, + SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, HTTP_VERSION_NOT_SUPPORTED, VARIANT_ALSO_NEGOTIATES, + INSUFFICIENT_STORAGE, LOOP_DETECTED, BANDWIDTH_LIMIT_EXCEEDED, NOT_EXTENDED, NETWORK_AUTHENTICATION_REQUIRED); + /** * createServiceCallResult. * @param calleeServiceName will pick up url host when null @@ -100,7 +97,7 @@ public abstract class AbstractPolarisReporterAdapter { * @param exception exception * @return ServiceCallResult */ - public ServiceCallResult createServiceCallResult( + public static ServiceCallResult createServiceCallResult(String callerHost, @Nullable String calleeServiceName, @Nullable String calleeHost, @Nullable Integer calleePort, URI uri, HttpHeaders requestHeaders, @Nullable HttpHeaders responseHeaders, @Nullable Integer statusCode, long delay, @Nullable Throwable exception) { @@ -112,11 +109,11 @@ public abstract class AbstractPolarisReporterAdapter { resultRequest.setRetCode(statusCode == null ? -1 : statusCode); resultRequest.setDelay(delay); resultRequest.setCallerService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE)); - resultRequest.setCallerIp(this.context.getConfig().getGlobal().getAPI().getBindIP()); + resultRequest.setCallerIp(callerHost); resultRequest.setHost(StringUtils.isBlank(calleeHost) ? uri.getHost() : calleeHost); resultRequest.setPort(calleePort == null ? getPort(uri) : calleePort); resultRequest.setLabels(getLabels(requestHeaders)); - resultRequest.setRetStatus(getRetStatusFromRequest(responseHeaders, getDefaultRetStatus(statusCode, exception))); + resultRequest.setRetStatus(getRetStatusFromRequest(responseHeaders, statusCode, exception)); resultRequest.setRuleName(getActiveRuleNameFromRequest(responseHeaders)); return resultRequest; } @@ -132,7 +129,7 @@ public abstract class AbstractPolarisReporterAdapter { * @param exception exception * @return ResourceStat */ - public ResourceStat createInstanceResourceStat( + public static ResourceStat createInstanceResourceStat( @Nullable String calleeServiceName, @Nullable String calleeHost, @Nullable Integer calleePort, URI uri, @Nullable Integer statusCode, long delay, @Nullable Throwable exception) { ServiceKey calleeServiceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE, StringUtils.isBlank(calleeServiceName) ? uri.getHost() : calleeServiceName); @@ -165,42 +162,40 @@ public abstract class AbstractPolarisReporterAdapter { * @param httpStatus request http status code * @return true , otherwise return false . */ - protected boolean apply(@Nullable HttpStatus httpStatus) { + static boolean apply(@Nullable HttpStatus httpStatus) { if (Objects.isNull(httpStatus)) { return false; } - else { - // statuses > series - List status = reportProperties.getStatuses(); - - if (status.isEmpty()) { - List series = reportProperties.getSeries(); - // Check INTERNAL_SERVER_ERROR (500) status. - if (reportProperties.isIgnoreInternalServerError() && Objects.equals(httpStatus, INTERNAL_SERVER_ERROR)) { - return false; - } - if (series.isEmpty()) { - return HTTP_STATUSES.contains(httpStatus); - } - else { - try { - return series.contains(HttpStatus.Series.valueOf(httpStatus)); - } - catch (Exception e) { - LOG.warn("Decode http status failed.", e); - } - } + RpcEnhancementReporterProperties reportProperties; + try { + reportProperties = ApplicationContextAwareUtils.getApplicationContext().getBean(RpcEnhancementReporterProperties.class); + } + catch (BeansException e) { + LOG.error("get RpcEnhancementReporterProperties bean err", e); + reportProperties = new RpcEnhancementReporterProperties(); + } + // statuses > series + List status = reportProperties.getStatuses(); + if (status.isEmpty()) { + List series = reportProperties.getSeries(); + // Check INTERNAL_SERVER_ERROR (500) status. + if (reportProperties.isIgnoreInternalServerError() && Objects.equals(httpStatus, INTERNAL_SERVER_ERROR)) { + return false; } - else { - // Use the user-specified fuse status code. - return status.contains(httpStatus); + if (series.isEmpty()) { + return HTTP_STATUSES.contains(httpStatus); } + return series.contains(httpStatus.series()); } - // DEFAULT RETURN FALSE. - return false; + // Use the user-specified fuse status code. + return status.contains(httpStatus); + } + + public static RetStatus getRetStatusFromRequest(HttpHeaders headers, Integer statusCode, Throwable exception) { + return getRetStatusFromRequest(headers, getDefaultRetStatus(statusCode, exception)); } - protected RetStatus getRetStatusFromRequest(HttpHeaders headers, RetStatus defaultVal) { + static RetStatus getRetStatusFromRequest(HttpHeaders headers, RetStatus defaultVal) { if (headers != null && headers.containsKey(HeaderConstant.INTERNAL_CALLEE_RET_STATUS)) { List values = headers.get(HeaderConstant.INTERNAL_CALLEE_RET_STATUS); if (CollectionUtils.isNotEmpty(values)) { @@ -216,7 +211,7 @@ public abstract class AbstractPolarisReporterAdapter { return defaultVal; } - protected String getActiveRuleNameFromRequest(HttpHeaders headers) { + static String getActiveRuleNameFromRequest(HttpHeaders headers) { if (headers != null && headers.containsKey(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME)) { Collection values = headers.get(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME); if (CollectionUtils.isNotEmpty(values)) { @@ -226,7 +221,7 @@ public abstract class AbstractPolarisReporterAdapter { return ""; } - private RetStatus getDefaultRetStatus(Integer statusCode, Throwable exception) { + private static RetStatus getDefaultRetStatus(Integer statusCode, Throwable exception) { RetStatus retStatus = RetStatus.RetSuccess; if (exception != null) { retStatus = RetStatus.RetFail; @@ -240,12 +235,12 @@ public abstract class AbstractPolarisReporterAdapter { return retStatus; } - private int getPort(URI uri) { + private static int getPort(URI uri) { // -1 means access directly by url, and use http default port number 80 return uri.getPort() == -1 ? 80 : uri.getPort(); } - private String getLabels(HttpHeaders headers) { + private static String getLabels(HttpHeaders headers) { if (headers != null) { Collection labels = headers.get(RouterConstant.ROUTER_LABEL_HEADER); if (CollectionUtils.isNotEmpty(labels) && labels.iterator().hasNext()) { @@ -262,5 +257,27 @@ public abstract class AbstractPolarisReporterAdapter { return null; } + public static Map getLabelMap(HttpHeaders headers) { + if (headers != null) { + Collection labels = headers.get(RouterConstant.ROUTER_LABEL_HEADER); + if (CollectionUtils.isNotEmpty(labels) && labels.iterator().hasNext()) { + String label = labels.iterator().next(); + try { + label = URLDecoder.decode(label, UTF_8); + } + catch (UnsupportedEncodingException e) { + LOG.error("unsupported charset exception " + UTF_8, e); + } + try { + return new ObjectMapper().readValue(label, new TypeReference>() { }); + } + catch (JsonProcessingException e) { + LOG.error("parse label map exception", e); + } + } + } + return null; + } + } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java index 76c4250b3..471c9a179 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java @@ -20,37 +20,38 @@ package com.tencent.cloud.rpc.enhancement.plugin.reporter; import java.util.Optional; -import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; 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.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils; import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.rpc.ServiceCallResult; -import com.tencent.polaris.client.api.SDKContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.Ordered; + +import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.CONSUMER_REPORTER_PLUGIN_ORDER; /** * Polaris reporter when feign call fails. * * @author Haotian Zhang */ -public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { +public class ExceptionPolarisReporter implements EnhancedPlugin { private static final Logger LOG = LoggerFactory.getLogger(ExceptionPolarisReporter.class); private final ConsumerAPI consumerAPI; - public ExceptionPolarisReporter(RpcEnhancementReporterProperties reporterProperties, - SDKContext context, + private final RpcEnhancementReporterProperties reportProperties; + + public ExceptionPolarisReporter(RpcEnhancementReporterProperties reportProperties, ConsumerAPI consumerAPI) { - super(reporterProperties, context); + this.reportProperties = reportProperties; this.consumerAPI = consumerAPI; } @@ -61,22 +62,24 @@ public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter imp @Override public EnhancedPluginType getType() { - return EnhancedPluginType.EXCEPTION; + return EnhancedPluginType.Client.EXCEPTION; } @Override public void run(EnhancedPluginContext context) { - if (!super.reportProperties.isEnabled()) { + if (!this.reportProperties.isEnabled()) { return; } EnhancedRequestContext request = context.getRequest(); - ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); - - ServiceCallResult resultRequest = createServiceCallResult( - serviceInstance.getServiceId(), - serviceInstance.getHost(), - serviceInstance.getPort(), + ServiceInstance callerServiceInstance = Optional.ofNullable(context.getLocalServiceInstance()).orElse(new DefaultServiceInstance()); + ServiceInstance calleeServiceInstance = Optional.ofNullable(context.getTargetServiceInstance()).orElse(new DefaultServiceInstance()); + + ServiceCallResult resultRequest = PolarisEnhancedPluginUtils.createServiceCallResult( + callerServiceInstance.getHost(), + calleeServiceInstance.getServiceId(), + calleeServiceInstance.getHost(), + calleeServiceInstance.getPort(), request.getUrl(), request.getHttpHeaders(), null, @@ -100,7 +103,7 @@ public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter imp @Override public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE + 1; + return CONSUMER_REPORTER_PLUGIN_ORDER; } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java index 4b35396da..d4c7d6a1e 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java @@ -19,38 +19,39 @@ package com.tencent.cloud.rpc.enhancement.plugin.reporter; import java.util.Optional; -import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; 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.EnhancedRequestContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; +import com.tencent.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils; import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.rpc.ServiceCallResult; -import com.tencent.polaris.client.api.SDKContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.Ordered; + +import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.CONSUMER_REPORTER_PLUGIN_ORDER; /** * Polaris reporter when feign call is successful. * * @author Haotian Zhang */ -public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { +public class SuccessPolarisReporter implements EnhancedPlugin { private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class); private final ConsumerAPI consumerAPI; - public SuccessPolarisReporter(RpcEnhancementReporterProperties properties, - SDKContext context, + private final RpcEnhancementReporterProperties reportProperties; + + public SuccessPolarisReporter(RpcEnhancementReporterProperties reportProperties, ConsumerAPI consumerAPI) { - super(properties, context); + this.reportProperties = reportProperties; this.consumerAPI = consumerAPI; } @@ -61,23 +62,25 @@ public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter imple @Override public EnhancedPluginType getType() { - return EnhancedPluginType.POST; + return EnhancedPluginType.Client.POST; } @Override public void run(EnhancedPluginContext context) { - if (!super.reportProperties.isEnabled()) { + if (!this.reportProperties.isEnabled()) { return; } EnhancedRequestContext request = context.getRequest(); EnhancedResponseContext response = context.getResponse(); - ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); - - ServiceCallResult resultRequest = createServiceCallResult( - serviceInstance.getServiceId(), - serviceInstance.getHost(), - serviceInstance.getPort(), + ServiceInstance callerServiceInstance = Optional.ofNullable(context.getLocalServiceInstance()).orElse(new DefaultServiceInstance()); + ServiceInstance calleeServiceInstance = Optional.ofNullable(context.getTargetServiceInstance()).orElse(new DefaultServiceInstance()); + + ServiceCallResult resultRequest = PolarisEnhancedPluginUtils.createServiceCallResult( + callerServiceInstance.getHost(), + calleeServiceInstance.getServiceId(), + calleeServiceInstance.getHost(), + calleeServiceInstance.getPort(), request.getUrl(), request.getHttpHeaders(), response.getHttpHeaders(), @@ -101,6 +104,6 @@ public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter imple @Override public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE + 1; + return CONSUMER_REPORTER_PLUGIN_ORDER; } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptor.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptor.java index e67e241f2..c50cbb907 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptor.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptor.java @@ -18,25 +18,21 @@ package com.tencent.cloud.rpc.enhancement.resttemplate; import java.io.IOException; -import java.util.Map; -import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; -import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; /** * EnhancedRestTemplateInterceptor. @@ -63,8 +59,13 @@ public class EnhancedRestTemplateInterceptor implements ClientHttpRequestInterce .build(); enhancedPluginContext.setRequest(enhancedRequestContext); + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + enhancedPluginContext.setTargetServiceInstance((ServiceInstance) MetadataContextHolder.get() + .getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE), request.getURI()); + // Run pre enhanced plugins. - pluginRunner.run(PRE, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.PRE, enhancedPluginContext); + long startMillis = System.currentTimeMillis(); try { ClientHttpResponse response = execution.execute(request, body); @@ -76,29 +77,20 @@ public class EnhancedRestTemplateInterceptor implements ClientHttpRequestInterce .build(); enhancedPluginContext.setResponse(enhancedResponseContext); - Map loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata(); - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); - serviceInstance.setServiceId(request.getURI().getHost()); - serviceInstance.setHost(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST)); - if (loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT) != null) { - serviceInstance.setPort(Integer.parseInt(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT))); - } - enhancedPluginContext.setServiceInstance(serviceInstance); - // Run post enhanced plugins. - pluginRunner.run(POST, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); return response; } catch (IOException e) { enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); enhancedPluginContext.setThrowable(e); // Run exception enhanced plugins. - pluginRunner.run(EXCEPTION, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.EXCEPTION, enhancedPluginContext); throw e; } finally { // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformer.java similarity index 55% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformer.java index 04ffac0cf..961633cfa 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformer.java @@ -17,28 +17,36 @@ package com.tencent.cloud.rpc.enhancement.resttemplate; -import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.metadata.MetadataContextHolder; -import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; +import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestTransformer; +import org.springframework.http.HttpRequest; /** - * Extract load balancer result from {@link LoadBalancerClient} and put to MetadataContext. - * @author lepdou 2022-09-06 + * PolarisLoadBalancerRequestTransformer. + * + * @author sean yu */ -public final class LoadBalancerClientAspectUtils { +public class PolarisLoadBalancerRequestTransformer implements LoadBalancerRequestTransformer { - private LoadBalancerClientAspectUtils() { - } + /** + * LOAD_BALANCER_SERVICE_INSTANCE MetadataContext key. + */ + public static final String LOAD_BALANCER_SERVICE_INSTANCE = "LOAD_BALANCER_SERVICE_INSTANCE"; - public static void extractLoadBalancerResult(ProceedingJoinPoint joinPoint) { - Object server = joinPoint.getArgs()[0]; - if (server instanceof ServiceInstance) { - ServiceInstance instance = (ServiceInstance) server; - MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST, instance.getHost()); - MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT, String.valueOf(instance.getPort())); + /** + * Transform Request, add Loadbalancer ServiceInstance to MetadataContext. + * @param request request + * @param instance instance + * @return HttpRequest + */ + @Override + public HttpRequest transformRequest(HttpRequest request, ServiceInstance instance) { + if (instance != null) { + MetadataContextHolder.get().setLoadbalancer(LOAD_BALANCER_SERVICE_INSTANCE, instance); } + return request; } + } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilter.java index 6f0a02615..7afcc114b 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilter.java @@ -21,6 +21,7 @@ import java.net.URI; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; import reactor.core.publisher.Mono; @@ -33,10 +34,6 @@ import org.springframework.cloud.gateway.route.Route; import org.springframework.core.Ordered; import org.springframework.web.server.ServerWebExchange; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR; @@ -65,22 +62,26 @@ public class EnhancedGatewayGlobalFilter implements GlobalFilter, Ordered { enhancedPluginContext.setRequest(enhancedRequestContext); // Run pre enhanced plugins. - pluginRunner.run(PRE, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.PRE, enhancedPluginContext); long startTime = System.currentTimeMillis(); return chain.filter(exchange) .doOnSubscribe(v -> { - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR); - if (route != null) { - serviceInstance.setServiceId(route.getUri().getHost()); - } URI uri = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR); + enhancedPluginContext.getRequest().setUrl(uri); if (uri != null) { - serviceInstance.setHost(uri.getHost()); - serviceInstance.setPort(uri.getPort()); + if (route != null && route.getUri().getScheme().contains("lb")) { + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); + serviceInstance.setServiceId(route.getUri().getHost()); + serviceInstance.setHost(uri.getHost()); + serviceInstance.setPort(uri.getPort()); + enhancedPluginContext.setTargetServiceInstance(serviceInstance, null); + } + else { + enhancedPluginContext.setTargetServiceInstance(null, uri); + } } - enhancedPluginContext.setServiceInstance(serviceInstance); }) .doOnSuccess(v -> { enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); @@ -91,18 +92,18 @@ public class EnhancedGatewayGlobalFilter implements GlobalFilter, Ordered { enhancedPluginContext.setResponse(enhancedResponseContext); // Run post enhanced plugins. - pluginRunner.run(POST, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); }) .doOnError(t -> { enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); enhancedPluginContext.setThrowable(t); // Run exception enhanced plugins. - pluginRunner.run(EXCEPTION, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.EXCEPTION, enhancedPluginContext); }) .doFinally(v -> { // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); }); } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientExchangeFilterFunction.java similarity index 68% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporter.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientExchangeFilterFunction.java index 2b62fc5d0..673cac3da 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientExchangeFilterFunction.java @@ -17,35 +17,31 @@ package com.tencent.cloud.rpc.enhancement.webclient; -import java.util.Map; - -import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; import reactor.core.publisher.Mono; -import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; import org.springframework.web.reactive.function.client.ExchangeFunction; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; /** - * EnhancedWebClientReporter. + * EnhancedWebClientExchangeFilterFunction. * * @author sean yu */ -public class EnhancedWebClientReporter implements ExchangeFilterFunction { +public class EnhancedWebClientExchangeFilterFunction implements ExchangeFilterFunction { private final EnhancedPluginRunner pluginRunner; - public EnhancedWebClientReporter(EnhancedPluginRunner pluginRunner) { + public EnhancedWebClientExchangeFilterFunction(EnhancedPluginRunner pluginRunner) { this.pluginRunner = pluginRunner; } @@ -60,38 +56,37 @@ public class EnhancedWebClientReporter implements ExchangeFilterFunction { .build(); enhancedPluginContext.setRequest(enhancedRequestContext); + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + enhancedPluginContext.setTargetServiceInstance((ServiceInstance) MetadataContextHolder.get() + .getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE), request.url()); + + // Run post enhanced plugins. + pluginRunner.run(EnhancedPluginType.Client.PRE, enhancedPluginContext); + long startTime = System.currentTimeMillis(); return next.exchange(request) - .doOnSubscribe(subscription -> { - Map loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata(); - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); - serviceInstance.setServiceId(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID)); - serviceInstance.setHost(request.url().getHost()); - serviceInstance.setPort(request.url().getPort()); - enhancedPluginContext.setServiceInstance(serviceInstance); - }) .doOnSuccess(response -> { enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder() - .httpStatus(response.rawStatusCode()) + .httpStatus(response.statusCode().value()) .httpHeaders(response.headers().asHttpHeaders()) .build(); enhancedPluginContext.setResponse(enhancedResponseContext); // Run post enhanced plugins. - pluginRunner.run(POST, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); }) .doOnError(t -> { enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); enhancedPluginContext.setThrowable(t); // Run exception enhanced plugins. - pluginRunner.run(EXCEPTION, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.EXCEPTION, enhancedPluginContext); }) .doFinally(v -> { // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); }); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformer.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformer.java index 4e6913164..be1807ff0 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformer.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformer.java @@ -17,13 +17,14 @@ package com.tencent.cloud.rpc.enhancement.webclient; -import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.metadata.MetadataContextHolder; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerClientRequestTransformer; import org.springframework.web.reactive.function.client.ClientRequest; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; + /** * PolarisLoadBalancerClientRequestTransformer. * @@ -31,10 +32,16 @@ import org.springframework.web.reactive.function.client.ClientRequest; */ public class PolarisLoadBalancerClientRequestTransformer implements LoadBalancerClientRequestTransformer { + /** + * Transform Request, add Loadbalancer ServiceInstance to MetadataContext. + * @param request request + * @param instance instance + * @return HttpRequest + */ @Override public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) { if (instance != null) { - MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID, instance.getServiceId()); + MetadataContextHolder.get().setLoadbalancer(LOAD_BALANCER_SERVICE_INSTANCE, instance); } return request; } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/RibbonLoadBalancerClientAspect.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/RibbonLoadBalancerClientAspect.java similarity index 73% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/RibbonLoadBalancerClientAspect.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/RibbonLoadBalancerClientAspect.java index 59f3ec90f..64ff67ba4 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/RibbonLoadBalancerClientAspect.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/RibbonLoadBalancerClientAspect.java @@ -15,13 +15,16 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.rpc.enhancement.resttemplate; +package com.tencent.cloud.rpc.enhancement.webclient; +import com.tencent.cloud.common.metadata.MetadataContextHolder; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; + /** * Intercept for RibbonLoadBalancerClient, put host and port to thread local. * @@ -30,14 +33,17 @@ import org.aspectj.lang.annotation.Pointcut; @Aspect public class RibbonLoadBalancerClientAspect { - @Pointcut("execution(public * org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.reconstructURI(..))") + @Pointcut("execution(public * org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.choose(..))") public void pointcut() { } @Around("pointcut()") public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable { - LoadBalancerClientAspectUtils.extractLoadBalancerResult(joinPoint); - return joinPoint.proceed(); + Object result = joinPoint.proceed(); + if (result != null) { + MetadataContextHolder.get().setLoadbalancer(LOAD_BALANCER_SERVICE_INSTANCE, result); + } + return result; } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedErrorZuulFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedErrorZuulFilter.java index 362e9be0b..778b81329 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedErrorZuulFilter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedErrorZuulFilter.java @@ -24,22 +24,18 @@ import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import com.tencent.cloud.common.constant.ContextConstant; -import com.tencent.cloud.common.util.ZuulFilterUtils; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponse; import org.springframework.core.env.Environment; import org.springframework.http.HttpHeaders; import org.springframework.util.StringUtils; import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_PRE_ROUTE_TIME; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ERROR_TYPE; /** @@ -90,13 +86,9 @@ public class EnhancedErrorZuulFilter extends ZuulFilter { enhancedPluginContext = (EnhancedPluginContext) enhancedPluginContextObj; } - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); - Object ribbonResponseObj = context.get("ribbonResponse"); Object startTimeMilliObject = context.get(POLARIS_PRE_ROUTE_TIME); Throwable throwable = context.getThrowable(); - RibbonApacheHttpResponse ribbonResponse; - if (throwable != null && ribbonResponseObj != null && ribbonResponseObj instanceof RibbonApacheHttpResponse - && startTimeMilliObject != null && startTimeMilliObject instanceof Long) { + if (throwable != null && startTimeMilliObject != null && startTimeMilliObject instanceof Long) { HttpHeaders responseHeaders = new HttpHeaders(); Collection names = context.getResponse().getHeaderNames(); for (String name : names) { @@ -110,17 +102,12 @@ public class EnhancedErrorZuulFilter extends ZuulFilter { Long startTimeMilli = (Long) startTimeMilliObject; enhancedPluginContext.setDelay(System.currentTimeMillis() - startTimeMilli); enhancedPluginContext.setThrowable(throwable); - ribbonResponse = (RibbonApacheHttpResponse) ribbonResponseObj; - serviceInstance.setServiceId(ZuulFilterUtils.getServiceId(context)); - serviceInstance.setHost(ribbonResponse.getRequestedURI().getHost()); - serviceInstance.setPort(ribbonResponse.getRequestedURI().getPort()); - enhancedPluginContext.setServiceInstance(serviceInstance); // Run post enhanced plugins. - pluginRunner.run(EXCEPTION, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.EXCEPTION, enhancedPluginContext); // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); } return null; } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPostZuulFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPostZuulFilter.java index ff1ba4095..9ee466383 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPostZuulFilter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPostZuulFilter.java @@ -24,22 +24,18 @@ import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import com.tencent.cloud.common.constant.ContextConstant; -import com.tencent.cloud.common.util.ZuulFilterUtils; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponse; import org.springframework.core.env.Environment; import org.springframework.http.HttpHeaders; import org.springframework.util.StringUtils; import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_PRE_ROUTE_TIME; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER; @@ -89,12 +85,8 @@ public class EnhancedPostZuulFilter extends ZuulFilter { enhancedPluginContext = (EnhancedPluginContext) enhancedPluginContextObj; } - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); - Object ribbonResponseObj = context.get("ribbonResponse"); Object startTimeMilliObject = context.get(POLARIS_PRE_ROUTE_TIME); - RibbonApacheHttpResponse ribbonResponse; - if (ribbonResponseObj != null && ribbonResponseObj instanceof RibbonApacheHttpResponse - && startTimeMilliObject != null && startTimeMilliObject instanceof Long) { + if (startTimeMilliObject instanceof Long) { HttpHeaders responseHeaders = new HttpHeaders(); Collection names = context.getResponse().getHeaderNames(); for (String name : names) { @@ -107,17 +99,12 @@ public class EnhancedPostZuulFilter extends ZuulFilter { enhancedPluginContext.setResponse(enhancedResponseContext); Long startTimeMilli = (Long) startTimeMilliObject; enhancedPluginContext.setDelay(System.currentTimeMillis() - startTimeMilli); - ribbonResponse = (RibbonApacheHttpResponse) ribbonResponseObj; - serviceInstance.setServiceId(ZuulFilterUtils.getServiceId(context)); - serviceInstance.setHost(ribbonResponse.getRequestedURI().getHost()); - serviceInstance.setPort(ribbonResponse.getRequestedURI().getPort()); - enhancedPluginContext.setServiceInstance(serviceInstance); // Run post enhanced plugins. - pluginRunner.run(POST, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); } return null; } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPreZuulFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedRouteZuulFilter.java similarity index 73% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPreZuulFilter.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedRouteZuulFilter.java index 65484c131..8d3372335 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPreZuulFilter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedRouteZuulFilter.java @@ -29,46 +29,48 @@ import com.tencent.cloud.common.constant.ContextConstant; import com.tencent.cloud.common.util.ZuulFilterUtils; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponse; import org.springframework.core.env.Environment; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.util.StringUtils; import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_PRE_ROUTE_TIME; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; +import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.RIBBON_ROUTING_FILTER_ORDER; +import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE; /** * Polaris circuit breaker implement in Zuul. * * @author Haotian Zhang */ -public class EnhancedPreZuulFilter extends ZuulFilter { +public class EnhancedRouteZuulFilter extends ZuulFilter { - private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedPreZuulFilter.class); + private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedRouteZuulFilter.class); private final EnhancedPluginRunner pluginRunner; private final Environment environment; - public EnhancedPreZuulFilter(EnhancedPluginRunner pluginRunner, Environment environment) { + public EnhancedRouteZuulFilter(EnhancedPluginRunner pluginRunner, Environment environment) { this.pluginRunner = pluginRunner; this.environment = environment; } @Override public String filterType() { - return PRE_TYPE; + return ROUTE_TYPE; } @Override public int filterOrder() { - return PRE_DECORATION_FILTER_ORDER + 1; + return RIBBON_ROUTING_FILTER_ORDER + 1; } @Override @@ -100,9 +102,24 @@ public class EnhancedPreZuulFilter extends ZuulFilter { .build(); enhancedPluginContext.setRequest(enhancedRequestContext); + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + + Object ribbonResponseObj = context.get("ribbonResponse"); + RibbonApacheHttpResponse ribbonResponse; + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); + if (ribbonResponseObj != null && ribbonResponseObj instanceof RibbonApacheHttpResponse) { + ribbonResponse = (RibbonApacheHttpResponse) ribbonResponseObj; + serviceInstance.setServiceId(ZuulFilterUtils.getServiceId(context)); + serviceInstance.setHost(ribbonResponse.getRequestedURI().getHost()); + serviceInstance.setPort(ribbonResponse.getRequestedURI().getPort()); + enhancedPluginContext.setTargetServiceInstance(serviceInstance, null); + } + else { + enhancedPluginContext.setTargetServiceInstance(null, uri); + } // Run pre enhanced plugins. - pluginRunner.run(PRE, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.PRE, enhancedPluginContext); Object startTimeMilliObject = context.get(POLARIS_PRE_ROUTE_TIME); if (startTimeMilliObject == null || !(startTimeMilliObject instanceof Long)) { diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java index fe02ab397..aca9847ca 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java @@ -23,7 +23,6 @@ import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; 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; -import com.tencent.polaris.api.core.ConsumerAPI; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -55,7 +54,6 @@ public class RpcEnhancementAutoConfigurationTest { @Test public void testDefaultInitialization() { this.contextRunner.run(context -> { - assertThat(context).hasSingleBean(ConsumerAPI.class); assertThat(context).hasSingleBean(EnhancedPluginRunner.class); assertThat(context).hasSingleBean(EnhancedFeignBeanPostProcessor.class); assertThat(context).hasSingleBean(SuccessPolarisReporter.class); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java index 2ff9ff909..8edf80b19 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; @@ -34,6 +35,7 @@ import feign.Target; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -55,6 +57,9 @@ import static org.mockito.Mockito.mock; properties = {"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp", "spring.cloud.gateway.enabled=false"}) public class EnhancedFeignClientTest { + @Autowired + private PolarisSDKContextManager polarisSDKContextManager; + @Test public void testConstructor() { try { @@ -75,7 +80,8 @@ public class EnhancedFeignClientTest { List enhancedPlugins = getMockEnhancedFeignPlugins(); try { - new EnhancedFeignClient(mock(Client.class), new DefaultEnhancedPluginRunner(enhancedPlugins)); + new EnhancedFeignClient(mock(Client.class), + new DefaultEnhancedPluginRunner(enhancedPlugins, null, polarisSDKContextManager.getSDKContext())); } catch (Throwable e) { fail("Exception encountered.", e); @@ -104,7 +110,8 @@ public class EnhancedFeignClientTest { RequestTemplate requestTemplate = new RequestTemplate(); requestTemplate.feignTarget(target); - EnhancedFeignClient polarisFeignClient = new EnhancedFeignClient(delegate, new DefaultEnhancedPluginRunner(getMockEnhancedFeignPlugins())); + EnhancedFeignClient polarisFeignClient = new EnhancedFeignClient(delegate, + new DefaultEnhancedPluginRunner(getMockEnhancedFeignPlugins(), null, polarisSDKContextManager.getSDKContext())); // 200 Response response = polarisFeignClient.execute(Request.create(Request.HttpMethod.GET, "http://localhost:8080/test", @@ -134,7 +141,7 @@ public class EnhancedFeignClientTest { enhancedPlugins.add(new EnhancedPlugin() { @Override public EnhancedPluginType getType() { - return EnhancedPluginType.PRE; + return EnhancedPluginType.Client.PRE; } @Override @@ -156,7 +163,7 @@ public class EnhancedFeignClientTest { enhancedPlugins.add(new EnhancedPlugin() { @Override public EnhancedPluginType getType() { - return EnhancedPluginType.POST; + return EnhancedPluginType.Client.POST; } @Override @@ -178,7 +185,7 @@ public class EnhancedFeignClientTest { enhancedPlugins.add(new EnhancedPlugin() { @Override public EnhancedPluginType getType() { - return EnhancedPluginType.EXCEPTION; + return EnhancedPluginType.Client.EXCEPTION; } @Override @@ -200,7 +207,7 @@ public class EnhancedFeignClientTest { enhancedPlugins.add(new EnhancedPlugin() { @Override public EnhancedPluginType getType() { - return EnhancedPluginType.FINALLY; + return EnhancedPluginType.Client.FINALLY; } @Override diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContextTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContextTest.java index a516483f1..646ee0263 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContextTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContextTest.java @@ -18,13 +18,18 @@ package com.tencent.cloud.rpc.enhancement.plugin; import java.net.URI; +import java.net.URISyntaxException; import java.util.Arrays; +import java.util.Collections; 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.reporter.ExceptionPolarisReporter; import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter; +import com.tencent.polaris.api.config.Configuration; +import com.tencent.polaris.api.config.global.APIConfig; +import com.tencent.polaris.api.config.global.GlobalConfig; import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.client.api.SDKContext; import org.junit.jupiter.api.AfterAll; @@ -38,6 +43,7 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -65,6 +71,8 @@ public class EnhancedPluginContextTest { private SDKContext sdkContext; @Mock private ConsumerAPI consumerAPI; + @Mock + private Registration registration; @BeforeAll static void beforeAll() { @@ -111,24 +119,57 @@ public class EnhancedPluginContextTest { EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext(); enhancedPluginContext.setRequest(requestContext); enhancedPluginContext.setResponse(responseContext); - enhancedPluginContext.setServiceInstance(new DefaultServiceInstance()); + enhancedPluginContext.setTargetServiceInstance(new DefaultServiceInstance(), null); enhancedPluginContext.setThrowable(mock(Exception.class)); enhancedPluginContext.setDelay(0); assertThat(enhancedPluginContext.getRequest()).isNotNull(); assertThat(enhancedPluginContext.getResponse()).isNotNull(); - assertThat(enhancedPluginContext.getServiceInstance()).isNotNull(); + assertThat(enhancedPluginContext.getTargetServiceInstance()).isNotNull(); assertThat(enhancedPluginContext.getThrowable()).isNotNull(); assertThat(enhancedPluginContext.getDelay()).isNotNull(); - EnhancedPlugin enhancedPlugin = new SuccessPolarisReporter(reporterProperties, sdkContext, consumerAPI); - EnhancedPlugin enhancedPlugin1 = new ExceptionPolarisReporter(reporterProperties, sdkContext, consumerAPI); - EnhancedPluginRunner enhancedPluginRunner = new DefaultEnhancedPluginRunner(Arrays.asList(enhancedPlugin, enhancedPlugin1)); - enhancedPluginRunner.run(EnhancedPluginType.POST, enhancedPluginContext); + EnhancedPlugin enhancedPlugin = new SuccessPolarisReporter(reporterProperties, consumerAPI); + EnhancedPlugin enhancedPlugin1 = new ExceptionPolarisReporter(reporterProperties, consumerAPI); + EnhancedPluginRunner enhancedPluginRunner = new DefaultEnhancedPluginRunner(Arrays.asList(enhancedPlugin, enhancedPlugin1), registration, sdkContext); + enhancedPluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); + + assertThat(enhancedPluginRunner.getLocalServiceInstance()).isEqualTo(registration); EnhancedPlugin enhancedPlugin2 = mock(EnhancedPlugin.class); doThrow(new RuntimeException()).when(enhancedPlugin2).run(any()); - doReturn(EnhancedPluginType.POST).when(enhancedPlugin2).getType(); - enhancedPluginRunner = new DefaultEnhancedPluginRunner(Arrays.asList(enhancedPlugin2)); - enhancedPluginRunner.run(EnhancedPluginType.POST, enhancedPluginContext); + doReturn(EnhancedPluginType.Client.POST).when(enhancedPlugin2).getType(); + + APIConfig apiConfig = mock(APIConfig.class); + doReturn("0.0.0.0").when(apiConfig).getBindIP(); + + GlobalConfig globalConfig = mock(GlobalConfig.class); + doReturn(apiConfig).when(globalConfig).getAPI(); + + Configuration configuration = mock(Configuration.class); + doReturn(globalConfig).when(configuration).getGlobal(); + + doReturn(configuration).when(sdkContext).getConfig(); + + enhancedPluginRunner = new DefaultEnhancedPluginRunner(Collections.singletonList(enhancedPlugin2), null, sdkContext); + enhancedPluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); + } + + @Test + public void testSetTargetServiceInstance() throws URISyntaxException { + EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext(); + + // targetServiceInstance != null + DefaultServiceInstance testDefaultServiceInstance = new DefaultServiceInstance(); + testDefaultServiceInstance.setPort(1); + enhancedPluginContext.setTargetServiceInstance(testDefaultServiceInstance, null); + assertThat(enhancedPluginContext.getTargetServiceInstance().getPort()).isEqualTo(1); + + // targetServiceInstance == null && url != null + enhancedPluginContext.setTargetServiceInstance(null, new URI("https://www.qq.com")); + assertThat(enhancedPluginContext.getTargetServiceInstance().getPort()).isEqualTo(443); + + // targetServiceInstance == null && url == null + enhancedPluginContext.setTargetServiceInstance(null, null); + assertThat(enhancedPluginContext.getTargetServiceInstance().getPort()).isEqualTo(0); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java index 21c61ef92..5288b35ce 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java @@ -23,11 +23,7 @@ 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.reporter.ExceptionPolarisReporter; -import com.tencent.polaris.api.config.Configuration; -import com.tencent.polaris.api.config.global.APIConfig; -import com.tencent.polaris.api.config.global.GlobalConfig; import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.client.api.SDKContext; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -40,6 +36,7 @@ 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; @@ -63,8 +60,6 @@ public class ExceptionPolarisReporterTest { private static MockedStatic mockedApplicationContextAwareUtils; @Mock private RpcEnhancementReporterProperties reporterProperties; - @Mock - private SDKContext sdkContext; @InjectMocks private ExceptionPolarisReporter exceptionPolarisReporter; @Mock @@ -75,6 +70,12 @@ public class ExceptionPolarisReporterTest { 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 @@ -95,7 +96,7 @@ public class ExceptionPolarisReporterTest { @Test public void testType() { - assertThat(exceptionPolarisReporter.getType()).isEqualTo(EnhancedPluginType.EXCEPTION); + assertThat(exceptionPolarisReporter.getType()).isEqualTo(EnhancedPluginType.Client.EXCEPTION); } @Test @@ -107,32 +108,23 @@ public class ExceptionPolarisReporterTest { doReturn(true).when(reporterProperties).isEnabled(); - APIConfig apiConfig = mock(APIConfig.class); - doReturn("0.0.0.0").when(apiConfig).getBindIP(); - - GlobalConfig globalConfig = mock(GlobalConfig.class); - doReturn(apiConfig).when(globalConfig).getAPI(); - - Configuration configuration = mock(Configuration.class); - doReturn(globalConfig).when(configuration).getGlobal(); - - doReturn(configuration).when(sdkContext).getConfig(); - 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 serviceInstance = new DefaultServiceInstance(); serviceInstance.setServiceId(SERVICE_PROVIDER); pluginContext.setRequest(request); pluginContext.setResponse(response); - pluginContext.setServiceInstance(serviceInstance); + pluginContext.setTargetServiceInstance(serviceInstance, null); pluginContext.setThrowable(new RuntimeException()); exceptionPolarisReporter.run(pluginContext); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/PolarisEnhancedPluginUtilsTest.java similarity index 55% rename from spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/PolarisEnhancedPluginUtilsTest.java index 825da246f..6b0006da6 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/PolarisEnhancedPluginUtilsTest.java @@ -15,20 +15,19 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.rpc.enhancement; +package com.tencent.cloud.rpc.enhancement.plugin; import java.net.SocketTimeoutException; import java.net.URI; import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.HashMap; import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.constant.RouterConstant; 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.polaris.api.config.Configuration; -import com.tencent.polaris.api.config.global.APIConfig; -import com.tencent.polaris.api.config.global.GlobalConfig; import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; import com.tencent.polaris.api.pojo.RetStatus; import com.tencent.polaris.api.rpc.ServiceCallResult; @@ -43,6 +42,7 @@ 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; @@ -54,12 +54,12 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; /** - * Test For {@link AbstractPolarisReporterAdapter}. + * Test For {@link PolarisEnhancedPluginUtils}. * * @author Elve.Xu 2022/7/11 */ @ExtendWith(MockitoExtension.class) -public class AbstractPolarisReporterAdapterTest { +public class PolarisEnhancedPluginUtilsTest { private static MockedStatic mockedApplicationContextAwareUtils; private final RpcEnhancementReporterProperties reporterProperties = new RpcEnhancementReporterProperties(); @@ -71,6 +71,12 @@ public class AbstractPolarisReporterAdapterTest { 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 @@ -86,25 +92,18 @@ public class AbstractPolarisReporterAdapterTest { @Test public void testServiceCallResult() throws URISyntaxException { - APIConfig apiConfig = mock(APIConfig.class); - doReturn("0.0.0.0").when(apiConfig).getBindIP(); - - GlobalConfig globalConfig = mock(GlobalConfig.class); - doReturn(apiConfig).when(globalConfig).getAPI(); - - Configuration configuration = mock(Configuration.class); - doReturn(globalConfig).when(configuration).getGlobal(); - - doReturn(configuration).when(sdkContext).getConfig(); - - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(reporterProperties, sdkContext); ServiceCallResult serviceCallResult; HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.add(RouterConstant.ROUTER_LABEL_HEADER, "{\"k1\":\"v1\"}"); - serviceCallResult = adapter.createServiceCallResult( + assertThat(PolarisEnhancedPluginUtils.getLabelMap(requestHeaders)).isEqualTo(new HashMap() {{ + put("k1", "v1"); + }}); + + serviceCallResult = PolarisEnhancedPluginUtils.createServiceCallResult( + "0.0.0.0", "test", null, null, @@ -117,7 +116,8 @@ public class AbstractPolarisReporterAdapterTest { ); assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetSuccess); - serviceCallResult = adapter.createServiceCallResult( + serviceCallResult = PolarisEnhancedPluginUtils.createServiceCallResult( + "0.0.0.0", "test", null, null, @@ -130,7 +130,8 @@ public class AbstractPolarisReporterAdapterTest { ); assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetFail); - serviceCallResult = adapter.createServiceCallResult( + serviceCallResult = PolarisEnhancedPluginUtils.createServiceCallResult( + "0.0.0.0", "test", null, null, @@ -143,7 +144,8 @@ public class AbstractPolarisReporterAdapterTest { ); assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetTimeout); - serviceCallResult = adapter.createServiceCallResult( + serviceCallResult = PolarisEnhancedPluginUtils.createServiceCallResult( + "0.0.0.0", "test", "0.0.0.0", 8080, @@ -162,11 +164,9 @@ public class AbstractPolarisReporterAdapterTest { @Test public void testResourceStat() throws URISyntaxException { - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(reporterProperties, sdkContext); - ResourceStat resourceStat; - resourceStat = adapter.createInstanceResourceStat("test", + resourceStat = PolarisEnhancedPluginUtils.createInstanceResourceStat("test", null, null, new URI("http://0.0.0.0/"), @@ -176,7 +176,7 @@ public class AbstractPolarisReporterAdapterTest { ); assertThat(resourceStat.getRetStatus()).isEqualTo(RetStatus.RetSuccess); - resourceStat = adapter.createInstanceResourceStat("test", + resourceStat = PolarisEnhancedPluginUtils.createInstanceResourceStat("test", null, null, new URI("http://0.0.0.0/"), @@ -186,7 +186,7 @@ public class AbstractPolarisReporterAdapterTest { ); assertThat(resourceStat.getRetStatus()).isEqualTo(RetStatus.RetTimeout); - resourceStat = adapter.createInstanceResourceStat("test", + resourceStat = PolarisEnhancedPluginUtils.createInstanceResourceStat("test", null, null, new URI("http://0.0.0.0/"), @@ -200,13 +200,32 @@ public class AbstractPolarisReporterAdapterTest { @Test public void testApplyWithDefaultConfig() { RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); - // Mock Condition - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); + // Assert + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); + } + + @Test + public void testApplyWithHttpStatus() { + RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); + properties.setStatuses(Arrays.asList(HttpStatus.BAD_GATEWAY, HttpStatus.INTERNAL_SERVER_ERROR)); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); // Assert - assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(null)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); } @Test @@ -216,12 +235,16 @@ public class AbstractPolarisReporterAdapterTest { properties.getStatuses().clear(); properties.setIgnoreInternalServerError(false); - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); // Assert - assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(true); - assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); } @Test @@ -231,12 +254,16 @@ public class AbstractPolarisReporterAdapterTest { properties.getStatuses().clear(); properties.setIgnoreInternalServerError(true); - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); // Assert - assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); } @Test @@ -246,12 +273,16 @@ public class AbstractPolarisReporterAdapterTest { properties.getStatuses().clear(); properties.getSeries().clear(); - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); // Assert - assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); } @Test @@ -262,65 +293,46 @@ public class AbstractPolarisReporterAdapterTest { properties.getSeries().clear(); properties.getSeries().add(HttpStatus.Series.CLIENT_ERROR); - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); // Assert - assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.FORBIDDEN)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.FORBIDDEN)).isEqualTo(true); } @Test public void testGetRetStatusFromRequest() { - RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); - // Mock Condition - properties.getStatuses().clear(); - properties.getSeries().clear(); - properties.getSeries().add(HttpStatus.Series.CLIENT_ERROR); - - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); HttpHeaders headers = new HttpHeaders(); - RetStatus ret = adapter.getRetStatusFromRequest(headers, RetStatus.RetFail); + RetStatus ret = PolarisEnhancedPluginUtils.getRetStatusFromRequest(headers, RetStatus.RetFail); assertThat(ret).isEqualTo(RetStatus.RetFail); headers.set(HeaderConstant.INTERNAL_CALLEE_RET_STATUS, RetStatus.RetFlowControl.getDesc()); - ret = adapter.getRetStatusFromRequest(headers, RetStatus.RetFail); + ret = PolarisEnhancedPluginUtils.getRetStatusFromRequest(headers, RetStatus.RetFail); assertThat(ret).isEqualTo(RetStatus.RetFlowControl); headers.set(HeaderConstant.INTERNAL_CALLEE_RET_STATUS, RetStatus.RetReject.getDesc()); - ret = adapter.getRetStatusFromRequest(headers, RetStatus.RetFail); + ret = PolarisEnhancedPluginUtils.getRetStatusFromRequest(headers, RetStatus.RetFail); assertThat(ret).isEqualTo(RetStatus.RetReject); } @Test public void testGetActiveRuleNameFromRequest() { - RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); - // Mock Condition - properties.getStatuses().clear(); - properties.getSeries().clear(); - properties.getSeries().add(HttpStatus.Series.CLIENT_ERROR); - - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); HttpHeaders headers = new HttpHeaders(); - String ruleName = adapter.getActiveRuleNameFromRequest(headers); + String ruleName = PolarisEnhancedPluginUtils.getActiveRuleNameFromRequest(headers); assertThat(ruleName).isEqualTo(""); headers.set(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, "mock_rule"); - ruleName = adapter.getActiveRuleNameFromRequest(headers); + ruleName = PolarisEnhancedPluginUtils.getActiveRuleNameFromRequest(headers); assertThat(ruleName).isEqualTo("mock_rule"); } - /** - * Simple Polaris CircuitBreak Adapter Implements . - */ - public static class SimplePolarisReporterAdapter extends AbstractPolarisReporterAdapter { - - protected SimplePolarisReporterAdapter(RpcEnhancementReporterProperties reportProperties, SDKContext context) { - super(reportProperties, context); - } - } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java index 9af4ca019..bb82ce8c3 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java @@ -23,11 +23,7 @@ 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.reporter.SuccessPolarisReporter; -import com.tencent.polaris.api.config.Configuration; -import com.tencent.polaris.api.config.global.APIConfig; -import com.tencent.polaris.api.config.global.GlobalConfig; import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.client.api.SDKContext; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -40,6 +36,7 @@ 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.HttpMethod; import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; @@ -60,8 +57,6 @@ import static org.mockito.Mockito.verify; public class SuccessPolarisReporterTest { private static MockedStatic mockedApplicationContextAwareUtils; @Mock - private SDKContext sdkContext; - @Mock private RpcEnhancementReporterProperties reporterProperties; @InjectMocks private SuccessPolarisReporter successPolarisReporter; @@ -73,6 +68,12 @@ public class SuccessPolarisReporterTest { 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 @@ -93,7 +94,7 @@ public class SuccessPolarisReporterTest { @Test public void testType() { - assertThat(successPolarisReporter.getType()).isEqualTo(EnhancedPluginType.POST); + assertThat(successPolarisReporter.getType()).isEqualTo(EnhancedPluginType.Client.POST); } @Test @@ -105,31 +106,23 @@ public class SuccessPolarisReporterTest { verify(context, times(0)).getRequest(); doReturn(true).when(reporterProperties).isEnabled(); - APIConfig apiConfig = mock(APIConfig.class); - doReturn("0.0.0.0").when(apiConfig).getBindIP(); - - GlobalConfig globalConfig = mock(GlobalConfig.class); - doReturn(apiConfig).when(globalConfig).getAPI(); - - Configuration configuration = mock(Configuration.class); - doReturn(globalConfig).when(configuration).getGlobal(); - - doReturn(configuration).when(sdkContext).getConfig(); EnhancedPluginContext pluginContext = new EnhancedPluginContext(); EnhancedRequestContext request = EnhancedRequestContext.builder() .httpMethod(HttpMethod.GET) .url(URI.create("http://0.0.0.0/")) .build(); + request.toString(); EnhancedResponseContext response = EnhancedResponseContext.builder() .httpStatus(200) .build(); + response.toString(); DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); serviceInstance.setServiceId(SERVICE_PROVIDER); pluginContext.setRequest(request); pluginContext.setResponse(response); - pluginContext.setServiceInstance(serviceInstance); + pluginContext.setTargetServiceInstance(serviceInstance, null); successPolarisReporter.run(pluginContext); successPolarisReporter.getOrder(); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptorTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptorTest.java index 6b256f014..10bcbab69 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptorTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptorTest.java @@ -40,6 +40,7 @@ import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -65,6 +66,8 @@ public class EnhancedRestTemplateInterceptorTest { @Mock private SDKContext sdkContext; @Mock + Registration registration; + @Mock private ClientHttpRequestExecution mockClientHttpRequestExecution; @Mock private ClientHttpResponse mockClientHttpResponse; @@ -109,7 +112,7 @@ public class EnhancedRestTemplateInterceptorTest { doReturn(mockHttpHeaders).when(mockHttpRequest).getHeaders(); doReturn(mockClientHttpResponse).when(mockClientHttpRequestExecution).execute(mockHttpRequest, inputBody); - EnhancedRestTemplateInterceptor reporter = new EnhancedRestTemplateInterceptor(new DefaultEnhancedPluginRunner(new ArrayList<>())); + EnhancedRestTemplateInterceptor reporter = new EnhancedRestTemplateInterceptor(new DefaultEnhancedPluginRunner(new ArrayList<>(), registration, null)); actualResult = reporter.intercept(mockHttpRequest, inputBody, mockClientHttpRequestExecution); assertThat(actualResult).isEqualTo(mockClientHttpResponse); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformerTest.java similarity index 79% rename from spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformerTest.java index 82bf173ba..4ae6084ad 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformerTest.java @@ -17,13 +17,11 @@ package com.tencent.cloud.rpc.enhancement.resttemplate; -import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.ApplicationContextAwareUtils; -import org.aspectj.lang.ProceedingJoinPoint; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -36,7 +34,9 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.client.ServiceInstance; import org.springframework.context.ApplicationContext; +import org.springframework.http.HttpRequest; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; 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; @@ -45,13 +45,16 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @ExtendWith(MockitoExtension.class) -public class BlockingLoadBalancerClientAspectTest { - +public class PolarisLoadBalancerRequestTransformerTest { private static MockedStatic mockedApplicationContextAwareUtils; + + private PolarisLoadBalancerRequestTransformer transformer = new PolarisLoadBalancerRequestTransformer(); + @Mock - private ProceedingJoinPoint proceedingJoinPoint; + private HttpRequest clientRequest; - private BlockingLoadBalancerClientAspect aspect = new BlockingLoadBalancerClientAspect(); + @Mock + private ServiceInstance serviceInstance; @BeforeAll static void beforeAll() { @@ -79,14 +82,8 @@ public class BlockingLoadBalancerClientAspectTest { @Test public void test() throws Throwable { - ServiceInstance serviceInstance = mock(ServiceInstance.class); - doReturn("0.0.0.0").when(serviceInstance).getHost(); - doReturn(80).when(serviceInstance).getPort(); - doReturn(new Object[]{ serviceInstance }).when(proceedingJoinPoint).getArgs(); - aspect.invoke(proceedingJoinPoint); - aspect.pointcut(); - assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST)).isEqualTo("0.0.0.0"); - assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT)).isEqualTo("80"); + transformer.transformRequest(clientRequest, serviceInstance); + assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE)).isEqualTo(serviceInstance); } - } + diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java index 69867c6ab..397068162 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java @@ -39,6 +39,7 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import reactor.core.publisher.Mono; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.route.Route; import org.springframework.context.ApplicationContext; @@ -62,6 +63,8 @@ public class EnhancedGatewayGlobalFilterTest { private static MockedStatic mockedApplicationContextAwareUtils; @Mock + Registration registration; + @Mock ServerWebExchange exchange; @Mock GatewayFilterChain chain; @@ -115,7 +118,7 @@ public class EnhancedGatewayGlobalFilterTest { doReturn(request).when(exchange).getRequest(); doReturn(response).when(exchange).getResponse(); - EnhancedGatewayGlobalFilter reporter = new EnhancedGatewayGlobalFilter(new DefaultEnhancedPluginRunner(new ArrayList<>())); + EnhancedGatewayGlobalFilter reporter = new EnhancedGatewayGlobalFilter(new DefaultEnhancedPluginRunner(new ArrayList<>(), registration, null)); reporter.getOrder(); reporter.filter(exchange, chain).block(); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifierTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifierTest.java index fbfdcc9f2..52c125ebf 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifierTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifierTest.java @@ -17,8 +17,9 @@ package com.tencent.cloud.rpc.enhancement.stat.config; -import com.tencent.polaris.client.api.SDKContext; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.polaris.plugins.stat.prometheus.handler.PrometheusHandlerConfig; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -62,11 +63,17 @@ public class StatConfigModifierTest { .withPropertyValues("spring.application.name=test") .withPropertyValues("spring.cloud.gateway.enabled=false"); + @BeforeEach + void setUp() { + PolarisSDKContextManager.innerDestroy(); + } + @Test void testPull() { pullContextRunner.run(context -> { - SDKContext sdkContext = context.getBean(SDKContext.class); - PrometheusHandlerConfig prometheusHandlerConfig = sdkContext.getConfig().getGlobal().getStatReporter() + PolarisSDKContextManager polarisSDKContextManager = context.getBean(PolarisSDKContextManager.class); + PrometheusHandlerConfig prometheusHandlerConfig = polarisSDKContextManager.getSDKContext().getConfig() + .getGlobal().getStatReporter() .getPluginConfig(DEFAULT_REPORTER_PROMETHEUS, PrometheusHandlerConfig.class); assertThat(prometheusHandlerConfig.getType()).isEqualTo("pull"); assertThat(prometheusHandlerConfig.getHost()).isEqualTo("127.0.0.1"); @@ -78,8 +85,9 @@ public class StatConfigModifierTest { @Test void testPush() { pushContextRunner.run(context -> { - SDKContext sdkContext = context.getBean(SDKContext.class); - PrometheusHandlerConfig prometheusHandlerConfig = sdkContext.getConfig().getGlobal().getStatReporter() + PolarisSDKContextManager polarisSDKContextManager = context.getBean(PolarisSDKContextManager.class); + PrometheusHandlerConfig prometheusHandlerConfig = polarisSDKContextManager.getSDKContext().getConfig() + .getGlobal().getStatReporter() .getPluginConfig(DEFAULT_REPORTER_PROMETHEUS, PrometheusHandlerConfig.class); assertThat(prometheusHandlerConfig.getType()).isEqualTo("push"); assertThat(prometheusHandlerConfig.getAddress()).isEqualTo("127.0.0.1:9091"); @@ -90,8 +98,9 @@ public class StatConfigModifierTest { @Test void testDisabled() { disabledContextRunner.run(context -> { - SDKContext sdkContext = context.getBean(SDKContext.class); - PrometheusHandlerConfig prometheusHandlerConfig = sdkContext.getConfig().getGlobal().getStatReporter() + PolarisSDKContextManager polarisSDKContextManager = context.getBean(PolarisSDKContextManager.class); + PrometheusHandlerConfig prometheusHandlerConfig = polarisSDKContextManager.getSDKContext().getConfig() + .getGlobal().getStatReporter() .getPluginConfig(DEFAULT_REPORTER_PROMETHEUS, PrometheusHandlerConfig.class); assertThat(prometheusHandlerConfig.getPort()).isEqualTo(-1); }); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientExchangeFilterFunctionTest.java similarity index 91% rename from spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientExchangeFilterFunctionTest.java index f8a4a673a..4801e4cb2 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientExchangeFilterFunctionTest.java @@ -39,9 +39,11 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import reactor.core.publisher.Mono; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ExchangeFunction; @@ -56,7 +58,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @ExtendWith(MockitoExtension.class) -public class EnhancedWebClientReporterTest { +public class EnhancedWebClientExchangeFilterFunctionTest { private static MockedStatic mockedApplicationContextAwareUtils; @Mock @@ -64,6 +66,8 @@ public class EnhancedWebClientReporterTest { @Mock private SDKContext sdkContext; @Mock + private Registration registration; + @Mock private ClientRequest clientRequest; @Mock private ExchangeFunction exchangeFunction; @@ -101,9 +105,10 @@ public class EnhancedWebClientReporterTest { doReturn(HttpMethod.GET).when(clientRequest).method(); ClientResponse.Headers headers = mock(ClientResponse.Headers.class); doReturn(headers).when(clientResponse).headers(); + doReturn(HttpStatus.valueOf(200)).when(clientResponse).statusCode(); doReturn(Mono.just(clientResponse)).when(exchangeFunction).exchange(any()); - EnhancedWebClientReporter reporter = new EnhancedWebClientReporter(new DefaultEnhancedPluginRunner(new ArrayList<>())); + EnhancedWebClientExchangeFilterFunction reporter = new EnhancedWebClientExchangeFilterFunction(new DefaultEnhancedPluginRunner(new ArrayList<>(), registration, null)); ClientResponse clientResponse1 = reporter.filter(clientRequest, exchangeFunction).block(); assertThat(clientResponse1).isEqualTo(clientResponse); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java index 811b7c5eb..7b7c4e0d5 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java @@ -17,7 +17,6 @@ package com.tencent.cloud.rpc.enhancement.webclient; -import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.StaticMetadataManager; @@ -37,6 +36,7 @@ import org.springframework.cloud.client.ServiceInstance; import org.springframework.context.ApplicationContext; import org.springframework.web.reactive.function.client.ClientRequest; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; 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; @@ -83,8 +83,7 @@ public class PolarisLoadBalancerClientRequestTransformerTest { @Test public void test() throws Throwable { - doReturn("test").when(serviceInstance).getServiceId(); transformer.transformRequest(clientRequest, serviceInstance); - assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID)).isEqualTo("test"); + assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE)).isEqualTo(serviceInstance); } }