Skip to content

Commit

Permalink
*support springboot3
Browse files Browse the repository at this point in the history
Signed-off-by: provenceee <[email protected]>
  • Loading branch information
provenceee committed Nov 11, 2024
1 parent 6692b83 commit ab4585b
Show file tree
Hide file tree
Showing 12 changed files with 226 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,12 @@ public static void install(String artifact, Map<String, Object> argsMap, Instrum
agentType = AgentType.AGENTMAIN.getValue();
}
artifactCache = artifact;
adviserCache = new DefaultAdviser();

// 初始化默认日志,在未加载日志引擎前保证日志可用
LoggerFactory.initDefaultLogger(artifact);

adviserCache = new DefaultAdviser();

// 初始化框架类加载器
ClassLoaderManager.init(argsMap);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public static Logger getLogger() {
if (defaultLogger == null) {
synchronized (LoggerFactory.class) {
if (defaultLogger == null) {
defaultLogger = java.util.logging.Logger.getLogger("sermant");
defaultLogger = java.util.logging.Logger.getLogger("sermant.default");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
*
* * Copyright (C) 2024-2024 Huawei Technologies Co., Ltd. All rights reserved.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * 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.huaweicloud.sermant.router.spring.declarer;

import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher;

/**
* 获取http请求数据
*
* @author provenceee
* @since 2024-11-11
*/
public class DispatcherServletDeclarer extends AbstractDeclarer {
private static final String ENHANCE_CLASS
= "org.springframework.web.servlet.DispatcherServlet";

private static final String INTERCEPT_CLASS
= "com.huaweicloud.sermant.router.spring.interceptor.DispatcherServletInterceptor";

private static final String METHOD_NAME = "doService";

/**
* 构造方法
*/
public DispatcherServletDeclarer() {
super(ENHANCE_CLASS, INTERCEPT_CLASS, METHOD_NAME);
}

@Override
public ClassMatcher getClassMatcher() {
return ClassMatcher.nameEquals(ENHANCE_CLASS);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public ExecuteContext before(ExecuteContext context) {
Object serviceName = ReflectUtils.getFieldValue(obj, "serviceName").orElse(null);
if (serviceName instanceof String) {
AppCache.INSTANCE.setAppName((String) serviceName);
configService.init(RouterConstant.SPRING_CACHE_NAME, (String) serviceName);
} else {
LOGGER.warning("Service name is null or not instanceof string.");
}
Expand All @@ -69,7 +70,6 @@ public ExecuteContext before(ExecuteContext context) {

@Override
public ExecuteContext after(ExecuteContext context) {
configService.init(RouterConstant.SPRING_CACHE_NAME, AppCache.INSTANCE.getAppName());
return context;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
*
* * Copyright (C) 2024-2024 Huawei Technologies Co., Ltd. All rights reserved.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * 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.huaweicloud.sermant.router.spring.interceptor;

import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
import com.huaweicloud.sermant.core.plugin.agent.interceptor.AbstractInterceptor;
import com.huaweicloud.sermant.core.plugin.service.PluginServiceManager;
import com.huaweicloud.sermant.router.common.handler.Handler;
import com.huaweicloud.sermant.router.common.utils.CollectionUtils;
import com.huaweicloud.sermant.router.common.utils.ThreadLocalUtils;
import com.huaweicloud.sermant.router.spring.handler.AbstractRequestTagHandler;
import com.huaweicloud.sermant.router.spring.handler.AbstractRequestTagHandler.Keys;
import com.huaweicloud.sermant.router.spring.handler.LaneRequestTagHandler;
import com.huaweicloud.sermant.router.spring.handler.RouteRequestTagHandler;
import com.huaweicloud.sermant.router.spring.service.SpringConfigService;
import com.huaweicloud.sermant.router.spring.utils.SpringRouterUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* 获取http请求数据
*
* @author provenceee
* @since 2024-11-11
*/
public class DispatcherServletInterceptor extends AbstractInterceptor {
private final List<AbstractRequestTagHandler> handlers;

private final SpringConfigService configService;

/**
* 构造方法
*/
public DispatcherServletInterceptor() {
configService = PluginServiceManager.getPluginService(SpringConfigService.class);
handlers = new ArrayList<>();
handlers.add(new LaneRequestTagHandler());
handlers.add(new RouteRequestTagHandler());
handlers.sort(Comparator.comparingInt(Handler::getOrder));
}

@Override
public ExecuteContext before(ExecuteContext context) {
Set<String> matchKeys = configService.getMatchKeys();
Set<String> injectTags = configService.getInjectTags();
if (CollectionUtils.isEmpty(matchKeys) && CollectionUtils.isEmpty(injectTags)) {
// 染色标记为空,代表没有染色规则,直接return
return context;
}
Object request = context.getArguments()[0];
Map<String, List<String>> headers = getHeaders(request);
Map<String, String[]> parameterMap = SpringRouterUtils.getParameterMap(request);
String path = SpringRouterUtils.getRequestUri(request);
String method = SpringRouterUtils.getMethod(request);
handlers.forEach(handler -> ThreadLocalUtils.addRequestTag(
handler.getRequestTag(path, method, headers, parameterMap, new Keys(matchKeys, injectTags))));
return context;
}

@Override
public ExecuteContext after(ExecuteContext context) {
ThreadLocalUtils.removeRequestData();
ThreadLocalUtils.removeRequestTag();
return context;
}

@Override
public ExecuteContext onThrow(ExecuteContext context) {
ThreadLocalUtils.removeRequestData();
ThreadLocalUtils.removeRequestTag();
return context;
}

private Map<String, List<String>> getHeaders(Object request) {
Map<String, List<String>> headers = new HashMap<>();
Enumeration<?> enumeration = SpringRouterUtils.getHeaderNames(request);
while (enumeration.hasMoreElements()) {
String key = (String) enumeration.nextElement();
headers.put(key, enumeration2List(SpringRouterUtils.getHeaders(request, key)));
}
return headers;
}

private List<String> enumeration2List(Enumeration<?> enumeration) {
if (enumeration == null) {
return Collections.emptyList();
}
List<String> collection = new ArrayList<>();
while (enumeration.hasMoreElements()) {
collection.add((String) enumeration.nextElement());
}
return collection;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ public ExecuteContext before(ExecuteContext context) {
if (argument instanceof InstanceInfo) {
InstanceInfo instanceInfo = (InstanceInfo) argument;
AppCache.INSTANCE.setAppName(instanceInfo.getAppName());
configService.init(RouterConstant.SPRING_CACHE_NAME, instanceInfo.getAppName());
SpringRouterUtils.putMetaData(instanceInfo.getMetadata(), routerConfig);
}
return context;
}

@Override
public ExecuteContext after(ExecuteContext context) {
configService.init(RouterConstant.SPRING_CACHE_NAME, AppCache.INSTANCE.getAppName());
return context;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public ExecuteContext before(ExecuteContext context) {
serviceRegistration.getClass().getDeclaredMethod("getRegistration"))
.invoke(serviceRegistration);
AppCache.INSTANCE.setAppName(registration.getServiceId());
configService.init(RouterConstant.SPRING_CACHE_NAME, registration.getServiceId());
SpringRouterUtils.putMetaData(registration.getMetadata(), routerConfig);
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException ex) {
LOGGER.log(Level.WARNING, "Can not get the registration.", ex);
Expand All @@ -76,7 +77,6 @@ public ExecuteContext before(ExecuteContext context) {

@Override
public ExecuteContext after(ExecuteContext context) {
configService.init(RouterConstant.SPRING_CACHE_NAME, AppCache.INSTANCE.getAppName());
return context;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.huaweicloud.sermant.router.common.utils.ReflectUtils;
import com.huaweicloud.sermant.router.spring.cache.AppCache;

import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;

Expand All @@ -39,6 +40,57 @@ public class SpringRouterUtils {
private SpringRouterUtils() {
}

/**
* 获取请求中的parameter
*
* @param obj HttpServletRequest
* @return parameter
*/
public static Map<String, String[]> getParameterMap(Object obj) {
return (Map<String, String[]>) ReflectUtils.invokeWithNoneParameter(obj, "getParameterMap");
}

/**
* 获取请求中的uri
*
* @param obj HttpServletRequest
* @return uri
*/
public static String getRequestUri(Object obj) {
return ReflectUtils.invokeWithNoneParameterAndReturnString(obj, "getRequestURI");
}

/**
* 获取请求中的方法
*
* @param obj HttpServletRequest
* @return method
*/
public static String getMethod(Object obj) {
return ReflectUtils.invokeWithNoneParameterAndReturnString(obj, "getMethod");
}

/**
* 获取请求中的所有请求头的key
*
* @param obj HttpServletRequest
* @return key
*/
public static Enumeration<?> getHeaderNames(Object obj) {
return (Enumeration<?>) ReflectUtils.invokeWithNoneParameter(obj, "getHeaderNames");
}

/**
* 获取元数据
*
* @param obj HttpServletRequest
* @param key header key
* @return 元数据
*/
public static Enumeration<?> getHeaders(Object obj, String key) {
return (Enumeration<?>) ReflectUtils.invokeWithParameter(obj, "getHeaders", key, String.class);
}

/**
* 获取元数据
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ com.huaweicloud.sermant.router.spring.declarer.AbstractHandlerMappingDeclarer
com.huaweicloud.sermant.router.spring.declarer.BaseLoadBalancerDeclarer
com.huaweicloud.sermant.router.spring.declarer.ClientHttpRequestDeclarer
com.huaweicloud.sermant.router.spring.declarer.DiscoveryManagerDeclarer
com.huaweicloud.sermant.router.spring.declarer.DispatcherServletDeclarer
com.huaweicloud.sermant.router.spring.declarer.EurekaHttpClientDeclarer
com.huaweicloud.sermant.router.spring.declarer.FeignClientDeclarer
com.huaweicloud.sermant.router.spring.declarer.HandlerExecutionChainDeclarer
#com.huaweicloud.sermant.router.spring.declarer.HandlerExecutionChainDeclarer
com.huaweicloud.sermant.router.spring.declarer.HystrixActionDeclarer
com.huaweicloud.sermant.router.spring.declarer.LoadBalancerClientFilterDeclarer
com.huaweicloud.sermant.router.spring.declarer.NopInstanceFilterDeclarer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,6 @@ public void testBefore() {
context.getArguments()[0] = new TestObject(null);
interceptor.before(context);
Assert.assertEquals("foo", AppCache.INSTANCE.getAppName());
}

/**
* 测试after方法
*/
@Test
public void testAfter() {
AppCache.INSTANCE.setAppName("foo");
interceptor.after(context);
Assert.assertEquals(RouterConstant.SPRING_CACHE_NAME, configService.getCacheName());
Assert.assertEquals("foo", configService.getServiceName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,6 @@ public void testBefore() {
Assert.assertEquals(routerConfig.getRouterVersion(), metadata.get("version"));
Assert.assertEquals("bar1", metadata.get("bar"));
Assert.assertEquals("foo2", metadata.get("foo"));
}

/**
* 测试after方法
*/
@Test
public void testAfter() {
AppCache.INSTANCE.setAppName("FOO");
interceptor.after(context);
Assert.assertEquals(RouterConstant.SPRING_CACHE_NAME, configService.getCacheName());
Assert.assertEquals("FOO", configService.getServiceName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,6 @@ public void testBefore() {
Assert.assertEquals(routerConfig.getRouterVersion(), metadata.get("version"));
Assert.assertEquals("bar1", metadata.get("bar"));
Assert.assertEquals("foo2", metadata.get("foo"));
}

/**
* 测试after方法
*/
@Test
public void testAfter() {
AppCache.INSTANCE.setAppName("foo");
interceptor.after(context);
Assert.assertEquals(RouterConstant.SPRING_CACHE_NAME, configService.getCacheName());
Assert.assertEquals("foo", configService.getServiceName());
}
Expand Down

0 comments on commit ab4585b

Please sign in to comment.