Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
kt-keystone
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Matrix
kt-keystone
Commits
f38e0b2e
提交
f38e0b2e
authored
3月 09, 2022
作者:
Matrix
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(行为执行器): 增加了行为执行器的运行与行为变量解析
上级
acd1e56e
全部展开
显示空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
235 行增加
和
7 行删除
+235
-7
HttpResponseDetail.java
...a/org/matrix/actuators/httpclient/HttpResponseDetail.java
+2
-0
MoveActuator.java
...src/main/java/org/matrix/actuators/move/MoveActuator.java
+0
-0
MoveRegularObject.java
...ain/java/org/matrix/actuators/move/MoveRegularObject.java
+28
-0
MoveStrategy.java
...src/main/java/org/matrix/actuators/move/MoveStrategy.java
+24
-0
SqlExpActuator.java
...rc/main/java/org/matrix/actuators/sql/SqlExpActuator.java
+43
-4
Action.java
kt-base/src/main/java/org/matrix/database/entity/Action.java
+2
-1
IActionService.java
...main/java/org/matrix/database/service/IActionService.java
+4
-0
ActionServiceImpl.java
...a/org/matrix/database/service/impl/ActionServiceImpl.java
+19
-1
DynamicVariableServiceImpl.java
...rix/database/service/impl/DynamicVariableServiceImpl.java
+1
-1
ActionType.java
kt-base/src/main/java/org/matrix/enums/ActionType.java
+43
-0
BeanFlattener.java
kt-base/src/main/java/org/matrix/util/BeanFlattener.java
+69
-0
没有找到文件。
kt-base/src/main/java/org/matrix/actuators/httpclient/HttpResponseDetail.java
浏览文件 @
f38e0b2e
...
...
@@ -3,6 +3,7 @@ package org.matrix.actuators.httpclient;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.NoArgsConstructor
;
import
org.apache.http.client.methods.CloseableHttpResponse
;
import
org.matrix.actuators.usecase.BaseTestCaseResponseDetail
;
...
...
@@ -11,6 +12,7 @@ import org.springframework.http.HttpStatus;
/**
* @author huangxiahao
*/
@EqualsAndHashCode
(
callSuper
=
true
)
@Data
@AllArgsConstructor
@NoArgsConstructor
...
...
kt-base/src/main/java/org/matrix/actuators/move/MoveActuator.java
0 → 100644
浏览文件 @
f38e0b2e
差异被折叠。
点击展开。
kt-base/src/main/java/org/matrix/actuators/move/MoveRegularObject.java
0 → 100644
浏览文件 @
f38e0b2e
package
org
.
matrix
.
actuators
.
move
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
/**
* MoveRegularObject.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2022/3/7 at 6:24 PM
* Suffering is the most powerful teacher of life.
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public
class
MoveRegularObject
{
/**
* 在ThreadLocal里的key值
*/
private
String
key
;
/**
* 要取的字段名
*/
private
String
colName
;
}
kt-base/src/main/java/org/matrix/actuators/move/MoveStrategy.java
0 → 100644
浏览文件 @
f38e0b2e
package
org
.
matrix
.
actuators
.
move
;
/**
* MoveStrategy.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2022/3/7 at 3:11 PM
* Suffering is the most powerful teacher of life.
*/
public
enum
MoveStrategy
{
/**
* 前置动作
*/
PRE_MOVE
,
/**
* 中间动作
*/
MID_MOVE
,
/**
* 后置动作
*/
AFT_MOVE
;
}
kt-base/src/main/java/org/matrix/actuators/sql/SqlExpActuator.java
浏览文件 @
f38e0b2e
...
...
@@ -45,7 +45,7 @@ import static org.springframework.util.CollectionUtils.isEmpty;
public
class
SqlExpActuator
implements
Actuator
{
/**
* 用于正则找出形如${id}这样的SQL变量
* 用于正则找出形如${id}
或者 ${id}[1]
这样的SQL变量
*/
public
static
final
String
DYNAMIC_VAR_EXP
=
"\\$\\{(\\w*)}\\[?(\\d*)]?"
;
...
...
@@ -62,13 +62,51 @@ public class SqlExpActuator implements Actuator {
private
final
IDynamicVariableService
varService
;
private
final
IConnectService
connectService
;
private
final
IDataSourceService
dataSourceService
;
private
final
ITestCaseService
caseService
;
private
final
ITestDataService
dataService
;
/**
* 解析并运行SQL语句,可以包含别的SQL变量,例如 'select * from user where user.id = ${user_id} '
* @param sqlDetail sql的poolId与sql语句的对象
* @param envId 环境id
* @param projectId 项目id
* @return 运行SQL后取完数值的结果, 是一张数据表, 以LIST<MAP>的形式呈现
*/
public
List
<
Map
<
String
,
Object
>>
parseSql
(
SqlExpDetail
sqlDetail
,
Long
envId
,
Long
projectId
){
// 找到第一层的SQL变量,递归替换
String
sqlExp
=
sqlDetail
.
getSqlExp
();
Long
connectId
=
sqlDetail
.
getPoolId
();
List
<
SqlRegularObject
>
varList
=
findDynamicVarList
(
sqlExp
);
for
(
SqlRegularObject
sqlReg
:
varList
)
{
sqlExp
=
sqlExp
.
replaceAll
(
sqlReg
.
getVarName
(),
parseVarByName
(
sqlReg
.
getVarName
(),
envId
,
projectId
));
}
// 运行SQL
DataSourceDTO
dataSourceDTO
=
Optional
.
of
(
connectService
.
getById
(
connectId
))
.
orElseThrow
(()
->
new
GlobalException
(
String
.
format
(
"没有找到id = %d 的连接池connect对象"
,
connectId
)))
.
toDataSourceDTO
();
// 替换环境共享变量
sqlExp
=
envActuator
.
replaceEnvVar
(
sqlExp
,
envId
);
// 校验dynamicVar里的detail是否是可以直接执行的SQL
boolean
allVarParsed
=
findDynamicVarList
(
sqlExp
).
size
()
==
0
;
if
(
allVarParsed
)
{
// 切换数据源,执行SQL,获取数值
Set
<
String
>
dataSources
=
dataSourceService
.
switchDataSource
(
dataSourceDTO
);
log
.
info
(
"当前存在的数据源 {}"
,
dataSources
);
List
<
Map
<
String
,
Object
>>
resultMap
=
jdbcTemplate
.
queryForList
(
sqlExp
);
dataSourceService
.
switchMainDataSource
();
return
resultMap
;
}
else
{
throw
new
GlobalException
(
String
.
format
(
"SQL解析异常,SQL语句为%s,连接池id为%d"
,
sqlDetail
.
getSqlExp
(),
sqlDetail
.
getPoolId
()));
}
}
/**
* 解析给定的动态变量ByName
*
* @param varNameString 变量名,形如${id}
这样的字符串
* @param varNameString 变量名,形如${id}
或者是 ${id}[1]这样的字符串,默认下标为0
* @param projectId 该变量所在的项目ID
* @return 变量递归解析后的值
*/
...
...
@@ -170,7 +208,8 @@ public class SqlExpActuator implements Actuator {
String
sqlExp
=
dynamicVar
.
getSqlExpDetail
().
getSqlExp
();
sqlExp
=
envActuator
.
replaceEnvVar
(
sqlExp
,
envId
);
List
<
SqlRegularObject
>
dynamicVarList
=
findDynamicVarList
(
dynamicVar
.
getDetail
());
String
detail
=
dynamicVar
.
getDetail
();
List
<
SqlRegularObject
>
dynamicVarList
=
findDynamicVarList
(
detail
);
// 解析SQL表达式,判断是可以直接执行的SQL还是需要再递归解析动态变量
if
(!
isEmpty
(
dynamicVarList
))
{
// 如果还存在动态变量,则继续递归解析
...
...
kt-base/src/main/java/org/matrix/database/entity/Action.java
浏览文件 @
f38e0b2e
...
...
@@ -7,6 +7,7 @@ import lombok.AllArgsConstructor;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.NoArgsConstructor
;
import
org.matrix.enums.ActionType
;
/**
* <p>
...
...
@@ -37,7 +38,7 @@ public class Action extends BaseEntity {
private
String
remark
;
@ApiModelProperty
(
"类型 1为SQL,2为HTTP,3为CASE,4为WAIT_TIME"
)
private
Integer
type
;
private
ActionType
type
;
@ApiModelProperty
(
"详细参数"
)
private
String
detail
;
...
...
kt-base/src/main/java/org/matrix/database/service/IActionService.java
浏览文件 @
f38e0b2e
...
...
@@ -3,6 +3,8 @@ package org.matrix.database.service;
import
org.matrix.database.entity.Action
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
java.util.Optional
;
/**
* <p>
* 动作 服务类
...
...
@@ -13,4 +15,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public
interface
IActionService
extends
IService
<
Action
>
{
Optional
<
Action
>
findByMoveAndEnv
(
Long
moveId
,
Long
envId
);
}
kt-base/src/main/java/org/matrix/database/service/impl/ActionServiceImpl.java
浏览文件 @
f38e0b2e
package
org
.
matrix
.
database
.
service
.
impl
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.matrix.database.entity.Action
;
import
org.matrix.database.mapper.ActionMapper
;
import
org.matrix.database.service.IActionService
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
org.springframework.stereotype.Service
;
import
java.util.Optional
;
/**
* <p>
* 动作 服务实现类
...
...
@@ -17,4 +21,18 @@ import org.springframework.stereotype.Service;
@Service
public
class
ActionServiceImpl
extends
ServiceImpl
<
ActionMapper
,
Action
>
implements
IActionService
{
private
final
ActionMapper
actionMapper
;
public
ActionServiceImpl
(
ActionMapper
mapper
)
{
this
.
actionMapper
=
mapper
;
}
@Override
public
Optional
<
Action
>
findByMoveAndEnv
(
Long
moveId
,
Long
envId
)
{
LambdaQueryWrapper
<
Action
>
actionWrappers
=
Wrappers
.
lambdaQuery
(
Action
.
class
);
Action
action
=
actionMapper
.
selectOne
(
actionWrappers
.
eq
(
Action:
:
getMoveId
,
moveId
)
.
eq
(
Action:
:
getEnvId
,
envId
));
return
Optional
.
ofNullable
(
action
);
}
}
kt-base/src/main/java/org/matrix/database/service/impl/DynamicVariableServiceImpl.java
浏览文件 @
f38e0b2e
...
...
@@ -35,7 +35,7 @@ public class DynamicVariableServiceImpl extends ServiceImpl<DynamicVariableMappe
*/
@Override
public
Optional
<
DynamicVariable
>
getByName
(
String
name
,
Long
projectId
)
{
return
Optional
.
ofNullable
(
mapper
.
selectOne
(
Wrappers
.
lambda
Update
(
DynamicVariable
.
class
)
return
Optional
.
ofNullable
(
mapper
.
selectOne
(
Wrappers
.
lambda
Query
(
DynamicVariable
.
class
)
.
eq
(
DynamicVariable:
:
getName
,
name
)
.
eq
(
DynamicVariable:
:
getProjectId
,
projectId
)));
}
...
...
kt-base/src/main/java/org/matrix/enums/ActionType.java
0 → 100644
浏览文件 @
f38e0b2e
package
org
.
matrix
.
enums
;
import
com.baomidou.mybatisplus.annotation.EnumValue
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
/**
* ActionType.
* 动作的类型,该变量决定了运行时使用哪一种执行器
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2022/2/25 at 5:18 PM
* Suffering is the most powerful teacher of life.
*/
@Getter
@AllArgsConstructor
public
enum
ActionType
{
/**
* SQL类型动作,该动作执行SQL语句
*/
SQL_ACTION
(
1
,
"SQL类型动作"
),
/**
* HTTP类型动作,该动作执行HTTP接口
*/
HTTP_ACTION
(
2
,
"HTTP类型动作"
),
/**
* 用例类型动作,该动作执行另外的测试用例
*/
CASE_ACTION
(
3
,
"用例类型动作"
),
/**
* 等待类动作,线程休眠指定的秒数
*/
WAIT_ACTION
(
4
,
"等待类动作"
);
/**
* 数据库里记录的字段使用该字段来记录
*/
@EnumValue
private
final
int
code
;
private
final
String
des
;
}
kt-base/src/main/java/org/matrix/util/BeanFlattener.java
0 → 100644
浏览文件 @
f38e0b2e
package
org
.
matrix
.
util
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Modifier
;
import
java.util.*
;
/**
* BeanFlattener. javaBean 转对象
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2022/3/7 at 5:15 PM
* Suffering is the most powerful teacher of life.
*/
public
final
class
BeanFlattener
{
private
BeanFlattener
()
{}
public
static
Map
<
String
,
Object
>
deepToMap
(
Object
bean
)
{
Map
<
String
,
Object
>
map
=
new
LinkedHashMap
<>();
try
{
putValues
(
bean
,
map
,
null
);
}
catch
(
IllegalAccessException
x
)
{
throw
new
IllegalArgumentException
(
x
);
}
return
map
;
}
private
static
void
putValues
(
Object
bean
,
Map
<
String
,
Object
>
map
,
String
prefix
)
throws
IllegalAccessException
{
Class
<?>
cls
=
bean
.
getClass
();
for
(
Field
field
:
cls
.
getDeclaredFields
())
{
if
(
field
.
isSynthetic
()
||
Modifier
.
isStatic
(
field
.
getModifiers
()))
{
continue
;
}
field
.
setAccessible
(
true
);
Object
value
=
field
.
get
(
bean
);
String
key
;
if
(
prefix
==
null
)
{
key
=
field
.
getName
();
}
else
{
key
=
prefix
+
"."
+
field
.
getName
();
}
if
(
isValue
(
value
))
{
map
.
put
(
key
,
value
);
}
else
{
putValues
(
value
,
map
,
key
);
}
}
}
private
static
final
Set
<
Class
<?>>
VALUE_CLASSES
=
Collections
.
unmodifiableSet
(
new
HashSet
<>(
Arrays
.
asList
(
Object
.
class
,
String
.
class
,
Boolean
.
class
,
Character
.
class
,
Byte
.
class
,
Short
.
class
,
Integer
.
class
,
Long
.
class
,
Float
.
class
,
Double
.
class
// etc.
)));
private
static
boolean
isValue
(
Object
value
)
{
return
value
==
null
||
value
instanceof
Enum
<?>
||
VALUE_CLASSES
.
contains
(
value
.
getClass
());
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论