fix(场景自动化): 优化运行环境

This commit is contained in:
shiziyuan9527 2021-04-01 19:23:54 +08:00 committed by BugKing
parent 22fd1fa93e
commit 40f99ad65a
9 changed files with 244 additions and 34 deletions

View File

@ -2,8 +2,10 @@ package io.metersphere.api.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.api.dto.ApiScenarioEnvRequest;
import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.JmxInfoDTO;
import io.metersphere.api.dto.ScenarioEnv;
import io.metersphere.api.dto.automation.*;
import io.metersphere.api.dto.automation.parse.ScenarioImport;
import io.metersphere.api.dto.definition.RunDefinitionRequest;
@ -99,6 +101,11 @@ public class ApiAutomationController {
return apiAutomationService.getApiScenario(id);
}
@PostMapping("/getApiScenarioEnv")
public ScenarioEnv getScenarioDefinition(@RequestBody ApiScenarioEnvRequest request) {
return apiAutomationService.getApiScenarioEnv(request.getDefinition());
}
@PostMapping("/getApiScenarios")
public List<ApiScenarioWithBLOBs> getApiScenarios(@RequestBody List<String> ids) {
return apiAutomationService.getApiScenarios(ids);

View File

@ -0,0 +1,11 @@
package io.metersphere.api.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class ApiScenarioEnvRequest {
private String definition;
}

View File

@ -0,0 +1,15 @@
package io.metersphere.api.dto;
import lombok.Getter;
import lombok.Setter;
import java.util.HashSet;
import java.util.Set;
@Getter
@Setter
public class ScenarioEnv {
private Set<String> projectIds = new HashSet<>();
private Boolean fullUrl = true;
}

View File

@ -4,18 +4,21 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.DeleteAPIReportRequest;
import io.metersphere.api.dto.JmxInfoDTO;
import io.metersphere.api.dto.ScenarioEnv;
import io.metersphere.api.dto.automation.*;
import io.metersphere.api.dto.automation.parse.ScenarioImport;
import io.metersphere.api.dto.automation.parse.ScenarioImportParserFactory;
import io.metersphere.api.dto.datacount.ApiDataCountResult;
import io.metersphere.api.dto.definition.RunDefinitionRequest;
import io.metersphere.api.dto.definition.request.*;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.definition.request.unknown.MsJmeterElement;
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
@ -93,6 +96,10 @@ public class ApiAutomationService {
private TestPlanScenarioCaseService testPlanScenarioCaseService;
@Resource
private EsbApiParamService esbApiParamService;
@Resource
private ApiTestCaseService apiTestCaseService;
@Resource
private ApiDefinitionService apiDefinitionService;
public List<ApiScenarioDTO> list(ApiScenarioRequest request) {
request = this.initRequest(request, true, true);
@ -365,6 +372,144 @@ public class ApiAutomationService {
return null;
}
public ScenarioEnv getApiScenarioEnv(String definition) {
ObjectMapper mapper = new ObjectMapper();
ScenarioEnv env = new ScenarioEnv();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
JSONObject element = JSON.parseObject(definition);
List<MsTestElement> hashTree = mapper.readValue(element.getString("hashTree"), new TypeReference<LinkedList<MsTestElement>>(){});
for (int i = 0; i < hashTree.size(); i++) {
MsTestElement tr = hashTree.get(i);
String referenced = tr.getReferenced();
if (StringUtils.equals(MsTestElementConstants.REF.name(), referenced)) {
if (StringUtils.equals(tr.getType(), "HTTPSamplerProxy")) {
MsHTTPSamplerProxy http = (MsHTTPSamplerProxy)tr;
String refType = tr.getRefType();
if (StringUtils.equals(refType, "CASE")) {
http.setUrl(null);
} else {
ApiDefinition apiDefinition = apiDefinitionService.get(tr.getId());
http.setUrl(apiDefinition.getPath());
}
if (StringUtils.isBlank(http.getUrl()) || !isURL(http.getUrl())) {
env.getProjectIds().add(http.getProjectId());
env.setFullUrl(false);
}
} else if (StringUtils.equals(tr.getType(), "TCPSampler")) {
if (StringUtils.equals(tr.getRefType(), "CASE")) {
ApiTestCaseWithBLOBs apiTestCaseWithBLOBs = apiTestCaseService.get(tr.getId());
env.getProjectIds().add(apiTestCaseWithBLOBs.getProjectId());
} else {
ApiDefinition apiDefinition = apiDefinitionService.get(tr.getId());
env.getProjectIds().add(apiDefinition.getProjectId());
}
} else if (StringUtils.equals(tr.getType(), "scenario")) {
ApiScenarioDTO apiScenario = getApiScenario(tr.getId());
String scenarioDefinition = apiScenario.getScenarioDefinition();
JSONObject element1 = JSON.parseObject(scenarioDefinition);
LinkedList<MsTestElement> hashTree1 = mapper.readValue(element1.getString("hashTree"), new TypeReference<LinkedList<MsTestElement>>(){});
tr.setHashTree(hashTree1);
}
} else {
if (StringUtils.equals(tr.getType(), "HTTPSamplerProxy")) {
// 校验是否是全路径
MsHTTPSamplerProxy httpSamplerProxy = (MsHTTPSamplerProxy)tr;
if (httpSamplerProxy.isEnable()) {
if (StringUtils.isBlank(httpSamplerProxy.getUrl()) || !isURL(httpSamplerProxy.getUrl())) {
env.getProjectIds().add(httpSamplerProxy.getProjectId());
env.setFullUrl(false);
}
}
} else if (StringUtils.equals(tr.getType(), "TCPSampler")) {
env.getProjectIds().add(tr.getProjectId());
}
}
if (CollectionUtils.isNotEmpty(tr.getHashTree())) {
getHashTree(tr.getHashTree(), env);
}
}
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return env;
}
private void getHashTree(List<MsTestElement> tree, ScenarioEnv env) {
try {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
for (int i = 0; i < tree.size(); i++) {
MsTestElement tr = tree.get(i);
String referenced = tr.getReferenced();
if (StringUtils.equals(MsTestElementConstants.REF.name(), referenced)) {
if (StringUtils.equals(tr.getType(), "HTTPSamplerProxy")) {
MsHTTPSamplerProxy http = (MsHTTPSamplerProxy)tr;
String refType = tr.getRefType();
if (StringUtils.equals(refType, "CASE")) {
http.setUrl(null);
} else {
ApiDefinition apiDefinition = apiDefinitionService.get(tr.getId());
http.setUrl(apiDefinition.getPath());
}
if (StringUtils.isBlank(http.getUrl()) || !this.isURL(http.getUrl())) {
env.setFullUrl(false);
env.getProjectIds().add(http.getProjectId());
}
} else if (StringUtils.equals(tr.getType(), "TCPSampler")) {
if (StringUtils.equals(tr.getRefType(), "CASE")) {
ApiTestCaseWithBLOBs apiTestCaseWithBLOBs = apiTestCaseService.get(tr.getId());
env.getProjectIds().add(apiTestCaseWithBLOBs.getProjectId());
} else {
ApiDefinition apiDefinition = apiDefinitionService.get(tr.getId());
env.getProjectIds().add(apiDefinition.getProjectId());
}
} else if (StringUtils.equals(tr.getType(), "scenario")) {
ApiScenarioDTO apiScenario = getApiScenario(tr.getId());
String scenarioDefinition = apiScenario.getScenarioDefinition();
JSONObject element1 = JSON.parseObject(scenarioDefinition);
LinkedList<MsTestElement> hashTree1 = mapper.readValue(element1.getString("hashTree"), new TypeReference<LinkedList<MsTestElement>>(){});
tr.setHashTree(hashTree1);
}
} else {
if (StringUtils.equals(tr.getType(), "HTTPSamplerProxy")) {
// 校验是否是全路径
MsHTTPSamplerProxy httpSamplerProxy = (MsHTTPSamplerProxy)tr;
if (httpSamplerProxy.isEnable()) {
if (StringUtils.isBlank(httpSamplerProxy.getUrl()) || !isURL(httpSamplerProxy.getUrl())) {
env.setFullUrl(false);
env.getProjectIds().add(httpSamplerProxy.getProjectId());
}
}
} else if (StringUtils.equals(tr.getType(), "TCPSampler")) {
env.getProjectIds().add(tr.getProjectId());
}
}
if (CollectionUtils.isNotEmpty(tr.getHashTree())) {
getHashTree(tr.getHashTree(), env);
}
}
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
private boolean isURL(String str) {
try {
String regex = "^((https|http|ftp|rtsp|mms)?://)"
+ "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?"
+ "(([0-9]{1,3}\\.){3}[0-9]{1,3}" + "|" + "([0-9a-z_!~*'()-]+\\.)*"
+ "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\\."
+ "[a-z]{2,6})"
+ "(:[0-9]{1,5})?"
+ "((/?)|"
+ "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";
return str.matches(regex) || (str.matches("^(http|https|ftp)://.*$") && str.matches(".*://\\$\\{.*$"));
} catch (Exception e) {
return false;
}
}
public List<ApiScenarioWithBLOBs> getApiScenarios(List<String> ids) {
if (CollectionUtils.isNotEmpty(ids)) {
return extApiScenarioMapper.selectIds(ids);

View File

@ -61,6 +61,7 @@
this.request.method = row.method;
}
this.request.resourceId = getUUID();
this.request.projectId = this.$store.state.projectId;
let obj = {};
Object.assign(obj, this.request);
this.$emit('addCustomizeApi', obj);

View File

@ -325,6 +325,7 @@
projectList: [],
debugResult: new Map,
drawer: false,
isFullUrl: true
}
},
created() {
@ -602,6 +603,11 @@
if (!arr[i].projectId) {
// IDIDIDID
arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId;
} else {
const project = this.projectList.find(p => p.id === arr[i].projectId);
if (!project) {
arr[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId;
}
}
if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) {
@ -625,6 +631,11 @@
// ID
if (!this.scenarioDefinition[i].projectId) {
this.scenarioDefinition[i].projectId = this.projectId;
} else {
const project = this.projectList.find(p => p.id === this.scenarioDefinition[i].projectId);
if (!project) {
this.scenarioDefinition[i].projectId = this.projectId;
}
}
if (this.scenarioDefinition[i].hashTree != undefined && this.scenarioDefinition[i].hashTree.length > 0) {
@ -647,7 +658,7 @@
this.customizeRequest = {};
this.sort();
this.reload();
this.initProjectIds();
// this.initProjectIds();
},
addScenario(arr) {
if (arr && arr.length > 0) {
@ -670,7 +681,7 @@
this.isBtnHide = false;
this.sort();
this.reload();
this.initProjectIds();
// this.initProjectIds();
},
setApiParameter(item, refType, referenced) {
let request = {};
@ -712,7 +723,7 @@
this.isBtnHide = false;
this.sort();
this.reload();
this.initProjectIds();
// this.initProjectIds();
},
getMaintainerOptions() {
let workspaceId = localStorage.getItem(WORKSPACE_ID);
@ -739,7 +750,7 @@
hashTree.splice(index, 1);
this.sort();
this.reload();
this.initProjectIds();
// this.initProjectIds();
}
}
});
@ -766,11 +777,14 @@
this.loading = true
this.$nextTick(() => {
this.loading = false
})
});
let definition = JSON.parse(JSON.stringify(this.currentScenario));
definition.hashTree = this.scenarioDefinition;
this.getEnv(JSON.stringify(definition));
},
runDebug() {
/*触发执行操作*/
let sign = this.$refs.envPopover.checkEnv(this.scenarioDefinition);
let sign = this.$refs.envPopover.checkEnv(this.isFullUrl);
if (!sign) {
return;
}
@ -961,6 +975,14 @@
})
});
},
getEnv(definition) {
this.$post("/api/automation/getApiScenarioEnv", {definition: definition}, res => {
if (res.data) {
this.projectIds = new Set(res.data.projectIds);
this.isFullUrl = res.data.fullUrl;
}
})
},
getApiScenario() {
this.loading = true;
if (this.currentScenario.tags != undefined && !(this.currentScenario.tags instanceof Array)) {
@ -977,6 +999,7 @@
if (response.data) {
this.path = "/api/automation/update";
if (response.data.scenarioDefinition != null) {
this.getEnv(response.data.scenarioDefinition);
let obj = JSON.parse(response.data.scenarioDefinition);
if (obj) {
this.currentEnvironmentId = obj.environmentId;
@ -1015,7 +1038,7 @@
}
this.loading = false;
this.sort();
this.initProjectIds();
// this.initProjectIds();
// this.getEnvironments();
})
}
@ -1085,18 +1108,18 @@
})
},
refReload() {
this.initProjectIds();
// this.initProjectIds();
this.reload();
},
initProjectIds() {
//
this.$nextTick(() => {
this.projectIds.clear();
this.scenarioDefinition.forEach(data => {
let arr = jsonPath.query(data, "$..projectId");
arr.forEach(a => this.projectIds.add(a));
})
})
// //
// this.$nextTick(() => {
// this.projectIds.clear();
// this.scenarioDefinition.forEach(data => {
// let arr = jsonPath.query(data, "$..projectId");
// arr.forEach(a => this.projectIds.add(a));
// })
// })
},
detailRefresh(result) {
//

View File

@ -243,7 +243,9 @@
}
})
} else {
sign = false;
if (!data) {
sign = false;
}
}
//
//this.checkFullUrl(data);

View File

@ -258,9 +258,7 @@
this.request.id = response.data.id;
this.request.disabled = true;
this.request.root = true;
if (!this.request.projectId) {
this.request.projectId = response.data.projectId;
}
this.request.projectId = response.data.projectId;
this.reload();
this.sort();
} else {

View File

@ -68,14 +68,16 @@
obj = JSON.parse(response.data.scenarioDefinition);
this.scenario.hashTree = obj.hashTree;
}
this.scenario.projectId = response.data.projectId;
const pro = this.projectList.find(p => p.id === response.data.projectId);
if (!pro) {
this.scenario.projectId = this.$store.state.projectId;
}
if (this.scenario.hashTree) {
this.setDisabled(this.scenario.hashTree);
this.setDisabled(this.scenario.hashTree, this.scenario.projectId);
}
//this.scenario.disabled = true;
this.scenario.name = response.data.name;
if (!this.scenario.projectId) {
this.scenario.projectId = response.data.projectId;
}
this.scenario.headers = obj.headers;
this.scenario.variables = obj.variables;
this.scenario.environmentMap = obj.environmentMap;
@ -123,25 +125,31 @@
this.loading = false
})
},
recursive(arr) {
recursive(arr, id) {
for (let i in arr) {
arr[i].disabled = true;
if (!arr[i].projectId) {
arr[i].projectId = getCurrentProjectID();
}
arr[i].projectId = this.calcProjectId(arr[i].projectId, id);
if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) {
this.recursive(arr[i].hashTree);
this.recursive(arr[i].hashTree, arr[i].projectId);
}
}
},
setDisabled(scenarioDefinition) {
setDisabled(scenarioDefinition, id) {
for (let i in scenarioDefinition) {
scenarioDefinition[i].disabled = true;
if (!scenarioDefinition[i].projectId) {
scenarioDefinition[i].projectId = getCurrentProjectID();
}
scenarioDefinition[i].projectId = this.calcProjectId(scenarioDefinition[i].projectId, id);
if (scenarioDefinition[i].hashTree != undefined && scenarioDefinition[i].hashTree.length > 0) {
this.recursive(scenarioDefinition[i].hashTree);
this.recursive(scenarioDefinition[i].hashTree, scenarioDefinition[i].projectId);
}
}
},
calcProjectId(projectId, parentId) {
if (!projectId) {
return parentId ? parentId : this.$store.state.projectId;
} else {
const project = this.projectList.find(p => p.id === projectId);
if (!project) {
return parentId ? parentId : this.$store.state.projectId;
}
}
},