diff --git a/CHANGELOG.md b/CHANGELOG.md
index dbd8440bb..e53681b5d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,3 +6,5 @@
- [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)
- [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)
diff --git a/spring-cloud-starter-tencent-polaris-router/pom.xml b/spring-cloud-starter-tencent-polaris-router/pom.xml
index 644612dc0..4e78b9cda 100644
--- a/spring-cloud-starter-tencent-polaris-router/pom.xml
+++ b/spring-cloud-starter-tencent-polaris-router/pom.xml
@@ -19,6 +19,10 @@
com.tencent.cloud
spring-cloud-tencent-polaris-loadbalancer
+
+ com.tencent.cloud
+ spring-cloud-starter-tencent-metadata-transfer
+
@@ -43,7 +47,7 @@
spring-boot-starter-web
true
-
+
diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java
index 5065b09b5..305b4087e 100644
--- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java
+++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterAutoConfiguration.java
@@ -18,11 +18,13 @@
package com.tencent.cloud.polaris.router.config;
+import java.util.List;
+
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
import com.tencent.cloud.polaris.context.ServiceRuleManager;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
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.spi.RouterLabelResolver;
@@ -45,10 +47,10 @@ import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;
public class RouterAutoConfiguration {
@Bean
- public RouterLabelInterceptor routerLabelInterceptor(@Nullable RouterLabelResolver resolver,
+ public RouterLabelFeignInterceptor routerLabelInterceptor(@Nullable List routerLabelResolvers,
MetadataLocalProperties metadataLocalProperties,
RouterRuleLabelResolver routerRuleLabelResolver) {
- return new RouterLabelInterceptor(resolver, metadataLocalProperties, routerRuleLabelResolver);
+ return new RouterLabelFeignInterceptor(routerLabelResolvers, metadataLocalProperties, routerRuleLabelResolver);
}
@Bean
diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelInterceptor.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java
similarity index 79%
rename from spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelInterceptor.java
rename to spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java
index 48c3fb667..a8d2a5659 100644
--- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelInterceptor.java
+++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/feign/RouterLabelFeignInterceptor.java
@@ -19,7 +19,9 @@
package com.tencent.cloud.polaris.router.feign;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -44,17 +46,23 @@ import org.springframework.util.CollectionUtils;
*
*@author lepdou 2022-05-12
*/
-public class RouterLabelInterceptor implements RequestInterceptor, Ordered {
- private static final Logger LOGGER = LoggerFactory.getLogger(RouterLabelInterceptor.class);
+public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered {
+ private static final Logger LOGGER = LoggerFactory.getLogger(RouterLabelFeignInterceptor.class);
- private final RouterLabelResolver resolver;
+ private final List routerLabelResolvers;
private final MetadataLocalProperties metadataLocalProperties;
private final RouterRuleLabelResolver routerRuleLabelResolver;
- public RouterLabelInterceptor(RouterLabelResolver resolver,
+ public RouterLabelFeignInterceptor(List routerLabelResolvers,
MetadataLocalProperties metadataLocalProperties,
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.routerRuleLabelResolver = routerRuleLabelResolver;
}
@@ -74,16 +82,18 @@ public class RouterLabelInterceptor implements RequestInterceptor, Ordered {
labels.putAll(transitiveLabels);
// labels from request
- if (resolver != null) {
- try {
- Map customResolvedLabels = resolver.resolve(requestTemplate);
- if (!CollectionUtils.isEmpty(customResolvedLabels)) {
- labels.putAll(customResolvedLabels);
+ if (!CollectionUtils.isEmpty(routerLabelResolvers)) {
+ routerLabelResolvers.forEach(resolver -> {
+ try {
+ Map customResolvedLabels = resolver.resolve(requestTemplate);
+ 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
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 6fe192003..5bafbd9fb 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
@@ -18,7 +18,10 @@
package com.tencent.cloud.polaris.router.resttemplate;
+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;
@@ -50,12 +53,12 @@ public class PolarisLoadBalancerBeanPostProcessor implements BeanPostProcessor,
if (bean instanceof LoadBalancerInterceptor) {
LoadBalancerRequestFactory requestFactory = this.factory.getBean(LoadBalancerRequestFactory.class);
LoadBalancerClient loadBalancerClient = this.factory.getBean(LoadBalancerClient.class);
- RouterLabelResolver routerLabelResolver = this.factory.getBean(RouterLabelResolver.class);
+ List routerLabelResolvers = BeanFactoryUtils.getBeans(factory, RouterLabelResolver.class);
MetadataLocalProperties metadataLocalProperties = this.factory.getBean(MetadataLocalProperties.class);
RouterRuleLabelResolver routerRuleLabelResolver = this.factory.getBean(RouterRuleLabelResolver.class);
return new PolarisLoadBalancerInterceptor(loadBalancerClient, requestFactory,
- routerLabelResolver, metadataLocalProperties, routerRuleLabelResolver);
+ routerLabelResolvers, metadataLocalProperties, routerRuleLabelResolver);
}
return bean;
}
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 a432830b3..938652497 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
@@ -21,7 +21,9 @@ package com.tencent.cloud.polaris.router.resttemplate;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
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.LoadBalancerRequestFactory;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
+import org.springframework.core.Ordered;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpResponse;
@@ -56,7 +59,7 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor {
private final LoadBalancerClient loadBalancer;
private final LoadBalancerRequestFactory requestFactory;
- private final RouterLabelResolver resolver;
+ private final List routerLabelResolvers;
private final MetadataLocalProperties metadataLocalProperties;
private final RouterRuleLabelResolver routerRuleLabelResolver;
@@ -64,16 +67,23 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor {
public PolarisLoadBalancerInterceptor(LoadBalancerClient loadBalancer,
LoadBalancerRequestFactory requestFactory,
- RouterLabelResolver resolver,
+ List routerLabelResolvers,
MetadataLocalProperties metadataLocalProperties,
RouterRuleLabelResolver routerRuleLabelResolver) {
super(loadBalancer, requestFactory);
this.loadBalancer = loadBalancer;
this.requestFactory = requestFactory;
- this.resolver = resolver;
this.metadataLocalProperties = metadataLocalProperties;
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;
}
@@ -104,16 +114,18 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor {
labels.putAll(transitiveLabels);
// labels from request
- if (resolver != null) {
- try {
- Map customResolvedLabels = resolver.resolve(request, body);
- if (!CollectionUtils.isEmpty(customResolvedLabels)) {
- labels.putAll(customResolvedLabels);
+ if (!CollectionUtils.isEmpty(routerLabelResolvers)) {
+ routerLabelResolvers.forEach(resolver -> {
+ try {
+ Map customResolvedLabels = resolver.resolve(request, body);
+ 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
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/RouterLabelResolver.java
index 8b2f394d5..49b9ccf4c 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/RouterLabelResolver.java
@@ -22,6 +22,7 @@ import java.util.Map;
import feign.RequestTemplate;
+import org.springframework.core.Ordered;
import org.springframework.http.HttpRequest;
/**
@@ -29,7 +30,7 @@ import org.springframework.http.HttpRequest;
*
* @author lepdou 2022-05-11
*/
-public interface RouterLabelResolver {
+public interface RouterLabelResolver extends Ordered {
/**
* resolve labels from feign request.
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java
new file mode 100644
index 000000000..715a154fc
--- /dev/null
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java
@@ -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 List getBeans(BeanFactory beanFactory, Class 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());
+ }
+}
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 0eb90aa69..bd289abb9 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
@@ -57,4 +57,9 @@ public class CustomRouterLabelResolver implements RouterLabelResolver {
labels.put("user", user.getName());
return labels;
}
+
+ @Override
+ public int getOrder() {
+ return 0;
+ }
}