From aa536051593932e4843be82d6fb1bd711b4c0524 Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Mon, 22 Aug 2022 20:09:19 +0800 Subject: [PATCH] add router actuator endpoint. (#523) --- CHANGELOG.md | 1 + .../endpoint/PolarisConfigEndpoint.java | 1 - ...olarisConfigEndpointAutoConfiguration.java | 1 - ...int.java => PolarisDiscoveryEndpoint.java} | 19 ++- ...risDiscoveryEndpointAutoConfiguration.java | 4 +- ...java => PolarisDiscoveryEndpointTest.java} | 15 +-- .../pom.xml | 8 +- .../PolarisRateLimitRuleEndpoint.java | 24 ++-- .../PolarisRateLimitRuleEndpointTests.java | 2 +- .../pom.xml | 12 ++ .../endpoint/PolarisRouterEndpoint.java | 108 ++++++++++++++++ ...olarisRouterEndpointAutoConfiguration.java | 46 +++++++ .../main/resources/META-INF/spring.factories | 3 +- .../endpoint/PolarisRouterEndpointTest.java | 118 ++++++++++++++++++ .../discovery-callee-service/pom.xml | 85 ++++++------- .../src/main/resources/bootstrap.yml | 6 + spring-cloud-tencent-examples/pom.xml | 44 +++---- 17 files changed, 386 insertions(+), 111 deletions(-) rename spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/{PolarisDiscoveryEndPoint.java => PolarisDiscoveryEndpoint.java} (83%) rename spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/{PolarisDiscoveryEndPointTest.java => PolarisDiscoveryEndpointTest.java} (88%) create mode 100644 spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpoint.java create mode 100644 spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpointAutoConfiguration.java create mode 100644 spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpointTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index ec185458..3f07921c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,3 +18,4 @@ - [Fix typo & Code optimization](https://github.com/Tencent/spring-cloud-tencent/pull/512) - [BeanFactoryUtils returns all beans including beans defined in ancestor bean factories](https://github.com/Tencent/spring-cloud-tencent/pull/517) - [fix:add spring-cloud-starter-bootstrap dependency for example](https://github.com/Tencent/spring-cloud-tencent/pull/521) +- [Feature: Add router actuate endpoint](https://github.com/Tencent/spring-cloud-tencent/pull/523) diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpoint.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpoint.java index ead47900..e7d71f96 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpoint.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpoint.java @@ -13,7 +13,6 @@ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. - * */ package com.tencent.cloud.polaris.config.endpoint; diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointAutoConfiguration.java index 27954cce..55186e6d 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/endpoint/PolarisConfigEndpointAutoConfiguration.java @@ -13,7 +13,6 @@ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. - * */ package com.tencent.cloud.polaris.config.endpoint; diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPoint.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpoint.java similarity index 83% rename from spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPoint.java rename to spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpoint.java index 7a30ef69..6603896d 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPoint.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpoint.java @@ -39,13 +39,13 @@ import org.springframework.cloud.client.discovery.DiscoveryClient; * @author shuiqingliu */ @Endpoint(id = "polaris-discovery") -public class PolarisDiscoveryEndPoint { +public class PolarisDiscoveryEndpoint { private final PolarisDiscoveryProperties polarisDiscoveryProperties; private final DiscoveryClient polarisDiscoveryClient; private final PolarisDiscoveryHandler polarisDiscoveryHandler; - public PolarisDiscoveryEndPoint(PolarisDiscoveryProperties polarisDiscoveryProperties, + public PolarisDiscoveryEndpoint(PolarisDiscoveryProperties polarisDiscoveryProperties, DiscoveryClient polarisDiscoveryClient, PolarisDiscoveryHandler polarisDiscoveryHandler) { this.polarisDiscoveryProperties = polarisDiscoveryProperties; this.polarisDiscoveryClient = polarisDiscoveryClient; @@ -54,16 +54,16 @@ public class PolarisDiscoveryEndPoint { @ReadOperation public Map polarisDiscovery(@Selector String serviceId) { - Map polarisDisConveryInfo = new HashMap<>(); - polarisDisConveryInfo.put("PolarisDiscoveryProperties", polarisDiscoveryProperties); + Map polarisDiscoveryInfo = new HashMap<>(); + polarisDiscoveryInfo.put("PolarisDiscoveryProperties", polarisDiscoveryProperties); List serviceInstancesInfoList = new ArrayList<>(); if (StringUtils.isNotEmpty(serviceId)) { ServiceInstances serviceInstances = getServiceInstances(serviceId); serviceInstancesInfoList.add(serviceInstances); - polarisDisConveryInfo.put("ServiceInstances", serviceInstancesInfoList); - return polarisDisConveryInfo; + polarisDiscoveryInfo.put("ServiceInstances", serviceInstancesInfoList); + return polarisDiscoveryInfo; } for (String service : polarisDiscoveryClient.getServices()) { @@ -71,13 +71,12 @@ public class PolarisDiscoveryEndPoint { serviceInstancesInfoList.add(serviceInstances); } - polarisDisConveryInfo.put("ServiceInstances", serviceInstancesInfoList); - return polarisDisConveryInfo; + polarisDiscoveryInfo.put("ServiceInstances", serviceInstancesInfoList); + return polarisDiscoveryInfo; } private ServiceInstances getServiceInstances(String serviceId) { InstancesResponse instancesResponse = polarisDiscoveryHandler.getHealthyInstances(serviceId); - ServiceInstances serviceInstances = instancesResponse.toServiceInstances(); - return serviceInstances; + return instancesResponse.toServiceInstances(); } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointAutoConfiguration.java index d6b59763..d37229f3 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointAutoConfiguration.java @@ -42,8 +42,8 @@ public class PolarisDiscoveryEndpointAutoConfiguration { @Bean @ConditionalOnMissingBean @ConditionalOnAvailableEndpoint - public PolarisDiscoveryEndPoint polarisDiscoveryEndPoint(PolarisDiscoveryProperties polarisDiscoveryProperties, + public PolarisDiscoveryEndpoint polarisDiscoveryEndPoint(PolarisDiscoveryProperties polarisDiscoveryProperties, DiscoveryClient discoveryClient, PolarisDiscoveryHandler polarisDiscoveryHandler) { - return new PolarisDiscoveryEndPoint(polarisDiscoveryProperties, discoveryClient, polarisDiscoveryHandler); + return new PolarisDiscoveryEndpoint(polarisDiscoveryProperties, discoveryClient, polarisDiscoveryHandler); } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPointTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointTest.java similarity index 88% rename from spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPointTest.java rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointTest.java index 0144c8ee..9de0e709 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndPointTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/endpoint/PolarisDiscoveryEndpointTest.java @@ -14,7 +14,6 @@ * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ - package com.tencent.cloud.polaris.endpoint; import java.util.Map; @@ -45,13 +44,13 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author shuiqingliu */ -public class PolarisDiscoveryEndPointTest { +public class PolarisDiscoveryEndpointTest { private static NamingServer namingServer; private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withConfiguration(AutoConfigurations.of( - PolarisDiscoveryEndPointTest.PolarisPropertiesConfiguration.class, + PolarisPropertiesConfiguration.class, PolarisDiscoveryClientConfiguration.class, PolarisDiscoveryAutoConfiguration.class, PolarisDiscoveryEndpointAutoConfiguration.class)) @@ -76,14 +75,12 @@ public class PolarisDiscoveryEndPointTest { @Test public void testPolarisDiscoveryEndpoint() { this.contextRunner.run(context -> { - PolarisDiscoveryProperties polarisDiscoveryProperties = context - .getBean(PolarisDiscoveryProperties.class); - DiscoveryClient discoveryClient = context - .getBean(PolarisDiscoveryClient.class); + PolarisDiscoveryProperties polarisDiscoveryProperties = context.getBean(PolarisDiscoveryProperties.class); + DiscoveryClient discoveryClient = context.getBean(PolarisDiscoveryClient.class); PolarisDiscoveryHandler polarisDiscoveryHandler = context.getBean(PolarisDiscoveryHandler.class); - PolarisDiscoveryEndPoint polarisDiscoveryEndPoint = new PolarisDiscoveryEndPoint(polarisDiscoveryProperties, discoveryClient, polarisDiscoveryHandler); + PolarisDiscoveryEndpoint polarisDiscoveryEndpoint = new PolarisDiscoveryEndpoint(polarisDiscoveryProperties, discoveryClient, polarisDiscoveryHandler); - Map mapInfo = polarisDiscoveryEndPoint.polarisDiscovery("java_provider_test"); + Map mapInfo = polarisDiscoveryEndpoint.polarisDiscovery("java_provider_test"); assertThat(polarisDiscoveryProperties).isEqualTo(mapInfo.get("PolarisDiscoveryProperties")); }); diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml index 138eb41a..78cec1c4 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml +++ b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml @@ -15,10 +15,10 @@ - - com.tencent.cloud - spring-cloud-tencent-polaris-context - + + com.tencent.cloud + spring-cloud-tencent-polaris-context + diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpoint.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpoint.java index 6597ea6f..fe888ed8 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpoint.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpoint.java @@ -24,19 +24,16 @@ import java.util.Map; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; +import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.polaris.context.ServiceRuleManager; import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties; import com.tencent.polaris.client.pb.RateLimitProto; -import com.tencent.polaris.client.pb.RoutingProto; -import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; -import org.springframework.boot.actuate.endpoint.annotation.Selector; -import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; /** @@ -59,20 +56,17 @@ public class PolarisRateLimitRuleEndpoint { } @ReadOperation - public Map rateLimit( - @Selector String namespace, @Selector String service, @Nullable String dstService) { + public Map rateLimit() { + RateLimitProto.RateLimit rateLimit = serviceRuleManager.getServiceRateLimitRule(MetadataContext.LOCAL_NAMESPACE, + MetadataContext.LOCAL_SERVICE); + Map result = new HashMap<>(); - RateLimitProto.RateLimit rateLimit = serviceRuleManager.getServiceRateLimitRule(namespace, service); + result.put("properties", polarisRateLimitProperties); - result.put("namespace", namespace); - result.put("service", service); - result.put("rateLimits", parseRateLimitRule(rateLimit)); + result.put("namespace", MetadataContext.LOCAL_NAMESPACE); + result.put("service", MetadataContext.LOCAL_SERVICE); + result.put("rateLimitRules", parseRateLimitRule(rateLimit)); - if (StringUtils.isEmpty(dstService)) { - return result; - } - List routes = serviceRuleManager.getServiceRouterRule(namespace, service, dstService); - result.put("routes", routes); return result; } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointTests.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointTests.java index eda08c48..33edd0b3 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointTests.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/endpoint/PolarisRateLimitRuleEndpointTests.java @@ -97,7 +97,7 @@ public class PolarisRateLimitRuleEndpointTests { public void testPolarisRateLimit() { this.contextRunner.run(context -> polarisRateLimitProperties = context.getBean(PolarisRateLimitProperties.class)); PolarisRateLimitRuleEndpoint polarisRateLimitRuleEndpoint = new PolarisRateLimitRuleEndpoint(serviceRuleManager, polarisRateLimitProperties); - Map rateLimit = polarisRateLimitRuleEndpoint.rateLimit("namespaceTest", "TestApp2", "TestApp3"); + Map rateLimit = polarisRateLimitRuleEndpoint.rateLimit(); assertThat(polarisRateLimitProperties).isEqualTo(rateLimit.get("properties")); } diff --git a/spring-cloud-starter-tencent-polaris-router/pom.xml b/spring-cloud-starter-tencent-polaris-router/pom.xml index f8445ef6..55000050 100644 --- a/spring-cloud-starter-tencent-polaris-router/pom.xml +++ b/spring-cloud-starter-tencent-polaris-router/pom.xml @@ -70,6 +70,18 @@ + + org.springframework.boot + spring-boot-actuator + true + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + org.springframework.boot spring-boot-starter-test diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpoint.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpoint.java new file mode 100644 index 00000000..5326c808 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpoint.java @@ -0,0 +1,108 @@ +/* + * 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.endpoint; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.MessageOrBuilder; +import com.google.protobuf.util.JsonFormat; +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.polaris.client.pb.RoutingProto; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.actuate.endpoint.annotation.Selector; +import org.springframework.util.CollectionUtils; + +/** + * Router actuator endpoint. + * + * @author lepdou 2022-07-25 + */ +@Endpoint(id = "polaris-router") +public class PolarisRouterEndpoint { + private static final Logger LOGGER = LoggerFactory.getLogger(PolarisRouterEndpoint.class); + + private final ServiceRuleManager serviceRuleManager; + + public PolarisRouterEndpoint(ServiceRuleManager serviceRuleManager) { + this.serviceRuleManager = serviceRuleManager; + } + + @ReadOperation + public Map router(@Selector String dstService) { + List routerRules = serviceRuleManager.getServiceRouterRule(MetadataContext.LOCAL_NAMESPACE, + MetadataContext.LOCAL_SERVICE, dstService); + + Map result = new HashMap<>(); + + List rules = new LinkedList<>(); + result.put("routerRules", rules); + + if (CollectionUtils.isEmpty(routerRules)) { + return result; + } + + for (RoutingProto.Route route : routerRules) { + rules.add(parseRouterRule(route)); + } + + return result; + } + + private Object parseRouterRule(RoutingProto.Route routeRule) { + Map result = new HashMap<>(); + + List sourcePbs = routeRule.getSourcesList(); + List sources = new LinkedList<>(); + for (RoutingProto.Source sourcePb : sourcePbs) { + sources.add(pb2Json(sourcePb)); + } + result.put("sources", sources); + + List destPbs = routeRule.getDestinationsList(); + List destinations = new LinkedList<>(); + for (RoutingProto.Destination destPb : destPbs) { + destinations.add(pb2Json(destPb)); + } + result.put("destinations", destinations); + + return result; + } + + private Object pb2Json(MessageOrBuilder pbObject) { + String jsonStr; + try { + jsonStr = JsonFormat.printer().print(pbObject); + } + catch (InvalidProtocolBufferException e) { + String msg = "parse router rule to json error."; + LOGGER.error(msg, e); + throw new RuntimeException(msg, e); + } + return JacksonUtils.deserialize2Map(jsonStr); + } +} diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpointAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpointAutoConfiguration.java new file mode 100644 index 00000000..3cc275bf --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpointAutoConfiguration.java @@ -0,0 +1,46 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.router.endpoint; + +import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; +import com.tencent.cloud.polaris.context.ServiceRuleManager; + +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * The AutoConfiguration for polaris router endpoint. + * + * @author lepdou 2022-07-25 + **/ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Endpoint.class) +@ConditionalOnPolarisEnabled +public class PolarisRouterEndpointAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + public PolarisRouterEndpoint polarisRouterEndpoint(ServiceRuleManager serviceRuleManager) { + return new PolarisRouterEndpoint(serviceRuleManager); + } +} diff --git a/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 index 3b20deb5..75f7939c 100644 --- a/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 @@ -1,3 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.polaris.router.config.RouterAutoConfiguration,\ - com.tencent.cloud.polaris.router.config.FeignAutoConfiguration + com.tencent.cloud.polaris.router.config.FeignAutoConfiguration,\ + com.tencent.cloud.polaris.router.endpoint.PolarisRouterEndpointAutoConfiguration diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpointTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpointTest.java new file mode 100644 index 00000000..e400013c --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/endpoint/PolarisRouterEndpointTest.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.router.endpoint; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import com.google.common.collect.Lists; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.polaris.context.ServiceRuleManager; +import com.tencent.polaris.client.pb.ModelProto; +import com.tencent.polaris.client.pb.RoutingProto; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +/** + * Test for {@link PolarisRouterEndpoint}. + * + * @author lepdou 2022-07-25 + */ +@RunWith(MockitoJUnitRunner.class) +public class PolarisRouterEndpointTest { + + private static final String testDestService = "dstService"; + private static MockedStatic mockedApplicationContextAwareUtils; + + @Mock + private ServiceRuleManager serviceRuleManager; + @InjectMocks + private PolarisRouterEndpoint polarisRouterEndpoint; + + @BeforeClass + public static void beforeClass() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn(testDestService); + } + + @AfterClass + public static void afterClass() { + mockedApplicationContextAwareUtils.close(); + } + + @Test + public void testHasRouterRule() { + Map labels = new HashMap<>(); + ModelProto.MatchString matchString = ModelProto.MatchString.getDefaultInstance(); + String validKey1 = "${http.header.uid}"; + String validKey2 = "${http.query.name}"; + String validKey3 = "${http.method}"; + String validKey4 = "${http.uri}"; + String validKey5 = "${http.body.customkey}"; + String invalidKey = "$http.expression.wrong}"; + labels.put(validKey1, matchString); + labels.put(validKey2, matchString); + labels.put(validKey3, matchString); + labels.put(validKey4, matchString); + labels.put(validKey5, matchString); + labels.put(invalidKey, matchString); + + RoutingProto.Source source1 = RoutingProto.Source.newBuilder().putAllMetadata(labels).build(); + RoutingProto.Source source2 = RoutingProto.Source.newBuilder().putAllMetadata(labels).build(); + RoutingProto.Source source3 = RoutingProto.Source.newBuilder().putAllMetadata(new HashMap<>()).build(); + + List routes = new LinkedList<>(); + RoutingProto.Route route = RoutingProto.Route.newBuilder() + .addAllSources(Lists.newArrayList(source1, source2, source3)) + .build(); + routes.add(route); + + when(serviceRuleManager.getServiceRouterRule(testDestService, testDestService, testDestService)).thenReturn(routes); + + Map actuator = polarisRouterEndpoint.router(testDestService); + + Assert.assertNotNull(actuator.get("routerRules")); + Assert.assertEquals(1, ((List) actuator.get("routerRules")).size()); + } + + @Test + public void testHasNotRouterRule() { + List routes = new LinkedList<>(); + + when(serviceRuleManager.getServiceRouterRule(testDestService, testDestService, testDestService)).thenReturn(routes); + + Map actuator = polarisRouterEndpoint.router(testDestService); + + Assert.assertNotNull(actuator.get("routerRules")); + Assert.assertEquals(0, ((List) actuator.get("routerRules")).size()); + } +} 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 78bc477d..e93408d1 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,19 +1,19 @@ - - polaris-discovery-example - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 + 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"> + + polaris-discovery-example + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 - discovery-callee-service - Polaris Discovery Callee Service + discovery-callee-service + Polaris Discovery Callee Service - + com.tencent.cloud spring-cloud-starter-tencent-polaris-discovery @@ -28,38 +28,33 @@ - - - org.springframework.cloud - spring-cloud-starter-bootstrap - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.2.0 - - - attach-sources - - jar - - - - - - + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.0 + + + attach-sources + + jar + + + + + + diff --git a/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/resources/bootstrap.yml index e8f79333..7a53c2f0 100644 --- a/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/resources/bootstrap.yml @@ -14,3 +14,9 @@ spring: enabled: true loadbalancer: enabled: true +management: + endpoints: + web: + exposure: + include: + - polaris-router diff --git a/spring-cloud-tencent-examples/pom.xml b/spring-cloud-tencent-examples/pom.xml index 8419d244..ab0b95cc 100644 --- a/spring-cloud-tencent-examples/pom.xml +++ b/spring-cloud-tencent-examples/pom.xml @@ -1,25 +1,25 @@ - - spring-cloud-tencent - com.tencent.cloud - ${revision} - ../pom.xml - - 4.0.0 + 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-examples - pom - Spring Cloud Tencent Examples - Examples of Spring Cloud Tencent + spring-cloud-tencent-examples + pom + Spring Cloud Tencent Examples + Examples of Spring Cloud Tencent - - polaris-discovery-example - polaris-ratelimit-example - polaris-circuitbreaker-example - polaris-gateway-example + + polaris-discovery-example + polaris-ratelimit-example + polaris-circuitbreaker-example + polaris-gateway-example polaris-config-example polaris-router-example metadata-transfer-example @@ -27,16 +27,16 @@ polaris-config-data-example - - true - + + true + org.owasp.esapi esapi - 2.1.0.1 + 2.5.0.0