diff --git a/CHANGELOG.md b/CHANGELOG.md index c8ef2712..768892d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,4 +19,5 @@ - [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) -- [Code optimization for rpc-enhancement module](https://github.com/Tencent/spring-cloud-tencent/pull/526) +- [Optimize router label resolver spi](https://github.com/Tencent/spring-cloud-tencent/pull/524) +- [Code optimization for rpc-enhancement module](https://github.com/Tencent/spring-cloud-tencent/pull/526) \ No newline at end of file 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 fe77ec3e..36f1da74 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; @@ -39,7 +39,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 cba84518..613369bd 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; @@ -50,11 +50,11 @@ import org.springframework.util.CollectionUtils; 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)) { @@ -80,14 +80,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); } @@ -118,10 +121,7 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered } } - 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 5bafbd9f..5bfe2141 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 b5040ca9..cf5215ad 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; @@ -61,13 +61,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); @@ -103,7 +103,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); } @@ -112,7 +115,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); } @@ -143,10 +146,7 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor { } } - 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 ca45878d..8b80c245 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; @@ -55,7 +55,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 24bfba30..dd4d4103 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 @@ -34,7 +34,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; import reactor.core.publisher.Mono; @@ -83,14 +83,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; @@ -223,7 +223,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); } @@ -232,7 +235,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); } @@ -251,10 +254,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 00000000..6ff5c9c5 --- /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 d885581c..55db8498 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 26c1dfb1..f7c32a0b 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 d5f7f97e..e3e0d55c 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; @@ -60,7 +60,7 @@ public class RouterLabelFeignInterceptorTest { @Mock private RouterRuleLabelResolver routerRuleLabelResolver; @Mock - private RouterLabelResolver routerLabelResolver; + private FeignRouterLabelResolver routerLabelResolver; @Test public void testResolveRouterLabel() throws UnsupportedEncodingException { @@ -95,12 +95,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}"); @@ -108,7 +102,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 e335e83f..a83db5b7 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; @@ -63,7 +63,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 e80dfaed..8f8a67dd 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 @@ -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; @@ -72,7 +72,7 @@ public class PolarisLoadBalancerInterceptorTest { @Mock private LoadBalancerRequestFactory loadBalancerRequestFactory; @Mock - private RouterLabelResolver routerLabelResolver; + private SpringWebRouterLabelResolver routerLabelResolver; @Mock private MetadataLocalProperties metadataLocalProperties; @Mock @@ -105,12 +105,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<>(); @@ -118,6 +112,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 @@ -138,7 +138,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 @@ -153,12 +153,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<>(); @@ -166,6 +160,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 @@ -183,7 +183,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() 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 35e91ca7..195af9b7 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; @@ -68,7 +68,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 6be6dce0..08c79fb2 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; @@ -72,7 +72,7 @@ public class PolarisReactiveLoadBalancerClientFilterTest { @Mock private MetadataLocalProperties metadataLocalProperties; @Mock - private RouterLabelResolver routerLabelResolver; + private SpringWebRouterLabelResolver routerLabelResolver; @Mock private RouterRuleLabelResolver routerRuleLabelResolver; @Mock @@ -127,7 +127,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 aa568311..81767ce9 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 @@ -84,6 +84,7 @@ public final class ExpressionLabelUtils { * the suffix of expression. */ public static final String LABEL_SUFFIX = "}"; + private ExpressionLabelUtils() { } @@ -91,14 +92,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 8e312453..716ac1d8 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 bd289abb..be9b010e 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 00000000..44570366 --- /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; + } + +}