feat:support new label expression. (#641)

* feat:support new label expression.

* feat:support new label expression.
pull/644/head
Haotian Zhang 2 years ago committed by GitHub
parent fb4d270073
commit af0845f01f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,3 +10,4 @@
- [Feature: support spring-retry router](https://github.com/Tencent/spring-cloud-tencent/pull/633) - [Feature: support spring-retry router](https://github.com/Tencent/spring-cloud-tencent/pull/633)
- [Bugfix: fix throw npe when router context is null](https://github.com/Tencent/spring-cloud-tencent/pull/634) - [Bugfix: fix throw npe when router context is null](https://github.com/Tencent/spring-cloud-tencent/pull/634)
- [feat:Transfer http headers specified by environment variables](https://github.com/Tencent/spring-cloud-tencent/pull/637) - [feat:Transfer http headers specified by environment variables](https://github.com/Tencent/spring-cloud-tencent/pull/637)
- [feat:support new label expression](https://github.com/Tencent/spring-cloud-tencent/pull/641)

@ -21,6 +21,7 @@ import java.util.List;
import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.StaticMetadataManager;
import com.tencent.cloud.common.util.BeanFactoryUtils; import com.tencent.cloud.common.util.BeanFactoryUtils;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.scg.PolarisReactiveLoadBalancerClientFilter; import com.tencent.cloud.polaris.router.scg.PolarisReactiveLoadBalancerClientFilter;
import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver;
@ -60,10 +61,11 @@ public class ReactiveLoadBalancerClientFilterBeanPostProcessor implements BeanPo
List<SpringWebRouterLabelResolver> routerLabelResolvers = BeanFactoryUtils.getBeans(factory, SpringWebRouterLabelResolver.class); List<SpringWebRouterLabelResolver> routerLabelResolvers = BeanFactoryUtils.getBeans(factory, SpringWebRouterLabelResolver.class);
StaticMetadataManager staticMetadataManager = this.factory.getBean(StaticMetadataManager.class); StaticMetadataManager staticMetadataManager = this.factory.getBean(StaticMetadataManager.class);
RouterRuleLabelResolver routerRuleLabelResolver = this.factory.getBean(RouterRuleLabelResolver.class); RouterRuleLabelResolver routerRuleLabelResolver = this.factory.getBean(RouterRuleLabelResolver.class);
PolarisContextProperties polarisContextProperties = this.factory.getBean(PolarisContextProperties.class);
return new PolarisReactiveLoadBalancerClientFilter( return new PolarisReactiveLoadBalancerClientFilter(
loadBalancerClientFactory, gatewayLoadBalancerProperties, loadBalancerProperties, loadBalancerClientFactory, gatewayLoadBalancerProperties, loadBalancerProperties,
staticMetadataManager, routerRuleLabelResolver, routerLabelResolvers); staticMetadataManager, routerRuleLabelResolver, routerLabelResolvers, polarisContextProperties);
} }
return bean; return bean;
} }

@ -21,6 +21,7 @@ package com.tencent.cloud.polaris.router.config;
import java.util.List; import java.util.List;
import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.StaticMetadataManager;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.feign.RouterLabelFeignInterceptor; import com.tencent.cloud.polaris.router.feign.RouterLabelFeignInterceptor;
import com.tencent.cloud.polaris.router.spi.FeignRouterLabelResolver; import com.tencent.cloud.polaris.router.spi.FeignRouterLabelResolver;
@ -38,7 +39,8 @@ public class FeignAutoConfiguration {
@Bean @Bean
public RouterLabelFeignInterceptor routerLabelInterceptor(@Nullable List<FeignRouterLabelResolver> routerLabelResolvers, public RouterLabelFeignInterceptor routerLabelInterceptor(@Nullable List<FeignRouterLabelResolver> routerLabelResolvers,
StaticMetadataManager staticMetadataManager, StaticMetadataManager staticMetadataManager,
RouterRuleLabelResolver routerRuleLabelResolver) { RouterRuleLabelResolver routerRuleLabelResolver,
return new RouterLabelFeignInterceptor(routerLabelResolvers, staticMetadataManager, routerRuleLabelResolver); PolarisContextProperties polarisContextProperties) {
return new RouterLabelFeignInterceptor(routerLabelResolvers, staticMetadataManager, routerRuleLabelResolver, polarisContextProperties);
} }
} }

@ -24,6 +24,7 @@ import java.util.List;
import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.StaticMetadataManager;
import com.tencent.cloud.polaris.context.ServiceRuleManager; import com.tencent.cloud.polaris.context.ServiceRuleManager;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.beanprocessor.LoadBalancerInterceptorBeanPostProcessor; import com.tencent.cloud.polaris.router.beanprocessor.LoadBalancerInterceptorBeanPostProcessor;
import com.tencent.cloud.polaris.router.beanprocessor.ReactiveLoadBalancerClientFilterBeanPostProcessor; import com.tencent.cloud.polaris.router.beanprocessor.ReactiveLoadBalancerClientFilterBeanPostProcessor;
@ -114,8 +115,10 @@ public class RouterAutoConfiguration {
public RouterLabelRestTemplateInterceptor routerLabelRestTemplateInterceptor( public RouterLabelRestTemplateInterceptor routerLabelRestTemplateInterceptor(
List<SpringWebRouterLabelResolver> routerLabelResolvers, List<SpringWebRouterLabelResolver> routerLabelResolvers,
StaticMetadataManager staticMetadataManager, StaticMetadataManager staticMetadataManager,
RouterRuleLabelResolver routerRuleLabelResolver) { RouterRuleLabelResolver routerRuleLabelResolver,
return new RouterLabelRestTemplateInterceptor(routerLabelResolvers, staticMetadataManager, routerRuleLabelResolver); PolarisContextProperties polarisContextProperties) {
return new RouterLabelRestTemplateInterceptor(routerLabelResolvers, staticMetadataManager,
routerRuleLabelResolver, polarisContextProperties);
} }
@Bean @Bean

@ -49,24 +49,24 @@ public final class FeignExpressionLabelUtils {
Map<String, String> labels = new HashMap<>(); Map<String, String> labels = new HashMap<>();
for (String labelKey : labelKeys) { for (String labelKey : labelKeys) {
if (StringUtils.startsWithIgnoreCase(labelKey, ExpressionLabelUtils.LABEL_HEADER_PREFIX)) { if (ExpressionLabelUtils.isHeaderLabel(labelKey)) {
String headerKey = ExpressionLabelUtils.parseHeaderKey(labelKey); String headerKey = ExpressionLabelUtils.parseHeaderKey(labelKey);
if (StringUtils.isBlank(headerKey)) { if (StringUtils.isBlank(headerKey)) {
continue; continue;
} }
labels.put(labelKey, getHeaderValue(request, headerKey)); labels.put(labelKey, getHeaderValue(request, headerKey));
} }
else if (StringUtils.startsWithIgnoreCase(labelKey, ExpressionLabelUtils.LABEL_QUERY_PREFIX)) { else if (ExpressionLabelUtils.isQueryLabel(labelKey)) {
String queryKey = ExpressionLabelUtils.parseQueryKey(labelKey); String queryKey = ExpressionLabelUtils.parseQueryKey(labelKey);
if (StringUtils.isBlank(queryKey)) { if (StringUtils.isBlank(queryKey)) {
continue; continue;
} }
labels.put(labelKey, getQueryValue(request, queryKey)); labels.put(labelKey, getQueryValue(request, queryKey));
} }
else if (StringUtils.equalsIgnoreCase(ExpressionLabelUtils.LABEL_METHOD, labelKey)) { else if (ExpressionLabelUtils.isMethodLabel(labelKey)) {
labels.put(labelKey, request.method()); labels.put(labelKey, request.method());
} }
else if (StringUtils.equalsIgnoreCase(ExpressionLabelUtils.LABEL_URI, labelKey)) { else if (ExpressionLabelUtils.isUriLabel(labelKey)) {
URI uri = URI.create(request.request().url()); URI uri = URI.create(request.request().url());
labels.put(labelKey, uri.getPath()); labels.put(labelKey, uri.getPath());
} }

@ -32,6 +32,8 @@ import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.StaticMetadataManager;
import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.common.util.expresstion.ExpressionLabelUtils;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.FeignRouterLabelResolver; import com.tencent.cloud.polaris.router.spi.FeignRouterLabelResolver;
import feign.RequestInterceptor; import feign.RequestInterceptor;
@ -55,10 +57,12 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered
private final List<FeignRouterLabelResolver> routerLabelResolvers; private final List<FeignRouterLabelResolver> routerLabelResolvers;
private final StaticMetadataManager staticMetadataManager; private final StaticMetadataManager staticMetadataManager;
private final RouterRuleLabelResolver routerRuleLabelResolver; private final RouterRuleLabelResolver routerRuleLabelResolver;
private final PolarisContextProperties polarisContextProperties;
public RouterLabelFeignInterceptor(List<FeignRouterLabelResolver> routerLabelResolvers, public RouterLabelFeignInterceptor(List<FeignRouterLabelResolver> routerLabelResolvers,
StaticMetadataManager staticMetadataManager, StaticMetadataManager staticMetadataManager,
RouterRuleLabelResolver routerRuleLabelResolver) { RouterRuleLabelResolver routerRuleLabelResolver,
PolarisContextProperties polarisContextProperties) {
if (!CollectionUtils.isEmpty(routerLabelResolvers)) { if (!CollectionUtils.isEmpty(routerLabelResolvers)) {
routerLabelResolvers.sort(Comparator.comparingInt(Ordered::getOrder)); routerLabelResolvers.sort(Comparator.comparingInt(Ordered::getOrder));
this.routerLabelResolvers = routerLabelResolvers; this.routerLabelResolvers = routerLabelResolvers;
@ -68,6 +72,7 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered
} }
this.staticMetadataManager = staticMetadataManager; this.staticMetadataManager = staticMetadataManager;
this.routerRuleLabelResolver = routerRuleLabelResolver; this.routerRuleLabelResolver = routerRuleLabelResolver;
this.polarisContextProperties = polarisContextProperties;
} }
@Override @Override
@ -124,6 +129,16 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered
return Collections.emptyMap(); return Collections.emptyMap();
} }
return FeignExpressionLabelUtils.resolve(requestTemplate, labelKeys); //enrich labels from request
Map<String, String> labels = FeignExpressionLabelUtils.resolve(requestTemplate, labelKeys);
//enrich caller ip label
for (String labelKey : labelKeys) {
if (ExpressionLabelUtils.isCallerIPLabel(labelKey)) {
labels.put(labelKey, polarisContextProperties.getLocalIpAddress());
}
}
return labels;
} }
} }

@ -33,7 +33,9 @@ import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.StaticMetadataManager;
import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.common.util.expresstion.ExpressionLabelUtils;
import com.tencent.cloud.common.util.expresstion.SpringWebExpressionLabelUtils; import com.tencent.cloud.common.util.expresstion.SpringWebExpressionLabelUtils;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -62,12 +64,15 @@ public class RouterLabelRestTemplateInterceptor implements ClientHttpRequestInte
private final List<SpringWebRouterLabelResolver> routerLabelResolvers; private final List<SpringWebRouterLabelResolver> routerLabelResolvers;
private final StaticMetadataManager staticMetadataManager; private final StaticMetadataManager staticMetadataManager;
private final RouterRuleLabelResolver routerRuleLabelResolver; private final RouterRuleLabelResolver routerRuleLabelResolver;
private final PolarisContextProperties polarisContextProperties;
public RouterLabelRestTemplateInterceptor(List<SpringWebRouterLabelResolver> routerLabelResolvers, public RouterLabelRestTemplateInterceptor(List<SpringWebRouterLabelResolver> routerLabelResolvers,
StaticMetadataManager staticMetadataManager, StaticMetadataManager staticMetadataManager,
RouterRuleLabelResolver routerRuleLabelResolver) { RouterRuleLabelResolver routerRuleLabelResolver,
PolarisContextProperties polarisContextProperties) {
this.staticMetadataManager = staticMetadataManager; this.staticMetadataManager = staticMetadataManager;
this.routerRuleLabelResolver = routerRuleLabelResolver; this.routerRuleLabelResolver = routerRuleLabelResolver;
this.polarisContextProperties = polarisContextProperties;
if (!CollectionUtils.isEmpty(routerLabelResolvers)) { if (!CollectionUtils.isEmpty(routerLabelResolvers)) {
routerLabelResolvers.sort(Comparator.comparingInt(Ordered::getOrder)); routerLabelResolvers.sort(Comparator.comparingInt(Ordered::getOrder));
@ -145,6 +150,16 @@ public class RouterLabelRestTemplateInterceptor implements ClientHttpRequestInte
return Collections.emptyMap(); return Collections.emptyMap();
} }
return SpringWebExpressionLabelUtils.resolve(request, labelKeys); //enrich labels from request
Map<String, String> labels = SpringWebExpressionLabelUtils.resolve(request, labelKeys);
//enrich caller ip label
for (String labelKey : labelKeys) {
if (ExpressionLabelUtils.isCallerIPLabel(labelKey)) {
labels.put(labelKey, polarisContextProperties.getLocalIpAddress());
}
}
return labels;
} }
} }

@ -32,7 +32,9 @@ import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.StaticMetadataManager;
import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.common.util.expresstion.ExpressionLabelUtils;
import com.tencent.cloud.common.util.expresstion.SpringWebExpressionLabelUtils; import com.tencent.cloud.common.util.expresstion.SpringWebExpressionLabelUtils;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.cloud.polaris.router.PolarisRouterServiceInstanceListSupplier; import com.tencent.cloud.polaris.router.PolarisRouterServiceInstanceListSupplier;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver;
@ -87,13 +89,15 @@ public class PolarisReactiveLoadBalancerClientFilter extends ReactiveLoadBalance
private final StaticMetadataManager staticMetadataManager; private final StaticMetadataManager staticMetadataManager;
private final RouterRuleLabelResolver routerRuleLabelResolver; private final RouterRuleLabelResolver routerRuleLabelResolver;
private final List<SpringWebRouterLabelResolver> routerLabelResolvers; private final List<SpringWebRouterLabelResolver> routerLabelResolvers;
private final PolarisContextProperties polarisContextProperties;
public PolarisReactiveLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory, public PolarisReactiveLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory,
GatewayLoadBalancerProperties gatewayLoadBalancerProperties, GatewayLoadBalancerProperties gatewayLoadBalancerProperties,
LoadBalancerProperties loadBalancerProperties, LoadBalancerProperties loadBalancerProperties,
StaticMetadataManager staticMetadataManager, StaticMetadataManager staticMetadataManager,
RouterRuleLabelResolver routerRuleLabelResolver, RouterRuleLabelResolver routerRuleLabelResolver,
List<SpringWebRouterLabelResolver> routerLabelResolvers) { List<SpringWebRouterLabelResolver> routerLabelResolvers,
PolarisContextProperties polarisContextProperties) {
super(clientFactory, gatewayLoadBalancerProperties, loadBalancerProperties); super(clientFactory, gatewayLoadBalancerProperties, loadBalancerProperties);
this.clientFactory = clientFactory; this.clientFactory = clientFactory;
@ -102,6 +106,7 @@ public class PolarisReactiveLoadBalancerClientFilter extends ReactiveLoadBalance
this.staticMetadataManager = staticMetadataManager; this.staticMetadataManager = staticMetadataManager;
this.routerRuleLabelResolver = routerRuleLabelResolver; this.routerRuleLabelResolver = routerRuleLabelResolver;
this.routerLabelResolvers = routerLabelResolvers; this.routerLabelResolvers = routerLabelResolvers;
this.polarisContextProperties = polarisContextProperties;
} }
/** /**
@ -262,6 +267,16 @@ public class PolarisReactiveLoadBalancerClientFilter extends ReactiveLoadBalance
return Collections.emptyMap(); return Collections.emptyMap();
} }
return SpringWebExpressionLabelUtils.resolve(exchange, labelKeys); //enrich labels from request
Map<String, String> labels = SpringWebExpressionLabelUtils.resolve(exchange, labelKeys);
//enrich caller ip label
for (String labelKey : labelKeys) {
if (ExpressionLabelUtils.isCallerIPLabel(labelKey)) {
labels.put(labelKey, polarisContextProperties.getLocalIpAddress());
}
}
return labels;
} }
} }

@ -84,12 +84,12 @@ public class RouterRuleLabelResolverTest {
Set<String> resolvedExpressionLabelKeys = resolver.getExpressionLabelKeys(testNamespace, testSourceService, testDstService); Set<String> resolvedExpressionLabelKeys = resolver.getExpressionLabelKeys(testNamespace, testSourceService, testDstService);
Assert.assertNotNull(resolvedExpressionLabelKeys); Assert.assertNotNull(resolvedExpressionLabelKeys);
Assert.assertEquals(5, resolvedExpressionLabelKeys.size()); Assert.assertEquals(6, resolvedExpressionLabelKeys.size());
Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey1)); Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey1));
Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey2)); Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey2));
Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey3)); Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey3));
Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey4)); Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey4));
Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey5)); Assert.assertTrue(resolvedExpressionLabelKeys.contains(validKey5));
Assert.assertFalse(resolvedExpressionLabelKeys.contains(invalidKey)); Assert.assertTrue(resolvedExpressionLabelKeys.contains(invalidKey));
} }
} }

@ -33,6 +33,7 @@ import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.StaticMetadataManager;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.FeignRouterLabelResolver; import com.tencent.cloud.polaris.router.spi.FeignRouterLabelResolver;
import feign.RequestTemplate; import feign.RequestTemplate;
@ -63,12 +64,14 @@ public class RouterLabelFeignInterceptorTest {
private RouterRuleLabelResolver routerRuleLabelResolver; private RouterRuleLabelResolver routerRuleLabelResolver;
@Mock @Mock
private FeignRouterLabelResolver routerLabelResolver; private FeignRouterLabelResolver routerLabelResolver;
@Mock
private PolarisContextProperties polarisContextProperties;
@Test @Test
public void testResolveRouterLabel() { public void testResolveRouterLabel() {
RouterLabelFeignInterceptor routerLabelFeignInterceptor = new RouterLabelFeignInterceptor( RouterLabelFeignInterceptor routerLabelFeignInterceptor = new RouterLabelFeignInterceptor(
Collections.singletonList(routerLabelResolver), Collections.singletonList(routerLabelResolver),
staticMetadataManager, routerRuleLabelResolver); staticMetadataManager, routerRuleLabelResolver, polarisContextProperties);
// mock request template // mock request template
RequestTemplate requestTemplate = new RequestTemplate(); RequestTemplate requestTemplate = new RequestTemplate();

@ -32,6 +32,7 @@ import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.StaticMetadataManager;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
@ -67,6 +68,8 @@ public class RouterLabelRestTemplateInterceptorTest {
private StaticMetadataManager staticMetadataManager; private StaticMetadataManager staticMetadataManager;
@Mock @Mock
private RouterRuleLabelResolver routerRuleLabelResolver; private RouterRuleLabelResolver routerRuleLabelResolver;
@Mock
private PolarisContextProperties polarisContextProperties;
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
@ -119,7 +122,7 @@ public class RouterLabelRestTemplateInterceptorTest {
mockedMetadataContextHolder.when(MetadataContextHolder::get).thenReturn(metadataContext); mockedMetadataContextHolder.when(MetadataContextHolder::get).thenReturn(metadataContext);
RouterLabelRestTemplateInterceptor routerLabelRestTemplateInterceptor = new RouterLabelRestTemplateInterceptor( RouterLabelRestTemplateInterceptor routerLabelRestTemplateInterceptor = new RouterLabelRestTemplateInterceptor(
Collections.singletonList(routerLabelResolver), staticMetadataManager, routerRuleLabelResolver); Collections.singletonList(routerLabelResolver), staticMetadataManager, routerRuleLabelResolver, polarisContextProperties);
routerLabelRestTemplateInterceptor.setLabelsToHeaders(request, null, calleeService); routerLabelRestTemplateInterceptor.setLabelsToHeaders(request, null, calleeService);

@ -33,6 +33,7 @@ import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.StaticMetadataManager;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver; import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver;
import org.junit.AfterClass; import org.junit.AfterClass;
@ -82,6 +83,8 @@ public class PolarisReactiveLoadBalancerClientFilterTest {
private GatewayLoadBalancerProperties gatewayLoadBalancerProperties; private GatewayLoadBalancerProperties gatewayLoadBalancerProperties;
@Mock @Mock
private LoadBalancerProperties loadBalancerProperties; private LoadBalancerProperties loadBalancerProperties;
@Mock
private PolarisContextProperties polarisContextProperties;
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
@ -111,7 +114,7 @@ public class PolarisReactiveLoadBalancerClientFilterTest {
public void testGenRouterHttpHeaders() throws UnsupportedEncodingException { public void testGenRouterHttpHeaders() throws UnsupportedEncodingException {
PolarisReactiveLoadBalancerClientFilter filter = new PolarisReactiveLoadBalancerClientFilter(loadBalancerClientFactory, PolarisReactiveLoadBalancerClientFilter filter = new PolarisReactiveLoadBalancerClientFilter(loadBalancerClientFactory,
gatewayLoadBalancerProperties, loadBalancerProperties, staticMetadataManager, routerRuleLabelResolver, gatewayLoadBalancerProperties, loadBalancerProperties, staticMetadataManager, routerRuleLabelResolver,
Lists.newArrayList(routerLabelResolver)); Lists.newArrayList(routerLabelResolver), polarisContextProperties);
Map<String, String> localMetadata = new HashMap<>(); Map<String, String> localMetadata = new HashMap<>();
localMetadata.put("env", "blue"); localMetadata.put("env", "blue");

@ -13,12 +13,13 @@
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * 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 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License. * specific language governing permissions and limitations under the License.
*
*/ */
package com.tencent.cloud.common.util.expresstion; package com.tencent.cloud.common.util.expresstion;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@ -33,69 +34,105 @@ import org.springframework.util.CollectionUtils;
*/ */
public final class ExpressionLabelUtils { public final class ExpressionLabelUtils {
/** private static final List<ExpressionParser> EXPRESSION_PARSERS;
* the expression prefix of header label.
*/ static {
public static final String LABEL_HEADER_PREFIX = "${http.header."; EXPRESSION_PARSERS = new ArrayList<>(2);
/** EXPRESSION_PARSERS.add(new ExpressionParserV1());
* the length of expression header label prefix. EXPRESSION_PARSERS.add(new ExpressionParserV2());
*/ }
public static final int LABEL_HEADER_PREFIX_LEN = LABEL_HEADER_PREFIX.length();
/**
* the expression prefix of query.
*/
public static final String LABEL_QUERY_PREFIX = "${http.query.";
/**
* the length of expression query label prefix.
*/
public static final int LABEL_QUERY_PREFIX_LEN = LABEL_QUERY_PREFIX.length();
/**
* the expression prefix of cookie.
*/
public static final String LABEL_COOKIE_PREFIX = "${http.cookie.";
/**
* the length of expression cookie label prefix.
*/
public static final int LABEL_COOKIE_PREFIX_LEN = LABEL_COOKIE_PREFIX.length();
/**
* the expression of method.
*/
public static final String LABEL_METHOD = "${http.method}";
/**
* the expression of uri.
*/
public static final String LABEL_URI = "${http.uri}";
/**
* the prefix of expression.
*/
public static final String LABEL_PREFIX = "${";
/**
* the suffix of expression.
*/
public static final String LABEL_SUFFIX = "}";
private ExpressionLabelUtils() { private ExpressionLabelUtils() {
} }
public static boolean isExpressionLabel(String labelKey) { public static boolean isExpressionLabel(String expression) {
if (StringUtils.isEmpty(labelKey)) { for (ExpressionParser parser : EXPRESSION_PARSERS) {
return false; if (parser.isExpressionLabel(expression)) {
return true;
}
} }
return StringUtils.startsWith(labelKey, LABEL_PREFIX) && StringUtils.endsWith(labelKey, LABEL_SUFFIX); return false;
}
public static boolean isHeaderLabel(String expression) {
for (ExpressionParser parser : EXPRESSION_PARSERS) {
if (parser.isHeaderLabel(expression)) {
return true;
}
}
return false;
} }
public static String parseHeaderKey(String expression) { public static String parseHeaderKey(String expression) {
return expression.substring(LABEL_HEADER_PREFIX_LEN, expression.length() - 1); for (ExpressionParser parser : EXPRESSION_PARSERS) {
if (parser.isHeaderLabel(expression)) {
return parser.parseHeaderKey(expression);
}
}
return "";
}
public static boolean isQueryLabel(String expression) {
for (ExpressionParser parser : EXPRESSION_PARSERS) {
if (parser.isQueryLabel(expression)) {
return true;
}
}
return false;
} }
public static String parseQueryKey(String expression) { public static String parseQueryKey(String expression) {
return expression.substring(LABEL_QUERY_PREFIX_LEN, expression.length() - 1); for (ExpressionParser parser : EXPRESSION_PARSERS) {
if (parser.isQueryLabel(expression)) {
return parser.parseQueryKey(expression);
}
}
return "";
}
public static boolean isCookieLabel(String expression) {
for (ExpressionParser parser : EXPRESSION_PARSERS) {
if (parser.isCookieLabel(expression)) {
return true;
}
}
return false;
} }
public static String parseCookieKey(String expression) { public static String parseCookieKey(String expression) {
return expression.substring(LABEL_COOKIE_PREFIX_LEN, expression.length() - 1); for (ExpressionParser parser : EXPRESSION_PARSERS) {
if (parser.isCookieLabel(expression)) {
return parser.parseCookieKey(expression);
}
}
return "";
}
public static boolean isMethodLabel(String expression) {
for (ExpressionParser parser : EXPRESSION_PARSERS) {
if (parser.isMethodLabel(expression)) {
return true;
}
}
return false;
}
public static boolean isUriLabel(String expression) {
for (ExpressionParser parser : EXPRESSION_PARSERS) {
if (parser.isUriLabel(expression)) {
return true;
}
}
return false;
}
public static boolean isCallerIPLabel(String expression) {
for (ExpressionParser parser : EXPRESSION_PARSERS) {
if (parser.isCallerIPLabel(expression)) {
return true;
}
}
return false;
} }
public static String getQueryValue(String queryString, String queryKey) { public static String getQueryValue(String queryString, String queryKey) {

@ -0,0 +1,95 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.tencent.cloud.common.util.expresstion;
/**
* Expression parser for rate limit rule and router rule.
* @author lepdou 2022-10-08
*/
public interface ExpressionParser {
/**
* whether is valid expression.
* @param expression the expression
* @return true if is valid
*/
boolean isExpressionLabel(String expression);
/**
* whether is header expression.
* @param expression the expression
* @return true if is header expression
*/
boolean isHeaderLabel(String expression);
/**
* parse label from header expression.
* @param expression the expression
* @return parsed key from expression
*/
String parseHeaderKey(String expression);
/**
* whether is query expression.
* @param expression the expression
* @return true if is query expression
*/
boolean isQueryLabel(String expression);
/**
* parse label from query expression.
* @param expression the expression
* @return parsed key from expression
*/
String parseQueryKey(String expression);
/**
* whether is cookie expression.
* @param expression the expression
* @return true if is cookie expression
*/
boolean isCookieLabel(String expression);
/**
* parse label from cookie expression.
* @param expression the expression
* @return parsed cookie key from expression
*/
String parseCookieKey(String expression);
/**
* whether is method expression.
* @param expression the expression
* @return true if is method expression
*/
boolean isMethodLabel(String expression);
/**
* whether is uri/path expression.
* @param expression the expression
* @return true if is uri/path expression
*/
boolean isUriLabel(String expression);
/**
* whether is caller ip expression.
* @param expression the expression
* @return true if is caller ip expression
*/
boolean isCallerIPLabel(String expression);
}

@ -0,0 +1,93 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.tencent.cloud.common.util.expresstion;
import org.apache.commons.lang.StringUtils;
/**
* Old custom expression resolver like ${http.query.key}${http.header.key}.
* New expression like $query.key$header.key
* @author lepdou 2022-10-08
*/
public class ExpressionParserV1 implements ExpressionParser {
private static final String LABEL_HEADER_PREFIX = "${http.header.";
private static final int LABEL_HEADER_PREFIX_LEN = LABEL_HEADER_PREFIX.length();
private static final String LABEL_QUERY_PREFIX = "${http.query.";
private static final int LABEL_QUERY_PREFIX_LEN = LABEL_QUERY_PREFIX.length();
private static final String LABEL_COOKIE_PREFIX = "${http.cookie.";
private static final int LABEL_COOKIE_PREFIX_LEN = LABEL_COOKIE_PREFIX.length();
private static final String LABEL_METHOD = "${http.method}";
private static final String LABEL_URI = "${http.uri}";
private static final String LABEL_CALLER_IP = "${http.caller.ip}";
private static final String LABEL_PREFIX = "${";
private static final String LABEL_SUFFIX = "}";
@Override
public boolean isExpressionLabel(String labelKey) {
if (StringUtils.isEmpty(labelKey)) {
return false;
}
return StringUtils.startsWith(labelKey, LABEL_PREFIX) && StringUtils.endsWith(labelKey, LABEL_SUFFIX);
}
@Override
public boolean isHeaderLabel(String expression) {
return StringUtils.startsWith(expression, LABEL_HEADER_PREFIX) && StringUtils.endsWith(expression, LABEL_SUFFIX);
}
@Override
public String parseHeaderKey(String expression) {
return StringUtils.substring(expression, LABEL_HEADER_PREFIX_LEN, expression.length() - 1);
}
@Override
public boolean isQueryLabel(String expression) {
return StringUtils.startsWith(expression, LABEL_QUERY_PREFIX) && StringUtils.endsWith(expression, LABEL_SUFFIX);
}
@Override
public String parseQueryKey(String expression) {
return StringUtils.substring(expression, LABEL_QUERY_PREFIX_LEN, expression.length() - 1);
}
@Override
public boolean isCookieLabel(String expression) {
return StringUtils.startsWith(expression, LABEL_COOKIE_PREFIX) && StringUtils.endsWith(expression, LABEL_SUFFIX);
}
@Override
public String parseCookieKey(String expression) {
return StringUtils.substring(expression, LABEL_COOKIE_PREFIX_LEN, expression.length() - 1);
}
@Override
public boolean isMethodLabel(String expression) {
return StringUtils.equalsIgnoreCase(expression, LABEL_METHOD);
}
@Override
public boolean isUriLabel(String expression) {
return StringUtils.equalsIgnoreCase(expression, LABEL_URI);
}
@Override
public boolean isCallerIPLabel(String expression) {
return StringUtils.equalsIgnoreCase(expression, LABEL_CALLER_IP);
}
}

@ -0,0 +1,88 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.tencent.cloud.common.util.expresstion;
import org.apache.commons.lang.StringUtils;
/**
* New custom expression resolver like $query.key$header.key.
* Old expression like ${http.query.key}${http.header.key}
* @author lepdou 2022-10-08
*/
public class ExpressionParserV2 implements ExpressionParser {
private static final String LABEL_HEADER_PREFIX = "$header.";
private static final int LABEL_HEADER_PREFIX_LEN = LABEL_HEADER_PREFIX.length();
private static final String LABEL_QUERY_PREFIX = "$query.";
private static final int LABEL_QUERY_PREFIX_LEN = LABEL_QUERY_PREFIX.length();
private static final String LABEL_METHOD = "$method";
private static final String LABEL_PATH = "$path";
private static final String LABEL_CALLER_IP = "$caller_ip";
private static final String LABEL_PREFIX = "$";
@Override
public boolean isExpressionLabel(String expression) {
return StringUtils.startsWith(expression, LABEL_PREFIX);
}
@Override
public boolean isHeaderLabel(String expression) {
return StringUtils.startsWith(expression, LABEL_HEADER_PREFIX);
}
@Override
public String parseHeaderKey(String expression) {
return StringUtils.substring(expression, LABEL_HEADER_PREFIX_LEN);
}
@Override
public boolean isQueryLabel(String expression) {
return StringUtils.startsWith(expression, LABEL_QUERY_PREFIX);
}
@Override
public String parseQueryKey(String expression) {
return StringUtils.substring(expression, LABEL_QUERY_PREFIX_LEN);
}
@Override
public boolean isCookieLabel(String expression) {
return false;
}
@Override
public String parseCookieKey(String expression) {
return null;
}
@Override
public boolean isMethodLabel(String expression) {
return StringUtils.equalsIgnoreCase(expression, LABEL_METHOD);
}
@Override
public boolean isUriLabel(String expression) {
return StringUtils.equalsIgnoreCase(expression, LABEL_PATH);
}
@Override
public boolean isCallerIPLabel(String expression) {
return StringUtils.equalsIgnoreCase(expression, LABEL_CALLER_IP);
}
}

@ -50,31 +50,31 @@ public final class ServletExpressionLabelUtils {
if (!ExpressionLabelUtils.isExpressionLabel(labelKey)) { if (!ExpressionLabelUtils.isExpressionLabel(labelKey)) {
continue; continue;
} }
if (StringUtils.startsWithIgnoreCase(labelKey, ExpressionLabelUtils.LABEL_HEADER_PREFIX)) { if (ExpressionLabelUtils.isHeaderLabel(labelKey)) {
String headerKey = ExpressionLabelUtils.parseHeaderKey(labelKey); String headerKey = ExpressionLabelUtils.parseHeaderKey(labelKey);
if (StringUtils.isBlank(headerKey)) { if (StringUtils.isBlank(headerKey)) {
continue; continue;
} }
labels.put(labelKey, request.getHeader(headerKey)); labels.put(labelKey, request.getHeader(headerKey));
} }
else if (StringUtils.startsWithIgnoreCase(labelKey, ExpressionLabelUtils.LABEL_QUERY_PREFIX)) { else if (ExpressionLabelUtils.isQueryLabel(labelKey)) {
String queryKey = ExpressionLabelUtils.parseQueryKey(labelKey); String queryKey = ExpressionLabelUtils.parseQueryKey(labelKey);
if (StringUtils.isBlank(queryKey)) { if (StringUtils.isBlank(queryKey)) {
continue; continue;
} }
labels.put(labelKey, ExpressionLabelUtils.getQueryValue(request.getQueryString(), queryKey)); labels.put(labelKey, ExpressionLabelUtils.getQueryValue(request.getQueryString(), queryKey));
} }
else if (StringUtils.startsWithIgnoreCase(labelKey, ExpressionLabelUtils.LABEL_COOKIE_PREFIX)) { else if (ExpressionLabelUtils.isCookieLabel(labelKey)) {
String cookieKey = ExpressionLabelUtils.parseCookieKey(labelKey); String cookieKey = ExpressionLabelUtils.parseCookieKey(labelKey);
if (StringUtils.isBlank(cookieKey)) { if (StringUtils.isBlank(cookieKey)) {
continue; continue;
} }
labels.put(labelKey, getCookieValue(request.getCookies(), cookieKey)); labels.put(labelKey, getCookieValue(request.getCookies(), cookieKey));
} }
else if (StringUtils.equalsIgnoreCase(ExpressionLabelUtils.LABEL_METHOD, labelKey)) { else if (ExpressionLabelUtils.isMethodLabel(labelKey)) {
labels.put(labelKey, request.getMethod()); labels.put(labelKey, request.getMethod());
} }
else if (StringUtils.equalsIgnoreCase(ExpressionLabelUtils.LABEL_URI, labelKey)) { else if (ExpressionLabelUtils.isUriLabel(labelKey)) {
labels.put(labelKey, request.getRequestURI()); labels.put(labelKey, request.getRequestURI());
} }
} }

@ -53,31 +53,31 @@ public final class SpringWebExpressionLabelUtils {
if (!ExpressionLabelUtils.isExpressionLabel(labelKey)) { if (!ExpressionLabelUtils.isExpressionLabel(labelKey)) {
continue; continue;
} }
if (StringUtils.startsWithIgnoreCase(labelKey, ExpressionLabelUtils.LABEL_HEADER_PREFIX)) { if (ExpressionLabelUtils.isHeaderLabel(labelKey)) {
String headerKey = ExpressionLabelUtils.parseHeaderKey(labelKey); String headerKey = ExpressionLabelUtils.parseHeaderKey(labelKey);
if (StringUtils.isBlank(headerKey)) { if (StringUtils.isBlank(headerKey)) {
continue; continue;
} }
labels.put(labelKey, getHeaderValue(exchange.getRequest(), headerKey)); labels.put(labelKey, getHeaderValue(exchange.getRequest(), headerKey));
} }
else if (StringUtils.startsWithIgnoreCase(labelKey, ExpressionLabelUtils.LABEL_QUERY_PREFIX)) { else if (ExpressionLabelUtils.isQueryLabel(labelKey)) {
String queryKey = ExpressionLabelUtils.parseQueryKey(labelKey); String queryKey = ExpressionLabelUtils.parseQueryKey(labelKey);
if (StringUtils.isBlank(queryKey)) { if (StringUtils.isBlank(queryKey)) {
continue; continue;
} }
labels.put(labelKey, getQueryValue(exchange.getRequest(), queryKey)); labels.put(labelKey, getQueryValue(exchange.getRequest(), queryKey));
} }
else if (StringUtils.startsWithIgnoreCase(labelKey, ExpressionLabelUtils.LABEL_COOKIE_PREFIX)) { else if (ExpressionLabelUtils.isCookieLabel(labelKey)) {
String cookieKey = ExpressionLabelUtils.parseCookieKey(labelKey); String cookieKey = ExpressionLabelUtils.parseCookieKey(labelKey);
if (StringUtils.isBlank(cookieKey)) { if (StringUtils.isBlank(cookieKey)) {
continue; continue;
} }
labels.put(labelKey, getCookieValue(exchange.getRequest(), cookieKey)); labels.put(labelKey, getCookieValue(exchange.getRequest(), cookieKey));
} }
else if (StringUtils.equalsIgnoreCase(ExpressionLabelUtils.LABEL_METHOD, labelKey)) { else if (ExpressionLabelUtils.isMethodLabel(labelKey)) {
labels.put(labelKey, exchange.getRequest().getMethodValue()); labels.put(labelKey, exchange.getRequest().getMethodValue());
} }
else if (StringUtils.equalsIgnoreCase(ExpressionLabelUtils.LABEL_URI, labelKey)) { else if (ExpressionLabelUtils.isUriLabel(labelKey)) {
labels.put(labelKey, exchange.getRequest().getURI().getPath()); labels.put(labelKey, exchange.getRequest().getURI().getPath());
} }
} }
@ -96,24 +96,24 @@ public final class SpringWebExpressionLabelUtils {
if (!ExpressionLabelUtils.isExpressionLabel(labelKey)) { if (!ExpressionLabelUtils.isExpressionLabel(labelKey)) {
continue; continue;
} }
if (StringUtils.startsWithIgnoreCase(labelKey, ExpressionLabelUtils.LABEL_HEADER_PREFIX)) { if (ExpressionLabelUtils.isHeaderLabel(labelKey)) {
String headerKey = ExpressionLabelUtils.parseHeaderKey(labelKey); String headerKey = ExpressionLabelUtils.parseHeaderKey(labelKey);
if (StringUtils.isBlank(headerKey)) { if (StringUtils.isBlank(headerKey)) {
continue; continue;
} }
labels.put(labelKey, getHeaderValue(request, headerKey)); labels.put(labelKey, getHeaderValue(request, headerKey));
} }
else if (StringUtils.startsWithIgnoreCase(labelKey, ExpressionLabelUtils.LABEL_QUERY_PREFIX)) { else if (ExpressionLabelUtils.isQueryLabel(labelKey)) {
String queryKey = ExpressionLabelUtils.parseQueryKey(labelKey); String queryKey = ExpressionLabelUtils.parseQueryKey(labelKey);
if (StringUtils.isBlank(queryKey)) { if (StringUtils.isBlank(queryKey)) {
continue; continue;
} }
labels.put(labelKey, getQueryValue(request, queryKey)); labels.put(labelKey, getQueryValue(request, queryKey));
} }
else if (StringUtils.equalsIgnoreCase(ExpressionLabelUtils.LABEL_METHOD, labelKey)) { else if (ExpressionLabelUtils.isMethodLabel(labelKey)) {
labels.put(labelKey, request.getMethodValue()); labels.put(labelKey, request.getMethodValue());
} }
else if (StringUtils.equalsIgnoreCase(ExpressionLabelUtils.LABEL_URI, labelKey)) { else if (ExpressionLabelUtils.isUriLabel(labelKey)) {
labels.put(labelKey, request.getURI().getPath()); labels.put(labelKey, request.getURI().getPath());
} }
} }

@ -71,12 +71,12 @@ public class ExpressionLabelUtilsTest {
Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(validLabel5)); Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(validLabel5));
Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel1)); Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel1));
Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel2)); Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel2));
Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel3)); Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel3));
Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel4)); Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel4));
Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel5)); Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel5));
Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel6)); Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel6));
Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel7)); Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel7));
Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel8)); Assert.assertTrue(ExpressionLabelUtils.isExpressionLabel(invalidLabel8));
Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel9)); Assert.assertFalse(ExpressionLabelUtils.isExpressionLabel(invalidLabel9));
} }

@ -0,0 +1,70 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.tencent.cloud.common.util;
import com.tencent.cloud.common.util.expresstion.ExpressionParserV1;
import org.junit.Assert;
import org.junit.Test;
/**
* Test for {@link ExpressionParserV1}
* @author lepdou 2022-10-08
*/
public class ExpressionParserV1Test {
@Test
public void testExpressionLabel() {
String validLabel1 = "${http.query.uid}";
String validLabel2 = "${http.header.uid}";
String validLabel3 = "${http.cookie.uid}";
String validLabel4 = "${http.method}";
String validLabel5 = "${http.uri}";
String invalidLabel1 = "${http.queryuid}";
String invalidLabel2 = "{http.query.uid}";
String invalidLabel3 = "${http.query.uid";
String invalidLabel4 = "$ {http.query.uid}";
String invalidLabel5 = "${ http.query.uid}";
String invalidLabel6 = "${query.uid}";
String invalidLabel7 = "http.query.uid";
String invalidLabel8 = "$${http.uri}";
String invalidLabel9 = "#{http.uri}";
ExpressionParserV1 parser = new ExpressionParserV1();
Assert.assertTrue(parser.isExpressionLabel(validLabel1));
Assert.assertTrue(parser.isExpressionLabel(validLabel2));
Assert.assertTrue(parser.isExpressionLabel(validLabel3));
Assert.assertTrue(parser.isExpressionLabel(validLabel4));
Assert.assertTrue(parser.isExpressionLabel(validLabel5));
Assert.assertTrue(parser.isExpressionLabel(invalidLabel1));
Assert.assertFalse(parser.isExpressionLabel(invalidLabel2));
Assert.assertFalse(parser.isExpressionLabel(invalidLabel3));
Assert.assertFalse(parser.isExpressionLabel(invalidLabel4));
Assert.assertTrue(parser.isExpressionLabel(invalidLabel5));
Assert.assertTrue(parser.isExpressionLabel(invalidLabel6));
Assert.assertFalse(parser.isExpressionLabel(invalidLabel7));
Assert.assertFalse(parser.isExpressionLabel(invalidLabel8));
Assert.assertFalse(parser.isExpressionLabel(invalidLabel9));
Assert.assertTrue(parser.isQueryLabel(validLabel1));
Assert.assertTrue(parser.isHeaderLabel(validLabel2));
Assert.assertTrue(parser.isCookieLabel(validLabel3));
Assert.assertTrue(parser.isMethodLabel(validLabel4));
Assert.assertTrue(parser.isUriLabel(validLabel5));
}
}

@ -0,0 +1,74 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.tencent.cloud.common.util;
import com.tencent.cloud.common.util.expresstion.ExpressionParserV2;
import org.junit.Assert;
import org.junit.Test;
/**
* Test for {@link ExpressionParserV2}
* @author lepdou 2022-10-08
*/
public class ExpressionParserV2Test {
@Test
public void testExpressionLabel() {
String validLabel1 = "${http.query.uid}";
String validLabel2 = "${http.header.uid}";
String validLabel3 = "${http.cookie.uid}";
String validLabel4 = "${http.method}";
String validLabel5 = "${http.uri}";
String invalidLabel1 = "${http.queryuid}";
String invalidLabel2 = "{http.query.uid}";
String invalidLabel3 = "${http.query.uid";
String invalidLabel4 = "$ {http.query.uid}";
String invalidLabel5 = "${ http.query.uid}";
String invalidLabel6 = "${query.uid}";
String invalidLabel7 = "http.query.uid";
String invalidLabel8 = "$${http.uri}";
String invalidLabel9 = "#{http.uri}";
ExpressionParserV2 parser = new ExpressionParserV2();
Assert.assertTrue(parser.isExpressionLabel(validLabel1));
Assert.assertTrue(parser.isExpressionLabel(validLabel2));
Assert.assertTrue(parser.isExpressionLabel(validLabel3));
Assert.assertTrue(parser.isExpressionLabel(validLabel4));
Assert.assertTrue(parser.isExpressionLabel(validLabel5));
Assert.assertTrue(parser.isExpressionLabel(invalidLabel1));
Assert.assertFalse(parser.isExpressionLabel(invalidLabel2));
Assert.assertTrue(parser.isExpressionLabel(invalidLabel3));
Assert.assertTrue(parser.isExpressionLabel(invalidLabel4));
Assert.assertTrue(parser.isExpressionLabel(invalidLabel5));
Assert.assertTrue(parser.isExpressionLabel(invalidLabel6));
Assert.assertFalse(parser.isExpressionLabel(invalidLabel7));
Assert.assertTrue(parser.isExpressionLabel(invalidLabel8));
Assert.assertFalse(parser.isExpressionLabel(invalidLabel9));
Assert.assertFalse(parser.isQueryLabel(validLabel1));
Assert.assertFalse(parser.isHeaderLabel(validLabel2));
Assert.assertFalse(parser.isCookieLabel(validLabel3));
Assert.assertFalse(parser.isMethodLabel(validLabel4));
Assert.assertFalse(parser.isUriLabel(validLabel5));
Assert.assertTrue(parser.isHeaderLabel("$header.userId"));
Assert.assertTrue(parser.isMethodLabel("$method"));
Assert.assertTrue(parser.isQueryLabel("$query.userId"));
}
}

@ -73,7 +73,7 @@
<revision>1.8.0-2020.0.5-SNAPSHOT</revision> <revision>1.8.0-2020.0.5-SNAPSHOT</revision>
<!-- Dependencies --> <!-- Dependencies -->
<polaris.version>1.8.0</polaris.version> <polaris.version>1.9.1</polaris.version>
<logback.version>1.2.11</logback.version> <logback.version>1.2.11</logback.version>
<mocktio.version>4.5.1</mocktio.version> <mocktio.version>4.5.1</mocktio.version>
<byte-buddy.version>1.12.10</byte-buddy.version> <byte-buddy.version>1.12.10</byte-buddy.version>

@ -11,7 +11,7 @@ spring:
region: shanghai region: shanghai
rpc-enhancement: rpc-enhancement:
reporter: reporter:
enabled: true enabled: false
polaris: polaris:
address: grpc://183.47.111.80:8091 address: grpc://183.47.111.80:8091
namespace: default namespace: default

@ -18,8 +18,11 @@
package com.tencent.cloud.polaris.context.config; package com.tencent.cloud.polaris.context.config;
import java.util.List;
import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled;
import com.tencent.cloud.polaris.context.ModifyAddress; import com.tencent.cloud.polaris.context.ModifyAddress;
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
import com.tencent.cloud.polaris.context.ServiceRuleManager; import com.tencent.cloud.polaris.context.ServiceRuleManager;
import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.core.ConsumerAPI;
import com.tencent.polaris.api.core.ProviderAPI; import com.tencent.polaris.api.core.ProviderAPI;
@ -31,6 +34,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
/** /**
* Autoconfiguration for Polaris {@link SDKContext}. * Autoconfiguration for Polaris {@link SDKContext}.
@ -44,9 +48,11 @@ public class PolarisContextAutoConfiguration {
@Bean(name = "polarisContext", initMethod = "init", destroyMethod = "destroy") @Bean(name = "polarisContext", initMethod = "init", destroyMethod = "destroy")
@ConditionalOnMissingBean @ConditionalOnMissingBean
public SDKContext polarisContext(PolarisContextProperties properties) public SDKContext polarisContext(PolarisContextProperties properties, Environment environment,
List<PolarisConfigModifier> modifierList)
throws PolarisException { throws PolarisException {
return SDKContext.initContextByConfig(properties.configuration()); return SDKContext.initContextByConfig(properties.configuration(modifierList,
() -> environment.getProperty("spring.cloud.client.ip-address")));
} }
@Bean @Bean

@ -21,6 +21,7 @@ package com.tencent.cloud.polaris.context.config;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.tencent.cloud.polaris.context.PolarisConfigModifier; import com.tencent.cloud.polaris.context.PolarisConfigModifier;
@ -30,9 +31,7 @@ import com.tencent.polaris.factory.ConfigAPIFactory;
import com.tencent.polaris.factory.config.ConfigurationImpl; import com.tencent.polaris.factory.config.ConfigurationImpl;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.env.Environment;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
@ -68,19 +67,18 @@ public class PolarisContextProperties {
*/ */
private String service; private String service;
@Autowired public Configuration configuration(List<PolarisConfigModifier> modifierList, Supplier<String> ipAddressSupplier) {
private Environment environment;
@Autowired
private List<PolarisConfigModifier> modifierList;
protected Configuration configuration() {
// 1. Read user-defined polaris.yml configuration // 1. Read user-defined polaris.yml configuration
ConfigurationImpl configuration = (ConfigurationImpl) ConfigAPIFactory ConfigurationImpl configuration = (ConfigurationImpl) ConfigAPIFactory
.defaultConfig(ConfigProvider.DEFAULT_CONFIG); .defaultConfig(ConfigProvider.DEFAULT_CONFIG);
// 2. Override user-defined polaris.yml configuration with SCT configuration // 2. Override user-defined polaris.yml configuration with SCT configuration
String defaultHost = getHost(); String defaultHost = this.localIpAddress;
if (StringUtils.isBlank(localIpAddress)) {
defaultHost = ipAddressSupplier.get();
this.localIpAddress = defaultHost;
}
configuration.getGlobal().getAPI().setBindIP(defaultHost); configuration.getGlobal().getAPI().setBindIP(defaultHost);
Collection<PolarisConfigModifier> modifiers = modifierList; Collection<PolarisConfigModifier> modifiers = modifierList;
@ -96,13 +94,6 @@ public class PolarisContextProperties {
return configuration; return configuration;
} }
private String getHost() {
if (StringUtils.isNotBlank(localIpAddress)) {
return localIpAddress;
}
return environment.getProperty("spring.cloud.client.ip-address");
}
public String getAddress() { public String getAddress() {
return address; return address;
} }
@ -111,11 +102,11 @@ public class PolarisContextProperties {
this.address = address; this.address = address;
} }
String getLocalIpAddress() { public String getLocalIpAddress() {
return localIpAddress; return localIpAddress;
} }
void setLocalIpAddress(String localIpAddress) { public void setLocalIpAddress(String localIpAddress) {
this.localIpAddress = localIpAddress; this.localIpAddress = localIpAddress;
} }
@ -142,5 +133,4 @@ public class PolarisContextProperties {
public void setService(String service) { public void setService(String service) {
this.service = service; this.service = service;
} }
} }

Loading…
Cancel
Save