diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java index 76084eb565..4e91455ace 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java @@ -80,8 +80,8 @@ public class ApiAutomationController { } @PostMapping("/reduction") - public void reduction(@RequestBody List requests) { - apiAutomationService.reduction(requests); + public void reduction(@RequestBody List ids) { + apiAutomationService.reduction(ids); } @GetMapping("/getApiScenario/{id}") diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java index 4dba923d8b..31fed91906 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java @@ -133,8 +133,8 @@ public class ApiDefinitionController { } @PostMapping("/reduction") - public void reduction(@RequestBody List requests) { - apiDefinitionService.reduction(requests); + public void reduction(@RequestBody ApiBatchRequest request) { + apiDefinitionService.reduction(request); } @GetMapping("/get/{id}") diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/ApiTestBatchRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/ApiTestBatchRequest.java index ab2788aae6..1e8791ce01 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/ApiTestBatchRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/ApiTestBatchRequest.java @@ -40,4 +40,7 @@ public class ApiTestBatchRequest extends ApiTestCaseWithBLOBs { private String protocol; private String status; + + private String envId; + } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java index 3b05aefa87..c51b92ac47 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java @@ -58,6 +58,7 @@ public class Swagger2Parser extends SwaggerAbstractParser { ApiModule parentNode = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId()); + String basePath = swagger.getBasePath(); for (String pathName : pathNames) { Path path = paths.get(pathName); Map operationMap = path.getOperationMap(); @@ -68,6 +69,10 @@ public class Swagger2Parser extends SwaggerAbstractParser { ApiDefinitionWithBLOBs apiDefinition = buildApiDefinition(request.getId(), operation, pathName, method.name(),importRequest); parseParameters(operation, request); addBodyHeader(request); + if (StringUtils.isNotBlank(basePath)) { + apiDefinition.setPath(basePath + apiDefinition.getPath()); + request.setPath(basePath + request.getPath()); + } apiDefinition.setRequest(JSON.toJSONString(request)); apiDefinition.setResponse(JSON.toJSONString(parseResponse(operation, operation.getResponses()))); buildModule(parentNode, apiDefinition, operation.getTags()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java index b1d038c51f..30543eeb31 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java @@ -17,6 +17,8 @@ import org.apache.jmeter.control.LoopController; import org.apache.jmeter.control.RunTime; import org.apache.jmeter.control.WhileController; import org.apache.jmeter.modifiers.CounterConfig; +import org.apache.jmeter.modifiers.JSR223PreProcessor; +import org.apache.jmeter.protocol.java.sampler.JSR223Sampler; import org.apache.jmeter.reporters.ResultAction; import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testelement.TestElement; @@ -24,6 +26,7 @@ import org.apache.jmeter.timers.ConstantTimer; import org.apache.jorphan.collections.HashTree; import java.util.List; +import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @@ -42,6 +45,9 @@ public class MsLoopController extends MsTestElement { @JSONField(ordinal = 23) private MsWhileController whileController; + + private String ms_current_timer = UUID.randomUUID().toString(); + @Override public void toHashTree(HashTree tree, List hashTree, ParameterConfig config) { // 非导出操作,且不是启用状态则跳过执行 @@ -122,7 +128,8 @@ public class MsLoopController extends MsTestElement { operator = ""; value = ""; } - return "${__jexl3(" + variable + operator + value + ")}"; + ms_current_timer = UUID.randomUUID().toString(); + return "${__jexl3(" + variable + operator + value + " && \"${" + ms_current_timer + "}\" !=\"stop\")}"; } private WhileController initWhileController() { @@ -151,6 +158,32 @@ public class MsLoopController extends MsTestElement { return controller; } + private String script() { + String script = "\n" + + "import java.util.*;\n" + + "import java.text.SimpleDateFormat;\n" + + "import org.apache.jmeter.threads.JMeterContextService;\n" + + "\n" + + "// 循环控制器超时后结束循环\n" + + "try{\n" + + "\tString ms_current_timer = vars.get(\"" + ms_current_timer + "\");\n" + + "\tlong _nowTime = System.currentTimeMillis(); \n" + + "\tif(ms_current_timer == null ){\n" + + "\t\tvars.put(\"" + ms_current_timer + "\",_nowTime.toString());\n" + + "\t}\n" + + "\tlong time = Long.parseLong(vars.get(\"" + ms_current_timer + "\"));\n" + + "\t if((_nowTime - time) > " + this.whileController.getTimeout() + " ){\n" + + "\t \tvars.put(\"" + ms_current_timer + "\", \"stop\");\n" + + "\t \tlog.info( \"结束循环\");\n" + + "\t }\n" + + "}catch (Exception e){\n" + + "\tlog.info( e.getMessage());\n" + + "\tvars.put(\"" + ms_current_timer + "\", \"stop\");\n" + + "}\n"; + + return script; + } + private HashTree controller(HashTree tree) { if (StringUtils.equals(this.loopType, LoopConstants.WHILE.name()) && this.whileController != null) { RunTime runTime = new RunTime(); @@ -162,9 +195,17 @@ public class MsLoopController extends MsTestElement { timeout = 1; } runTime.setRuntime(timeout); + HashTree hashTree = tree.add(initWhileController()); // 添加超时处理,防止死循环 - HashTree hashTree = tree.add(runTime); - return hashTree.add(initWhileController()); + JSR223PreProcessor jsr223PreProcessor = new JSR223PreProcessor(); + jsr223PreProcessor.setName("循环超时处理"); + jsr223PreProcessor.setProperty(TestElement.TEST_CLASS, JSR223Sampler.class.getName()); + jsr223PreProcessor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); + jsr223PreProcessor.setProperty("cacheKey", "true"); + jsr223PreProcessor.setProperty("scriptLanguage", "beanshell"); + jsr223PreProcessor.setProperty("script", script()); + hashTree.add(jsr223PreProcessor); + return hashTree; } if (StringUtils.equals(this.loopType, LoopConstants.FOREACH.name()) && this.forEachController != null) { return tree.add(initForeachController()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java index 6a41b3d039..2c1c86c777 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java @@ -34,10 +34,10 @@ public class MsExtract extends MsTestElement { if (!config.isOperating() && !this.isEnable()) { return; } - addRequestExtractors(tree); + addRequestExtractors(tree, config); } - private void addRequestExtractors(HashTree samplerHashTree) { + private void addRequestExtractors(HashTree samplerHashTree, ParameterConfig config) { StringJoiner extract = new StringJoiner(";"); if (CollectionUtils.isNotEmpty(this.getRegex())) { @@ -55,7 +55,7 @@ public class MsExtract extends MsTestElement { samplerHashTree.add(jsonPostProcessor(extractJSONPath, extract)) ); } - if (Optional.ofNullable(extract).orElse(extract).length() > 0) { + if (Optional.ofNullable(extract).orElse(extract).length() > 0 && !config.isOperating()) { JSR223PostProcessor shell = new JSR223PostProcessor(); shell.setEnabled(true); shell.setName(StringUtils.isEmpty(this.getName()) ? "JSR223PostProcessor" : this.getName()); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index 4b4abebdb6..517e9ae764 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -114,9 +114,13 @@ public class ApiAutomationService { Map map = d.getEnvironmentMap(); if (map != null) { if (map.isEmpty()) { - List ids = (List) JSONPath.read(definition, "$..projectId"); - if (CollectionUtils.isNotEmpty(ids)) { - idList.addAll(new HashSet<>(ids)); + try { + List ids = (List) JSONPath.read(definition, "$..projectId"); + if (CollectionUtils.isNotEmpty(ids)) { + idList.addAll(new HashSet<>(ids)); + } + } catch (Exception e) { + LogUtil.error("JSONPath.read projectId fail."); } } else { Set set = d.getEnvironmentMap().keySet(); @@ -316,13 +320,8 @@ public class ApiAutomationService { } } - public void reduction(List requests) { - List apiIds = new ArrayList<>(); - requests.forEach(item -> { - checkNameExist(item); - apiIds.add(item.getId()); - }); - extApiScenarioMapper.reduction(apiIds); + public void reduction(List ids) { + extApiScenarioMapper.reduction(ids); } private void checkNameExist(SaveApiScenarioRequest request) { diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 761f53a2f3..a6cc7ed85e 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -137,10 +137,11 @@ public class ApiDefinitionService { public ApiDefinitionWithBLOBs getBLOBs(String id) { return apiDefinitionMapper.selectByPrimaryKey(id); } + public List getBLOBs(List idList) { - if(idList == null || idList.isEmpty()){ - return new ArrayList<>(0); - }else{ + if (idList == null || idList.isEmpty()) { + return new ArrayList<>(0); + } else { ApiDefinitionExample example = new ApiDefinitionExample(); example.createCriteria().andIdIn(idList); example.setOrderByClause("create_time DESC "); @@ -190,13 +191,8 @@ public class ApiDefinitionService { extApiDefinitionMapper.removeToGc(apiIds); } - public void reduction(List requests) { - List apiIds = new ArrayList<>(); - requests.forEach(item -> { - checkNameExist(item); - apiIds.add(item.getId()); - }); - extApiDefinitionMapper.reduction(apiIds); + public void reduction(ApiBatchRequest request) { + extApiDefinitionMapper.reduction(request.getIds()); } public void deleteBodyFiles(String apiId) { @@ -244,7 +240,7 @@ public class ApiDefinitionService { private ApiDefinition updateTest(SaveApiDefinitionRequest request) { checkNameExist(request); - if(StringUtils.equals(request.getMethod(),"ESB")){ + if (StringUtils.equals(request.getMethod(), "ESB")) { //ESB的接口类型数据,采用TCP方式去发送。并将方法类型改为TCP。 并修改发送数据 request = esbApiParamService.handleEsbRequest(request); } @@ -273,7 +269,7 @@ public class ApiDefinitionService { private ApiDefinition createTest(SaveApiDefinitionRequest request) { checkNameExist(request); - if(StringUtils.equals(request.getMethod(),"ESB")){ + if (StringUtils.equals(request.getMethod(), "ESB")) { //ESB的接口类型数据,采用TCP方式去发送。并将方法类型改为TCP。 并修改发送数据 request = esbApiParamService.handleEsbRequest(request); } @@ -764,6 +760,7 @@ public class ApiDefinitionService { calculateResult(resList); return resList; } + public List listRelevanceReview(ApiDefinitionRequest request) { request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); List resList = extApiDefinitionMapper.listRelevanceReview(request); @@ -795,7 +792,7 @@ public class ApiDefinitionService { res.setCaseStatus("-"); } - if(StringUtils.equals("ESB",res.getMethod())){ + if (StringUtils.equals("ESB", res.getMethod())) { esbApiParamService.handleApiEsbParams(res); } } @@ -882,8 +879,7 @@ public class ApiDefinitionService { ((MsApiExportResult) apiExportResult).setProtocol(request.getProtocol()); ((MsApiExportResult) apiExportResult).setProjectId(request.getProjectId()); ((MsApiExportResult) apiExportResult).setVersion(System.getenv("MS_VERSION")); - } - else { // 导出为 Swagger 格式 + } else { // 导出为 Swagger 格式 Swagger3Parser swagger3Parser = new Swagger3Parser(); System.out.println(apiDefinitionMapper.selectByExampleWithBLOBs(example)); apiExportResult = swagger3Parser.swagger3Export(apiDefinitionMapper.selectByExampleWithBLOBs(example)); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java index 5ffa9ad8d5..2540a207c9 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java @@ -50,7 +50,7 @@ public class ApiTestCaseService { @Resource TestPlanMapper testPlanMapper; @Resource - TestCaseReviewMapper testCaseReviewMapper; + TestCaseReviewMapper testCaseReviewMapper; @Resource private ApiTestCaseMapper apiTestCaseMapper; @Resource @@ -82,12 +82,12 @@ public class ApiTestCaseService { public List list(ApiTestCaseRequest request) { request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); - List returnList = extApiTestCaseMapper.list(request); + List returnList = extApiTestCaseMapper.list(request); for (ApiTestCaseResult res : returnList) { esbApiParamService.handleApiEsbParams(res); } - return returnList; + return returnList; } public List listSimple(ApiTestCaseRequest request) { @@ -230,7 +230,7 @@ public class ApiTestCaseService { private ApiTestCase updateTest(SaveApiTestCaseRequest request) { checkNameExist(request); - if(StringUtils.isNotEmpty(request.getEsbDataStruct())){ + if (StringUtils.isNotEmpty(request.getEsbDataStruct())) { request = esbApiParamService.handleEsbRequest(request); } @@ -253,7 +253,7 @@ public class ApiTestCaseService { request.setId(UUID.randomUUID().toString()); checkNameExist(request); - if(StringUtils.isNotEmpty(request.getEsbDataStruct())||StringUtils.isNotEmpty(request.getBackEsbDataStruct())){ + if (StringUtils.isNotEmpty(request.getEsbDataStruct()) || StringUtils.isNotEmpty(request.getBackEsbDataStruct())) { request = esbApiParamService.handleEsbRequest(request); } @@ -332,7 +332,8 @@ public class ApiTestCaseService { List apiTestCases = apiTestCaseMapper.selectByExample(example); relevance(apiTestCases, request); } - public void relevanceByApiByReview(ApiCaseRelevanceRequest request){ + + public void relevanceByApiByReview(ApiCaseRelevanceRequest request) { List ids = request.getSelectIds(); if (CollectionUtils.isEmpty(ids)) { return; @@ -342,6 +343,7 @@ public class ApiTestCaseService { List apiTestCases = apiTestCaseMapper.selectByExample(example); relevanceByReview(apiTestCases, request); } + public void relevanceByCase(ApiCaseRelevanceRequest request) { List ids = request.getSelectIds(); if (CollectionUtils.isEmpty(ids)) { @@ -391,7 +393,7 @@ public class ApiTestCaseService { TestCaseReviewApiCase.setUpdateTime(System.currentTimeMillis()); batchMapper.insertIfNotExists(TestCaseReviewApiCase); }); - TestCaseReview testCaseReview=testCaseReviewMapper.selectByPrimaryKey(request.getReviewId()); + TestCaseReview testCaseReview = testCaseReviewMapper.selectByPrimaryKey(request.getReviewId()); if (StringUtils.equals(testCaseReview.getStatus(), TestPlanStatus.Prepare.name()) || StringUtils.equals(testCaseReview.getStatus(), TestPlanStatus.Completed.name())) { testCaseReview.setStatus(TestPlanStatus.Underway.name()); @@ -399,11 +401,13 @@ public class ApiTestCaseService { } sqlSession.flushStatements(); } + public List selectIdsNotExistsInPlan(String projectId, String planId) { return extApiTestCaseMapper.selectIdsNotExistsInPlan(projectId, planId); } - public List selectIdsNotExistsInReview(String projectId,String reviewId){ - return extApiTestCaseMapper.selectIdsNotExistsInReview(projectId,reviewId); + + public List selectIdsNotExistsInReview(String projectId, String reviewId) { + return extApiTestCaseMapper.selectIdsNotExistsInReview(projectId, reviewId); } public List countProtocolByProjectID(String projectId) { @@ -497,7 +501,22 @@ public class ApiTestCaseService { sqlSession.flushStatements(); } + if (StringUtils.isNotEmpty(request.getEnvId())) { + List bloBs = apiTestCaseMapper.selectByExampleWithBLOBs(apiDefinitionExample); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + ApiTestCaseMapper batchMapper = sqlSession.getMapper(ApiTestCaseMapper.class); + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + bloBs.forEach(apiTestCase -> { + JSONObject req = JSON.parseObject(apiTestCase.getRequest()); + req.put("useEnvironment", request.getEnvId()); + String requestStr = JSON.toJSONString(req); + apiTestCase.setRequest(requestStr); + batchMapper.updateByPrimaryKeySelective(apiTestCase); + }); + sqlSession.flushStatements(); + } } private List getAllApiCaseIdsByFontedSelect(Map> filters, List moduleIds, String name, String projectId, String protocol, List unSelectIds, String status) { diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml index 22a4d71d62..82948829e2 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml @@ -306,9 +306,12 @@ or test_case.num like CONCAT('%', #{request.name},'%') or test_case.tags like CONCAT('%', #{request.name},'%')) - + and test_case.id in (select test_case_id from test_case_test where test_case_test.create_time >= #{request.createTime}) + + and test_case.create_time >= #{request.createTime} + and test_case.node_id in diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml index 4d85aac3e1..454782792f 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml @@ -137,7 +137,7 @@