From baabb69be3b777c3df58994ac5a70948430c71bb Mon Sep 17 00:00:00 2001 From: SkyeBeFreeman <928016560@qq.com> Date: Fri, 25 Mar 2022 15:56:11 +0800 Subject: [PATCH] feat:optimize project structure and checkstyle --- .editorconfig | 28 ++ pom.xml | 414 ++++++++++-------- .../pom.xml | 68 +++ .../PolarisFeignClientAutoConfiguration.java | 65 +-- .../feign/PolarisFeignBeanPostProcessor.java | 97 ++++ ...olarisFeignBlockingLoadBalancerClient.java | 14 +- .../feign/PolarisFeignClient.java | 104 +++++ .../feign/PolarisLoadBalancerFeignClient.java | 14 +- .../spring-configuration-metadata.json | 2 +- .../main/resources/META-INF/spring.factories | 2 +- .../feign/PolarisFeignClientTest.java | 51 ++- .../feign/TestPolarisFeignApp.java | 43 +- .../src/test/resources/application.yml | 2 +- .../pom.xml | 34 +- .../cloud/polaris/PolarisProperties.java | 231 ++++++++++ .../cloud/polaris/client/PolarisClient.java | 22 +- .../ConditionalOnPolarisDiscoveryEnabled.java | 6 +- .../PolarisDiscoveryAutoConfiguration.java | 58 +-- .../discovery/PolarisDiscoveryClient.java | 41 +- .../PolarisDiscoveryClientConfiguration.java | 13 +- .../discovery/PolarisDiscoveryHandler.java | 113 +++++ .../discovery/PolarisServiceDiscovery.java | 71 +++ .../PolarisReactiveDiscoveryClient.java | 88 ++++ ...sReactiveDiscoveryClientConfiguration.java | 19 +- .../PolarisAutoServiceRegistration.java | 98 +++++ .../polaris/registry/PolarisRegistration.java | 93 ++++ .../registry/PolarisServiceRegistry.java | 213 +++++++++ ...larisServiceRegistryAutoConfiguration.java | 54 ++- ...larisDiscoveryRibbonAutoConfiguration.java | 1 + .../PolarisRibbonServerListConfiguration.java | 19 +- .../polaris/ribbon/PolarisServerList.java | 69 +-- .../cloud/polaris/util/OkHttpUtil.java | 99 +++++ ...itional-spring-configuration-metadata.json | 0 .../main/resources/META-INF/spring.factories | 1 - .../cloud/polaris/PolarisPropertiesTest.java | 56 ++- ...PolarisDiscoveryAutoConfigurationTest.java | 79 ++-- ...larisDiscoveryClientConfigurationTest.java | 82 ++-- .../discovery/PolarisDiscoveryClientTest.java | 57 ++- .../PolarisServiceDiscoveryTest.java | 118 +++++ ...ctiveDiscoveryClientConfigurationTest.java | 72 +-- .../PolarisReactiveDiscoveryClientTest.java | 62 +-- ...sServiceRegistryAutoConfigurationTest.java | 77 ++-- .../registry/PolarisServiceRegistryTest.java | 120 +++++ ...arisRibbonServerListConfigurationTest.java | 89 ++-- .../polaris/ribbon/PolarisServerListTest.java | 145 ++++++ .../pom.xml | 94 ++++ .../config}/RateLimitConfiguration.java | 89 ++-- .../ratelimit/constant/RateLimitConstant.java | 33 +- .../filter/QuotaCheckReactiveFilter.java | 106 +++++ .../filter/QuotaCheckServletFilter.java | 97 ++++ .../ratelimit/utils/QuotaCheckUtils.java | 54 ++- ...itional-spring-configuration-metadata.json | 0 .../main/resources/META-INF/spring.factories | 2 + .../controller/CalleeControllerTests.java | 150 +++++++ .../ratelimit/controller/TestController.java | 15 +- .../pom.xml | 38 +- .../router/PolarisRoutingLoadBalancer.java | 138 ++++++ .../PolarisRibbonAutoConfiguration.java | 25 +- .../PolarisRibbonClientConfiguration.java | 35 +- .../config/PolarisRibbonProperties.java | 59 +-- .../router/rule/PolarisLoadBalanceRule.java | 49 +-- .../rule/PolarisWeightedRandomRule.java | 60 +-- ...itional-spring-configuration-metadata.json | 0 .../main/resources/META-INF/spring.factories | 0 .../PolarisRibbonAutoConfigurationTest.java | 47 +- spring-cloud-tencent-commons/pom.xml | 79 ++++ .../common/constant/ContextConstant.java | 46 +- .../cloud/common/pojo/PolarisServer.java | 111 +++++ .../common/pojo/PolarisServiceInstance.java | 93 ++++ .../util/ApplicationContextAwareUtils.java | 64 ++- .../cloud/common/util/JacksonUtils.java | 84 ++++ .../cloud/common/util/ReflectionUtils.java | 39 +- .../main/resources/META-INF/spring.factories | 1 - spring-cloud-tencent-coverage/pom.xml | 9 +- spring-cloud-tencent-dependencies/pom.xml | 12 - .../circuitbreaker/example/ProviderB.java | 16 +- .../example/ProviderBFallback.java | 8 +- .../circuitbreaker/example/ServiceA.java | 14 +- .../example/ServiceAController.java | 60 ++- .../src/main/resources/bootstrap.yml | 2 +- .../src/main/resources/polaris.yml | 7 +- .../circuitbreaker/example/ProviderA.java | 16 +- .../example/ProviderAFallback.java | 9 +- .../circuitbreaker/example/ServiceB.java | 16 +- .../example/ServiceBController.java | 63 ++- .../src/main/resources/bootstrap.yml | 2 +- .../discovery-callee-service/pom.xml | 20 +- .../callee/DiscoveryCalleeController.java | 46 +- .../callee/DiscoveryCalleeService.java | 9 +- .../src/main/resources/bootstrap.yml | 30 +- .../src/main/resources/log4j.properties | 2 +- .../src/main/resources/polaris.yml | 2 +- .../discovery-caller-service/pom.xml | 28 +- .../caller/DiscoveryCalleeService.java | 21 +- .../DiscoveryCalleeServiceCallback.java | 9 +- .../caller/DiscoveryCallerController.java | 65 ++- .../caller/DiscoveryCallerService.java | 16 +- .../src/main/resources/bootstrap.yml | 34 +- .../src/main/resources/log4j.properties | 2 +- .../src/main/resources/polaris.yml | 2 +- .../gateway-callee-service/pom.xml | 44 +- .../callee/GatewayCalleeApplication.java | 6 +- .../callee/GatewayCalleeController.java | 52 ++- .../src/main/resources/application.yml | 2 +- .../gateway-scg-service/pom.xml | 52 +-- .../example/scg/GatewayScgApplication.java | 6 +- .../src/main/resources/application.yml | 6 +- .../gateway-zuul-service/pom.xml | 56 +-- .../example/zuul/GatewayZuulApplication.java | 6 +- .../service/callee/BusinessController.java | 70 +-- .../callee/RateLimitCalleeService.java | 19 +- .../src/main/resources/bootstrap.yml | 2 +- .../src/main/resources/log4j.properties | 2 +- .../src/main/resources/rule.json | 2 +- spring-cloud-tencent-metadata/pom.xml | 68 +++ .../config/MetadataConfiguration.java | 247 +++++++++++ .../config/MetadataLocalProperties.java | 59 +-- .../metadata/constant/MetadataConstant.java | 122 ++++++ .../metadata/context/MetadataContext.java | 87 ++++ .../context/MetadataContextHolder.java | 142 ++++++ .../gateway/scg/Metadata2HeaderScgFilter.java | 83 ++++ .../gateway/scg/MetadataFirstScgFilter.java | 77 ++++ .../zuul}/Metadata2HeaderZuulFilter.java | 83 ++-- .../zuul}/MetadataFirstZuulFilter.java | 60 +-- .../filter/web/MetadataReactiveFilter.java | 100 +++++ .../filter/web/MetadataServletFilter.java | 97 ++++ .../Metadata2HeaderFeignInterceptor.java | 89 ++++ .../feign/MetadataFirstFeignInterceptor.java | 56 +++ .../MetadataRestTemplateInterceptor.java | 85 ++++ ...itional-spring-configuration-metadata.json | 0 .../main/resources/META-INF/spring.factories | 1 - .../config/MetadataConfigurationTest.java | 157 +++++++ .../config/MetadataLocalPropertiesTest.java | 44 +- .../context/MetadataContextHolderTest.java | 87 ++++ .../web}/MetadataReactiveFilterTest.java | 71 +-- .../web}/MetadataServletFilterTest.java | 66 +-- .../Metadata2HeaderFeignInterceptorTest.java | 123 ++++++ .../MetadataRestTemplateInterceptorTest.java | 101 +++-- .../src/test/resources/application-test.yml | 15 + .../pom.xml | 36 +- .../context/PolarisConfigModifier.java | 23 +- .../context/PolarisContextConfiguration.java | 87 ++-- .../context/PolarisContextProperties.java | 95 ++-- .../consul/ConsulContextProperties.java | 144 ++++++ .../spring-configuration-metadata.json | 0 .../main/resources/META-INF/spring.factories | 0 .../context/PolarisContextApplication.java | 0 .../PolarisContextConfigurationTest.java | 23 +- .../context/PolarisContextGetHostTest.java | 22 +- .../src/test/resources/application-test.yml | 0 spring-cloud-tencent-starters/pom.xml | 54 --- .../pom.xml | 62 --- .../feign/PolarisFeignBeanPostProcessor.java | 91 ---- .../feign/PolarisFeignClient.java | 94 ---- .../cloud/polaris/PolarisProperties.java | 269 ------------ .../discovery/PolarisDiscoveryHandler.java | 112 ----- .../discovery/PolarisServiceDiscovery.java | 80 ---- .../PolarisReactiveDiscoveryClient.java | 84 ---- .../PolarisAutoServiceRegistration.java | 95 ---- .../polaris/registry/PolarisRegistration.java | 92 ---- .../registry/PolarisServiceRegistry.java | 200 --------- .../cloud/polaris/util/OkHttpUtil.java | 83 ---- .../PolarisServiceDiscoveryTest.java | 107 ----- .../registry/PolarisServiceRegistryTest.java | 107 ----- .../polaris/ribbon/PolarisServerListTest.java | 133 ------ .../pom.xml | 88 ---- .../ratelimit/callee/QuotaCheckFilter.java | 87 ---- .../cloud/polaris/ratelimit/utils/Consts.java | 26 -- .../main/resources/META-INF/spring.factories | 2 - .../controller/CalleeControllerTests.java | 137 ------ .../router/PolarisRoutingLoadBalancer.java | 124 ------ .../spring-cloud-tencent-commons/pom.xml | 74 ---- .../cloud/polaris/pojo/PolarisServer.java | 109 ----- .../polaris/pojo/PolarisServiceInstance.java | 90 ---- .../spring-cloud-tencent-feign/pom.xml | 30 -- .../tencent/cloud/feign/PluggableFeign.java | 158 ------- .../PluggableFeignAutoConfiguration.java | 43 -- .../cloud/feign/PluggableFeignContext.java | 124 ------ .../feign/PluggableFeignContractHolder.java | 53 --- .../PluggableFeignInvocationHandler.java | 172 -------- .../cloud/feign/PluggableFeignPluginType.java | 42 -- ...itional-spring-configuration-metadata.json | 10 - .../main/resources/META-INF/spring.factories | 2 - .../spring-cloud-tencent-metadata/pom.xml | 68 --- .../config/MetadataConfiguration.java | 187 -------- .../metadata/constant/MetadataConstant.java | 111 ----- .../metadata/context/MetadataContext.java | 87 ---- .../context/MetadataContextHolder.java | 133 ------ .../core/filter/MetadataReactiveFilter.java | 90 ---- .../core/filter/MetadataServletFilter.java | 85 ---- .../Metadata2HeaderFeignInterceptor.java | 80 ---- .../MetadataRestTemplateInterceptor.java | 75 ---- .../feign/MetadataFirstFeignPlugin.java | 75 ---- .../cloud/metadata/util/JacksonUtils.java | 74 ---- .../cloud/metadata/util/MetadataUtils.java | 60 --- .../config/MetadataConfigurationTest.java | 126 ------ .../context/MetadataContextHolderTest.java | 86 ---- .../Metadata2HeaderFeignInterceptorTest.java | 106 ----- .../src/test/resources/application-test.yml | 11 - .../consul/ConsulContextProperties.java | 126 ------ .../pom.xml | 47 -- .../PolarisGatewayAutoConfiguration.java | 90 ---- .../core/route/DynamicRouteService.java | 103 ----- .../core/scg/filter/AbstractGlobalFilter.java | 49 --- .../scg/filter/DynamicRouteScgFilter.java | 98 ----- .../scg/filter/Metadata2HeaderScgFilter.java | 79 ---- .../scg/filter/MetadataFirstScgFilter.java | 68 --- .../core/scg/filter/RateLimitScgFilter.java | 103 ----- .../core/zuul/filter/RateLimitZuulFilter.java | 99 ----- .../main/resources/META-INF/spring.factories | 2 - src/checkstyle/checkstyle-suppressions.xml | 7 + 211 files changed, 6423 insertions(+), 7143 deletions(-) create mode 100644 .editorconfig create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker => spring-cloud-starter-tencent-polaris-circuitbreaker}/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfiguration.java (65%) create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker => spring-cloud-starter-tencent-polaris-circuitbreaker}/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java (76%) create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker => spring-cloud-starter-tencent-polaris-circuitbreaker}/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java (80%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker => spring-cloud-starter-tencent-polaris-circuitbreaker}/src/main/resources/META-INF/spring-configuration-metadata.json (99%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker => spring-cloud-starter-tencent-polaris-circuitbreaker}/src/main/resources/META-INF/spring.factories (89%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker => spring-cloud-starter-tencent-polaris-circuitbreaker}/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java (63%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker => spring-cloud-starter-tencent-polaris-circuitbreaker}/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/TestPolarisFeignApp.java (64%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker => spring-cloud-starter-tencent-polaris-circuitbreaker}/src/test/resources/application.yml (86%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/pom.xml (73%) create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/java/com/tencent/cloud/polaris/client/PolarisClient.java (86%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java (94%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java (60%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java (60%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java (84%) create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java (79%) create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java (61%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisDiscoveryRibbonAutoConfiguration.java (99%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfiguration.java (77%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisServerList.java (52%) create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/resources/META-INF/additional-spring-configuration-metadata.json (100%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/main/resources/META-INF/spring.factories (99%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/test/java/com/tencent/cloud/polaris/PolarisPropertiesTest.java (68%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java (55%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java (53%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java (65%) create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java (57%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientTest.java (62%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery => spring-cloud-starter-tencent-polaris-discovery}/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java (58%) create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java rename spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListAutoConfigurationTest.java => spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java (52%) create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java create mode 100644 spring-cloud-starter-tencent-polaris-ratelimit/pom.xml rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit => spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config}/RateLimitConfiguration.java (50%) rename spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignPlugin.java => spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java (65%) create mode 100644 spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java create mode 100644 spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit => spring-cloud-starter-tencent-polaris-ratelimit}/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java (54%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit => spring-cloud-starter-tencent-polaris-ratelimit}/src/main/resources/META-INF/additional-spring-configuration-metadata.json (100%) create mode 100644 spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories create mode 100644 spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit => spring-cloud-starter-tencent-polaris-ratelimit}/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java (87%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router => spring-cloud-starter-tencent-polaris-router}/pom.xml (59%) create mode 100644 spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRoutingLoadBalancer.java rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router => spring-cloud-starter-tencent-polaris-router}/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfiguration.java (82%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router => spring-cloud-starter-tencent-polaris-router}/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonClientConfiguration.java (69%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router => spring-cloud-starter-tencent-polaris-router}/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonProperties.java (54%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router => spring-cloud-starter-tencent-polaris-router}/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisLoadBalanceRule.java (61%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router => spring-cloud-starter-tencent-polaris-router}/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisWeightedRandomRule.java (54%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router => spring-cloud-starter-tencent-polaris-router}/src/main/resources/META-INF/additional-spring-configuration-metadata.json (100%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router => spring-cloud-starter-tencent-polaris-router}/src/main/resources/META-INF/spring.factories (100%) rename {spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router => spring-cloud-starter-tencent-polaris-router}/src/test/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfigurationTest.java (62%) create mode 100644 spring-cloud-tencent-commons/pom.xml rename {spring-cloud-tencent-starters/spring-cloud-tencent-commons => spring-cloud-tencent-commons}/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java (65%) create mode 100644 spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServer.java create mode 100644 spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.java rename {spring-cloud-tencent-starters/spring-cloud-tencent-commons => spring-cloud-tencent-commons}/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java (52%) create mode 100644 spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java rename {spring-cloud-tencent-starters/spring-cloud-tencent-commons => spring-cloud-tencent-commons}/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java (63%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-commons => spring-cloud-tencent-commons}/src/main/resources/META-INF/spring.factories (99%) create mode 100644 spring-cloud-tencent-metadata/pom.xml create mode 100644 spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataConfiguration.java rename {spring-cloud-tencent-starters/spring-cloud-tencent-metadata => spring-cloud-tencent-metadata}/src/main/java/com/tencent/cloud/metadata/config/MetadataLocalProperties.java (62%) create mode 100644 spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/constant/MetadataConstant.java create mode 100644 spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContext.java create mode 100644 spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContextHolder.java create mode 100644 spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/scg/Metadata2HeaderScgFilter.java create mode 100644 spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/scg/MetadataFirstScgFilter.java rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter => spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/zuul}/Metadata2HeaderZuulFilter.java (53%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter => spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/zuul}/MetadataFirstZuulFilter.java (55%) create mode 100644 spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/web/MetadataReactiveFilter.java create mode 100644 spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/web/MetadataServletFilter.java create mode 100644 spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/Metadata2HeaderFeignInterceptor.java create mode 100644 spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/MetadataFirstFeignInterceptor.java create mode 100644 spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/resttemplate/MetadataRestTemplateInterceptor.java rename {spring-cloud-tencent-starters/spring-cloud-tencent-metadata => spring-cloud-tencent-metadata}/src/main/resources/META-INF/additional-spring-configuration-metadata.json (100%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-metadata => spring-cloud-tencent-metadata}/src/main/resources/META-INF/spring.factories (99%) create mode 100644 spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataConfigurationTest.java rename {spring-cloud-tencent-starters/spring-cloud-tencent-metadata => spring-cloud-tencent-metadata}/src/test/java/com/tencent/cloud/metadata/config/MetadataLocalPropertiesTest.java (60%) create mode 100644 spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/context/MetadataContextHolderTest.java rename {spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter => spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/web}/MetadataReactiveFilterTest.java (51%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter => spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/web}/MetadataServletFilterTest.java (55%) create mode 100644 spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/feign/Metadata2HeaderFeignInterceptorTest.java rename {spring-cloud-tencent-starters/spring-cloud-tencent-metadata => spring-cloud-tencent-metadata}/src/test/java/com/tencent/cloud/metadata/core/intercepter/resttemplate/MetadataRestTemplateInterceptorTest.java (50%) create mode 100644 spring-cloud-tencent-metadata/src/test/resources/application-test.yml rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context => spring-cloud-tencent-polaris-context}/pom.xml (79%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context => spring-cloud-tencent-polaris-context}/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java (80%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context => spring-cloud-tencent-polaris-context}/src/main/java/com/tencent/cloud/polaris/context/PolarisContextConfiguration.java (50%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context => spring-cloud-tencent-polaris-context}/src/main/java/com/tencent/cloud/polaris/context/PolarisContextProperties.java (52%) create mode 100644 spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/extend/consul/ConsulContextProperties.java rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context => spring-cloud-tencent-polaris-context}/src/main/resources/META-INF/spring-configuration-metadata.json (100%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context => spring-cloud-tencent-polaris-context}/src/main/resources/META-INF/spring.factories (100%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context => spring-cloud-tencent-polaris-context}/src/test/java/com/tencent/cloud/polaris/context/PolarisContextApplication.java (100%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context => spring-cloud-tencent-polaris-context}/src/test/java/com/tencent/cloud/polaris/context/PolarisContextConfigurationTest.java (67%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context => spring-cloud-tencent-polaris-context}/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java (73%) rename {spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context => spring-cloud-tencent-polaris-context}/src/test/resources/application-test.yml (100%) delete mode 100644 spring-cloud-tencent-starters/pom.xml delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/callee/QuotaCheckFilter.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/Consts.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRoutingLoadBalancer.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-commons/pom.xml delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServer.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServiceInstance.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-feign/pom.xml delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignAutoConfiguration.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContext.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContractHolder.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignInvocationHandler.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignPluginType.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/resources/META-INF/additional-spring-configuration-metadata.json delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/pom.xml delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataConfiguration.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/constant/MetadataConstant.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContext.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContextHolder.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/MetadataReactiveFilter.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/MetadataServletFilter.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/Metadata2HeaderFeignInterceptor.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/resttemplate/MetadataRestTemplateInterceptor.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/plugin/feign/MetadataFirstFeignPlugin.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/util/JacksonUtils.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/util/MetadataUtils.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataConfigurationTest.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/context/MetadataContextHolderTest.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/feign/Metadata2HeaderFeignInterceptorTest.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/resources/application-test.yml delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/extend/consul/ConsulContextProperties.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/pom.xml delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/config/PolarisGatewayAutoConfiguration.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/route/DynamicRouteService.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/AbstractGlobalFilter.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/Metadata2HeaderScgFilter.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/MetadataFirstScgFilter.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/RateLimitScgFilter.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter/RateLimitZuulFilter.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/resources/META-INF/spring.factories create mode 100644 src/checkstyle/checkstyle-suppressions.xml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..b29845b4 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,28 @@ +root = true + +[*.java] +indent_style = tab +indent_size = 4 +continuation_indent_size = 8 + +[*.groovy] +indent_style = tab +indent_size = 4 +continuation_indent_size = 8 + +[*.xml] +indent_style = tab +indent_size = 4 +continuation_indent_size = 8 + +[*.yml] +indent_style = space +indent_size = 2 + +[*.yaml] +indent_style = space +indent_size = 2 + +[*.sh] +indent_style = space +indent_size = 4 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 651c1390..1a333907 100644 --- a/pom.xml +++ b/pom.xml @@ -38,193 +38,233 @@ - spring-cloud-tencent-dependencies - spring-cloud-tencent-starters - spring-cloud-tencent-examples - spring-cloud-tencent-coverage - - - - - SkyeBeFreeman - Haotian Zhang - 928016560@qq.com - Tencent - https://github.com/SkyeBeFreeman/ - - - - Andrew Shan - samshan08@126.com - Tencent - - - - xiaoyao1999hn - Jie Cheng - 348893717@qq.com - Tencent - https://github.com/xiaoyao1999hn/ - - - - - - 1.2.0.Hoxton.SR9-SNAPSHOT - - - Hoxton.SR9 - - - 1.2.7 - - - 0.8.3 - 3.2.0 - 1.2.7 - - - - - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring.cloud.version} - pom - import - - - - - com.tencent.cloud - spring-cloud-tencent-dependencies - ${revision} - pom - import - - - - ch.qos.logback - logback-classic - ${logback.version} - - - - - - - - - org.jacoco - jacoco-maven-plugin - ${jacoco.version} - - - - - - org.apache.maven.plugins - maven-compiler-plugin - true - - 1.8 - 1.8 - true - - - - org.apache.maven.plugins - maven-surefire-plugin - true - - 1 - false - - - - org.codehaus.mojo - flatten-maven-plugin - ${flatten-maven-plugin.version} - - true - resolveCiFriendliesOnly - - - - flatten - process-resources - - flatten - - - - flatten.clean - clean - - clean - - - - - - - - - - release - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - attach-javadocs - - jar - - - - - - - org.apache.maven.plugins - maven-source-plugin - ${maven-source-plugin.version} - - - package - - jar-no-fork - - - - - - - org.apache.maven.plugins - maven-gpg-plugin - ${maven-gpg-plugin.version} - - - verify - - sign - - - - - + spring-cloud-tencent-polaris-context + spring-cloud-tencent-commons + spring-cloud-tencent-metadata + spring-cloud-starter-tencent-polaris-discovery + spring-cloud-starter-tencent-polaris-ratelimit + spring-cloud-starter-tencent-polaris-circuitbreaker + spring-cloud-starter-tencent-polaris-router + spring-cloud-tencent-dependencies + spring-cloud-tencent-examples + spring-cloud-tencent-coverage + + + + + SkyeBeFreeman + Haotian Zhang + 928016560@qq.com + Tencent + https://github.com/SkyeBeFreeman/ + + + + Andrew Shan + samshan08@126.com + Tencent + + + + xiaoyao1999hn + Jie Cheng + 348893717@qq.com + Tencent + https://github.com/xiaoyao1999hn/ + + + + + + 1.2.0.Hoxton.SR9-SNAPSHOT + + + Hoxton.SR9 + + + 1.2.7 + + + 0.8.3 + 3.2.0 + 1.2.7 + + + true + true + true + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + com.tencent.cloud + spring-cloud-tencent-dependencies + ${revision} + pom + import + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + + + + io.spring.javaformat + spring-javaformat-maven-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + true + + 1.8 + 1.8 + true + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + jacoco-initialize + + prepare-agent + + + + jacoco-site + test + + report + + + + + + org.apache.maven.plugins + maven-surefire-plugin + true + + 1 + false + + + + org.codehaus.mojo + flatten-maven-plugin + ${flatten-maven-plugin.version} + + true + resolveCiFriendliesOnly + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + + + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + + + + release + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + package + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg-plugin.version} + + + verify + + sign + + + + + diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml new file mode 100644 index 00000000..d90ddbc0 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml @@ -0,0 +1,68 @@ + + + + spring-cloud-tencent + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + spring-cloud-starter-tencent-polaris-circuitbreaker + Spring Cloud Starter Tencent Polaris Circuitbreaker + + + + + com.tencent.cloud + spring-cloud-tencent-commons + + + + com.tencent.cloud + spring-cloud-tencent-metadata + + + + com.tencent.cloud + spring-cloud-tencent-polaris-context + + + + + + com.tencent.polaris + polaris-discovery-factory + + + + com.tencent.polaris + polaris-circuitbreaker-factory + + + + + org.springframework.cloud + spring-cloud-loadbalancer + + + + org.springframework.cloud + spring-cloud-starter-netflix-ribbon + test + + + + org.springframework.cloud + spring-cloud-openfeign-core + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfiguration.java similarity index 65% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfiguration.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfiguration.java index 1ecbbcea..d4b81277 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfiguration.java @@ -17,8 +17,6 @@ package com.tencent.cloud.polaris.circuitbreaker; -import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; - import com.tencent.cloud.common.constant.ContextConstant.ModifierOrder; import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisFeignBeanPostProcessor; import com.tencent.cloud.polaris.context.PolarisConfigModifier; @@ -27,6 +25,7 @@ import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.factory.api.DiscoveryAPIFactory; import com.tencent.polaris.factory.config.ConfigurationImpl; + import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -35,47 +34,51 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; +import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; + /** - * Configuration for Polaris {@link feign.Feign} which can automatically bring in the call results for reporting + * Configuration for Polaris {@link feign.Feign} which can automatically bring in the call + * results for reporting. * * @author Haotian Zhang */ -@ConditionalOnProperty( - value = "spring.cloud.polaris.circuitbreaker.enabled", - havingValue = "true", - matchIfMissing = true) +@ConditionalOnProperty(value = "spring.cloud.polaris.circuitbreaker.enabled", + havingValue = "true", matchIfMissing = true) @Configuration(proxyBeanMethods = false) @AutoConfigureAfter(PolarisContextConfiguration.class) @AutoConfigureBefore(FeignAutoConfiguration.class) public class PolarisFeignClientAutoConfiguration { - @Bean - public ConsumerAPI consumerAPI(SDKContext context) { - return DiscoveryAPIFactory.createConsumerAPIByContext(context); - } + @Bean + public ConsumerAPI consumerAPI(SDKContext context) { + return DiscoveryAPIFactory.createConsumerAPIByContext(context); + } + + @Bean + @Order(HIGHEST_PRECEDENCE) + public PolarisFeignBeanPostProcessor polarisFeignBeanPostProcessor( + ConsumerAPI consumerAPI) { + return new PolarisFeignBeanPostProcessor(consumerAPI); + } + + @Bean + public CircuitBreakerConfigModifier circuitBreakerConfigModifier() { + return new CircuitBreakerConfigModifier(); + } - @Bean - @Order(value = HIGHEST_PRECEDENCE) - public PolarisFeignBeanPostProcessor polarisFeignBeanPostProcessor(ConsumerAPI consumerAPI) { - return new PolarisFeignBeanPostProcessor(consumerAPI); - } + public static class CircuitBreakerConfigModifier implements PolarisConfigModifier { - @Bean - public CircuitBreakerConfigModifier circuitBreakerConfigModifier() { - return new CircuitBreakerConfigModifier(); - } + @Override + public void modify(ConfigurationImpl configuration) { + // 开启熔断配置 + configuration.getConsumer().getCircuitBreaker().setEnable(true); + } - public static class CircuitBreakerConfigModifier implements PolarisConfigModifier { + @Override + public int getOrder() { + return ModifierOrder.CIRCUIT_BREAKER_ORDER; + } - @Override - public void modify(ConfigurationImpl configuration) { - //开启熔断配置 - configuration.getConsumer().getCircuitBreaker().setEnable(true); - } + } - @Override - public int getOrder() { - return ModifierOrder.CIRCUIT_BREAKER_ORDER; - } - } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java new file mode 100644 index 00000000..da672648 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java @@ -0,0 +1,97 @@ +/* + * 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 com.tencent.polaris.api.core.ConsumerAPI; +import feign.Client; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; +import org.springframework.cloud.netflix.ribbon.SpringClientFactory; +import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; +import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory; +import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient; + +/** + * Wrap Spring Bean and decorating proxy for Feign Client. + * + * @author Haotian Zhang + */ +public class PolarisFeignBeanPostProcessor + implements BeanPostProcessor, BeanFactoryAware { + + private final ConsumerAPI consumerAPI; + + private BeanFactory factory; + + public PolarisFeignBeanPostProcessor(ConsumerAPI consumerAPI) { + this.consumerAPI = consumerAPI; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return wrapper(bean); + } + + private Object wrapper(Object bean) { + if (isNeedWrap(bean)) { + if (bean instanceof LoadBalancerFeignClient) { + LoadBalancerFeignClient client = ((LoadBalancerFeignClient) bean); + return new PolarisLoadBalancerFeignClient( + createPolarisFeignClient(client.getDelegate()), factory(), + clientFactory()); + } + if (bean instanceof FeignBlockingLoadBalancerClient) { + FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) bean; + return new PolarisFeignBlockingLoadBalancerClient( + createPolarisFeignClient(client.getDelegate()), + factory.getBean(BlockingLoadBalancerClient.class)); + } + return createPolarisFeignClient((Client) bean); + } + return bean; + } + + private boolean isNeedWrap(Object bean) { + return bean instanceof Client && !(bean instanceof PolarisFeignClient) + && !(bean instanceof PolarisFeignBlockingLoadBalancerClient) + && !(bean instanceof PolarisLoadBalancerFeignClient); + } + + private PolarisFeignClient createPolarisFeignClient(Client delegate) { + return new PolarisFeignClient(delegate, consumerAPI); + } + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.factory = beanFactory; + } + + CachingSpringLoadBalancerFactory factory() { + return this.factory.getBean(CachingSpringLoadBalancerFactory.class); + } + + SpringClientFactory clientFactory() { + return this.factory.getBean(SpringClientFactory.class); + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java similarity index 76% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java index 076e269e..9adaa6bf 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java @@ -18,19 +18,21 @@ package com.tencent.cloud.polaris.circuitbreaker.feign; import feign.Client; + import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; /** - * Wrap for {@link FeignBlockingLoadBalancerClient} + * Wrap for {@link FeignBlockingLoadBalancerClient}. * * @author Haotian Zhang */ -public class PolarisFeignBlockingLoadBalancerClient extends FeignBlockingLoadBalancerClient { +public class PolarisFeignBlockingLoadBalancerClient + extends FeignBlockingLoadBalancerClient { - public PolarisFeignBlockingLoadBalancerClient(Client delegate, - BlockingLoadBalancerClient loadBalancerClient) { - super(delegate, loadBalancerClient); - } + public PolarisFeignBlockingLoadBalancerClient(Client delegate, + BlockingLoadBalancerClient loadBalancerClient) { + super(delegate, loadBalancerClient); + } } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java new file mode 100644 index 00000000..2fa32715 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java @@ -0,0 +1,104 @@ +/* + * 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.io.IOException; +import java.net.URI; + +import com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey; +import com.tencent.cloud.metadata.context.MetadataContext; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.api.pojo.RetStatus; +import com.tencent.polaris.api.pojo.ServiceKey; +import com.tencent.polaris.api.rpc.ServiceCallResult; +import feign.Client; +import feign.Request; +import feign.Request.Options; +import feign.Response; +import org.apache.commons.lang.StringUtils; + +import static feign.Util.checkNotNull; + +/** + * Wrap for {@link Client}. + * + * @author Haotian Zhang + */ +public class PolarisFeignClient implements Client { + + private final Client delegate; + + private final ConsumerAPI consumerAPI; + + public PolarisFeignClient(Client target, ConsumerAPI consumerAPI) { + this.delegate = checkNotNull(target, "target"); + this.consumerAPI = checkNotNull(consumerAPI, "CircuitBreakAPI"); + } + + @Override + public Response execute(Request request, Options options) throws IOException { + final ServiceCallResult resultRequest = createServiceCallResult(request); + try { + Response response = delegate.execute(request, options); + // HTTP code greater than 400 is an exception + if (response.status() >= 400) { + resultRequest.setRetStatus(RetStatus.RetFail); + } + return response; + } + catch (IOException origin) { + resultRequest.setRetStatus(RetStatus.RetFail); + throw origin; + } + finally { + consumerAPI.updateServiceCallResult(resultRequest); + } + } + + private ServiceCallResult createServiceCallResult(final Request request) { + ServiceCallResult resultRequest = new ServiceCallResult(); + + MetadataContext metadataContext = MetadataContextHolder.get(); + String namespace = metadataContext + .getSystemMetadata(SystemMetadataKey.PEER_NAMESPACE); + resultRequest.setNamespace(namespace); + String serviceName = metadataContext + .getSystemMetadata(SystemMetadataKey.PEER_SERVICE); + resultRequest.setService(serviceName); + String method = metadataContext.getSystemMetadata(SystemMetadataKey.PEER_PATH); + resultRequest.setMethod(method); + resultRequest.setRetStatus(RetStatus.RetSuccess); + String sourceNamespace = metadataContext + .getSystemMetadata(SystemMetadataKey.LOCAL_NAMESPACE); + String sourceService = metadataContext + .getSystemMetadata(SystemMetadataKey.LOCAL_SERVICE); + if (StringUtils.isNotBlank(sourceNamespace) + && StringUtils.isNotBlank(sourceService)) { + resultRequest + .setCallerService(new ServiceKey(sourceNamespace, sourceService)); + } + + URI uri = URI.create(request.url()); + resultRequest.setHost(uri.getHost()); + resultRequest.setPort(uri.getPort()); + + return resultRequest; + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java similarity index 80% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java index 420cf27e..41e4a608 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java @@ -18,20 +18,22 @@ package com.tencent.cloud.polaris.circuitbreaker.feign; import feign.Client; + import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory; import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient; /** - * Wrap for {@link LoadBalancerFeignClient} + * Wrap for {@link LoadBalancerFeignClient}. * * @author Haotian Zhang */ public class PolarisLoadBalancerFeignClient extends LoadBalancerFeignClient { - public PolarisLoadBalancerFeignClient(Client delegate, - CachingSpringLoadBalancerFactory lbClientFactory, - SpringClientFactory clientFactory) { - super(delegate, lbClientFactory, clientFactory); - } + public PolarisLoadBalancerFeignClient(Client delegate, + CachingSpringLoadBalancerFactory lbClientFactory, + SpringClientFactory clientFactory) { + super(delegate, lbClientFactory, clientFactory); + } + } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring-configuration-metadata.json b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring-configuration-metadata.json similarity index 99% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring-configuration-metadata.json rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring-configuration-metadata.json index 3ab08a57..195c3cb2 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring-configuration-metadata.json +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring-configuration-metadata.json @@ -7,4 +7,4 @@ } ], "hints": [] -} \ No newline at end of file +} diff --git a/spring-cloud-tencent-starters/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 similarity index 89% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories index 9ef0f8c3..4ceef0fb 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories @@ -1,2 +1,2 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.tencent.cloud.polaris.circuitbreaker.PolarisFeignClientAutoConfiguration \ No newline at end of file + com.tencent.cloud.polaris.circuitbreaker.PolarisFeignClientAutoConfiguration diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java similarity index 63% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java index a6a15d19..e2f80848 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java @@ -22,6 +22,7 @@ import feign.Client; import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContext; @@ -33,30 +34,32 @@ import org.springframework.test.context.junit4.SpringRunner; */ @RunWith(SpringRunner.class) @SpringBootTest(classes = TestPolarisFeignApp.class) -@ContextConfiguration(classes = {PolarisFeignClientAutoConfiguration.class}) +@ContextConfiguration(classes = { PolarisFeignClientAutoConfiguration.class }) public class PolarisFeignClientTest { - @Autowired - private ApplicationContext springCtx; - - @Test - public void testPolarisFeignBeanPostProcessor() { - final PolarisFeignBeanPostProcessor postProcessor = springCtx.getBean(PolarisFeignBeanPostProcessor.class); - Assertions.assertNotNull(postProcessor, "PolarisFeignBeanPostProcessor"); - } - - @Test - public void testFeignClient() { - final Client client = springCtx.getBean(Client.class); - if (client instanceof PolarisFeignClient) { - return; - } - if (client instanceof PolarisLoadBalancerFeignClient) { - return; - } - if (client instanceof PolarisFeignBlockingLoadBalancerClient) { - return; - } - throw new IllegalStateException("Polaris burying failed"); - } + @Autowired + private ApplicationContext springCtx; + + @Test + public void testPolarisFeignBeanPostProcessor() { + final PolarisFeignBeanPostProcessor postProcessor = springCtx + .getBean(PolarisFeignBeanPostProcessor.class); + Assertions.assertNotNull(postProcessor, "PolarisFeignBeanPostProcessor"); + } + + @Test + public void testFeignClient() { + final Client client = springCtx.getBean(Client.class); + if (client instanceof PolarisFeignClient) { + return; + } + if (client instanceof PolarisLoadBalancerFeignClient) { + return; + } + if (client instanceof PolarisFeignBlockingLoadBalancerClient) { + return; + } + throw new IllegalStateException("Polaris burying failed"); + } + } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/TestPolarisFeignApp.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/TestPolarisFeignApp.java similarity index 64% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/TestPolarisFeignApp.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/TestPolarisFeignApp.java index 1b451746..0fb951af 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/TestPolarisFeignApp.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/TestPolarisFeignApp.java @@ -17,7 +17,6 @@ package com.tencent.cloud.polaris.circuitbreaker.feign; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @@ -32,32 +31,30 @@ import org.springframework.web.bind.annotation.GetMapping; @EnableFeignClients public class TestPolarisFeignApp { - @Autowired - TestPolarisService service; + public static void main(String[] args) { + SpringApplication.run(TestPolarisFeignApp.class); + } - public static void main(String[] args) { - SpringApplication.run(TestPolarisFeignApp.class); - } + @FeignClient(name = "feign-service-polaris", + fallback = TestPolarisServiceFallback.class) + public interface TestPolarisService { - @FeignClient(name = "feign-service-polaris", fallback = TestPolarisServiceFallback.class) - public interface TestPolarisService { + /** + * Get info of service B. + */ + @GetMapping("/example/service/b/info") + String info(); - /** - * 获取B的服务的信息 - * - * @return - */ - @GetMapping("/example/service/b/info") - String info(); + } - } + @Component + public static class TestPolarisServiceFallback implements TestPolarisService { - @Component - public static class TestPolarisServiceFallback implements TestPolarisService { + @Override + public String info() { + return "trigger the refuse"; + } + + } - @Override - public String info() { - return "trigger the refuse"; - } - } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application.yml b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application.yml similarity index 86% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application.yml rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application.yml index beaf23b7..07f266da 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application.yml +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application.yml @@ -12,4 +12,4 @@ feign: mime-types: text/xml,application/xml,application/json #指定压缩的请求数据类型 min-request-size: 2048 #超过该大小的请求会被压缩 response: - enabled: false #是否对响应进行GZIP压缩 \ No newline at end of file + enabled: false #是否对响应进行GZIP压缩 diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/pom.xml b/spring-cloud-starter-tencent-polaris-discovery/pom.xml similarity index 73% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/pom.xml rename to spring-cloud-starter-tencent-polaris-discovery/pom.xml index fa2cabb0..fa1431e8 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/pom.xml +++ b/spring-cloud-starter-tencent-polaris-discovery/pom.xml @@ -1,23 +1,23 @@ - - - spring-cloud-tencent-starters - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 + + + spring-cloud-tencent + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 - spring-cloud-starter-tencent-polaris-discovery - Spring Cloud Starter Tencent Polaris Discovery + spring-cloud-starter-tencent-polaris-discovery + Spring Cloud Starter Tencent Polaris Discovery - - - - com.tencent.cloud - spring-cloud-tencent-commons + + + + com.tencent.cloud + spring-cloud-tencent-commons diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java new file mode 100644 index 00000000..f9e4e39d --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java @@ -0,0 +1,231 @@ +/* + * 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; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang.StringUtils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.commons.util.InetUtils; +import org.springframework.core.env.Environment; + +/** + * Properties for Polaris. + * + * @author Haotian Zhang, Andrew Shan, Jie Cheng + */ +@ConfigurationProperties("spring.cloud.polaris.discovery") +public class PolarisProperties { + + /** + * The polaris authentication token. + */ + private String token; + + /** + * Namespace, separation registry of different environments. + */ + @Value("${spring.cloud.polaris.discovery.namespace:#{'default'}}") + private String namespace; + + /** + * Service name to registry. + */ + @Value("${spring.cloud.polaris.discovery.service:${spring.application.name:}}") + private String service; + + /** + * Load balance weight. + */ + @Value("${spring.cloud.polaris.discovery.weight:#{100}}") + private float weight; + + /** + * Version number. + */ + private String version; + + /** + * Protocol name such as http, https. + */ + @Value("${spring.cloud.polaris.discovery.protocol:http}") + private String protocol; + + /** + * Port of instance. + */ + @Value("${server.port:}") + private int port; + + /** + * Ip address to be registered. + */ + private String ipAddress; + + /** + * If instance registered. + */ + @Value("${spring.cloud.polaris.discovery.register.enabled:#{true}}") + private Boolean registerEnabled; + + /** + * If heartbeat enabled. + */ + @Value("${spring.cloud.polaris.discovery.heartbeat.enabled:#{true}}") + private Boolean heartbeatEnabled = true; + + /** + * Custom health check url to override default. + */ + @Value("${spring.cloud.polaris.discovery.health-check-url:}") + private String healthCheckUrl; + + @Autowired + private Environment environment; + + public PolarisProperties(InetUtils inetUtils) { + if (inetUtils != null) { + this.ipAddress = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress(); + } + } + + /** + * Init properties. + */ + @PostConstruct + public void init() { + if (StringUtils.isEmpty(this.getNamespace())) { + this.setNamespace(environment + .resolvePlaceholders("${spring.cloud.polaris.discovery.namespace:}")); + } + if (StringUtils.isEmpty(this.getService())) { + this.setService(environment + .resolvePlaceholders("${spring.cloud.polaris.discovery.service:}")); + } + if (StringUtils.isEmpty(this.getToken())) { + this.setToken(environment + .resolvePlaceholders("${spring.cloud.polaris.discovery.token:}")); + } + } + + public boolean isHeartbeatEnabled() { + if (null == heartbeatEnabled) { + return false; + } + return heartbeatEnabled; + } + + public void setHeartbeatEnabled(Boolean heartbeatEnabled) { + this.heartbeatEnabled = heartbeatEnabled; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public float getWeight() { + return weight; + } + + public void setWeight(float weight) { + this.weight = weight; + } + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + public boolean isRegisterEnabled() { + return registerEnabled; + } + + public void setRegisterEnabled(boolean registerEnabled) { + this.registerEnabled = registerEnabled; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getIpAddress() { + return ipAddress; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + + public String getHealthCheckUrl() { + return healthCheckUrl; + } + + public void setHealthCheckUrl(String healthCheckUrl) { + this.healthCheckUrl = healthCheckUrl; + } + + @Override + public String toString() { + return "PolarisProperties{" + "token='" + token + '\'' + ", namespace='" + + namespace + '\'' + ", service='" + service + '\'' + ", weight=" + weight + + ", version='" + version + '\'' + ", protocol='" + protocol + '\'' + + ", port=" + port + ", ipAddress='" + ipAddress + '\'' + + ", registerEnabled=" + registerEnabled + ", heartbeatEnabled=" + + heartbeatEnabled + ", healthCheckUrl=" + healthCheckUrl + + ", environment=" + environment + '}'; + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/client/PolarisClient.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/client/PolarisClient.java similarity index 86% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/client/PolarisClient.java rename to spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/client/PolarisClient.java index 102b20a7..6ab0adbf 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/client/PolarisClient.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/client/PolarisClient.java @@ -35,18 +35,16 @@ import java.lang.annotation.Target; @Inherited public @interface PolarisClient { - /** - * service - * - * @return service - */ - String service() default ""; + /** + * Service name of instance. + * @return service + */ + String service() default ""; - /** - * namespace - * - * @return namespace - */ - String namespace() default ""; + /** + * Namespace name of instance. + * @return namespace + */ + String namespace() default ""; } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java similarity index 94% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java rename to spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java index d0829df6..49bcea80 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/ConditionalOnPolarisDiscoveryEnabled.java @@ -21,6 +21,7 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; + import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; @@ -28,9 +29,10 @@ import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; * @author Haotian Zhang, Andrew Shan, Jie Cheng */ @Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.METHOD}) +@Target({ ElementType.TYPE, ElementType.METHOD }) @ConditionalOnDiscoveryEnabled -@ConditionalOnProperty(value = "spring.cloud.polaris.discovery.enabled", matchIfMissing = true) +@ConditionalOnProperty(value = "spring.cloud.polaris.discovery.enabled", + matchIfMissing = true) public @interface ConditionalOnPolarisDiscoveryEnabled { } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java similarity index 60% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java rename to spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java index 863db32b..acd7b350 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfiguration.java @@ -24,6 +24,7 @@ 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 org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cloud.commons.util.InetUtils; import org.springframework.context.annotation.Bean; @@ -37,36 +38,41 @@ import org.springframework.context.annotation.Import; */ @Configuration(proxyBeanMethods = false) @ConditionalOnPolarisDiscoveryEnabled -@Import({PolarisDiscoveryClientConfiguration.class, PolarisReactiveDiscoveryClientConfiguration.class}) +@Import({ PolarisDiscoveryClientConfiguration.class, + PolarisReactiveDiscoveryClientConfiguration.class }) public class PolarisDiscoveryAutoConfiguration { - @Bean - @ConditionalOnMissingBean - public PolarisProperties polarisDiscoveryProperties(InetUtils inetUtils) { - return new PolarisProperties(inetUtils); - } + @Bean + @ConditionalOnMissingBean + public PolarisProperties polarisDiscoveryProperties(InetUtils inetUtils) { + return new PolarisProperties(inetUtils); + } + + @Bean(name = "polarisProvider") + @ConditionalOnMissingBean + public ProviderAPI polarisProvider(SDKContext polarisContext) + throws PolarisException { + return DiscoveryAPIFactory.createProviderAPIByContext(polarisContext); + } - @Bean(name = "polarisProvider") - @ConditionalOnMissingBean - public ProviderAPI polarisProvider(SDKContext polarisContext) throws PolarisException { - return DiscoveryAPIFactory.createProviderAPIByContext(polarisContext); - } + @Bean(name = "polarisConsumer") + @ConditionalOnMissingBean + public ConsumerAPI polarisConsumer(SDKContext polarisContext) + throws PolarisException { + return DiscoveryAPIFactory.createConsumerAPIByContext(polarisContext); + } - @Bean(name = "polarisConsumer") - @ConditionalOnMissingBean - public ConsumerAPI polarisConsumer(SDKContext polarisContext) throws PolarisException { - return DiscoveryAPIFactory.createConsumerAPIByContext(polarisContext); - } + @Bean + @ConditionalOnMissingBean + public PolarisDiscoveryHandler polarisDiscoveryHandler() { + return new PolarisDiscoveryHandler(); + } - @Bean - @ConditionalOnMissingBean - public PolarisDiscoveryHandler polarisDiscoveryHandler() { - return new PolarisDiscoveryHandler(); - } + @Bean + @ConditionalOnMissingBean + public PolarisServiceDiscovery polarisServiceDiscovery( + PolarisDiscoveryHandler polarisDiscoveryHandler) { + return new PolarisServiceDiscovery(polarisDiscoveryHandler); + } - @Bean - @ConditionalOnMissingBean - public PolarisServiceDiscovery polarisServiceDiscovery(PolarisDiscoveryHandler polarisDiscoveryHandler) { - return new PolarisServiceDiscovery(polarisDiscoveryHandler); - } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java similarity index 60% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java rename to spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java index 90bec09c..783ef468 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClient.java @@ -18,6 +18,7 @@ package com.tencent.cloud.polaris.discovery; import java.util.List; + import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; @@ -28,30 +29,30 @@ import org.springframework.cloud.client.discovery.DiscoveryClient; */ public class PolarisDiscoveryClient implements DiscoveryClient { - /** - * Polaris Discovery Client Description. - */ - public final String description = "Spring Cloud Polaris Discovery Client"; + /** + * Polaris Discovery Client Description. + */ + public final String description = "Spring Cloud Polaris Discovery Client"; - private final PolarisServiceDiscovery polarisServiceDiscovery; + private final PolarisServiceDiscovery polarisServiceDiscovery; - public PolarisDiscoveryClient(PolarisServiceDiscovery polarisServiceDiscovery) { - this.polarisServiceDiscovery = polarisServiceDiscovery; - } + public PolarisDiscoveryClient(PolarisServiceDiscovery polarisServiceDiscovery) { + this.polarisServiceDiscovery = polarisServiceDiscovery; + } - @Override - public String description() { - return description; - } + @Override + public String description() { + return description; + } - @Override - public List getInstances(String service) { - return polarisServiceDiscovery.getInstances(service); - } + @Override + public List getInstances(String service) { + return polarisServiceDiscovery.getInstances(service); + } - @Override - public List getServices() { - return polarisServiceDiscovery.getServices(); - } + @Override + public List getServices() { + return polarisServiceDiscovery.getServices(); + } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java similarity index 84% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java rename to spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java index a788d2b5..24968594 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfiguration.java @@ -33,14 +33,15 @@ import org.springframework.context.annotation.Configuration; */ @Configuration(proxyBeanMethods = false) @ConditionalOnBlockingDiscoveryEnabled -@AutoConfigureBefore({SimpleDiscoveryClientAutoConfiguration.class, - CommonsClientAutoConfiguration.class}) +@AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class, + CommonsClientAutoConfiguration.class }) @AutoConfigureAfter(PolarisDiscoveryAutoConfiguration.class) public class PolarisDiscoveryClientConfiguration { - @Bean - public DiscoveryClient polarisDiscoveryClient(PolarisServiceDiscovery polarisServiceDiscovery) { - return new PolarisDiscoveryClient(polarisServiceDiscovery); - } + @Bean + public DiscoveryClient polarisDiscoveryClient( + PolarisServiceDiscovery polarisServiceDiscovery) { + return new PolarisDiscoveryClient(polarisServiceDiscovery); + } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java new file mode 100644 index 00000000..42869c28 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java @@ -0,0 +1,113 @@ +/* + * 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 java.util.Map; + +import com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import com.tencent.cloud.polaris.PolarisProperties; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.api.core.ProviderAPI; +import com.tencent.polaris.api.pojo.ServiceInfo; +import com.tencent.polaris.api.rpc.GetAllInstancesRequest; +import com.tencent.polaris.api.rpc.GetInstancesRequest; +import com.tencent.polaris.api.rpc.GetServicesRequest; +import com.tencent.polaris.api.rpc.InstancesResponse; +import com.tencent.polaris.api.rpc.ServicesResponse; +import org.apache.commons.lang.StringUtils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Discovery Handler for Polaris. + * + * @author Haotian Zhang, Andrew Shan, Jie Cheng + */ +@Component +public class PolarisDiscoveryHandler { + + @Autowired + private PolarisProperties polarisProperties; + + @Autowired + private ProviderAPI providerAPI; + + @Autowired + private ConsumerAPI polarisConsumer; + + /** + * Get a list of instances after service routing. + * @param service service name + * @return list of instances + */ + public InstancesResponse getFilteredInstances(String service) { + String namespace = polarisProperties.getNamespace(); + GetInstancesRequest getInstancesRequest = new GetInstancesRequest(); + getInstancesRequest.setNamespace(namespace); + getInstancesRequest.setService(service); + String method = MetadataContextHolder.get() + .getSystemMetadata(SystemMetadataKey.PEER_PATH); + getInstancesRequest.setMethod(method); + String localNamespace = MetadataContextHolder.get() + .getSystemMetadata(SystemMetadataKey.LOCAL_NAMESPACE); + String localService = MetadataContextHolder.get() + .getSystemMetadata(SystemMetadataKey.LOCAL_SERVICE); + Map allTransitiveCustomMetadata = MetadataContextHolder.get() + .getAllTransitiveCustomMetadata(); + if (StringUtils.isNotBlank(localNamespace) || StringUtils.isNotBlank(localService) + || null != allTransitiveCustomMetadata) { + ServiceInfo sourceService = new ServiceInfo(); + sourceService.setNamespace(localNamespace); + sourceService.setService(localService); + sourceService.setMetadata(allTransitiveCustomMetadata); + getInstancesRequest.setServiceInfo(sourceService); + } + return polarisConsumer.getInstances(getInstancesRequest); + } + + /** + * Return all instances for the given service. + * @param service serviceName + * @return list of instances + */ + public InstancesResponse getInstances(String service) { + String namespace = polarisProperties.getNamespace(); + GetAllInstancesRequest request = new GetAllInstancesRequest(); + request.setNamespace(namespace); + request.setService(service); + return polarisConsumer.getAllInstance(request); + } + + public ProviderAPI getProviderAPI() { + return providerAPI; + } + + /** + * Return all service for given namespace. + * @return service list + */ + public ServicesResponse GetServices() { + String namespace = polarisProperties.getNamespace(); + GetServicesRequest request = new GetServicesRequest(); + request.setNamespace(namespace); + return polarisConsumer.getServices(request); + } + +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java new file mode 100644 index 00000000..6f85be6c --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java @@ -0,0 +1,71 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.discovery; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import com.tencent.cloud.common.pojo.PolarisServiceInstance; +import com.tencent.polaris.api.exception.PolarisException; +import com.tencent.polaris.api.pojo.Instance; +import com.tencent.polaris.api.pojo.ServiceInfo; +import com.tencent.polaris.api.pojo.ServiceInstances; +import com.tencent.polaris.api.rpc.InstancesResponse; + +import org.springframework.cloud.client.ServiceInstance; + +/** + * @author Haotian Zhang, Andrew Shan, Jie Cheng + */ +public class PolarisServiceDiscovery { + + private final PolarisDiscoveryHandler polarisDiscoveryHandler; + + public PolarisServiceDiscovery(PolarisDiscoveryHandler polarisDiscoveryHandler) { + this.polarisDiscoveryHandler = polarisDiscoveryHandler; + } + + /** + * Return all instances for the given service. + * @param serviceId id of service + * @return list of instances + * @throws PolarisException polarisException + */ + public List getInstances(String serviceId) throws PolarisException { + List instances = new ArrayList<>(); + InstancesResponse filteredInstances = polarisDiscoveryHandler + .getFilteredInstances(serviceId); + ServiceInstances serviceInstances = filteredInstances.toServiceInstances(); + for (Instance instance : serviceInstances.getInstances()) { + instances.add(new PolarisServiceInstance(instance)); + } + return instances; + } + + /** + * Return the names of all services. + * @return list of service names + * @throws PolarisException polarisException + */ + public List getServices() throws PolarisException { + return polarisDiscoveryHandler.GetServices().getServices().stream() + .map(ServiceInfo::getService).collect(Collectors.toList()); + } + +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java new file mode 100644 index 00000000..aa098ac0 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java @@ -0,0 +1,88 @@ +/* + * 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.reactive; + +import java.util.function.Function; + +import com.tencent.cloud.polaris.discovery.PolarisServiceDiscovery; +import com.tencent.polaris.api.exception.PolarisException; +import org.reactivestreams.Publisher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; + +/** + * Reactive Discovery Client for Polaris. + * + * @author Haotian Zhang, Andrew Shan, Jie Cheng + */ +public class PolarisReactiveDiscoveryClient implements ReactiveDiscoveryClient { + + private static final Logger log = LoggerFactory + .getLogger(PolarisReactiveDiscoveryClient.class); + + private PolarisServiceDiscovery polarisServiceDiscovery; + + public PolarisReactiveDiscoveryClient( + PolarisServiceDiscovery polarisServiceDiscovery) { + this.polarisServiceDiscovery = polarisServiceDiscovery; + } + + @Override + public String description() { + return "Spring Cloud Polaris Reactive Discovery Client"; + } + + @Override + public Flux getInstances(String serviceId) { + + return Mono.justOrEmpty(serviceId).flatMapMany(loadInstancesFromPolaris()) + .subscribeOn(Schedulers.boundedElastic()); + } + + private Function> loadInstancesFromPolaris() { + return serviceId -> { + try { + return Flux.fromIterable(polarisServiceDiscovery.getInstances(serviceId)); + } + catch (PolarisException e) { + log.error("get service instance[{}] from polaris error!", serviceId, e); + return Flux.empty(); + } + }; + } + + @Override + public Flux getServices() { + return Flux.defer(() -> { + try { + return Flux.fromIterable(polarisServiceDiscovery.getServices()); + } + catch (Exception e) { + log.error("get services from polaris server fail,", e); + return Flux.empty(); + } + }).subscribeOn(Schedulers.boundedElastic()); + } + +} diff --git a/spring-cloud-tencent-starters/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 similarity index 79% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java rename to spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfiguration.java index 77a62343..09928e20 100644 --- a/spring-cloud-tencent-starters/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 @@ -19,6 +19,7 @@ package com.tencent.cloud.polaris.discovery.reactive; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; 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.ConditionalOnMissingBean; @@ -35,16 +36,16 @@ import org.springframework.context.annotation.Configuration; */ @Configuration(proxyBeanMethods = false) @ConditionalOnReactiveDiscoveryEnabled -@AutoConfigureAfter({PolarisDiscoveryAutoConfiguration.class, - ReactiveCompositeDiscoveryClientAutoConfiguration.class}) -@AutoConfigureBefore({ReactiveCommonsClientAutoConfiguration.class}) +@AutoConfigureAfter({ PolarisDiscoveryAutoConfiguration.class, + ReactiveCompositeDiscoveryClientAutoConfiguration.class }) +@AutoConfigureBefore({ ReactiveCommonsClientAutoConfiguration.class }) public class PolarisReactiveDiscoveryClientConfiguration { - @Bean - @ConditionalOnMissingBean - public PolarisReactiveDiscoveryClient polarisReactiveDiscoveryClient( - PolarisServiceDiscovery polarisServiceDiscovery) { - return new PolarisReactiveDiscoveryClient(polarisServiceDiscovery); - } + @Bean + @ConditionalOnMissingBean + public PolarisReactiveDiscoveryClient polarisReactiveDiscoveryClient( + PolarisServiceDiscovery polarisServiceDiscovery) { + return new PolarisReactiveDiscoveryClient(polarisServiceDiscovery); + } } 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 new file mode 100644 index 00000000..5ae88311 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java @@ -0,0 +1,98 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.registry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration; +import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; +import org.springframework.util.StringUtils; + +/** + * @author Haotian Zhang, Andrew Shan, Jie Cheng + */ +public class PolarisAutoServiceRegistration + extends AbstractAutoServiceRegistration { + + private static final Logger log = LoggerFactory + .getLogger(PolarisAutoServiceRegistration.class); + + private final PolarisRegistration registration; + + public PolarisAutoServiceRegistration(ServiceRegistry serviceRegistry, + AutoServiceRegistrationProperties autoServiceRegistrationProperties, + PolarisRegistration registration) { + super(serviceRegistry, autoServiceRegistrationProperties); + this.registration = registration; + } + + @Override + protected PolarisRegistration getRegistration() { + if (this.registration.getPort() <= 0) { + this.registration.setPort(this.getPort().get()); + } + return this.registration; + } + + @Override + protected PolarisRegistration getManagementRegistration() { + return null; + } + + @Override + protected void register() { + if (!this.registration.getPolarisProperties().isRegisterEnabled()) { + log.debug("Registration disabled."); + return; + } + if (this.registration.getPort() <= 0) { + this.registration.setPort(getPort().get()); + } + super.register(); + } + + @Override + protected void registerManagement() { + if (!this.registration.getPolarisProperties().isRegisterEnabled()) { + return; + } + super.registerManagement(); + + } + + @Override + protected Object getConfiguration() { + return this.registration.getPolarisProperties(); + } + + @Override + protected boolean isEnabled() { + return this.registration.getPolarisProperties().isRegisterEnabled(); + } + + @Override + @SuppressWarnings("deprecation") + protected String getAppName() { + String appName = registration.getPolarisProperties().getService(); + return StringUtils.isEmpty(appName) ? super.getAppName() : appName; + } + +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java new file mode 100644 index 00000000..374bb281 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.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.polaris.registry; + +import java.net.URI; +import java.util.Map; + +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import com.tencent.cloud.polaris.PolarisProperties; +import com.tencent.polaris.client.api.SDKContext; +import org.apache.commons.lang.StringUtils; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.serviceregistry.Registration; + +/** + * @author Haotian Zhang, Andrew Shan, Jie Cheng + */ +public class PolarisRegistration implements Registration, ServiceInstance { + + private final PolarisProperties polarisProperties; + + private final SDKContext polarisContext; + + public PolarisRegistration(PolarisProperties polarisProperties, SDKContext context) { + this.polarisProperties = polarisProperties; + this.polarisContext = context; + } + + @Override + public String getServiceId() { + return polarisProperties.getService(); + } + + @Override + public String getHost() { + if (StringUtils.isNotBlank(polarisProperties.getIpAddress())) { + return polarisProperties.getIpAddress(); + } + return polarisContext.getConfig().getGlobal().getAPI().getBindIP(); + } + + @Override + public int getPort() { + return polarisProperties.getPort(); + } + + public void setPort(int port) { + this.polarisProperties.setPort(port); + } + + @Override + public boolean isSecure() { + return StringUtils.equalsIgnoreCase(polarisProperties.getProtocol(), "https"); + } + + @Override + public URI getUri() { + return DefaultServiceInstance.getUri(this); + } + + @Override + public Map getMetadata() { + return MetadataContextHolder.get().getAllSystemMetadata(); + } + + public PolarisProperties getPolarisProperties() { + return polarisProperties; + } + + @Override + public String toString() { + return "PolarisRegistration{" + "polarisProperties=" + polarisProperties + + ", polarisContext=" + polarisContext + '}'; + } + +} 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 new file mode 100644 index 00000000..b665c224 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java @@ -0,0 +1,213 @@ +/* + * 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 java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import com.tencent.cloud.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.polaris.PolarisProperties; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; +import com.tencent.polaris.api.core.ProviderAPI; +import com.tencent.polaris.api.exception.PolarisException; +import com.tencent.polaris.api.pojo.Instance; +import com.tencent.polaris.api.rpc.InstanceDeregisterRequest; +import com.tencent.polaris.api.rpc.InstanceHeartbeatRequest; +import com.tencent.polaris.api.rpc.InstanceRegisterRequest; +import com.tencent.polaris.api.rpc.InstancesResponse; +import com.tencent.polaris.client.util.NamedThreadFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.BeanUtils; +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; +import org.springframework.util.StringUtils; + +import static org.springframework.util.ReflectionUtils.rethrowRuntimeException; + +/** + * @author Haotian Zhang, Andrew Shan, Jie Cheng + */ +public class PolarisServiceRegistry implements ServiceRegistry { + + private static final Logger log = LoggerFactory + .getLogger(PolarisServiceRegistry.class); + + private static final int ttl = 5; + + private final PolarisProperties polarisProperties; + + private final PolarisDiscoveryHandler polarisDiscoveryHandler; + + private final MetadataLocalProperties metadataLocalProperties; + + private final ScheduledExecutorService heartbeatExecutor; + + public PolarisServiceRegistry(PolarisProperties polarisProperties, + PolarisDiscoveryHandler polarisDiscoveryHandler, + MetadataLocalProperties metadataLocalProperties) { + this.polarisProperties = polarisProperties; + this.polarisDiscoveryHandler = polarisDiscoveryHandler; + this.metadataLocalProperties = metadataLocalProperties; + if (polarisProperties.isHeartbeatEnabled()) { + ScheduledThreadPoolExecutor heartbeatExecutor = new ScheduledThreadPoolExecutor( + 0, new NamedThreadFactory("spring-cloud-heartbeat")); + heartbeatExecutor.setMaximumPoolSize(1); + this.heartbeatExecutor = heartbeatExecutor; + } + else { + this.heartbeatExecutor = null; + } + } + + @Override + public void register(Registration registration) { + + if (StringUtils.isEmpty(registration.getServiceId())) { + log.warn("No service to register for polaris client..."); + return; + } + // 注册实例 + InstanceRegisterRequest instanceRegisterRequest = new InstanceRegisterRequest(); + instanceRegisterRequest.setNamespace(polarisProperties.getNamespace()); + instanceRegisterRequest.setService(registration.getServiceId()); + instanceRegisterRequest.setHost(registration.getHost()); + instanceRegisterRequest.setPort(registration.getPort()); + instanceRegisterRequest.setToken(polarisProperties.getToken()); + if (null != heartbeatExecutor) { + instanceRegisterRequest.setTtl(ttl); + } + instanceRegisterRequest.setMetadata(metadataLocalProperties.getContent()); + instanceRegisterRequest.setProtocol(polarisProperties.getProtocol()); + instanceRegisterRequest.setVersion(polarisProperties.getVersion()); + try { + ProviderAPI providerClient = polarisDiscoveryHandler.getProviderAPI(); + providerClient.register(instanceRegisterRequest); + log.info("polaris registry, {} {} {}:{} {} register finished", + polarisProperties.getNamespace(), registration.getServiceId(), + registration.getHost(), registration.getPort(), + metadataLocalProperties.getContent()); + + if (null != heartbeatExecutor) { + InstanceHeartbeatRequest heartbeatRequest = new InstanceHeartbeatRequest(); + BeanUtils.copyProperties(instanceRegisterRequest, heartbeatRequest); + // 注册成功后开始启动心跳线程 + heartbeat(heartbeatRequest); + } + } + catch (Exception e) { + log.error("polaris registry, {} register failed...{},", + registration.getServiceId(), registration, e); + rethrowRuntimeException(e); + } + } + + @Override + public void deregister(Registration registration) { + + log.info("De-registering from Polaris Server now..."); + + if (StringUtils.isEmpty(registration.getServiceId())) { + log.warn("No dom to de-register for polaris client..."); + return; + } + + InstanceDeregisterRequest deRegisterRequest = new InstanceDeregisterRequest(); + deRegisterRequest.setToken(polarisProperties.getToken()); + deRegisterRequest.setNamespace(polarisProperties.getNamespace()); + deRegisterRequest.setService(registration.getServiceId()); + deRegisterRequest.setHost(registration.getHost()); + deRegisterRequest.setPort(registration.getPort()); + + try { + ProviderAPI providerClient = polarisDiscoveryHandler.getProviderAPI(); + providerClient.deRegister(deRegisterRequest); + } + catch (Exception e) { + log.error("ERR_POLARIS_DEREGISTER, de-register failed...{},", registration, + e); + } + finally { + if (null != heartbeatExecutor) { + heartbeatExecutor.shutdown(); + } + } + log.info("De-registration finished."); + } + + @Override + public void close() { + + } + + @Override + public void setStatus(Registration registration, String status) { + + } + + @Override + public Object getStatus(Registration registration) { + String serviceName = registration.getServiceId(); + InstancesResponse instancesResponse = polarisDiscoveryHandler + .getInstances(serviceName); + Instance[] instances = instancesResponse.getInstances(); + if (null == instances || instances.length == 0) { + return null; + } + for (Instance instance : instances) { + if (instance.getHost().equalsIgnoreCase(registration.getHost()) + && instance.getPort() == polarisProperties.getPort()) { + return instance.isHealthy() ? "UP" : "DOWN"; + } + } + return null; + } + + /** + * Start the heartbeat thread. + * @param heartbeatRequest heartbeat request + */ + public void heartbeat(InstanceHeartbeatRequest heartbeatRequest) { + heartbeatExecutor.scheduleWithFixedDelay(new Runnable() { + @Override + public void run() { + try { + // String healthCheckUrl = String.format("http://%s:%s%s", + // heartbeatRequest.getHost(), heartbeatRequest.getPort(), + // polarisProperties.getHealthCheckUrl()); + // //先判断是否配置了health-check-url,如果配置了,需要先进行服务实例健康检查,如果健康检查通过,则进行心跳上报,如果不通过,则不上报心跳 + // if (Strings.isNotEmpty(healthCheckUrl) && + // !OkHttpUtil.get(healthCheckUrl, null)) { + // log.error("polaris health check failed"); + // return; + // } + polarisDiscoveryHandler.getProviderAPI().heartbeat(heartbeatRequest); + } + catch (PolarisException e) { + log.error("polaris heartbeat[{}]", e.getCode(), e); + } + catch (Exception e) { + log.error("polaris heartbeat runtime error", e); + } + } + }, 0, ttl, TimeUnit.SECONDS); + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java similarity index 61% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java rename to spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java index 85816e61..5c037c69 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java @@ -19,10 +19,11 @@ package com.tencent.cloud.polaris.registry; import com.tencent.cloud.metadata.config.MetadataLocalProperties; import com.tencent.cloud.polaris.PolarisProperties; -import com.tencent.polaris.client.api.SDKContext; import com.tencent.cloud.polaris.discovery.ConditionalOnPolarisDiscoveryEnabled; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; +import com.tencent.polaris.client.api.SDKContext; + import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -39,32 +40,37 @@ import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties @ConditionalOnPolarisDiscoveryEnabled -@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) -@AutoConfigureAfter({AutoServiceRegistrationConfiguration.class, - AutoServiceRegistrationAutoConfiguration.class, - PolarisDiscoveryAutoConfiguration.class}) +@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", + matchIfMissing = true) +@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class, + AutoServiceRegistrationAutoConfiguration.class, + PolarisDiscoveryAutoConfiguration.class }) public class PolarisServiceRegistryAutoConfiguration { - @Bean - public PolarisServiceRegistry polarisServiceRegistry(PolarisProperties polarisProperties, - PolarisDiscoveryHandler polarisDiscoveryHandler, - MetadataLocalProperties metadataLocalProperties) { - return new PolarisServiceRegistry(polarisProperties, polarisDiscoveryHandler, metadataLocalProperties); - } + @Bean + public PolarisServiceRegistry polarisServiceRegistry( + PolarisProperties polarisProperties, + PolarisDiscoveryHandler polarisDiscoveryHandler, + MetadataLocalProperties metadataLocalProperties) { + return new PolarisServiceRegistry(polarisProperties, polarisDiscoveryHandler, + metadataLocalProperties); + } - @Bean - @ConditionalOnBean(AutoServiceRegistrationProperties.class) - public PolarisRegistration polarisRegistration(PolarisProperties polarisProperties, - SDKContext context) { - return new PolarisRegistration(polarisProperties, context); - } + @Bean + @ConditionalOnBean(AutoServiceRegistrationProperties.class) + public PolarisRegistration polarisRegistration(PolarisProperties polarisProperties, + SDKContext context) { + return new PolarisRegistration(polarisProperties, context); + } - @Bean - @ConditionalOnBean(AutoServiceRegistrationProperties.class) - public PolarisAutoServiceRegistration polarisAutoServiceRegistration(PolarisServiceRegistry registry, - AutoServiceRegistrationProperties autoServiceRegistrationProperties, PolarisRegistration registration) { - return new PolarisAutoServiceRegistration(registry, - autoServiceRegistrationProperties, registration); - } + @Bean + @ConditionalOnBean(AutoServiceRegistrationProperties.class) + public PolarisAutoServiceRegistration polarisAutoServiceRegistration( + PolarisServiceRegistry registry, + AutoServiceRegistrationProperties autoServiceRegistrationProperties, + PolarisRegistration registration) { + return new PolarisAutoServiceRegistration(registry, + autoServiceRegistrationProperties, registration); + } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisDiscoveryRibbonAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisDiscoveryRibbonAutoConfiguration.java similarity index 99% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisDiscoveryRibbonAutoConfiguration.java rename to spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisDiscoveryRibbonAutoConfiguration.java index 869c7328..be581457 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisDiscoveryRibbonAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisDiscoveryRibbonAutoConfiguration.java @@ -18,6 +18,7 @@ package com.tencent.cloud.polaris.ribbon; import com.tencent.cloud.polaris.discovery.ConditionalOnPolarisDiscoveryEnabled; + import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfiguration.java similarity index 77% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfiguration.java rename to spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfiguration.java index 74efa132..81b8af79 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfiguration.java @@ -21,6 +21,7 @@ import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ServerList; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; + import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -31,12 +32,14 @@ import org.springframework.context.annotation.Configuration; @Configuration public class PolarisRibbonServerListConfiguration { - @Bean - @ConditionalOnMissingBean - public ServerList ribbonServerList(PolarisDiscoveryHandler polarisDiscoveryHandler, - IClientConfig iClientConfig) { - PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); - serverList.initWithNiwsConfig(iClientConfig); - return serverList; - } + @Bean + @ConditionalOnMissingBean + public ServerList ribbonServerList( + PolarisDiscoveryHandler polarisDiscoveryHandler, + IClientConfig iClientConfig) { + PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); + serverList.initWithNiwsConfig(iClientConfig); + return serverList; + } + } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisServerList.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisServerList.java similarity index 52% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisServerList.java rename to spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisServerList.java index b771a314..d716b544 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisServerList.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/ribbon/PolarisServerList.java @@ -17,58 +17,59 @@ package com.tencent.cloud.polaris.ribbon; +import java.util.ArrayList; +import java.util.List; + import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractServerList; import com.netflix.loadbalancer.Server; -import com.tencent.cloud.polaris.pojo.PolarisServer; +import com.tencent.cloud.common.pojo.PolarisServer; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import com.tencent.polaris.api.pojo.Instance; import com.tencent.polaris.api.pojo.ServiceInstances; import com.tencent.polaris.api.rpc.InstancesResponse; -import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; - -import java.util.ArrayList; -import java.util.List; /** * @author Haotian Zhang, Andrew Shan, Jie Cheng */ public class PolarisServerList extends AbstractServerList { - private String serviceId; + private String serviceId; - private PolarisDiscoveryHandler polarisDiscoveryHandler; + private PolarisDiscoveryHandler polarisDiscoveryHandler; - public PolarisServerList(PolarisDiscoveryHandler polarisDiscoveryHandler) { - this.polarisDiscoveryHandler = polarisDiscoveryHandler; - } + public PolarisServerList(PolarisDiscoveryHandler polarisDiscoveryHandler) { + this.polarisDiscoveryHandler = polarisDiscoveryHandler; + } - @Override - public List getInitialListOfServers() { - return getServers(); - } + @Override + public List getInitialListOfServers() { + return getServers(); + } - @Override - public List getUpdatedListOfServers() { - return getServers(); - } + @Override + public List getUpdatedListOfServers() { + return getServers(); + } - private List getServers() { - InstancesResponse filteredInstances = polarisDiscoveryHandler.getFilteredInstances(serviceId); - ServiceInstances serviceInstances = filteredInstances.toServiceInstances(); - List polarisServers = new ArrayList<>(); - for (Instance instance : serviceInstances.getInstances()) { - polarisServers.add(new PolarisServer(serviceInstances, instance)); - } - return polarisServers; - } + private List getServers() { + InstancesResponse filteredInstances = polarisDiscoveryHandler + .getFilteredInstances(serviceId); + ServiceInstances serviceInstances = filteredInstances.toServiceInstances(); + List polarisServers = new ArrayList<>(); + for (Instance instance : serviceInstances.getInstances()) { + polarisServers.add(new PolarisServer(serviceInstances, instance)); + } + return polarisServers; + } - public String getServiceId() { - return serviceId; - } + public String getServiceId() { + return serviceId; + } - @Override - public void initWithNiwsConfig(IClientConfig iClientConfig) { - this.serviceId = iClientConfig.getClientName(); - } + @Override + public void initWithNiwsConfig(IClientConfig iClientConfig) { + this.serviceId = iClientConfig.getClientName(); + } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java new file mode 100644 index 00000000..b569b8ec --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java @@ -0,0 +1,99 @@ +/* + * 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.util; + +import java.util.Map; +import java.util.Objects; + +import com.squareup.okhttp.MediaType; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * okhttp util. + * + * @author kan peng + */ +public final class OkHttpUtil { + + /** + * Logger. + */ + public final static Logger logger = LoggerFactory.getLogger(OkHttpUtil.class); + + /** + * JSON format. + */ + public static final MediaType MEDIA_TYPE_JSON = MediaType + .parse("application/json; charset=utf-8"); + + /** + * client. + */ + private final static OkHttpClient HTTP_CLIENT = new OkHttpClient(); + + private OkHttpUtil() { + + } + + /** + * get request. + * @param url url + * @param headers headers + * @return response + */ + public static boolean get(String url, Map headers) { + try { + Request.Builder builder = new Request.Builder(); + buildHeader(builder, headers); + Request request = builder.url(url).build(); + Response response = HTTP_CLIENT.newCall(request).execute(); + + if (response.isSuccessful() && Objects.nonNull(response.body())) { + String result = response.body().string(); + logger.info("exec get request, url: {} success,response data: {}", url, + result); + return true; + } + } + catch (Exception e) { + logger.error("exec get request,url: {} failed!", url, e); + } + return false; + } + + /** + * build header. + * @param builder builder + * @param headers headers + */ + private static void buildHeader(Request.Builder builder, + Map headers) { + if (Objects.nonNull(headers) && headers.size() > 0) { + headers.forEach((k, v) -> { + if (Objects.nonNull(k) && Objects.nonNull(v)) { + builder.addHeader(k, v); + } + }); + } + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json similarity index 100% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json rename to spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories similarity index 99% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories rename to spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories index 75b02a91..a9cafd05 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories @@ -2,4 +2,3 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration,\ com.tencent.cloud.polaris.ribbon.PolarisDiscoveryRibbonAutoConfiguration,\ com.tencent.cloud.polaris.registry.PolarisServiceRegistryAutoConfiguration - diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisPropertiesTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisPropertiesTest.java similarity index 68% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisPropertiesTest.java rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisPropertiesTest.java index 38c40454..6b40c732 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisPropertiesTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisPropertiesTest.java @@ -17,36 +17,44 @@ package com.tencent.cloud.polaris; +import org.junit.Test; + +import org.springframework.cloud.commons.util.InetUtils; +import org.springframework.cloud.commons.util.InetUtilsProperties; 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.junit.Assert.fail; -import org.junit.Test; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.commons.util.InetUtilsProperties; - +/** + * Test for {@link PolarisProperties} + * + * @author Haotian Zhang + */ public class PolarisPropertiesTest { - @Test - public void testInitAndGetSet() { - PolarisProperties temp = new PolarisProperties(new InetUtils(new InetUtilsProperties())); - try { - temp.setNamespace(NAMESPACE_TEST); - temp.getNamespace(); - - temp.setService(SERVICE_PROVIDER); - temp.getService(); - - temp.setToken("xxxxxx"); - temp.getToken(); - - temp.init(); - assertThat(temp).isNotNull(); - } catch (Exception e) { - fail(); - e.printStackTrace(); - } - } + @Test + public void testInitAndGetSet() { + PolarisProperties temp = new PolarisProperties( + new InetUtils(new InetUtilsProperties())); + try { + temp.setNamespace(NAMESPACE_TEST); + temp.getNamespace(); + + temp.setService(SERVICE_PROVIDER); + temp.getService(); + + temp.setToken("xxxxxx"); + temp.getToken(); + + temp.init(); + assertThat(temp).isNotNull(); + } + catch (Exception e) { + fail(); + e.printStackTrace(); + } + } + } diff --git a/spring-cloud-tencent-starters/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 similarity index 55% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryAutoConfigurationTest.java index c95058b0..b8d6b319 100644 --- a/spring-cloud-tencent-starters/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 @@ -17,10 +17,6 @@ package com.tencent.cloud.polaris.discovery; -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 com.tencent.cloud.polaris.PolarisProperties; import com.tencent.cloud.polaris.context.PolarisContextConfiguration; import com.tencent.polaris.api.core.ConsumerAPI; @@ -29,52 +25,61 @@ import com.tencent.polaris.test.mock.discovery.NamingServer; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; + import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 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.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link PolarisDiscoveryAutoConfiguration} + * + * @author Haotian Zhang + */ public class PolarisDiscoveryAutoConfigurationTest { - private static NamingServer namingServer; + private static NamingServer namingServer; - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of( - PolarisContextConfiguration.class, - PolarisDiscoveryAutoConfiguration.class, - PolarisDiscoveryClientConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) - .withPropertyValues("server.port=" + PORT) - .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisContextConfiguration.class, + PolarisDiscoveryAutoConfiguration.class, + PolarisDiscoveryClientConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); - @BeforeClass - public static void beforeClass() throws Exception { - namingServer = NamingServer.startNamingServer(10081); - } + @BeforeClass + public static void beforeClass() throws Exception { + namingServer = NamingServer.startNamingServer(10081); + } - @AfterClass - public static void afterClass() throws Exception { - if (null != namingServer) { - namingServer.terminate(); - } - } + @AfterClass + public static void afterClass() throws Exception { + if (null != namingServer) { + namingServer.terminate(); + } + } - @Test - public void testDefaultInitialization() { - this.contextRunner.run(context -> { - assertThat(context).hasSingleBean(ProviderAPI.class); - assertThat(context).hasSingleBean(ConsumerAPI.class); - assertThat(context).hasSingleBean(PolarisProperties.class); - assertThat(context).hasSingleBean(PolarisServiceDiscovery.class); - }); - } + @Test + public void testDefaultInitialization() { + this.contextRunner.run(context -> { + assertThat(context).hasSingleBean(ProviderAPI.class); + assertThat(context).hasSingleBean(ConsumerAPI.class); + assertThat(context).hasSingleBean(PolarisProperties.class); + assertThat(context).hasSingleBean(PolarisServiceDiscovery.class); + }); + } - @Configuration - @EnableAutoConfiguration - @EnableDiscoveryClient - static class PolarisDiscoveryAutoConfiguration { + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + static class PolarisDiscoveryAutoConfiguration { - } + } } diff --git a/spring-cloud-tencent-starters/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 similarity index 53% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientConfigurationTest.java index 05c26209..c4738115 100644 --- a/spring-cloud-tencent-starters/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,59 +17,69 @@ package com.tencent.cloud.polaris.discovery; -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 com.tencent.cloud.polaris.context.PolarisContextConfiguration; import com.tencent.polaris.test.mock.discovery.NamingServer; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; + import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 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.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link PolarisDiscoveryClientConfiguration} + * + * @author Haotian Zhang + */ public class PolarisDiscoveryClientConfigurationTest { - private static NamingServer namingServer; + private static NamingServer namingServer; + + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisContextConfiguration.class, + PolarisDiscoveryClientConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); + + @BeforeClass + public static void beforeClass() throws Exception { + namingServer = NamingServer.startNamingServer(10081); + } - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of( - PolarisContextConfiguration.class, - PolarisDiscoveryClientConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) - .withPropertyValues("server.port=" + PORT) - .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); + @AfterClass + public static void afterClass() throws Exception { + if (null != namingServer) { + namingServer.terminate(); + } + } - @BeforeClass - public static void beforeClass() throws Exception { - namingServer = NamingServer.startNamingServer(10081); - } + @Test + public void testDefaultInitialization() { + this.contextRunner.run(context -> assertThat(context) + .hasSingleBean(PolarisDiscoveryClient.class)); + } - @AfterClass - public static void afterClass() throws Exception { - if (null != namingServer) { - namingServer.terminate(); - } - } + @Test + public void testDiscoveryBlockingDisabled() { + this.contextRunner + .withPropertyValues("spring.cloud.discovery.blocking.enabled=false") + .run(context -> assertThat(context) + .doesNotHaveBean(PolarisDiscoveryClient.class)); + } - @Test - public void testDefaultInitialization() { - this.contextRunner.run(context -> assertThat(context).hasSingleBean(PolarisDiscoveryClient.class)); - } + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + static class PolarisDiscoveryClientConfiguration { - @Test - public void testDiscoveryBlockingDisabled() { - this.contextRunner.withPropertyValues("spring.cloud.discovery.blocking.enabled=false") - .run(context -> assertThat(context).doesNotHaveBean(PolarisDiscoveryClient.class)); - } + } - @Configuration - @EnableAutoConfiguration - @EnableDiscoveryClient - static class PolarisDiscoveryClientConfiguration { - } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java similarity index 65% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java index ceefa8f9..baad9d36 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java @@ -17,52 +17,61 @@ package com.tencent.cloud.polaris.discovery; -import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - import java.util.List; -import com.tencent.cloud.polaris.pojo.PolarisServiceInstance; +import com.tencent.cloud.common.pojo.PolarisServiceInstance; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.modules.junit4.PowerMockRunner; + import org.springframework.cloud.client.ServiceInstance; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Test for {@link PolarisDiscoveryClient} + * + * @author Haotian Zhang + */ @RunWith(PowerMockRunner.class) @PowerMockIgnore("javax.management.*") public class PolarisDiscoveryClientTest { - @Mock - private PolarisServiceDiscovery polarisServiceDiscovery; + @Mock + private PolarisServiceDiscovery polarisServiceDiscovery; + + @InjectMocks + private PolarisDiscoveryClient client; - @InjectMocks - private PolarisDiscoveryClient client; + @Test + public void testGetInstances() { - @Test - public void testGetInstances() { + when(polarisServiceDiscovery.getInstances(anyString())) + .thenReturn(singletonList(mock(PolarisServiceInstance.class))); - when(polarisServiceDiscovery.getInstances(anyString())).thenReturn(singletonList(mock(PolarisServiceInstance.class))); + List serviceInstances = client.getInstances(SERVICE_PROVIDER); - List serviceInstances = client.getInstances(SERVICE_PROVIDER); + assertThat(serviceInstances).isNotEmpty(); + } - assertThat(serviceInstances).isNotEmpty(); - } + @Test + public void testGetServices() { - @Test - public void testGetServices() { + when(polarisServiceDiscovery.getServices()) + .thenReturn(singletonList(SERVICE_PROVIDER)); - when(polarisServiceDiscovery.getServices()).thenReturn(singletonList(SERVICE_PROVIDER)); + List services = client.getServices(); - List services = client.getServices(); + assertThat(services).contains(SERVICE_PROVIDER).size().isEqualTo(1); - assertThat(services).contains(SERVICE_PROVIDER).size().isEqualTo(1); + } - } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java new file mode 100644 index 00000000..de38a3b1 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java @@ -0,0 +1,118 @@ +/* + * 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 java.util.List; + +import com.tencent.cloud.polaris.context.PolarisContextConfiguration; +import com.tencent.polaris.api.exception.PolarisException; +import com.tencent.polaris.api.pojo.ServiceKey; +import com.tencent.polaris.test.mock.discovery.NamingServer; +import com.tencent.polaris.test.mock.discovery.NamingService; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.annotation.Configuration; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.PORT; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link PolarisServiceDiscovery} + * + * @author Haotian Zhang + */ +public class PolarisServiceDiscoveryTest { + + private static NamingServer namingServer; + + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisContextConfiguration.class, + PolarisServiceDiscoveryTest.PolarisPropertiesConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisDiscoveryAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") + .withPropertyValues( + "spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) + .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); + + @BeforeClass + public static void beforeClass() throws Exception { + namingServer = NamingServer.startNamingServer(10081); + + // add service with 3 instances + NamingService.InstanceParameter instanceParameter = new NamingService.InstanceParameter(); + instanceParameter.setHealthy(true); + instanceParameter.setIsolated(false); + instanceParameter.setWeight(100); + ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER); + namingServer.getNamingService().batchAddInstances(serviceKey, PORT, 3, + instanceParameter); + } + + @AfterClass + public static void afterClass() throws Exception { + if (null != namingServer) { + namingServer.terminate(); + } + } + + @Test + public void testGetInstances() { + this.contextRunner.run(context -> { + PolarisServiceDiscovery polarisServiceDiscovery = context + .getBean(PolarisServiceDiscovery.class); + List serviceInstances = polarisServiceDiscovery + .getInstances(SERVICE_PROVIDER); + assertThat(serviceInstances.isEmpty()).isFalse(); + assertThat(serviceInstances).hasSize(3); + assertThat(serviceInstances.get(0).getPort()).isEqualTo(PORT); + assertThat(serviceInstances.get(1).getPort()).isEqualTo(PORT + 1); + assertThat(serviceInstances.get(2).getPort()).isEqualTo(PORT + 2); + }); + } + + @Test + public void testGetServices() throws PolarisException { + this.contextRunner.run(context -> { + PolarisServiceDiscovery polarisServiceDiscovery = context + .getBean(PolarisServiceDiscovery.class); + List services = polarisServiceDiscovery.getServices(); + assertThat(services.size()).isEqualTo(1); + }); + + } + + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + static class PolarisPropertiesConfiguration { + + } + +} diff --git a/spring-cloud-tencent-starters/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 similarity index 57% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientConfigurationTest.java index 330cde35..25dff7d4 100644 --- a/spring-cloud-tencent-starters/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,57 +17,63 @@ package com.tencent.cloud.polaris.discovery.reactive; -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 com.tencent.cloud.polaris.context.PolarisContextConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; import com.tencent.polaris.test.mock.discovery.NamingServer; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; + import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 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.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link PolarisReactiveDiscoveryClientConfiguration} + * + * @author Haotian Zhang + */ public class PolarisReactiveDiscoveryClientConfigurationTest { - private static NamingServer namingServer; + private static NamingServer namingServer; + + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisContextConfiguration.class, + PolarisReactiveDiscoveryClientConfiguration.class, + PolarisDiscoveryClientConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of( - PolarisContextConfiguration.class, - PolarisReactiveDiscoveryClientConfiguration.class, - PolarisDiscoveryClientConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) - .withPropertyValues("server.port=" + PORT) - .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); + @BeforeClass + public static void beforeClass() throws Exception { + namingServer = NamingServer.startNamingServer(10081); + } - @BeforeClass - public static void beforeClass() throws Exception { - namingServer = NamingServer.startNamingServer(10081); - } + @AfterClass + public static void afterClass() throws Exception { + if (null != namingServer) { + namingServer.terminate(); + } + } - @AfterClass - public static void afterClass() throws Exception { - if (null != namingServer) { - namingServer.terminate(); - } - } + @Test + public void testDefaultInitialization() { + this.contextRunner.run(context -> assertThat(context) + .hasSingleBean(PolarisReactiveDiscoveryClient.class)); + } - @Test - public void testDefaultInitialization() { - this.contextRunner.run(context -> assertThat(context) - .hasSingleBean(PolarisReactiveDiscoveryClient.class)); - } + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + static class PolarisReactiveDiscoveryClientConfiguration { + } - @Configuration - @EnableAutoConfiguration - @EnableDiscoveryClient - static class PolarisReactiveDiscoveryClientConfiguration { - } } diff --git a/spring-cloud-tencent-starters/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 similarity index 62% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientTest.java rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClientTest.java index aaca939f..99aa8f1d 100644 --- a/spring-cloud-tencent-starters/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 @@ -17,57 +17,65 @@ package com.tencent.cloud.polaris.discovery.reactive; -import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; -import static java.util.Collections.singletonList; -import static org.mockito.Mockito.when; - -import com.tencent.polaris.api.exception.PolarisException; -import com.tencent.cloud.polaris.discovery.PolarisServiceDiscovery; - import java.util.Arrays; +import com.tencent.cloud.polaris.discovery.PolarisServiceDiscovery; +import com.tencent.polaris.api.exception.PolarisException; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.cloud.client.ServiceInstance; import reactor.core.publisher.Flux; import reactor.test.StepVerifier; +import org.springframework.cloud.client.ServiceInstance; + +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static java.util.Collections.singletonList; +import static org.mockito.Mockito.when; + +/** + * Test for {@link PolarisReactiveDiscoveryClient} + * + * @author Haotian Zhang + */ @RunWith(PowerMockRunner.class) @PowerMockIgnore("javax.management.*") public class PolarisReactiveDiscoveryClientTest { - @Mock - private PolarisServiceDiscovery serviceDiscovery; + @Mock + private PolarisServiceDiscovery serviceDiscovery; - @Mock - private ServiceInstance serviceInstance; + @Mock + private ServiceInstance serviceInstance; - @InjectMocks - private PolarisReactiveDiscoveryClient client; + @InjectMocks + private PolarisReactiveDiscoveryClient client; - @Test - public void testGetInstances() throws PolarisException { + @Test + public void testGetInstances() throws PolarisException { - when(serviceDiscovery.getInstances(SERVICE_PROVIDER)).thenReturn(singletonList(serviceInstance)); + when(serviceDiscovery.getInstances(SERVICE_PROVIDER)) + .thenReturn(singletonList(serviceInstance)); - Flux instances = this.client.getInstances(SERVICE_PROVIDER); + Flux instances = this.client.getInstances(SERVICE_PROVIDER); - StepVerifier.create(instances).expectNextCount(1).expectComplete().verify(); - } + StepVerifier.create(instances).expectNextCount(1).expectComplete().verify(); + } - @Test - public void testGetServices() throws PolarisException { + @Test + public void testGetServices() throws PolarisException { - when(serviceDiscovery.getServices()).thenReturn(Arrays.asList(SERVICE_PROVIDER + 1, SERVICE_PROVIDER + 2)); + when(serviceDiscovery.getServices()) + .thenReturn(Arrays.asList(SERVICE_PROVIDER + 1, SERVICE_PROVIDER + 2)); - Flux services = this.client.getServices(); + Flux services = this.client.getServices(); - StepVerifier.create(services).expectNext(SERVICE_PROVIDER + 1, SERVICE_PROVIDER + 2) - .expectComplete().verify(); - } + StepVerifier.create(services) + .expectNext(SERVICE_PROVIDER + 1, SERVICE_PROVIDER + 2).expectComplete() + .verify(); + } } diff --git a/spring-cloud-tencent-starters/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 similarity index 58% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfigurationTest.java index 877903e6..12f7d6a7 100644 --- a/spring-cloud-tencent-starters/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 @@ -19,15 +19,12 @@ package com.tencent.cloud.polaris.registry; import com.tencent.cloud.polaris.context.PolarisContextConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; - -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 com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; import com.tencent.polaris.test.mock.discovery.NamingServer; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; + import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; @@ -35,43 +32,53 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration; 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.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link PolarisServiceRegistryAutoConfiguration} + * + * @author Haotian Zhang + */ public class PolarisServiceRegistryAutoConfigurationTest { - private static NamingServer namingServer; + private static NamingServer namingServer; + + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisContextConfiguration.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"); - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of( - PolarisContextConfiguration.class, - PolarisServiceRegistryAutoConfiguration.class, - PolarisDiscoveryClientConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) - .withPropertyValues("server.port=" + PORT) - .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); + @BeforeClass + public static void beforeClass() throws Exception { + namingServer = NamingServer.startNamingServer(10081); + } - @BeforeClass - public static void beforeClass() throws Exception { - namingServer = NamingServer.startNamingServer(10081); - } + @AfterClass + public static void afterClass() throws Exception { + if (null != namingServer) { + namingServer.terminate(); + } + } - @AfterClass - public static void afterClass() throws Exception { - if (null != namingServer) { - namingServer.terminate(); - } - } + @Test + public void testDefaultInitialization() { + this.contextRunner.run(context -> { + assertThat(context).hasSingleBean(PolarisDiscoveryAutoConfiguration.class); + assertThat(context) + .hasSingleBean(AutoServiceRegistrationAutoConfiguration.class); + }); + } - @Test - public void testDefaultInitialization() { - this.contextRunner.run(context -> { - assertThat(context).hasSingleBean(PolarisDiscoveryAutoConfiguration.class); - assertThat(context).hasSingleBean(AutoServiceRegistrationAutoConfiguration.class); - }); - } + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + static class PolarisServiceRegistryAutoConfiguration { - @Configuration - @EnableAutoConfiguration - @EnableDiscoveryClient - static class PolarisServiceRegistryAutoConfiguration { + } - } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java new file mode 100644 index 00000000..76aa9e6f --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java @@ -0,0 +1,120 @@ +/* + * 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.PolarisContextConfiguration; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; +import com.tencent.polaris.api.pojo.ServiceKey; +import com.tencent.polaris.test.mock.discovery.NamingServer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mockito; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.annotation.Configuration; + +import static com.tencent.polaris.test.common.Consts.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.junit.Assert.fail; +import static org.mockito.Mockito.when; + +/** + * Test for {@link PolarisServiceRegistry} + * + * @author Haotian Zhang + */ +public class PolarisServiceRegistryTest { + + private static NamingServer namingServer; + + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisContextConfiguration.class, + PolarisPropertiesConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisDiscoveryAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") + .withPropertyValues( + "spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) + .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); + + @BeforeClass + public static void beforeClass() throws Exception { + namingServer = NamingServer.startNamingServer(10081); + + // add service + namingServer.getNamingService() + .addService(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER)); + } + + @AfterClass + public static void afterClass() throws Exception { + if (null != namingServer) { + namingServer.terminate(); + } + } + + @Test + public void testRegister() { + this.contextRunner.run(context -> { + PolarisServiceRegistry registry = context + .getBean(PolarisServiceRegistry.class); + PolarisRegistration registration = Mockito.mock(PolarisRegistration.class); + when(registration.getHost()).thenReturn("127.0.0.1"); + when(registration.getPort()).thenReturn(PORT); + when(registration.getServiceId()).thenReturn(SERVICE_PROVIDER); + + try { + registry.register(registration); + } + catch (Exception e) { + fail(); + } + + try { + assertThat(registry.getStatus(registration)).isEqualTo("DOWN"); + } + catch (Exception e) { + fail(); + } + + try { + registry.deregister(registration); + } + catch (Exception e) { + fail(); + } + }); + } + + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + static class PolarisPropertiesConfiguration { + + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java similarity index 52% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListAutoConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java index 93b5c7c4..99660fb6 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java @@ -17,16 +17,12 @@ package com.tencent.cloud.polaris.ribbon; -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 com.netflix.client.config.DefaultClientConfigImpl; import com.netflix.client.config.IClientConfig; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import org.junit.Test; + import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; @@ -36,48 +32,59 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; -public class PolarisRibbonServerListAutoConfigurationTest { +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.PORT; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link PolarisRibbonServerListConfiguration} + * + * @author Haotian Zhang + */ +public class PolarisRibbonServerListConfigurationTest { - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of( - PolarisRibbonClientTest.class, - PolarisDiscoveryClientConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) - .withPropertyValues("server.port=" + PORT) - .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") - .withPropertyValues("spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) - .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisRibbonClientTest.class, + PolarisDiscoveryClientConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") + .withPropertyValues( + "spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) + .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); - @Test - public void testProperties() { - this.contextRunner.run(context -> { - PolarisDiscoveryHandler discoveryHandler = context.getBean(PolarisDiscoveryHandler.class); - PolarisServerList serverList = new PolarisServerList(discoveryHandler); - IClientConfig iClientConfig = context.getBean(IClientConfig.class); - serverList.initWithNiwsConfig(iClientConfig); + @Test + public void testProperties() { + this.contextRunner.run(context -> { + PolarisDiscoveryHandler discoveryHandler = context + .getBean(PolarisDiscoveryHandler.class); + PolarisServerList serverList = new PolarisServerList(discoveryHandler); + IClientConfig iClientConfig = context.getBean(IClientConfig.class); + serverList.initWithNiwsConfig(iClientConfig); - assertThat(serverList.getServiceId()).isEqualTo(SERVICE_PROVIDER); - }); - } + assertThat(serverList.getServiceId()).isEqualTo(SERVICE_PROVIDER); + }); + } - @Configuration - @EnableAutoConfiguration - @EnableDiscoveryClient - static class PolarisRibbonClientTest { + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + static class PolarisRibbonClientTest { - @Bean - IClientConfig iClientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.setClientName(SERVICE_PROVIDER); - return config; - } + @Bean + IClientConfig iClientConfig() { + DefaultClientConfigImpl config = new DefaultClientConfigImpl(); + config.setClientName(SERVICE_PROVIDER); + return config; + } - @Bean - @LoadBalanced - RestTemplate restTemplate() { - return new RestTemplate(); - } + @Bean + @LoadBalanced + RestTemplate restTemplate() { + return new RestTemplate(); + } - } + } } 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 new file mode 100644 index 00000000..53dd1eb9 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java @@ -0,0 +1,145 @@ +/* + * 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.ribbon; + +import java.util.List; + +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.Server; +import com.tencent.cloud.polaris.context.PolarisContextConfiguration; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; +import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; +import com.tencent.polaris.api.pojo.ServiceKey; +import com.tencent.polaris.test.mock.discovery.NamingServer; +import com.tencent.polaris.test.mock.discovery.NamingService; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.annotation.Configuration; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.PORT; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Test for {@link PolarisServerList} + * + * @author Haotian Zhang + */ +public class PolarisServerListTest { + + private static NamingServer namingServer; + + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisContextConfiguration.class, + PolarisServerListTest.PolarisPropertiesConfiguration.class, + PolarisDiscoveryClientConfiguration.class, + PolarisDiscoveryAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") + .withPropertyValues( + "spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) + .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); + + @BeforeClass + public static void beforeClass() throws Exception { + namingServer = NamingServer.startNamingServer(10081); + + // add service + namingServer.getNamingService() + .addService(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER)); + } + + @AfterClass + public static void afterClass() throws Exception { + if (null != namingServer) { + namingServer.terminate(); + } + } + + /** + * Test {@link PolarisServerList#getInitialListOfServers()} with empty server list. + */ + @Test + @SuppressWarnings("unchecked") + public void test1() { + this.contextRunner.run(context -> { + // mock + IClientConfig iClientConfig = mock(IClientConfig.class); + when(iClientConfig.getClientName()).thenReturn(SERVICE_PROVIDER); + PolarisDiscoveryHandler polarisDiscoveryHandler = context + .getBean(PolarisDiscoveryHandler.class); + PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); + serverList.initWithNiwsConfig(iClientConfig); + + List servers = serverList.getInitialListOfServers(); + assertThat(servers).isEmpty(); + }); + } + + /** + * Test {@link PolarisServerList#getUpdatedListOfServers()} with server list of size + * 3. + */ + @Test + @SuppressWarnings("unchecked") + public void test2() throws Exception { + this.contextRunner.run(context -> { + // mock + IClientConfig iClientConfig = mock(IClientConfig.class); + when(iClientConfig.getClientName()).thenReturn(SERVICE_PROVIDER); + PolarisDiscoveryHandler polarisDiscoveryHandler = context + .getBean(PolarisDiscoveryHandler.class); + PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); + serverList.initWithNiwsConfig(iClientConfig); + + // add service with 3 instances + NamingService.InstanceParameter instanceParameter = new NamingService.InstanceParameter(); + instanceParameter.setHealthy(true); + instanceParameter.setIsolated(false); + instanceParameter.setWeight(100); + ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER); + namingServer.getNamingService().batchAddInstances(serviceKey, PORT, 3, + instanceParameter); + + List servers = serverList.getUpdatedListOfServers(); + assertThat(servers).hasSize(3); + assertThat(servers.get(0).getPort()).isEqualTo(PORT); + assertThat(servers.get(1).getPort()).isEqualTo(PORT + 1); + assertThat(servers.get(2).getPort()).isEqualTo(PORT + 2); + }); + } + + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + static class PolarisPropertiesConfiguration { + + } + +} diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml new file mode 100644 index 00000000..ef74b7a7 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml @@ -0,0 +1,94 @@ + + + + spring-cloud-tencent + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + spring-cloud-starter-tencent-polaris-ratelimit + Spring Cloud Starter Tencent Polaris Ratelimit + + + + + com.tencent.cloud + spring-cloud-tencent-commons + + + + com.tencent.cloud + spring-cloud-tencent-polaris-context + + + + com.tencent.cloud + spring-cloud-tencent-commons + + + + com.tencent.cloud + spring-cloud-tencent-metadata + + + + + + com.tencent.polaris + polaris-ratelimit-factory + + + + com.tencent.polaris + polaris-test-common + test + + + + com.tencent.polaris + polaris-test-mock-discovery + test + + + + + org.springframework.boot + spring-boot-starter-web + true + + + + org.springframework.boot + spring-boot-starter-webflux + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.cloud + spring-cloud-starter-netflix-ribbon + test + + + + org.powermock + powermock-module-junit4 + test + + + + org.powermock + powermock-api-mockito2 + test + + + \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/RateLimitConfiguration.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/RateLimitConfiguration.java similarity index 50% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/RateLimitConfiguration.java rename to spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/RateLimitConfiguration.java index ea32c470..27a16189 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/RateLimitConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/RateLimitConfiguration.java @@ -15,18 +15,15 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.ratelimit; +package com.tencent.cloud.polaris.ratelimit.config; -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; - -import com.tencent.cloud.polaris.ratelimit.callee.QuotaCheckFilter; +import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant; +import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckReactiveFilter; +import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter; 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.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; @@ -34,42 +31,64 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +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; + /** * @author Haotian Zhang */ @Configuration -@ConditionalOnProperty(name = "spring.cloud.polaris.ratelimit.enabled", matchIfMissing = true) +@ConditionalOnProperty(name = "spring.cloud.polaris.ratelimit.enabled", + matchIfMissing = true) public class RateLimitConfiguration { - @Bean - @ConditionalOnMissingBean - public LimitAPI limitAPI(SDKContext polarisContext) { - return LimitAPIFactory.createLimitAPIByContext(polarisContext); - } + @Bean + @ConditionalOnMissingBean + public LimitAPI limitAPI(SDKContext polarisContext) { + return LimitAPIFactory.createLimitAPIByContext(polarisContext); + } + + /** + * Create when web application type is SERVLET. + */ + @Configuration + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) + static class QuotaCheckFilterConfig { + + @Bean + @ConditionalOnMissingBean + public QuotaCheckServletFilter quotaCheckFilter(LimitAPI limitAPI) { + return new QuotaCheckServletFilter(limitAPI); + } + + @Bean + public FilterRegistrationBean quotaFilterRegistrationBean( + QuotaCheckServletFilter quotaCheckServletFilter) { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>( + quotaCheckServletFilter); + registrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST); + registrationBean.setName("quotaFilterRegistrationBean"); + registrationBean.setOrder(RateLimitConstant.FILTER_ORDER); + return registrationBean; + } - /** - * 被调方限流 - */ - @Configuration - @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) - static class QuotaCheckFilterConfig { + } - @Bean - @ConditionalOnMissingBean - public QuotaCheckFilter quotaCheckFilter(LimitAPI limitAPI) { - return new QuotaCheckFilter(limitAPI); - } + /** + * Create when web application type is REACTIVE. + */ + @Configuration + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) + static class MetadataReactiveFilterConfig { - @Bean - public FilterRegistrationBean quotaFilterRegistrationBean( - QuotaCheckFilter quotaCheckFilter) { - FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(quotaCheckFilter); - registrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST); - registrationBean.setName("quotaFilterRegistrationBean"); - registrationBean.setOrder(QuotaCheckFilter.ORDER); - return registrationBean; - } - } + @Bean + public QuotaCheckReactiveFilter quotaCheckReactiveFilter(LimitAPI limitAPI) { + return new QuotaCheckReactiveFilter(limitAPI); + } + } } diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignPlugin.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java similarity index 65% rename from spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignPlugin.java rename to spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java index add79d7b..c5fde4af 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignPlugin.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/constant/RateLimitConstant.java @@ -15,35 +15,28 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.feign; +package com.tencent.cloud.polaris.ratelimit.constant; import org.springframework.core.Ordered; /** - * Pre plugin used by PluggableFeign. + * Constant for rate-limiter. * * @author Haotian Zhang */ -public interface PluggableFeignPlugin extends Ordered { +public final class RateLimitConstant { - /** - * Get name of plugin - * - * @return - */ - String getName(); + /** + * Order of filter. + */ + public static final int FILTER_ORDER = Ordered.HIGHEST_PRECEDENCE + 10; - /** - * Get type of plugin - * @see PluggableFeignPluginType - * - * @return - */ - PluggableFeignPluginType getType(); + /** + * Info of rate limit. + */ + public static String QUOTA_LIMITED_INFO = "request blocked by polaris, reason is "; - /** - * Run the plugin - */ - void run(PluggableFeignContext context); + private RateLimitConstant() { + } } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java new file mode 100644 index 00000000..2d9fffaa --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java @@ -0,0 +1,106 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.ratelimit.filter; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +import com.tencent.cloud.metadata.constant.MetadataConstant; +import com.tencent.cloud.metadata.context.MetadataContext; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant; +import com.tencent.cloud.polaris.ratelimit.utils.QuotaCheckUtils; +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 org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +import org.springframework.core.Ordered; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; + +/** + * Reactive filter to check quota. + * + * @author Haotian Zhang + */ +public class QuotaCheckReactiveFilter implements WebFilter, Ordered { + + private static final Logger LOG = LoggerFactory + .getLogger(QuotaCheckReactiveFilter.class); + + private final LimitAPI limitAPI; + + public QuotaCheckReactiveFilter(LimitAPI limitAPI) { + this.limitAPI = limitAPI; + } + + @Override + public int getOrder() { + return RateLimitConstant.FILTER_ORDER; + } + + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + // get metadata of current thread + MetadataContext metadataContext = exchange + .getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT); + + String localNamespace = MetadataContextHolder.get() + .getSystemMetadata(MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE); + String localService = MetadataContextHolder.get() + .getSystemMetadata(MetadataConstant.SystemMetadataKey.LOCAL_SERVICE); + String method = MetadataContextHolder.get() + .getSystemMetadata(MetadataConstant.SystemMetadataKey.LOCAL_PATH); + Map labels = null; + if (StringUtils.isNotBlank(method)) { + labels = new HashMap<>(); + labels.put("method", method); + } + + try { + QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(limitAPI, + localNamespace, localService, 1, labels, null); + if (quotaResponse.getCode() == QuotaResultCode.QuotaResultLimited) { + ServerHttpResponse response = exchange.getResponse(); + response.setStatusCode(HttpStatus.TOO_MANY_REQUESTS); + response.getHeaders().setContentType(MediaType.APPLICATION_JSON); + DataBuffer dataBuffer = response.bufferFactory().allocateBuffer().write( + (RateLimitConstant.QUOTA_LIMITED_INFO + quotaResponse.getInfo()) + .getBytes(StandardCharsets.UTF_8)); + return response.writeWith(Mono.just(dataBuffer)); + } + } + catch (Throwable t) { + // 限流API调用出现异常,不应该影响业务流程的调用 + LOG.error("fail to invoke getQuota, service is " + localService, t); + } + + return chain.filter(exchange); + } + +} diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java new file mode 100644 index 00000000..cbfe4e46 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java @@ -0,0 +1,97 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.ratelimit.filter; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant; +import com.tencent.cloud.polaris.ratelimit.utils.QuotaCheckUtils; +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 org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.core.annotation.Order; +import org.springframework.web.filter.OncePerRequestFilter; + +import static org.springframework.http.HttpStatus.TOO_MANY_REQUESTS; + +/** + * Servlet filter to check quota. + * + * @author Haotian Zhang + */ +@Order(RateLimitConstant.FILTER_ORDER) +public class QuotaCheckServletFilter extends OncePerRequestFilter { + + private static final Logger LOG = LoggerFactory + .getLogger(QuotaCheckServletFilter.class); + + private final LimitAPI limitAPI; + + public QuotaCheckServletFilter(LimitAPI limitAPI) { + this.limitAPI = limitAPI; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + String localNamespace = MetadataContextHolder.get() + .getSystemMetadata(SystemMetadataKey.LOCAL_NAMESPACE); + String localService = MetadataContextHolder.get() + .getSystemMetadata(SystemMetadataKey.LOCAL_SERVICE); + String method = MetadataContextHolder.get() + .getSystemMetadata(SystemMetadataKey.LOCAL_PATH); + Map labels = null; + if (StringUtils.isNotBlank(method)) { + labels = new HashMap<>(); + labels.put("method", method); + } + + try { + QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(limitAPI, + localNamespace, localService, 1, labels, null); + if (quotaResponse.getCode() == QuotaResultCode.QuotaResultLimited) { + response.setStatus(TOO_MANY_REQUESTS.value()); + response.getWriter().write( + RateLimitConstant.QUOTA_LIMITED_INFO + quotaResponse.getInfo()); + } + else { + filterChain.doFilter(request, response); + } + } + catch (Throwable t) { + // 限流API调用出现异常,不应该影响业务流程的调用 + LOG.error("fail to invoke getQuota, service is " + localService, t); + filterChain.doFilter(request, response); + } + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java similarity index 54% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java rename to spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java index df257077..bceb49e9 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java @@ -16,6 +16,8 @@ */ package com.tencent.cloud.polaris.ratelimit.utils; +import java.util.Map; + import com.tencent.polaris.api.plugin.ratelimiter.QuotaResult; import com.tencent.polaris.ratelimit.api.core.LimitAPI; import com.tencent.polaris.ratelimit.api.rpc.QuotaRequest; @@ -23,33 +25,37 @@ import com.tencent.polaris.ratelimit.api.rpc.QuotaResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Map; - /** - * Utils for quota checking + * Utils for quota checking. * * @author Haotian Zhang */ -public class QuotaCheckUtils { - - private static final Logger LOG = LoggerFactory.getLogger(QuotaCheckUtils.class); - - public static QuotaResponse getQuota(LimitAPI limitAPI, String namespace, String service, int count, - Map labels, String method) { - // build quota request - QuotaRequest quotaRequest = new QuotaRequest(); - quotaRequest.setNamespace(namespace); - quotaRequest.setService(service); - quotaRequest.setCount(count); - quotaRequest.setLabels(labels); - quotaRequest.setMethod(method); - - try { - return limitAPI.getQuota(quotaRequest); - } catch (Throwable throwable) { - LOG.error("fail to invoke getQuota of LimitAPI with QuotaRequest[{}].", quotaRequest, throwable); - return new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultOk, 0, "get quota failed")); - } - } +public final class QuotaCheckUtils { + + private static final Logger LOG = LoggerFactory.getLogger(QuotaCheckUtils.class); + + private QuotaCheckUtils() { + } + + public static QuotaResponse getQuota(LimitAPI limitAPI, String namespace, + String service, int count, Map labels, String method) { + // build quota request + QuotaRequest quotaRequest = new QuotaRequest(); + quotaRequest.setNamespace(namespace); + quotaRequest.setService(service); + quotaRequest.setCount(count); + quotaRequest.setLabels(labels); + quotaRequest.setMethod(method); + + try { + return limitAPI.getQuota(quotaRequest); + } + catch (Throwable throwable) { + LOG.error("fail to invoke getQuota of LimitAPI with QuotaRequest[{}].", + quotaRequest, throwable); + return new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultOk, 0, + "get quota failed")); + } + } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/additional-spring-configuration-metadata.json similarity index 100% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/additional-spring-configuration-metadata.json rename to spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/additional-spring-configuration-metadata.json diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..89a6c50a --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.tencent.cloud.polaris.ratelimit.config.RateLimitConfiguration diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java new file mode 100644 index 00000000..4aabf24c --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java @@ -0,0 +1,150 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.ratelimit.controller; + +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.test.mock.discovery.NamingServer; +import com.tencent.polaris.test.mock.discovery.NamingService; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +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.test.context.junit4.SpringRunner; +import org.springframework.web.client.HttpClientErrorException.TooManyRequests; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +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.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Test for rate-limit. + * + * @author Haotian Zhang + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + classes = { CalleeControllerTests.Config.class, TestController.class }, + properties = { "spring.application.name=java_provider_test", + "spring.cloud.polaris.discovery.namespace=Test", + "spring.cloud.polaris.address=grpc://127.0.0.1:10081" }) +public class CalleeControllerTests { + + private static NamingServer namingServer; + + @LocalServerPort + private int port; + + @Autowired + private RestTemplate restTemplate; + + @MockBean + private LimitAPI limitAPI; + + @BeforeClass + public static void beforeClass() throws Exception { + namingServer = NamingServer.startNamingServer(10081); + + // add service with 3 instances + NamingService.InstanceParameter instanceParameter = new NamingService.InstanceParameter(); + instanceParameter.setHealthy(true); + instanceParameter.setIsolated(false); + instanceParameter.setWeight(100); + ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER); + namingServer.getNamingService().batchAddInstances(serviceKey, PORT, 3, + instanceParameter); + } + + @AfterClass + public static void afterClass() throws Exception { + if (null != namingServer) { + namingServer.terminate(); + } + } + + @Before + public void setUp() { + QuotaResponse quotaResponse = mock(QuotaResponse.class); + when(quotaResponse.getCode()).thenReturn(QuotaResultCode.QuotaResultOk); + when(limitAPI.getQuota(any())).thenReturn(quotaResponse); + } + + @Test + public void test1() { + String url = "http://localhost:" + port + "/test/info"; + + boolean hasPassed = false; + boolean hasLimited = false; + for (int i = 0; i < 30; i++) { + try { + if (i > 9) { + QuotaResponse quotaResponse = mock(QuotaResponse.class); + when(quotaResponse.getCode()) + .thenReturn(QuotaResultCode.QuotaResultLimited); + when(quotaResponse.getInfo()) + .thenReturn("Testing rate limit after 10 times success."); + when(limitAPI.getQuota(any())).thenReturn(quotaResponse); + } + String result = restTemplate.getForObject(url, String.class); + System.out.println(result + " [" + i + "]"); + hasPassed = true; + } + catch (RestClientException e) { + if (e instanceof TooManyRequests) { + System.out.println(((TooManyRequests) e).getResponseBodyAsString()); + hasLimited = true; + } + else { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + } + } + Assert.assertTrue(hasPassed); + Assert.assertTrue(hasLimited); + } + + @Configuration + @EnableAutoConfiguration + public static class Config { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java similarity index 87% rename from spring-cloud-tencent-starters/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/ratelimit/controller/TestController.java index ff3d479f..1ede96b4 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/TestController.java @@ -21,15 +21,18 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; - +/** + * Test controller. + * + * @author Haotian Zhang + */ @RestController @RequestMapping("/test") public class TestController { - @GetMapping("/info") - public String info() throws Exception { - return "hello service info"; - } - + @GetMapping("/info") + public String info() throws Exception { + return "hello service info"; + } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/pom.xml b/spring-cloud-starter-tencent-polaris-router/pom.xml similarity index 59% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/pom.xml rename to spring-cloud-starter-tencent-polaris-router/pom.xml index 41697663..13f2b53a 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/pom.xml +++ b/spring-cloud-starter-tencent-polaris-router/pom.xml @@ -1,23 +1,23 @@ - - - spring-cloud-tencent-starters - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 - - spring-cloud-starter-tencent-polaris-router - Spring Cloud Starter Tencent Polaris Router - - - - - com.tencent.cloud - spring-cloud-tencent-commons + + + spring-cloud-tencent + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + spring-cloud-starter-tencent-polaris-router + Spring Cloud Starter Tencent Polaris Router + + + + + com.tencent.cloud + spring-cloud-tencent-commons diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRoutingLoadBalancer.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRoutingLoadBalancer.java new file mode 100644 index 00000000..1277ab17 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRoutingLoadBalancer.java @@ -0,0 +1,138 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.router; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.DynamicServerListLoadBalancer; +import com.netflix.loadbalancer.IPing; +import com.netflix.loadbalancer.IRule; +import com.netflix.loadbalancer.PollingServerListUpdater; +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; +import com.tencent.cloud.common.pojo.PolarisServer; +import com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import com.tencent.polaris.api.pojo.DefaultInstance; +import com.tencent.polaris.api.pojo.DefaultServiceInstances; +import com.tencent.polaris.api.pojo.Instance; +import com.tencent.polaris.api.pojo.ServiceInfo; +import com.tencent.polaris.api.pojo.ServiceInstances; +import com.tencent.polaris.api.pojo.ServiceKey; +import com.tencent.polaris.router.api.core.RouterAPI; +import com.tencent.polaris.router.api.rpc.ProcessRoutersRequest; +import com.tencent.polaris.router.api.rpc.ProcessRoutersResponse; +import org.apache.commons.lang.StringUtils; + +import org.springframework.util.CollectionUtils; + +/** + * Routing load balancer of polaris. + * + * @author Haotian Zhang + */ +public class PolarisRoutingLoadBalancer extends DynamicServerListLoadBalancer { + + private final RouterAPI routerAPI; + + public PolarisRoutingLoadBalancer(IClientConfig config, IRule rule, IPing ping, + ServerList serverList, RouterAPI routerAPI) { + super(config, rule, ping, serverList, null, new PollingServerListUpdater()); + this.routerAPI = routerAPI; + } + + @Override + public List getReachableServers() { + List allServers = super.getAllServers(); + if (CollectionUtils.isEmpty(allServers)) { + return allServers; + } + ServiceInstances serviceInstances = null; + if (allServers.get(0) instanceof PolarisServer) { + serviceInstances = ((PolarisServer) allServers.get(0)).getServiceInstances(); + } + else { + String serviceName; + // notice the difference between different service registries + if (StringUtils.isNotBlank( + allServers.get(0).getMetaInfo().getServiceIdForDiscovery())) { + serviceName = allServers.get(0).getMetaInfo().getServiceIdForDiscovery(); + } + else { + serviceName = allServers.get(0).getMetaInfo().getAppName(); + } + if (StringUtils.isBlank(serviceName)) { + throw new IllegalStateException( + "PolarisRoutingLoadBalancer only Server with AppName or ServiceIdForDiscovery attribute"); + } + ServiceKey serviceKey = new ServiceKey(MetadataContextHolder.LOCAL_NAMESPACE, + serviceName); + List instances = new ArrayList<>(8); + for (Server server : allServers) { + DefaultInstance instance = new DefaultInstance(); + instance.setNamespace(MetadataContextHolder.LOCAL_NAMESPACE); + instance.setService(serviceName); + instance.setHealthy(server.isAlive()); + instance.setProtocol(server.getScheme()); + instance.setId(server.getId()); + instance.setHost(server.getHost()); + instance.setPort(server.getPort()); + instance.setZone(server.getZone()); + instance.setWeight(100); + instances.add(instance); + } + serviceInstances = new DefaultServiceInstances(serviceKey, instances); + } + ProcessRoutersRequest processRoutersRequest = new ProcessRoutersRequest(); + processRoutersRequest.setDstInstances(serviceInstances); + String srcNamespace = MetadataContextHolder.get() + .getSystemMetadata(SystemMetadataKey.LOCAL_NAMESPACE); + String srcService = MetadataContextHolder.get() + .getSystemMetadata(SystemMetadataKey.LOCAL_SERVICE); + Map transitiveCustomMetadata = MetadataContextHolder.get() + .getAllTransitiveCustomMetadata(); + String method = MetadataContextHolder.get() + .getSystemMetadata(SystemMetadataKey.PEER_PATH); + processRoutersRequest.setMethod(method); + if (StringUtils.isNotBlank(srcNamespace) && StringUtils.isNotBlank(srcService)) { + ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.setNamespace(srcNamespace); + serviceInfo.setService(srcService); + serviceInfo.setMetadata(transitiveCustomMetadata); + processRoutersRequest.setSourceService(serviceInfo); + } + ProcessRoutersResponse processRoutersResponse = routerAPI + .processRouters(processRoutersRequest); + ServiceInstances filteredServiceInstances = processRoutersResponse + .getServiceInstances(); + List filteredInstances = new ArrayList<>(); + for (Instance instance : filteredServiceInstances.getInstances()) { + filteredInstances.add(new PolarisServer(serviceInstances, instance)); + } + return filteredInstances; + } + + @Override + public List getAllServers() { + return getReachableServers(); + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfiguration.java similarity index 82% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfiguration.java rename to spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfiguration.java index 8d33972a..5a7469ea 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfiguration.java @@ -21,6 +21,7 @@ import com.tencent.polaris.api.exception.PolarisException; import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.factory.api.RouterAPIFactory; import com.tencent.polaris.router.api.core.RouterAPI; + import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -37,20 +38,22 @@ import org.springframework.context.annotation.Configuration; */ @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties -@ConditionalOnProperty(value = "spring.cloud.polaris.loadbalancer.enabled", matchIfMissing = true) +@ConditionalOnProperty(value = "spring.cloud.polaris.loadbalancer.enabled", + matchIfMissing = true) @AutoConfigureAfter(RibbonAutoConfiguration.class) @RibbonClients(defaultConfiguration = PolarisRibbonClientConfiguration.class) public class PolarisRibbonAutoConfiguration { - @Bean - @ConditionalOnMissingBean - public PolarisRibbonProperties polarisRibbonProperties() { - return new PolarisRibbonProperties(); - } + @Bean + @ConditionalOnMissingBean + public PolarisRibbonProperties polarisRibbonProperties() { + return new PolarisRibbonProperties(); + } + + @Bean(name = "polarisRoute") + @ConditionalOnMissingBean + public RouterAPI polarisRouter(SDKContext polarisContext) throws PolarisException { + return RouterAPIFactory.createRouterAPIByContext(polarisContext); + } - @Bean(name = "polarisRoute") - @ConditionalOnMissingBean - public RouterAPI polarisRouter(SDKContext polarisContext) throws PolarisException { - return RouterAPIFactory.createRouterAPIByContext(polarisContext); - } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonClientConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonClientConfiguration.java similarity index 69% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonClientConfiguration.java rename to spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonClientConfiguration.java index 5d0ed05b..050b1ac5 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonClientConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonClientConfiguration.java @@ -27,6 +27,7 @@ import com.tencent.cloud.polaris.router.PolarisRoutingLoadBalancer; import com.tencent.cloud.polaris.router.rule.PolarisLoadBalanceRule; import com.tencent.cloud.polaris.router.rule.PolarisWeightedRandomRule; import com.tencent.polaris.router.api.core.RouterAPI; + import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -37,20 +38,24 @@ import org.springframework.context.annotation.Configuration; @Configuration public class PolarisRibbonClientConfiguration { - @Bean - @ConditionalOnMissingBean - public IRule polarisRibbonRule(PolarisRibbonProperties polarisRibbonProperties) { - switch (PolarisLoadBalanceRule.fromStrategy(polarisRibbonProperties.getPolicy())) { - case WEIGHTED_RANDOM_RULE: - default: - return new PolarisWeightedRandomRule(); - } - } + @Bean + @ConditionalOnMissingBean + public IRule polarisRibbonRule(PolarisRibbonProperties polarisRibbonProperties) { + switch (PolarisLoadBalanceRule + .fromStrategy(polarisRibbonProperties.getStrategy())) { + case WEIGHTED_RANDOM_RULE: + default: + return new PolarisWeightedRandomRule(); + } + } + + @Bean + @ConditionalOnMissingBean + public ILoadBalancer polarisRoutingLoadBalancer(IClientConfig iClientConfig, + IRule iRule, IPing iPing, ServerList serverList, + RouterAPI polarisRouter) { + return new PolarisRoutingLoadBalancer(iClientConfig, iRule, iPing, serverList, + polarisRouter); + } - @Bean - @ConditionalOnMissingBean - public ILoadBalancer polarisRoutingLoadBalancer(IClientConfig iClientConfig, IRule iRule, IPing iPing, - ServerList serverList, RouterAPI polarisRouter) { - return new PolarisRoutingLoadBalancer(iClientConfig, iRule, iPing, serverList, polarisRouter); - } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonProperties.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonProperties.java similarity index 54% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonProperties.java rename to spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonProperties.java index 6e6ab501..db5e14fd 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonProperties.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRibbonProperties.java @@ -21,44 +21,45 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; /** + * Properties of Ribbon. + * * @author Haotian Zhang */ @ConfigurationProperties("spring.cloud.polaris.ribbon") public class PolarisRibbonProperties { - /** - * 是否开启负载均衡 - */ - @Value("${spring.cloud.polaris.loadbalancer.enabled:#{true}}") - private Boolean loadbalancerEnabled; + /** + * If load-balance enabled. + */ + @Value("${spring.cloud.polaris.discovery.loadbalancer.enabled:#{true}}") + private Boolean loadbalancerEnabled; + + /** + * Load balance strategy. + */ + @Value("${spring.cloud.polaris.loadbalancer.strategy:#{'weightedRandom'}}") + private String strategy; - /** - * loadbalnce strategy - */ - @Value("${spring.cloud.polaris.loadbalancer.strategy:#{'weightedRandom'}}") - private String policy; + public String getStrategy() { + return strategy; + } - public String getPolicy() { - return policy; - } + public void setStrategy(String strategy) { + this.strategy = strategy; + } - public void setPolicy(String policy) { - this.policy = policy; - } + public Boolean getLoadbalancerEnabled() { + return loadbalancerEnabled; + } - public Boolean getLoadbalancerEnabled() { - return loadbalancerEnabled; - } + public void setLoadbalancerEnabled(Boolean loadbalancerEnabled) { + this.loadbalancerEnabled = loadbalancerEnabled; + } - public void setLoadbalancerEnabled(Boolean loadbalancerEnabled) { - this.loadbalancerEnabled = loadbalancerEnabled; - } + @Override + public String toString() { + return "PolarisRibbonProperties{" + "loadbalancerEnabled=" + loadbalancerEnabled + + ", strategy='" + strategy + '\'' + '}'; + } - @Override - public String toString() { - return "PolarisRibbonProperties{" + - "loadbalancerEnabled=" + loadbalancerEnabled + - ", policy='" + policy + '\'' + - '}'; - } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisLoadBalanceRule.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisLoadBalanceRule.java similarity index 61% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisLoadBalanceRule.java rename to spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisLoadBalanceRule.java index b39b9e17..b95f3519 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisLoadBalanceRule.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisLoadBalanceRule.java @@ -20,34 +20,33 @@ package com.tencent.cloud.polaris.router.rule; import java.util.Arrays; /** + * Load balance rule. + * * @author Haotian Zhang */ public enum PolarisLoadBalanceRule { - /** - * 加权随机 - */ - WEIGHTED_RANDOM_RULE("weighted_random"); - - /** - * 策略 - */ - String policy; - - PolarisLoadBalanceRule(String strategy) { - this.policy = strategy; - } - - public static PolarisLoadBalanceRule fromStrategy(String strategy) { - return Arrays.stream(values()).filter(t -> t.getPolicy().equals(strategy)).findAny() - .orElse(WEIGHTED_RANDOM_RULE); - } - - /** - * {@link #policy}的getter方法。 - */ - public String getPolicy() { - return policy; - } + /** + * Weighted random load balance rule. + */ + WEIGHTED_RANDOM_RULE("weighted_random"); + + /** + * Load balance strategy. + */ + final String policy; + + PolarisLoadBalanceRule(String strategy) { + this.policy = strategy; + } + + public static PolarisLoadBalanceRule fromStrategy(String strategy) { + return Arrays.stream(values()).filter(t -> t.getPolicy().equals(strategy)) + .findAny().orElse(WEIGHTED_RANDOM_RULE); + } + + public String getPolicy() { + return policy; + } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisWeightedRandomRule.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisWeightedRandomRule.java similarity index 54% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisWeightedRandomRule.java rename to spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisWeightedRandomRule.java index d9dffa23..4da574cf 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisWeightedRandomRule.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisWeightedRandomRule.java @@ -17,51 +17,57 @@ package com.tencent.cloud.polaris.router.rule; +import java.util.List; + import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.Server; -import com.tencent.cloud.polaris.pojo.PolarisServer; +import com.tencent.cloud.common.pojo.PolarisServer; import com.tencent.polaris.api.config.consumer.LoadBalanceConfig; import com.tencent.polaris.api.pojo.Instance; import com.tencent.polaris.router.api.core.RouterAPI; import com.tencent.polaris.router.api.rpc.ProcessLoadBalanceRequest; import com.tencent.polaris.router.api.rpc.ProcessLoadBalanceResponse; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; -import java.util.List; - /** + * Weighted random load balance strategy. + * * @author Haotian Zhang */ public class PolarisWeightedRandomRule extends AbstractLoadBalancerRule { - private static final String POLICY = LoadBalanceConfig.LOAD_BALANCE_WEIGHTED_RANDOM; + private static final String POLICY = LoadBalanceConfig.LOAD_BALANCE_WEIGHTED_RANDOM; + + @Autowired + private RouterAPI polarisRouter; - @Autowired - private RouterAPI polarisRouter; + @Override + public void initWithNiwsConfig(IClientConfig clientConfig) { - @Override - public void initWithNiwsConfig(IClientConfig clientConfig) { + } - } + @Override + public Server choose(Object key) { + List allServers = getLoadBalancer().getReachableServers(); + if (CollectionUtils.isEmpty(allServers)) { + return null; + } + Server server = allServers.get(0); + if (!(server instanceof PolarisServer)) { + throw new IllegalStateException( + "PolarisDiscoveryRule only support PolarisServer instances"); + } + PolarisServer polarisServer = (PolarisServer) server; + ProcessLoadBalanceRequest request = new ProcessLoadBalanceRequest(); + request.setDstInstances(polarisServer.getServiceInstances()); + request.setLbPolicy(POLICY); + ProcessLoadBalanceResponse processLoadBalanceResponse = polarisRouter + .processLoadBalance(request); + Instance targetInstance = processLoadBalanceResponse.getTargetInstance(); + return new PolarisServer(polarisServer.getServiceInstances(), targetInstance); + } - @Override - public Server choose(Object key) { - List allServers = getLoadBalancer().getReachableServers(); - if (CollectionUtils.isEmpty(allServers)) { - return null; - } - Server server = allServers.get(0); - if (!(server instanceof PolarisServer)) { - throw new IllegalStateException("PolarisDiscoveryRule only support PolarisServer instances"); - } - PolarisServer polarisServer = (PolarisServer) server; - ProcessLoadBalanceRequest request = new ProcessLoadBalanceRequest(); - request.setDstInstances(polarisServer.getServiceInstances()); - request.setLbPolicy(POLICY); - ProcessLoadBalanceResponse processLoadBalanceResponse = polarisRouter.processLoadBalance(request); - Instance targetInstance = processLoadBalanceResponse.getTargetInstance(); - return new PolarisServer(polarisServer.getServiceInstances(), targetInstance); - } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/additional-spring-configuration-metadata.json similarity index 100% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/additional-spring-configuration-metadata.json rename to spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/additional-spring-configuration-metadata.json diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories rename to spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfigurationTest.java similarity index 62% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfigurationTest.java index b6ec3abe..cd92a08d 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfigurationTest.java @@ -19,6 +19,7 @@ package com.tencent.cloud.polaris.router.config; import com.tencent.polaris.router.api.core.RouterAPI; import org.junit.Test; + import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -29,29 +30,31 @@ import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; import static org.assertj.core.api.Assertions.assertThat; /** - * @author skyehtzhang + * Test for {@link PolarisRibbonAutoConfiguration} + * + * @author Haotian Zhang */ public class PolarisRibbonAutoConfigurationTest { - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of( - PolarisRibbonTest.class, - PolarisRibbonAutoConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) - .withPropertyValues("server.port=" + PORT) - .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); - - @Test - public void testDefaultInitialization() { - this.contextRunner.run(context -> { - assertThat(context).hasSingleBean(RouterAPI.class); - assertThat(context).hasSingleBean(PolarisRibbonProperties.class); - }); - } - - @Configuration - @EnableAutoConfiguration - static class PolarisRibbonTest { - - } + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(PolarisRibbonTest.class, + PolarisRibbonAutoConfiguration.class)) + .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) + .withPropertyValues("server.port=" + PORT) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); + + @Test + public void testDefaultInitialization() { + this.contextRunner.run(context -> { + assertThat(context).hasSingleBean(RouterAPI.class); + assertThat(context).hasSingleBean(PolarisRibbonProperties.class); + }); + } + + @Configuration + @EnableAutoConfiguration + static class PolarisRibbonTest { + + } + } diff --git a/spring-cloud-tencent-commons/pom.xml b/spring-cloud-tencent-commons/pom.xml new file mode 100644 index 00000000..2df9ab98 --- /dev/null +++ b/spring-cloud-tencent-commons/pom.xml @@ -0,0 +1,79 @@ + + + + spring-cloud-tencent + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + spring-cloud-tencent-commons + Spring Cloud Tencent Commons + + + 3.2.2 + 2.5 + 2.7 + + + + + + com.tencent.polaris + polaris-model + + + + + org.springframework.boot + spring-boot-autoconfigure + + + + org.springframework.boot + spring-boot-configuration-processor + + + + org.springframework.boot + spring-boot-starter-json + + + + org.springframework.cloud + spring-cloud-commons + + + + com.netflix.ribbon + ribbon-loadbalancer + + + + com.google.guava + guava + + + + commons-collections + commons-collections + ${commons.collections.version} + + + + commons-lang + commons-lang + ${commons.lang.version} + + + + commons-io + commons-io + ${commons.io.version} + + + + \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java similarity index 65% rename from spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java rename to spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java index 3436b661..b7d2fae8 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java @@ -22,26 +22,28 @@ package com.tencent.cloud.common.constant; * * @author skyehtzhang */ -public interface ContextConstant { - - /** - * Order of configuration modifier. - */ - interface ModifierOrder { - - /** - * First modifier order. - */ - Integer FIRST = Integer.MIN_VALUE; - - /** - * Last modifier order. - */ - Integer LAST = Integer.MAX_VALUE; - - /** - * Order of circuit breaker configuration modifier. - */ - Integer CIRCUIT_BREAKER_ORDER = 1; - } +public final class ContextConstant { + + /** + * Order of configuration modifier. + */ + public static final class ModifierOrder { + + /** + * First modifier order. + */ + public static Integer FIRST = Integer.MIN_VALUE; + + /** + * Last modifier order. + */ + public static Integer LAST = Integer.MAX_VALUE; + + /** + * Order of circuit breaker configuration modifier. + */ + public static Integer CIRCUIT_BREAKER_ORDER = 1; + + } + } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServer.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServer.java new file mode 100644 index 00000000..be55ed31 --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServer.java @@ -0,0 +1,111 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.common.pojo; + +import java.util.Map; +import java.util.Objects; + +import com.netflix.loadbalancer.Server; +import com.tencent.polaris.api.pojo.Instance; +import com.tencent.polaris.api.pojo.ServiceInstances; +import org.apache.commons.lang.StringUtils; + +/** + * Polaris' implementation of {@link Server}. + * + * @author Haotian Zhang + */ +public class PolarisServer extends Server { + + private final ServiceInstances serviceInstances; + + private final Instance instance; + + private final MetaInfo metaInfo; + + public PolarisServer(ServiceInstances serviceInstances, Instance instance) { + super(instance.getHost(), instance.getPort()); + if (StringUtils.equalsIgnoreCase(instance.getProtocol(), "https")) { + setSchemea("https"); + } + else { + setSchemea("http"); + } + this.serviceInstances = serviceInstances; + this.instance = instance; + this.metaInfo = new MetaInfo() { + @Override + public String getAppName() { + return instance.getService(); + } + + @Override + public String getServerGroup() { + return null; + } + + @Override + public String getServiceIdForDiscovery() { + return instance.getService(); + } + + @Override + public String getInstanceId() { + return instance.getId(); + } + }; + } + + public Instance getInstance() { + return instance; + } + + @Override + public MetaInfo getMetaInfo() { + return metaInfo; + } + + public Map getMetadata() { + return instance.getMetadata(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + PolarisServer that = (PolarisServer) o; + return Objects.equals(instance, that.instance); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), instance); + } + + public ServiceInstances getServiceInstances() { + return serviceInstances; + } + +} diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.java new file mode 100644 index 00000000..ce244db0 --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/pojo/PolarisServiceInstance.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.common.pojo; + +import java.net.URI; +import java.util.Map; + +import com.tencent.polaris.api.pojo.Instance; +import org.apache.commons.lang.StringUtils; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; + +/** + * Polaris's implementation of {@link ServiceInstance}. + * + * @author Haotian Zhang + */ +public class PolarisServiceInstance implements ServiceInstance { + + private final Instance instance; + + private final boolean isSecure; + + private final String scheme; + + public PolarisServiceInstance(Instance instance) { + this.instance = instance; + this.isSecure = StringUtils.equalsIgnoreCase(instance.getProtocol(), "https"); + if (isSecure) { + scheme = "https"; + } + else { + scheme = "http"; + } + } + + @Override + public String getInstanceId() { + return ServiceInstance.super.getInstanceId(); + } + + @Override + public String getServiceId() { + return instance.getService(); + } + + @Override + public String getHost() { + return instance.getHost(); + } + + @Override + public int getPort() { + return instance.getPort(); + } + + @Override + public boolean isSecure() { + return this.isSecure; + } + + @Override + public URI getUri() { + return DefaultServiceInstance.getUri(this); + } + + @Override + public Map getMetadata() { + return instance.getMetadata(); + } + + @Override + public String getScheme() { + return this.scheme; + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java similarity index 52% rename from spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java rename to spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java index 5071628b..e945a7a2 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ApplicationContextAwareUtils.java @@ -23,47 +23,45 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; /** - * Spring Context Util + * Spring Context Util. * * @author Hongwei Zhu */ @Component public class ApplicationContextAwareUtils implements ApplicationContextAware { - private static ApplicationContext applicationContext; + private static ApplicationContext applicationContext; - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - ApplicationContextAwareUtils.applicationContext = applicationContext; - } + /** + * Get application context. + * @return application context + */ + public static ApplicationContext getApplicationContext() { + return applicationContext; + } - /** - * 获取上下文 - * - * @return Spring上下文 - */ - public static ApplicationContext getApplicationContext() { - return applicationContext; - } + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + ApplicationContextAwareUtils.applicationContext = applicationContext; + } - /** - * 获取Spring配置 - * - * @param key 配置名称 - * @return 配置值 - */ - public static String getProperties(String key) { - return applicationContext.getEnvironment().getProperty(key); - } + /** + * Get application property. + * @param key property name + * @return property value + */ + public static String getProperties(String key) { + return applicationContext.getEnvironment().getProperty(key); + } + + /** + * Get application property. If null, return default. + * @param key property name + * @param defaultValue default value + * @return property value + */ + public static String getProperties(String key, String defaultValue) { + return applicationContext.getEnvironment().getProperty(key, defaultValue); + } - /** - * 获取Spring配置
- * 没有配置时,返回默认值 - * - * @param key 配置名称 - * @param defaultValue 默认值 - * @return 配置值 - */ - public static String getProperties(String key, String defaultValue) { - return applicationContext.getEnvironment().getProperty(key, defaultValue); - } } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java new file mode 100644 index 00000000..628c718a --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java @@ -0,0 +1,84 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.common.util; + +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.util.StringUtils; + +/** + * Utils for Jackson. + * + * @author Haotian Zhang + */ +public final class JacksonUtils { + + /** + * Object Mapper. + */ + public static final ObjectMapper OM = new ObjectMapper(); + + private static final Logger LOG = LoggerFactory.getLogger(JacksonUtils.class); + + private JacksonUtils() { + + } + + /** + * Object to Json. + * @param object object to be serialized + * @param type of object + * @return Json String + */ + public static String serialize2Json(T object) { + try { + return OM.writeValueAsString(object); + } + catch (JsonProcessingException e) { + LOG.error("Object to Json failed. {}", object, e); + throw new RuntimeException("Object to Json failed.", e); + } + } + + /** + * Json to Map. + * @param jsonStr Json String + * @return Map + */ + public static Map deserialize2Map(String jsonStr) { + try { + if (StringUtils.hasText(jsonStr)) { + return OM.readValue(jsonStr, Map.class); + } + return new HashMap<>(); + } + catch (JsonProcessingException e) { + LOG.error( + "Json to map failed. check if the format of the json string[{}] is correct.", + jsonStr, e); + throw new RuntimeException("Json to map failed.", e); + } + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java similarity index 63% rename from spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java rename to spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java index b0aee0f4..67e4c921 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java @@ -20,24 +20,31 @@ package com.tencent.cloud.common.util; import java.lang.reflect.Field; /** - * Reflection Utils + * Reflection Utils. * * @author Haotian Zhang */ -public class ReflectionUtils { - - public static Object getFieldValue(Object instance, String fieldName) { - Field field = org.springframework.util.ReflectionUtils.findField(instance.getClass(), fieldName); - - field.setAccessible(true); - try { - return field.get(instance); - } catch (IllegalAccessException e) { - // ignore - } finally { - field.setAccessible(false); - } - return null; - } +public final class ReflectionUtils { + + private ReflectionUtils() { + + } + + public static Object getFieldValue(Object instance, String fieldName) { + Field field = org.springframework.util.ReflectionUtils + .findField(instance.getClass(), fieldName); + + field.setAccessible(true); + try { + return field.get(instance); + } + catch (IllegalAccessException e) { + // ignore + } + finally { + field.setAccessible(false); + } + return null; + } } diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories similarity index 99% rename from spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories rename to spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories index 7e757f5e..45b6e58e 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories @@ -1,3 +1,2 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.common.util.ApplicationContextAwareUtils - diff --git a/spring-cloud-tencent-coverage/pom.xml b/spring-cloud-tencent-coverage/pom.xml index 0780b079..681297c8 100644 --- a/spring-cloud-tencent-coverage/pom.xml +++ b/spring-cloud-tencent-coverage/pom.xml @@ -1,6 +1,6 @@ - spring-cloud-tencent @@ -44,11 +44,6 @@ spring-cloud-tencent-metadata
- - com.tencent.cloud - spring-cloud-tencent-feign - - com.tencent.cloud spring-cloud-starter-tencent-polaris-router diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 60165c6d..189b5fb0 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -121,24 +121,12 @@ ${revision} - - com.tencent.cloud - spring-cloud-tencent-polaris-gateway - ${revision} - - com.tencent.cloud spring-cloud-tencent-metadata ${revision} - - com.tencent.cloud - spring-cloud-tencent-feign - ${revision} - - com.tencent.cloud spring-cloud-starter-tencent-polaris-discovery diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderB.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderB.java index bab2c2a7..fb201cfd 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderB.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderB.java @@ -25,15 +25,15 @@ import org.springframework.web.bind.annotation.GetMapping; * * @author Haotian Zhang */ -@FeignClient(name = "polaris-circuitbreaker-example-b", fallback = ProviderBFallback.class) +@FeignClient(name = "polaris-circuitbreaker-example-b", + fallback = ProviderBFallback.class) public interface ProviderB { - /** - * 获取B的服务的信息 - * - * @return - */ - @GetMapping("/example/service/b/info") - String info(); + /** + * Get info of service B. + * @return info of service B + */ + @GetMapping("/example/service/b/info") + String info(); } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderBFallback.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderBFallback.java index f972e567..e71eb10d 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderBFallback.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderBFallback.java @@ -27,9 +27,9 @@ import org.springframework.stereotype.Component; @Component public class ProviderBFallback implements ProviderB { - @Override - public String info() { - return "trigger the refuse for service b"; - } + @Override + public String info() { + return "trigger the refuse for service b"; + } } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java index d3b15803..7a20778b 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java @@ -34,13 +34,13 @@ import org.springframework.web.client.RestTemplate; @EnableFeignClients public class ServiceA { - @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); - } + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } - public static void main(String[] args) { - SpringApplication.run(ServiceA.class); - } + public static void main(String[] args) { + SpringApplication.run(ServiceA.class); + } } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java index aadbfaac..b00e7522 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java @@ -33,41 +33,39 @@ import org.springframework.web.client.RestTemplate; @RequestMapping("/example/service/a") public class ServiceAController { - private final ProviderB polarisServiceB; + private final ProviderB polarisServiceB; - private final RestTemplate restTemplate; + private final RestTemplate restTemplate; - public ServiceAController(ProviderB polarisServiceB, RestTemplate restTemplate) { - this.polarisServiceB = polarisServiceB; - this.restTemplate = restTemplate; - } + public ServiceAController(ProviderB polarisServiceB, RestTemplate restTemplate) { + this.polarisServiceB = polarisServiceB; + this.restTemplate = restTemplate; + } - /** - * 获取当前服务的信息 - * - * @return 返回服务信息 - * @throws Exception - */ - @GetMapping("/info") - public String info() throws Exception { - return "hello world ! I'am a service"; - } + /** + * 获取当前服务的信息 + * @return 返回服务信息 + */ + @GetMapping("/info") + public String info() { + return "hello world ! I'am a service"; + } - /** - * 获取B服务的信息 - * - * @return 返回B服务的信息 - * @throws Exception - */ - @GetMapping("/getBServiceInfo") - public String getBServiceInfo() throws Exception { - return polarisServiceB.info(); - } + /** + * 获取B服务的信息 + * @return 返回B服务的信息 + */ + @GetMapping("/getBServiceInfo") + public String getBServiceInfo() { + return polarisServiceB.info(); + } - @RequestMapping(value = "/testRest", method = RequestMethod.GET) - public String testRest() { - ResponseEntity entity = restTemplate.getForEntity("http://polaris-circuitbreaker-example-b/example/service/b/info", String.class); - return entity.getBody(); - } + @RequestMapping(value = "/testRest", method = RequestMethod.GET) + public String testRest() { + ResponseEntity entity = restTemplate.getForEntity( + "http://polaris-circuitbreaker-example-b/example/service/b/info", + String.class); + return entity.getBody(); + } } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml index 32f2eb16..c6b7d843 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml @@ -37,4 +37,4 @@ ribbon: enabled: on serivceB: - url: http://localhost:48081 \ No newline at end of file + url: http://localhost:48081 diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/polaris.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/polaris.yml index 39d33bd6..af1466d2 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/polaris.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/polaris.yml @@ -264,11 +264,8 @@ consumer: metricStatTimeWindow: 100ms #描述:基于周期错误率的熔断策略配置 errorRate: - #描述:触发错误率熔断的阈值 - #类型:double - #范围:(0:1] - #默认值:0.5 - errorRateThreshold: 0.01 + #描述:触发错误率熔断的阈值百分比 + errorRateThreshold: 50 #描述:错误率熔断的最小统计单元数量 #类型:int #范围:[1:...] diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderA.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderA.java index df1fca9b..2e45cb07 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderA.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderA.java @@ -25,15 +25,15 @@ import org.springframework.web.bind.annotation.GetMapping; * * @author Haotian Zhang */ -@FeignClient(name = "polaris-circuitbreaker-example-a", fallback = ProviderAFallback.class) +@FeignClient(name = "polaris-circuitbreaker-example-a", + fallback = ProviderAFallback.class) public interface ProviderA { - /** - * 获取B的服务的信息 - * - * @return - */ - @GetMapping("/example/service/a/info") - String info(); + /** + * Get info of service A. + * @return info of service A + */ + @GetMapping("/example/service/a/info") + String info(); } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderAFallback.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderAFallback.java index cfbe437e..ef9deb1f 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderAFallback.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderAFallback.java @@ -27,8 +27,9 @@ import org.springframework.stereotype.Component; @Component public class ProviderAFallback implements ProviderA { - @Override - public String info() { - return "trigger the refuse for service a"; - } + @Override + public String info() { + return "trigger the refuse for service a"; + } + } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java index 8da0f9de..4fe91984 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java @@ -34,13 +34,13 @@ import org.springframework.web.client.RestTemplate; @EnableFeignClients public class ServiceB { - @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); - } + public static void main(String[] args) { + SpringApplication.run(ServiceB.class); + } - public static void main(String[] args) { - SpringApplication.run(ServiceB.class); - } + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } -} \ No newline at end of file +} diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java index df3c6af9..66fa40ce 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java @@ -33,43 +33,40 @@ import org.springframework.web.client.RestTemplate; @RequestMapping("/example/service/b") public class ServiceBController { - private final ProviderA polarisServiceA; + private final ProviderA polarisServiceA; - private final RestTemplate restTemplate; + private final RestTemplate restTemplate; - public ServiceBController(ProviderA polarisServiceA, RestTemplate restTemplate) { - this.polarisServiceA = polarisServiceA; - this.restTemplate = restTemplate; - } + public ServiceBController(ProviderA polarisServiceA, RestTemplate restTemplate) { + this.polarisServiceA = polarisServiceA; + this.restTemplate = restTemplate; + } - /** - * 获取当前服务的信息 - * - * @return 返回服务信息 - * @throws Exception - */ - @GetMapping("/info") - public String info() throws Exception { -// return "hello world ! I'am a service"; - throw new RuntimeException("failed for call my service"); - } + /** + * 获取当前服务的信息 + * @return 返回服务信息 + */ + @GetMapping("/info") + public String info() { + // return "hello world ! I'am a service"; + throw new RuntimeException("failed for call my service"); + } - /** - * 获取B服务的信息 - * - * @return 返回B服务的信息 - * @throws Exception - */ - @GetMapping("/getAServiceInfo") - public String getAServiceInfo() throws Exception { - return polarisServiceA.info(); - } - - @RequestMapping(value = "/testRest", method = RequestMethod.GET) - public String testRest() { - ResponseEntity entity = restTemplate.getForEntity("http://polaris-circuitbreaker-example-a/example/service/b/info", String.class); - return entity.getBody(); - } + /** + * 获取B服务的信息 + * @return 返回B服务的信息 + */ + @GetMapping("/getAServiceInfo") + public String getAServiceInfo() { + return polarisServiceA.info(); + } + @RequestMapping(value = "/testRest", method = RequestMethod.GET) + public String testRest() { + ResponseEntity entity = restTemplate.getForEntity( + "http://polaris-circuitbreaker-example-a/example/service/b/info", + String.class); + return entity.getBody(); + } } diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml index eedf3e1e..4e78d978 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml @@ -37,4 +37,4 @@ ribbon: enabled: on serivceB: - url: http://localhost:48081 \ No newline at end of file + url: http://localhost:48081 diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml index afdba705..169f2114 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml @@ -1,6 +1,6 @@ - polaris-discovery-example @@ -19,15 +19,15 @@ com.tencent.cloud - - - - + + + + - - - - + + + +
diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/DiscoveryCalleeController.java b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/DiscoveryCalleeController.java index 0ca911b7..5cf952ed 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/DiscoveryCalleeController.java +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/DiscoveryCalleeController.java @@ -17,6 +17,9 @@ package com.tencent.cloud.polaris.discovery.service.callee; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -29,26 +32,27 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/discovery/service/callee") public class DiscoveryCalleeController { - /** - * 获取当前服务的信息 - * - * @return 返回服务信息 - */ - @GetMapping("/info") - public String info() { - return "Discovery Service Callee"; - } - - /** - * 获取相加完的结果 - * - * @param value1 值1 - * @param value2 值2 - * @return 总值 - */ - @GetMapping("/sum") - public int sum(@RequestParam int value1, @RequestParam int value2) { - return value1 + value2; - } + private static Logger logger = LoggerFactory + .getLogger(DiscoveryCalleeController.class); + + /** + * 获取当前服务的信息 + * @return 返回服务信息 + */ + @GetMapping("/info") + public String info() { + return "Discovery Service Callee"; + } + + /** + * 获取相加完的结果 + * @param value1 值1 + * @param value2 值2 + * @return 总值 + */ + @GetMapping("/sum") + public int sum(@RequestParam int value1, @RequestParam int value2) { + return value1 + value2; + } } diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/DiscoveryCalleeService.java b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/DiscoveryCalleeService.java index bfe92d37..8f3195f2 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/DiscoveryCalleeService.java +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/java/com/tencent/cloud/polaris/discovery/service/callee/DiscoveryCalleeService.java @@ -19,14 +19,17 @@ package com.tencent.cloud.polaris.discovery.service.callee; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.bind.annotation.RestController; /** * @author Haotian Zhang */ @SpringBootApplication +@RestController public class DiscoveryCalleeService { - public static void main(String[] args) { - SpringApplication.run(DiscoveryCalleeService.class, args); - } + public static void main(String[] args) { + SpringApplication.run(DiscoveryCalleeService.class, args); + } + } 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 c681f756..c75893d3 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 @@ -7,18 +7,20 @@ spring: cloud: polaris: address: grpc://127.0.0.1:8091 - consul: - port: 8500 - host: 127.0.0.1 - enabled: true discovery: - register: true - instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port} - enabled: true - service-name: ${spring.application.name} - ip-address: localhost - prefer-ip-address: true -eureka: - client: - serviceUrl: - defaultZone: http://127.0.0.1:7654/eureka/ \ No newline at end of file + ip-address: 127.0.0.1 +# consul: +# port: 8500 +# host: 127.0.0.1 +# enabled: true +# discovery: +# register: true +# instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port} +# enabled: true +# service-name: ${spring.application.name} +# ip-address: localhost +# prefer-ip-address: true +#eureka: +# client: +# serviceUrl: +# defaultZone: http://127.0.0.1:7654/eureka/ diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/log4j.properties b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/log4j.properties index 9e520cb7..b0b20e72 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/log4j.properties +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/log4j.properties @@ -12,4 +12,4 @@ log4j.appender.FILE.File=applog/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log log4j.appender.FILE.Threshold=INFO log4j.appender.FILE.layout=org.apache.log4j.PatternLayout log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} [%5p] - %c -%F(%L) -%m%n -log4j.appender.FILE.MaxFileSize=10MB \ No newline at end of file +log4j.appender.FILE.MaxFileSize=10MB diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/polaris.yml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/polaris.yml index c6a3d334..8e0b95dc 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/polaris.yml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/polaris.yml @@ -3,4 +3,4 @@ global: discoverCluster: sameAsBuiltin: true healthCheckCluster: - sameAsBuiltin: true \ No newline at end of file + sameAsBuiltin: true diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml index e3372c51..11e6b940 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml @@ -1,6 +1,6 @@ - polaris-discovery-example @@ -23,20 +23,20 @@ com.tencent.cloud
- - - - + + + + - - - - + + + + - - com.tencent.cloud - spring-cloud-starter-tencent-polaris-router - + + + +
diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCalleeService.java b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCalleeService.java index bd4c51df..29e3f5cd 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCalleeService.java +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCalleeService.java @@ -24,16 +24,17 @@ import org.springframework.web.bind.annotation.RequestParam; /** * @author Haotian Zhang */ -@FeignClient(value = "DiscoveryCalleeService", fallback = DiscoveryCalleeServiceCallback.class) +@FeignClient(value = "DiscoveryCalleeService", + fallback = DiscoveryCalleeServiceCallback.class) public interface DiscoveryCalleeService { - /** - * 求和计算 - * - * @param value1 值1 - * @param value2 值2 - * @return 总值 - */ - @GetMapping("/discovery/service/callee/sum") - int sum(@RequestParam("value1") final int value1, @RequestParam("value2") final int value2); + /** + * 求和计算 + * @param value1 值1 + * @param value2 值2 + * @return 总值 + */ + @GetMapping("/discovery/service/callee/sum") + int sum(@RequestParam("value1") int value1, @RequestParam("value2") int value2); + } diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCalleeServiceCallback.java b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCalleeServiceCallback.java index c8e52a66..2d087b0a 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCalleeServiceCallback.java +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCalleeServiceCallback.java @@ -25,8 +25,9 @@ import org.springframework.stereotype.Component; @Component public class DiscoveryCalleeServiceCallback implements DiscoveryCalleeService { - @Override - public int sum(int value1, int value2) { - return 0; - } + @Override + public int sum(int value1, int value2) { + return 0; + } + } diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java index ae7b2f30..18a331db 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java @@ -31,42 +31,41 @@ import org.springframework.web.client.RestTemplate; @RequestMapping("/discovery/service/caller") public class DiscoveryCallerController { - @Autowired - private RestTemplate restTemplate; + @Autowired + private RestTemplate restTemplate; - @Autowired - private DiscoveryCalleeService discoveryCalleeService; + @Autowired + private DiscoveryCalleeService discoveryCalleeService; - /** - * 获取相加完的结果 - * - * @param value1 值1 - * @param value2 值2 - * @return 总值 - */ - @GetMapping("/feign") - public int feign(@RequestParam int value1, @RequestParam int value2) { - return discoveryCalleeService.sum(value1, value2); - } + /** + * 获取相加完的结果 + * @param value1 值1 + * @param value2 值2 + * @return 总值 + */ + @GetMapping("/feign") + public int feign(@RequestParam int value1, @RequestParam int value2) { + return discoveryCalleeService.sum(value1, value2); + } - /** - * 获取被调服务信息 - * - * @return 信息 - */ - @GetMapping("/rest") - public String rest() { - return restTemplate.getForObject("http://DiscoveryCalleeService/discovery/service/callee/info", String.class); - } + /** + * 获取被调服务信息 + * @return 信息 + */ + @GetMapping("/rest") + public String rest() { + return restTemplate.getForObject( + "http://DiscoveryCalleeService/discovery/service/callee/info", + String.class); + } + /** + * health check + * @return 信息 + */ + @GetMapping("/healthCheck") + public String healthCheck() { + return "pk ok"; + } - /** - * health check - * - * @return 信息 - */ - @GetMapping("/healthCheck") - public String healthCheck() { - return "pk ok"; - } } diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerService.java b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerService.java index 16e9539f..d410400b 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerService.java +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerService.java @@ -33,14 +33,14 @@ import org.springframework.web.client.RestTemplate; @EnableFeignClients public class DiscoveryCallerService { - @Bean - @LoadBalanced - public RestTemplate restTemplate() { - return new RestTemplate(); - } + public static void main(String[] args) { + SpringApplication.run(DiscoveryCallerService.class, args); + } - public static void main(String[] args) { - SpringApplication.run(DiscoveryCallerService.class, args); - } + @Bean + @LoadBalanced + public RestTemplate restTemplate() { + return new RestTemplate(); + } } 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 9093ea22..25306f56 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 @@ -11,20 +11,20 @@ spring: heartbeat: enabled: true health-check-url: /discovery/service/caller/healthCheck - consul: - port: 8500 - host: 127.0.0.1 - enabled: true - discovery: - register: true - health-check-path: /actuator/health - health-check-interval: 10s - instance-id: ${spring.application.name}:${server.port} - enabled: true - service-name: ${spring.application.name} - ip-address: localhost - prefer-ip-address: true -eureka: - client: - serviceUrl: - defaultZone: http://127.0.0.1:7654/eureka/ +# consul: +# port: 8500 +# host: 127.0.0.1 +# enabled: true +# discovery: +# register: true +# health-check-path: /actuator/health +# health-check-interval: 10s +# instance-id: ${spring.application.name}:${server.port} +# enabled: true +# service-name: ${spring.application.name} +# ip-address: localhost +# prefer-ip-address: true +#eureka: +# client: +# serviceUrl: +# defaultZone: http://127.0.0.1:7654/eureka/ diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/log4j.properties b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/log4j.properties index 9e520cb7..b0b20e72 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/log4j.properties +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/log4j.properties @@ -12,4 +12,4 @@ log4j.appender.FILE.File=applog/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log log4j.appender.FILE.Threshold=INFO log4j.appender.FILE.layout=org.apache.log4j.PatternLayout log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} [%5p] - %c -%F(%L) -%m%n -log4j.appender.FILE.MaxFileSize=10MB \ No newline at end of file +log4j.appender.FILE.MaxFileSize=10MB diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/polaris.yml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/polaris.yml index c6a3d334..8e0b95dc 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/polaris.yml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/polaris.yml @@ -3,4 +3,4 @@ global: discoverCluster: sameAsBuiltin: true healthCheckCluster: - sameAsBuiltin: true \ No newline at end of file + sameAsBuiltin: true diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/pom.xml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/pom.xml index c2198299..1e5e388c 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/pom.xml @@ -1,27 +1,27 @@ - - - polaris-gateway-example - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 + + + polaris-gateway-example + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 - gateway-callee-service - Spring Cloud Starter Tencent Polaris Gateway Callee Example + gateway-callee-service + Spring Cloud Starter Tencent Polaris Gateway Callee Example - - - spring-cloud-starter-tencent-polaris-discovery - com.tencent.cloud - + + + spring-cloud-starter-tencent-polaris-discovery + com.tencent.cloud + - - org.springframework.boot - spring-boot-starter-web - - + + org.springframework.boot + spring-boot-starter-web + + \ No newline at end of file diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeApplication.java b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeApplication.java index de8dae89..9d618f4c 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeApplication.java +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeApplication.java @@ -26,8 +26,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class GatewayCalleeApplication { - public static void main(String[] args) { - SpringApplication.run(GatewayCalleeApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(GatewayCalleeApplication.class, args); + } } diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeController.java b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeController.java index 6356ef26..13e6b470 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeController.java +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/java/com/tencent/cloud/polaris/gateway/example/callee/GatewayCalleeController.java @@ -17,16 +17,17 @@ package com.tencent.cloud.polaris.gateway.example.callee; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; + import com.tencent.cloud.metadata.constant.MetadataConstant; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; - /** * @author Haotian Zhang */ @@ -34,29 +35,26 @@ import java.net.URLDecoder; @RequestMapping("/gateway/example/callee") public class GatewayCalleeController { - private static Logger logger = LoggerFactory.getLogger(GatewayCalleeController.class); - - /** - * Get info string - * - * @return 返回服务信息 - */ - @RequestMapping("/info") - public String info() { - return "Gateway Example Callee"; - } - - /** - * Get metadata in HTTP header - * - * @param metadataStr - * @return - * @throws UnsupportedEncodingException - */ - @RequestMapping("/echo") - public String echoHeader(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String metadataStr) throws UnsupportedEncodingException { - logger.info(URLDecoder.decode(metadataStr, "UTF-8")); - return URLDecoder.decode(metadataStr, "UTF-8"); - } + private static Logger logger = LoggerFactory.getLogger(GatewayCalleeController.class); + + /** + * Get info string + * @return 返回服务信息 + */ + @RequestMapping("/info") + public String info() { + return "Gateway Example Callee"; + } + + /** + * Get metadata in HTTP header + */ + @RequestMapping("/echo") + public String echoHeader( + @RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String metadataStr) + throws UnsupportedEncodingException { + logger.info(URLDecoder.decode(metadataStr, "UTF-8")); + return URLDecoder.decode(metadataStr, "UTF-8"); + } } diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/application.yml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/application.yml index 2ca31ba4..29ab597b 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/application.yml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service/src/main/resources/application.yml @@ -6,4 +6,4 @@ spring: name: GatewayCalleeService cloud: polaris: - address: grpc://127.0.0.1:8091 \ No newline at end of file + address: grpc://127.0.0.1:8091 diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/pom.xml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/pom.xml index 71183a5b..545b74fb 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/pom.xml @@ -1,32 +1,32 @@ - - - polaris-gateway-example - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 + + + polaris-gateway-example + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 - gateway-scg-service - Spring Cloud Starter Tencent Polaris Gateway SCG Example + gateway-scg-service + Spring Cloud Starter Tencent Polaris Gateway SCG Example - - - spring-cloud-starter-tencent-polaris-discovery - com.tencent.cloud - + + + spring-cloud-starter-tencent-polaris-discovery + com.tencent.cloud + - - com.tencent.cloud - spring-cloud-tencent-polaris-gateway - + + spring-cloud-starter-tencent-polaris-ratelimit + com.tencent.cloud + - - org.springframework.cloud - spring-cloud-starter-gateway - - + + org.springframework.cloud + spring-cloud-starter-gateway + + \ No newline at end of file diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/java/com/tencent/cloud/polaris/gateway/example/scg/GatewayScgApplication.java b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/java/com/tencent/cloud/polaris/gateway/example/scg/GatewayScgApplication.java index e397463f..dc2a98e7 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/java/com/tencent/cloud/polaris/gateway/example/scg/GatewayScgApplication.java +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/java/com/tencent/cloud/polaris/gateway/example/scg/GatewayScgApplication.java @@ -26,8 +26,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class GatewayScgApplication { - public static void main(String[] args) { - SpringApplication.run(GatewayScgApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(GatewayScgApplication.class, args); + } } diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/application.yml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/application.yml index 59f5467d..103112ec 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/application.yml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/application.yml @@ -5,14 +5,14 @@ spring: application: name: GatewayScgService cloud: - polaris: - address: grpc://127.0.0.1:8091 tencent: metadata: content: a: 1 transitive: - a + polaris: + address: grpc://127.0.0.1:8091 gateway: discovery: locator: @@ -28,4 +28,4 @@ spring: logging: level: - org.springframework.cloud.gateway: trace + org.springframework.cloud.gateway: info diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/pom.xml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/pom.xml index 0c149c8d..697fe770 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/pom.xml @@ -1,38 +1,38 @@ - - - polaris-gateway-example - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 + + + polaris-gateway-example + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 - gateway-zuul-service + gateway-zuul-service Spring Cloud Starter Tencent Polaris Gateway Zuul Example - - - spring-cloud-starter-tencent-polaris-discovery - com.tencent.cloud - + + + spring-cloud-starter-tencent-polaris-discovery + com.tencent.cloud + - - com.tencent.cloud - spring-cloud-tencent-polaris-gateway - + + spring-cloud-starter-tencent-polaris-ratelimit + com.tencent.cloud + - - org.springframework.cloud - spring-cloud-starter-netflix-zuul - + + org.springframework.cloud + spring-cloud-starter-netflix-zuul + - - org.springframework.boot - spring-boot-starter-web - + + org.springframework.boot + spring-boot-starter-web + \ No newline at end of file diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/java/com/tencent/cloud/polaris/gateway/example/zuul/GatewayZuulApplication.java b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/java/com/tencent/cloud/polaris/gateway/example/zuul/GatewayZuulApplication.java index b748b986..681b68ad 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/java/com/tencent/cloud/polaris/gateway/example/zuul/GatewayZuulApplication.java +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-zuul-service/src/main/java/com/tencent/cloud/polaris/gateway/example/zuul/GatewayZuulApplication.java @@ -28,8 +28,8 @@ import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @EnableZuulProxy public class GatewayZuulApplication { - public static void main(String[] args) { - SpringApplication.run(GatewayZuulApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(GatewayZuulApplication.class, args); + } } diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java index 76790744..49e41125 100644 --- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java @@ -18,6 +18,7 @@ package com.tencent.cloud.ratelimit.example.service.callee; import java.util.concurrent.atomic.AtomicInteger; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; @@ -35,42 +36,43 @@ import org.springframework.web.client.RestTemplate; @RequestMapping("/business") public class BusinessController { - @Autowired - private RestTemplate restTemplate; + private final AtomicInteger index = new AtomicInteger(0); - private final AtomicInteger index = new AtomicInteger(0); + @Autowired + private RestTemplate restTemplate; - @Value("${spring.application.name}") - private String appName; + @Value("${spring.application.name}") + private String appName; + /** + * 获取当前服务的信息 + * @return 返回服务信息 + */ + @GetMapping("/info") + public String info() { + return "hello world for ratelimit service " + index.incrementAndGet(); + } - /** - * 获取当前服务的信息 - * - * @return 返回服务信息 - */ - @GetMapping("/info") - public String info() { - return "hello world for ratelimit service " + index.incrementAndGet(); - } + @GetMapping("/invoke") + public String invokeInfo() throws Exception { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < 30; i++) { + try { + ResponseEntity entity = restTemplate.getForEntity( + "http://" + appName + "/business/info", String.class); + builder.append(entity.getBody()).append("
"); + } + catch (RestClientException e) { + if (e instanceof TooManyRequests) { + builder.append(((TooManyRequests) e).getResponseBodyAsString()) + .append(index.incrementAndGet()).append("
"); + } + else { + throw e; + } + } + } + return builder.toString(); + } - @GetMapping("/invoke") - public String invokeInfo() throws Exception { - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < 30; i++) { - try { - ResponseEntity entity = restTemplate - .getForEntity("http://" + appName + "/business/info", String.class); - builder.append(entity.getBody()).append("
"); - } catch (RestClientException e) { - if (e instanceof TooManyRequests) { - builder.append(((TooManyRequests) e).getResponseBodyAsString()).append(index.incrementAndGet()) - .append("
"); - } else { - throw e; - } - } - } - return builder.toString(); - } -} \ No newline at end of file +} diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/RateLimitCalleeService.java b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/RateLimitCalleeService.java index 342d1280..69cbd555 100644 --- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/RateLimitCalleeService.java +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/RateLimitCalleeService.java @@ -18,7 +18,6 @@ package com.tencent.cloud.ratelimit.example.service.callee; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; @@ -28,16 +27,16 @@ import org.springframework.web.client.RestTemplate; * @author Haotian Zhang */ @SpringBootApplication -@EnableAutoConfiguration public class RateLimitCalleeService { - @Bean - @LoadBalanced - public RestTemplate restTemplate() { - return new RestTemplate(); - } + public static void main(String[] args) { + SpringApplication.run(RateLimitCalleeService.class, args); + } + + @Bean + @LoadBalanced + public RestTemplate restTemplate() { + return new RestTemplate(); + } - public static void main(String[] args) { - SpringApplication.run(RateLimitCalleeService.class, args); - } } 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 9974b810..f93c70ab 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 @@ -8,4 +8,4 @@ spring: polaris: address: grpc://127.0.0.1:8091 discovery: - namespace: Test \ No newline at end of file + namespace: Test diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/log4j.properties b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/log4j.properties index 9e520cb7..b0b20e72 100644 --- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/log4j.properties +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/log4j.properties @@ -12,4 +12,4 @@ log4j.appender.FILE.File=applog/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log log4j.appender.FILE.Threshold=INFO log4j.appender.FILE.layout=org.apache.log4j.PatternLayout log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} [%5p] - %c -%F(%L) -%m%n -log4j.appender.FILE.MaxFileSize=10MB \ No newline at end of file +log4j.appender.FILE.MaxFileSize=10MB diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/rule.json b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/rule.json index 9eabb50a..f047dc2b 100644 --- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/rule.json +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/rule.json @@ -16,4 +16,4 @@ } ], "action": "REJECT" -} \ No newline at end of file +} diff --git a/spring-cloud-tencent-metadata/pom.xml b/spring-cloud-tencent-metadata/pom.xml new file mode 100644 index 00000000..7c6517ff --- /dev/null +++ b/spring-cloud-tencent-metadata/pom.xml @@ -0,0 +1,68 @@ + + + + spring-cloud-tencent + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + spring-cloud-tencent-metadata + Spring Cloud Tencent Metadata + + + + + com.tencent.cloud + spring-cloud-tencent-commons + + + + + org.springframework.cloud + spring-cloud-starter-netflix-zuul + true + + + + org.springframework.cloud + spring-cloud-starter-gateway + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.cloud + spring-cloud-starter-netflix-ribbon + test + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + org.powermock + powermock-module-junit4 + test + + + + + org.powermock + powermock-api-mockito2 + test + + + + \ No newline at end of file diff --git a/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataConfiguration.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataConfiguration.java new file mode 100644 index 00000000..4fc3714d --- /dev/null +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataConfiguration.java @@ -0,0 +1,247 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.config; + +import java.util.List; +import java.util.Map; + +import com.netflix.zuul.ZuulFilter; +import com.tencent.cloud.metadata.constant.MetadataConstant; +import com.tencent.cloud.metadata.core.filter.gateway.scg.Metadata2HeaderScgFilter; +import com.tencent.cloud.metadata.core.filter.gateway.scg.MetadataFirstScgFilter; +import com.tencent.cloud.metadata.core.filter.gateway.zuul.Metadata2HeaderZuulFilter; +import com.tencent.cloud.metadata.core.filter.gateway.zuul.MetadataFirstZuulFilter; +import com.tencent.cloud.metadata.core.filter.web.MetadataReactiveFilter; +import com.tencent.cloud.metadata.core.filter.web.MetadataServletFilter; +import com.tencent.cloud.metadata.core.interceptor.feign.Metadata2HeaderFeignInterceptor; +import com.tencent.cloud.metadata.core.interceptor.feign.MetadataFirstFeignInterceptor; +import com.tencent.cloud.metadata.core.interceptor.resttemplate.MetadataRestTemplateInterceptor; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.util.CollectionUtils; +import org.springframework.web.client.RestTemplate; + +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; + +/** + * Metadata Configuration. + * + * @author Haotian Zhang + */ +@Configuration +public class MetadataConfiguration { + + /** + * metadata properties. + * @return metadata properties + */ + @Bean + public MetadataLocalProperties metadataLocalProperties() { + return new MetadataLocalProperties(); + } + + /** + * Create when web application type is SERVLET. + */ + @Configuration + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) + static class MetadataServletFilterConfig { + + @Bean + public FilterRegistrationBean metadataServletFilterRegistrationBean( + MetadataServletFilter metadataServletFilter) { + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>( + metadataServletFilter); + filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, + REQUEST); + filterRegistrationBean.setOrder(MetadataConstant.OrderConstant.FILTER_ORDER); + return filterRegistrationBean; + } + + @Bean + public MetadataServletFilter metadataServletFilter() { + return new MetadataServletFilter(); + } + + } + + /** + * Create when web application type is REACTIVE. + */ + @Configuration + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) + static class MetadataReactiveFilterConfig { + + @Bean + public MetadataReactiveFilter metadataReactiveFilter() { + return new MetadataReactiveFilter(); + } + + } + + /** + * Create when gateway application is Zuul. + */ + @Configuration + @ConditionalOnClass(name = "com.netflix.zuul.http.ZuulServlet") + static class MetadataZuulFilterConfig { + + @Bean + public ZuulFilter metadataFirstZuulFilter() { + return new MetadataFirstZuulFilter(); + } + + @Bean + public ZuulFilter metadata2HeaderZuulFilter() { + return new Metadata2HeaderZuulFilter(); + } + + } + + /** + * Create when gateway application is SCG. + */ + @Configuration + @ConditionalOnClass(name = "org.springframework.cloud.gateway.filter.GlobalFilter") + static class MetadataScgFilterConfig { + + @Bean + public GlobalFilter metadataFirstScgFilter() { + return new MetadataFirstScgFilter(); + } + + @Bean + public GlobalFilter metadata2HeaderScgFilter() { + return new Metadata2HeaderScgFilter(); + } + + } + + /** + * Create when Feign exists. + */ + @Configuration + @ConditionalOnClass(name = "feign.Feign") + static class MetadataFeignPluginConfig { + + @Bean + public MetadataFirstFeignInterceptor metadataFirstFeignInterceptor() { + return new MetadataFirstFeignInterceptor(); + } + + @Bean + public Metadata2HeaderFeignInterceptor metadataFeignInterceptor() { + return new Metadata2HeaderFeignInterceptor(); + } + + } + + /** + * Create when RestTemplate exists. + */ + @Configuration + @ConditionalOnClass(name = "org.springframework.web.client.RestTemplate") + static class MetadataRestTemplateConfig implements ApplicationContextAware { + + private ApplicationContext context; + + @Bean + public MetadataRestTemplateInterceptor metadataRestTemplateInterceptor() { + return new MetadataRestTemplateInterceptor(); + } + + @Bean + BeanPostProcessor metadataRestTemplatePostProcessor( + MetadataRestTemplateInterceptor metadataRestTemplateInterceptor) { + // Coping with multiple bean injection scenarios + Map beans = this.context + .getBeansOfType(RestTemplate.class); + // If the restTemplate has been created when the + // MetadataRestTemplatePostProcessor Bean + // is initialized, then manually set the interceptor. + if (!CollectionUtils.isEmpty(beans)) { + for (RestTemplate restTemplate : beans.values()) { + List interceptors = restTemplate + .getInterceptors(); + // Avoid setting interceptor repeatedly. + if (null != interceptors + && !interceptors.contains(metadataRestTemplateInterceptor)) { + interceptors.add(metadataRestTemplateInterceptor); + restTemplate.setInterceptors(interceptors); + } + } + } + return new MetadataRestTemplatePostProcessor(metadataRestTemplateInterceptor); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.context = applicationContext; + } + + public static class MetadataRestTemplatePostProcessor + implements BeanPostProcessor { + + private MetadataRestTemplateInterceptor metadataRestTemplateInterceptor; + + MetadataRestTemplatePostProcessor( + MetadataRestTemplateInterceptor metadataRestTemplateInterceptor) { + this.metadataRestTemplateInterceptor = metadataRestTemplateInterceptor; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) { + if (bean instanceof RestTemplate) { + RestTemplate restTemplate = (RestTemplate) bean; + List interceptors = restTemplate + .getInterceptors(); + // Avoid setting interceptor repeatedly. + if (null != interceptors + && !interceptors.contains(metadataRestTemplateInterceptor)) { + interceptors.add(this.metadataRestTemplateInterceptor); + restTemplate.setInterceptors(interceptors); + } + } + return bean; + } + + } + + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataLocalProperties.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataLocalProperties.java similarity index 62% rename from spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataLocalProperties.java rename to spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataLocalProperties.java index 459c9f78..a637b6e9 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataLocalProperties.java +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataLocalProperties.java @@ -17,14 +17,14 @@ package com.tencent.cloud.metadata.config; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.util.CollectionUtils; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.CollectionUtils; + /** * Metadata Properties from local properties file. * @@ -33,35 +33,36 @@ import java.util.Map; @ConfigurationProperties(prefix = "spring.cloud.tencent.metadata") public class MetadataLocalProperties { - /** - * metadata content. - */ - private Map content; + /** + * metadata content. + */ + private Map content; + + /** + * transitive metadata key list. + */ + private List transitive; - /** - * transitive metadata key list. - */ - private List transitive; + public Map getContent() { + if (CollectionUtils.isEmpty(content)) { + content = new HashMap<>(); + } + return content; + } - public Map getContent() { - if (CollectionUtils.isEmpty(content)) { - content = new HashMap<>(); - } - return content; - } + public void setContent(Map content) { + this.content = content; + } - public void setContent(Map content) { - this.content = content; - } + public List getTransitive() { + if (CollectionUtils.isEmpty(transitive)) { + transitive = new ArrayList<>(); + } + return transitive; + } - public List getTransitive() { - if (CollectionUtils.isEmpty(transitive)) { - transitive = new ArrayList<>(); - } - return transitive; - } + public void setTransitive(List transitive) { + this.transitive = transitive; + } - public void setTransitive(List transitive) { - this.transitive = transitive; - } } diff --git a/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/constant/MetadataConstant.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/constant/MetadataConstant.java new file mode 100644 index 00000000..9217a9a9 --- /dev/null +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/constant/MetadataConstant.java @@ -0,0 +1,122 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.constant; + +import org.springframework.core.Ordered; + +/** + * Constant for spring-cloud-tencent-metadata. + * + * @author Haotian Zhang + */ +public final class MetadataConstant { + + /** + * System metadata key. + */ + public static class SystemMetadataKey { + + /** + * Local namespace. + */ + public static String LOCAL_NAMESPACE = "LOCAL_NAMESPACE"; + + /** + * Local service. + */ + public static String LOCAL_SERVICE = "LOCAL_SERVICE"; + + /** + * Local path. + */ + public static String LOCAL_PATH = "LOCAL_PATH"; + + /** + * Peer namespace. + */ + public static String PEER_NAMESPACE = "PEER_NAMESPACE"; + + /** + * Peer service. + */ + public static String PEER_SERVICE = "PEER_SERVICE"; + + /** + * Peer path. + */ + public static String PEER_PATH = "PEER_PATH"; + + } + + /** + * Order of filter, interceptor, ... + */ + public static class OrderConstant { + + /** + * Order of filter. + */ + public static final int FILTER_ORDER = Ordered.HIGHEST_PRECEDENCE + 13; + + /** + * Order of MetadataFirstFeignPlugin. + */ + public static int METADATA_FIRST_FEIGN_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + + 1; + + /** + * Order of MetadataFirstFeignInterceptor. + */ + public static int METADATA_FIRST_FEIGN_INTERCEPTOR_ORDER = Ordered.HIGHEST_PRECEDENCE + + 1; + + /** + * Order of Metadata2HeaderFeignInterceptor. + */ + public static int METADATA_2_HEADER_FEIGN_INTERCEPTOR_ORDER = Ordered.LOWEST_PRECEDENCE; + + /** + * Order of interceptor. + */ + public static int INTERCEPTOR_ORDER = Ordered.LOWEST_PRECEDENCE; + + } + + /** + * Metadata HTTP header name. + */ + public static class HeaderName { + + /** + * Custom metadata. + */ + public static final String CUSTOM_METADATA = "SCT-CUSTOM-METADATA"; + + /** + * System Metadata. + */ + public static final String SYSTEM_METADATA = "SCT-SYSTEM-METADATA"; + + /** + * Metadata context. + */ + public static final String METADATA_CONTEXT = "SCT-METADATA-CONTEXT"; + + } + +} diff --git a/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContext.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContext.java new file mode 100644 index 00000000..e48367ca --- /dev/null +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContext.java @@ -0,0 +1,87 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.context; + +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.tencent.cloud.common.util.JacksonUtils; + +/** + * Transitive Metadata Context. + * + * @author Haotian Zhang + */ +public class MetadataContext { + + /** + * Transitive custom metadata content. + */ + private final Map transitiveCustomMetadata; + + /** + * System metadata content. + */ + private final Map systemMetadata; + + public MetadataContext() { + this.transitiveCustomMetadata = new ConcurrentHashMap<>(); + this.systemMetadata = new ConcurrentHashMap<>(); + } + + public Map getAllTransitiveCustomMetadata() { + return Collections.unmodifiableMap(this.transitiveCustomMetadata); + } + + public String getTransitiveCustomMetadata(String key) { + return this.transitiveCustomMetadata.get(key); + } + + public void putTransitiveCustomMetadata(String key, String value) { + this.transitiveCustomMetadata.put(key, value); + } + + public void putAllTransitiveCustomMetadata(Map customMetadata) { + this.transitiveCustomMetadata.putAll(customMetadata); + } + + public Map getAllSystemMetadata() { + return Collections.unmodifiableMap(this.systemMetadata); + } + + public String getSystemMetadata(String key) { + return this.systemMetadata.get(key); + } + + public void putSystemMetadata(String key, String value) { + this.systemMetadata.put(key, value); + } + + public void putAllSystemMetadata(Map systemMetadata) { + this.systemMetadata.putAll(systemMetadata); + } + + @Override + public String toString() { + return "MetadataContext{" + "transitiveCustomMetadata=" + + JacksonUtils.serialize2Json(transitiveCustomMetadata) + + ", systemMetadata=" + JacksonUtils.serialize2Json(systemMetadata) + '}'; + } + +} diff --git a/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContextHolder.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContextHolder.java new file mode 100644 index 00000000..69c16483 --- /dev/null +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContextHolder.java @@ -0,0 +1,142 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.context; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.metadata.constant.MetadataConstant; + +import org.springframework.util.CollectionUtils; + +/** + * Metadata Context Holder. + * + * @author Haotian Zhang + */ +public final class MetadataContextHolder { + + /** + * Namespace of local instance. + */ + public static final String LOCAL_NAMESPACE = ApplicationContextAwareUtils + .getProperties("spring.cloud" + ".polaris.discovery.namespace", "default"); + + private static final ThreadLocal METADATA_CONTEXT = new InheritableThreadLocal<>(); + + private static final String LOCAL_SPRING_APPLICATION_NAME = ApplicationContextAwareUtils + .getProperties("spring.application.name", null); + + /** + * Service name of local instance. + */ + public static final String LOCAL_SERVICE = ApplicationContextAwareUtils.getProperties( + "spring.cloud.polaris" + ".discovery.service", LOCAL_SPRING_APPLICATION_NAME); + + private static MetadataLocalProperties metadataLocalProperties; + + private MetadataContextHolder() { + + } + + /** + * Get metadata context. Create if not existing. + * @return METADATA_CONTEXT + */ + public static MetadataContext get() { + if (null == METADATA_CONTEXT.get()) { + MetadataContext metadataContext = new MetadataContext(); + if (metadataLocalProperties == null) { + metadataLocalProperties = (MetadataLocalProperties) ApplicationContextAwareUtils + .getApplicationContext().getBean("metadataLocalProperties"); + } + + // init custom metadata and load local metadata + Map transitiveMetadataMap = getTransitiveMetadataMap( + metadataLocalProperties.getContent(), + metadataLocalProperties.getTransitive()); + metadataContext.putAllTransitiveCustomMetadata(transitiveMetadataMap); + + // init system metadata + metadataContext.putSystemMetadata( + MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE, LOCAL_NAMESPACE); + metadataContext.putSystemMetadata( + MetadataConstant.SystemMetadataKey.LOCAL_SERVICE, LOCAL_SERVICE); + + METADATA_CONTEXT.set(metadataContext); + } + return METADATA_CONTEXT.get(); + } + + /** + * Filter and store the transitive metadata to transitive metadata context. + * @param source all metadata content + * @param transitiveMetadataKeyList transitive metadata name list + * @return result + */ + private static Map getTransitiveMetadataMap( + Map source, List transitiveMetadataKeyList) { + Map result = new HashMap<>(); + for (String key : transitiveMetadataKeyList) { + if (source.containsKey(key)) { + result.put(key, source.get(key)); + } + } + return result; + } + + /** + * Set metadata context. + * @param metadataContext metadata context + */ + public static void set(MetadataContext metadataContext) { + METADATA_CONTEXT.set(metadataContext); + } + + /** + * Save metadata map to thread local. + * @param customMetadataMap custom metadata collection + * @param systemMetadataMap system metadata collection + */ + public static void init(Map customMetadataMap, + Map systemMetadataMap) { + // Init ThreadLocal. + MetadataContextHolder.remove(); + MetadataContext metadataContext = MetadataContextHolder.get(); + + // Save to ThreadLocal. + if (!CollectionUtils.isEmpty(customMetadataMap)) { + metadataContext.putAllTransitiveCustomMetadata(customMetadataMap); + } + if (!CollectionUtils.isEmpty(systemMetadataMap)) { + metadataContext.putAllSystemMetadata(systemMetadataMap); + } + MetadataContextHolder.set(metadataContext); + } + + /** + * Remove metadata context. + */ + public static void remove() { + METADATA_CONTEXT.remove(); + } + +} diff --git a/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/scg/Metadata2HeaderScgFilter.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/scg/Metadata2HeaderScgFilter.java new file mode 100644 index 00000000..b0fe6f78 --- /dev/null +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/scg/Metadata2HeaderScgFilter.java @@ -0,0 +1,83 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.core.filter.gateway.scg; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Map; + +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.metadata.constant.MetadataConstant; +import com.tencent.cloud.metadata.context.MetadataContext; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.util.CollectionUtils; +import org.springframework.web.server.ServerWebExchange; + +import static org.springframework.cloud.gateway.filter.LoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER; + +/** + * Scg filter used for writing metadata in HTTP request header. + * + * @author Haotian Zhang + */ +public class Metadata2HeaderScgFilter implements GlobalFilter, Ordered { + + private static final int METADATA_SCG_FILTER_ORDER = LOAD_BALANCER_CLIENT_FILTER_ORDER + + 1; + + @Override + public int getOrder() { + return METADATA_SCG_FILTER_ORDER; + } + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + // get request builder + ServerHttpRequest.Builder builder = exchange.getRequest().mutate(); + + // get metadata of current thread + MetadataContext metadataContext = exchange + .getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT); + + // add new metadata and cover old + if (metadataContext == null) { + metadataContext = MetadataContextHolder.get(); + } + Map customMetadata = metadataContext + .getAllTransitiveCustomMetadata(); + if (!CollectionUtils.isEmpty(customMetadata)) { + String metadataStr = JacksonUtils.serialize2Json(customMetadata); + try { + builder.header(MetadataConstant.HeaderName.CUSTOM_METADATA, + URLEncoder.encode(metadataStr, "UTF-8")); + } + catch (UnsupportedEncodingException e) { + builder.header(MetadataConstant.HeaderName.CUSTOM_METADATA, metadataStr); + } + } + + return chain.filter(exchange.mutate().request(builder.build()).build()); + } + +} diff --git a/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/scg/MetadataFirstScgFilter.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/scg/MetadataFirstScgFilter.java new file mode 100644 index 00000000..62ff66dc --- /dev/null +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/scg/MetadataFirstScgFilter.java @@ -0,0 +1,77 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.metadata.core.filter.gateway.scg; + +import com.tencent.cloud.metadata.constant.MetadataConstant; +import com.tencent.cloud.metadata.context.MetadataContext; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.cloud.gateway.route.Route; +import org.springframework.core.Ordered; +import org.springframework.web.server.ServerWebExchange; + +import static org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter.ROUTE_TO_URL_FILTER_ORDER; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR; + +/** + * Scg output first filter used for setting peer info in context. + * + * @author Haotian Zhang + */ +public class MetadataFirstScgFilter implements GlobalFilter, Ordered { + + /** + * Order of MetadataFirstScgFilter. + */ + public static final int METADATA_FIRST_FILTER_ORDER = ROUTE_TO_URL_FILTER_ORDER + 1; + + @Override + public int getOrder() { + return METADATA_FIRST_FILTER_ORDER; + } + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + // get request context + Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR); + + // get metadata of current thread + MetadataContext metadataContext = exchange + .getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT); + + // TODO 对端命名空间暂时与本地命名空间相同 + metadataContext.putSystemMetadata( + MetadataConstant.SystemMetadataKey.PEER_NAMESPACE, + MetadataContextHolder.get().getSystemMetadata( + MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE)); + metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_SERVICE, + route.getId()); + metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_PATH, + exchange.getRequest().getURI().getPath()); + + exchange.getAttributes().put(MetadataConstant.HeaderName.METADATA_CONTEXT, + metadataContext); + + return chain.filter(exchange); + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter/Metadata2HeaderZuulFilter.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/zuul/Metadata2HeaderZuulFilter.java similarity index 53% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter/Metadata2HeaderZuulFilter.java rename to spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/zuul/Metadata2HeaderZuulFilter.java index 4b743f07..e427b31e 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter/Metadata2HeaderZuulFilter.java +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/zuul/Metadata2HeaderZuulFilter.java @@ -15,20 +15,20 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.gateway.core.zuul.filter; +package com.tencent.cloud.metadata.core.filter.gateway.zuul; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Map; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; +import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.metadata.constant.MetadataConstant; import com.tencent.cloud.metadata.context.MetadataContext; import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.cloud.metadata.util.JacksonUtils; -import org.springframework.util.CollectionUtils; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.Map; +import org.springframework.util.CollectionUtils; 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; @@ -36,44 +36,49 @@ import static org.springframework.cloud.netflix.zuul.filters.support.FilterConst /** * Zuul filter used for writing metadata in HTTP request header. * - * @author skyehtzhang + * @author Haotian Zhang */ public class Metadata2HeaderZuulFilter extends ZuulFilter { - @Override - public String filterType() { - return ROUTE_TYPE; - } + @Override + public String filterType() { + return ROUTE_TYPE; + } + + @Override + public int filterOrder() { + return RIBBON_ROUTING_FILTER_ORDER - 1; + } - @Override - public int filterOrder() { - return RIBBON_ROUTING_FILTER_ORDER - 1; - } + @Override + public boolean shouldFilter() { + return true; + } - @Override - public boolean shouldFilter() { - return true; - } + @Override + public Object run() { + // get request context + RequestContext requestContext = RequestContext.getCurrentContext(); - @Override - public Object run() { - // get request context - RequestContext requestContext = RequestContext.getCurrentContext(); + // get metadata of current thread + MetadataContext metadataContext = MetadataContextHolder.get(); - // get metadata of current thread - MetadataContext metadataContext = MetadataContextHolder.get(); + // add new metadata and cover old + Map customMetadata = metadataContext + .getAllTransitiveCustomMetadata(); + if (!CollectionUtils.isEmpty(customMetadata)) { + String metadataStr = JacksonUtils.serialize2Json(customMetadata); + try { + requestContext.addZuulRequestHeader( + MetadataConstant.HeaderName.CUSTOM_METADATA, + URLEncoder.encode(metadataStr, "UTF-8")); + } + catch (UnsupportedEncodingException e) { + requestContext.addZuulRequestHeader( + MetadataConstant.HeaderName.CUSTOM_METADATA, metadataStr); + } + } + return null; + } - // add new metadata and cover old - Map customMetadata = metadataContext.getAllTransitiveCustomMetadata(); - if (!CollectionUtils.isEmpty(customMetadata)) { - String metadataStr = JacksonUtils.serialize2Json(customMetadata); - try { - requestContext.addZuulRequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA, - URLEncoder.encode(metadataStr, "UTF-8")); - } catch (UnsupportedEncodingException e) { - requestContext.addZuulRequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA, metadataStr); - } - } - return null; - } } diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter/MetadataFirstZuulFilter.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/zuul/MetadataFirstZuulFilter.java similarity index 55% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter/MetadataFirstZuulFilter.java rename to spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/zuul/MetadataFirstZuulFilter.java index 2d158d0e..96813842 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter/MetadataFirstZuulFilter.java +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/gateway/zuul/MetadataFirstZuulFilter.java @@ -14,7 +14,7 @@ * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.gateway.core.zuul.filter; +package com.tencent.cloud.metadata.core.filter.gateway.zuul; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; @@ -27,38 +27,44 @@ import static org.springframework.cloud.netflix.zuul.filters.support.FilterConst import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY; /** - * Zuul filter used for setting peer info in context. + * Zuul output first filter used for setting peer info in context. * * @author Haotian Zhang */ public class MetadataFirstZuulFilter extends ZuulFilter { - @Override - public String filterType() { - return PRE_TYPE; - } - @Override - public int filterOrder() { - return PRE_DECORATION_FILTER_ORDER + 1; - } + @Override + public String filterType() { + return PRE_TYPE; + } - @Override - public boolean shouldFilter() { - return true; - } + @Override + public int filterOrder() { + return PRE_DECORATION_FILTER_ORDER + 1; + } - @Override - public Object run() { - // get request context - RequestContext requestContext = RequestContext.getCurrentContext(); + @Override + public boolean shouldFilter() { + return true; + } + + @Override + public Object run() { + // get request context + RequestContext requestContext = RequestContext.getCurrentContext(); + + // TODO 对端命名空间暂时与本地命名空间相同 + MetadataContextHolder.get().putSystemMetadata( + MetadataConstant.SystemMetadataKey.PEER_NAMESPACE, + MetadataContextHolder.get().getSystemMetadata( + MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE)); + MetadataContextHolder.get().putSystemMetadata( + MetadataConstant.SystemMetadataKey.PEER_SERVICE, + (String) requestContext.get(SERVICE_ID_KEY)); + MetadataContextHolder.get().putSystemMetadata( + MetadataConstant.SystemMetadataKey.PEER_PATH, + (String) requestContext.get(REQUEST_URI_KEY)); + return null; + } - // TODO 对端命名空间暂时与本地命名空间相同 - MetadataContextHolder.get().putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_NAMESPACE, - MetadataContextHolder.get().getSystemMetadata(MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE)); - MetadataContextHolder.get().putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_SERVICE, - (String) requestContext.get(SERVICE_ID_KEY)); - MetadataContextHolder.get().putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_PATH, - (String) requestContext.get(REQUEST_URI_KEY)); - return null; - } } diff --git a/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/web/MetadataReactiveFilter.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/web/MetadataReactiveFilter.java new file mode 100644 index 00000000..6ed602ec --- /dev/null +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/web/MetadataReactiveFilter.java @@ -0,0 +1,100 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.core.filter.web; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.HashMap; +import java.util.Map; + +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.metadata.constant.MetadataConstant; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +import org.springframework.core.Ordered; +import org.springframework.http.HttpHeaders; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.util.StringUtils; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; + +import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE; +import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_PATH; +import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_SERVICE; + +/** + * Filter used for storing the metadata from upstream temporarily when web application is + * REACTIVE. + * + * @author Haotian Zhang + */ +public class MetadataReactiveFilter implements WebFilter, Ordered { + + private static final Logger LOG = LoggerFactory + .getLogger(MetadataReactiveFilter.class); + + @Override + public int getOrder() { + return MetadataConstant.OrderConstant.FILTER_ORDER; + } + + @Override + public Mono filter(ServerWebExchange serverWebExchange, + WebFilterChain webFilterChain) { + // Get metadata string from http header. + ServerHttpRequest serverHttpRequest = serverWebExchange.getRequest(); + HttpHeaders httpHeaders = serverHttpRequest.getHeaders(); + String customMetadataStr = httpHeaders + .getFirst(MetadataConstant.HeaderName.CUSTOM_METADATA); + try { + if (StringUtils.hasText(customMetadataStr)) { + customMetadataStr = URLDecoder.decode(customMetadataStr, "UTF-8"); + } + } + catch (UnsupportedEncodingException e) { + LOG.error("Runtime system does not support utf-8 coding.", e); + } + LOG.debug("Get upstream metadata string: {}", customMetadataStr); + + // create custom metadata. + Map upstreamCustomMetadataMap = JacksonUtils + .deserialize2Map(customMetadataStr); + + // create system metadata. + Map systemMetadataMap = new HashMap<>(); + systemMetadataMap.put(LOCAL_NAMESPACE, MetadataContextHolder.LOCAL_NAMESPACE); + systemMetadataMap.put(LOCAL_SERVICE, MetadataContextHolder.LOCAL_SERVICE); + systemMetadataMap.put(LOCAL_PATH, serverHttpRequest.getURI().getPath()); + + MetadataContextHolder.init(upstreamCustomMetadataMap, systemMetadataMap); + + // Save to ServerWebExchange. + serverWebExchange.getAttributes().put( + MetadataConstant.HeaderName.METADATA_CONTEXT, + MetadataContextHolder.get()); + return webFilterChain.filter(serverWebExchange) + .doOnError(throwable -> LOG.error("handle metadata[{}] error.", + MetadataContextHolder.get(), throwable)) + .doFinally((type) -> MetadataContextHolder.remove()); + } + +} diff --git a/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/web/MetadataServletFilter.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/web/MetadataServletFilter.java new file mode 100644 index 00000000..747912e4 --- /dev/null +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/web/MetadataServletFilter.java @@ -0,0 +1,97 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.core.filter.web; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.metadata.constant.MetadataConstant; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.core.annotation.Order; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE; +import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_PATH; +import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_SERVICE; + +/** + * Filter used for storing the metadata from upstream temporarily when web application is + * SERVLET. + * + * @author Haotian Zhang + */ +@Order(MetadataConstant.OrderConstant.FILTER_ORDER) +public class MetadataServletFilter extends OncePerRequestFilter { + + private static final Logger LOG = LoggerFactory + .getLogger(MetadataServletFilter.class); + + @Override + protected void doFilterInternal(HttpServletRequest httpServletRequest, + HttpServletResponse httpServletResponse, FilterChain filterChain) + throws ServletException, IOException { + // Get custom metadata string from http header. + String customMetadataStr = httpServletRequest + .getHeader(MetadataConstant.HeaderName.CUSTOM_METADATA); + try { + if (StringUtils.hasText(customMetadataStr)) { + customMetadataStr = URLDecoder.decode(customMetadataStr, "UTF-8"); + } + } + catch (UnsupportedEncodingException e) { + LOG.error("Runtime system does not support utf-8 coding.", e); + } + LOG.debug("Get upstream metadata string: {}", customMetadataStr); + + // create custom metadata. + Map upstreamCustomMetadataMap = JacksonUtils + .deserialize2Map(customMetadataStr); + + // create system metadata. + Map systemMetadataMap = new HashMap<>(); + systemMetadataMap.put(LOCAL_NAMESPACE, MetadataContextHolder.LOCAL_NAMESPACE); + systemMetadataMap.put(LOCAL_SERVICE, MetadataContextHolder.LOCAL_SERVICE); + systemMetadataMap.put(LOCAL_PATH, httpServletRequest.getRequestURI()); + + try { + MetadataContextHolder.init(upstreamCustomMetadataMap, systemMetadataMap); + + filterChain.doFilter(httpServletRequest, httpServletResponse); + } + catch (IOException | ServletException | RuntimeException e) { + throw e; + } + finally { + MetadataContextHolder.remove(); + } + } + +} diff --git a/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/Metadata2HeaderFeignInterceptor.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/Metadata2HeaderFeignInterceptor.java new file mode 100644 index 00000000..c92b2d94 --- /dev/null +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/Metadata2HeaderFeignInterceptor.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.metadata.core.interceptor.feign; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Map; + +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.metadata.constant.MetadataConstant; +import com.tencent.cloud.metadata.context.MetadataContext; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import feign.RequestInterceptor; +import feign.RequestTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.core.Ordered; +import org.springframework.util.CollectionUtils; + +import static com.tencent.cloud.metadata.constant.MetadataConstant.HeaderName.CUSTOM_METADATA; + +/** + * Interceptor used for adding the metadata in http headers from context when web client + * is Feign. + * + * @author Haotian Zhang + */ +public class Metadata2HeaderFeignInterceptor implements RequestInterceptor, Ordered { + + private static final Logger LOG = LoggerFactory + .getLogger(Metadata2HeaderFeignInterceptor.class); + + @Override + public int getOrder() { + return MetadataConstant.OrderConstant.METADATA_2_HEADER_FEIGN_INTERCEPTOR_ORDER; + } + + @Override + public void apply(RequestTemplate requestTemplate) { + // get metadata of current thread + MetadataContext metadataContext = MetadataContextHolder.get(); + + // add new metadata and cover old + if (!CollectionUtils.isEmpty(requestTemplate.headers()) && !CollectionUtils + .isEmpty(requestTemplate.headers().get(CUSTOM_METADATA))) { + for (String headerMetadataStr : requestTemplate.headers() + .get(CUSTOM_METADATA)) { + Map headerMetadataMap = JacksonUtils + .deserialize2Map(headerMetadataStr); + for (String key : headerMetadataMap.keySet()) { + metadataContext.putTransitiveCustomMetadata(key, + headerMetadataMap.get(key)); + } + } + } + + Map customMetadata = metadataContext + .getAllTransitiveCustomMetadata(); + if (!CollectionUtils.isEmpty(customMetadata)) { + String metadataStr = JacksonUtils.serialize2Json(customMetadata); + requestTemplate.removeHeader(CUSTOM_METADATA); + try { + requestTemplate.header(CUSTOM_METADATA, + URLEncoder.encode(metadataStr, "UTF-8")); + } + catch (UnsupportedEncodingException e) { + LOG.error("Set header failed.", e); + requestTemplate.header(CUSTOM_METADATA, metadataStr); + } + } + } + +} diff --git a/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/MetadataFirstFeignInterceptor.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/MetadataFirstFeignInterceptor.java new file mode 100644 index 00000000..4fa10988 --- /dev/null +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/MetadataFirstFeignInterceptor.java @@ -0,0 +1,56 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.core.interceptor.feign; + +import com.tencent.cloud.metadata.constant.MetadataConstant; +import com.tencent.cloud.metadata.context.MetadataContext; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import feign.RequestInterceptor; +import feign.RequestTemplate; + +import org.springframework.core.Ordered; + +/** + * Interceptor used for setting peer info in context. + * + * @author Haotian Zhang + */ +public class MetadataFirstFeignInterceptor implements RequestInterceptor, Ordered { + + @Override + public int getOrder() { + return MetadataConstant.OrderConstant.METADATA_FIRST_FEIGN_INTERCEPTOR_ORDER; + } + + @Override + public void apply(RequestTemplate requestTemplate) { + // get metadata of current thread + MetadataContext metadataContext = MetadataContextHolder.get(); + + // TODO 对端命名空间暂时与本地命名空间相同 + metadataContext.putSystemMetadata( + MetadataConstant.SystemMetadataKey.PEER_NAMESPACE, + MetadataContextHolder.get().getSystemMetadata( + MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE)); + metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_SERVICE, + requestTemplate.feignTarget().name()); + metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_PATH, + requestTemplate.path()); + } + +} diff --git a/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/resttemplate/MetadataRestTemplateInterceptor.java b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/resttemplate/MetadataRestTemplateInterceptor.java new file mode 100644 index 00000000..53b2ef56 --- /dev/null +++ b/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/resttemplate/MetadataRestTemplateInterceptor.java @@ -0,0 +1,85 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.core.interceptor.resttemplate; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Map; + +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.metadata.constant.MetadataConstant; +import com.tencent.cloud.metadata.context.MetadataContext; +import com.tencent.cloud.metadata.context.MetadataContextHolder; + +import org.springframework.core.Ordered; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +/** + * Interceptor used for adding the metadata in http headers from context when web client + * is RestTemplate. + * + * @author Haotian Zhang + */ +public class MetadataRestTemplateInterceptor + implements ClientHttpRequestInterceptor, Ordered { + + @Override + public int getOrder() { + return MetadataConstant.OrderConstant.INTERCEPTOR_ORDER; + } + + @Override + public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, + ClientHttpRequestExecution clientHttpRequestExecution) throws IOException { + // get metadata of current thread + MetadataContext metadataContext = MetadataContextHolder.get(); + + // add new metadata and cover old + String metadataStr = httpRequest.getHeaders() + .getFirst(MetadataConstant.HeaderName.CUSTOM_METADATA); + if (!StringUtils.isEmpty(metadataStr)) { + Map headerMetadataMap = JacksonUtils + .deserialize2Map(metadataStr); + for (String key : headerMetadataMap.keySet()) { + metadataContext.putTransitiveCustomMetadata(key, + headerMetadataMap.get(key)); + } + } + Map customMetadata = metadataContext + .getAllTransitiveCustomMetadata(); + if (!CollectionUtils.isEmpty(customMetadata)) { + metadataStr = JacksonUtils.serialize2Json(customMetadata); + try { + httpRequest.getHeaders().set(MetadataConstant.HeaderName.CUSTOM_METADATA, + URLEncoder.encode(metadataStr, "UTF-8")); + } + catch (UnsupportedEncodingException e) { + httpRequest.getHeaders().set(MetadataConstant.HeaderName.CUSTOM_METADATA, + metadataStr); + } + } + return clientHttpRequestExecution.execute(httpRequest, bytes); + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-tencent-metadata/src/main/resources/META-INF/additional-spring-configuration-metadata.json similarity index 100% rename from spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/resources/META-INF/additional-spring-configuration-metadata.json rename to spring-cloud-tencent-metadata/src/main/resources/META-INF/additional-spring-configuration-metadata.json diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-metadata/src/main/resources/META-INF/spring.factories similarity index 99% rename from spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/resources/META-INF/spring.factories rename to spring-cloud-tencent-metadata/src/main/resources/META-INF/spring.factories index 89c425fe..66321f37 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-tencent-metadata/src/main/resources/META-INF/spring.factories @@ -1,3 +1,2 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.metadata.config.MetadataConfiguration - diff --git a/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataConfigurationTest.java b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataConfigurationTest.java new file mode 100644 index 00000000..d90cea69 --- /dev/null +++ b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataConfigurationTest.java @@ -0,0 +1,157 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.config; + +import com.tencent.cloud.metadata.core.filter.web.MetadataReactiveFilter; +import com.tencent.cloud.metadata.core.filter.web.MetadataServletFilter; +import com.tencent.cloud.metadata.core.interceptor.feign.Metadata2HeaderFeignInterceptor; +import com.tencent.cloud.metadata.core.interceptor.feign.MetadataFirstFeignInterceptor; +import com.tencent.cloud.metadata.core.interceptor.resttemplate.MetadataRestTemplateInterceptor; +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; + +/** + * Test for {@link MetadataConfiguration} + * + * @author Haotian Zhang + */ +public class MetadataConfigurationTest { + + private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); + + private final WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner(); + + private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = new ReactiveWebApplicationContextRunner(); + + /** + * No any web application. + */ + @Test + public void test1() { + this.applicationContextRunner + .withConfiguration(AutoConfigurations.of(MetadataConfiguration.class)) + .run(context -> { + Assertions.assertThat(context) + .hasSingleBean(MetadataLocalProperties.class); + Assertions.assertThat(context).doesNotHaveBean( + MetadataConfiguration.MetadataReactiveFilterConfig.class); + Assertions.assertThat(context) + .doesNotHaveBean(MetadataReactiveFilter.class); + Assertions.assertThat(context).doesNotHaveBean( + MetadataConfiguration.MetadataServletFilterConfig.class); + Assertions.assertThat(context) + .doesNotHaveBean(MetadataServletFilter.class); + // Assertions.assertThat(context) + // .doesNotHaveBean(MetadataConfiguration.MetadataZuulFilterConfig.class); + // Assertions.assertThat(context) + // .doesNotHaveBean(MetadataFirstZuulFilter.class); + // Assertions.assertThat(context) + // .doesNotHaveBean(Metadata2HeaderZuulFilter.class); + // Assertions.assertThat(context) + // .doesNotHaveBean(MetadataConfiguration.MetadataScgFilterConfig.class); + // Assertions.assertThat(context) + // .doesNotHaveBean(MetadataFirstScgFilter.class); + // Assertions.assertThat(context) + // .doesNotHaveBean(Metadata2HeaderScgFilter.class); + Assertions.assertThat(context).hasSingleBean( + MetadataConfiguration.MetadataFeignPluginConfig.class); + Assertions.assertThat(context) + .hasSingleBean(MetadataFirstFeignInterceptor.class); + Assertions.assertThat(context) + .hasSingleBean(Metadata2HeaderFeignInterceptor.class); + Assertions.assertThat(context).hasSingleBean( + MetadataConfiguration.MetadataRestTemplateConfig.class); + Assertions.assertThat(context) + .hasSingleBean(MetadataRestTemplateInterceptor.class); + Assertions.assertThat(context).hasSingleBean( + MetadataConfiguration.MetadataRestTemplateConfig.MetadataRestTemplatePostProcessor.class); + }); + } + + /** + * web application. + */ + @Test + public void test2() { + this.webApplicationContextRunner + .withConfiguration(AutoConfigurations.of(MetadataConfiguration.class)) + .run(context -> { + Assertions.assertThat(context) + .hasSingleBean(MetadataLocalProperties.class); + Assertions.assertThat(context).doesNotHaveBean( + MetadataConfiguration.MetadataReactiveFilterConfig.class); + Assertions.assertThat(context) + .doesNotHaveBean(MetadataReactiveFilter.class); + Assertions.assertThat(context).hasSingleBean( + MetadataConfiguration.MetadataServletFilterConfig.class); + Assertions.assertThat(context) + .hasSingleBean(MetadataServletFilter.class); + Assertions.assertThat(context).hasSingleBean( + MetadataConfiguration.MetadataFeignPluginConfig.class); + Assertions.assertThat(context) + .hasSingleBean(MetadataFirstFeignInterceptor.class); + Assertions.assertThat(context) + .hasSingleBean(Metadata2HeaderFeignInterceptor.class); + Assertions.assertThat(context).hasSingleBean( + MetadataConfiguration.MetadataRestTemplateConfig.class); + Assertions.assertThat(context) + .hasSingleBean(MetadataRestTemplateInterceptor.class); + Assertions.assertThat(context).hasSingleBean( + MetadataConfiguration.MetadataRestTemplateConfig.MetadataRestTemplatePostProcessor.class); + }); + } + + /** + * reactive web application. + */ + @Test + public void test3() { + this.reactiveWebApplicationContextRunner + .withConfiguration(AutoConfigurations.of(MetadataConfiguration.class)) + .run(context -> { + Assertions.assertThat(context) + .hasSingleBean(MetadataLocalProperties.class); + Assertions.assertThat(context).hasSingleBean( + MetadataConfiguration.MetadataReactiveFilterConfig.class); + Assertions.assertThat(context) + .hasSingleBean(MetadataReactiveFilter.class); + Assertions.assertThat(context).doesNotHaveBean( + MetadataConfiguration.MetadataServletFilterConfig.class); + Assertions.assertThat(context) + .doesNotHaveBean(MetadataServletFilter.class); + Assertions.assertThat(context).hasSingleBean( + MetadataConfiguration.MetadataFeignPluginConfig.class); + Assertions.assertThat(context) + .hasSingleBean(MetadataFirstFeignInterceptor.class); + Assertions.assertThat(context) + .hasSingleBean(Metadata2HeaderFeignInterceptor.class); + Assertions.assertThat(context).hasSingleBean( + MetadataConfiguration.MetadataRestTemplateConfig.class); + Assertions.assertThat(context) + .hasSingleBean(MetadataRestTemplateInterceptor.class); + Assertions.assertThat(context).hasSingleBean( + MetadataConfiguration.MetadataRestTemplateConfig.MetadataRestTemplatePostProcessor.class); + }); + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataLocalPropertiesTest.java b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataLocalPropertiesTest.java similarity index 60% rename from spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataLocalPropertiesTest.java rename to spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataLocalPropertiesTest.java index d7b1f4a4..30569161 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataLocalPropertiesTest.java +++ b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataLocalPropertiesTest.java @@ -20,6 +20,7 @@ package com.tencent.cloud.metadata.config; import org.assertj.core.api.Assertions; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; @@ -28,32 +29,37 @@ import org.springframework.test.context.junit4.SpringRunner; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** - * Test of {@link MetadataLocalProperties} + * Test for {@link MetadataLocalProperties} * - * @author skyehtzhang + * @author Haotian Zhang */ @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, classes = MetadataLocalPropertiesTest.TestApplication.class, - properties = {"spring.config.location = classpath:application-test.yml"}) +@SpringBootTest(webEnvironment = RANDOM_PORT, + classes = MetadataLocalPropertiesTest.TestApplication.class, + properties = { "spring.config.location = classpath:application-test.yml" }) public class MetadataLocalPropertiesTest { - @Autowired - private MetadataLocalProperties metadataLocalProperties; + @Autowired + private MetadataLocalProperties metadataLocalProperties; + + @Test + public void test1() { + Assertions.assertThat(metadataLocalProperties.getContent().get("a")) + .isEqualTo("1"); + Assertions.assertThat(metadataLocalProperties.getContent().get("b")) + .isEqualTo("2"); + Assertions.assertThat(metadataLocalProperties.getContent().get("c")).isNull(); + } - @Test - public void test1() { - Assertions.assertThat(metadataLocalProperties.getContent().get("a")).isEqualTo("1"); - Assertions.assertThat(metadataLocalProperties.getContent().get("b")).isEqualTo("2"); - Assertions.assertThat(metadataLocalProperties.getContent().get("c")).isNull(); - } + @Test + public void test2() { + Assertions.assertThat(metadataLocalProperties.getTransitive().contains("b")) + .isTrue(); + } - @Test - public void test2() { - Assertions.assertThat(metadataLocalProperties.getTransitive().contains("b")).isTrue(); - } + @SpringBootApplication + protected static class TestApplication { - @SpringBootApplication - protected static class TestApplication { + } - } } diff --git a/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/context/MetadataContextHolderTest.java b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/context/MetadataContextHolderTest.java new file mode 100644 index 00000000..4a8099da --- /dev/null +++ b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/context/MetadataContextHolderTest.java @@ -0,0 +1,87 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.context; + +import java.util.HashMap; +import java.util.Map; + +import org.assertj.core.api.Assertions; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +/** + * Test for {@link MetadataContextHolder} + * + * @author Haotian Zhang + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = RANDOM_PORT, + classes = MetadataContextHolderTest.TestApplication.class, + properties = { "spring.config.location = classpath:application-test.yml" }) +public class MetadataContextHolderTest { + + @Test + public void test1() { + Map customMetadata = new HashMap<>(); + customMetadata.put("a", "1"); + customMetadata.put("b", "2"); + MetadataContext metadataContext = MetadataContextHolder.get(); + metadataContext.putAllTransitiveCustomMetadata(customMetadata); + MetadataContextHolder.set(metadataContext); + + customMetadata = MetadataContextHolder.get().getAllTransitiveCustomMetadata(); + Assertions.assertThat(customMetadata.get("a")).isEqualTo("1"); + Assertions.assertThat(customMetadata.get("b")).isEqualTo("2"); + + MetadataContextHolder.remove(); + + customMetadata = new HashMap<>(); + customMetadata.put("a", "1"); + customMetadata.put("b", "22"); + customMetadata.put("c", "3"); + Map systemMetadata = new HashMap<>(); + systemMetadata.put(LOCAL_NAMESPACE, "namespace"); + MetadataContextHolder.init(customMetadata, systemMetadata); + metadataContext = MetadataContextHolder.get(); + customMetadata = metadataContext.getAllTransitiveCustomMetadata(); + systemMetadata = metadataContext.getAllSystemMetadata(); + Assertions.assertThat(customMetadata.get("a")).isEqualTo("1"); + Assertions.assertThat(customMetadata.get("b")).isEqualTo("22"); + Assertions.assertThat(customMetadata.get("c")).isEqualTo("3"); + Assertions.assertThat(systemMetadata.get(LOCAL_NAMESPACE)).isEqualTo("namespace"); + } + + @Test + public void test2() { + Assertions.assertThat(MetadataContextHolder.LOCAL_NAMESPACE).isEqualTo("default"); + Assertions.assertThat(MetadataContextHolder.LOCAL_SERVICE).isEqualTo("test"); + } + + @SpringBootApplication + protected static class TestApplication { + + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/MetadataReactiveFilterTest.java b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/web/MetadataReactiveFilterTest.java similarity index 51% rename from spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/MetadataReactiveFilterTest.java rename to spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/web/MetadataReactiveFilterTest.java index 75f6de1f..b06e1d8a 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/MetadataReactiveFilterTest.java +++ b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/web/MetadataReactiveFilterTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.metadata.core.filter; +package com.tencent.cloud.metadata.core.filter.web; import com.tencent.cloud.metadata.config.MetadataLocalProperties; import com.tencent.cloud.metadata.constant.MetadataConstant; @@ -23,6 +23,8 @@ import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import reactor.core.publisher.Mono; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; @@ -30,52 +32,53 @@ import org.springframework.mock.web.server.MockServerWebExchange; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilterChain; -import reactor.core.publisher.Mono; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.MOCK; /** - * Test of {@link MetadataReactiveFilter} + * Test for {@link MetadataReactiveFilter} * - * @author skyehtzhang + * @author Haotian Zhang */ @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - classes = MetadataServletFilterTest.TestApplication.class, - properties = {"spring.config.location = classpath:application-test.yml"}) +@SpringBootTest(webEnvironment = MOCK, + classes = MetadataServletFilterTest.TestApplication.class, + properties = { "spring.config.location = classpath:application-test.yml" }) public class MetadataReactiveFilterTest { - @Autowired - private MetadataLocalProperties metadataLocalProperties; + @Autowired + private MetadataLocalProperties metadataLocalProperties; - private MetadataReactiveFilter metadataReactiveFilter; + private MetadataReactiveFilter metadataReactiveFilter; - @Before - public void setUp() { - this.metadataReactiveFilter = new MetadataReactiveFilter(); - } + @Before + public void setUp() { + this.metadataReactiveFilter = new MetadataReactiveFilter(); + } - @Test - public void test1() { - Assertions.assertThat(this.metadataReactiveFilter.getOrder()).isEqualTo( - MetadataConstant.OrderConstant.FILTER_ORDER); - } + @Test + public void test1() { + Assertions.assertThat(this.metadataReactiveFilter.getOrder()) + .isEqualTo(MetadataConstant.OrderConstant.FILTER_ORDER); + } - @Test - public void test2() { - // Create mock WebFilterChain - WebFilterChain webFilterChain = serverWebExchange -> Mono.empty(); + @Test + public void test2() { + // Create mock WebFilterChain + WebFilterChain webFilterChain = serverWebExchange -> Mono.empty(); - // Mock request - MockServerHttpRequest request = MockServerHttpRequest - .get("test") - .header(MetadataConstant.HeaderName.CUSTOM_METADATA, "{\"c\": \"3\"}").build(); - ServerWebExchange exchange = MockServerWebExchange.from(request); + // Mock request + MockServerHttpRequest request = MockServerHttpRequest.get("test") + .header(MetadataConstant.HeaderName.CUSTOM_METADATA, "{\"c\": \"3\"}") + .build(); + ServerWebExchange exchange = MockServerWebExchange.from(request); - metadataReactiveFilter.filter(exchange, webFilterChain); - Assertions.assertThat(metadataLocalProperties.getContent().get("a")).isEqualTo("1"); - Assertions.assertThat(metadataLocalProperties.getContent().get("b")).isEqualTo("2"); - Assertions.assertThat(metadataLocalProperties.getContent().get("c")).isNull(); - } + metadataReactiveFilter.filter(exchange, webFilterChain); + Assertions.assertThat(metadataLocalProperties.getContent().get("a")) + .isEqualTo("1"); + Assertions.assertThat(metadataLocalProperties.getContent().get("b")) + .isEqualTo("2"); + Assertions.assertThat(metadataLocalProperties.getContent().get("c")).isNull(); + } } diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/MetadataServletFilterTest.java b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/web/MetadataServletFilterTest.java similarity index 55% rename from spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/MetadataServletFilterTest.java rename to spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/web/MetadataServletFilterTest.java index d50174d5..33f7c522 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/MetadataServletFilterTest.java +++ b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/filter/web/MetadataServletFilterTest.java @@ -15,13 +15,19 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.metadata.core.filter; +package com.tencent.cloud.metadata.core.filter.web; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; import com.tencent.cloud.metadata.config.MetadataLocalProperties; import com.tencent.cloud.metadata.constant.MetadataConstant; import org.assertj.core.api.Assertions; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; @@ -29,51 +35,47 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.context.junit4.SpringRunner; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import java.io.IOException; - import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** - * Test of {@link MetadataServletFilter} + * Test for {@link MetadataServletFilter} * - * @author skyehtzhang + * @author Haotian Zhang */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT, - classes = MetadataServletFilterTest.TestApplication.class, - properties = {"spring.config.location = classpath:application-test.yml"}) + classes = MetadataServletFilterTest.TestApplication.class, + properties = { "spring.config.location = classpath:application-test.yml" }) public class MetadataServletFilterTest { - @Autowired - private MetadataLocalProperties metadataLocalProperties; + @Autowired + private MetadataLocalProperties metadataLocalProperties; - @Autowired - private MetadataServletFilter metadataServletFilter; + @Autowired + private MetadataServletFilter metadataServletFilter; - @Test - public void test1() throws ServletException, IOException { - // Create mock FilterChain - FilterChain filterChain = (servletRequest, servletResponse) -> { + @Test + public void test1() throws ServletException, IOException { + // Create mock FilterChain + FilterChain filterChain = (servletRequest, servletResponse) -> { - }; + }; - // Mock request - MockHttpServletRequest request = new MockHttpServletRequest(); - request.addHeader(MetadataConstant.HeaderName.CUSTOM_METADATA, "{\"c\": \"3\"}"); - MockHttpServletResponse response = new MockHttpServletResponse(); - metadataServletFilter.doFilter(request, response, filterChain); - Assertions.assertThat(metadataLocalProperties.getContent().get("a")).isEqualTo("1"); - Assertions.assertThat(metadataLocalProperties.getContent().get("b")).isEqualTo("2"); - Assertions.assertThat(metadataLocalProperties.getContent().get("c")).isNull(); - } + // Mock request + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader(MetadataConstant.HeaderName.CUSTOM_METADATA, "{\"c\": \"3\"}"); + MockHttpServletResponse response = new MockHttpServletResponse(); + metadataServletFilter.doFilter(request, response, filterChain); + Assertions.assertThat(metadataLocalProperties.getContent().get("a")) + .isEqualTo("1"); + Assertions.assertThat(metadataLocalProperties.getContent().get("b")) + .isEqualTo("2"); + Assertions.assertThat(metadataLocalProperties.getContent().get("c")).isNull(); + } - @SpringBootApplication - protected static class TestApplication { + @SpringBootApplication + protected static class TestApplication { - } + } } diff --git a/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/feign/Metadata2HeaderFeignInterceptorTest.java b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/feign/Metadata2HeaderFeignInterceptorTest.java new file mode 100644 index 00000000..ac25e2bb --- /dev/null +++ b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/feign/Metadata2HeaderFeignInterceptorTest.java @@ -0,0 +1,123 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.core.intercepter.feign; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; + +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.metadata.constant.MetadataConstant; +import com.tencent.cloud.metadata.context.MetadataContextHolder; +import com.tencent.cloud.metadata.core.interceptor.feign.Metadata2HeaderFeignInterceptor; +import feign.RequestInterceptor; +import feign.RequestTemplate; +import org.assertj.core.api.Assertions; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; + +/** + * Test for {@link Metadata2HeaderFeignInterceptor} + * + * @author Haotian Zhang + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = DEFINED_PORT, + classes = Metadata2HeaderFeignInterceptorTest.TestApplication.class, + properties = { "server.port=8081", + "spring.config.location = classpath:application-test.yml" }) +public class Metadata2HeaderFeignInterceptorTest { + + @Autowired + private MetadataLocalProperties metadataLocalProperties; + + @Autowired + private TestApplication.TestFeign testFeign; + + @Test + public void test1() { + String metadata = testFeign.test(); + Assertions.assertThat(metadata).isEqualTo( + "{\"a\":\"11\",\"b\":\"22\",\"c\":\"33\"}{\"LOCAL_SERVICE\":\"test" + + "\",\"LOCAL_PATH\":\"/test\",\"LOCAL_NAMESPACE\":\"default\"}"); + Assertions.assertThat(metadataLocalProperties.getContent().get("a")) + .isEqualTo("1"); + Assertions.assertThat(metadataLocalProperties.getContent().get("b")) + .isEqualTo("2"); + Assertions + .assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("a")) + .isEqualTo("11"); + Assertions + .assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("b")) + .isEqualTo("22"); + Assertions + .assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("c")) + .isEqualTo("33"); + } + + @SpringBootApplication + @EnableFeignClients + @RestController + protected static class TestApplication { + + @RequestMapping("/test") + public String test( + @RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String customMetadataStr) + throws UnsupportedEncodingException { + String systemMetadataStr = JacksonUtils + .serialize2Json(MetadataContextHolder.get().getAllSystemMetadata()); + return URLDecoder.decode(customMetadataStr, "UTF-8") + systemMetadataStr; + } + + @FeignClient(name = "test-feign", url = "http://localhost:8081") + public interface TestFeign { + + @RequestMapping(value = "/test", + headers = { MetadataConstant.HeaderName.CUSTOM_METADATA + + "={\"a\":\"11" + "\",\"b\":\"22\",\"c\":\"33\"}" }) + String test(); + + } + + @Configuration + static class TestRequestInterceptor implements RequestInterceptor { + + @Override + public void apply(RequestTemplate template) { + template.header(MetadataConstant.HeaderName.CUSTOM_METADATA, + "{\"a\":\"11\",\"b\":\"22\",\"c\":\"33\"}"); + } + + } + + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/resttemplate/MetadataRestTemplateInterceptorTest.java b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/resttemplate/MetadataRestTemplateInterceptorTest.java similarity index 50% rename from spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/resttemplate/MetadataRestTemplateInterceptorTest.java rename to spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/resttemplate/MetadataRestTemplateInterceptorTest.java index 3fcc704f..7764aec7 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/resttemplate/MetadataRestTemplateInterceptorTest.java +++ b/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/resttemplate/MetadataRestTemplateInterceptorTest.java @@ -17,14 +17,18 @@ package com.tencent.cloud.metadata.core.intercepter.resttemplate; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; + +import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.metadata.config.MetadataLocalProperties; import com.tencent.cloud.metadata.constant.MetadataConstant; import com.tencent.cloud.metadata.context.MetadataContextHolder; import com.tencent.cloud.metadata.core.interceptor.resttemplate.MetadataRestTemplateInterceptor; -import com.tencent.cloud.metadata.util.JacksonUtils; import org.assertj.core.api.Assertions; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; @@ -39,63 +43,74 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; - import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * Test for {@link MetadataRestTemplateInterceptor} * - * @author skyehtzhang + * @author Haotian Zhang */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT, - classes = MetadataRestTemplateInterceptorTest.TestApplication.class, - properties = {"spring.config.location = classpath:application-test.yml"}) + classes = MetadataRestTemplateInterceptorTest.TestApplication.class, + properties = { "spring.config.location = classpath:application-test.yml" }) public class MetadataRestTemplateInterceptorTest { - @Autowired - private MetadataLocalProperties metadataLocalProperties; + @Autowired + private MetadataLocalProperties metadataLocalProperties; + + @Autowired + private RestTemplate restTemplate; - @Autowired - private RestTemplate restTemplate; + @LocalServerPort + private int localServerPort; - @LocalServerPort - private int localServerPort; + @Test + public void test1() { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.set(MetadataConstant.HeaderName.CUSTOM_METADATA, + "{\"a\":\"11\",\"b\":\"22\",\"c\":\"33\"}"); + HttpEntity httpEntity = new HttpEntity<>(httpHeaders); + String metadata = restTemplate + .exchange("http://localhost:" + localServerPort + "/test", HttpMethod.GET, + httpEntity, String.class) + .getBody(); + Assertions.assertThat(metadata).isEqualTo( + "{\"a\":\"11\",\"b\":\"22\",\"c\":\"33\"}{\"LOCAL_SERVICE\":\"test" + + "\",\"LOCAL_PATH\":\"/test\",\"LOCAL_NAMESPACE\":\"default\"}"); + Assertions.assertThat(metadataLocalProperties.getContent().get("a")) + .isEqualTo("1"); + Assertions.assertThat(metadataLocalProperties.getContent().get("b")) + .isEqualTo("2"); + Assertions + .assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("a")) + .isEqualTo("11"); + Assertions + .assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("b")) + .isEqualTo("22"); + Assertions + .assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("c")) + .isEqualTo("33"); + } - @Test - public void test1() { - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.set(MetadataConstant.HeaderName.CUSTOM_METADATA, "{\"a\":\"11\",\"b\":\"22\",\"c\":\"33\"}"); - HttpEntity httpEntity = new HttpEntity<>(httpHeaders); - String metadata = restTemplate.exchange("http://localhost:" + localServerPort + "/test", - HttpMethod.GET, httpEntity, String.class).getBody(); - Assertions.assertThat(metadata).isEqualTo("{\"a\":\"11\",\"b\":\"22\",\"c\":\"33\"}{\"LOCAL_SERVICE\":\"test" - + "\",\"LOCAL_PATH\":\"/test\",\"LOCAL_NAMESPACE\":\"default\"}"); - Assertions.assertThat(metadataLocalProperties.getContent().get("a")).isEqualTo("1"); - Assertions.assertThat(metadataLocalProperties.getContent().get("b")).isEqualTo("2"); - Assertions.assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("a")).isEqualTo("11"); - Assertions.assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("b")).isEqualTo("22"); - Assertions.assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("c")).isEqualTo("33"); - } + @SpringBootApplication + @RestController + protected static class TestApplication { - @SpringBootApplication - @RestController - protected static class TestApplication { + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } - @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); - } + @RequestMapping("/test") + public String test( + @RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String customMetadataStr) + throws UnsupportedEncodingException { + String systemMetadataStr = JacksonUtils + .serialize2Json(MetadataContextHolder.get().getAllSystemMetadata()); + return URLDecoder.decode(customMetadataStr, "UTF-8") + systemMetadataStr; + } - @RequestMapping("/test") - public String test(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String customMetadataStr) - throws UnsupportedEncodingException { - String systemMetadataStr = - JacksonUtils.serialize2Json(MetadataContextHolder.get().getAllSystemMetadata()); - return URLDecoder.decode(customMetadataStr, "UTF-8") + systemMetadataStr; - } + } - } } diff --git a/spring-cloud-tencent-metadata/src/test/resources/application-test.yml b/spring-cloud-tencent-metadata/src/test/resources/application-test.yml new file mode 100644 index 00000000..f0b649a0 --- /dev/null +++ b/spring-cloud-tencent-metadata/src/test/resources/application-test.yml @@ -0,0 +1,15 @@ +spring: + application: + name: test + autoconfigure: + exclude: + - org.springframework.cloud.gateway.config.GatewayAutoConfiguration + - org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration + cloud: + tencent: + metadata: + content: + a: 1 + b: 2 + transitive: + - b diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/pom.xml b/spring-cloud-tencent-polaris-context/pom.xml similarity index 79% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/pom.xml rename to spring-cloud-tencent-polaris-context/pom.xml index 9a506d4b..5a9c354b 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/pom.xml +++ b/spring-cloud-tencent-polaris-context/pom.xml @@ -1,23 +1,23 @@ - - spring-cloud-tencent-starters - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 - - spring-cloud-tencent-polaris-context - Spring Cloud Tencent Polaris SDK Context - - - - - com.tencent.cloud - spring-cloud-tencent-commons + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + spring-cloud-tencent + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + spring-cloud-tencent-polaris-context + Spring Cloud Tencent Polaris SDK Context + + + + + com.tencent.cloud + spring-cloud-tencent-commons diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java similarity index 80% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java rename to spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java index f977bebb..0152b7b6 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisConfigModifier.java @@ -26,17 +26,16 @@ import com.tencent.polaris.factory.config.ConfigurationImpl; */ public interface PolarisConfigModifier { - /** - * Modify configuration. - * - * @param configuration - */ - void modify(ConfigurationImpl configuration); + /** + * Modify configuration. + * @param configuration configuration to be modified + */ + void modify(ConfigurationImpl configuration); + + /** + * Get modifier order for sorting. + * @return order + */ + int getOrder(); - /** - * Get modifier order for sorting. - * - * @return order - */ - int getOrder(); } diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextConfiguration.java similarity index 50% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextConfiguration.java rename to spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextConfiguration.java index 3a2f5c8d..aead0776 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextConfiguration.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextConfiguration.java @@ -17,67 +17,74 @@ package com.tencent.cloud.polaris.context; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + import com.tencent.cloud.common.constant.ContextConstant.ModifierOrder; import com.tencent.cloud.polaris.context.extend.consul.ConsulContextProperties; import com.tencent.polaris.api.exception.PolarisException; import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.factory.config.ConfigurationImpl; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; import org.apache.commons.lang.StringUtils; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; /** - * Configuration for Polaris {@link SDKContext} + * Configuration for Polaris {@link SDKContext}. * * @author Haotian Zhang */ -@EnableConfigurationProperties({PolarisContextProperties.class, ConsulContextProperties.class}) +@EnableConfigurationProperties({ PolarisContextProperties.class, + ConsulContextProperties.class }) public class PolarisContextConfiguration { - private static final String ADDRESS_SEPARATOR = ","; + private static final String ADDRESS_SEPARATOR = ","; + + @Bean(name = "polarisContext", initMethod = "init", destroyMethod = "destroy") + @ConditionalOnMissingBean + public SDKContext polarisContext(PolarisContextProperties properties) + throws PolarisException { + return SDKContext.initContextByConfig(properties.configuration()); + } + + @Bean + @ConditionalOnMissingBean + public PolarisConfigModifier polarisConfigModifier() { + return new ModifyAddress(); + } - @Bean(name = "polarisContext", initMethod = "init", destroyMethod = "destroy") - @ConditionalOnMissingBean - public SDKContext polarisContext(PolarisContextProperties properties) throws PolarisException { - return SDKContext.initContextByConfig(properties.configuration()); - } + private static class ModifyAddress implements PolarisConfigModifier { - @Bean - @ConditionalOnMissingBean - public PolarisConfigModifier polarisConfigModifier() { - return new ModifyAddress(); - } + @Autowired + private PolarisContextProperties properties; - private static class ModifyAddress implements PolarisConfigModifier { + @Override + public void modify(ConfigurationImpl configuration) { + if (!StringUtils.isBlank(properties.getAddress())) { + configuration.getGlobal().getServerConnector() + .setAddresses(getAddressList(properties.getAddress())); + } + } - @Autowired - private PolarisContextProperties properties; + @Override + public int getOrder() { + return ModifierOrder.FIRST; + } - @Override - public void modify(ConfigurationImpl configuration) { - if (!StringUtils.isBlank(properties.getAddress())) { - configuration.getGlobal().getServerConnector().setAddresses(getAddressList(properties.getAddress())); - } - } + private List getAddressList(String addressInfo) { + List addressList = new ArrayList<>(); + String[] addresses = addressInfo.split(ADDRESS_SEPARATOR); + for (String address : addresses) { + URI uri = URI.create(address.trim()); + addressList.add(uri.getAuthority()); + } + return addressList; + } - @Override - public int getOrder() { - return ModifierOrder.FIRST; - } + } - private List getAddressList(String addressInfo) { - List addressList = new ArrayList<>(); - String[] addresses = addressInfo.split(ADDRESS_SEPARATOR); - for (String address : addresses) { - URI uri = URI.create(address.trim()); - addressList.add(uri.getAuthority()); - } - return addressList; - } - } -} \ No newline at end of file +} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextProperties.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextProperties.java similarity index 52% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextProperties.java rename to spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextProperties.java index ad575c59..9235de4a 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextProperties.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisContextProperties.java @@ -17,15 +17,17 @@ package com.tencent.cloud.polaris.context; -import com.tencent.polaris.api.config.ConfigProvider; -import com.tencent.polaris.api.config.Configuration; -import com.tencent.polaris.factory.ConfigAPIFactory; -import com.tencent.polaris.factory.config.ConfigurationImpl; import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; + +import com.tencent.polaris.api.config.ConfigProvider; +import com.tencent.polaris.api.config.Configuration; +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.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.commons.util.InetUtilsProperties; @@ -33,57 +35,60 @@ import org.springframework.core.env.Environment; import org.springframework.util.CollectionUtils; /** - * Properties for Polaris {@link com.tencent.polaris.client.api.SDKContext} + * Properties for Polaris {@link com.tencent.polaris.client.api.SDKContext}. * * @author Haotian Zhang */ @ConfigurationProperties(prefix = "spring.cloud.polaris") public class PolarisContextProperties { - /** - * polaris server 地址 - */ - private String address; + /** + * polaris server adress. + */ + private String address; + + @Autowired + private InetUtilsProperties inetUtilsProperties; - @Autowired - private InetUtilsProperties inetUtilsProperties; + @Autowired + private Environment environment; - @Autowired - private Environment environment; + @Autowired + private List modifierList; - @Autowired - private List modifierList; + public String getAddress() { + return address; + } - public String getAddress() { - return address; - } + public void setAddress(String address) { + this.address = address; + } - public void setAddress(String address) { - this.address = address; - } + protected Configuration configuration() { + ConfigurationImpl configuration = (ConfigurationImpl) ConfigAPIFactory + .defaultConfig(ConfigProvider.DEFAULT_CONFIG); + configuration.setDefault(); + String defaultHost = getHost(); + configuration.getGlobal().getAPI().setBindIP(defaultHost); + Collection modifiers = modifierList; + modifiers = modifiers.stream() + .sorted(Comparator.comparingInt(PolarisConfigModifier::getOrder)) + .collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(modifiers)) { + for (PolarisConfigModifier modifier : modifiers) { + modifier.modify(configuration); + } + } + return configuration; + } - protected Configuration configuration() { - ConfigurationImpl configuration = (ConfigurationImpl) ConfigAPIFactory - .defaultConfig(ConfigProvider.DEFAULT_CONFIG); - configuration.setDefault(); - String defaultHost = getHost(); - configuration.getGlobal().getAPI().setBindIP(defaultHost); - Collection modifiers = modifierList; - modifiers = modifiers.stream().sorted(Comparator.comparingInt(PolarisConfigModifier::getOrder)) - .collect(Collectors.toList()); - if (!CollectionUtils.isEmpty(modifiers)) { - for (PolarisConfigModifier modifier : modifiers) { - modifier.modify(configuration); - } - } - return configuration; - } + private String getHost() { + String defaultIpAddress = inetUtilsProperties.getDefaultIpAddress(); + if (!StringUtils.isBlank(defaultIpAddress) + && !defaultIpAddress.equals("127.0.0.1")) { + return defaultIpAddress; + } + return environment.getProperty("spring.cloud.client.ip-address"); + } - private String getHost() { - String defaultIpAddress = inetUtilsProperties.getDefaultIpAddress(); - if (!StringUtils.isBlank(defaultIpAddress) && !defaultIpAddress.equals("127.0.0.1")) { - return defaultIpAddress; - } - return environment.getProperty("spring.cloud.client.ip-address"); - } -} \ No newline at end of file +} diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/extend/consul/ConsulContextProperties.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/extend/consul/ConsulContextProperties.java new file mode 100644 index 00000000..c3976e31 --- /dev/null +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/extend/consul/ConsulContextProperties.java @@ -0,0 +1,144 @@ +/* + * 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.extend.consul; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Map; + +import com.tencent.cloud.common.constant.ContextConstant.ModifierOrder; +import com.tencent.cloud.polaris.context.PolarisConfigModifier; +import com.tencent.polaris.api.config.plugin.DefaultPlugins; +import com.tencent.polaris.factory.config.ConfigurationImpl; +import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl; +import com.tencent.polaris.plugins.connector.common.constant.ConsulConstant.MetadataMapKey; +import org.apache.commons.lang.StringUtils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.util.CollectionUtils; + +/** + * Discovery configuration of Consul. + * + * @author Haotian Zhang + */ +@ConditionalOnExpression("'true'.equals('${spring.cloud.consul.enabled:true}')" + + " && 'true'.equals('${spring.cloud.consul.discovery.enabled:true}')") +@ConfigurationProperties("spring.cloud.consul") +public class ConsulContextProperties { + + /** + * Host of consul(or consul agent). + */ + private String host; + + private int port; + + private boolean enabled; + + @Value("${spring.cloud.consul.discovery.register:#{'true'}}") + private boolean register; + + @Value("${spring.cloud.consul.discovery.enabled:#{'true'}}") + private boolean discoveryEnabled; + + @Value("${spring.cloud.consul.discovery.instance-id:}") + private String instanceId; + + @Value("${spring.cloud.consul.discovery.service-name:${spring.application.name:}}") + private String serviceName; + + @Value("${spring.cloud.consul.discovery.ip-address:}") + private String ipAddress; + + @Value("${spring.cloud.consul.discovery.prefer-ip-address:#{'false'}}") + private boolean preferIpAddress; + + public void setHost(String host) { + this.host = host; + } + + public void setPort(int port) { + this.port = port; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @Bean + @ConditionalOnMissingBean + public ConsulConfigModifier consulConfigModifier() { + return new ConsulConfigModifier(); + } + + private static class ConsulConfigModifier implements PolarisConfigModifier { + + @Autowired(required = false) + private ConsulContextProperties consulContextProperties; + + @Override + public void modify(ConfigurationImpl configuration) { + if (consulContextProperties != null && consulContextProperties.enabled + && consulContextProperties.discoveryEnabled + && consulContextProperties.register) { + if (CollectionUtils + .isEmpty(configuration.getGlobal().getServerConnectors())) { + configuration.getGlobal().setServerConnectors(new ArrayList<>()); + } + configuration.getGlobal().getServerConnectors() + .add(configuration.getGlobal().getServerConnector()); + ServerConnectorConfigImpl serverConnectorConfig = new ServerConnectorConfigImpl(); + serverConnectorConfig.setAddresses( + Collections.singletonList(consulContextProperties.host + ":" + + consulContextProperties.port)); + serverConnectorConfig.setProtocol(DefaultPlugins.SERVER_CONNECTOR_CONSUL); + Map metadata = serverConnectorConfig.getMetadata(); + if (StringUtils.isNotBlank(consulContextProperties.serviceName)) { + metadata.put(MetadataMapKey.SERVICE_NAME_KEY, + consulContextProperties.serviceName); + } + if (StringUtils.isNotBlank(consulContextProperties.instanceId)) { + metadata.put(MetadataMapKey.INSTANCE_ID_KEY, + consulContextProperties.instanceId); + } + if (consulContextProperties.preferIpAddress + && StringUtils.isNotBlank(consulContextProperties.ipAddress)) { + metadata.put(MetadataMapKey.PREFER_IP_ADDRESS_KEY, + String.valueOf(consulContextProperties.preferIpAddress)); + metadata.put(MetadataMapKey.IP_ADDRESS_KEY, + consulContextProperties.ipAddress); + } + configuration.getGlobal().getServerConnectors() + .add(serverConnectorConfig); + } + } + + @Override + public int getOrder() { + return ModifierOrder.LAST; + } + + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring-configuration-metadata.json b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring-configuration-metadata.json similarity index 100% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring-configuration-metadata.json rename to spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring-configuration-metadata.json diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories rename to spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextApplication.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextApplication.java similarity index 100% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextApplication.java rename to spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextApplication.java diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextConfigurationTest.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextConfigurationTest.java similarity index 67% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextConfigurationTest.java rename to spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextConfigurationTest.java index dffed8f7..d81c849b 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextConfigurationTest.java +++ b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextConfigurationTest.java @@ -20,6 +20,7 @@ package com.tencent.cloud.polaris.context; import com.tencent.polaris.client.api.SDKContext; import org.junit.Assert; import org.junit.Test; + import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.cloud.commons.util.UtilAutoConfiguration; @@ -29,17 +30,17 @@ import org.springframework.cloud.commons.util.UtilAutoConfiguration; */ public class PolarisContextConfigurationTest { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(UtilAutoConfiguration.class)) - .withConfiguration(AutoConfigurations.of(PolarisContextConfiguration.class)) - .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:8083"); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(UtilAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(PolarisContextConfiguration.class)) + .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:8083"); - @Test - public void testProperties() { - contextRunner.run(context -> { - final SDKContext sdkContext = context.getBean(SDKContext.class); - Assert.assertNotNull(sdkContext); - }); - } + @Test + public void testProperties() { + contextRunner.run(context -> { + final SDKContext sdkContext = context.getBean(SDKContext.class); + Assert.assertNotNull(sdkContext); + }); + } } diff --git a/spring-cloud-tencent-starters/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 similarity index 73% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java rename to spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/PolarisContextGetHostTest.java index 53e31573..0ead596e 100644 --- a/spring-cloud-tencent-starters/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 @@ -22,22 +22,24 @@ import org.junit.Assert; import org.junit.Test; import org.junit.platform.commons.util.StringUtils; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest(classes = PolarisContextApplication.class, properties = { - "spring.config.location = classpath:application-test.yml"}) +@SpringBootTest(classes = PolarisContextApplication.class, + properties = { "spring.config.location = classpath:application-test.yml" }) public class PolarisContextGetHostTest { - @Autowired - private SDKContext polarisContext; + @Autowired + private SDKContext polarisContext; + + @Test + public void testGetConfigHost() { + String bindIP = polarisContext.getConfig().getGlobal().getAPI().getBindIP(); + Assert.assertFalse(StringUtils.isBlank(bindIP)); + Assert.assertNotEquals(bindIP, "127.0.0.1"); + } - @Test - public void testGetConfigHost() { - String bindIP = polarisContext.getConfig().getGlobal().getAPI().getBindIP(); - Assert.assertFalse(StringUtils.isBlank(bindIP)); - Assert.assertNotEquals(bindIP, "127.0.0.1"); - } } diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/test/resources/application-test.yml b/spring-cloud-tencent-polaris-context/src/test/resources/application-test.yml similarity index 100% rename from spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/test/resources/application-test.yml rename to spring-cloud-tencent-polaris-context/src/test/resources/application-test.yml diff --git a/spring-cloud-tencent-starters/pom.xml b/spring-cloud-tencent-starters/pom.xml deleted file mode 100644 index 6b6325b5..00000000 --- a/spring-cloud-tencent-starters/pom.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - spring-cloud-tencent - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 - - spring-cloud-tencent-starters - pom - Spring Cloud Tencent Starters - Spring Cloud Tencent Starters - - - spring-cloud-tencent-polaris-context - spring-cloud-tencent-commons - spring-cloud-tencent-metadata - spring-cloud-tencent-feign - spring-cloud-starter-tencent-polaris-discovery - spring-cloud-starter-tencent-polaris-ratelimit - spring-cloud-starter-tencent-polaris-circuitbreaker - spring-cloud-starter-tencent-polaris-router - spring-cloud-tencent-polaris-gateway - - - - - - org.jacoco - jacoco-maven-plugin - ${jacoco.version} - - - jacoco-initialize - - prepare-agent - - - - jacoco-site - test - - report - - - - - - - \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml deleted file mode 100644 index 632fde33..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - spring-cloud-tencent-starters - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 - spring-cloud-starter-tencent-polaris-circuitbreaker - Spring Cloud Starter Tencent Polaris Circuitbreaker - - - - - com.tencent.cloud - spring-cloud-tencent-commons - - - - com.tencent.cloud - spring-cloud-tencent-metadata - - - - com.tencent.cloud - spring-cloud-tencent-polaris-context - - - - - - com.tencent.polaris - polaris-discovery-factory - - - - com.tencent.polaris - polaris-circuitbreaker-factory - - - - - org.springframework.cloud - spring-cloud-loadbalancer - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - test - - - \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java deleted file mode 100644 index 339f3a58..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.circuitbreaker.feign; - -import com.tencent.polaris.api.core.ConsumerAPI; -import feign.Client; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; -import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory; -import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient; - -/** - * Wrap Spring Bean and decorating proxy for Feign Client. - * - * @author Haotian Zhang - */ -public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { - - private BeanFactory factory; - - private final ConsumerAPI consumerAPI; - - public PolarisFeignBeanPostProcessor(ConsumerAPI consumerAPI) { - this.consumerAPI = consumerAPI; - } - - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - return wrapper(bean); - } - - private Object wrapper(Object bean) { - if (isNeedWrap(bean)) { - if (bean instanceof LoadBalancerFeignClient) { - LoadBalancerFeignClient client = ((LoadBalancerFeignClient) bean); - return new PolarisLoadBalancerFeignClient(createPolarisFeignClient(client.getDelegate()), factory(), - clientFactory()); - } - if (bean instanceof FeignBlockingLoadBalancerClient) { - FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) bean; - return new PolarisFeignBlockingLoadBalancerClient(createPolarisFeignClient(client.getDelegate()), - factory.getBean(BlockingLoadBalancerClient.class)); - } - return createPolarisFeignClient((Client) bean); - } - return bean; - } - - private boolean isNeedWrap(Object bean) { - return bean instanceof Client && !(bean instanceof PolarisFeignClient) - && !(bean instanceof PolarisFeignBlockingLoadBalancerClient) - && !(bean instanceof PolarisLoadBalancerFeignClient); - } - - private PolarisFeignClient createPolarisFeignClient(Client delegate) { - return new PolarisFeignClient(delegate, consumerAPI); - } - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.factory = beanFactory; - } - - CachingSpringLoadBalancerFactory factory() { - return this.factory.getBean(CachingSpringLoadBalancerFactory.class); - } - - SpringClientFactory clientFactory() { - return this.factory.getBean(SpringClientFactory.class); - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java deleted file mode 100644 index 85c61a93..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.circuitbreaker.feign; - -import static feign.Util.checkNotNull; - -import com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey; -import com.tencent.cloud.metadata.context.MetadataContext; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.pojo.RetStatus; -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.api.rpc.ServiceCallResult; -import feign.Client; -import feign.Request; -import feign.Request.Options; -import feign.Response; -import java.io.IOException; -import java.net.URI; -import org.apache.commons.lang.StringUtils; - -/** - * Wrap for {@link Client} - * - * @author Haotian Zhang - */ -public class PolarisFeignClient implements Client { - - private final Client delegate; - - private final ConsumerAPI consumerAPI; - - public PolarisFeignClient(Client target, ConsumerAPI consumerAPI) { - this.delegate = checkNotNull(target, "target"); - this.consumerAPI = checkNotNull(consumerAPI, "CircuitBreakAPI"); - } - - @Override - public Response execute(Request request, Options options) throws IOException { - final ServiceCallResult resultRequest = createServiceCallResult(request); - try { - Response response = delegate.execute(request, options); - //HTTP code greater than 400 is an exception - if (response.status() >= 400) { - resultRequest.setRetStatus(RetStatus.RetFail); - } - return response; - } catch (IOException origin) { - resultRequest.setRetStatus(RetStatus.RetFail); - throw origin; - } finally { - consumerAPI.updateServiceCallResult(resultRequest); - } - } - - private ServiceCallResult createServiceCallResult(final Request request) { - ServiceCallResult resultRequest = new ServiceCallResult(); - - MetadataContext metadataContext = MetadataContextHolder.get(); - String namespace = metadataContext.getSystemMetadata(SystemMetadataKey.PEER_NAMESPACE); - resultRequest.setNamespace(namespace); - String serviceName = metadataContext.getSystemMetadata(SystemMetadataKey.PEER_SERVICE); - resultRequest.setService(serviceName); - String method = metadataContext.getSystemMetadata(SystemMetadataKey.PEER_PATH); - resultRequest.setMethod(method); - resultRequest.setRetStatus(RetStatus.RetSuccess); - String sourceNamespace = metadataContext.getSystemMetadata(SystemMetadataKey.LOCAL_NAMESPACE); - String sourceService = metadataContext.getSystemMetadata(SystemMetadataKey.LOCAL_SERVICE); - if (StringUtils.isNotBlank(sourceNamespace) && StringUtils.isNotBlank(sourceService)) { - resultRequest.setCallerService(new ServiceKey(sourceNamespace, sourceService)); - } - - URI uri = URI.create(request.url()); - resultRequest.setHost(uri.getHost()); - resultRequest.setPort(uri.getPort()); - - return resultRequest; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java deleted file mode 100644 index 7140a5d1..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris; - -import javax.annotation.PostConstruct; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.core.env.Environment; - -/** - * Properties for Polaris. - * - * @author Haotian Zhang, Andrew Shan, Jie Cheng - */ -@ConfigurationProperties("spring.cloud.polaris.discovery") -public class PolarisProperties { - - /** - * the polaris authentication token. - */ - private String token; - - /** - * namespace, separation registry of different environments. - */ - @Value("${spring.cloud.polaris.discovery.namespace:#{'default'}}") - private String namespace; - - /** - * service name to registry. - */ - @Value("${spring.cloud.polaris.discovery.service:${spring.application.name:}}") - private String service; - - /** - * 权重 - */ - @Value("${spring.cloud.polaris.discovery.weight:#{100}}") - private float weight; - - /** - * 版本号 - */ - private String version; - - /** - * 协议名称 - */ - @Value("${spring.cloud.polaris.discovery.protocol:http}") - private String protocol; - - /** - * 使用spring cloud监听端口 - */ - @Value("${server.port:}") - private int port; - - /** - * Ip address to be registered. - */ - private String ipAddress; - - /** - * 是否开启负载均衡 - */ - @Value("${spring.cloud.polaris.discovery.loadbalancer.enabled:#{true}}") - private Boolean loadbalancerEnabled; - - - /** - * loadbalnce strategy - */ - @Value("${spring.cloud.polaris.discovery.loadbalancer.policy:#{'weightedRandom'}}") - private String policy; - - - /** - * loadbalnce strategy - */ - @Value("${spring.cloud.polaris.discovery.register.enabled:#{true}}") - private Boolean registerEnabled; - - /** - * loadbalnce strategy - */ - @Value("${spring.cloud.polaris.discovery.heartbeat.enabled:#{false}}") - private Boolean heartbeatEnabled = true; - - /** - * Custom health check url to override default - */ - @Value("${spring.cloud.polaris.discovery.health-check-url:}") - private String healthCheckUrl; - - @Autowired - private Environment environment; - - public PolarisProperties(InetUtils inetUtils) { - if (inetUtils != null) { - this.ipAddress = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress(); - } - } - - /** - * init properties - * - * @throws Exception - */ - @PostConstruct - public void init() throws Exception { - if (StringUtils.isEmpty(this.getNamespace())) { - this.setNamespace(environment.resolvePlaceholders("${spring.cloud.polaris.discovery.namespace:}")); - } - if (StringUtils.isEmpty(this.getService())) { - this.setService(environment.resolvePlaceholders("${spring.cloud.polaris.discovery.service:}")); - } - if (StringUtils.isEmpty(this.getToken())) { - this.setToken(environment.resolvePlaceholders("${spring.cloud.polaris.discovery.token:}")); - } - } - - public boolean isHeartbeatEnabled() { - if (null == heartbeatEnabled) { - return false; - } - return heartbeatEnabled; - } - - public void setHeartbeatEnabled(Boolean heartbeatEnabled) { - this.heartbeatEnabled = heartbeatEnabled; - } - - public String getNamespace() { - return namespace; - } - - public void setNamespace(String namespace) { - this.namespace = namespace; - } - - public float getWeight() { - return weight; - } - - public void setWeight(float weight) { - this.weight = weight; - } - - public String getService() { - return service; - } - - public void setService(String service) { - this.service = service; - } - - - public boolean isRegisterEnabled() { - return registerEnabled; - } - - public void setRegisterEnabled(boolean registerEnabled) { - this.registerEnabled = registerEnabled; - } - - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getPolicy() { - return policy; - } - - public void setPolicy(String policy) { - this.policy = policy; - } - - public Boolean getLoadbalancerEnabled() { - return loadbalancerEnabled; - } - - public void setLoadbalancerEnabled(Boolean loadbalancerEnabled) { - this.loadbalancerEnabled = loadbalancerEnabled; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public String getIpAddress() { - return ipAddress; - } - - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - } - - public String getHealthCheckUrl() { - return healthCheckUrl; - } - - public void setHealthCheckUrl(String healthCheckUrl) { - this.healthCheckUrl = healthCheckUrl; - } - - @Override - @SuppressWarnings("checkstyle:all") - public String toString() { - return "PolarisProperties{" + - "token='" + token + '\'' + - ", namespace='" + namespace + '\'' + - ", service='" + service + '\'' + - ", weight=" + weight + - ", version='" + version + '\'' + - ", protocol='" + protocol + '\'' + - ", port=" + port + - ", ipAddress='" + ipAddress + '\'' + - ", loadbalancerEnabled=" + loadbalancerEnabled + - ", policy='" + policy + '\'' + - ", registerEnabled=" + registerEnabled + - ", heartbeatEnabled=" + heartbeatEnabled + - ", healthCheckUrl=" + healthCheckUrl + - ", environment=" + environment + - '}'; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java deleted file mode 100644 index e858d466..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.discovery; - -import com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.cloud.polaris.PolarisProperties; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.core.ProviderAPI; -import com.tencent.polaris.api.pojo.ServiceInfo; -import com.tencent.polaris.api.rpc.GetAllInstancesRequest; -import com.tencent.polaris.api.rpc.GetInstancesRequest; -import com.tencent.polaris.api.rpc.InstancesResponse; -import com.tencent.polaris.api.rpc.ServicesResponse; -import com.tencent.polaris.api.rpc.GetServicesRequest; - -import java.util.Map; - -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * Discovery Handler for Polaris. - * - * @author Haotian Zhang, Andrew Shan, Jie Cheng - */ -@Component -public class PolarisDiscoveryHandler { - - @Autowired - private PolarisProperties polarisProperties; - - @Autowired - private ProviderAPI providerAPI; - - @Autowired - private ConsumerAPI polarisConsumer; - - /** - * 获取服务路由后的实例列表 - * - * @param service 服务名 - * @return 服务实例列表 - */ - public InstancesResponse getFilteredInstances(String service) { - String namespace = polarisProperties.getNamespace(); - GetInstancesRequest getInstancesRequest = new GetInstancesRequest(); - getInstancesRequest.setNamespace(namespace); - getInstancesRequest.setService(service); - String method = MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.PEER_PATH); - getInstancesRequest.setMethod(method); - String localNamespace = MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.LOCAL_NAMESPACE); - String localService = MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.LOCAL_SERVICE); - Map allTransitiveCustomMetadata = MetadataContextHolder.get().getAllTransitiveCustomMetadata(); - if (StringUtils.isNotBlank(localNamespace) || StringUtils.isNotBlank(localService) - || null != allTransitiveCustomMetadata) { - ServiceInfo sourceService = new ServiceInfo(); - sourceService.setNamespace(localNamespace); - sourceService.setService(localService); - sourceService.setMetadata(allTransitiveCustomMetadata); - getInstancesRequest.setServiceInfo(sourceService); - } - return polarisConsumer.getInstances(getInstancesRequest); - } - - /** - * Return all instances for the given service. - * - * @param service serviceName - * @return 服务实例列表 - */ - public InstancesResponse getInstances(String service) { - String namespace = polarisProperties.getNamespace(); - GetAllInstancesRequest request = new GetAllInstancesRequest(); - request.setNamespace(namespace); - request.setService(service); - return polarisConsumer.getAllInstance(request); - } - - public ProviderAPI getProviderAPI() { - return providerAPI; - } - - /** - * Return all service for given namespace - * - * @return service list - */ - public ServicesResponse GetServices() { - String namespace = polarisProperties.getNamespace(); - GetServicesRequest request = new GetServicesRequest(); - request.setNamespace(namespace); - return polarisConsumer.getServices(request); - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java deleted file mode 100644 index 31eeb1fb..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.discovery; - -import com.tencent.cloud.polaris.PolarisProperties; -import com.tencent.cloud.polaris.pojo.PolarisServiceInstance; -import com.tencent.polaris.api.exception.PolarisException; -import com.tencent.polaris.api.pojo.Instance; -import com.tencent.polaris.api.pojo.ServiceInfo; -import com.tencent.polaris.api.pojo.ServiceInstances; -import com.tencent.polaris.api.rpc.InstancesResponse; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import com.tencent.polaris.api.rpc.ServicesResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.client.ServiceInstance; - -/** - * @author Haotian Zhang, Andrew Shan, Jie Cheng - */ -public class PolarisServiceDiscovery { - - private final PolarisDiscoveryHandler polarisDiscoveryHandler; - - public PolarisServiceDiscovery(PolarisDiscoveryHandler polarisDiscoveryHandler) { - this.polarisDiscoveryHandler = polarisDiscoveryHandler; - } - - /** - * Return all instances for the given service. - * - * @param serviceId id of service - * @return list of instances - * @throws PolarisException polarisException - */ - public List getInstances(String serviceId) throws PolarisException { - List instances = new ArrayList<>(); - InstancesResponse filteredInstances = polarisDiscoveryHandler.getFilteredInstances(serviceId); - ServiceInstances serviceInstances = filteredInstances.toServiceInstances(); - for (Instance instance : serviceInstances.getInstances()) { - instances.add(new PolarisServiceInstance(instance)); - } - return instances; - } - - /** - * Return the names of all services. - * - * @return list of service names - * @throws PolarisException polarisException - */ - public List getServices() throws PolarisException { - return polarisDiscoveryHandler. - GetServices(). - getServices(). - stream(). - map(ServiceInfo::getService). - collect(Collectors.toList()); - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java deleted file mode 100644 index b316f5d8..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/reactive/PolarisReactiveDiscoveryClient.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.discovery.reactive; - -import com.tencent.polaris.api.exception.PolarisException; -import com.tencent.cloud.polaris.discovery.PolarisServiceDiscovery; -import java.util.function.Function; -import org.reactivestreams.Publisher; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.scheduler.Schedulers; - -/** - * Reactive Discovery Client for Polaris. - * - * @author Haotian Zhang, Andrew Shan, Jie Cheng - */ -public class PolarisReactiveDiscoveryClient implements ReactiveDiscoveryClient { - - private static final Logger log = LoggerFactory - .getLogger(PolarisReactiveDiscoveryClient.class); - - private PolarisServiceDiscovery polarisServiceDiscovery; - - public PolarisReactiveDiscoveryClient( - PolarisServiceDiscovery polarisServiceDiscovery) { - this.polarisServiceDiscovery = polarisServiceDiscovery; - } - - @Override - public String description() { - return "Spring Cloud Polaris Reactive Discovery Client"; - } - - @Override - public Flux getInstances(String serviceId) { - - return Mono.justOrEmpty(serviceId).flatMapMany(loadInstancesFromPolaris()) - .subscribeOn(Schedulers.boundedElastic()); - } - - private Function> loadInstancesFromPolaris() { - return serviceId -> { - try { - return Flux.fromIterable(polarisServiceDiscovery.getInstances(serviceId)); - } catch (PolarisException e) { - log.error("get service instance[{}] from polaris error!", serviceId, e); - return Flux.empty(); - } - }; - } - - @Override - public Flux getServices() { - return Flux.defer(() -> { - try { - return Flux.fromIterable(polarisServiceDiscovery.getServices()); - } catch (Exception e) { - log.error("get services from polaris server fail,", e); - return Flux.empty(); - } - }).subscribeOn(Schedulers.boundedElastic()); - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java deleted file mode 100644 index 9b33854f..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.registry; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration; -import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.client.serviceregistry.ServiceRegistry; -import org.springframework.util.StringUtils; - -/** - * @author Haotian Zhang, Andrew Shan, Jie Cheng - */ -public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistration { - - private static final Logger log = LoggerFactory.getLogger(PolarisAutoServiceRegistration.class); - - private final PolarisRegistration registration; - - public PolarisAutoServiceRegistration(ServiceRegistry serviceRegistry, - AutoServiceRegistrationProperties autoServiceRegistrationProperties, - PolarisRegistration registration) { - super(serviceRegistry, autoServiceRegistrationProperties); - this.registration = registration; - } - - @Override - protected PolarisRegistration getRegistration() { - if (this.registration.getPort() <= 0) { - this.registration.setPort(this.getPort().get()); - } - return this.registration; - } - - @Override - protected PolarisRegistration getManagementRegistration() { - return null; - } - - @Override - protected void register() { - if (!this.registration.getPolarisProperties().isRegisterEnabled()) { - log.debug("Registration disabled."); - return; - } - if (this.registration.getPort() <= 0) { - this.registration.setPort(getPort().get()); - } - super.register(); - } - - @Override - protected void registerManagement() { - if (!this.registration.getPolarisProperties().isRegisterEnabled()) { - return; - } - super.registerManagement(); - - } - - @Override - protected Object getConfiguration() { - return this.registration.getPolarisProperties(); - } - - @Override - protected boolean isEnabled() { - return this.registration.getPolarisProperties().isRegisterEnabled(); - } - - @Override - @SuppressWarnings("deprecation") - protected String getAppName() { - String appName = registration.getPolarisProperties().getService(); - return StringUtils.isEmpty(appName) ? super.getAppName() : appName; - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java deleted file mode 100644 index 57bc3ceb..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.registry; - -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.cloud.polaris.PolarisProperties; -import com.tencent.polaris.client.api.SDKContext; -import java.net.URI; -import java.util.Map; -import org.apache.commons.lang.StringUtils; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.serviceregistry.Registration; - -/** - * @author Haotian Zhang, Andrew Shan, Jie Cheng - */ -public class PolarisRegistration implements Registration, ServiceInstance { - - private final PolarisProperties polarisProperties; - - private final SDKContext polarisContext; - - public PolarisRegistration(PolarisProperties polarisProperties, SDKContext context) { - this.polarisProperties = polarisProperties; - this.polarisContext = context; - } - - @Override - public String getServiceId() { - return polarisProperties.getService(); - } - - @Override - public String getHost() { - if (StringUtils.isNotBlank(polarisProperties.getIpAddress())) { - return polarisProperties.getIpAddress(); - } - return polarisContext.getConfig().getGlobal().getAPI().getBindIP(); - } - - @Override - public int getPort() { - return polarisProperties.getPort(); - } - - public void setPort(int port) { - this.polarisProperties.setPort(port); - } - - @Override - public boolean isSecure() { - return StringUtils.equalsIgnoreCase(polarisProperties.getProtocol(), "https"); - } - - @Override - public URI getUri() { - return DefaultServiceInstance.getUri(this); - } - - @Override - public Map getMetadata() { - return MetadataContextHolder.get().getAllSystemMetadata(); - } - - public PolarisProperties getPolarisProperties() { - return polarisProperties; - } - - @Override - public String toString() { - return "PolarisRegistration{" + - "polarisProperties=" + polarisProperties + - ", polarisContext=" + polarisContext + - '}'; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java deleted file mode 100644 index d3c87480..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.registry; - -import static org.springframework.util.ReflectionUtils.rethrowRuntimeException; - -import com.tencent.cloud.metadata.config.MetadataLocalProperties; -import com.tencent.cloud.polaris.PolarisProperties; -import com.tencent.cloud.polaris.util.OkHttpUtil; -import com.tencent.polaris.api.core.ProviderAPI; -import com.tencent.polaris.api.exception.PolarisException; -import com.tencent.polaris.api.pojo.Instance; -import com.tencent.polaris.api.rpc.InstanceDeregisterRequest; -import com.tencent.polaris.api.rpc.InstanceHeartbeatRequest; -import com.tencent.polaris.api.rpc.InstanceRegisterRequest; -import com.tencent.polaris.api.rpc.InstancesResponse; -import com.tencent.polaris.client.util.NamedThreadFactory; -import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import org.apache.logging.log4j.util.Strings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.BeanUtils; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.client.serviceregistry.ServiceRegistry; -import org.springframework.util.StringUtils; - -/** - * @author Haotian Zhang, Andrew Shan, Jie Cheng - */ -public class PolarisServiceRegistry implements ServiceRegistry { - - private static final Logger log = LoggerFactory.getLogger(PolarisServiceRegistry.class); - - private static final int ttl = 5; - - private final PolarisProperties polarisProperties; - - private final PolarisDiscoveryHandler polarisDiscoveryHandler; - - private final MetadataLocalProperties metadataLocalProperties; - - private final ScheduledExecutorService heartbeatExecutor; - - public PolarisServiceRegistry(PolarisProperties polarisProperties, PolarisDiscoveryHandler polarisDiscoveryHandler, - MetadataLocalProperties metadataLocalProperties) { - this.polarisProperties = polarisProperties; - this.polarisDiscoveryHandler = polarisDiscoveryHandler; - this.metadataLocalProperties = metadataLocalProperties; - if (polarisProperties.isHeartbeatEnabled()) { - ScheduledThreadPoolExecutor heartbeatExecutor = new ScheduledThreadPoolExecutor(0, - new NamedThreadFactory("spring-cloud-heartbeat")); - heartbeatExecutor.setMaximumPoolSize(1); - this.heartbeatExecutor = heartbeatExecutor; - } else { - this.heartbeatExecutor = null; - } - } - - @Override - public void register(Registration registration) { - - if (StringUtils.isEmpty(registration.getServiceId())) { - log.warn("No service to register for polaris client..."); - return; - } - // 注册实例 - InstanceRegisterRequest instanceRegisterRequest = new InstanceRegisterRequest(); - instanceRegisterRequest.setNamespace(polarisProperties.getNamespace()); - instanceRegisterRequest.setService(registration.getServiceId()); - instanceRegisterRequest.setHost(registration.getHost()); - instanceRegisterRequest.setPort(registration.getPort()); - instanceRegisterRequest.setToken(polarisProperties.getToken()); - if (null != heartbeatExecutor) { - instanceRegisterRequest.setTtl(ttl); - } - instanceRegisterRequest.setMetadata(metadataLocalProperties.getContent()); - instanceRegisterRequest.setProtocol(polarisProperties.getProtocol()); - instanceRegisterRequest.setVersion(polarisProperties.getVersion()); - try { - ProviderAPI providerClient = polarisDiscoveryHandler.getProviderAPI(); - providerClient.register(instanceRegisterRequest); - log.info("polaris registry, {} {} {}:{} {} register finished", - polarisProperties.getNamespace(), - registration.getServiceId(), registration.getHost(), - registration.getPort(), metadataLocalProperties.getContent()); - - if (null != heartbeatExecutor) { - InstanceHeartbeatRequest heartbeatRequest = new InstanceHeartbeatRequest(); - BeanUtils.copyProperties(instanceRegisterRequest, heartbeatRequest); - //注册成功后开始启动心跳线程 - heartbeat(heartbeatRequest); - } - } catch (Exception e) { - log.error("polaris registry, {} register failed...{},", registration.getServiceId(), registration, e); - rethrowRuntimeException(e); - } - } - - @Override - public void deregister(Registration registration) { - - log.info("De-registering from Polaris Server now..."); - - if (StringUtils.isEmpty(registration.getServiceId())) { - log.warn("No dom to de-register for polaris client..."); - return; - } - - InstanceDeregisterRequest deRegisterRequest = new InstanceDeregisterRequest(); - deRegisterRequest.setToken(polarisProperties.getToken()); - deRegisterRequest.setNamespace(polarisProperties.getNamespace()); - deRegisterRequest.setService(registration.getServiceId()); - deRegisterRequest.setHost(registration.getHost()); - deRegisterRequest.setPort(registration.getPort()); - - try { - ProviderAPI providerClient = polarisDiscoveryHandler.getProviderAPI(); - providerClient.deRegister(deRegisterRequest); - } catch (Exception e) { - log.error("ERR_POLARIS_DEREGISTER, de-register failed...{},", registration, e); - } finally { - if (null != heartbeatExecutor) { - heartbeatExecutor.shutdown(); - } - } - log.info("De-registration finished."); - } - - @Override - public void close() { - - } - - @Override - public void setStatus(Registration registration, String status) { - - } - - @Override - public Object getStatus(Registration registration) { - String serviceName = registration.getServiceId(); - InstancesResponse instancesResponse = polarisDiscoveryHandler.getInstances(serviceName); - Instance[] instances = instancesResponse.getInstances(); - if (null == instances || instances.length == 0) { - return null; - } - for (Instance instance : instances) { - if (instance.getHost().equalsIgnoreCase(registration.getHost()) - && instance.getPort() == polarisProperties.getPort()) { - return instance.isHealthy() ? "UP" : "DOWN"; - } - } - return null; - } - - /** - * 开启心跳线程 - * - * @param heartbeatRequest 心跳请求 - */ - public void heartbeat(InstanceHeartbeatRequest heartbeatRequest) { - heartbeatExecutor.scheduleWithFixedDelay(new Runnable() { - @Override - public void run() { - try { - String healthCheckUrl = String.format("http://%s:%s%s", heartbeatRequest.getHost(), heartbeatRequest.getPort(), polarisProperties.getHealthCheckUrl()); - //先判断是否配置了health-check-url,如果配置了,需要先进行服务实例健康检查,如果健康检查通过,则进行心跳上报,如果不通过,则不上报心跳 - if (Strings.isNotEmpty(healthCheckUrl) && !OkHttpUtil.get(healthCheckUrl, null)){ - log.error("polaris health check failed"); - return; - } - polarisDiscoveryHandler.getProviderAPI().heartbeat(heartbeatRequest); - } catch (PolarisException e) { - log.error("polaris heartbeat[{}]", e.getCode(), e); - } catch (Exception e) { - log.error("polaris heartbeat runtime error", e); - } - } - }, 0, ttl, TimeUnit.SECONDS); - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java deleted file mode 100644 index 71020f00..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.tencent.cloud.polaris.util; - -import com.squareup.okhttp.MediaType; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.Response; -import com.squareup.okhttp.OkHttpClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.util.Map; -import java.util.Objects; -/** - * okhttp util. - * - * @author kan peng - */ -public class OkHttpUtil { - public final static Logger logger = LoggerFactory.getLogger(OkHttpUtil.class); - /** - * JSON format - */ - public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8"); - /** - * client - */ - private final static OkHttpClient HTTP_CLIENT = new OkHttpClient(); - - /** - * get request. - * - * @param url url - * @param headers headers - * @return response - */ - public static boolean get(String url, Map headers) { - try { - Request.Builder builder = new Request.Builder(); - buildHeader(builder, headers); - Request request = builder.url(url).build(); - Response response = HTTP_CLIENT.newCall(request).execute(); - - if (response.isSuccessful() && Objects.nonNull(response.body())) { - String result = response.body().string(); - logger.info("exec get request, url: {} success,response data: {}", url, result); - return true; - } - } catch (Exception e) { - logger.error("exec get request,url: {} failed!", url, e); - } - return false; - } - - /** - * build header. - * - * @param builder builder - * @param headers headers - */ - private static void buildHeader(Request.Builder builder, Map headers) { - if (Objects.nonNull(headers) && headers.size() > 0) { - headers.forEach((k, v) -> { - if (Objects.nonNull(k) && Objects.nonNull(v)) { - builder.addHeader(k, v); - } - }); - } - } -} \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java deleted file mode 100644 index 5b6c7aa9..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscoveryTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.discovery; - -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 com.tencent.cloud.polaris.context.PolarisContextConfiguration; -import com.tencent.polaris.api.exception.PolarisException; - -import java.util.List; - -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.test.mock.discovery.NamingServer; -import com.tencent.polaris.test.mock.discovery.NamingService; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -import org.springframework.context.annotation.Configuration; - -public class PolarisServiceDiscoveryTest { - - private static NamingServer namingServer; - - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of( - PolarisContextConfiguration.class, - PolarisServiceDiscoveryTest.PolarisPropertiesConfiguration.class, - PolarisDiscoveryClientConfiguration.class, - PolarisDiscoveryAutoConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) - .withPropertyValues("server.port=" + PORT) - .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") - .withPropertyValues("spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) - .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); - - @BeforeClass - public static void beforeClass() throws Exception { - namingServer = NamingServer.startNamingServer(10081); - - // add service with 3 instances - NamingService.InstanceParameter instanceParameter = new NamingService.InstanceParameter(); - instanceParameter.setHealthy(true); - instanceParameter.setIsolated(false); - instanceParameter.setWeight(100); - ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER); - namingServer.getNamingService().batchAddInstances(serviceKey, PORT, 3, instanceParameter); - } - - @AfterClass - public static void afterClass() throws Exception { - if (null != namingServer) { - namingServer.terminate(); - } - } - - @Test - public void testGetInstances() { - this.contextRunner.run(context -> { - PolarisServiceDiscovery polarisServiceDiscovery = context.getBean(PolarisServiceDiscovery.class); - List serviceInstances = polarisServiceDiscovery.getInstances(SERVICE_PROVIDER); - assertThat(serviceInstances.isEmpty()).isFalse(); - assertThat(serviceInstances).hasSize(3); - assertThat(serviceInstances.get(0).getPort()).isEqualTo(PORT); - assertThat(serviceInstances.get(1).getPort()).isEqualTo(PORT + 1); - assertThat(serviceInstances.get(2).getPort()).isEqualTo(PORT + 2); - }); - } - - @Test - public void testGetServices() throws PolarisException { - this.contextRunner.run(context -> { - PolarisServiceDiscovery polarisServiceDiscovery = context.getBean(PolarisServiceDiscovery.class); - List services = polarisServiceDiscovery.getServices(); - assertThat(services.size()).isEqualTo(1); - }); - - } - - @Configuration - @EnableAutoConfiguration - @EnableDiscoveryClient - static class PolarisPropertiesConfiguration { - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java deleted file mode 100644 index 1265ca6e..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.registry; - -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.junit.Assert.fail; -import static org.mockito.Mockito.when; - -import com.tencent.cloud.polaris.context.PolarisContextConfiguration; -import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; -import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.test.mock.discovery.NamingServer; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.mockito.Mockito; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -import org.springframework.context.annotation.Configuration; - -public class PolarisServiceRegistryTest { - - private static NamingServer namingServer; - - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of( - PolarisContextConfiguration.class, - PolarisPropertiesConfiguration.class, - PolarisDiscoveryClientConfiguration.class, - PolarisDiscoveryAutoConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) - .withPropertyValues("server.port=" + PORT) - .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") - .withPropertyValues("spring.cloud.polaris.discovery.namespace="+ NAMESPACE_TEST) - .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); - - @BeforeClass - public static void beforeClass() throws Exception { - namingServer = NamingServer.startNamingServer(10081); - - // add service - namingServer.getNamingService().addService(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER)); - } - - @AfterClass - public static void afterClass() throws Exception { - if (null != namingServer) { - namingServer.terminate(); - } - } - - @Test - public void testRegister() { - this.contextRunner.run(context -> { - PolarisServiceRegistry registry = context.getBean(PolarisServiceRegistry.class); - PolarisRegistration registration = Mockito.mock(PolarisRegistration.class); - when(registration.getHost()).thenReturn("127.0.0.1"); - when(registration.getPort()).thenReturn(PORT); - when(registration.getServiceId()).thenReturn(SERVICE_PROVIDER); - - try { - registry.register(registration); - } catch (Exception e) { - fail(); - } - - try { - assertThat(registry.getStatus(registration)).isEqualTo("DOWN"); - } catch (Exception e) { - fail(); - } - - try { - registry.deregister(registration); - } catch (Exception e) { - fail(); - } - }); - } - - @Configuration - @EnableAutoConfiguration - @EnableDiscoveryClient - static class PolarisPropertiesConfiguration { - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java deleted file mode 100644 index f42fcb68..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.ribbon; - -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.mock; -import static org.mockito.Mockito.when; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import com.tencent.cloud.polaris.context.PolarisContextConfiguration; -import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; -import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; -import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; -import java.util.List; - -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.test.mock.discovery.NamingServer; -import com.tencent.polaris.test.mock.discovery.NamingService; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -import org.springframework.context.annotation.Configuration; - -public class PolarisServerListTest { - - private static NamingServer namingServer; - - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of( - PolarisContextConfiguration.class, - PolarisServerListTest.PolarisPropertiesConfiguration.class, - PolarisDiscoveryClientConfiguration.class, - PolarisDiscoveryAutoConfiguration.class)) - .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) - .withPropertyValues("server.port=" + PORT) - .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081") - .withPropertyValues("spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) - .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); - - @BeforeClass - public static void beforeClass() throws Exception { - namingServer = NamingServer.startNamingServer(10081); - - // add service - namingServer.getNamingService().addService(new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER)); - } - - @AfterClass - public static void afterClass() throws Exception { - if (null != namingServer) { - namingServer.terminate(); - } - } - - /** - * Test {@link PolarisServerList#getInitialListOfServers()} with empty server list. - */ - @Test - @SuppressWarnings("unchecked") - public void test1(){ - this.contextRunner.run(context -> { - // mock - IClientConfig iClientConfig = mock(IClientConfig.class); - when(iClientConfig.getClientName()).thenReturn(SERVICE_PROVIDER); - PolarisDiscoveryHandler polarisDiscoveryHandler = context.getBean(PolarisDiscoveryHandler.class); - PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); - serverList.initWithNiwsConfig(iClientConfig); - - List servers = serverList.getInitialListOfServers(); - assertThat(servers).isEmpty(); - }); - } - - /** - * Test {@link PolarisServerList#getUpdatedListOfServers()} with server list of size 3. - */ - @Test - @SuppressWarnings("unchecked") - public void test2() throws Exception { - this.contextRunner.run(context -> { - // mock - IClientConfig iClientConfig = mock(IClientConfig.class); - when(iClientConfig.getClientName()).thenReturn(SERVICE_PROVIDER); - PolarisDiscoveryHandler polarisDiscoveryHandler = context.getBean(PolarisDiscoveryHandler.class); - PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); - serverList.initWithNiwsConfig(iClientConfig); - - - // add service with 3 instances - NamingService.InstanceParameter instanceParameter = new NamingService.InstanceParameter(); - instanceParameter.setHealthy(true); - instanceParameter.setIsolated(false); - instanceParameter.setWeight(100); - ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER); - namingServer.getNamingService().batchAddInstances(serviceKey, PORT, 3, instanceParameter); - - List servers = serverList.getUpdatedListOfServers(); - assertThat(servers).hasSize(3); - assertThat(servers.get(0).getPort()).isEqualTo(PORT); - assertThat(servers.get(1).getPort()).isEqualTo(PORT + 1); - assertThat(servers.get(2).getPort()).isEqualTo(PORT + 2); - }); - } - - @Configuration - @EnableAutoConfiguration - @EnableDiscoveryClient - static class PolarisPropertiesConfiguration { - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml deleted file mode 100644 index acf7e431..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - spring-cloud-tencent-starters - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 - - spring-cloud-starter-tencent-polaris-ratelimit - Spring Cloud Starter Tencent Polaris Ratelimit - - - - - com.tencent.cloud - spring-cloud-tencent-commons - - - - com.tencent.cloud - spring-cloud-tencent-polaris-context - - - - com.tencent.cloud - spring-cloud-tencent-commons - - - - com.tencent.cloud - spring-cloud-tencent-metadata - - - - - - com.tencent.polaris - polaris-ratelimit-factory - - - - com.tencent.polaris - polaris-test-common - test - - - - com.tencent.polaris - polaris-test-mock-discovery - test - - - - - org.springframework.boot - spring-boot-starter-web - true - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - test - - - - org.powermock - powermock-module-junit4 - test - - - - org.powermock - powermock-api-mockito2 - test - - - \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/callee/QuotaCheckFilter.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/callee/QuotaCheckFilter.java deleted file mode 100644 index e1b1ee8c..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/callee/QuotaCheckFilter.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.ratelimit.callee; - -import static org.springframework.http.HttpStatus.TOO_MANY_REQUESTS; - -import com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.cloud.polaris.ratelimit.utils.Consts; -import com.tencent.cloud.polaris.ratelimit.utils.QuotaCheckUtils; -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 java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.web.filter.OncePerRequestFilter; - -/** - * @author Haotian Zhang - */ -@Order(QuotaCheckFilter.ORDER) -public class QuotaCheckFilter extends OncePerRequestFilter { - - private static final Logger LOG = LoggerFactory.getLogger(QuotaCheckFilter.class); - - public static final int ORDER = Ordered.HIGHEST_PRECEDENCE + 10; - - private final LimitAPI limitAPI; - - public QuotaCheckFilter(LimitAPI limitAPI) { - this.limitAPI = limitAPI; - } - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - String localNamespace = MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.LOCAL_NAMESPACE); - String localService = MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.LOCAL_SERVICE); - String method = MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.LOCAL_PATH); - Map labels = null; - if (StringUtils.isNotBlank(method)) { - labels = new HashMap<>(); - labels.put("method", method); - } - - try { - QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(limitAPI, localNamespace, localService, 1, labels, - null); - if (quotaResponse.getCode() == QuotaResultCode.QuotaResultLimited) { - response.setStatus(TOO_MANY_REQUESTS.value()); - response.getWriter().write(Consts.QUOTA_LIMITED_INFO + quotaResponse.getInfo()); - } else { - filterChain.doFilter(request, response); - } - } catch (Throwable t) { - //限流API调用出现异常,不应该影响业务流程的调用 - LOG.error("fail to invoke getQuota, service is " + localService, t); - filterChain.doFilter(request, response); - } - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/Consts.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/Consts.java deleted file mode 100644 index 34260e7b..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/Consts.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.ratelimit.utils; - -/** - * @author Haotian Zhang - */ -public interface Consts { - - String QUOTA_LIMITED_INFO = "request blocked by polaris, reason is "; -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 59b514cb..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.tencent.cloud.polaris.ratelimit.RateLimitConfiguration \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java deleted file mode 100644 index 2a4f4e80..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/controller/CalleeControllerTests.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.ratelimit.controller; - -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.test.mock.discovery.NamingServer; -import com.tencent.polaris.test.mock.discovery.NamingService; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -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.test.context.junit4.SpringRunner; -import org.springframework.web.client.HttpClientErrorException.TooManyRequests; -import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestTemplate; - -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.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - classes = {CalleeControllerTests.Config.class, - TestController.class}, properties = {"spring.application.name=java_provider_test", - "spring.cloud.polaris.discovery.namespace=Test", "spring.cloud.polaris.address=grpc://127.0.0.1:10081"}) -public class CalleeControllerTests { - - private static NamingServer namingServer; - - @LocalServerPort - private int port; - - @Autowired - private RestTemplate restTemplate; - - @MockBean - private LimitAPI limitAPI; - - @BeforeClass - public static void beforeClass() throws Exception { - namingServer = NamingServer.startNamingServer(10081); - - // add service with 3 instances - NamingService.InstanceParameter instanceParameter = new NamingService.InstanceParameter(); - instanceParameter.setHealthy(true); - instanceParameter.setIsolated(false); - instanceParameter.setWeight(100); - ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER); - namingServer.getNamingService().batchAddInstances(serviceKey, PORT, 3, instanceParameter); - } - - @AfterClass - public static void afterClass() throws Exception { - if (null != namingServer) { - namingServer.terminate(); - } - } - - @Before - public void setUp() throws Exception { - QuotaResponse quotaResponse = mock(QuotaResponse.class); - when(quotaResponse.getCode()).thenReturn(QuotaResultCode.QuotaResultOk); - when(limitAPI.getQuota(any())).thenReturn(quotaResponse); - } - - @Test - public void test1() { - String url = "http://localhost:" + port + "/test/info"; - - boolean hasPassed = false; - boolean hasLimited = false; - for (int i = 0; i < 30; i++) { - try { - if (i > 9) { - QuotaResponse quotaResponse = mock(QuotaResponse.class); - when(quotaResponse.getCode()).thenReturn(QuotaResultCode.QuotaResultLimited); - when(quotaResponse.getInfo()).thenReturn("Testing rate limit after 10 times success."); - when(limitAPI.getQuota(any())).thenReturn(quotaResponse); - } - String result = restTemplate.getForObject(url, String.class); - System.out.println(result + " [" + i + "]"); - hasPassed = true; - } catch (RestClientException e) { - if (e instanceof TooManyRequests) { - System.out.println(((TooManyRequests) e).getResponseBodyAsString()); - hasLimited = true; - } else { - e.printStackTrace(); - Assert.fail(e.getMessage()); - } - } - } - Assert.assertTrue(hasPassed); - Assert.assertTrue(hasLimited); - } - - - @Configuration - @EnableAutoConfiguration - public static class Config { - - @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); - } - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRoutingLoadBalancer.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRoutingLoadBalancer.java deleted file mode 100644 index 5c2258ef..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRoutingLoadBalancer.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.router; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.DynamicServerListLoadBalancer; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.PollingServerListUpdater; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.cloud.polaris.pojo.PolarisServer; -import com.tencent.polaris.api.pojo.DefaultInstance; -import com.tencent.polaris.api.pojo.DefaultServiceInstances; -import com.tencent.polaris.api.pojo.Instance; -import com.tencent.polaris.api.pojo.ServiceInfo; -import com.tencent.polaris.api.pojo.ServiceInstances; -import com.tencent.polaris.api.pojo.ServiceKey; -import com.tencent.polaris.router.api.core.RouterAPI; -import com.tencent.polaris.router.api.rpc.ProcessRoutersRequest; -import com.tencent.polaris.router.api.rpc.ProcessRoutersResponse; -import org.apache.commons.lang.StringUtils; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * @author Haotian Zhang - */ -public class PolarisRoutingLoadBalancer extends DynamicServerListLoadBalancer { - - private final RouterAPI routerAPI; - - public PolarisRoutingLoadBalancer(IClientConfig config, IRule rule, IPing ping, - ServerList serverList, RouterAPI routerAPI) { - super(config, rule, ping, serverList, null, new PollingServerListUpdater()); - this.routerAPI = routerAPI; - } - - @Override - public List getReachableServers() { - List allServers = super.getAllServers(); - if (CollectionUtils.isEmpty(allServers)) { - return allServers; - } - ServiceInstances serviceInstances = null; - if (allServers.get(0) instanceof PolarisServer) { - serviceInstances = ((PolarisServer) allServers.get(0)).getServiceInstances(); - } else { - String serviceName; - // notice the difference between different service registries - if (StringUtils.isNotBlank(allServers.get(0).getMetaInfo().getServiceIdForDiscovery())) { - serviceName = allServers.get(0).getMetaInfo().getServiceIdForDiscovery(); - } else { - serviceName = allServers.get(0).getMetaInfo().getAppName(); - } - if (StringUtils.isBlank(serviceName)) { - throw new IllegalStateException( - "PolarisRoutingLoadBalancer only Server with AppName or ServiceIdForDiscovery attribute"); - } - ServiceKey serviceKey = new ServiceKey(MetadataContextHolder.LOCAL_NAMESPACE, serviceName); - List instances = new ArrayList<>(8); - for (Server server : allServers) { - DefaultInstance instance = new DefaultInstance(); - instance.setNamespace(MetadataContextHolder.LOCAL_NAMESPACE); - instance.setService(serviceName); - instance.setHealthy(server.isAlive()); - instance.setProtocol(server.getScheme()); - instance.setId(server.getId()); - instance.setHost(server.getHost()); - instance.setPort(server.getPort()); - instance.setZone(server.getZone()); - instance.setWeight(100); - instances.add(instance); - } - serviceInstances = new DefaultServiceInstances(serviceKey, instances); - } - ProcessRoutersRequest processRoutersRequest = new ProcessRoutersRequest(); - processRoutersRequest.setDstInstances(serviceInstances); - String srcNamespace = MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.LOCAL_NAMESPACE); - String srcService = MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.LOCAL_SERVICE); - Map transitiveCustomMetadata = MetadataContextHolder.get().getAllTransitiveCustomMetadata(); - String method = MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.PEER_PATH); - processRoutersRequest.setMethod(method); - if (StringUtils.isNotBlank(srcNamespace) && StringUtils.isNotBlank(srcService)) { - ServiceInfo serviceInfo = new ServiceInfo(); - serviceInfo.setNamespace(srcNamespace); - serviceInfo.setService(srcService); - serviceInfo.setMetadata(transitiveCustomMetadata); - processRoutersRequest.setSourceService(serviceInfo); - } - ProcessRoutersResponse processRoutersResponse = routerAPI.processRouters(processRoutersRequest); - ServiceInstances filteredServiceInstances = processRoutersResponse.getServiceInstances(); - List filteredInstances = new ArrayList<>(); - for (Instance instance : filteredServiceInstances.getInstances()) { - filteredInstances.add(new PolarisServer(serviceInstances, instance)); - } - return filteredInstances; - } - - @Override - public List getAllServers() { - return getReachableServers(); - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/pom.xml b/spring-cloud-tencent-starters/spring-cloud-tencent-commons/pom.xml deleted file mode 100644 index 66d33281..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/pom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - spring-cloud-tencent-starters - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 - - spring-cloud-tencent-commons - Spring Cloud Tencent Commons - - - 3.2.2 - 2.5 - 2.7 - - - - - - com.tencent.polaris - polaris-model - - - - - org.springframework.boot - spring-boot-autoconfigure - - - - org.springframework.boot - spring-boot-configuration-processor - - - - org.springframework.cloud - spring-cloud-commons - - - - com.netflix.ribbon - ribbon-loadbalancer - - - - com.google.guava - guava - - - - commons-collections - commons-collections - ${commons.collections.version} - - - - commons-lang - commons-lang - ${commons.lang.version} - - - - commons-io - commons-io - ${commons.io.version} - - - - \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServer.java b/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServer.java deleted file mode 100644 index eeb8c74b..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServer.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.pojo; - -import com.google.common.base.Objects; -import com.netflix.loadbalancer.Server; -import com.tencent.polaris.api.pojo.Instance; -import com.tencent.polaris.api.pojo.ServiceInstances; -import org.apache.commons.lang.StringUtils; - -import java.util.Map; - -/** - * Polaris implementation of {@link Server} - * - * @author Haotian Zhang - */ -public class PolarisServer extends Server { - - private final ServiceInstances serviceInstances; - - private final Instance instance; - - private final MetaInfo metaInfo; - - public PolarisServer(ServiceInstances serviceInstances, Instance instance) { - super(instance.getHost(), instance.getPort()); - if (StringUtils.equalsIgnoreCase(instance.getProtocol(), "https")) { - setSchemea("https"); - } else { - setSchemea("http"); - } - this.serviceInstances = serviceInstances; - this.instance = instance; - this.metaInfo = new MetaInfo() { - @Override - public String getAppName() { - return instance.getService(); - } - - @Override - public String getServerGroup() { - return null; - } - - @Override - public String getServiceIdForDiscovery() { - return instance.getService(); - } - - @Override - public String getInstanceId() { - return instance.getId(); - } - }; - } - - public Instance getInstance() { - return instance; - } - - @Override - public MetaInfo getMetaInfo() { - return metaInfo; - } - - public Map getMetadata() { - return instance.getMetadata(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - if (!super.equals(o)) { - return false; - } - PolarisServer that = (PolarisServer) o; - return Objects.equal(instance, that.instance); - } - - @Override - public int hashCode() { - return Objects.hashCode(super.hashCode(), instance); - } - - public ServiceInstances getServiceInstances() { - return serviceInstances; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServiceInstance.java b/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServiceInstance.java deleted file mode 100644 index 056b063f..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServiceInstance.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.pojo; - -import com.tencent.polaris.api.pojo.Instance; -import org.apache.commons.lang.StringUtils; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; - -import java.net.URI; -import java.util.Map; - -/** - * Polaris implementation of {@link ServiceInstance} - * - * @author Haotian Zhang - */ -public class PolarisServiceInstance implements ServiceInstance { - - private final Instance instance; - - private final boolean isSecure; - - private final String scheme; - - public PolarisServiceInstance(Instance instance) { - this.instance = instance; - this.isSecure = StringUtils.equalsIgnoreCase(instance.getProtocol(), "https"); - if (isSecure) { - scheme = "https"; - } else { - scheme = "http"; - } - } - - @Override - public String getInstanceId() { - return ServiceInstance.super.getInstanceId(); - } - - @Override - public String getServiceId() { - return instance.getService(); - } - - @Override - public String getHost() { - return instance.getHost(); - } - - @Override - public int getPort() { - return instance.getPort(); - } - - @Override - public boolean isSecure() { - return this.isSecure; - } - - @Override - public URI getUri() { - return DefaultServiceInstance.getUri(this); - } - - @Override - public Map getMetadata() { - return instance.getMetadata(); - } - - @Override - public String getScheme() { - return this.scheme; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/pom.xml b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/pom.xml deleted file mode 100644 index b1a84d2d..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/pom.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - spring-cloud-tencent-starters - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 - - spring-cloud-tencent-feign - Spring Cloud Tencent Feign - - - - - com.tencent.cloud - spring-cloud-tencent-commons - - - - - org.springframework.cloud - spring-cloud-starter-openfeign - - - - \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java deleted file mode 100644 index 44ca1fb7..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.feign; - -import com.tencent.cloud.common.util.ReflectionUtils; -import feign.Contract; -import feign.Feign; -import feign.InvocationHandlerFactory; -import feign.Target; -import feign.hystrix.FallbackFactory; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import org.springframework.beans.BeansException; -import org.springframework.cloud.openfeign.FeignContext; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.util.StringUtils; - -/** - * Pluggable Feign builder. - * - * @author Haotian Zhang - */ -public class PluggableFeign { - - private PluggableFeign() { - } - - public static Builder builder() { - return new Builder(); - } - - public static final class Builder extends Feign.Builder implements ApplicationContextAware { - - private Contract contract = new Contract.Default(); - - private ApplicationContext applicationContext; - - private FeignContext feignContext; - - @Override - public Feign.Builder invocationHandlerFactory(InvocationHandlerFactory invocationHandlerFactory) { - throw new UnsupportedOperationException(); - } - - @Override - public Builder contract(Contract contract) { - this.contract = contract; - return this; - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - feignContext = applicationContext.getBean(FeignContext.class); - } - - @Override - public Feign build() { - super.invocationHandlerFactory(new InvocationHandlerFactory() { - @Override - public InvocationHandler create(Target target, Map dispatch) { - Object feignClientFactoryBean = applicationContext.getBean("&" + target.type().getName()); - - Class fallback = (Class) ReflectionUtils.getFieldValue(feignClientFactoryBean, "fallback"); - Class fallbackFactory = (Class) ReflectionUtils.getFieldValue(feignClientFactoryBean, - "fallbackFactory"); - String beanName = (String) ReflectionUtils.getFieldValue(feignClientFactoryBean, "contextId"); - if (!StringUtils.hasText(beanName)) { - beanName = (String) ReflectionUtils.getFieldValue(feignClientFactoryBean, "name"); - } - - Object fallbackInstance; - FallbackFactory fallbackFactoryInstance; - - // Get FeignPlugins - List pluggableFeignPlugins = getSortedFeignPrePlugins(); - - if (void.class != fallback) { - fallbackInstance = getFallbackInstanceFromContext(beanName, "fallback", fallback, - target.type()); - return new PluggableFeignInvocationHandler(target, dispatch, - new FallbackFactory.Default<>(fallbackInstance), pluggableFeignPlugins); - } - - if (void.class != fallbackFactory) { - fallbackFactoryInstance = (FallbackFactory) getFallbackInstanceFromContext(beanName, - "fallbackFactory", - fallbackFactory, FallbackFactory.class); - return new PluggableFeignInvocationHandler(target, dispatch, fallbackFactoryInstance, - pluggableFeignPlugins); - } - - return new PluggableFeignInvocationHandler(target, dispatch, null, pluggableFeignPlugins); - } - - private Object getFallbackInstanceFromContext(String name, String type, Class fallbackType, - Class targetType) { - if (feignContext == null) { - feignContext = applicationContext.getBean(FeignContext.class); - } - Object fallbackInstance = feignContext.getInstance(name, fallbackType); - if (fallbackInstance == null) { - throw new IllegalStateException(String.format("No %s instance of type %s found for feign " - + "client %s", - type, fallbackType, name)); - } - - if (!targetType.isAssignableFrom(fallbackType)) { - throw new IllegalStateException(String.format( - "Incompatible %s instance. Fallback/fallbackFactory of type %s is not assignable to " - + "%s for feign client %s", - type, fallbackType, targetType, name)); - } - return fallbackInstance; - } - - /** - * Ascending, which means the lower order number, the earlier executing the feign plugin. - * - * @return sorted feign pre plugin list - */ - private List getSortedFeignPrePlugins() { - Map feignPrePluginMap = - applicationContext.getBeansOfType(PluggableFeignPlugin.class); - return new ArrayList<>(feignPrePluginMap.values()) - .stream() - .sorted(Comparator.comparing(PluggableFeignPlugin::getOrder)) - .collect(Collectors.toList()); - } - }); - - super.contract(new PluggableFeignContractHolder(contract)); - return super.build(); - } - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignAutoConfiguration.java b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignAutoConfiguration.java deleted file mode 100644 index 75f1a94c..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignAutoConfiguration.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.feign; - -import feign.Feign; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Pluggable Feign Auto Configuration. - * - * @author Haotian Zhang - */ -@Configuration -@ConditionalOnProperty(name = "com.tencent.cloud.feign.enabled", matchIfMissing = true) -@ConditionalOnClass(Feign.class) -public class PluggableFeignAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public Feign.Builder pluggableFeignBuilder() { - return PluggableFeign.builder(); - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContext.java b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContext.java deleted file mode 100644 index 57484600..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContext.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.feign; - -import feign.FeignException; -import feign.InvocationHandlerFactory; -import feign.Target; -import feign.hystrix.FallbackFactory; - -import java.lang.reflect.Method; -import java.util.Map; - -/** - * Context used by PluggableFeign - * - * @author Haotian Zhang - */ -public class PluggableFeignContext { - - private Target target; - - private Map dispatch; - - private FallbackFactory fallbackFactory; - - private Map fallbackMethodMap; - - private Object proxy; - - private Method method; - - private Object[] args; - - private FeignException feignException; - - private Object result; - - public Target getTarget() { - return target; - } - - public void setTarget(Target target) { - this.target = target; - } - - public Map getDispatch() { - return dispatch; - } - - public void setDispatch(Map dispatch) { - this.dispatch = dispatch; - } - - public FallbackFactory getFallbackFactory() { - return fallbackFactory; - } - - public void setFallbackFactory(FallbackFactory fallbackFactory) { - this.fallbackFactory = fallbackFactory; - } - - public Map getFallbackMethodMap() { - return fallbackMethodMap; - } - - public void setFallbackMethodMap(Map fallbackMethodMap) { - this.fallbackMethodMap = fallbackMethodMap; - } - - public Object getProxy() { - return proxy; - } - - public void setProxy(Object proxy) { - this.proxy = proxy; - } - - public Method getMethod() { - return method; - } - - public void setMethod(Method method) { - this.method = method; - } - - public Object[] getArgs() { - return args; - } - - public void setArgs(Object[] args) { - this.args = args; - } - - public FeignException getFeignException() { - return feignException; - } - - public void setFeignException(FeignException feignException) { - this.feignException = feignException; - } - - public Object getResult() { - return result; - } - - public void setResult(Object result) { - this.result = result; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContractHolder.java b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContractHolder.java deleted file mode 100644 index 9b246d35..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContractHolder.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.feign; - -import feign.Contract; -import feign.MethodMetadata; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Contract for PluggableFeign - * - * @author Haotian Zhang - */ -public class PluggableFeignContractHolder implements Contract { - - private final Contract delegate; - - /** - * Key of metadata is full name of method including full name of class, name of method and types of parameters. - */ - public static final Map METHOD_METADATA = new HashMap<>(); - - public PluggableFeignContractHolder(Contract delegate) { - this.delegate = delegate; - } - - @Override - public List parseAndValidateMetadata(Class targetType) { - List metadataList = delegate.parseAndValidateMetadata(targetType); - metadataList.forEach(metadata -> - METHOD_METADATA.put(targetType.getPackage().getName() + "." + metadata.configKey(), metadata)); - return metadataList; - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignInvocationHandler.java b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignInvocationHandler.java deleted file mode 100644 index f05d4a4f..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignInvocationHandler.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.feign; - -import feign.FeignException; -import feign.InvocationHandlerFactory; -import feign.Target; -import feign.hystrix.FallbackFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.CollectionUtils; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import static feign.Util.checkNotNull; - -/** - * InvocationHandler used by PluggableFeign. - * - * @author Haotian Zhang - */ -public class PluggableFeignInvocationHandler implements InvocationHandler { - - private static final Logger LOG = LoggerFactory.getLogger(PluggableFeignInvocationHandler.class); - - private final Target target; - - private final Map dispatch; - - private FallbackFactory fallbackFactory; - - private Map fallbackMethodMap; - - private List prePluggableFeignPlugins; - - private List postPluggableFeignPlugins; - - private List exceptionPluggableFeignPlugins; - - PluggableFeignInvocationHandler(Target target, Map dispatch, - FallbackFactory fallbackFactory, List pluggableFeignPlugins) { - this.target = checkNotNull(target, "target"); - this.dispatch = checkNotNull(dispatch, "dispatch"); - this.fallbackFactory = fallbackFactory; - this.fallbackMethodMap = toFallbackMethod(dispatch); - - this.prePluggableFeignPlugins = new ArrayList<>(); - this.postPluggableFeignPlugins = new ArrayList<>(); - this.exceptionPluggableFeignPlugins = new ArrayList<>(); - for (PluggableFeignPlugin feignPlugin : pluggableFeignPlugins) { - if (feignPlugin.getType().equals(PluggableFeignPluginType.PRE)) { - prePluggableFeignPlugins.add(feignPlugin); - } else if (feignPlugin.getType().equals(PluggableFeignPluginType.POST)) { - postPluggableFeignPlugins.add(feignPlugin); - } else if (feignPlugin.getType().equals(PluggableFeignPluginType.EXCEPTION)) { - exceptionPluggableFeignPlugins.add(feignPlugin); - } - } - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if ("equals".equals(method.getName())) { - try { - Object otherHandler = args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null; - return equals(otherHandler); - } catch (IllegalArgumentException e) { - return false; - } - } else if ("hashCode".equals(method.getName())) { - return hashCode(); - } else if ("toString".equals(method.getName())) { - return toString(); - } - - Object result = null; - PluggableFeignContext context = new PluggableFeignContext(); - try { - context.setTarget(target); - context.setDispatch(dispatch); - context.setFallbackFactory(fallbackFactory); - context.setFallbackMethodMap(fallbackMethodMap); - context.setProxy(proxy); - context.setMethod(method); - context.setArgs(args); - - // executing pre plugins - for (PluggableFeignPlugin prePlugin : this.prePluggableFeignPlugins) { - prePlugin.run(context); - } - - result = this.dispatch.get(method).invoke(args); - - context.setResult(result); - - // executing post plugins - for (PluggableFeignPlugin postPlugin : this.postPluggableFeignPlugins) { - postPlugin.run(context); - } - } catch (Throwable throwable) { - if (throwable.getCause() instanceof FeignException) { - context.setFeignException((FeignException) throwable.getCause()); - } - - // executing exception plugins - for (PluggableFeignPlugin exceptionPlugin : this.exceptionPluggableFeignPlugins) { - exceptionPlugin.run(context); - } - - // executing fallback logic - if (this.fallbackFactory != null) { - return this.fallbackMethodMap.get(method).invoke(fallbackFactory.create(throwable), args); - } else { - LOG.error("FallbackFactory is null!"); - throw throwable; - } - } - - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof PluggableFeignInvocationHandler) { - PluggableFeignInvocationHandler other = (PluggableFeignInvocationHandler) obj; - return target.equals(other.target); - } - return false; - } - - @Override - public int hashCode() { - return target.hashCode(); - } - - @Override - public String toString() { - return target.toString(); - } - - static Map toFallbackMethod(Map dispatch) { - Map result = new LinkedHashMap<>(); - if (!CollectionUtils.isEmpty(dispatch)) { - for (Method method : dispatch.keySet()) { - method.setAccessible(true); - result.put(method, method); - } - } - return result; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignPluginType.java b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignPluginType.java deleted file mode 100644 index b21bc192..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignPluginType.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.feign; - -/** - * Type of PluggableFeign. - * - * @author Haotian Zhang - */ -public enum PluggableFeignPluginType { - - /** - * Pre feign plugin - */ - PRE, - - /** - * Post feign plugin - */ - POST, - - /** - * Exception feign plugin - */ - EXCEPTION - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index 16838cb6..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "properties": [ - { - "name": "com.tencent.cloud.feign.enabled", - "type": "java.lang.Boolean", - "defaultValue": true, - "description": "If feign is enabled." - } - ] -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 107c6ed5..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.tencent.cloud.feign.PluggableFeignAutoConfiguration diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/pom.xml b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/pom.xml deleted file mode 100644 index 1dd81df5..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/pom.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - spring-cloud-tencent-starters - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 - - spring-cloud-tencent-metadata - Spring Cloud Tencent Metadata - - - - - com.tencent.cloud - spring-cloud-tencent-commons - - - - com.tencent.cloud - spring-cloud-tencent-feign - - - - - org.springframework.boot - spring-boot-starter-web - true - - - - org.springframework.boot - spring-boot-starter-webflux - true - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - test - - - - - org.powermock - powermock-module-junit4 - test - - - - - org.powermock - powermock-api-mockito2 - test - - - - \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataConfiguration.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataConfiguration.java deleted file mode 100644 index eb6e4c3f..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/config/MetadataConfiguration.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.config; - -import com.tencent.cloud.feign.PluggableFeign; -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.metadata.core.filter.MetadataReactiveFilter; -import com.tencent.cloud.metadata.core.filter.MetadataServletFilter; -import com.tencent.cloud.metadata.core.interceptor.feign.Metadata2HeaderFeignInterceptor; -import com.tencent.cloud.metadata.core.interceptor.resttemplate.MetadataRestTemplateInterceptor; -import com.tencent.cloud.metadata.core.plugin.feign.MetadataFirstFeignPlugin; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.util.CollectionUtils; -import org.springframework.web.client.RestTemplate; - -import java.util.List; -import java.util.Map; - -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; - -/** - * Metadata Configuration - * - * @author Haotian Zhang - */ -@Configuration -public class MetadataConfiguration { - - /** - * metadata properties. - */ - @Bean - public MetadataLocalProperties metadataLocalProperties() { - return new MetadataLocalProperties(); - } - - /** - * Create when web application type is SERVLET. - */ - @Configuration - @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) - static class MetadataServletFilterConfig { - - @Bean - public FilterRegistrationBean - metadataServletFilterRegistrationBean(MetadataServletFilter metadataServletFilter) { - FilterRegistrationBean filterRegistrationBean = - new FilterRegistrationBean<>(metadataServletFilter); - filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST); - filterRegistrationBean.setOrder(MetadataConstant.OrderConstant.FILTER_ORDER); - return filterRegistrationBean; - } - - @Bean - public MetadataServletFilter metadataServletFilter(MetadataLocalProperties metadataLocalProperties) { - return new MetadataServletFilter(); - } - } - - /** - * Create when web application type is REACTIVE. - */ - @Configuration - @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) - static class MetadataReactiveFilterConfig { - - @Bean - public MetadataReactiveFilter metadataReactiveFilter(MetadataLocalProperties metadataLocalProperties) { - return new MetadataReactiveFilter(); - } - } - - /** - * Create when Feign exists. - */ - @Configuration - @ConditionalOnClass(PluggableFeign.Builder.class) - static class MetadataFeignPluginConfig { - - @Bean - public MetadataFirstFeignPlugin metadataFirstFeignPlugin() { - return new MetadataFirstFeignPlugin(); - } - - @Bean - public Metadata2HeaderFeignInterceptor metadataFeignInterceptor() { - return new Metadata2HeaderFeignInterceptor(); - } - } - - /** - * Create when RestTemplate exists. - */ - @Configuration - @ConditionalOnClass(RestTemplate.class) - static class MetadataRestTemplateConfig implements ApplicationContextAware { - - private ApplicationContext context; - - @Bean - public MetadataRestTemplateInterceptor metadataRestTemplateInterceptor() { - return new MetadataRestTemplateInterceptor(); - } - - @Bean - BeanPostProcessor metadataRestTemplatePostProcessor( - MetadataRestTemplateInterceptor metadataRestTemplateInterceptor) { - // Coping with multiple bean injection scenarios - Map beans = this.context.getBeansOfType(RestTemplate.class); - // If the restTemplate has been created when the MetadataRestTemplatePostProcessor Bean - // is initialized, then manually set the interceptor. - if (!CollectionUtils.isEmpty(beans)) { - for (RestTemplate restTemplate : beans.values()) { - List interceptors = restTemplate.getInterceptors(); - // Avoid setting interceptor repeatedly. - if (null != interceptors && !interceptors.contains(metadataRestTemplateInterceptor)) { - interceptors.add(metadataRestTemplateInterceptor); - restTemplate.setInterceptors(interceptors); - } - } - } - return new MetadataRestTemplatePostProcessor(metadataRestTemplateInterceptor); - } - - public static class MetadataRestTemplatePostProcessor implements BeanPostProcessor { - - private MetadataRestTemplateInterceptor metadataRestTemplateInterceptor; - - MetadataRestTemplatePostProcessor( - MetadataRestTemplateInterceptor metadataRestTemplateInterceptor) { - this.metadataRestTemplateInterceptor = metadataRestTemplateInterceptor; - } - - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) { - return bean; - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) { - if (bean instanceof RestTemplate) { - RestTemplate restTemplate = (RestTemplate) bean; - List interceptors = restTemplate.getInterceptors(); - // Avoid setting interceptor repeatedly. - if (null != interceptors && !interceptors.contains(metadataRestTemplateInterceptor)) { - interceptors.add(this.metadataRestTemplateInterceptor); - restTemplate.setInterceptors(interceptors); - } - } - return bean; - } - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.context = applicationContext; - } - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/constant/MetadataConstant.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/constant/MetadataConstant.java deleted file mode 100644 index 88e6a27a..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/constant/MetadataConstant.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.constant; - -import org.springframework.core.Ordered; - -/** - * Constant for spring-cloud-tencent-metadata. - * - * @author Haotian Zhang - */ -public interface MetadataConstant { - - /** - * Metadata HTTP header name. - */ - interface HeaderName { - - /** - * Custom metadata - */ - String CUSTOM_METADATA = "SCT-CUSTOM-METADATA"; - - /** - * System Metadata - */ - String SYSTEM_METADATA = "SCT-SYSTEM-METADATA"; - - /** - * Metadata context - */ - String METADATA_CONTEXT = "SCT-METADATA-CONTEXT"; - } - - /** - * Order of filter, interceptor, ... - */ - interface OrderConstant { - - /** - * Order of filter - */ - int FILTER_ORDER = Ordered.HIGHEST_PRECEDENCE + 3; - - /** - * Order of MetadataFirstFeignPlugin - */ - int METADATA_FIRST_FEIGN_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 1; - - /** - * Order of Metadata2HeaderFeignInterceptor - */ - int METADATA_2_HEADER_FEIGN_INTERCEPTOR_ORDER = Ordered.LOWEST_PRECEDENCE; - - /** - * Order of interceptor - */ - int INTERCEPTOR_ORDER = Ordered.LOWEST_PRECEDENCE; - } - - /** - * System metadata key - */ - interface SystemMetadataKey { - - /** - * Local namespace - */ - String LOCAL_NAMESPACE = "LOCAL_NAMESPACE"; - - /** - * Local service - */ - String LOCAL_SERVICE = "LOCAL_SERVICE"; - - /** - * Local path - */ - String LOCAL_PATH = "LOCAL_PATH"; - - /** - * Peer namespace - */ - String PEER_NAMESPACE = "PEER_NAMESPACE"; - - /** - * Peer service - */ - String PEER_SERVICE = "PEER_SERVICE"; - - /** - * Peer path - */ - String PEER_PATH = "PEER_PATH"; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContext.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContext.java deleted file mode 100644 index 8b9ee06f..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContext.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.context; - -import com.tencent.cloud.metadata.util.JacksonUtils; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * Transitive Metadata Context - * - * @author Haotian Zhang - */ -public class MetadataContext { - - /** - * Transitive custom metadata content - */ - private Map transitiveCustomMetadata; - - /** - * System metadata content - */ - private Map systemMetadata; - - public MetadataContext() { - this.transitiveCustomMetadata = new HashMap<>(); - this.systemMetadata = new HashMap<>(); - } - - public Map getAllTransitiveCustomMetadata() { - return Collections.unmodifiableMap(this.transitiveCustomMetadata); - } - - public String getTransitiveCustomMetadata(String key) { - return this.transitiveCustomMetadata.get(key); - } - - public void putTransitiveCustomMetadata(String key, String value) { - this.transitiveCustomMetadata.put(key, value); - } - - public void putAllTransitiveCustomMetadata(Map customMetadata) { - this.transitiveCustomMetadata.putAll(customMetadata); - } - - public Map getAllSystemMetadata() { - return Collections.unmodifiableMap(this.systemMetadata); - } - - public String getSystemMetadata(String key) { - return this.systemMetadata.get(key); - } - - public void putSystemMetadata(String key, String value) { - this.systemMetadata.put(key, value); - } - - public void putAllSystemMetadata(Map systemMetadata) { - this.systemMetadata.putAll(systemMetadata); - } - - @Override - public String toString() { - return "MetadataContext{" + - "transitiveCustomMetadata=" + JacksonUtils.serialize2Json(transitiveCustomMetadata) + - ", systemMetadata=" + JacksonUtils.serialize2Json(systemMetadata) + - '}'; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContextHolder.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContextHolder.java deleted file mode 100644 index 3235c89d..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/context/MetadataContextHolder.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.context; - -import com.tencent.cloud.metadata.config.MetadataLocalProperties; -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.common.util.ApplicationContextAwareUtils; -import org.springframework.util.CollectionUtils; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Metadata Context Holder - * - * @author Haotian Zhang - */ -public class MetadataContextHolder { - - private static final ThreadLocal METADATA_CONTEXT = new InheritableThreadLocal<>(); - - private static MetadataLocalProperties metadataLocalProperties; - - public static final String LOCAL_NAMESPACE = ApplicationContextAwareUtils.getProperties("spring.cloud" - + ".polaris.discovery.namespace", "default"); - - private static final String LOCAL_SPRING_APPLICATION_NAME = - ApplicationContextAwareUtils.getProperties("spring.application.name", null); - - public static final String LOCAL_SERVICE = ApplicationContextAwareUtils.getProperties("spring.cloud.polaris" - + ".discovery.service", LOCAL_SPRING_APPLICATION_NAME); - - /** - * Get metadata context. - * Create if not existing. - * - * @return METADATA_CONTEXT - */ - public static MetadataContext get() { - if (null == METADATA_CONTEXT.get()) { - MetadataContext metadataContext = new MetadataContext(); - if (metadataLocalProperties == null) { - metadataLocalProperties = (MetadataLocalProperties) ApplicationContextAwareUtils - .getApplicationContext().getBean("metadataLocalProperties"); - } - - // init custom metadata and load local metadata - Map transitiveMetadataMap = getTransitiveMetadataMap(metadataLocalProperties.getContent(), - metadataLocalProperties.getTransitive()); - metadataContext.putAllTransitiveCustomMetadata(transitiveMetadataMap); - - // init system metadata - metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE, - LOCAL_NAMESPACE); - metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.LOCAL_SERVICE, - LOCAL_SERVICE); - - METADATA_CONTEXT.set(metadataContext); - } - return METADATA_CONTEXT.get(); - } - - /** - * Filter and store the transitive metadata to transitive metadata context. - * - * @param source - * @param transitiveMetadataKeyList - * @return result - */ - private static Map getTransitiveMetadataMap(Map source, - List transitiveMetadataKeyList) { - Map result = new HashMap<>(); - for (String key : transitiveMetadataKeyList) { - if (source.containsKey(key)) { - result.put(key, source.get(key)); - } - } - return result; - } - - /** - * Set metadata context. - * - * @param metadataContext - */ - public static void set(MetadataContext metadataContext) { - METADATA_CONTEXT.set(metadataContext); - } - - /** - * Save metadata map to thread local. - * - * @param customMetadataMap - * @param systemMetadataMap - */ - public static void init(Map customMetadataMap, Map systemMetadataMap) { - // Init ThreadLocal. - MetadataContextHolder.remove(); - MetadataContext metadataContext = MetadataContextHolder.get(); - - // Save to ThreadLocal. - if (!CollectionUtils.isEmpty(customMetadataMap)) { - metadataContext.putAllTransitiveCustomMetadata(customMetadataMap); - } - if (!CollectionUtils.isEmpty(systemMetadataMap)) { - metadataContext.putAllSystemMetadata(systemMetadataMap); - } - MetadataContextHolder.set(metadataContext); - } - - /** - * Remove metadata context. - */ - public static void remove() { - METADATA_CONTEXT.remove(); - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/MetadataReactiveFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/MetadataReactiveFilter.java deleted file mode 100644 index a683d681..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/MetadataReactiveFilter.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.core.filter; - -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.cloud.metadata.util.JacksonUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.Ordered; -import org.springframework.http.HttpHeaders; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.util.StringUtils; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.WebFilter; -import org.springframework.web.server.WebFilterChain; -import reactor.core.publisher.Mono; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.HashMap; -import java.util.Map; - -import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE; -import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_PATH; -import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_SERVICE; - -/** - * Filter used for storing the metadata from upstream temporarily when web application is REACTIVE. - * - * @author Haotian Zhang - */ -public class MetadataReactiveFilter implements WebFilter, Ordered { - - private static final Logger LOG = LoggerFactory.getLogger(MetadataReactiveFilter.class); - - @Override - public int getOrder() { - return MetadataConstant.OrderConstant.FILTER_ORDER; - } - - @Override - public Mono filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) { - // Get metadata string from http header. - ServerHttpRequest serverHttpRequest = serverWebExchange.getRequest(); - HttpHeaders httpHeaders = serverHttpRequest.getHeaders(); - String customMetadataStr = httpHeaders.getFirst(MetadataConstant.HeaderName.CUSTOM_METADATA); - try { - if (StringUtils.hasText(customMetadataStr)) { - customMetadataStr = URLDecoder.decode(customMetadataStr, "UTF-8"); - } - } catch (UnsupportedEncodingException e) { - LOG.error("Runtime system does not support utf-8 coding.", e); - } - LOG.debug("Get upstream metadata string: {}", customMetadataStr); - - // create custom metadata. - Map upstreamCustomMetadataMap = JacksonUtils.deserialize2Map(customMetadataStr); - - // create system metadata. - Map systemMetadataMap = new HashMap<>(); - systemMetadataMap.put(LOCAL_NAMESPACE, MetadataContextHolder.LOCAL_NAMESPACE); - systemMetadataMap.put(LOCAL_SERVICE, MetadataContextHolder.LOCAL_SERVICE); - systemMetadataMap.put(LOCAL_PATH, serverHttpRequest.getURI().getPath()); - - MetadataContextHolder.init(upstreamCustomMetadataMap, systemMetadataMap); - - // Save to ServerWebExchange. - serverWebExchange.getAttributes() - .put(MetadataConstant.HeaderName.METADATA_CONTEXT, MetadataContextHolder.get()); - return webFilterChain.filter(serverWebExchange) - .doOnError(throwable -> LOG.error("handle metadata[{}] error.", MetadataContextHolder.get(), throwable)) - .doFinally((type) -> MetadataContextHolder.remove()); - } -} \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/MetadataServletFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/MetadataServletFilter.java deleted file mode 100644 index ff4e57b6..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/filter/MetadataServletFilter.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.core.filter; - -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.cloud.metadata.util.JacksonUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.StringUtils; -import org.springframework.web.filter.OncePerRequestFilter; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.HashMap; -import java.util.Map; - -import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE; -import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_PATH; -import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_SERVICE; - -/** - * Filter used for storing the metadata from upstream temporarily when web application is SERVLET. - * - * @author Haotian Zhang - */ -public class MetadataServletFilter extends OncePerRequestFilter { - - private static final Logger LOG = LoggerFactory.getLogger(MetadataServletFilter.class); - - @Override - protected void doFilterInternal(HttpServletRequest httpServletRequest, - HttpServletResponse httpServletResponse, - FilterChain filterChain) throws ServletException, IOException { - // Get custom metadata string from http header. - String customMetadataStr = httpServletRequest.getHeader(MetadataConstant.HeaderName.CUSTOM_METADATA); - try { - if (StringUtils.hasText(customMetadataStr)) { - customMetadataStr = URLDecoder.decode(customMetadataStr, "UTF-8"); - } - } catch (UnsupportedEncodingException e) { - LOG.error("Runtime system does not support utf-8 coding.", e); - } - LOG.debug("Get upstream metadata string: {}", customMetadataStr); - - // create custom metadata. - Map upstreamCustomMetadataMap = JacksonUtils.deserialize2Map(customMetadataStr); - - // create system metadata. - Map systemMetadataMap = new HashMap<>(); - systemMetadataMap.put(LOCAL_NAMESPACE, MetadataContextHolder.LOCAL_NAMESPACE); - systemMetadataMap.put(LOCAL_SERVICE, MetadataContextHolder.LOCAL_SERVICE); - systemMetadataMap.put(LOCAL_PATH, httpServletRequest.getRequestURI()); - - try { - MetadataContextHolder.init(upstreamCustomMetadataMap, systemMetadataMap); - - filterChain.doFilter(httpServletRequest, httpServletResponse); - } catch (IOException | ServletException | RuntimeException e) { - throw e; - } finally { - MetadataContextHolder.remove(); - } - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/Metadata2HeaderFeignInterceptor.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/Metadata2HeaderFeignInterceptor.java deleted file mode 100644 index 11c33ed0..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/feign/Metadata2HeaderFeignInterceptor.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.core.interceptor.feign; - -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.metadata.util.JacksonUtils; -import com.tencent.cloud.metadata.context.MetadataContext; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import feign.RequestInterceptor; -import feign.RequestTemplate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.Ordered; -import org.springframework.util.CollectionUtils; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.Map; - -import static com.tencent.cloud.metadata.constant.MetadataConstant.HeaderName.CUSTOM_METADATA; - -/** - * Interceptor used for adding the metadata in http headers from context when web client is Feign. - * - * @author Haotian Zhang - */ -public class Metadata2HeaderFeignInterceptor implements RequestInterceptor, Ordered { - - private static final Logger LOG = LoggerFactory.getLogger(Metadata2HeaderFeignInterceptor.class); - - @Override - public int getOrder() { - return MetadataConstant.OrderConstant.METADATA_2_HEADER_FEIGN_INTERCEPTOR_ORDER; - } - - @Override - public void apply(RequestTemplate requestTemplate) { - // get metadata of current thread - MetadataContext metadataContext = MetadataContextHolder.get(); - - // add new metadata and cover old - if (!CollectionUtils.isEmpty(requestTemplate.headers()) - && !CollectionUtils.isEmpty(requestTemplate.headers().get(CUSTOM_METADATA))) { - for (String headerMetadataStr : requestTemplate.headers().get(CUSTOM_METADATA)) { - Map headerMetadataMap = JacksonUtils.deserialize2Map(headerMetadataStr); - for (String key : headerMetadataMap.keySet()) { - metadataContext.putTransitiveCustomMetadata(key, headerMetadataMap.get(key)); - } - } - } - - Map customMetadata = metadataContext.getAllTransitiveCustomMetadata(); - if (!CollectionUtils.isEmpty(customMetadata)) { - String metadataStr = JacksonUtils.serialize2Json(customMetadata); - requestTemplate.removeHeader(CUSTOM_METADATA); - try { - requestTemplate.header(CUSTOM_METADATA, - URLEncoder.encode(metadataStr, "UTF-8")); - } catch (UnsupportedEncodingException e) { - LOG.error("Set header failed.", e); - requestTemplate.header(CUSTOM_METADATA, metadataStr); - } - } - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/resttemplate/MetadataRestTemplateInterceptor.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/resttemplate/MetadataRestTemplateInterceptor.java deleted file mode 100644 index 48322e66..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/interceptor/resttemplate/MetadataRestTemplateInterceptor.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.core.interceptor.resttemplate; - -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.metadata.context.MetadataContext; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.cloud.metadata.util.JacksonUtils; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.Map; -import org.springframework.core.Ordered; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; - -/** - * Interceptor used for adding the metadata in http headers from context when web client is RestTemplate. - * - * @author Haotian Zhang - */ -public class MetadataRestTemplateInterceptor implements ClientHttpRequestInterceptor, Ordered { - - @Override - public int getOrder() { - return MetadataConstant.OrderConstant.INTERCEPTOR_ORDER; - } - - @Override - public ClientHttpResponse intercept(HttpRequest httpRequest, - byte[] bytes, - ClientHttpRequestExecution clientHttpRequestExecution) throws IOException { - // get metadata of current thread - MetadataContext metadataContext = MetadataContextHolder.get(); - - // add new metadata and cover old - String metadataStr = httpRequest.getHeaders().getFirst(MetadataConstant.HeaderName.CUSTOM_METADATA); - if (!StringUtils.isEmpty(metadataStr)) { - Map headerMetadataMap = JacksonUtils.deserialize2Map(metadataStr); - for (String key : headerMetadataMap.keySet()) { - metadataContext.putTransitiveCustomMetadata(key, headerMetadataMap.get(key)); - } - } - Map customMetadata = metadataContext.getAllTransitiveCustomMetadata(); - if (!CollectionUtils.isEmpty(customMetadata)) { - metadataStr = JacksonUtils.serialize2Json(customMetadata); - try { - httpRequest.getHeaders().set(MetadataConstant.HeaderName.CUSTOM_METADATA, - URLEncoder.encode(metadataStr, "UTF-8")); - } catch (UnsupportedEncodingException e) { - httpRequest.getHeaders().set(MetadataConstant.HeaderName.CUSTOM_METADATA, metadataStr); - } - } - return clientHttpRequestExecution.execute(httpRequest, bytes); - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/plugin/feign/MetadataFirstFeignPlugin.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/plugin/feign/MetadataFirstFeignPlugin.java deleted file mode 100644 index 5d5f1148..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/core/plugin/feign/MetadataFirstFeignPlugin.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.core.plugin.feign; - -import com.tencent.cloud.feign.PluggableFeignContext; -import com.tencent.cloud.feign.PluggableFeignContractHolder; -import com.tencent.cloud.feign.PluggableFeignPlugin; -import com.tencent.cloud.feign.PluggableFeignPluginType; -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.metadata.context.MetadataContext; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import feign.Feign; -import feign.MethodMetadata; -import feign.RequestTemplate; - -/** - * Plugin used for adding the metadata in http headers from context when web client is Feign. - * - * @author Haotian Zhang - */ -public class MetadataFirstFeignPlugin implements PluggableFeignPlugin { - - @Override - public int getOrder() { - return MetadataConstant.OrderConstant.METADATA_FIRST_FEIGN_PLUGIN_ORDER; - } - - @Override - public String getName() { - return MetadataFirstFeignPlugin.class.getName(); - } - - @Override - public PluggableFeignPluginType getType() { - return PluggableFeignPluginType.PRE; - } - - @Override - public void run(PluggableFeignContext context) { - if (context.getTarget() != null && context.getMethod() != null) { - MethodMetadata methodMetadata = PluggableFeignContractHolder.METHOD_METADATA - .get(context.getTarget().type().getPackage().getName() + "." - + Feign.configKey(context.getTarget().type(), context.getMethod())); - if (methodMetadata == null) { - return; - } - RequestTemplate requestTemplate = methodMetadata.template(); - // get metadata of current thread - MetadataContext metadataContext = MetadataContextHolder.get(); - - // TODO 对端命名空间暂时与本地命名空间相同 - MetadataContextHolder.get().putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_NAMESPACE, - metadataContext.getSystemMetadata(MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE)); - MetadataContextHolder.get().putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_SERVICE, - context.getTarget().name()); - MetadataContextHolder.get().putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_PATH, - requestTemplate.path()); - } - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/util/JacksonUtils.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/util/JacksonUtils.java deleted file mode 100644 index a5b9d156..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/util/JacksonUtils.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.util; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.StringUtils; - -import java.util.HashMap; -import java.util.Map; - -/** - * @author Haotian Zhang - */ -public class JacksonUtils { - - private static final Logger LOG = LoggerFactory.getLogger(JacksonUtils.class); - - /** - * Object Mapper - */ - public static final ObjectMapper OM = new ObjectMapper(); - - /** - * Object to Json - * - * @param object - * @param type of object - * @return Json String - */ - public static String serialize2Json(T object) { - try { - return OM.writeValueAsString(object); - } catch (JsonProcessingException e) { - LOG.error("Object to Json failed. {}", object, e); - throw new RuntimeException("Object to Json failed.", e); - } - } - - /** - * Json to Map - * - * @param jsonStr Json String - * @return Map - */ - public static Map deserialize2Map(String jsonStr) { - try { - if (StringUtils.hasText(jsonStr)) { - return OM.readValue(jsonStr, Map.class); - } - return new HashMap<>(); - } catch (JsonProcessingException e) { - LOG.error("Json to map failed. check if the format of the json string[{}] is correct.", jsonStr, e); - throw new RuntimeException("Json to map failed.", e); - } - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/util/MetadataUtils.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/util/MetadataUtils.java deleted file mode 100644 index 08372f48..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/main/java/com/tencent/cloud/metadata/util/MetadataUtils.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.util; - -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; - -import java.util.HashMap; -import java.util.Map; - -/** - * Processing metadata. - * - * @author Haotian Zhang - */ -public class MetadataUtils { - - /** - * merge metadata map and new metadata map string. - * - * @param localCustomMetadataMap - * @param newMetadataStr - * @return - */ - public static Map loadAndMergeCustomMetadata(Map localCustomMetadataMap, - String newMetadataStr) { - // Load local metadata. - Map metadataMap = new HashMap<>(); - if (!CollectionUtils.isEmpty(localCustomMetadataMap)) { - metadataMap.putAll(localCustomMetadataMap); - } - - // Transfer string to map. - if (StringUtils.hasText(newMetadataStr)) { - Map requestMetadataMap = JacksonUtils.deserialize2Map(newMetadataStr); - - // metadata from upstream cover local metadata for this thread. - for (String key : requestMetadataMap.keySet()) { - metadataMap.put(key, requestMetadataMap.get(key)); - } - } - - return metadataMap; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataConfigurationTest.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataConfigurationTest.java deleted file mode 100644 index 5b086c6e..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/config/MetadataConfigurationTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.config; - -import com.tencent.cloud.metadata.core.filter.MetadataReactiveFilter; -import com.tencent.cloud.metadata.core.filter.MetadataServletFilter; -import com.tencent.cloud.metadata.core.interceptor.feign.Metadata2HeaderFeignInterceptor; -import com.tencent.cloud.metadata.core.interceptor.resttemplate.MetadataRestTemplateInterceptor; -import com.tencent.cloud.metadata.core.plugin.feign.MetadataFirstFeignPlugin; -import org.assertj.core.api.Assertions; -import org.junit.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; - -/** - * Test of {@link MetadataConfiguration} - * - * @author skyehtzhang - */ -public class MetadataConfigurationTest { - - private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner(); - - private final WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner(); - - private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = - new ReactiveWebApplicationContextRunner(); - - /** - * No any web application. - */ - @Test - public void test1() { - this.applicationContextRunner - .withConfiguration(AutoConfigurations.of(MetadataConfiguration.class)) - .run(context -> { - Assertions.assertThat(context).hasSingleBean(MetadataLocalProperties.class); - Assertions.assertThat(context) - .doesNotHaveBean(MetadataConfiguration.MetadataReactiveFilterConfig.class); - Assertions.assertThat(context).doesNotHaveBean(MetadataReactiveFilter.class); - Assertions.assertThat(context) - .doesNotHaveBean(MetadataConfiguration.MetadataServletFilterConfig.class); - Assertions.assertThat(context).doesNotHaveBean(MetadataServletFilter.class); - Assertions.assertThat(context) - .hasSingleBean(MetadataConfiguration.MetadataFeignPluginConfig.class); - Assertions.assertThat(context).hasSingleBean(MetadataFirstFeignPlugin.class); - Assertions.assertThat(context).hasSingleBean(Metadata2HeaderFeignInterceptor.class); - Assertions.assertThat(context) - .hasSingleBean(MetadataConfiguration.MetadataRestTemplateConfig.class); - Assertions.assertThat(context).hasSingleBean(MetadataRestTemplateInterceptor.class); - Assertions.assertThat(context).hasSingleBean(MetadataConfiguration - .MetadataRestTemplateConfig.MetadataRestTemplatePostProcessor.class); - }); - } - - /** - * web application. - */ - @Test - public void test2() { - this.webApplicationContextRunner - .withConfiguration(AutoConfigurations.of(MetadataConfiguration.class)) - .run(context -> { - Assertions.assertThat(context).hasSingleBean(MetadataLocalProperties.class); - Assertions.assertThat(context) - .doesNotHaveBean(MetadataConfiguration.MetadataReactiveFilterConfig.class); - Assertions.assertThat(context).doesNotHaveBean(MetadataReactiveFilter.class); - Assertions.assertThat(context) - .hasSingleBean(MetadataConfiguration.MetadataServletFilterConfig.class); - Assertions.assertThat(context).hasSingleBean(MetadataServletFilter.class); - Assertions.assertThat(context) - .hasSingleBean(MetadataConfiguration.MetadataFeignPluginConfig.class); - Assertions.assertThat(context).hasSingleBean(MetadataFirstFeignPlugin.class); - Assertions.assertThat(context).hasSingleBean(Metadata2HeaderFeignInterceptor.class); - Assertions.assertThat(context) - .hasSingleBean(MetadataConfiguration.MetadataRestTemplateConfig.class); - Assertions.assertThat(context).hasSingleBean(MetadataRestTemplateInterceptor.class); - Assertions.assertThat(context).hasSingleBean(MetadataConfiguration - .MetadataRestTemplateConfig.MetadataRestTemplatePostProcessor.class); - }); - } - - /** - * reactive web application. - */ - @Test - public void test3() { - this.reactiveWebApplicationContextRunner - .withConfiguration(AutoConfigurations.of(MetadataConfiguration.class)) - .run(context -> { - Assertions.assertThat(context).hasSingleBean(MetadataLocalProperties.class); - Assertions.assertThat(context) - .hasSingleBean(MetadataConfiguration.MetadataReactiveFilterConfig.class); - Assertions.assertThat(context).hasSingleBean(MetadataReactiveFilter.class); - Assertions.assertThat(context) - .doesNotHaveBean(MetadataConfiguration.MetadataServletFilterConfig.class); - Assertions.assertThat(context).doesNotHaveBean(MetadataServletFilter.class); - Assertions.assertThat(context) - .hasSingleBean(MetadataConfiguration.MetadataFeignPluginConfig.class); - Assertions.assertThat(context).hasSingleBean(MetadataFirstFeignPlugin.class); - Assertions.assertThat(context).hasSingleBean(Metadata2HeaderFeignInterceptor.class); - Assertions.assertThat(context) - .hasSingleBean(MetadataConfiguration.MetadataRestTemplateConfig.class); - Assertions.assertThat(context).hasSingleBean(MetadataRestTemplateInterceptor.class); - Assertions.assertThat(context).hasSingleBean(MetadataConfiguration - .MetadataRestTemplateConfig.MetadataRestTemplatePostProcessor.class); - }); - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/context/MetadataContextHolderTest.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/context/MetadataContextHolderTest.java deleted file mode 100644 index a842bc35..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/context/MetadataContextHolderTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.context; - -import org.assertj.core.api.Assertions; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.HashMap; -import java.util.Map; - -import static com.tencent.cloud.metadata.constant.MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * Test for {@link MetadataContextHolder} - * - * @author skyehtzhang - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - classes = MetadataContextHolderTest.TestApplication.class, - properties = {"spring.config.location = classpath:application-test.yml"}) -public class MetadataContextHolderTest { - - @Test - public void test1() { - Map customMetadata = new HashMap<>(); - customMetadata.put("a", "1"); - customMetadata.put("b", "2"); - MetadataContext metadataContext = MetadataContextHolder.get(); - metadataContext.putAllTransitiveCustomMetadata(customMetadata); - MetadataContextHolder.set(metadataContext); - - customMetadata = MetadataContextHolder.get().getAllTransitiveCustomMetadata(); - Assertions.assertThat(customMetadata.get("a")).isEqualTo("1"); - Assertions.assertThat(customMetadata.get("b")).isEqualTo("2"); - - MetadataContextHolder.remove(); - - customMetadata = new HashMap<>(); - customMetadata.put("a", "1"); - customMetadata.put("b", "22"); - customMetadata.put("c", "3"); - Map systemMetadata = new HashMap<>(); - systemMetadata.put(LOCAL_NAMESPACE, "namespace"); - MetadataContextHolder.init(customMetadata, systemMetadata); - metadataContext = MetadataContextHolder.get(); - customMetadata = metadataContext.getAllTransitiveCustomMetadata(); - systemMetadata = metadataContext.getAllSystemMetadata(); - Assertions.assertThat(customMetadata.get("a")).isEqualTo("1"); - Assertions.assertThat(customMetadata.get("b")).isEqualTo("22"); - Assertions.assertThat(customMetadata.get("c")).isEqualTo("3"); - Assertions.assertThat(systemMetadata.get(LOCAL_NAMESPACE)).isEqualTo("namespace"); - } - - @Test - public void test2() { - Assertions.assertThat(MetadataContextHolder.LOCAL_NAMESPACE).isEqualTo("default"); - Assertions.assertThat(MetadataContextHolder.LOCAL_SERVICE).isEqualTo("test"); - } - - @SpringBootApplication - protected static class TestApplication { - - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/feign/Metadata2HeaderFeignInterceptorTest.java b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/feign/Metadata2HeaderFeignInterceptorTest.java deleted file mode 100644 index ad32c4dc..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/java/com/tencent/cloud/metadata/core/intercepter/feign/Metadata2HeaderFeignInterceptorTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.core.intercepter.feign; - -import com.tencent.cloud.metadata.config.MetadataLocalProperties; -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.cloud.metadata.core.interceptor.feign.Metadata2HeaderFeignInterceptor; -import com.tencent.cloud.metadata.util.JacksonUtils; -import feign.RequestInterceptor; -import feign.RequestTemplate; -import org.assertj.core.api.Assertions; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.openfeign.EnableFeignClients; -import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; - -/** - * {@link Metadata2HeaderFeignInterceptor} - * - * @author skyehtzhang - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = DEFINED_PORT, - classes = Metadata2HeaderFeignInterceptorTest.TestApplication.class, - properties = {"server.port=8081", "spring.config.location = classpath:application-test.yml"}) -public class Metadata2HeaderFeignInterceptorTest { - - @Autowired - private MetadataLocalProperties metadataLocalProperties; - - @Autowired - private TestApplication.TestFeign testFeign; - - @Test - public void test1() { - String metadata = testFeign.test(); - Assertions.assertThat(metadata).isEqualTo("{\"a\":\"11\",\"b\":\"22\",\"c\":\"33\"}{\"LOCAL_SERVICE\":\"test" - + "\",\"LOCAL_PATH\":\"/test\",\"LOCAL_NAMESPACE\":\"default\"}"); - Assertions.assertThat(metadataLocalProperties.getContent().get("a")).isEqualTo("1"); - Assertions.assertThat(metadataLocalProperties.getContent().get("b")).isEqualTo("2"); - Assertions.assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("a")).isEqualTo("11"); - Assertions.assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("b")).isEqualTo("22"); - Assertions.assertThat(MetadataContextHolder.get().getTransitiveCustomMetadata("c")).isEqualTo("33"); - } - - @SpringBootApplication - @EnableFeignClients - @RestController - protected static class TestApplication { - - @RequestMapping("/test") - public String test(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String customMetadataStr) - throws UnsupportedEncodingException { - String systemMetadataStr = JacksonUtils.serialize2Json(MetadataContextHolder.get().getAllSystemMetadata()); - return URLDecoder.decode(customMetadataStr, "UTF-8") + systemMetadataStr; - } - - @FeignClient(name = "test-feign", url = "http://localhost:8081") - public interface TestFeign { - - @RequestMapping(value = "/test", headers = {MetadataConstant.HeaderName.CUSTOM_METADATA + "={\"a\":\"11" - + "\",\"b\":\"22\",\"c\":\"33\"}"}) - String test(); - } - - @Configuration - static class TestRequestInterceptor implements RequestInterceptor { - - @Override - public void apply(RequestTemplate template) { - template.header(MetadataConstant.HeaderName.CUSTOM_METADATA, - "{\"a\":\"11\",\"b\":\"22\",\"c\":\"33\"}"); - } - } - - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/resources/application-test.yml b/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/resources/application-test.yml deleted file mode 100644 index f15a2267..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-metadata/src/test/resources/application-test.yml +++ /dev/null @@ -1,11 +0,0 @@ -spring: - application: - name: test - cloud: - tencent: - metadata: - content: - a: 1 - b: 2 - transitive: - - b \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/extend/consul/ConsulContextProperties.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/extend/consul/ConsulContextProperties.java deleted file mode 100644 index 7142c0ad..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/extend/consul/ConsulContextProperties.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.context.extend.consul; - -import com.tencent.cloud.common.constant.ContextConstant.ModifierOrder; -import com.tencent.cloud.polaris.context.PolarisConfigModifier; -import com.tencent.polaris.api.config.plugin.DefaultPlugins; -import com.tencent.polaris.factory.config.ConfigurationImpl; -import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl; -import com.tencent.polaris.plugins.connector.common.constant.ConsulConstant.MetadataMapKey; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Map; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.util.CollectionUtils; - -/** - * Discovery configuration of Consul. - * - * @author Haotian Zhang - */ -@ConditionalOnExpression("'true'.equals('${spring.cloud.consul.enabled:true}')" - + " && 'true'.equals('${spring.cloud.consul.discovery.enabled:true}')") -@ConfigurationProperties("spring.cloud.consul") -public class ConsulContextProperties { - - /** - * Host of consul(or consul agent) - */ - private String host; - - private int port; - - private boolean enabled; - @Value("${spring.cloud.consul.discovery.register:#{'true'}}") - private boolean register; - @Value("${spring.cloud.consul.discovery.enabled:#{'true'}}") - private boolean discoveryEnabled; - @Value("${spring.cloud.consul.discovery.instance-id:}") - private String instanceId; - @Value("${spring.cloud.consul.discovery.service-name:${spring.application.name:}}") - private String serviceName; - @Value("${spring.cloud.consul.discovery.ip-address:}") - private String ipAddress; - @Value("${spring.cloud.consul.discovery.prefer-ip-address:#{'false'}}") - private boolean preferIpAddress; - - public void setHost(String host) { - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Bean - @ConditionalOnMissingBean - public ConsulConfigModifier consulConfigModifier() { - return new ConsulConfigModifier(); - } - - private static class ConsulConfigModifier implements PolarisConfigModifier { - - @Autowired(required = false) - private ConsulContextProperties consulContextProperties; - - @Override - public void modify(ConfigurationImpl configuration) { - if (consulContextProperties != null && consulContextProperties.enabled - && consulContextProperties.discoveryEnabled && consulContextProperties.register) { - if (CollectionUtils.isEmpty(configuration.getGlobal().getServerConnectors())) { - configuration.getGlobal().setServerConnectors(new ArrayList<>()); - } - configuration.getGlobal().getServerConnectors().add(configuration.getGlobal().getServerConnector()); - ServerConnectorConfigImpl serverConnectorConfig = new ServerConnectorConfigImpl(); - serverConnectorConfig.setAddresses( - Collections.singletonList(consulContextProperties.host + ":" + consulContextProperties.port)); - serverConnectorConfig.setProtocol(DefaultPlugins.SERVER_CONNECTOR_CONSUL); - Map metadata = serverConnectorConfig.getMetadata(); - if (StringUtils.isNotBlank(consulContextProperties.serviceName)) { - metadata.put(MetadataMapKey.SERVICE_NAME_KEY, consulContextProperties.serviceName); - } - if (StringUtils.isNotBlank(consulContextProperties.instanceId)) { - metadata.put(MetadataMapKey.INSTANCE_ID_KEY, consulContextProperties.instanceId); - } - if (consulContextProperties.preferIpAddress && StringUtils.isNotBlank( - consulContextProperties.ipAddress)) { - metadata.put(MetadataMapKey.PREFER_IP_ADDRESS_KEY, - String.valueOf(consulContextProperties.preferIpAddress)); - metadata.put(MetadataMapKey.IP_ADDRESS_KEY, consulContextProperties.ipAddress); - } - configuration.getGlobal().getServerConnectors().add(serverConnectorConfig); - } - } - - @Override - public int getOrder() { - return ModifierOrder.LAST; - } - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/pom.xml b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/pom.xml deleted file mode 100644 index 261bd215..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/pom.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - spring-cloud-tencent-starters - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 - - spring-cloud-tencent-polaris-gateway - Spring Cloud Tencent Polaris Gateway - - - - - com.tencent.cloud - spring-cloud-tencent-commons - - - - com.tencent.cloud - spring-cloud-tencent-metadata - - - - com.tencent.cloud - spring-cloud-starter-tencent-polaris-ratelimit - - - - - org.springframework.cloud - spring-cloud-starter-netflix-zuul - true - - - - org.springframework.cloud - spring-cloud-starter-gateway - true - - - - \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/config/PolarisGatewayAutoConfiguration.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/config/PolarisGatewayAutoConfiguration.java deleted file mode 100644 index 759e94c9..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/config/PolarisGatewayAutoConfiguration.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.gateway.config; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.http.ZuulServlet; -import com.tencent.cloud.polaris.gateway.core.route.DynamicRouteService; -import com.tencent.cloud.polaris.gateway.core.scg.filter.DynamicRouteScgFilter; -import com.tencent.cloud.polaris.gateway.core.scg.filter.Metadata2HeaderScgFilter; -import com.tencent.cloud.polaris.gateway.core.scg.filter.MetadataFirstScgFilter; -import com.tencent.cloud.polaris.gateway.core.scg.filter.RateLimitScgFilter; -import com.tencent.cloud.polaris.gateway.core.zuul.filter.Metadata2HeaderZuulFilter; -import com.tencent.cloud.polaris.gateway.core.zuul.filter.MetadataFirstZuulFilter; -import com.tencent.cloud.polaris.gateway.core.zuul.filter.RateLimitZuulFilter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.cloud.gateway.filter.GlobalFilter; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Polaris Gateway Auto Configuration - * - * @author skyehtzhang - */ -@Configuration -public class PolarisGatewayAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(ZuulServlet.class) - static class PolarisGatewayZuulAutoConfiguration { - @Bean - public ZuulFilter metadataFirstZuulFilter() { - return new MetadataFirstZuulFilter(); - } - - @Bean - public ZuulFilter rateLimitZuulFilter() { - return new RateLimitZuulFilter(); - } - @Bean - public ZuulFilter metadata2HeaderZuulFilter() { - return new Metadata2HeaderZuulFilter(); - } - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(GlobalFilter.class) - static class PolarisGatewayScgAutoConfiguration { - @Bean - public GlobalFilter metadataFirstScgFilter() { - return new MetadataFirstScgFilter(); - } - - @Bean - public GlobalFilter rateLimitScgFilter() { - return new RateLimitScgFilter(); - } - - @Bean - public GlobalFilter metadata2HeaderScgFilter() { - return new Metadata2HeaderScgFilter(); - } - - @Bean - public DynamicRouteService dynamicRouteService() { - return new DynamicRouteService(); - } - - @Bean - public DynamicRouteScgFilter dynamicRouteFilter() { - return new DynamicRouteScgFilter(); - } - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/route/DynamicRouteService.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/route/DynamicRouteService.java deleted file mode 100644 index 536ec069..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/route/DynamicRouteService.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.gateway.core.route; - -import javax.annotation.Resource; -import org.springframework.cloud.gateway.event.RefreshRoutesEvent; -import org.springframework.cloud.gateway.route.RouteDefinition; -import org.springframework.cloud.gateway.route.RouteDefinitionWriter; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; -import reactor.core.publisher.Mono; - - -/** - * dynamic route service. - * - * @author bruceppeng - */ -public class DynamicRouteService implements ApplicationEventPublisherAware { - - @Resource - private RouteDefinitionWriter routeDefinitionWriter; - - private ApplicationEventPublisher publisher; - - private void notifyChanged() { - this.publisher.publishEvent(new RefreshRoutesEvent(this)); - } - - - /** - * add route. - * @param definition definition - * @return sucess - */ - public String add(RouteDefinition definition) { - routeDefinitionWriter.save(Mono.just(definition)).subscribe(); - notifyChanged(); - return "success"; - } - - - /** - * update route. - * @param definition definition - * @return sucess - */ - public String update(RouteDefinition definition) { - try { - this.routeDefinitionWriter.delete(Mono.just(definition.getId())); - } catch (Exception e) { - return "update fail,not find route routeId: " + definition.getId(); - } - try { - routeDefinitionWriter.save(Mono.just(definition)).subscribe(); - notifyChanged(); - return "success"; - } catch (Exception e) { - return "update route fail"; - } - - - } - - /** - * delete route. - * @param id id - * @return sucess - */ - public String delete(String id) { - try { - this.routeDefinitionWriter.delete(Mono.just(id)).subscribe(); - - notifyChanged(); - return "delete success"; - } catch (Exception e) { - e.printStackTrace(); - return "delete fail"; - } - - } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { - this.publisher = applicationEventPublisher; - } - -} \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/AbstractGlobalFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/AbstractGlobalFilter.java deleted file mode 100644 index bb47812a..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/AbstractGlobalFilter.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.gateway.core.scg.filter; - -import org.springframework.cloud.gateway.filter.GatewayFilterChain; -import org.springframework.cloud.gateway.filter.GlobalFilter; -import org.springframework.core.Ordered; -import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Mono; - -/** - * Abstract Global filter for ordering and checking if shouldFilter. - * - * @author Haotian Zhang - */ -public abstract class AbstractGlobalFilter implements GlobalFilter, Ordered { - - @Override - public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { - if (shouldFilter(exchange, chain)) { - return doFilter(exchange, chain); - } else { - return chain.filter(exchange); - } - } - - @Override - abstract public int getOrder(); - - abstract public boolean shouldFilter(ServerWebExchange exchange, GatewayFilterChain chain); - - abstract public Mono doFilter(ServerWebExchange exchange, GatewayFilterChain chain); -} - diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java deleted file mode 100644 index f537d7ff..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/DynamicRouteScgFilter.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.gateway.core.scg.filter; - -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.polaris.gateway.core.route.DynamicRouteService; -import java.net.URI; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.gateway.config.GatewayProperties; -import org.springframework.cloud.gateway.filter.FilterDefinition; -import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; -import org.springframework.cloud.gateway.route.RouteDefinition; -import org.springframework.core.Ordered; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.WebFilter; -import org.springframework.web.server.WebFilterChain; -import reactor.core.publisher.Mono; - -/** - * Filter for implement dynamic route. - * - * @author kan peng - */ -public class DynamicRouteScgFilter implements WebFilter, Ordered { - - @Autowired - private DynamicRouteService dynamicRouteService; - - @Autowired - private GatewayProperties gatewayProperties; - - @Override - public int getOrder() { - return MetadataConstant.OrderConstant.FILTER_ORDER + 1; - } - - @Override - public Mono filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) { - - - ServerHttpRequest serverHttpRequest = serverWebExchange.getRequest(); - String requestPath = serverHttpRequest.getURI().getPath(); - String[] pathList = requestPath.split("/"); - String id = pathList[1]; - String path = String.format("/%s/**",id); - - //Check whether the route has been loaded - for(RouteDefinition routeDefinition: gatewayProperties.getRoutes()){ - if (id.equals(routeDefinition.getId())){ - return webFilterChain.filter(serverWebExchange); - } - } - - RouteDefinition definition = new RouteDefinition(); - definition.setId(id); - URI uri = URI.create("lb://"+id); - definition.setUri(uri); - - //Define the first assertion - PredicateDefinition predicate = new PredicateDefinition(); - predicate.setName("Path"); - - Map predicateParams = new HashMap<>(8); - predicateParams.put("pattern", path); - predicate.setArgs(predicateParams); - - //Define Filter - FilterDefinition filter = new FilterDefinition(); - filter.setName("StripPrefix"); - filter.addArg("parts","1"); - - definition.setFilters(Arrays.asList(filter)); - definition.setPredicates(Arrays.asList(predicate)); - dynamicRouteService.add(definition); - - return webFilterChain.filter(serverWebExchange); - } - -} \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/Metadata2HeaderScgFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/Metadata2HeaderScgFilter.java deleted file mode 100644 index 7ac146bc..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/Metadata2HeaderScgFilter.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.gateway.core.scg.filter; - -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.metadata.context.MetadataContext; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.cloud.metadata.util.JacksonUtils; -import org.springframework.cloud.gateway.filter.GatewayFilterChain; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.util.CollectionUtils; -import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Mono; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.Map; - -import static org.springframework.cloud.gateway.filter.LoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER; - -/** - * Scg filter used for writing metadata in HTTP request header. - * - * @author Haotian Zhang - */ -public class Metadata2HeaderScgFilter extends AbstractGlobalFilter { - - private static final int METADATA_SCG_FILTER_ORDER = LOAD_BALANCER_CLIENT_FILTER_ORDER + 1; - - @Override - public int getOrder() { - return METADATA_SCG_FILTER_ORDER; - } - - @Override - public boolean shouldFilter(ServerWebExchange exchange, GatewayFilterChain chain) { - return true; - } - - @Override - public Mono doFilter(ServerWebExchange exchange, GatewayFilterChain chain) { - // get request builder - ServerHttpRequest.Builder builder = exchange.getRequest().mutate(); - - // get metadata of current thread - MetadataContext metadataContext = exchange.getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT); - - // add new metadata and cover old - if (metadataContext == null) { - metadataContext = MetadataContextHolder.get(); - } - Map customMetadata = metadataContext.getAllTransitiveCustomMetadata(); - if (!CollectionUtils.isEmpty(customMetadata)) { - String metadataStr = JacksonUtils.serialize2Json(customMetadata); - try { - builder.header(MetadataConstant.HeaderName.CUSTOM_METADATA, URLEncoder.encode(metadataStr, "UTF-8")); - } catch (UnsupportedEncodingException e) { - builder.header(MetadataConstant.HeaderName.CUSTOM_METADATA, metadataStr); - } - } - - return chain.filter(exchange.mutate().request(builder.build()).build()); - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/MetadataFirstScgFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/MetadataFirstScgFilter.java deleted file mode 100644 index cbe8f479..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/MetadataFirstScgFilter.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - */ - -package com.tencent.cloud.polaris.gateway.core.scg.filter; - -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.metadata.context.MetadataContext; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import org.springframework.cloud.gateway.filter.GatewayFilterChain; -import org.springframework.cloud.gateway.route.Route; -import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Mono; - -import static org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter.ROUTE_TO_URL_FILTER_ORDER; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR; - -/** - * @author Haotian Zhang - */ -public class MetadataFirstScgFilter extends AbstractGlobalFilter { - - public static final int METADATA_FIRST_FILTER_ORDER = ROUTE_TO_URL_FILTER_ORDER + 1; - - @Override - public int getOrder() { - return METADATA_FIRST_FILTER_ORDER; - } - - @Override - public boolean shouldFilter(ServerWebExchange exchange, GatewayFilterChain chain) { - return true; - } - - @Override - public Mono doFilter(ServerWebExchange exchange, GatewayFilterChain chain) { - // get request context - Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR); - - // get metadata of current thread - MetadataContext metadataContext = exchange.getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT); - - // TODO 对端命名空间暂时与本地命名空间相同 - metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_NAMESPACE, - MetadataContextHolder.get().getSystemMetadata(MetadataConstant.SystemMetadataKey.LOCAL_NAMESPACE)); - metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_SERVICE, route.getId()); - metadataContext.putSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_PATH, - exchange.getRequest().getURI().getPath()); - - exchange.getAttributes().put(MetadataConstant.HeaderName.METADATA_CONTEXT, metadataContext); - - return chain.filter(exchange); - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/RateLimitScgFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/RateLimitScgFilter.java deleted file mode 100644 index b30c0cba..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/RateLimitScgFilter.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - */ - -package com.tencent.cloud.polaris.gateway.core.scg.filter; - -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.metadata.context.MetadataContext; -import com.tencent.cloud.polaris.ratelimit.utils.Consts; -import com.tencent.cloud.polaris.ratelimit.utils.QuotaCheckUtils; -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 org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.gateway.filter.GatewayFilterChain; -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Mono; - -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; - -import static com.tencent.cloud.polaris.gateway.core.scg.filter.MetadataFirstScgFilter.METADATA_FIRST_FILTER_ORDER; - -/** - * Scg filter used for writing metadata in HTTP request header. - * - * @author Haotian Zhang - */ -public class RateLimitScgFilter extends AbstractGlobalFilter { - - private static final Logger LOG = LoggerFactory.getLogger(RateLimitScgFilter.class); - - public static final int RATE_LIMIT_SCG_FILTER_ORDER = METADATA_FIRST_FILTER_ORDER + 1; - - @Autowired(required = false) - private LimitAPI limitAPI; - - @Override - public int getOrder() { - return RATE_LIMIT_SCG_FILTER_ORDER; - } - - @Override - public boolean shouldFilter(ServerWebExchange exchange, GatewayFilterChain chain) { - return limitAPI != null; - } - - @Override - public Mono doFilter(ServerWebExchange exchange, GatewayFilterChain chain) { - // get metadata of current thread - MetadataContext metadataContext = exchange.getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT); - - String peerNamespace = metadataContext.getSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_NAMESPACE); - String peerService = metadataContext.getSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_SERVICE); - String peerPath = metadataContext.getSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_PATH); - Map labels = null; - if (StringUtils.isNotBlank(peerPath)) { - labels = new HashMap<>(); - labels.put("method", peerPath); - } - - try { - QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(limitAPI, peerNamespace, peerService, 1, labels, - null); - if (quotaResponse.getCode() == QuotaResultCode.QuotaResultLimited) { - ServerHttpResponse response = exchange.getResponse(); - response.setStatusCode(HttpStatus.TOO_MANY_REQUESTS); - response.getHeaders().setContentType(MediaType.APPLICATION_JSON); - DataBuffer dataBuffer = response.bufferFactory().allocateBuffer() - .write((Consts.QUOTA_LIMITED_INFO + quotaResponse.getInfo()).getBytes(StandardCharsets.UTF_8)); - return response.writeWith(Mono.just(dataBuffer)); - } - } catch (Throwable throwable) { - //限流API调用出现异常,不应该影响业务流程的调用 - LOG.error("fail to rate limit with QuotaRequest[{}-{}-{}].", peerNamespace, peerService, peerPath, - throwable); - } - - return chain.filter(exchange); - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter/RateLimitZuulFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter/RateLimitZuulFilter.java deleted file mode 100644 index 89cf7896..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/zuul/filter/RateLimitZuulFilter.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.tencent.cloud.polaris.gateway.core.zuul.filter; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.tencent.cloud.metadata.constant.MetadataConstant; -import com.tencent.cloud.metadata.context.MetadataContextHolder; -import com.tencent.cloud.polaris.ratelimit.utils.Consts; -import com.tencent.cloud.polaris.ratelimit.utils.QuotaCheckUtils; -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 org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import java.util.HashMap; -import java.util.Map; - -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.http.HttpStatus.TOO_MANY_REQUESTS; - -/** - * Zuul filter used for rate limit. - * - * @author Haotian Zhang - */ -public class RateLimitZuulFilter extends ZuulFilter { - - private static final Logger LOG = LoggerFactory.getLogger(RateLimitZuulFilter.class); - - @Autowired(required = false) - private LimitAPI limitAPI; - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public int filterOrder() { - return RIBBON_ROUTING_FILTER_ORDER - 1; - } - - @Override - public boolean shouldFilter() { - return limitAPI != null; - } - - @Override - public Object run() { - // get request context - RequestContext requestContext = RequestContext.getCurrentContext(); - - String peerNamespace = - MetadataContextHolder.get().getSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_NAMESPACE); - String peerService = - MetadataContextHolder.get().getSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_SERVICE); - String peerPath = MetadataContextHolder.get().getSystemMetadata(MetadataConstant.SystemMetadataKey.PEER_PATH); - Map labels = null; - if (StringUtils.isNotBlank(peerPath)) { - labels = new HashMap<>(); - labels.put("method", peerPath); - } - - try { - QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(limitAPI, peerNamespace, peerService, 1, labels, - null); - if (quotaResponse.getCode() == QuotaResultCode.QuotaResultLimited) { - requestContext.setSendZuulResponse(false); - requestContext.setResponseStatusCode(TOO_MANY_REQUESTS.value()); - requestContext.getResponse().getWriter().write(Consts.QUOTA_LIMITED_INFO + quotaResponse.getInfo()); - } - } catch (Throwable throwable) { - //限流API调用出现异常,不应该影响业务流程的调用 - LOG.error("fail to rate limit with QuotaRequest[{}-{}-{}].", peerNamespace, peerService, peerPath, - throwable); - } - - return null; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/resources/META-INF/spring.factories deleted file mode 100644 index bc2e30e1..00000000 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.tencent.cloud.polaris.gateway.config.PolarisGatewayAutoConfiguration diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml new file mode 100644 index 00000000..5993108d --- /dev/null +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file