From b6e0e0e11d613b9014c3920fcf0d45229a0c9ca7 Mon Sep 17 00:00:00 2001
From: Fishtail <49390359+fuyuwei01@users.noreply.github.com>
Date: Tue, 16 Jul 2024 16:20:43 +0800
Subject: [PATCH] feat: add polaris router lane examples (#1340)
---
CHANGELOG.md | 1 +
.../polaris/router/RouterConfigModifier.java | 20 +++
...RouterConfigModifierAutoConfiguration.java | 5 +-
.../PolarisNearByRouterProperties.java | 11 ++
...itional-spring-configuration-metadata.json | 8 +-
.../RouterBootstrapAutoConfigurationTest.java | 15 +++
.../PolarisNearByRouterPropertiesTest.java | 2 +-
spring-cloud-tencent-dependencies/pom.xml | 2 +-
.../pom.xml | 31 +++++
.../pom.xml | 70 +++++++++++
.../cloud/lane/callee/CustomMetadata.java | 47 ++++++++
.../callee/LaneRouterCalleeApplication.java | 29 +++++
.../callee/LaneRouterCalleeController.java | 91 ++++++++++++++
.../src/main/resources/application.yml | 36 ++++++
.../pom.xml | 75 ++++++++++++
.../cloud/lane/caller/CustomMetadata.java | 47 ++++++++
.../lane/caller/LaneRouterCalleeService.java | 41 +++++++
.../caller/LaneRouterCallerApplication.java | 57 +++++++++
.../caller/LaneRouterCallerController.java | 114 ++++++++++++++++++
.../src/main/resources/application.yml | 42 +++++++
.../router-grayrelease-lane-gateway/pom.xml | 53 ++++++++
.../gateway/LaneRouterGatewayApplication.java | 29 +++++
.../src/main/resources/application.yml | 37 ++++++
spring-cloud-tencent-examples/pom.xml | 1 +
24 files changed, 859 insertions(+), 5 deletions(-)
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/pom.xml
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/pom.xml
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/CustomMetadata.java
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/LaneRouterCalleeApplication.java
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/LaneRouterCalleeController.java
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/resources/application.yml
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/pom.xml
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/CustomMetadata.java
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCalleeService.java
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCallerApplication.java
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCallerController.java
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/resources/application.yml
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/pom.xml
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/src/main/java/com/tencent/cloud/polaris/router/lane/gateway/LaneRouterGatewayApplication.java
create mode 100644 spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/src/main/resources/application.yml
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ebbf6b5e..9b6bd6a07 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,3 +7,4 @@
- [fix: fix RouterLabelRestTemplateInterceptor add response headers exception with httpclient5.](https://github.com/Tencent/spring-cloud-tencent/pull/1337)
- [feat: support lossless online/offline](https://github.com/Tencent/spring-cloud-tencent/pull/1338)
- [feat: support lane router](https://github.com/Tencent/spring-cloud-tencent/pull/1339)
+- [feat: add lane router examples](https://github.com/Tencent/spring-cloud-tencent/pull/1340)
\ No newline at end of file
diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConfigModifier.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConfigModifier.java
index 9f6d1e7d9..455578050 100644
--- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConfigModifier.java
+++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/RouterConfigModifier.java
@@ -20,9 +20,13 @@
import com.tencent.cloud.common.constant.OrderConstant;
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
+import com.tencent.cloud.polaris.router.config.properties.PolarisNearByRouterProperties;
import com.tencent.polaris.api.config.consumer.ServiceRouterConfig;
+import com.tencent.polaris.api.plugin.route.LocationLevel;
import com.tencent.polaris.factory.config.ConfigurationImpl;
import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig;
+import com.tencent.polaris.plugins.router.nearby.NearbyRouterConfig;
+import org.apache.commons.lang.StringUtils;
/**
* RouterConfigModifier.
@@ -31,6 +35,12 @@
*/
public class RouterConfigModifier implements PolarisConfigModifier {
+ private final PolarisNearByRouterProperties polarisNearByRouterProperties;
+
+ public RouterConfigModifier(PolarisNearByRouterProperties polarisNearByRouterProperties) {
+ this.polarisNearByRouterProperties = polarisNearByRouterProperties;
+ }
+
@Override
public void modify(ConfigurationImpl configuration) {
// Set excludeCircuitBreakInstances to false
@@ -41,6 +51,16 @@ public void modify(ConfigurationImpl configuration) {
// Update modified config to source properties
configuration.getConsumer().getServiceRouter()
.setPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, recoverRouterConfig);
+
+ if (StringUtils.isNotBlank(polarisNearByRouterProperties.getMatchLevel())) {
+ LocationLevel locationLevel = LocationLevel.valueOf(polarisNearByRouterProperties.getMatchLevel());
+ NearbyRouterConfig nearbyRouterConfig = configuration.getConsumer().getServiceRouter().getPluginConfig(
+ ServiceRouterConfig.DEFAULT_ROUTER_NEARBY, NearbyRouterConfig.class);
+ nearbyRouterConfig.setMatchLevel(locationLevel);
+ configuration.getConsumer().getServiceRouter()
+ .setPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_NEARBY, nearbyRouterConfig);
+ }
+
}
@Override
diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterConfigModifierAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterConfigModifierAutoConfiguration.java
index 82b85f0f3..782135dcb 100644
--- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterConfigModifierAutoConfiguration.java
+++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/RouterConfigModifierAutoConfiguration.java
@@ -19,6 +19,7 @@
package com.tencent.cloud.polaris.router.config;
import com.tencent.cloud.polaris.router.RouterConfigModifier;
+import com.tencent.cloud.polaris.router.config.properties.PolarisNearByRouterProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
@@ -35,8 +36,8 @@ public class RouterConfigModifierAutoConfiguration {
@Bean
@ConditionalOnMissingBean
- public RouterConfigModifier routerConfigModifier() {
- return new RouterConfigModifier();
+ public RouterConfigModifier routerConfigModifier(PolarisNearByRouterProperties polarisNearByRouterProperties) {
+ return new RouterConfigModifier(polarisNearByRouterProperties);
}
}
diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/properties/PolarisNearByRouterProperties.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/properties/PolarisNearByRouterProperties.java
index 0ca119564..df861e19a 100644
--- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/properties/PolarisNearByRouterProperties.java
+++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/properties/PolarisNearByRouterProperties.java
@@ -29,6 +29,8 @@ public class PolarisNearByRouterProperties {
private boolean enabled = true;
+ private String matchLevel;
+
public boolean isEnabled() {
return enabled;
}
@@ -37,10 +39,19 @@ public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
+ public String getMatchLevel() {
+ return matchLevel;
+ }
+
+ public void setMatchLevel(String matchLevel) {
+ this.matchLevel = matchLevel;
+ }
+
@Override
public String toString() {
return "PolarisNearByRouterProperties{" +
"enabled=" + enabled +
+ ", matchLevel='" + matchLevel + '\'' +
'}';
}
}
diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/additional-spring-configuration-metadata.json
index 0c935af6e..c5a47d1db 100644
--- a/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/additional-spring-configuration-metadata.json
+++ b/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/additional-spring-configuration-metadata.json
@@ -10,7 +10,13 @@
"name": "spring.cloud.polaris.router.nearby-router.enabled",
"type": "java.lang.Boolean",
"defaultValue": true,
- "description": "the switch for near by router."
+ "description": "the switch for nearby router."
+ },
+ {
+ "name": "spring.cloud.polaris.router.nearby-router.matchLevel",
+ "type": "java.lang.String",
+ "defaultValue": "zone",
+ "description": "the match level for nearby router, options can be region/zone/campus."
},
{
"name": "spring.cloud.polaris.router.rule-router.enabled",
diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/RouterBootstrapAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/RouterBootstrapAutoConfigurationTest.java
index bf989d9a8..f10d9ada4 100644
--- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/RouterBootstrapAutoConfigurationTest.java
+++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/RouterBootstrapAutoConfigurationTest.java
@@ -20,7 +20,14 @@
import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
import com.tencent.cloud.polaris.router.RouterConfigModifier;
+import com.tencent.cloud.polaris.router.config.properties.PolarisNearByRouterProperties;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration;
+import com.tencent.polaris.api.config.Configuration;
+import com.tencent.polaris.api.config.consumer.ServiceRouterConfig;
+import com.tencent.polaris.factory.ConfigAPIFactory;
+import com.tencent.polaris.factory.config.ConfigurationImpl;
+import com.tencent.polaris.plugins.router.nearby.NearbyRouterConfig;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
@@ -38,15 +45,23 @@ public class RouterBootstrapAutoConfigurationTest {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
PolarisContextAutoConfiguration.class,
+ PolarisNearByRouterProperties.class,
RpcEnhancementAutoConfiguration.class,
RouterBootstrapAutoConfiguration.class))
.withPropertyValues("spring.cloud.polaris.enabled=true")
+ .withPropertyValues("spring.cloud.polaris.router.nearby-router.matchLevel=campus")
.withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true");
@Test
public void testDefaultInitialization() {
this.contextRunner.run(context -> {
assertThat(context).hasSingleBean(RouterConfigModifier.class);
+ RouterConfigModifier routerConfigModifier = (RouterConfigModifier) context.getBean("routerConfigModifier");
+ Configuration configuration = ConfigAPIFactory.defaultConfig();
+ routerConfigModifier.modify((ConfigurationImpl) configuration);
+ NearbyRouterConfig nearbyRouterConfig = configuration.getConsumer().getServiceRouter().getPluginConfig(
+ ServiceRouterConfig.DEFAULT_ROUTER_NEARBY, NearbyRouterConfig.class);
+ Assertions.assertEquals("campus", nearbyRouterConfig.getMatchLevel().name());
});
}
}
diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/properties/PolarisNearByRouterPropertiesTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/properties/PolarisNearByRouterPropertiesTest.java
index 572b6f92b..379fbf7e9 100644
--- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/properties/PolarisNearByRouterPropertiesTest.java
+++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/properties/PolarisNearByRouterPropertiesTest.java
@@ -49,6 +49,6 @@ public void setEnabled() {
@Test
public void testToString() {
assertThat(properties.toString())
- .isEqualTo("PolarisNearByRouterProperties{enabled=true}");
+ .isEqualTo("PolarisNearByRouterProperties{enabled=true, matchLevel='null'}");
}
}
diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml
index 336d1435a..01b711d9d 100644
--- a/spring-cloud-tencent-dependencies/pom.xml
+++ b/spring-cloud-tencent-dependencies/pom.xml
@@ -74,7 +74,7 @@
1.14.0-2021.0.9-SNAPSHOT
- 1.15.3
+ 1.15.4-SNAPSHOT
32.0.1-jre
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/pom.xml b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/pom.xml
new file mode 100644
index 000000000..5b5eb0a57
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/pom.xml
@@ -0,0 +1,31 @@
+
+
+
+ spring-cloud-tencent-examples
+ com.tencent.cloud
+ ${revision}
+ ../pom.xml
+
+
+ router-grayrelease-lane-gateway
+ router-grayrelease-lane-caller-service
+ router-grayrelease-lane-callee-service
+
+ 4.0.0
+
+ com.tencent.polaris
+ polaris-router-grayrelease-lane-example
+
+ pom
+ Spring Cloud Tencent Polaris Router Lane Example
+ Example of Spring Cloud Tencent Polaris Router Lane
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-bootstrap
+
+
+
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/pom.xml b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/pom.xml
new file mode 100644
index 000000000..3431f03d0
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/pom.xml
@@ -0,0 +1,70 @@
+
+
+ 4.0.0
+
+ com.tencent.polaris
+ polaris-router-grayrelease-lane-example
+ ${revision}
+ ../pom.xml
+
+
+ route-grayrelease-lane-callee-service
+
+
+
+ spring-cloud-starter-tencent-polaris-discovery
+ com.tencent.cloud
+
+
+
+ com.tencent.cloud
+ spring-cloud-starter-tencent-polaris-router
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.0
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/CustomMetadata.java b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/CustomMetadata.java
new file mode 100644
index 000000000..ba623274e
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/CustomMetadata.java
@@ -0,0 +1,47 @@
+/*
+ * 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.lane.callee;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.tencent.cloud.common.spi.InstanceMetadataProvider;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * Custom metadata for instance.
+ *
+ * @author Haotian Zhang
+ */
+@Component
+public class CustomMetadata implements InstanceMetadataProvider {
+
+ @Value("${service.lane:base}")
+ private String lane;
+
+ @Override
+ public Map getMetadata() {
+ Map metadata = new HashMap<>();
+ if (!"base".equals(lane)) {
+ metadata.put("lane", lane);
+ }
+ return metadata;
+ }
+}
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/LaneRouterCalleeApplication.java b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/LaneRouterCalleeApplication.java
new file mode 100644
index 000000000..5ffabdd2c
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/LaneRouterCalleeApplication.java
@@ -0,0 +1,29 @@
+/*
+ * 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.lane.callee;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class LaneRouterCalleeApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(LaneRouterCalleeApplication.class, args);
+ }
+}
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/LaneRouterCalleeController.java b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/LaneRouterCalleeController.java
new file mode 100644
index 000000000..9ff9f0d49
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/java/com/tencent/cloud/lane/callee/LaneRouterCalleeController.java
@@ -0,0 +1,91 @@
+/*
+ * 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.lane.callee;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+import com.tencent.cloud.common.constant.MetadataConstant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
+
+@RestController
+@RequestMapping("/lane/callee")
+public class LaneRouterCalleeController {
+
+ private static final Logger LOG = LoggerFactory.getLogger(LaneRouterCalleeController.class);
+
+ @Value("${server.port:0}")
+ private int port;
+
+ @Value("${spring.cloud.client.ip-address:127.0.0.1}")
+ private String ip;
+
+ @Value("${appName:${spring.application.name}}")
+ private String appName;
+
+ @Value("${service.lane:base}")
+ private String lane;
+
+ /**
+ * Get sum of two value.
+ * @param value1 value 1
+ * @param value2 value 2
+ * @return sum
+ */
+ @GetMapping("/sum")
+ public String sum(@RequestParam int value1, @RequestParam int value2) {
+ LOG.info("Lane {} Callee Service [{}:{}] is called and sum is [{}].", lane, ip, port, value1 + value2);
+ return String.format("Lane %s Callee Service [%s:%s] is called and sum is [%s].", lane, ip, port, value1 + value2);
+ }
+
+ /**
+ * Get information of callee.
+ * @return information of callee
+ */
+ @GetMapping("/info")
+ public String info() {
+ LOG.info("Lane {} [{}] Service [{}:{}] is called.", lane, appName, ip, port);
+ return String.format("Lane %s [%s] Service [%s:%s] is called.", lane, appName, ip, port);
+ }
+
+ /**
+ * Get metadata in HTTP header.
+ *
+ * @param metadataStr metadata string
+ * @return metadata in HTTP header
+ * @throws UnsupportedEncodingException encoding exception
+ */
+ @RequestMapping("/echo")
+ public String echoHeader(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String metadataStr)
+ throws UnsupportedEncodingException {
+ LOG.info(URLDecoder.decode(metadataStr, UTF_8));
+ metadataStr = URLDecoder.decode(metadataStr, UTF_8);
+ return String.format("Lane %s: %s", lane, metadataStr);
+ }
+
+}
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/resources/application.yml b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/resources/application.yml
new file mode 100644
index 000000000..29d9d9c96
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-callee-service/src/main/resources/application.yml
@@ -0,0 +1,36 @@
+server:
+ port: 48093
+spring:
+ application:
+ name: LaneCalleeService
+ cloud:
+ polaris:
+ address: grpc://119.91.66.223:8091
+ namespace: default
+ enabled: true
+ discovery:
+ enabled: true
+ register: true
+ contract:
+ exposure: true
+ report:
+ enabled: true
+ stat:
+ enabled: true
+ port: 28083
+ # pushgateway:
+ # enabled: true
+ # address: 127.0.0.1:9091
+ config:
+ address: grpc://9.134.5.52:8093
+ auto-refresh: true
+ groups:
+ - name: ${spring.application.name}
+ files: [ "config/callee.properties" ]
+management:
+ endpoints:
+ web:
+ exposure:
+ include:
+ - polaris-discovery
+ - polaris-config
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/pom.xml b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/pom.xml
new file mode 100644
index 000000000..f1a48d81b
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/pom.xml
@@ -0,0 +1,75 @@
+
+
+ 4.0.0
+
+ com.tencent.polaris
+ polaris-router-grayrelease-lane-example
+ ${revision}
+ ../pom.xml
+
+
+ route-grayrelease-lane-caller-service
+
+
+
+ spring-cloud-starter-tencent-polaris-discovery
+ com.tencent.cloud
+
+
+
+ com.tencent.cloud
+ spring-cloud-starter-tencent-polaris-router
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.0
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/CustomMetadata.java b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/CustomMetadata.java
new file mode 100644
index 000000000..51939912e
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/CustomMetadata.java
@@ -0,0 +1,47 @@
+/*
+ * 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.lane.caller;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.tencent.cloud.common.spi.InstanceMetadataProvider;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * Custom metadata for instance.
+ *
+ * @author Haotian Zhang
+ */
+@Component
+public class CustomMetadata implements InstanceMetadataProvider {
+
+ @Value("${service.lane:base}")
+ private String lane;
+
+ @Override
+ public Map getMetadata() {
+ Map metadata = new HashMap<>();
+ if (!"base".equals(lane)) {
+ metadata.put("lane", lane);
+ }
+ return metadata;
+ }
+}
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCalleeService.java b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCalleeService.java
new file mode 100644
index 000000000..b057f4ffe
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCalleeService.java
@@ -0,0 +1,41 @@
+/*
+ * 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.lane.caller;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * Quickstart callee feign client.
+ *
+ * @author Haotian Zhang
+ */
+@FeignClient("LaneCalleeService")
+public interface LaneRouterCalleeService {
+
+ /**
+ * Get sum of two value.
+ *
+ * @param value1 value 1
+ * @param value2 value 2
+ * @return sum
+ */
+ @GetMapping("/lane/callee/sum")
+ String sum(@RequestParam("value1") int value1, @RequestParam("value2") int value2);
+}
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCallerApplication.java b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCallerApplication.java
new file mode 100644
index 000000000..6b387c7b1
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCallerApplication.java
@@ -0,0 +1,57 @@
+/*
+ * 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.lane.caller;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.util.DefaultUriBuilderFactory;
+
+@SpringBootApplication
+@EnableFeignClients
+public class LaneRouterCallerApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(LaneRouterCallerApplication.class, args);
+ }
+
+ @Bean
+ @LoadBalanced
+ public RestTemplate restTemplate() {
+ return new RestTemplate();
+ }
+
+ @Bean
+ @LoadBalanced
+ public RestTemplate defaultRestTemplate() {
+ DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://QuickstartCalleeService");
+ RestTemplate restTemplate = new RestTemplate();
+ restTemplate.setUriTemplateHandler(uriBuilderFactory);
+ return restTemplate;
+ }
+
+ @LoadBalanced
+ @Bean
+ WebClient.Builder webClientBuilder() {
+ return WebClient.builder().baseUrl("http://QuickstartCalleeService");
+ }
+}
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCallerController.java b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCallerController.java
new file mode 100644
index 000000000..6384a5fab
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/java/com/tencent/cloud/lane/caller/LaneRouterCallerController.java
@@ -0,0 +1,114 @@
+/*
+ * 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.lane.caller;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import reactor.core.publisher.Mono;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.reactive.function.client.WebClient;
+
+@RestController
+@RequestMapping("/lane/caller")
+public class LaneRouterCallerController {
+
+ private static final Logger LOG = LoggerFactory.getLogger(LaneRouterCallerController.class);
+
+ @Value("${server.port:0}")
+ private int port;
+
+ @Value("${spring.cloud.client.ip-address:127.0.0.1}")
+ private String ip;
+
+ @Autowired
+ private RestTemplate restTemplate;
+
+ @Autowired
+ private LaneRouterCalleeService quickstartCalleeService;
+
+ @Autowired
+ private WebClient.Builder webClientBuilder;
+
+ @Value("${service.lane:base}")
+ private String lane;
+
+ @Value("${appName:${spring.application.name}}")
+ private String appName;
+
+ /**
+ * Get sum of two value.
+ * @param value1 value 1
+ * @param value2 value 2
+ * @return sum
+ */
+ @GetMapping("/feign")
+ public String feign(@RequestParam int value1, @RequestParam int value2) {
+ String value = quickstartCalleeService.sum(value1, value2);
+ return String.format("Lane %s Caller Service %s: %s", lane, appName, value);
+ }
+
+ /**
+ * Get information of callee.
+ * @return information of callee
+ */
+ @GetMapping("/rest")
+ public String rest() {
+ String value = restTemplate.getForObject("http://QuickstartCalleeService/quickstart/callee/info", String.class);
+ return String.format("Lane %s Caller Service %s: %s", lane, appName, value);
+ }
+
+ /**
+ * Get information of callee.
+ * @return information of callee
+ */
+ @GetMapping("/webclient")
+ public Mono webclient() {
+ return webClientBuilder
+ .build()
+ .get()
+ .uri("/quickstart/callee/echo")
+ .retrieve()
+ .bodyToMono(String.class);
+ }
+
+ /**
+ * Get information of caller.
+ * @return information of caller
+ */
+ @GetMapping("/info")
+ public String info() {
+ LOG.info("Lane {} [{}] Service [{}:{}] is called.", lane, appName, ip, port);
+ return String.format("Lane %s [%s] Service [%s:%s] is called.", lane, appName, ip, port);
+ }
+
+ /**
+ * health check.
+ * @return health check info
+ */
+ @GetMapping("/healthCheck")
+ public String healthCheck() {
+ return "ok";
+ }
+}
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/resources/application.yml b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/resources/application.yml
new file mode 100644
index 000000000..259358d55
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-caller-service/src/main/resources/application.yml
@@ -0,0 +1,42 @@
+server:
+ port: 48092
+spring:
+ application:
+ name: LaneCallerService
+ cloud:
+ polaris:
+ address: grpc://119.91.66.223:8091
+ namespace: default
+ enabled: true
+ discovery:
+ enabled: true
+ register: true
+ heartbeat:
+ enabled: true
+ health-check-url: /lane/caller/healthCheck
+ contract:
+ exposure: true
+ report:
+ enabled: true
+ circuitbreaker:
+ enabled: true
+ stat:
+ enabled: true
+ port: 28082
+ # pushgateway:
+ # enabled: true
+ # address: 127.0.0.1:9091
+ tencent:
+ rpc-enhancement:
+ enabled: true
+ reporter:
+ enabled: true
+ ignore-internal-server-error: true
+ series: server_error
+ statuses: gateway_timeout, bad_gateway, service_unavailable
+management:
+ endpoints:
+ web:
+ exposure:
+ include:
+ - polaris-discovery
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/pom.xml b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/pom.xml
new file mode 100644
index 000000000..ddfe61927
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+
+ com.tencent.polaris
+ polaris-router-grayrelease-lane-example
+ ${revision}
+ ../pom.xml
+
+
+ router-grayrelease-lane-gateway
+
+
+
+ spring-cloud-starter-tencent-polaris-discovery
+ com.tencent.cloud
+
+
+
+ com.tencent.cloud
+ spring-cloud-starter-tencent-polaris-router
+
+
+
+ com.tencent.cloud
+ spring-cloud-tencent-gateway-plugin
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-gateway
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/src/main/java/com/tencent/cloud/polaris/router/lane/gateway/LaneRouterGatewayApplication.java b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/src/main/java/com/tencent/cloud/polaris/router/lane/gateway/LaneRouterGatewayApplication.java
new file mode 100644
index 000000000..338dd7b01
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/src/main/java/com/tencent/cloud/polaris/router/lane/gateway/LaneRouterGatewayApplication.java
@@ -0,0 +1,29 @@
+/*
+ * 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.lane.gateway;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class LaneRouterGatewayApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(LaneRouterGatewayApplication.class, args);
+ }
+}
diff --git a/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/src/main/resources/application.yml b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/src/main/resources/application.yml
new file mode 100644
index 000000000..5c39a3f50
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-router-grayrelease-lane-example/router-grayrelease-lane-gateway/src/main/resources/application.yml
@@ -0,0 +1,37 @@
+server:
+ port: 48090
+spring:
+ application:
+ name: LaneRouterGatewayService
+ cloud:
+ polaris:
+ address: grpc://119.91.66.223:8091
+ namespace: default
+ enabled: true
+ contract:
+ exposure: true
+ report:
+ enabled: true
+ stat:
+ enabled: true
+ port: 28081
+ gateway:
+ discovery:
+ locator:
+ enabled: true
+ 'predicates[0]':
+ name: Path
+ args:
+ patterns: '''/'' + serviceId + ''/**'''
+ 'filters[0]':
+ name: RewritePath
+ args:
+ regexp: '''/'' + serviceId + ''/(?.*)'''
+ replacement: '''/$\{remaining}'''
+ routes:
+ - id: LaneRouterCallerService
+ uri: lb://LaneCallerService
+ predicates:
+ - Path=/LaneCallerService/**
+ filters:
+ - StripPrefix=1
diff --git a/spring-cloud-tencent-examples/pom.xml b/spring-cloud-tencent-examples/pom.xml
index 0ff219d6b..0bed0196c 100644
--- a/spring-cloud-tencent-examples/pom.xml
+++ b/spring-cloud-tencent-examples/pom.xml
@@ -23,6 +23,7 @@
polaris-config-data-example
quickstart-example
lossless-example
+ polaris-router-grayrelease-lane-example