diff --git a/CHANGELOG.md b/CHANGELOG.md index 24a724e04..371cb3d58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,3 +15,4 @@ - [Feature: delete implement ServiceInstance](https://github.com/Tencent/spring-cloud-tencent/pull/482) - [Bugfix: update byte-buddy scope test to compile](https://github.com/Tencent/spring-cloud-tencent/pull/497) - [Fix the code analysis error.](https://github.com/Tencent/spring-cloud-tencent/pull/499) +- [Optimize router label resolver spi](https://github.com/Tencent/spring-cloud-tencent/pull/503) diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignAutoConfiguration.java index 107ea5e8e..81b720369 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/FeignAutoConfiguration.java @@ -23,7 +23,7 @@ import java.util.List; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.feign.RouterLabelFeignInterceptor; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.FeignRouterLabelResolver; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Bean; @@ -35,7 +35,7 @@ import org.springframework.lang.Nullable; public class FeignAutoConfiguration { @Bean - public RouterLabelFeignInterceptor routerLabelInterceptor(@Nullable List routerLabelResolvers, + public RouterLabelFeignInterceptor routerLabelInterceptor(@Nullable List routerLabelResolvers, MetadataLocalProperties metadataLocalProperties, RouterRuleLabelResolver routerRuleLabelResolver) { return new RouterLabelFeignInterceptor(routerLabelResolvers, metadataLocalProperties, routerRuleLabelResolver); diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java index abcd83d1f..2fd2a856d 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java @@ -33,7 +33,7 @@ import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.polaris.router.RouterConstants; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.FeignRouterLabelResolver; import feign.RequestInterceptor; import feign.RequestTemplate; import org.slf4j.Logger; @@ -52,11 +52,11 @@ import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered { private static final Logger LOGGER = LoggerFactory.getLogger(RouterLabelFeignInterceptor.class); - private final List routerLabelResolvers; + private final List routerLabelResolvers; private final MetadataLocalProperties metadataLocalProperties; private final RouterRuleLabelResolver routerRuleLabelResolver; - public RouterLabelFeignInterceptor(List routerLabelResolvers, + public RouterLabelFeignInterceptor(List routerLabelResolvers, MetadataLocalProperties metadataLocalProperties, RouterRuleLabelResolver routerRuleLabelResolver) { if (!CollectionUtils.isEmpty(routerLabelResolvers)) { @@ -82,14 +82,17 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered // labels from rule expression String peerServiceName = requestTemplate.feignTarget().name(); - Map ruleExpressionLabels = getRuleExpressionLabels(requestTemplate, peerServiceName); + Set expressionLabelKeys = routerRuleLabelResolver.getExpressionLabelKeys(MetadataContext.LOCAL_NAMESPACE, + MetadataContext.LOCAL_SERVICE, peerServiceName); + + Map ruleExpressionLabels = getRuleExpressionLabels(requestTemplate, expressionLabelKeys); labels.putAll(ruleExpressionLabels); - // labels from request + // labels from custom spi if (!CollectionUtils.isEmpty(routerLabelResolvers)) { routerLabelResolvers.forEach(resolver -> { try { - Map customResolvedLabels = resolver.resolve(requestTemplate); + Map customResolvedLabels = resolver.resolve(requestTemplate, expressionLabelKeys); if (!CollectionUtils.isEmpty(customResolvedLabels)) { labels.putAll(customResolvedLabels); } @@ -121,10 +124,7 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered requestTemplate.header(RouterConstants.ROUTER_LABEL_HEADER, encodedLabelsContent); } - private Map getRuleExpressionLabels(RequestTemplate requestTemplate, String peerService) { - Set labelKeys = routerRuleLabelResolver.getExpressionLabelKeys(MetadataContext.LOCAL_NAMESPACE, - MetadataContext.LOCAL_SERVICE, peerService); - + private Map getRuleExpressionLabels(RequestTemplate requestTemplate, Set labelKeys) { if (CollectionUtils.isEmpty(labelKeys)) { return Collections.emptyMap(); } diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessor.java index 5bafbd9fb..5bfe21415 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessor.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessor.java @@ -23,7 +23,7 @@ import java.util.List; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.BeanFactoryUtils; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; @@ -53,7 +53,7 @@ public class PolarisLoadBalancerBeanPostProcessor implements BeanPostProcessor, if (bean instanceof LoadBalancerInterceptor) { LoadBalancerRequestFactory requestFactory = this.factory.getBean(LoadBalancerRequestFactory.class); LoadBalancerClient loadBalancerClient = this.factory.getBean(LoadBalancerClient.class); - List routerLabelResolvers = BeanFactoryUtils.getBeans(factory, RouterLabelResolver.class); + List routerLabelResolvers = BeanFactoryUtils.getBeans(factory, SpringWebRouterLabelResolver.class); MetadataLocalProperties metadataLocalProperties = this.factory.getBean(MetadataLocalProperties.class); RouterRuleLabelResolver routerRuleLabelResolver = this.factory.getBean(RouterRuleLabelResolver.class); diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java index a0155315c..275c1a712 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptor.java @@ -36,7 +36,7 @@ import com.tencent.cloud.common.util.ExpressionLabelUtils; import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.polaris.router.RouterConstants; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,13 +63,13 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor { private final LoadBalancerClient loadBalancer; private final LoadBalancerRequestFactory requestFactory; - private final List routerLabelResolvers; + private final List routerLabelResolvers; private final MetadataLocalProperties metadataLocalProperties; private final RouterRuleLabelResolver routerRuleLabelResolver; public PolarisLoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory, - List routerLabelResolvers, + List routerLabelResolvers, MetadataLocalProperties metadataLocalProperties, RouterRuleLabelResolver routerRuleLabelResolver) { super(loadBalancer, requestFactory); @@ -105,7 +105,10 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor { Map labels = new HashMap<>(metadataLocalProperties.getContent()); // labels from rule expression - Map ruleExpressionLabels = getExpressionLabels(request, peerServiceName); + Set expressionLabelKeys = routerRuleLabelResolver.getExpressionLabelKeys(MetadataContext.LOCAL_NAMESPACE, + MetadataContext.LOCAL_SERVICE, peerServiceName); + + Map ruleExpressionLabels = getExpressionLabels(request, expressionLabelKeys); if (!CollectionUtils.isEmpty(ruleExpressionLabels)) { labels.putAll(ruleExpressionLabels); } @@ -114,7 +117,7 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor { if (!CollectionUtils.isEmpty(routerLabelResolvers)) { routerLabelResolvers.forEach(resolver -> { try { - Map customResolvedLabels = resolver.resolve(request, body); + Map customResolvedLabels = resolver.resolve(request, body, expressionLabelKeys); if (!CollectionUtils.isEmpty(customResolvedLabels)) { labels.putAll(customResolvedLabels); } @@ -145,10 +148,7 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor { request.getHeaders().set(RouterConstants.ROUTER_LABEL_HEADER, encodedLabelsContent); } - private Map getExpressionLabels(HttpRequest request, String peerServiceName) { - Set labelKeys = routerRuleLabelResolver.getExpressionLabelKeys(MetadataContext.LOCAL_NAMESPACE, - MetadataContext.LOCAL_SERVICE, peerServiceName); - + private Map getExpressionLabels(HttpRequest request, Set labelKeys) { if (CollectionUtils.isEmpty(labelKeys)) { return Collections.emptyMap(); } diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessor.java index 06d3fad8c..f080d2aa3 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessor.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessor.java @@ -23,7 +23,7 @@ import java.util.List; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.BeanFactoryUtils; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; @@ -56,7 +56,7 @@ public class PolarisLoadBalancerClientBeanPostProcessor implements BeanPostProce LoadBalancerClientFactory loadBalancerClientFactory = this.factory.getBean(LoadBalancerClientFactory.class); GatewayLoadBalancerProperties gatewayLoadBalancerProperties = this.factory.getBean(GatewayLoadBalancerProperties.class); LoadBalancerProperties loadBalancerProperties = this.factory.getBean(LoadBalancerProperties.class); - List routerLabelResolvers = BeanFactoryUtils.getBeans(factory, RouterLabelResolver.class); + List routerLabelResolvers = BeanFactoryUtils.getBeans(factory, SpringWebRouterLabelResolver.class); MetadataLocalProperties metadataLocalProperties = this.factory.getBean(MetadataLocalProperties.class); RouterRuleLabelResolver routerRuleLabelResolver = this.factory.getBean(RouterRuleLabelResolver.class); diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilter.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilter.java index 60f27ccfd..22add0264 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilter.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilter.java @@ -35,7 +35,7 @@ import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.polaris.router.PolarisRouterServiceInstanceListSupplier; import com.tencent.cloud.polaris.router.RouterConstants; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.core.publisher.Mono; @@ -86,14 +86,14 @@ public class PolarisReactiveLoadBalancerClientFilter extends ReactiveLoadBalance private final LoadBalancerProperties loadBalancerProperties; private final MetadataLocalProperties metadataLocalProperties; private final RouterRuleLabelResolver routerRuleLabelResolver; - private final List routerLabelResolvers; + private final List routerLabelResolvers; public PolarisReactiveLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory, GatewayLoadBalancerProperties gatewayLoadBalancerProperties, LoadBalancerProperties loadBalancerProperties, MetadataLocalProperties metadataLocalProperties, RouterRuleLabelResolver routerRuleLabelResolver, - List routerLabelResolvers) { + List routerLabelResolvers) { super(clientFactory, gatewayLoadBalancerProperties, loadBalancerProperties); this.clientFactory = clientFactory; @@ -226,7 +226,10 @@ public class PolarisReactiveLoadBalancerClientFilter extends ReactiveLoadBalance Map labels = new HashMap<>(metadataLocalProperties.getContent()); // labels from rule expression - Map ruleExpressionLabels = getExpressionLabels(exchange, peerServiceName); + Set expressionLabelKeys = routerRuleLabelResolver.getExpressionLabelKeys(MetadataContext.LOCAL_NAMESPACE, + MetadataContext.LOCAL_SERVICE, peerServiceName); + + Map ruleExpressionLabels = getExpressionLabels(exchange, expressionLabelKeys); if (!CollectionUtils.isEmpty(ruleExpressionLabels)) { labels.putAll(ruleExpressionLabels); } @@ -235,7 +238,7 @@ public class PolarisReactiveLoadBalancerClientFilter extends ReactiveLoadBalance if (!CollectionUtils.isEmpty(routerLabelResolvers)) { routerLabelResolvers.forEach(resolver -> { try { - Map customResolvedLabels = resolver.resolve(exchange); + Map customResolvedLabels = resolver.resolve(exchange, expressionLabelKeys); if (!CollectionUtils.isEmpty(customResolvedLabels)) { labels.putAll(customResolvedLabels); } @@ -254,10 +257,7 @@ public class PolarisReactiveLoadBalancerClientFilter extends ReactiveLoadBalance return labels; } - private Map getExpressionLabels(ServerWebExchange exchange, String peerServiceName) { - Set labelKeys = routerRuleLabelResolver.getExpressionLabelKeys(MetadataContext.LOCAL_NAMESPACE, - MetadataContext.LOCAL_SERVICE, peerServiceName); - + private Map getExpressionLabels(ServerWebExchange exchange, Set labelKeys) { if (CollectionUtils.isEmpty(labelKeys)) { return Collections.emptyMap(); } diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/FeignRouterLabelResolver.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/FeignRouterLabelResolver.java new file mode 100644 index 000000000..6ff5c9c56 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/FeignRouterLabelResolver.java @@ -0,0 +1,42 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.router.spi; + +import java.util.Map; +import java.util.Set; + +import feign.RequestTemplate; + +import org.springframework.core.Ordered; + +/** + * Router label resolver for feign request. + * @author lepdou 2022-07-20 + */ +public interface FeignRouterLabelResolver extends Ordered { + + /** + * Resolve labels from feign request. User can customize expression parser to extract labels. + * + * @param requestTemplate the feign request. + * @param expressionLabelKeys the expression labels which are configured in router rule. + * @return resolved labels + */ + Map resolve(RequestTemplate requestTemplate, Set expressionLabelKeys); +} diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/RouterLabelResolver.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/SpringWebRouterLabelResolver.java similarity index 65% rename from spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/RouterLabelResolver.java rename to spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/SpringWebRouterLabelResolver.java index d885581ca..55db8498b 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/RouterLabelResolver.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/spi/SpringWebRouterLabelResolver.java @@ -13,52 +13,45 @@ * 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.spi; import java.util.Collections; import java.util.Map; - -import feign.RequestTemplate; +import java.util.Set; import org.springframework.core.Ordered; import org.springframework.http.HttpRequest; import org.springframework.web.server.ServerWebExchange; /** - * The spi for resolving labels from request. - * - * @author lepdou 2022-05-11 + * Router label resolver for spring web http request. + * @author lepdou 2022-07-20 */ -public interface RouterLabelResolver extends Ordered { - - /** - * resolve labels from feign request. - * @param requestTemplate the feign request. - * @return resolved labels - */ - default Map resolve(RequestTemplate requestTemplate) { - return Collections.emptyMap(); - } +public interface SpringWebRouterLabelResolver extends Ordered { /** - * resolve labels from rest template request. + * resolve labels from rest template request. User can customize expression parser to extract labels. + * * @param request the rest template request. * @param body the rest template request body. + * @param expressionLabelKeys the expression labels which are configured in router rule. * @return resolved labels */ - default Map resolve(HttpRequest request, byte[] body) { + default Map resolve(HttpRequest request, byte[] body, Set expressionLabelKeys) { return Collections.emptyMap(); } + /** - * resolve labels from server web exchange. + * resolve labels from server web exchange. User can customize expression parser to extract labels. + * * @param exchange the server web exchange. + * @param expressionLabelKeys the expression labels which are configured in router rule. * @return resolved labels */ - default Map resolve(ServerWebExchange exchange) { + default Map resolve(ServerWebExchange exchange, Set expressionLabelKeys) { return Collections.emptyMap(); } } diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java index a910473ac..e16785c5c 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/RouterRuleLabelResolverTest.java @@ -59,11 +59,13 @@ public class RouterRuleLabelResolverTest { String validKey2 = "${http.query.name}"; String validKey3 = "${http.method}"; String validKey4 = "${http.uri}"; - String invalidKey = "${http.expression.wrong}"; + 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(); @@ -83,11 +85,12 @@ public class RouterRuleLabelResolverTest { Set resolvedExpressionLabelKeys = resolver.getExpressionLabelKeys(testNamespace, testSourceService, testDstService); Assert.assertNotNull(resolvedExpressionLabelKeys); - Assert.assertEquals(4, resolvedExpressionLabelKeys.size()); + Assert.assertEquals(5, resolvedExpressionLabelKeys.size()); Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey1)); Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey2)); Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey3)); Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey4)); + Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey5)); Assert.assertFalse(resolvedExpressionLabelKeys.contains(invalidKey)); } } diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java index c0aecea28..01824e50d 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptorTest.java @@ -34,7 +34,7 @@ import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.polaris.router.RouterConstants; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.FeignRouterLabelResolver; import feign.RequestTemplate; import feign.Target; import org.junit.Assert; @@ -62,7 +62,7 @@ public class RouterLabelFeignInterceptorTest { @Mock private RouterRuleLabelResolver routerRuleLabelResolver; @Mock - private RouterLabelResolver routerLabelResolver; + private FeignRouterLabelResolver routerLabelResolver; @Test public void testResolveRouterLabel() { @@ -97,12 +97,6 @@ public class RouterLabelFeignInterceptorTest { try (MockedStatic mockedMetadataContextHolder = Mockito.mockStatic(MetadataContextHolder.class)) { mockedMetadataContextHolder.when(MetadataContextHolder::get).thenReturn(metadataContext); - // mock custom resolved labels from request - Map customResolvedLabels = new HashMap<>(); - customResolvedLabels.put("k2", "v2"); - customResolvedLabels.put("k3", "v3"); - when(routerLabelResolver.resolve(requestTemplate)).thenReturn(customResolvedLabels); - // mock expression rule labels Set expressionKeys = new HashSet<>(); expressionKeys.add("${http.header.uid}"); @@ -110,7 +104,12 @@ public class RouterLabelFeignInterceptorTest { when(routerRuleLabelResolver.getExpressionLabelKeys(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE, peerService)).thenReturn(expressionKeys); - // mock local metadata + // mock custom resolved labels from request + Map customResolvedLabels = new HashMap<>(); + customResolvedLabels.put("k2", "v2"); + customResolvedLabels.put("k3", "v3"); + when(routerLabelResolver.resolve(requestTemplate, expressionKeys)).thenReturn(customResolvedLabels); + Map localMetadata = new HashMap<>(); localMetadata.put("k3", "v31"); localMetadata.put("k4", "v4"); diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java index 14f61d6c7..f173b67c8 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerBeanPostProcessorTest.java @@ -21,7 +21,7 @@ package com.tencent.cloud.polaris.router.resttemplate; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.BeanFactoryUtils; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -64,7 +64,7 @@ public class PolarisLoadBalancerBeanPostProcessorTest { when(beanFactory.getBean(RouterRuleLabelResolver.class)).thenReturn(routerRuleLabelResolver); try (MockedStatic mockedBeanFactoryUtils = Mockito.mockStatic(BeanFactoryUtils.class)) { - mockedBeanFactoryUtils.when(() -> BeanFactoryUtils.getBeans(beanFactory, RouterLabelResolver.class)) + mockedBeanFactoryUtils.when(() -> BeanFactoryUtils.getBeans(beanFactory, SpringWebRouterLabelResolver.class)) .thenReturn(null); LoadBalancerInterceptor loadBalancerInterceptor = new LoadBalancerInterceptor(loadBalancerClient, loadBalancerRequestFactory); diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java index 914240a12..78a9440e1 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java @@ -33,7 +33,7 @@ import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.polaris.router.RouterConstants; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -73,7 +73,7 @@ public class PolarisLoadBalancerInterceptorTest { @Mock private LoadBalancerRequestFactory loadBalancerRequestFactory; @Mock - private RouterLabelResolver routerLabelResolver; + private SpringWebRouterLabelResolver routerLabelResolver; @Mock private MetadataLocalProperties metadataLocalProperties; @Mock @@ -106,12 +106,6 @@ public class PolarisLoadBalancerInterceptorTest { localMetadata.put("k2", "v2"); when(metadataLocalProperties.getContent()).thenReturn(localMetadata); - // mock custom resolved from request - Map customResolvedLabels = new HashMap<>(); - customResolvedLabels.put("k3", "v3"); - customResolvedLabels.put("k4", "v4"); - when(routerLabelResolver.resolve(request, null)).thenReturn(customResolvedLabels); - // mock expression rule labels Set expressionKeys = new HashSet<>(); @@ -119,6 +113,12 @@ public class PolarisLoadBalancerInterceptorTest { expressionKeys.add("${http.uri}"); when(routerRuleLabelResolver.getExpressionLabelKeys(callerService, callerService, calleeService)).thenReturn(expressionKeys); + // mock custom resolved from request + Map customResolvedLabels = new HashMap<>(); + customResolvedLabels.put("k3", "v3"); + customResolvedLabels.put("k4", "v4"); + when(routerLabelResolver.resolve(request, null, expressionKeys)).thenReturn(customResolvedLabels); + MetadataContext metadataContext = Mockito.mock(MetadataContext.class); // mock transitive metadata @@ -139,7 +139,7 @@ public class PolarisLoadBalancerInterceptorTest { verify(metadataLocalProperties).getContent(); verify(routerRuleLabelResolver).getExpressionLabelKeys(callerService, callerService, calleeService); - verify(routerLabelResolver).resolve(request, null); + verify(routerLabelResolver).resolve(request, null, expressionKeys); } @Test @@ -154,12 +154,6 @@ public class PolarisLoadBalancerInterceptorTest { localMetadata.put("k2", "v2"); when(metadataLocalProperties.getContent()).thenReturn(localMetadata); - // mock custom resolved from request - Map customResolvedLabels = new HashMap<>(); - customResolvedLabels.put("k2", "v22"); - customResolvedLabels.put("k4", "v4"); - when(routerLabelResolver.resolve(request, null)).thenReturn(customResolvedLabels); - // mock expression rule labels Set expressionKeys = new HashSet<>(); @@ -167,6 +161,12 @@ public class PolarisLoadBalancerInterceptorTest { expressionKeys.add("${http.uri}"); when(routerRuleLabelResolver.getExpressionLabelKeys(callerService, callerService, calleeService)).thenReturn(expressionKeys); + // mock custom resolved from request + Map customResolvedLabels = new HashMap<>(); + customResolvedLabels.put("k2", "v22"); + customResolvedLabels.put("k4", "v4"); + when(routerLabelResolver.resolve(request, null, expressionKeys)).thenReturn(customResolvedLabels); + MetadataContext metadataContext = Mockito.mock(MetadataContext.class); // mock transitive metadata @@ -184,7 +184,7 @@ public class PolarisLoadBalancerInterceptorTest { verify(metadataLocalProperties).getContent(); verify(routerRuleLabelResolver).getExpressionLabelKeys(callerService, callerService, calleeService); - verify(routerLabelResolver).resolve(request, null); + verify(routerLabelResolver).resolve(request, null, expressionKeys); Map headers = JacksonUtils.deserialize2Map(URLDecoder.decode(request.getHeaders() .get(RouterConstants.ROUTER_LABEL_HEADER).get(0), UTF_8)); diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessorTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessorTest.java index 5633d72df..e354ab235 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessorTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisLoadBalancerClientBeanPostProcessorTest.java @@ -21,7 +21,7 @@ package com.tencent.cloud.polaris.router.scg; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.BeanFactoryUtils; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -69,7 +69,7 @@ public class PolarisLoadBalancerClientBeanPostProcessorTest { when(beanFactory.getBean(RouterRuleLabelResolver.class)).thenReturn(routerRuleLabelResolver); try (MockedStatic mockedBeanFactoryUtils = Mockito.mockStatic(BeanFactoryUtils.class)) { - mockedBeanFactoryUtils.when(() -> BeanFactoryUtils.getBeans(beanFactory, RouterLabelResolver.class)) + mockedBeanFactoryUtils.when(() -> BeanFactoryUtils.getBeans(beanFactory, SpringWebRouterLabelResolver.class)) .thenReturn(null); ReactiveLoadBalancerClientFilter reactiveLoadBalancerClientFilter = new ReactiveLoadBalancerClientFilter( diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilterTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilterTest.java index b1d29b1cd..81d8150f3 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilterTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilterTest.java @@ -34,7 +34,7 @@ import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.polaris.router.RouterConstants; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -73,7 +73,7 @@ public class PolarisReactiveLoadBalancerClientFilterTest { @Mock private MetadataLocalProperties metadataLocalProperties; @Mock - private RouterLabelResolver routerLabelResolver; + private SpringWebRouterLabelResolver routerLabelResolver; @Mock private RouterRuleLabelResolver routerRuleLabelResolver; @Mock @@ -128,7 +128,7 @@ public class PolarisReactiveLoadBalancerClientFilterTest { Map customMetadata = new HashMap<>(); customMetadata.put("k2", "v2"); - when(routerLabelResolver.resolve(webExchange)).thenReturn(customMetadata); + when(routerLabelResolver.resolve(webExchange, expressionLabelKeys)).thenReturn(customMetadata); HttpHeaders headers = filter.genRouterHttpHeaders(webExchange, calleeService); diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java index 4c10b6ab9..93cd9a1f7 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ExpressionLabelUtils.java @@ -43,6 +43,10 @@ import org.springframework.web.server.ServerWebExchange; * @author lepdou, cheese8 */ public final class ExpressionLabelUtils { + /** + * the prefix of expression. + */ + public static final String LABEL_PREFIX = "${"; /** * the expression prefix of header label. */ @@ -86,14 +90,7 @@ public final class ExpressionLabelUtils { if (StringUtils.isEmpty(labelKey)) { return false; } - if (StringUtils.equalsIgnoreCase(LABEL_METHOD, labelKey) || - StringUtils.startsWithIgnoreCase(LABEL_URI, labelKey)) { - return true; - } - return (StringUtils.startsWithIgnoreCase(labelKey, LABEL_HEADER_PREFIX) || - StringUtils.startsWithIgnoreCase(labelKey, LABEL_QUERY_PREFIX) || - StringUtils.startsWithIgnoreCase(labelKey, LABEL_COOKIE_PREFIX)) - && StringUtils.endsWith(labelKey, LABEL_SUFFIX); + return StringUtils.startsWith(labelKey, LABEL_PREFIX) && StringUtils.endsWith(labelKey, LABEL_SUFFIX); } public static Map resolve(HttpServletRequest request, Set labelKeys) { diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java index cc1eda27d..e0410e5ec 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/ExpressionLabelUtilsTest.java @@ -66,12 +66,12 @@ public class ExpressionLabelUtilsTest { Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(validLabel3)); Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(validLabel4)); Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(validLabel5)); - Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel1)); + Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel1)); Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel2)); Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel3)); Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel4)); - Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel5)); - Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel6)); + Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel5)); + Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel6)); Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel7)); Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel8)); Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel9)); diff --git a/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/java/com/tencent/cloud/polaris/router/example/CustomRouterLabelResolver.java b/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/java/com/tencent/cloud/polaris/router/example/CustomRouterLabelResolver.java index bd289abb9..be9b010ea 100644 --- a/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/java/com/tencent/cloud/polaris/router/example/CustomRouterLabelResolver.java +++ b/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/java/com/tencent/cloud/polaris/router/example/CustomRouterLabelResolver.java @@ -20,12 +20,12 @@ package com.tencent.cloud.polaris.router.example; import java.util.HashMap; import java.util.Map; +import java.util.Set; import com.google.gson.Gson; -import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; +import com.tencent.cloud.polaris.router.spi.FeignRouterLabelResolver; import feign.RequestTemplate; -import org.springframework.http.HttpRequest; import org.springframework.stereotype.Component; /** @@ -35,11 +35,11 @@ import org.springframework.stereotype.Component; *@author lepdou 2022-05-12 */ @Component -public class CustomRouterLabelResolver implements RouterLabelResolver { +public class CustomRouterLabelResolver implements FeignRouterLabelResolver { private final Gson gson = new Gson(); @Override - public Map resolve(RequestTemplate requestTemplate) { + public Map resolve(RequestTemplate requestTemplate, Set expressionLabelKeys) { Map labels = new HashMap<>(); User user = gson.fromJson(new String(requestTemplate.body()), User.class); @@ -49,15 +49,6 @@ public class CustomRouterLabelResolver implements RouterLabelResolver { return labels; } - @Override - public Map resolve(HttpRequest request, byte[] body) { - Map labels = new HashMap<>(); - User user = gson.fromJson(new String(body), User.class); - - labels.put("user", user.getName()); - return labels; - } - @Override public int getOrder() { return 0; diff --git a/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/java/com/tencent/cloud/polaris/router/example/CustomSpringWebRouterLabelResolver.java b/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/java/com/tencent/cloud/polaris/router/example/CustomSpringWebRouterLabelResolver.java new file mode 100644 index 000000000..44570366d --- /dev/null +++ b/spring-cloud-tencent-examples/polaris-router-example/router-caller-service/src/main/java/com/tencent/cloud/polaris/router/example/CustomSpringWebRouterLabelResolver.java @@ -0,0 +1,52 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.router.example; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import com.google.gson.Gson; +import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; + +import org.springframework.http.HttpRequest; +import org.springframework.stereotype.Component; + +/** + * Custom router label resolver for spring web request. + * @author lepdou 2022-07-20 + */ +@Component +public class CustomSpringWebRouterLabelResolver implements SpringWebRouterLabelResolver { + private final Gson gson = new Gson(); + + @Override + public int getOrder() { + return 0; + } + + @Override + public Map resolve(HttpRequest request, byte[] body, Set expressionLabelKeys) { + Map labels = new HashMap<>(); + User user = gson.fromJson(new String(body), User.class); + + labels.put("user", user.getName()); + return labels; + } + +}