From c4ba9498664516ac77451140111e3cca85726a51 Mon Sep 17 00:00:00 2001
From: provenceee <83857838+provenceee@users.noreply.github.com>
Date: Tue, 12 Nov 2024 11:19:38 +0800
Subject: [PATCH] *router piugin support springboot3
Signed-off-by: provenceee <83857838+provenceee@users.noreply.github.com>
---
.../flowcontrol-plugin/pom.xml | 2 +-
.../DispatcherServletInterceptor.java | 81 +++++++++++++++++--
.../sermant-monitor/monitor-plugin/pom.xml | 6 ++
.../DispatcherServletInterceptor.java | 35 +++++++-
.../DispatcherServletInterceptor.java | 51 ++++++++++--
.../DispatcherServletInterceptor.java | 69 ++++++++++++++--
6 files changed, 220 insertions(+), 24 deletions(-)
diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/pom.xml b/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/pom.xml
index 99034b5c20..acea97cd75 100644
--- a/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/pom.xml
+++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/pom.xml
@@ -67,7 +67,7 @@
javax.servlet
javax.servlet-api
${servlet-api.version}
- test
+ provided
org.springframework.boot
diff --git a/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/com/huawei/flowcontrol/DispatcherServletInterceptor.java b/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/com/huawei/flowcontrol/DispatcherServletInterceptor.java
index dcfb304d74..863f47594e 100644
--- a/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/com/huawei/flowcontrol/DispatcherServletInterceptor.java
+++ b/sermant-plugins/sermant-flowcontrol/flowcontrol-plugin/src/main/java/com/huawei/flowcontrol/DispatcherServletInterceptor.java
@@ -26,12 +26,19 @@
import com.huaweicloud.sermant.core.utils.LogUtils;
import com.huaweicloud.sermant.core.utils.ReflectUtils;
+import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
/**
* DispatcherServlet 的 API接口增强 埋点定义sentinel资源
@@ -42,6 +49,28 @@
public class DispatcherServletInterceptor extends InterceptorSupporter {
private final String className = DispatcherServletInterceptor.class.getName();
+ private Function
+
+ javax.servlet
+ javax.servlet-api
+ ${servlet-api.version}
+ provided
+
junit
junit
diff --git a/sermant-plugins/sermant-monitor/monitor-plugin/src/main/java/com/huawei/monitor/interceptor/DispatcherServletInterceptor.java b/sermant-plugins/sermant-monitor/monitor-plugin/src/main/java/com/huawei/monitor/interceptor/DispatcherServletInterceptor.java
index e1d73cd471..6571bdbd49 100644
--- a/sermant-plugins/sermant-monitor/monitor-plugin/src/main/java/com/huawei/monitor/interceptor/DispatcherServletInterceptor.java
+++ b/sermant-plugins/sermant-monitor/monitor-plugin/src/main/java/com/huawei/monitor/interceptor/DispatcherServletInterceptor.java
@@ -25,6 +25,10 @@
import com.huaweicloud.sermant.core.utils.LogUtils;
import com.huaweicloud.sermant.core.utils.ReflectUtils;
+import java.util.function.Function;
+
+import javax.servlet.http.HttpServletRequest;
+
/**
* HTTP拦截定义
*
@@ -34,6 +38,15 @@
public class DispatcherServletInterceptor extends AbstractInterceptor {
private static final String START_TIME = "startTime";
+ private Function getRequestUri;
+
+ /**
+ * 构造方法
+ */
+ public DispatcherServletInterceptor() {
+ initFunction();
+ }
+
@Override
public ExecuteContext before(ExecuteContext context) {
LogUtils.printHttpRequestBeforePoint(context);
@@ -50,7 +63,7 @@ public ExecuteContext after(ExecuteContext context) {
LogUtils.printHttpRequestAfterPoint(context);
return context;
}
- String uri = getRequestUri(context.getArguments()[0]);
+ String uri = getRequestUri.apply(context.getArguments()[0]);
MetricCalEntity metricCalEntity = MonitorCacheUtil.getMetricCalEntity(uri);
metricCalEntity.getReqNum().incrementAndGet();
long startTime = (Long) context.getExtMemberFieldValue(START_TIME);
@@ -70,7 +83,7 @@ public ExecuteContext onThrow(ExecuteContext context) {
LogUtils.printHttpRequestOnThrowPoint(context);
return context;
}
- String uri = getRequestUri(context.getArguments()[0]);
+ String uri = getRequestUri.apply(context.getArguments()[0]);
MetricCalEntity metricCalEntity = MonitorCacheUtil.getMetricCalEntity(uri);
metricCalEntity.getReqNum().incrementAndGet();
metricCalEntity.getFailedReqNum().incrementAndGet();
@@ -81,4 +94,22 @@ public ExecuteContext onThrow(ExecuteContext context) {
private String getRequestUri(Object httpServletRequest) {
return (String) ReflectUtils.invokeMethodWithNoneParameter(httpServletRequest, "getRequestURI").orElse(null);
}
+
+ private void initFunction() {
+ boolean canLoadLowVersion = canLoadLowVersion();
+ if (canLoadLowVersion) {
+ getRequestUri = obj -> ((HttpServletRequest) obj).getRequestURI();
+ } else {
+ getRequestUri = this::getRequestUri;
+ }
+ }
+
+ private boolean canLoadLowVersion() {
+ try {
+ Class.forName(HttpServletRequest.class.getCanonicalName());
+ } catch (NoClassDefFoundError | ClassNotFoundException error) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/sermant-plugins/sermant-router/spring-router-plugin/src/main/java/com/huaweicloud/sermant/router/spring/interceptor/DispatcherServletInterceptor.java b/sermant-plugins/sermant-router/spring-router-plugin/src/main/java/com/huaweicloud/sermant/router/spring/interceptor/DispatcherServletInterceptor.java
index 38efd2b9a0..f52cd92393 100644
--- a/sermant-plugins/sermant-router/spring-router-plugin/src/main/java/com/huaweicloud/sermant/router/spring/interceptor/DispatcherServletInterceptor.java
+++ b/sermant-plugins/sermant-router/spring-router-plugin/src/main/java/com/huaweicloud/sermant/router/spring/interceptor/DispatcherServletInterceptor.java
@@ -42,6 +42,10 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import javax.servlet.http.HttpServletRequest;
/**
* 获取http请求数据
@@ -54,6 +58,16 @@ public class DispatcherServletInterceptor extends AbstractInterceptor {
private final SpringConfigService configService;
+ private Function getQueryString;
+
+ private Function getRequestUri;
+
+ private Function getMethod;
+
+ private Function> getHeaderNames;
+
+ private BiFunction> getHeaders;
+
/**
* 构造方法
*/
@@ -63,6 +77,7 @@ public DispatcherServletInterceptor() {
handlers.add(new LaneHandler());
handlers.add(new RouteHandler());
handlers.sort(Comparator.comparingInt(Handler::getOrder));
+ initFunction();
}
@Override
@@ -75,11 +90,11 @@ public ExecuteContext before(ExecuteContext context) {
}
Object request = context.getArguments()[0];
Map> headers = getHeaders(request);
- String queryString = SpringRouterUtils.getQueryString(request);
+ String queryString = getQueryString.apply(request);
String decode = Optional.ofNullable(queryString).map(this::decode).orElse(StringUtils.EMPTY);
Map> queryParams = SpringRouterUtils.getParametersByQuery(decode);
- String path = SpringRouterUtils.getRequestUri(request);
- String method = SpringRouterUtils.getMethod(request);
+ String path = getRequestUri.apply(request);
+ String method = getMethod.apply(request);
handlers.forEach(handler -> ThreadLocalUtils.addRequestTag(
handler.getRequestTag(path, method, headers, queryParams, new Keys(matchKeys, injectTags))));
return context;
@@ -109,10 +124,10 @@ private String decode(String str) {
private Map> getHeaders(Object request) {
Map> headers = new HashMap<>();
- Enumeration> enumeration = SpringRouterUtils.getHeaderNames(request);
+ Enumeration> enumeration = getHeaderNames.apply(request);
while (enumeration.hasMoreElements()) {
String key = (String) enumeration.nextElement();
- headers.put(key, enumeration2List(SpringRouterUtils.getHeaders(request, key)));
+ headers.put(key, enumeration2List(getHeaders.apply(request, key)));
}
return headers;
}
@@ -127,4 +142,30 @@ private List enumeration2List(Enumeration> enumeration) {
}
return collection;
}
+
+ private void initFunction() {
+ boolean canLoadLowVersion = canLoadLowVersion();
+ if (canLoadLowVersion) {
+ getQueryString = obj -> ((HttpServletRequest) obj).getQueryString();
+ getRequestUri = obj -> ((HttpServletRequest) obj).getRequestURI();
+ getMethod = obj -> ((HttpServletRequest) obj).getMethod();
+ getHeaderNames = obj -> ((HttpServletRequest) obj).getHeaderNames();
+ getHeaders = (obj, key) -> ((HttpServletRequest) obj).getHeaders(key);
+ } else {
+ getQueryString = SpringRouterUtils::getQueryString;
+ getRequestUri = SpringRouterUtils::getRequestUri;
+ getMethod = SpringRouterUtils::getMethod;
+ getHeaderNames = SpringRouterUtils::getHeaderNames;
+ getHeaders = SpringRouterUtils::getHeaders;
+ }
+ }
+
+ private boolean canLoadLowVersion() {
+ try {
+ Class.forName(HttpServletRequest.class.getCanonicalName());
+ } catch (NoClassDefFoundError | ClassNotFoundException error) {
+ return false;
+ }
+ return true;
+ }
}
\ No newline at end of file
diff --git a/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/main/java/com/huawei/registry/grace/interceptors/DispatcherServletInterceptor.java b/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/main/java/com/huawei/registry/grace/interceptors/DispatcherServletInterceptor.java
index 73bdea5bd8..95f4ad74b2 100644
--- a/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/main/java/com/huawei/registry/grace/interceptors/DispatcherServletInterceptor.java
+++ b/sermant-plugins/sermant-service-registry/spring-cloud-registry-plugin/src/main/java/com/huawei/registry/grace/interceptors/DispatcherServletInterceptor.java
@@ -36,6 +36,12 @@
import com.huaweicloud.sermant.core.utils.ReflectUtils;
import com.huaweicloud.sermant.core.utils.StringUtils;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
/**
* Spring Web请求拦截器
*
@@ -47,12 +53,21 @@ public class DispatcherServletInterceptor extends GraceSwitchInterceptor {
private final GraceConfig graceConfig;
+ private Consumer addHeader;
+
+ private Function getServerPort;
+
+ private Function getRemoteAddr;
+
+ private BiFunction getHeader;
+
/**
* 构造方法
*/
public DispatcherServletInterceptor() {
graceService = PluginServiceManager.getPluginService(GraceService.class);
graceConfig = PluginConfigManager.getPluginConfig(GraceConfig.class);
+ initFunction();
}
@Override
@@ -70,11 +85,11 @@ public ExecuteContext doBefore(ExecuteContext context) {
if (graceShutDownManager.isShutDown() && graceConfig.isEnableGraceShutdown()) {
// 已被标记为关闭状态, 开始统计进入的请求数
final ClientInfo clientInfo = RegisterContext.INSTANCE.getClientInfo();
- addHeader(response, GraceConstants.MARK_SHUTDOWN_SERVICE_ENDPOINT,
+ addHeader.accept(response, GraceConstants.MARK_SHUTDOWN_SERVICE_ENDPOINT,
buildEndpoint(clientInfo.getIp(), clientInfo.getPort()));
- addHeader(response, GraceConstants.MARK_SHUTDOWN_SERVICE_ENDPOINT,
+ addHeader.accept(response, GraceConstants.MARK_SHUTDOWN_SERVICE_ENDPOINT,
buildEndpoint(clientInfo.getHost(), clientInfo.getPort()));
- addHeader(response, GraceConstants.MARK_SHUTDOWN_SERVICE_NAME, clientInfo.getServiceName());
+ addHeader.accept(response, GraceConstants.MARK_SHUTDOWN_SERVICE_NAME, clientInfo.getServiceName());
}
return context;
}
@@ -94,17 +109,17 @@ public ExecuteContext doThrow(ExecuteContext context) {
private void addGraceAddress(Object request) {
if (graceConfig.isEnableSpring() && graceConfig.isEnableGraceShutdown() && graceConfig.isEnableOfflineNotify()
&& GraceConstants.GRACE_OFFLINE_SOURCE_VALUE
- .equals(getHeader(request, GraceConstants.GRACE_OFFLINE_SOURCE_KEY))) {
- String address = getHeader(request, GraceConstants.SERMANT_GRACE_ADDRESS);
+ .equals(getHeader.apply(request, GraceConstants.GRACE_OFFLINE_SOURCE_KEY))) {
+ String address = getHeader.apply(request, GraceConstants.SERMANT_GRACE_ADDRESS);
if (StringUtils.isBlank(address)) {
- address = getRemoteAddr(request) + ":" + getServerPort(request);
+ address = getRemoteAddr.apply(request) + ":" + getServerPort.apply(request);
}
graceService.addAddress(address);
}
}
- private void addHeader(Object httpServletRequest, String key, String value) {
- ReflectUtils.invokeMethod(httpServletRequest, "addHeader", new Class[]{String.class, String.class},
+ private void addHeader(Object httpServletResponse, String key, String value) {
+ ReflectUtils.invokeMethod(httpServletResponse, "addHeader", new Class[]{String.class, String.class},
new Object[]{key, value});
}
@@ -124,4 +139,42 @@ private String getHeader(Object httpServletRequest, String key) {
private String getString(Object object, String method) {
return (String) ReflectUtils.invokeMethodWithNoneParameter(object, method).orElse(null);
}
+
+ private void initFunction() {
+ boolean canLoadLowVersion = canLoadLowVersion();
+ if (canLoadLowVersion) {
+ addHeader = (obj, key, value) -> ((HttpServletResponse) obj).addHeader(key, value);
+ getServerPort = obj -> ((HttpServletRequest) obj).getServerPort();
+ getRemoteAddr = obj -> ((HttpServletRequest) obj).getRemoteAddr();
+ getHeader = (obj, key) -> ((HttpServletRequest) obj).getHeader(key);
+ } else {
+ addHeader = this::addHeader;
+ getServerPort = this::getServerPort;
+ getRemoteAddr = this::getRemoteAddr;
+ getHeader = this::getHeader;
+ }
+ }
+
+ private boolean canLoadLowVersion() {
+ try {
+ Class.forName(HttpServletRequest.class.getCanonicalName());
+ } catch (NoClassDefFoundError | ClassNotFoundException error) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * mapping
+ *
+ * @param parameter1
+ * @param parameter2
+ * @param parameter3
+ * @author proveceee
+ * @since 2024-11-15
+ */
+ @FunctionalInterface
+ private interface Consumer {
+ void accept(T t, R r, U u);
+ }
}