feat:support polaris route for gateway mvc (#1493)

pull/1501/head
Guoji Lu 7 months ago committed by GitHub
parent a5dc460b9e
commit 0cf3d21f12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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)

@ -76,6 +76,14 @@
</dependency>
<!-- spring cloud gateway dependencies end -->
<!-- spring cloud gateway mvc dependencies start -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-server-mvc</artifactId>
<optional>true</optional>
</dependency>
<!-- spring cloud gateway mvc dependencies end -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>

@ -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

@ -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);
}
}

@ -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

@ -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 {
}
}

@ -74,7 +74,7 @@
<revision>2.0.0.0-2023.0.3-SNAPSHOT</revision>
<!-- Polaris SDK version -->
<polaris.version>2.0.0.0-SNAPSHOT</polaris.version>
<polaris.version>2.0.0.0</polaris.version>
<!-- Dependencies -->
<guava.version>32.0.1-jre</guava.version>

Loading…
Cancel
Save