Skip to content

Commit 5596250

Browse files
author
‘niuerzhuang’
committed
Merge branch 'beta' into fix/clean-code
2 parents 37035e3 + f31a67f commit 5596250

File tree

32 files changed

+1197
-234
lines changed

32 files changed

+1197
-234
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package io.dongtai.iast.agent.fallback.checker;
2+
3+
import io.dongtai.iast.agent.IastProperties;
4+
import io.dongtai.iast.agent.fallback.checker.impl.CpuUsageChecker;
5+
import io.dongtai.iast.common.entity.performance.PerformanceMetrics;
6+
import io.dongtai.iast.common.entity.performance.metrics.CpuInfoMetrics;
7+
import io.dongtai.iast.common.enums.MetricsKey;
8+
import org.junit.Assert;
9+
import org.junit.Test;
10+
11+
import java.util.Properties;
12+
13+
/**
14+
* 检查CPU使用率
15+
*/
16+
public class CpuUsageCheckerTest {
17+
18+
@Test
19+
public void testIsPerformanceOverLimit() {
20+
21+
22+
// 创建配置参数对象
23+
Properties cfg = new Properties();
24+
cfg.setProperty("iast.remoteSync.performanceLimit.maxThreshold.cpuUsage", "{\"cpuUsagePercentage\":80.0}");
25+
26+
//初始化临时目录
27+
IastProperties.initTmpDir();
28+
29+
// 创建测试用例对象
30+
CpuUsageChecker cpuUsageChecker = new CpuUsageChecker();
31+
// 创建模拟性能指标对象
32+
PerformanceMetrics nowMetrics = new PerformanceMetrics();
33+
CpuInfoMetrics cpuInfoMetrics = new CpuInfoMetrics();
34+
cpuInfoMetrics.setCpuUsagePercentage(81.0);
35+
36+
nowMetrics.setMetricsKey(MetricsKey.CPU_USAGE);
37+
nowMetrics.setMetricsValue(cpuInfoMetrics);
38+
39+
// CPU使用率超过阈值,应该返回true
40+
Assert.assertTrue(cpuUsageChecker.isPerformanceOverLimit(nowMetrics, cfg));
41+
42+
// 修改性能指标对象的CPU使用率为70%
43+
cpuInfoMetrics.setCpuUsagePercentage(70.0);
44+
// CPU使用率未超过阈值,应该返回false
45+
Assert.assertFalse(cpuUsageChecker.isPerformanceOverLimit(nowMetrics, cfg));
46+
}
47+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package io.dongtai.iast.agent.fallback.checker;
2+
3+
import io.dongtai.iast.agent.IastProperties;
4+
import io.dongtai.iast.agent.fallback.checker.impl.MemUsageChecker;
5+
import io.dongtai.iast.common.entity.performance.PerformanceMetrics;
6+
import io.dongtai.iast.common.entity.performance.metrics.MemoryUsageMetrics;
7+
import io.dongtai.iast.common.enums.MetricsKey;
8+
import org.junit.Assert;
9+
import org.junit.Test;
10+
11+
import java.util.Properties;
12+
13+
public class MemUsageCheckerTest {
14+
15+
16+
/**
17+
* 测试内存检查
18+
*/
19+
@Test
20+
public void testIsPerformanceOverLimit() {
21+
// 配置参数
22+
Properties cfg = new Properties();
23+
// 设置配置内存阈值
24+
cfg.setProperty("iast.remoteSync.performanceLimit.maxThreshold.memoryUsage", "{\"committed\":1024," +
25+
"\"init\":1024,\"max\":1024,\"memUsagePercentage\":80.0,\"systemMaxLimit\":-1," +
26+
"\"trulyMaxMem\":1024,\"used\":1024}\n");
27+
//初始化临时目录
28+
IastProperties.initTmpDir();
29+
// 创建检查器对象
30+
MemUsageChecker memUsageChecker = new MemUsageChecker();
31+
// 创建模拟性能指标对象
32+
PerformanceMetrics nowMetrics = new PerformanceMetrics();
33+
nowMetrics.setMetricsKey(MetricsKey.MEM_USAGE);
34+
nowMetrics.setMetricsValue(new MemoryUsageMetrics(1024L, 1024L, 1024L, 1024L));
35+
// 内存使用率超过阈值,应该返回true
36+
Assert.assertTrue(memUsageChecker.isPerformanceOverLimit(nowMetrics, cfg));
37+
38+
39+
// 修改性能指标对象的内存使用率为70%
40+
nowMetrics.setMetricsValue(new MemoryUsageMetrics(1024L, 500L, 1024L, 1024L));
41+
// 内存使用率未超过阈值,应该返回false
42+
Assert.assertFalse(memUsageChecker.isPerformanceOverLimit(nowMetrics, cfg));
43+
}
44+
}

dongtai-api-gather/dongtai-api-gather-spring-api/src/main/java/io/dongtai/iast/api/gather/spring/convertor/RequestMappingInfoConvertor.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ private void parsePathPatternsRequestCondition() {
6060
});
6161
}
6262
} catch (Throwable e) {
63-
DongTaiLog.debug("spring api path.getPathPatternsCondition router exception", e);
63+
// DongTaiLog.debug("spring api path.getPathPatternsCondition router exception", e);
6464
}
6565

6666
try {
@@ -78,7 +78,7 @@ public void accept(String s) {
7878
});
7979
}
8080
} catch (Throwable e) {
81-
DongTaiLog.debug("spring api path.getPatternsCondition router exception", e);
81+
// DongTaiLog.debug("spring api path.getPatternsCondition router exception", e);
8282
}
8383
}
8484

@@ -144,7 +144,7 @@ public void accept(RequestMethod requestMethod) {
144144
}
145145
});
146146
} catch (Throwable e) {
147-
DongTaiLog.debug("spring api method router exception", e);
147+
// DongTaiLog.debug("spring api method router exception", e);
148148
}
149149
}
150150

@@ -210,7 +210,7 @@ public void accept(NameValueExpression<String> stringNameValueExpression) {
210210
});
211211
return parameterList;
212212
} catch (Throwable e) {
213-
DongTaiLog.debug("spring api parameters router exception: {}", e.getMessage());
213+
// DongTaiLog.debug("spring api parameters router exception: {}", e.getMessage());
214214
}
215215
return Collections.emptyList();
216216
}
@@ -242,7 +242,7 @@ public void accept(NameValueExpression<String> stringNameValueExpression) {
242242
});
243243
return headerParameterList;
244244
} catch (Throwable e) {
245-
DongTaiLog.debug("spring api headers router exception: {}", e.getMessage());
245+
// DongTaiLog.debug("spring api headers router exception: {}", e.getMessage());
246246
}
247247
return Collections.emptyList();
248248
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.dongtai.iast.common.exception;
2+
3+
/**
4+
* 动态Agent整个项目内异常的基类,以后的异常尽量都继承这个类
5+
*
6+
* @author CC11001100
7+
* @since 1.13.2
8+
*/
9+
public class DongTaiIastException extends Exception {
10+
11+
public DongTaiIastException() {
12+
}
13+
14+
public DongTaiIastException(String message) {
15+
super(message);
16+
}
17+
18+
public DongTaiIastException(String message, Throwable cause) {
19+
super(message, cause);
20+
}
21+
22+
public DongTaiIastException(Throwable cause) {
23+
super(cause);
24+
}
25+
26+
public DongTaiIastException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
27+
super(message, cause, enableSuppression, writableStackTrace);
28+
}
29+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.dongtai.iast.common.string;
2+
3+
/**
4+
* 用于表示对 对象格式化的结果
5+
*
6+
* @author CC11001100
7+
* @since 1.13.2
8+
*/
9+
public class ObjectFormatResult {
10+
11+
// 对象格式化后的字符串,可能不是原始的完整的字符串是被格式化过的,仅作为展示之类的使用
12+
public String objectFormatString;
13+
14+
// 原始的字符串长度,对象格式化可以认为有三个步骤:
15+
//
16+
// object --> original string --> format string
17+
//
18+
// 其中original string通常是调用object的toString()得到的,长度可能比较短,也可能老长老长了
19+
// format string这一步相当于是对original string进行截断,控制字符串的长度
20+
public int originalLength;
21+
22+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package io.dongtai.iast.common.string;
2+
3+
import java.io.StringWriter;
4+
import java.util.ArrayList;
5+
import java.util.LinkedList;
6+
import java.util.List;
7+
import java.util.function.Consumer;
8+
9+
/**
10+
* 用于把对象格式化为字符串
11+
*
12+
* @author CC11001100
13+
* @since 1.13.2
14+
*/
15+
public class ObjectFormatter {
16+
17+
/**
18+
* 把对象格式化为字符串,高频调用要尽可能快
19+
*
20+
* @param value 要转换为字符串的对象
21+
* @param charLimit 转换时的字符长度限制,超过此长度将被格式化为一个祖传下来的表示字符串省略的格式 :)
22+
* @return 比如"aaa",如果超长可能会发生省略: "aaaaaaaaaaaaaaaaaa...aaaaaaaaaaaaaa"
23+
* @see ObjectFormatResult
24+
*/
25+
public static ObjectFormatResult formatObject(Object value, int charLimit) {
26+
27+
ObjectFormatResult r = new ObjectFormatResult();
28+
29+
if (null == value) {
30+
return r;
31+
}
32+
33+
try {
34+
if (value.getClass().isArray() && !value.getClass().getComponentType().isPrimitive()) {
35+
// 判断是否是基本类型的数组,基本类型的数组无法类型转换为Object[],导致java.lang.ClassCastException异常
36+
Object[] taints = (Object[]) value;
37+
return objArray2StringV2(taints, charLimit);
38+
} else if (value instanceof StringWriter) {
39+
String s = ((StringWriter) value).getBuffer().toString();
40+
r.originalLength = s.length();
41+
r.objectFormatString = StringUtils.normalize(s, charLimit);
42+
return r;
43+
} else {
44+
String s = value.toString();
45+
r.originalLength = s.length();
46+
r.objectFormatString = StringUtils.normalize(s, charLimit);
47+
return r;
48+
}
49+
} catch (Throwable e) {
50+
// org.jruby.RubyBasicObject.hashCode() may cause NullPointerException when RubyBasicObject.metaClass is null
51+
String typeName = value.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(value));
52+
r.originalLength = typeName.length();
53+
r.objectFormatString = StringUtils.normalize(typeName, charLimit);
54+
return r;
55+
}
56+
}
57+
58+
/**
59+
* 对象数组转为字符串,会往下穿透到第二层
60+
*
61+
* @param objArray 要转换为字符串的对象数组
62+
* @param charLimit 同 {{@link #formatObject(Object, int)}}
63+
* @return
64+
* @see #formatObject
65+
*/
66+
private static ObjectFormatResult objArray2StringV2(Object[] objArray, int charLimit) {
67+
68+
ObjectFormatResult r = new ObjectFormatResult();
69+
70+
// 第一步,先把对象都收集一下,把要处理的对象打平
71+
List<Object> objList = new ArrayList<>();
72+
for (Object taint : objArray) {
73+
if (taint != null) {
74+
if (taint.getClass().isArray() && !taint.getClass().getComponentType().isPrimitive()) {
75+
Object[] subTaints = (Object[]) taint;
76+
for (Object subTaint : subTaints) {
77+
if (subTaint == null) {
78+
continue;
79+
}
80+
objList.add(subTaint);
81+
}
82+
} else {
83+
objList.add(taint);
84+
}
85+
}
86+
}
87+
88+
// 从前往后开始读取
89+
StringBuilder header = new StringBuilder();
90+
int headIndex = 0;
91+
while (headIndex < objList.size()) {
92+
93+
String s = objList.get(headIndex).toString();
94+
headIndex++;
95+
// 如果这个地方的字符串比较长怎么办?是不是应该截断一下?还是有优化空间的
96+
header.append(s);
97+
r.originalLength += s.length();
98+
99+
// 如果进来的话,说明长度是超了,这个时候应该做的是从尾部读取一部分进来,然后等会儿做截断用
100+
if (header.length() > charLimit) {
101+
102+
// 然后就从尾部开始向前读取
103+
int readCount = 0;
104+
LinkedList<String> tailStringList = new LinkedList<>();
105+
int needReadChar = charLimit / 2 + charLimit % 2;
106+
for (int tailIndex = objList.size() - 1; tailIndex >= headIndex; tailIndex--) {
107+
s = objList.get(tailIndex).toString();
108+
// 仅读取需要的字符数,超过的话则不再读取
109+
if (readCount < needReadChar) {
110+
readCount += s.length();
111+
tailStringList.addFirst(s);
112+
}
113+
// 但是长度是要整个计算的
114+
r.originalLength += s.length();
115+
}
116+
117+
// 然后开始拼接处理
118+
tailStringList.forEach(new Consumer<String>() {
119+
@Override
120+
public void accept(String s) {
121+
// 是不是应该避免一下不必要的拼接拷贝?某些特殊数据下还是可能会发生占用较长时间
122+
header.append(s);
123+
}
124+
});
125+
126+
break;
127+
}
128+
}
129+
130+
r.objectFormatString = StringUtils.normalize(header.toString(), charLimit);
131+
return r;
132+
}
133+
134+
}

0 commit comments

Comments
 (0)