1. fix router rest template strong dependency on RouterLabelResolver

2. optimize RouterLabelResolver to list
3. add metadata-transfer dependency for router
pull/196/head
lepdou 3 years ago committed by Haotian Zhang
parent 7e847b81a1
commit d6e2923905

@ -6,3 +6,5 @@
- [Feature: Router support request label.](https://github.com/Tencent/spring-cloud-tencent/pull/165) - [Feature: Router support request label.](https://github.com/Tencent/spring-cloud-tencent/pull/165)
- [Feature: Support router expression label](https://github.com/Tencent/spring-cloud-tencent/pull/190) - [Feature: Support router expression label](https://github.com/Tencent/spring-cloud-tencent/pull/190)
- [Add metadata transfer example.](https://github.com/Tencent/spring-cloud-tencent/pull/184) - [Add metadata transfer example.](https://github.com/Tencent/spring-cloud-tencent/pull/184)
- [Feature: Support metadata router.](https://github.com/Tencent/spring-cloud-tencent/pull/191)
- [Feature: Misc optimize metadata router.](https://github.com/Tencent/spring-cloud-tencent/pull/192)

@ -19,6 +19,10 @@
<groupId>com.tencent.cloud</groupId> <groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-polaris-loadbalancer</artifactId> <artifactId>spring-cloud-tencent-polaris-loadbalancer</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-metadata-transfer</artifactId>
</dependency>
<!-- Spring Cloud Tencent dependencies end --> <!-- Spring Cloud Tencent dependencies end -->
<!-- Polaris dependencies start --> <!-- Polaris dependencies start -->

@ -18,11 +18,13 @@
package com.tencent.cloud.polaris.router.config; package com.tencent.cloud.polaris.router.config;
import java.util.List;
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
import com.tencent.cloud.polaris.context.ServiceRuleManager; import com.tencent.cloud.polaris.context.ServiceRuleManager;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.feign.PolarisCachingSpringLoadBalanceFactory; import com.tencent.cloud.polaris.router.feign.PolarisCachingSpringLoadBalanceFactory;
import com.tencent.cloud.polaris.router.feign.RouterLabelInterceptor; import com.tencent.cloud.polaris.router.feign.RouterLabelFeignInterceptor;
import com.tencent.cloud.polaris.router.resttemplate.PolarisLoadBalancerBeanPostProcessor; import com.tencent.cloud.polaris.router.resttemplate.PolarisLoadBalancerBeanPostProcessor;
import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; import com.tencent.cloud.polaris.router.spi.RouterLabelResolver;
@ -45,10 +47,10 @@ import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;
public class RouterAutoConfiguration { public class RouterAutoConfiguration {
@Bean @Bean
public RouterLabelInterceptor routerLabelInterceptor(@Nullable RouterLabelResolver resolver, public RouterLabelFeignInterceptor routerLabelInterceptor(@Nullable List<RouterLabelResolver> routerLabelResolvers,
MetadataLocalProperties metadataLocalProperties, MetadataLocalProperties metadataLocalProperties,
RouterRuleLabelResolver routerRuleLabelResolver) { RouterRuleLabelResolver routerRuleLabelResolver) {
return new RouterLabelInterceptor(resolver, metadataLocalProperties, routerRuleLabelResolver); return new RouterLabelFeignInterceptor(routerLabelResolvers, metadataLocalProperties, routerRuleLabelResolver);
} }
@Bean @Bean

@ -19,7 +19,9 @@
package com.tencent.cloud.polaris.router.feign; package com.tencent.cloud.polaris.router.feign;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -44,17 +46,23 @@ import org.springframework.util.CollectionUtils;
* *
*@author lepdou 2022-05-12 *@author lepdou 2022-05-12
*/ */
public class RouterLabelInterceptor implements RequestInterceptor, Ordered { public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered {
private static final Logger LOGGER = LoggerFactory.getLogger(RouterLabelInterceptor.class); private static final Logger LOGGER = LoggerFactory.getLogger(RouterLabelFeignInterceptor.class);
private final RouterLabelResolver resolver; private final List<RouterLabelResolver> routerLabelResolvers;
private final MetadataLocalProperties metadataLocalProperties; private final MetadataLocalProperties metadataLocalProperties;
private final RouterRuleLabelResolver routerRuleLabelResolver; private final RouterRuleLabelResolver routerRuleLabelResolver;
public RouterLabelInterceptor(RouterLabelResolver resolver, public RouterLabelFeignInterceptor(List<RouterLabelResolver> routerLabelResolvers,
MetadataLocalProperties metadataLocalProperties, MetadataLocalProperties metadataLocalProperties,
RouterRuleLabelResolver routerRuleLabelResolver) { RouterRuleLabelResolver routerRuleLabelResolver) {
this.resolver = resolver; if (!CollectionUtils.isEmpty(routerLabelResolvers)) {
routerLabelResolvers.sort(Comparator.comparingInt(Ordered::getOrder));
this.routerLabelResolvers = routerLabelResolvers;
}
else {
this.routerLabelResolvers = null;
}
this.metadataLocalProperties = metadataLocalProperties; this.metadataLocalProperties = metadataLocalProperties;
this.routerRuleLabelResolver = routerRuleLabelResolver; this.routerRuleLabelResolver = routerRuleLabelResolver;
} }
@ -74,16 +82,18 @@ public class RouterLabelInterceptor implements RequestInterceptor, Ordered {
labels.putAll(transitiveLabels); labels.putAll(transitiveLabels);
// labels from request // labels from request
if (resolver != null) { if (!CollectionUtils.isEmpty(routerLabelResolvers)) {
try { routerLabelResolvers.forEach(resolver -> {
Map<String, String> customResolvedLabels = resolver.resolve(requestTemplate); try {
if (!CollectionUtils.isEmpty(customResolvedLabels)) { Map<String, String> customResolvedLabels = resolver.resolve(requestTemplate);
labels.putAll(customResolvedLabels); if (!CollectionUtils.isEmpty(customResolvedLabels)) {
labels.putAll(customResolvedLabels);
}
}
catch (Throwable t) {
LOGGER.error("[SCT][Router] revoke RouterLabelResolver occur some exception. ", t);
} }
} });
catch (Throwable t) {
LOGGER.error("[SCT][Router] revoke RouterLabelResolver occur some exception. ", t);
}
} }
// labels from rule expression // labels from rule expression

@ -18,7 +18,10 @@
package com.tencent.cloud.polaris.router.resttemplate; package com.tencent.cloud.polaris.router.resttemplate;
import java.util.List;
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; 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.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.RouterLabelResolver; import com.tencent.cloud.polaris.router.spi.RouterLabelResolver;
@ -50,12 +53,12 @@ public class PolarisLoadBalancerBeanPostProcessor implements BeanPostProcessor,
if (bean instanceof LoadBalancerInterceptor) { if (bean instanceof LoadBalancerInterceptor) {
LoadBalancerRequestFactory requestFactory = this.factory.getBean(LoadBalancerRequestFactory.class); LoadBalancerRequestFactory requestFactory = this.factory.getBean(LoadBalancerRequestFactory.class);
LoadBalancerClient loadBalancerClient = this.factory.getBean(LoadBalancerClient.class); LoadBalancerClient loadBalancerClient = this.factory.getBean(LoadBalancerClient.class);
RouterLabelResolver routerLabelResolver = this.factory.getBean(RouterLabelResolver.class); List<RouterLabelResolver> routerLabelResolvers = BeanFactoryUtils.getBeans(factory, RouterLabelResolver.class);
MetadataLocalProperties metadataLocalProperties = this.factory.getBean(MetadataLocalProperties.class); MetadataLocalProperties metadataLocalProperties = this.factory.getBean(MetadataLocalProperties.class);
RouterRuleLabelResolver routerRuleLabelResolver = this.factory.getBean(RouterRuleLabelResolver.class); RouterRuleLabelResolver routerRuleLabelResolver = this.factory.getBean(RouterRuleLabelResolver.class);
return new PolarisLoadBalancerInterceptor(loadBalancerClient, requestFactory, return new PolarisLoadBalancerInterceptor(loadBalancerClient, requestFactory,
routerLabelResolver, metadataLocalProperties, routerRuleLabelResolver); routerLabelResolvers, metadataLocalProperties, routerRuleLabelResolver);
} }
return bean; return bean;
} }

@ -21,7 +21,9 @@ package com.tencent.cloud.polaris.router.resttemplate;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -39,6 +41,7 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor; import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory; import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient; import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.core.Ordered;
import org.springframework.http.HttpRequest; import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
@ -56,7 +59,7 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor {
private final LoadBalancerClient loadBalancer; private final LoadBalancerClient loadBalancer;
private final LoadBalancerRequestFactory requestFactory; private final LoadBalancerRequestFactory requestFactory;
private final RouterLabelResolver resolver; private final List<RouterLabelResolver> routerLabelResolvers;
private final MetadataLocalProperties metadataLocalProperties; private final MetadataLocalProperties metadataLocalProperties;
private final RouterRuleLabelResolver routerRuleLabelResolver; private final RouterRuleLabelResolver routerRuleLabelResolver;
@ -64,16 +67,23 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor {
public PolarisLoadBalancerInterceptor(LoadBalancerClient loadBalancer, public PolarisLoadBalancerInterceptor(LoadBalancerClient loadBalancer,
LoadBalancerRequestFactory requestFactory, LoadBalancerRequestFactory requestFactory,
RouterLabelResolver resolver, List<RouterLabelResolver> routerLabelResolvers,
MetadataLocalProperties metadataLocalProperties, MetadataLocalProperties metadataLocalProperties,
RouterRuleLabelResolver routerRuleLabelResolver) { RouterRuleLabelResolver routerRuleLabelResolver) {
super(loadBalancer, requestFactory); super(loadBalancer, requestFactory);
this.loadBalancer = loadBalancer; this.loadBalancer = loadBalancer;
this.requestFactory = requestFactory; this.requestFactory = requestFactory;
this.resolver = resolver;
this.metadataLocalProperties = metadataLocalProperties; this.metadataLocalProperties = metadataLocalProperties;
this.routerRuleLabelResolver = routerRuleLabelResolver; this.routerRuleLabelResolver = routerRuleLabelResolver;
if (!CollectionUtils.isEmpty(routerLabelResolvers)) {
routerLabelResolvers.sort(Comparator.comparingInt(Ordered::getOrder));
this.routerLabelResolvers = routerLabelResolvers;
}
else {
this.routerLabelResolvers = null;
}
this.isRibbonLoadBalanceClient = loadBalancer instanceof RibbonLoadBalancerClient; this.isRibbonLoadBalanceClient = loadBalancer instanceof RibbonLoadBalancerClient;
} }
@ -104,16 +114,18 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor {
labels.putAll(transitiveLabels); labels.putAll(transitiveLabels);
// labels from request // labels from request
if (resolver != null) { if (!CollectionUtils.isEmpty(routerLabelResolvers)) {
try { routerLabelResolvers.forEach(resolver -> {
Map<String, String> customResolvedLabels = resolver.resolve(request, body); try {
if (!CollectionUtils.isEmpty(customResolvedLabels)) { Map<String, String> customResolvedLabels = resolver.resolve(request, body);
labels.putAll(customResolvedLabels); if (!CollectionUtils.isEmpty(customResolvedLabels)) {
labels.putAll(customResolvedLabels);
}
}
catch (Throwable t) {
LOGGER.error("[SCT][Router] revoke RouterLabelResolver occur some exception. ", t);
} }
} });
catch (Throwable t) {
LOGGER.error("[SCT][Router] revoke RouterLabelResolver occur some exception. ", t);
}
} }
// labels from rule expression // labels from rule expression

@ -22,6 +22,7 @@ import java.util.Map;
import feign.RequestTemplate; import feign.RequestTemplate;
import org.springframework.core.Ordered;
import org.springframework.http.HttpRequest; import org.springframework.http.HttpRequest;
/** /**
@ -29,7 +30,7 @@ import org.springframework.http.HttpRequest;
* *
* @author lepdou 2022-05-11 * @author lepdou 2022-05-11
*/ */
public interface RouterLabelResolver { public interface RouterLabelResolver extends Ordered {
/** /**
* resolve labels from feign request. * resolve labels from feign request.

@ -0,0 +1,51 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
package com.tencent.cloud.common.util;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
/**
* the utils for bean factory.
* @author lepdou 2022-05-23
*/
public class BeanFactoryUtils {
public static <T> List<T> getBeans(BeanFactory beanFactory, Class<T> requiredType) {
if (!(beanFactory instanceof DefaultListableBeanFactory)) {
throw new RuntimeException("bean factory not support get list bean. factory type = " + beanFactory.getClass()
.getName());
}
String[] beanNames = ((DefaultListableBeanFactory) beanFactory).getBeanNamesForType(requiredType);
if (beanNames.length == 0) {
return Collections.emptyList();
}
return Arrays.stream(beanNames).map(
beanName -> beanFactory.getBean(beanName, requiredType)
).collect(Collectors.toList());
}
}

@ -57,4 +57,9 @@ public class CustomRouterLabelResolver implements RouterLabelResolver {
labels.put("user", user.getName()); labels.put("user", user.getName());
return labels; return labels;
} }
@Override
public int getOrder() {
return 0;
}
} }

Loading…
Cancel
Save