From 0cf3d21f12615e4384be35413c363615eb2b7204 Mon Sep 17 00:00:00 2001
From: Guoji Lu <63774857+luguoji@users.noreply.github.com>
Date: Tue, 18 Feb 2025 16:47:39 +0800
Subject: [PATCH] feat:support polaris route for gateway mvc (#1493)
---
CHANGELOG.md | 1 +
.../pom.xml | 8 ++
.../config/RouterAutoConfiguration.java | 15 +++
.../scgmvc/RouterLabelMvcFilter.java | 62 ++++++++++++
.../scg/RouterLabelGlobalFilterTest.java | 2 +-
.../scgmvc/RouterLabelMvcFilterTest.java | 97 +++++++++++++++++++
spring-cloud-tencent-dependencies/pom.xml | 2 +-
7 files changed, 185 insertions(+), 2 deletions(-)
create mode 100644 spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/instrument/scgmvc/RouterLabelMvcFilter.java
create mode 100644 spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/scgmvc/RouterLabelMvcFilterTest.java
diff --git a/CHANGELOG.md b/CHANGELOG.md
index acbf84d0c..546d6fe34 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -44,3 +44,4 @@
- [feat:support smooth upgrade from tsf.](https://github.com/Tencent/spring-cloud-tencent/pull/1482)
- [fix:fix caller disposable metadata handle when using tracing.](https://github.com/Tencent/spring-cloud-tencent/pull/1483)
- [refactor:update registry status.](https://github.com/Tencent/spring-cloud-tencent/pull/1484)
+- [feat:support polaris route for gateway mvc.](https://github.com/Tencent/spring-cloud-tencent/pull/1493)
diff --git a/spring-cloud-starter-tencent-polaris-router/pom.xml b/spring-cloud-starter-tencent-polaris-router/pom.xml
index e97f4d864..6f7a1dcec 100644
--- a/spring-cloud-starter-tencent-polaris-router/pom.xml
+++ b/spring-cloud-starter-tencent-polaris-router/pom.xml
@@ -76,6 +76,14 @@
+
+
+ org.springframework.cloud
+ spring-cloud-gateway-server-mvc
+ true
+
+
+
org.springframework.boot
spring-boot-actuator
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 48857ad46..1c8adb7da 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
@@ -27,6 +27,7 @@ import com.tencent.cloud.polaris.router.config.properties.PolarisNearByRouterPro
import com.tencent.cloud.polaris.router.config.properties.PolarisRuleBasedRouterProperties;
import com.tencent.cloud.polaris.router.instrument.resttemplate.RouterLabelRestTemplateInterceptor;
import com.tencent.cloud.polaris.router.instrument.scg.RouterLabelGlobalFilter;
+import com.tencent.cloud.polaris.router.instrument.scgmvc.RouterLabelMvcFilter;
import com.tencent.cloud.polaris.router.interceptor.MetadataRouterRequestInterceptor;
import com.tencent.cloud.polaris.router.interceptor.NamespaceRouterRequestInterceptor;
import com.tencent.cloud.polaris.router.interceptor.NearbyRouterRequestInterceptor;
@@ -91,6 +92,20 @@ public class RouterAutoConfiguration {
}
+ /**
+ * Create when gateway application is SCG MVC.
+ */
+ @Configuration(proxyBeanMethods = false)
+ @ConditionalOnClass(name = "org.springframework.cloud.gateway.server.mvc.filter.FormFilter")
+ protected static class RouterLabelScgMvcFilterConfig {
+
+ @Bean
+ public RouterLabelMvcFilter routerLabelMvcFilter() {
+ return new RouterLabelMvcFilter();
+ }
+
+ }
+
/**
* Create when RestTemplate exists.
* @author liuye 2022-09-14
diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/instrument/scgmvc/RouterLabelMvcFilter.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/instrument/scgmvc/RouterLabelMvcFilter.java
new file mode 100644
index 000000000..2d8d21764
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/instrument/scgmvc/RouterLabelMvcFilter.java
@@ -0,0 +1,62 @@
+/*
+ * Tencent is pleased to support the open source community by making spring-cloud-tencent available.
+ *
+ * Copyright (C) 2021 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.instrument.scgmvc;
+
+import java.io.IOException;
+
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import com.tencent.cloud.metadata.provider.ServletMetadataProvider;
+import com.tencent.polaris.metadata.core.MetadataType;
+import com.tencent.polaris.metadata.core.constant.MetadataConstants;
+import com.tencent.polaris.metadata.core.manager.CalleeMetadataContainerGroup;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+
+import org.springframework.core.Ordered;
+
+import static org.springframework.cloud.gateway.server.mvc.filter.FormFilter.FORM_FILTER_ORDER;
+
+/**
+ * Interceptor used for setting SCG MVC metadata provider.
+ *
+ * @author luguoji
+ */
+public class RouterLabelMvcFilter implements Filter, Ordered {
+
+ @Override
+ public int getOrder() {
+ return FORM_FILTER_ORDER - 1;
+ }
+
+ /**
+ * Create new RequestData for passing router labels.
+ */
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
+ throws IOException, ServletException {
+ MetadataContextHolder.get().getMetadataContainer(MetadataType.MESSAGE, false)
+ .setMetadataProvider(new ServletMetadataProvider((HttpServletRequest) request,
+ CalleeMetadataContainerGroup.getStaticApplicationMetadataContainer()
+ .getRawMetadataStringValue(MetadataConstants.LOCAL_IP)));
+ filterChain.doFilter(request, response);
+ }
+}
diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/scg/RouterLabelGlobalFilterTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/scg/RouterLabelGlobalFilterTest.java
index 52c03f416..c41f84279 100644
--- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/scg/RouterLabelGlobalFilterTest.java
+++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/scg/RouterLabelGlobalFilterTest.java
@@ -45,7 +45,7 @@ import static org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClien
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = RouterLabelGlobalFilterTest.TestApplication.class,
- properties = {"spring.cloud.polaris.namespace=test", "spring.application.name=test", "spring.main.web-application-type=reactive"})
+ properties = {"spring.cloud.polaris.namespace=test", "spring.application.name=test", "spring.main.web-application-type=reactive", "spring.cloud.gateway.mvc.enabled=false"})
public class RouterLabelGlobalFilterTest {
@Test
diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/scgmvc/RouterLabelMvcFilterTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/scgmvc/RouterLabelMvcFilterTest.java
new file mode 100644
index 000000000..76fc4edb4
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/scgmvc/RouterLabelMvcFilterTest.java
@@ -0,0 +1,97 @@
+/*
+ * Tencent is pleased to support the open source community by making spring-cloud-tencent available.
+ *
+ * Copyright (C) 2021 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.instrument.scgmvc;
+
+import java.io.IOException;
+
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import com.tencent.polaris.metadata.core.MessageMetadataContainer;
+import com.tencent.polaris.metadata.core.MetadataContainer;
+import com.tencent.polaris.metadata.core.MetadataType;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.HttpMethod;
+import org.springframework.mock.web.MockCookie;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+import static org.springframework.cloud.gateway.server.mvc.filter.FormFilter.FORM_FILTER_ORDER;
+
+/**
+ * Test for ${@link RouterLabelMvcFilter}.
+ *
+ * @author luguoji
+ */
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(classes = RouterLabelMvcFilterTest.TestApplication.class,
+ properties = {"spring.cloud.polaris.namespace=test", "spring.application.name=test", "spring.main.web-application-type=servlet", "spring.cloud.gateway.enabled=false"})
+public class RouterLabelMvcFilterTest {
+
+ @Test
+ public void testRouterLabelMvc() {
+ try {
+ RouterLabelMvcFilter routerLabelMvcFilter = new RouterLabelMvcFilter();
+
+ assertThat(routerLabelMvcFilter.getOrder())
+ .isEqualTo(FORM_FILTER_ORDER - 1);
+
+ FilterChain filterChain = (servletRequest, servletResponse) -> {
+
+ };
+
+ MockHttpServletRequest request = new MockHttpServletRequest();
+ request.addHeader("uid", "1000");
+ request.setCookies(new MockCookie("k1", "v1"));
+ request.setMethod(HttpMethod.POST.name());
+ request.setRequestURI("/test/path");
+ request.setQueryString("q1=a1");
+
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ routerLabelMvcFilter.doFilter(request, response, filterChain);
+ // get message metadata container
+ MetadataContainer metadataContainer = MetadataContextHolder.get()
+ .getMetadataContainer(MetadataType.MESSAGE, false);
+ // method
+ assertThat(metadataContainer.getRawMetadataStringValue(MessageMetadataContainer.LABEL_KEY_METHOD)).isEqualTo(HttpMethod.POST.toString());
+ // path
+ assertThat(metadataContainer.getRawMetadataStringValue(MessageMetadataContainer.LABEL_KEY_PATH)).isEqualTo("/test/path");
+ // header
+ assertThat(metadataContainer.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_HEADER, "uid")).isEqualTo("1000");
+ // cookie
+ assertThat(metadataContainer.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_COOKIE, "k1")).isEqualTo("v1");
+ // query
+ assertThat(metadataContainer.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_QUERY, "q1")).isEqualTo("a1");
+ }
+ catch (ServletException | IOException e) {
+ fail("Exception encountered.", e);
+ }
+ }
+
+ @SpringBootApplication
+ protected static class TestApplication {
+
+ }
+}
diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml
index f8af3f4fd..e63a07928 100644
--- a/spring-cloud-tencent-dependencies/pom.xml
+++ b/spring-cloud-tencent-dependencies/pom.xml
@@ -74,7 +74,7 @@
2.0.0.0-2023.0.3-SNAPSHOT
- 2.0.0.0-SNAPSHOT
+ 2.0.0.0
32.0.1-jre