提交 55c57ba4 authored 作者: Matrix's avatar Matrix

refactor(SQL执行器): 将SQL执行器里的环境变量替换抽离到环境执行器里

上级 e7acb461
package org.matrix.actuators.env;
import cn.hutool.core.util.ReUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.matrix.actuators.Actuator;
import org.matrix.database.entity.Environment;
import org.matrix.database.service.IEnvironmentService;
import org.matrix.exception.GlobalException;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* EnvironmentActuator.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2022/1/21 at 4:19 PM
* Suffering is the most powerful teacher of life.
*/
@Slf4j
@Component
@AllArgsConstructor
public class EnvironmentActuator implements Actuator {
private final IEnvironmentService envService;
/**
* 用于正则找出形如#{id}这样的环境
*/
public static final String ENV_VAR_EXP = "(#\\{(\\w*)})";
/**
* 替换掉SQL表达式中的形如#{id}这样的环境共享变量
* <blockquote><pre>
* 替换前 : select * from user where id = #{id}
* env的变量表 : key = id , value = 5
* 替换后 : select * from user where id = 5
* </pre></blockquote>
*
* @param sqlExp sql表达式
* @param envId 环境共享变量
* @return 替换后的字符串
*/
public String replaceEnvVar(String sqlExp, Long envId) {
// SQL表达式首先尝试替换掉形如#{name}的共享环境变量 todo 这里的env的map应该做一个缓存
Environment env = Optional.of(envService.getById(envId))
.orElseThrow(() -> new GlobalException("没有找到对应ID的example(env)对象,id = " + envId));
Map<String, String> envMap = env.getVariable();
List<String> envList = ReUtil.findAll(ENV_VAR_EXP, sqlExp, 2, new ArrayList<>());
// 到对应env的变量池里找到值替换掉
for (String key : envList) {
if (envMap.containsKey(key)) {
log.info("[变量替换] 将环境变量 {} 替换为 {}", String.format("#{%s}", key), envMap.get(key));
sqlExp = sqlExp.replaceAll(String.format("#\\{%s}", key), envMap.get(key));
} else {
throw new GlobalException(String.format("id = %d 的环境(用例)表里没有key = %s 的数值,当前环境的变量池 = %s",
envId, key, envMap));
}
}
return sqlExp;
}
}
package org.matrix.actuators.sql;
import cn.hutool.core.util.ReUtil;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.matrix.actuators.Actuator;
import org.matrix.actuators.datasource.DataSourceDTO;
import org.matrix.actuators.datasource.IDataSourceService;
import org.matrix.actuators.env.EnvironmentActuator;
import org.matrix.actuators.httpclient.HttpClientActuator;
import org.matrix.actuators.httpclient.HttpRequestDetail;
import org.matrix.actuators.httpclient.HttpResponseDetail;
import org.matrix.actuators.usecase.CaseActuator;
import org.matrix.config.HttpRequestConfig;
import org.matrix.database.entity.DynamicVariable;
import org.matrix.database.entity.Environment;
import org.matrix.database.entity.TestCase;
import org.matrix.database.service.IConnectService;
import org.matrix.database.service.IDynamicVariableService;
import org.matrix.database.service.IEnvironmentService;
import org.matrix.database.service.ITestCaseService;
import org.matrix.enums.DynamicVarType;
import org.matrix.exception.GlobalException;
......@@ -41,6 +40,7 @@ import static org.springframework.util.CollectionUtils.isEmpty;
*/
@Slf4j
@Component
@AllArgsConstructor
public class SqlExpActuator implements Actuator {
/**
......@@ -54,27 +54,13 @@ public class SqlExpActuator implements Actuator {
*/
public static final String REPLACE_VAR_EXP = "\\$\\{%s}(\\[\\w*])?";
/**
* 用于正则找出形如#{id}这样的环境
*/
public static final String ENV_VAR_EXP = "(#\\{(\\w*)})";
private final JdbcTemplate jdbcTemplate;
private final EnvironmentActuator envActuator;
private final IDynamicVariableService varService;
private final IEnvironmentService envService;
private final IConnectService connectService;
private final IDataSourceService dataSourceService;
private final ITestCaseService caseService;
public SqlExpActuator(JdbcTemplate jdbcTemplate, IDynamicVariableService varService, IEnvironmentService envService, IConnectService connectService, IDataSourceService dataSourceService, ITestCaseService caseService) {
this.jdbcTemplate = jdbcTemplate;
this.varService = varService;
this.envService = envService;
this.connectService = connectService;
this.dataSourceService = dataSourceService;
this.caseService = caseService;
}
/**
* 解析给定的动态变量ByName
*
......@@ -110,6 +96,15 @@ public class SqlExpActuator implements Actuator {
return parseVar(envId, 0, projectId, dynamicVar);
}
/**
* 依据不同的变量类型调用不同的解析Handler
* @param envId 环境ID - 环境共享变量需要
* @param takenIndex 使用的结果集下标,递归传递
* @param projectId 项目id,防止SQL表达式中带的嵌合动态变量名字重复
* @param dynamicVar {@link DynamicVariable}
* @return 变量递归解析后的值
*/
private String parseVar(Long envId, Integer takenIndex, Long projectId, DynamicVariable dynamicVar) {
DynamicVarType varType = dynamicVar.getType();
log.info("[SQL解析器] 当前解析的动态变量是: {}", JSON.toJSONString(dynamicVar));
......@@ -117,11 +112,11 @@ public class SqlExpActuator implements Actuator {
if (varType == CONSTANT_VARIABLE) {
return dynamicVar.getDetail();
} else if (varType == SQL_VARIABLE) {
return handleSqlVar(envId, takenIndex, projectId, dynamicVar);
return sqlVarHandler(envId, takenIndex, projectId, dynamicVar);
} else if (varType == HTTP_VARIABLE) {
return handleHttpVar(envId, projectId, dynamicVar);
return httpVarHandler(envId, projectId, dynamicVar);
} else if (varType == CASE_VARIABLE) {
return handleCaseVar(envId, projectId, dynamicVar);
return usecaseHandler(envId, projectId, dynamicVar);
} else {
throw new GlobalException("不支持的动态变量类型: " + varType);
}
......@@ -135,7 +130,7 @@ public class SqlExpActuator implements Actuator {
* @param dynamicVar {@link DynamicVariable}
* @return 解析后的字符串
*/
private String handleCaseVar(Long envId, Long projectId, DynamicVariable dynamicVar) {
private String usecaseHandler(Long envId, Long projectId, DynamicVariable dynamicVar) {
CaseActuator caseActuator = new CaseActuator(envId, projectId);
long caseId = Long.parseLong(dynamicVar.getDetail());
TestCase testCase = Optional.of(caseService.getById(caseId))
......@@ -152,7 +147,7 @@ public class SqlExpActuator implements Actuator {
* @param dynamicVar {@link DynamicVariable}
* @return 解析后的字符串
*/
private String handleHttpVar(Long envId, Long projectId, DynamicVariable dynamicVar) {
private String httpVarHandler(Long envId, Long projectId, DynamicVariable dynamicVar) {
HttpClientActuator httpClient = new HttpClientActuator(new HttpRequestConfig(), envId, projectId);
HttpRequestDetail httpRequestDetail = JSON.parseObject(dynamicVar.getDetail(), HttpRequestDetail.class);
return httpClient.sendHttpRequest(httpRequestDetail).getResponseBody();
......@@ -166,10 +161,10 @@ public class SqlExpActuator implements Actuator {
* @param dynamicVar {@link DynamicVariable}
* @return 解析后的字符串
*/
private String handleSqlVar(Long envId, Integer takenIndex, Long projectId, DynamicVariable dynamicVar) {
private String sqlVarHandler(Long envId, Integer takenIndex, Long projectId, DynamicVariable dynamicVar) {
// 首先替换掉#{id}这类的共享变量(如果有的话)
String sqlExp = dynamicVar.getSqlExpDetail().getSqlExp();
sqlExp = replaceEnvVar(sqlExp, envId);
sqlExp = envActuator.replaceEnvVar(sqlExp, envId);
List<SqlRegularObject> dynamicVarList = findDynamicVarList(dynamicVar.getDetail());
// 解析SQL表达式,判断是可以直接执行的SQL还是需要再递归解析动态变量
......@@ -209,32 +204,6 @@ public class SqlExpActuator implements Actuator {
}
/**
* 替换掉SQL表达式中的形如#{id}这样的环境共享变量
*
* @param sqlExp sql表达式
* @param envId 环境共享变量
* @return 替换后的字符串
*/
private String replaceEnvVar(String sqlExp, Long envId) {
// SQL表达式首先尝试替换掉形如#{name}的共享环境变量 todo 这里的env的map应该做一个缓存
Environment env = Optional.of(envService.getById(envId))
.orElseThrow(() -> new GlobalException("没有找到对应ID的example(env)对象,id = " + envId));
Map<String, String> envMap = env.getVariable();
List<String> envList = ReUtil.findAll(ENV_VAR_EXP, sqlExp, 2, new ArrayList<>());
// 到对应env的变量池里找到值替换掉
for (String key : envList) {
if (envMap.containsKey(key)) {
log.info("[变量替换] 将环境变量 {} 替换为 {}", String.format("#{%s}", key), envMap.get(key));
sqlExp = sqlExp.replaceAll(String.format("#\\{%s}", key), envMap.get(key));
} else {
throw new GlobalException(String.format("id = %d 的环境(用例)表里没有key = %s 的数值,当前环境的变量池 = %s",
envId, key, envMap));
}
}
return sqlExp;
}
/**
* 执行一段SQL,该SQL表达式必须要是可以直接执行的语句
......@@ -252,7 +221,7 @@ public class SqlExpActuator implements Actuator {
.toDataSourceDTO();
// 替换环境共享变量
sqlExp = replaceEnvVar(sqlExp, envId);
sqlExp = envActuator.replaceEnvVar(sqlExp, envId);
// 校验dynamicVar里的detail是否是可以直接执行的SQL
if (dynamicVar.getType() == SQL_VARIABLE && findDynamicVarList(sqlExp).size() == 0) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论