From db46056049a6cca8d03896930d8ee14167feaade Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 6 Apr 2022 14:23:55 +0800 Subject: [PATCH] =?UTF-8?q?perf(=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92):=20?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92=E6=89=A7=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E5=87=86=E5=A4=87=E6=95=B0=E6=8D=AE=E6=9F=A5=E8=AF=A2=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/exec/api/ApiCaseExecuteService.java | 23 +++++++++++--- .../api/ApiCaseParallelExecuteService.java | 19 ++++++++---- .../api/exec/api/ApiExecuteService.java | 9 +++--- .../exec/scenario/ApiScenarioEnvService.java | 5 ++-- .../scenario/ApiScenarioExecuteService.java | 2 +- .../scenario/ApiScenarioParallelService.java | 19 ++++++++---- .../scenario/ApiScenarioSerialService.java | 16 +++++----- .../utils/ApiDefinitionExecResultUtil.java | 22 +++++++------- .../io/metersphere/api/jmeter/FixedTask.java | 2 +- .../metersphere/api/jmeter/JMeterService.java | 18 ++++++----- .../api/jmeter/MsKafkaListener.java | 25 +++++----------- .../api/service/ApiExecutionQueueService.java | 2 +- .../api/service/ApiTestCaseService.java | 5 ++-- .../java/io/metersphere/config/WebConfig.java | 9 ++++++ .../track/service/TestPlanApiCaseService.java | 16 +++++----- .../service/TestPlanScenarioCaseService.java | 30 +++++++++++-------- .../track/service/TestPlanService.java | 7 +++-- 17 files changed, 136 insertions(+), 93 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java index 8965f08bc2..87e917ab15 100644 --- a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseExecuteService.java @@ -9,6 +9,7 @@ import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.exec.queue.DBTestQueue; import io.metersphere.api.exec.scenario.ApiScenarioSerialService; import io.metersphere.api.exec.utils.ApiDefinitionExecResultUtil; +import io.metersphere.api.exec.utils.GenerateHashTreeUtil; import io.metersphere.api.service.ApiCaseResultService; import io.metersphere.api.service.ApiExecutionQueueService; import io.metersphere.api.service.ApiScenarioReportStructureService; @@ -40,6 +41,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.*; +import java.util.stream.Collectors; @Service public class ApiCaseExecuteService { @@ -60,7 +62,7 @@ public class ApiCaseExecuteService { @Resource private ApiCaseResultService apiCaseResultService; @Resource - ApiScenarioReportStructureService apiScenarioReportStructureService; + private ApiScenarioReportStructureService apiScenarioReportStructureService; /** * 测试计划case执行 @@ -92,9 +94,22 @@ public class ApiCaseExecuteService { Map executeQueue = new LinkedHashMap<>(); List responseDTOS = new LinkedList<>(); String status = request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) ? APITestStatus.Waiting.name() : APITestStatus.Running.name(); + + // 查出用例 + List apiCaseIds = planApiCases.stream().map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList()); + ApiTestCaseExample caseExample = new ApiTestCaseExample(); + caseExample.createCriteria().andIdIn(apiCaseIds); + List apiTestCases = apiTestCaseMapper.selectByExample(caseExample); + Map caseMap = apiTestCases.stream().collect(Collectors.toMap(ApiTestCase::getId, a -> a, (k1, k2) -> k1)); + // 资源池 + String resourcePoolId = null; + if (request.getConfig() != null && GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()).isPool()) { + resourcePoolId = request.getConfig().getResourcePoolId(); + } + Map planProjects = new HashMap<>(); - planApiCases.forEach(testPlanApiCase -> { - ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status); + for (TestPlanApiCase testPlanApiCase : planApiCases) { + ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.addResult(request, testPlanApiCase, status, caseMap, resourcePoolId); if (planProjects.containsKey(testPlanApiCase.getTestPlanId())) { report.setProjectId(planProjects.get(testPlanApiCase.getTestPlanId())); } else { @@ -106,7 +121,7 @@ public class ApiCaseExecuteService { } executeQueue.put(testPlanApiCase.getId(), report); responseDTOS.add(new MsExecResponseDTO(testPlanApiCase.getId(), report.getId(), request.getTriggerMode())); - }); + } apiCaseResultService.batchSave(executeQueue); diff --git a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseParallelExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseParallelExecuteService.java index 28e800df85..e81613bc6a 100644 --- a/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseParallelExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/api/ApiCaseParallelExecuteService.java @@ -5,14 +5,18 @@ import io.metersphere.api.exec.scenario.ApiScenarioSerialService; import io.metersphere.api.exec.utils.GenerateHashTreeUtil; import io.metersphere.api.jmeter.JMeterService; import io.metersphere.base.domain.ApiDefinitionExecResult; +import io.metersphere.base.domain.TestResource; import io.metersphere.constants.RunModeConstants; import io.metersphere.dto.JmeterRunRequestDTO; import io.metersphere.dto.RunModeConfigDTO; +import io.metersphere.vo.BooleanPool; import org.apache.commons.collections4.MapUtils; import org.apache.jorphan.collections.HashTree; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; import java.util.Map; @Service @@ -23,11 +27,16 @@ public class ApiCaseParallelExecuteService { private JMeterService jMeterService; public void parallel(Map executeQueue, RunModeConfigDTO config, DBTestQueue executionQueue, String runMode) { + List resources = new ArrayList<>(); + BooleanPool pool = GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()); + if (pool.isPool()) { + resources = GenerateHashTreeUtil.setPoolResource(config.getResourcePoolId()); + } + for (String testId : executeQueue.keySet()) { ApiDefinitionExecResult result = executeQueue.get(testId); String reportId = result.getId(); - HashTree hashTree = null; - JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, hashTree); + JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testId, reportId, runMode, null); runRequest.setPool(GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId())); runRequest.setTestPlanReportId(executionQueue.getReportId()); runRequest.setPoolId(config.getResourcePoolId()); @@ -37,11 +46,11 @@ public class ApiCaseParallelExecuteService { if (MapUtils.isNotEmpty(executionQueue.getDetailMap())) { runRequest.setPlatformUrl(executionQueue.getDetailMap().get(result.getId())); } - if (!GenerateHashTreeUtil.isResourcePool(config.getResourcePoolId()).isPool()) { - hashTree = apiScenarioSerialService.generateHashTree(testId, config.getEnvMap(), runRequest); + if (!pool.isPool()) { + HashTree hashTree = apiScenarioSerialService.generateHashTree(testId, config.getEnvMap(), runRequest); runRequest.setHashTree(hashTree); } - jMeterService.run(runRequest); + jMeterService.run(runRequest, resources); } } } diff --git a/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java index 655f3cb989..65bfc0c72a 100644 --- a/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/api/ApiExecuteService.java @@ -3,7 +3,6 @@ package io.metersphere.api.exec.api; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import io.metersphere.api.dto.definition.RunCaseRequest; import io.metersphere.api.dto.definition.RunDefinitionRequest; @@ -60,6 +59,8 @@ public class ApiExecuteService { private TcpApiParamService tcpApiParamService; @Resource private ExtApiTestCaseMapper extApiTestCaseMapper; + @Resource + private ObjectMapper mapper; public MsExecResponseDTO jenkinsRun(RunCaseRequest request) { ApiTestCaseWithBLOBs caseWithBLOBs = null; @@ -117,7 +118,7 @@ public class ApiExecuteService { } // 调用执行方法 JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(testCaseWithBLOBs.getId(), StringUtils.isEmpty(request.getReportId()) ? request.getId() : request.getReportId(), request.getRunMode(), jmeterHashTree); - jMeterService.run(runRequest); + jMeterService.run(runRequest, new ArrayList<>()); } catch (Exception ex) { ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(request.getReportId()); if (result != null) { @@ -186,13 +187,11 @@ public class ApiExecuteService { this.put("SYN_RES", request.isSyncResult()); }}); // 开始执行 - jMeterService.run(runRequest); + jMeterService.run(runRequest, new ArrayList<>()); return new MsExecResponseDTO(runRequest.getTestId(), runRequest.getReportId(), runMode); } public HashTree generateHashTree(RunCaseRequest request, ApiTestCaseWithBLOBs testCaseWithBLOBs) throws Exception { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); JSONObject elementObj = JSON.parseObject(testCaseWithBLOBs.getRequest()); ElementUtil.dataFormatting(elementObj); diff --git a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioEnvService.java b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioEnvService.java index f92363cabd..b667733bc9 100644 --- a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioEnvService.java +++ b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioEnvService.java @@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; 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.EnvironmentType; import io.metersphere.api.dto.ScenarioEnv; @@ -55,6 +54,8 @@ public class ApiScenarioEnvService { private ApiTestEnvironmentMapper apiTestEnvironmentMapper; @Resource private TestPlanApiScenarioMapper testPlanApiScenarioMapper; + @Resource + private ObjectMapper mapper; public ScenarioEnv getApiScenarioEnv(String definition) { ScenarioEnv env = new ScenarioEnv(); @@ -138,8 +139,6 @@ public class ApiScenarioEnvService { private void getHashTree(List 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); if (!tr.isEnable()) { diff --git a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java index 54f25563f4..b7463129e5 100644 --- a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java +++ b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioExecuteService.java @@ -369,7 +369,7 @@ public class ApiScenarioExecuteService { // 调用执行方法 JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(request.getId(), request.getId(), runMode, hashTree); runRequest.setDebug(true); - jMeterService.run(runRequest); + jMeterService.run(runRequest, new ArrayList<>()); return request.getId(); } diff --git a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioParallelService.java b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioParallelService.java index 0650541756..c97da44ab1 100644 --- a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioParallelService.java +++ b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioParallelService.java @@ -6,13 +6,17 @@ import io.metersphere.api.dto.automation.RunScenarioRequest; import io.metersphere.api.exec.queue.DBTestQueue; import io.metersphere.api.exec.utils.GenerateHashTreeUtil; import io.metersphere.api.jmeter.JMeterService; +import io.metersphere.base.domain.TestResource; import io.metersphere.constants.RunModeConstants; import io.metersphere.dto.JmeterRunRequestDTO; import io.metersphere.utils.LoggerUtil; +import io.metersphere.vo.BooleanPool; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; import java.util.Map; @Service @@ -21,15 +25,20 @@ public class ApiScenarioParallelService { private JMeterService jMeterService; public void parallel(Map executeQueue, RunScenarioRequest request, String serialReportId, DBTestQueue executionQueue) { + List resources = new ArrayList<>(); + BooleanPool pool = GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()); + if (pool.isPool()) { + resources = GenerateHashTreeUtil.setPoolResource(request.getConfig().getResourcePoolId()); + } for (String reportId : executeQueue.keySet()) { RunModeDataDTO dataDTO = executeQueue.get(reportId); JmeterRunRequestDTO runRequest = new JmeterRunRequestDTO(dataDTO.getTestId(), StringUtils.isNotEmpty(serialReportId) ? serialReportId : reportId, request.getRunMode(), null); runRequest.setReportType(StringUtils.isNotEmpty(serialReportId) ? RunModeConstants.SET_REPORT.toString() : RunModeConstants.INDEPENDENCE.toString()); runRequest.setQueueId(executionQueue.getId()); - if (request.getConfig() != null) { - runRequest.setPool(GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId())); - runRequest.setPoolId(request.getConfig().getResourcePoolId()); - } + + runRequest.setPool(pool); + runRequest.setPoolId(request.getConfig().getResourcePoolId()); + runRequest.setTestPlanReportId(request.getTestPlanReportId()); runRequest.setPlatformUrl(executionQueue.getDetailMap().get(reportId)); runRequest.setRunType(RunModeConstants.PARALLEL.toString()); @@ -40,7 +49,7 @@ public class ApiScenarioParallelService { if (request.getConfig() != null && !runRequest.getPool().isPool()) { runRequest.setHashTree(GenerateHashTreeUtil.generateHashTree(dataDTO.getScenario(), dataDTO.getPlanEnvMap(), runRequest)); } - jMeterService.run(runRequest); + jMeterService.run(runRequest, resources); } } } diff --git a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java index 7b2f45a6b1..a685670dd3 100644 --- a/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java +++ b/backend/src/main/java/io/metersphere/api/exec/scenario/ApiScenarioSerialService.java @@ -3,7 +3,6 @@ package io.metersphere.api.exec.scenario; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import io.metersphere.api.dto.definition.request.ElementUtil; import io.metersphere.api.dto.definition.request.MsTestPlan; @@ -36,9 +35,7 @@ import org.apache.jorphan.collections.HashTree; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.Map; +import java.util.*; @Service public class ApiScenarioSerialService { @@ -58,6 +55,8 @@ public class ApiScenarioSerialService { private TestPlanApiScenarioMapper testPlanApiScenarioMapper; @Resource private ApiScenarioEnvService apiScenarioEnvService; + @Resource + private ObjectMapper mapper; public void serial(ApiExecutionQueue executionQueue, ApiExecutionQueueDetail queue) { LoggerUtil.debug("Scenario run-执行脚本装载-进入串行准备"); @@ -126,8 +125,13 @@ public class ApiScenarioSerialService { if (queue != null) { runRequest.setPlatformUrl(queue.getId()); } + List resources = new ArrayList<>(); + if (runRequest.getPool().isPool()) { + resources = GenerateHashTreeUtil.setPoolResource(runRequest.getPoolId()); + } + // 开始执行 - jMeterService.run(runRequest); + jMeterService.run(runRequest, resources); } catch (Exception e) { RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class); remakeReportService.remake(runRequest); @@ -188,8 +192,6 @@ public class ApiScenarioSerialService { } private MsTestElement parse(ApiTestCaseWithBLOBs caseWithBLOBs, String planId, String envId) { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); try { String api = caseWithBLOBs.getRequest(); JSONObject element = JSON.parseObject(api); diff --git a/backend/src/main/java/io/metersphere/api/exec/utils/ApiDefinitionExecResultUtil.java b/backend/src/main/java/io/metersphere/api/exec/utils/ApiDefinitionExecResultUtil.java index 8416e261a6..8930fc6e90 100644 --- a/backend/src/main/java/io/metersphere/api/exec/utils/ApiDefinitionExecResultUtil.java +++ b/backend/src/main/java/io/metersphere/api/exec/utils/ApiDefinitionExecResultUtil.java @@ -2,17 +2,16 @@ package io.metersphere.api.exec.utils; import io.metersphere.api.dto.definition.BatchRunDefinitionRequest; import io.metersphere.base.domain.ApiDefinitionExecResult; -import io.metersphere.base.domain.ApiTestCaseWithBLOBs; +import io.metersphere.base.domain.ApiTestCase; import io.metersphere.base.domain.TestPlanApiCase; -import io.metersphere.base.mapper.ApiTestCaseMapper; import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ReportTypeConstants; import io.metersphere.commons.constants.TriggerMode; -import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.SessionUtils; import io.metersphere.dto.RunModeConfigDTO; import org.apache.commons.lang3.StringUtils; +import java.util.Map; import java.util.Objects; import java.util.UUID; @@ -41,23 +40,24 @@ public class ApiDefinitionExecResultUtil { return apiResult; } - public static ApiDefinitionExecResult addResult(BatchRunDefinitionRequest request, TestPlanApiCase key, String status) { + public static ApiDefinitionExecResult addResult(BatchRunDefinitionRequest request, TestPlanApiCase key, String status, + Map caseMap, String poolId) { ApiDefinitionExecResult apiResult = new ApiDefinitionExecResult(); apiResult.setId(UUID.randomUUID().toString()); apiResult.setCreateTime(System.currentTimeMillis()); apiResult.setStartTime(System.currentTimeMillis()); apiResult.setEndTime(System.currentTimeMillis()); apiResult.setReportType(ReportTypeConstants.API_INDEPENDENT.name()); - ApiTestCaseWithBLOBs caseWithBLOBs = CommonBeanFactory.getBean(ApiTestCaseMapper.class).selectByPrimaryKey(key.getApiCaseId()); - if (caseWithBLOBs != null) { - apiResult.setName(caseWithBLOBs.getName()); - apiResult.setProjectId(caseWithBLOBs.getProjectId()); - apiResult.setVersionId(caseWithBLOBs.getVersionId()); + ApiTestCase testCase = caseMap.get(key.getApiCaseId()); + if (testCase != null) { + apiResult.setName(testCase.getName()); + apiResult.setProjectId(testCase.getProjectId()); + apiResult.setVersionId(testCase.getVersionId()); } apiResult.setTriggerMode(request.getTriggerMode()); apiResult.setActuator("LOCAL"); - if (request.getConfig() != null && GenerateHashTreeUtil.isResourcePool(request.getConfig().getResourcePoolId()).isPool()) { - apiResult.setActuator(request.getConfig().getResourcePoolId()); + if (StringUtils.isNotEmpty(poolId)) { + apiResult.setActuator(poolId); } if (StringUtils.isEmpty(request.getUserId())) { if (SessionUtils.getUser() != null) { diff --git a/backend/src/main/java/io/metersphere/api/jmeter/FixedTask.java b/backend/src/main/java/io/metersphere/api/jmeter/FixedTask.java index 21c5f938f2..ad3843e739 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/FixedTask.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/FixedTask.java @@ -14,6 +14,6 @@ public class FixedTask { if (queueService == null) { queueService = CommonBeanFactory.getBean(ApiExecutionQueueService.class); } - queueService.timeOut(); + queueService.defendQueue(); } } diff --git a/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java b/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java index 74abe28b20..2eecb3c40f 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java @@ -12,7 +12,9 @@ import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.config.JmeterProperties; import io.metersphere.config.KafkaConfig; import io.metersphere.constants.RunModeConstants; -import io.metersphere.dto.*; +import io.metersphere.dto.BaseSystemConfigDTO; +import io.metersphere.dto.JmeterRunRequestDTO; +import io.metersphere.dto.NodeDTO; import io.metersphere.jmeter.JMeterBase; import io.metersphere.jmeter.LocalRunner; import io.metersphere.performance.engine.Engine; @@ -112,7 +114,7 @@ public class JMeterService { runner.run(request.getReportId()); } - private void runNode(JmeterRunRequestDTO request) { + private void runNode(JmeterRunRequestDTO request, List resources) { // 获取可以执行的资源池 BaseSystemConfigDTO baseInfo = CommonBeanFactory.getBean(SystemParameterService.class).getBaseInfo(); // 占位符 @@ -145,13 +147,15 @@ public class JMeterService { MSException.throwException(e.getMessage()); } } else { - this.send(request); + this.send(request, resources); } } - private void send(JmeterRunRequestDTO request) { + private void send(JmeterRunRequestDTO request, List resources) { try { - List resources = GenerateHashTreeUtil.setPoolResource(request.getPoolId()); + if (StringUtils.isNotEmpty(request.getPoolId()) && CollectionUtils.isEmpty(resources)) { + resources = GenerateHashTreeUtil.setPoolResource(request.getPoolId()); + } if (CollectionUtils.isEmpty(resources)) { LoggerUtil.info("未获取到资源池,请检查配置【系统设置-系统-测试资源池】"); RemakeReportService remakeReportService = CommonBeanFactory.getBean(RemakeReportService.class); @@ -186,9 +190,9 @@ public class JMeterService { } - public void run(JmeterRunRequestDTO request) { + public void run(JmeterRunRequestDTO request, List resources) { if (request.getPool().isPool()) { - this.runNode(request); + this.runNode(request, resources); } else { CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).addTask(request); } diff --git a/backend/src/main/java/io/metersphere/api/jmeter/MsKafkaListener.java b/backend/src/main/java/io/metersphere/api/jmeter/MsKafkaListener.java index 2d719f5b62..294c3245ef 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/MsKafkaListener.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/MsKafkaListener.java @@ -1,10 +1,8 @@ package io.metersphere.api.jmeter; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil; -import io.metersphere.api.service.ApiEnvironmentRunningParamService; import io.metersphere.api.service.ApiExecutionQueueService; import io.metersphere.api.service.TestResultService; import io.metersphere.commons.constants.ApiRunMode; @@ -12,6 +10,7 @@ import io.metersphere.config.KafkaConfig; import io.metersphere.dto.ResultDTO; import io.metersphere.utils.LoggerUtil; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.springframework.context.annotation.Configuration; @@ -26,6 +25,10 @@ public class MsKafkaListener { public static final String CONSUME_ID = "ms-api-exec-consume"; @Resource private ApiExecutionQueueService apiExecutionQueueService; + @Resource + private TestResultService testResultService; + @Resource + private ObjectMapper mapper; private static final Map RUN_MODE_MAP = new HashMap() {{ this.put(ApiRunMode.SCHEDULE_API_PLAN.name(), "schedule-task"); @@ -72,7 +75,7 @@ public class MsKafkaListener { } } }); - if (!assortMap.isEmpty()) { + if (MapUtils.isNotEmpty(assortMap)) { testResultService.batchSaveResults(assortMap); LoggerUtil.info("KAFKA消费执行内容存储结束"); } @@ -99,26 +102,12 @@ public class MsKafkaListener { } } - @Resource - private TestResultService testResultService; - - @Resource - private ApiEnvironmentRunningParamService apiEnvironmentRunningParamService; - private ResultDTO formatResult(String result) { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); try { // 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取 if (StringUtils.isNotEmpty(result)) { - ResultDTO element = mapper.readValue(result, new TypeReference() { + return mapper.readValue(result, new TypeReference() { }); - if (StringUtils.isNotEmpty(element.getRunningDebugSampler())) { - String evnStr = element.getRunningDebugSampler(); - apiEnvironmentRunningParamService.parseEvn(evnStr); - } - LoggerUtil.info("formatResult 完成:" + element.getReportId()); - return element; } } catch (Exception e) { LoggerUtil.error("formatResult 格式化数据失败:", e); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java b/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java index 2be1f4fbde..8fb08517a9 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiExecutionQueueService.java @@ -296,7 +296,7 @@ public class ApiExecutionQueueService { LoggerUtil.info("处理队列结束:" + dto.getReportId() + "QID:" + dto.getQueueId()); } - public void timeOut() { + public void defendQueue() { final int SECOND_MILLIS = 1000; final int MINUTE_MILLIS = 60 * SECOND_MILLIS; // 计算一小时前的超时报告 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 a77210cde3..cf11c19c31 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java @@ -3,7 +3,6 @@ package io.metersphere.api.service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import io.metersphere.api.dto.ApiCaseEditRequest; import io.metersphere.api.dto.DeleteCheckResult; @@ -102,6 +101,8 @@ public class ApiTestCaseService { private ExtProjectVersionMapper extProjectVersionMapper; @Resource private TcpApiParamService tcpApiParamService; + @Resource + private ObjectMapper mapper; private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR; @@ -734,8 +735,6 @@ public class ApiTestCaseService { 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 -> { MsHTTPSamplerProxy req = JSON.parseObject(apiTestCase.getRequest(), MsHTTPSamplerProxy.class); try { diff --git a/backend/src/main/java/io/metersphere/config/WebConfig.java b/backend/src/main/java/io/metersphere/config/WebConfig.java index 44fb039e4f..e064f928d4 100644 --- a/backend/src/main/java/io/metersphere/config/WebConfig.java +++ b/backend/src/main/java/io/metersphere/config/WebConfig.java @@ -1,5 +1,7 @@ package io.metersphere.config; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; import io.metersphere.commons.utils.LogUtil; import org.apache.http.NoHttpResponseException; import org.apache.http.conn.ConnectTimeoutException; @@ -28,6 +30,13 @@ public class WebConfig implements WebMvcConfigurer { return getTimeOutTemplate(4000, 4000, 10 * 1000); } + @Bean + public ObjectMapper objectMapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + return mapper; + } + private RestTemplate getTimeOutTemplate(int requestTimeout, int connectTimeout, int readTimeout) { RestTemplate restTemplate = new RestTemplate(); HttpComponentsClientHttpRequestFactory httpRequestFactory = diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java index 430319e829..ed3f640530 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java @@ -289,10 +289,10 @@ public class TestPlanApiCaseService { String envGroupId = config.getEnvironmentGroupId(); Map envMap = config.getEnvMap(); if ((StringUtils.equals(envType, EnvironmentType.JSON.toString()) && envMap != null && !envMap.isEmpty())) { - setApiCaseEnv(request.getPlanIds(), envMap); + setApiCaseEnv(null, request.getPlanIds(), envMap); } else if ((StringUtils.equals(envType, EnvironmentType.GROUP.toString()) && StringUtils.isNotBlank(envGroupId))) { Map map = environmentGroupProjectService.getEnvMap(envGroupId); - setApiCaseEnv(request.getPlanIds(), map); + setApiCaseEnv(null, request.getPlanIds(), map); } } return testPlanApiCaseExecuteService.run(request); @@ -300,14 +300,16 @@ public class TestPlanApiCaseService { return null; } - public void setApiCaseEnv(List planIds, Map map) { + public void setApiCaseEnv(List testPlanApiCases, List planIds, Map map) { if (CollectionUtils.isEmpty(planIds) || (map != null && map.isEmpty())) { return; } - TestPlanApiCaseExample caseExample = new TestPlanApiCaseExample(); - caseExample.createCriteria().andIdIn(planIds); - List testPlanApiCases = testPlanApiCaseMapper.selectByExample(caseExample); + if (CollectionUtils.isEmpty(testPlanApiCases)) { + TestPlanApiCaseExample caseExample = new TestPlanApiCaseExample(); + caseExample.createCriteria().andIdIn(planIds); + testPlanApiCases = testPlanApiCaseMapper.selectByExample(caseExample); + } List apiCaseIds = testPlanApiCases.stream().map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList()); if (CollectionUtils.isEmpty(apiCaseIds)) { return; @@ -326,7 +328,7 @@ public class TestPlanApiCaseService { String caseId = testPlanApiCase.getApiCaseId(); String projectId = projectCaseIdMap.get(caseId); String envId = map.get(projectId); - if (StringUtils.isNotBlank(envId)) { + if (StringUtils.isNotBlank(envId) && !StringUtils.equals(testPlanApiCase.getEnvironmentId(), envId)) { testPlanApiCase.setEnvironmentId(envId); mapper.updateByPrimaryKey(testPlanApiCase); } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java index 499f545271..f6f6654ff3 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java @@ -188,7 +188,7 @@ public class TestPlanScenarioCaseService { if ((StringUtils.equals(envType, EnvironmentType.JSON.toString()) && envMap != null && !envMap.isEmpty()) || (StringUtils.equals(envType, EnvironmentType.GROUP.toString()) && StringUtils.isNotBlank(envGroupId))) { // 更新场景用例环境信息,运行时从数据库读取最新环境 - this.setScenarioEnv(planCaseIdList, testPlanScenarioRequest.getConfig()); + this.setScenarioEnv(new ArrayList<>(), planCaseIdList, testPlanScenarioRequest.getConfig()); } } planCaseIdList.forEach(item -> { @@ -218,12 +218,19 @@ public class TestPlanScenarioCaseService { return apiAutomationService.run(request); } - public void setScenarioEnv(List planScenarioIds, RunModeConfigDTO runModeConfig) { + public void setScenarioEnv(List testPlanApiScenarios, List planScenarioIds, RunModeConfigDTO runModeConfig) { if (CollectionUtils.isEmpty(planScenarioIds)) return; + + if (CollectionUtils.isEmpty(testPlanApiScenarios)) { + TestPlanApiScenarioExample testPlanApiScenarioExample = new TestPlanApiScenarioExample(); + testPlanApiScenarioExample.createCriteria().andIdIn(planScenarioIds); + testPlanApiScenarios = testPlanApiScenarioMapper.selectByExampleWithBLOBs(testPlanApiScenarioExample); + } + if (CollectionUtils.isEmpty(planScenarioIds)) { + return; + } + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); - TestPlanApiScenarioExample testPlanApiScenarioExample = new TestPlanApiScenarioExample(); - testPlanApiScenarioExample.createCriteria().andIdIn(planScenarioIds); - List testPlanApiScenarios = testPlanApiScenarioMapper.selectByExampleWithBLOBs(testPlanApiScenarioExample); TestPlanApiScenarioMapper mapper = sqlSession.getMapper(TestPlanApiScenarioMapper.class); String environmentType = runModeConfig.getEnvironmentType(); @@ -231,9 +238,6 @@ public class TestPlanScenarioCaseService { if (StringUtils.equals(environmentType, EnvironmentType.JSON.toString())) { Map envMap = runModeConfig.getEnvMap(); - if (CollectionUtils.isEmpty(planScenarioIds)) { - return; - } for (TestPlanApiScenario testPlanApiScenario : testPlanApiScenarios) { String env = testPlanApiScenario.getEnvironment(); if (StringUtils.isBlank(env)) { @@ -251,15 +255,17 @@ public class TestPlanScenarioCaseService { map.put(s, envMap.get(s)); } } - testPlanApiScenario.setEnvironmentType(EnvironmentType.JSON.toString()); - testPlanApiScenario.setEnvironment(JSON.toJSONString(map)); - mapper.updateByPrimaryKeyWithBLOBs(testPlanApiScenario); + String envJsonStr = JSON.toJSONString(map); + if (!StringUtils.equals(envJsonStr, testPlanApiScenario.getEnvironment())) { + testPlanApiScenario.setEnvironmentType(EnvironmentType.JSON.toString()); + testPlanApiScenario.setEnvironment(JSON.toJSONString(map)); + mapper.updateByPrimaryKeyWithBLOBs(testPlanApiScenario); + } } sqlSession.flushStatements(); if (sqlSession != null && sqlSessionFactory != null) { SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); } - return; } if (StringUtils.equals(environmentType, EnvironmentType.GROUP.toString())) { diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index ab72015520..f84b4a557c 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -1946,13 +1946,14 @@ public class TestPlanService { envMap = environmentGroupProjectService.getEnvMap(environmentGroupId); } - testPlanApiCaseService.setApiCaseEnv(planApiCaseIds, envMap); + testPlanApiCaseService.setApiCaseEnv(testPlanApiCases, planApiCaseIds, envMap); TestPlanApiScenarioExample scenarioExample = new TestPlanApiScenarioExample(); scenarioExample.createCriteria().andTestPlanIdEqualTo(planId); - List testPlanApiScenarios = testPlanApiScenarioMapper.selectByExample(scenarioExample); + + List testPlanApiScenarios = testPlanApiScenarioMapper.selectByExampleWithBLOBs(scenarioExample); List planScenarioIds = testPlanApiScenarios.stream().map(TestPlanApiScenario::getId).collect(Collectors.toList()); - testPlanScenarioCaseService.setScenarioEnv(planScenarioIds, runModeConfig); + testPlanScenarioCaseService.setScenarioEnv(testPlanApiScenarios, planScenarioIds, runModeConfig); } public void editReportConfig(TestPlanDTO testPlanDTO) {