提交 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; package org.matrix.actuators.sql;
import cn.hutool.core.util.ReUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.matrix.actuators.Actuator; import org.matrix.actuators.Actuator;
import org.matrix.actuators.datasource.DataSourceDTO; import org.matrix.actuators.datasource.DataSourceDTO;
import org.matrix.actuators.datasource.IDataSourceService; import org.matrix.actuators.datasource.IDataSourceService;
import org.matrix.actuators.env.EnvironmentActuator;
import org.matrix.actuators.httpclient.HttpClientActuator; import org.matrix.actuators.httpclient.HttpClientActuator;
import org.matrix.actuators.httpclient.HttpRequestDetail; import org.matrix.actuators.httpclient.HttpRequestDetail;
import org.matrix.actuators.httpclient.HttpResponseDetail; import org.matrix.actuators.httpclient.HttpResponseDetail;
import org.matrix.actuators.usecase.CaseActuator; import org.matrix.actuators.usecase.CaseActuator;
import org.matrix.config.HttpRequestConfig; import org.matrix.config.HttpRequestConfig;
import org.matrix.database.entity.DynamicVariable; import org.matrix.database.entity.DynamicVariable;
import org.matrix.database.entity.Environment;
import org.matrix.database.entity.TestCase; import org.matrix.database.entity.TestCase;
import org.matrix.database.service.IConnectService; import org.matrix.database.service.IConnectService;
import org.matrix.database.service.IDynamicVariableService; import org.matrix.database.service.IDynamicVariableService;
import org.matrix.database.service.IEnvironmentService;
import org.matrix.database.service.ITestCaseService; import org.matrix.database.service.ITestCaseService;
import org.matrix.enums.DynamicVarType; import org.matrix.enums.DynamicVarType;
import org.matrix.exception.GlobalException; import org.matrix.exception.GlobalException;
...@@ -41,6 +40,7 @@ import static org.springframework.util.CollectionUtils.isEmpty; ...@@ -41,6 +40,7 @@ import static org.springframework.util.CollectionUtils.isEmpty;
*/ */
@Slf4j @Slf4j
@Component @Component
@AllArgsConstructor
public class SqlExpActuator implements Actuator { public class SqlExpActuator implements Actuator {
/** /**
...@@ -54,27 +54,13 @@ public class SqlExpActuator implements Actuator { ...@@ -54,27 +54,13 @@ public class SqlExpActuator implements Actuator {
*/ */
public static final String REPLACE_VAR_EXP = "\\$\\{%s}(\\[\\w*])?"; public static final String REPLACE_VAR_EXP = "\\$\\{%s}(\\[\\w*])?";
/**
* 用于正则找出形如#{id}这样的环境
*/
public static final String ENV_VAR_EXP = "(#\\{(\\w*)})";
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final EnvironmentActuator envActuator;
private final IDynamicVariableService varService; private final IDynamicVariableService varService;
private final IEnvironmentService envService;
private final IConnectService connectService; private final IConnectService connectService;
private final IDataSourceService dataSourceService; private final IDataSourceService dataSourceService;
private final ITestCaseService caseService; 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 * 解析给定的动态变量ByName
* *
...@@ -110,6 +96,15 @@ public class SqlExpActuator implements Actuator { ...@@ -110,6 +96,15 @@ public class SqlExpActuator implements Actuator {
return parseVar(envId, 0, projectId, dynamicVar); 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) { private String parseVar(Long envId, Integer takenIndex, Long projectId, DynamicVariable dynamicVar) {
DynamicVarType varType = dynamicVar.getType(); DynamicVarType varType = dynamicVar.getType();
log.info("[SQL解析器] 当前解析的动态变量是: {}", JSON.toJSONString(dynamicVar)); log.info("[SQL解析器] 当前解析的动态变量是: {}", JSON.toJSONString(dynamicVar));
...@@ -117,11 +112,11 @@ public class SqlExpActuator implements Actuator { ...@@ -117,11 +112,11 @@ public class SqlExpActuator implements Actuator {
if (varType == CONSTANT_VARIABLE) { if (varType == CONSTANT_VARIABLE) {
return dynamicVar.getDetail(); return dynamicVar.getDetail();
} else if (varType == SQL_VARIABLE) { } else if (varType == SQL_VARIABLE) {
return handleSqlVar(envId, takenIndex, projectId, dynamicVar); return sqlVarHandler(envId, takenIndex, projectId, dynamicVar);
} else if (varType == HTTP_VARIABLE) { } else if (varType == HTTP_VARIABLE) {
return handleHttpVar(envId, projectId, dynamicVar); return httpVarHandler(envId, projectId, dynamicVar);
} else if (varType == CASE_VARIABLE) { } else if (varType == CASE_VARIABLE) {
return handleCaseVar(envId, projectId, dynamicVar); return usecaseHandler(envId, projectId, dynamicVar);
} else { } else {
throw new GlobalException("不支持的动态变量类型: " + varType); throw new GlobalException("不支持的动态变量类型: " + varType);
} }
...@@ -135,7 +130,7 @@ public class SqlExpActuator implements Actuator { ...@@ -135,7 +130,7 @@ public class SqlExpActuator implements Actuator {
* @param dynamicVar {@link DynamicVariable} * @param dynamicVar {@link DynamicVariable}
* @return 解析后的字符串 * @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); CaseActuator caseActuator = new CaseActuator(envId, projectId);
long caseId = Long.parseLong(dynamicVar.getDetail()); long caseId = Long.parseLong(dynamicVar.getDetail());
TestCase testCase = Optional.of(caseService.getById(caseId)) TestCase testCase = Optional.of(caseService.getById(caseId))
...@@ -152,7 +147,7 @@ public class SqlExpActuator implements Actuator { ...@@ -152,7 +147,7 @@ public class SqlExpActuator implements Actuator {
* @param dynamicVar {@link DynamicVariable} * @param dynamicVar {@link DynamicVariable}
* @return 解析后的字符串 * @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); HttpClientActuator httpClient = new HttpClientActuator(new HttpRequestConfig(), envId, projectId);
HttpRequestDetail httpRequestDetail = JSON.parseObject(dynamicVar.getDetail(), HttpRequestDetail.class); HttpRequestDetail httpRequestDetail = JSON.parseObject(dynamicVar.getDetail(), HttpRequestDetail.class);
return httpClient.sendHttpRequest(httpRequestDetail).getResponseBody(); return httpClient.sendHttpRequest(httpRequestDetail).getResponseBody();
...@@ -166,10 +161,10 @@ public class SqlExpActuator implements Actuator { ...@@ -166,10 +161,10 @@ public class SqlExpActuator implements Actuator {
* @param dynamicVar {@link DynamicVariable} * @param dynamicVar {@link DynamicVariable}
* @return 解析后的字符串 * @return 解析后的字符串
*/ */
private String handleSqlVar(Long envId, Integer takenIndex, Long projectId, DynamicVariable dynamicVar) { private String sqlVarHandler(Long envId, Integer takenIndex, Long projectId, DynamicVariable dynamicVar) {
// 首先替换掉#{id}这类的共享变量(如果有的话) // 首先替换掉#{id}这类的共享变量(如果有的话)
String sqlExp = dynamicVar.getSqlExpDetail().getSqlExp(); String sqlExp = dynamicVar.getSqlExpDetail().getSqlExp();
sqlExp = replaceEnvVar(sqlExp, envId); sqlExp = envActuator.replaceEnvVar(sqlExp, envId);
List<SqlRegularObject> dynamicVarList = findDynamicVarList(dynamicVar.getDetail()); List<SqlRegularObject> dynamicVarList = findDynamicVarList(dynamicVar.getDetail());
// 解析SQL表达式,判断是可以直接执行的SQL还是需要再递归解析动态变量 // 解析SQL表达式,判断是可以直接执行的SQL还是需要再递归解析动态变量
...@@ -209,32 +204,6 @@ public class SqlExpActuator implements Actuator { ...@@ -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表达式必须要是可以直接执行的语句 * 执行一段SQL,该SQL表达式必须要是可以直接执行的语句
...@@ -252,7 +221,7 @@ public class SqlExpActuator implements Actuator { ...@@ -252,7 +221,7 @@ public class SqlExpActuator implements Actuator {
.toDataSourceDTO(); .toDataSourceDTO();
// 替换环境共享变量 // 替换环境共享变量
sqlExp = replaceEnvVar(sqlExp, envId); sqlExp = envActuator.replaceEnvVar(sqlExp, envId);
// 校验dynamicVar里的detail是否是可以直接执行的SQL // 校验dynamicVar里的detail是否是可以直接执行的SQL
if (dynamicVar.getType() == SQL_VARIABLE && findDynamicVarList(sqlExp).size() == 0) { if (dynamicVar.getType() == SQL_VARIABLE && findDynamicVarList(sqlExp).size() == 0) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论