From 6493eecfa7855d516442b6e5c6d2d468589042dc Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Tue, 2 Jan 2024 17:14:54 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):=20A?= =?UTF-8?q?PI=E6=8A=A5=E5=91=8A=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sdk/dto/api/notice/ApiNoticeDTO.java | 7 +- .../sdk/dto/api/result/TaskResult.java | 8 +- .../sdk/dto/api/task/TaskRequest.java | 9 ++ .../sdk/util/ReportStatusUtils.java | 83 +++++++++++++++++++ .../service/ApiReportSendNoticeService.java | 11 ++- .../api/listener/MessageListenerTest.java | 8 +- 6 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 backend/framework/sdk/src/main/java/io/metersphere/sdk/util/ReportStatusUtils.java diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/notice/ApiNoticeDTO.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/notice/ApiNoticeDTO.java index 4cbfb41543..0a067988cc 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/notice/ApiNoticeDTO.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/notice/ApiNoticeDTO.java @@ -1,11 +1,16 @@ package io.metersphere.sdk.dto.api.notice; import io.metersphere.sdk.constants.ApiExecuteResourceType; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import java.io.Serial; +import java.util.List; @Data +@AllArgsConstructor +@NoArgsConstructor public class ApiNoticeDTO implements java.io.Serializable { @Serial private static final long serialVersionUID = 1L; @@ -15,6 +20,6 @@ public class ApiNoticeDTO implements java.io.Serializable { private String reportStatus; private String userId; private String projectId; - private String environmentId; + private List environmentIds; private String reportId; } diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/result/TaskResult.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/result/TaskResult.java index 59522359d8..c0d88463be 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/result/TaskResult.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/result/TaskResult.java @@ -26,8 +26,14 @@ public class TaskResult implements Serializable { private String runningDebugSampler; private Boolean hasEnded; private boolean retryEnable; + /** + * 项目id + */ private String projectId; - private String environmentId; + /** + * 执行环境id + */ + private List environmentIds; /** * 执行过程状态 */ diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/task/TaskRequest.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/task/TaskRequest.java index 450497df76..9203f23e2d 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/task/TaskRequest.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/api/task/TaskRequest.java @@ -58,5 +58,14 @@ public class TaskRequest implements Serializable { */ Map> fakeErrorMap; + /** + * 项目id + */ + private String projectId; + /** + * 执行环境id + */ + private List environmentIds; + // TODO 其它执行参数 } diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/ReportStatusUtils.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/ReportStatusUtils.java new file mode 100644 index 0000000000..2192d1bba0 --- /dev/null +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/ReportStatusUtils.java @@ -0,0 +1,83 @@ +package io.metersphere.sdk.util; + +import io.metersphere.sdk.constants.ApiReportStatus; +import io.metersphere.sdk.dto.api.result.ProcessResultDTO; +import io.metersphere.sdk.dto.api.result.RequestResult; +import io.metersphere.sdk.dto.api.result.TaskResult; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class ReportStatusUtils { + public static List filterRetryResults(List results) { + List list = new LinkedList<>(); + if (CollectionUtils.isNotEmpty(results)) { + Map> resultMap = results.stream().collect(Collectors.groupingBy(RequestResult::getResourceId)); + resultMap.forEach((k, v) -> { + if (CollectionUtils.isNotEmpty(v)) { + // 校验是否含重试结果 + List isRetryResults = v.stream().filter(c -> + StringUtils.isNotEmpty(c.getName()) && c.getName().startsWith(RetryResultUtils.RETRY_CN)) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(isRetryResults)) { + list.add(isRetryResults.getLast()); + } else { + // 成功的结果 + list.addAll(v); + } + } + }); + } + return list; + } + + /** + * 返回正确的报告状态 + * + * @param dto jmeter返回 + */ + public static ProcessResultDTO getStatus(TaskResult dto, ProcessResultDTO resultVO) { + resultVO.computerTotal(dto.getRequestResults().size()); + resultVO.computerSuccess(dto.getRequestResults().stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ApiReportStatus.SUCCESS.name())).count()); + if (StringUtils.equals(resultVO.getStatus(), ApiReportStatus.ERROR.name())) { + return resultVO; + } + if (ObjectUtils.isNotEmpty(dto.getProcessResultDTO())) { + // 资源池执行整体传输失败,单条传输内容,获取资源池执行统计的状态 + resultVO.setStatus(dto.getProcessResultDTO().getStatus()); + } + // 过滤掉重试结果后进行统计 + List requestResults = filterRetryResults(dto.getRequestResults()); + long errorSize = requestResults.stream().filter(requestResult -> + StringUtils.equalsIgnoreCase(requestResult.getStatus(), ApiReportStatus.ERROR.name())).count(); + // 误报 + long errorReportResultSize = dto.getRequestResults().stream().filter( + requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ApiReportStatus.FAKE_ERROR.name())).count(); + // 默认状态 + String status = dto.getRequestResults().isEmpty() && StringUtils.isEmpty(resultVO.getStatus()) + ? ApiReportStatus.PENDING.name() + : StringUtils.defaultIfEmpty(resultVO.getStatus(), ApiReportStatus.SUCCESS.name()); + + if (errorSize > 0) { + status = ApiReportStatus.ERROR.name(); + } else if (errorReportResultSize > 0) { + status = ApiReportStatus.FAKE_ERROR.name(); + } + resultVO.setStatus(status); + return resultVO; + } + + public static ProcessResultDTO computedProcess(TaskResult dto) { + ProcessResultDTO result = dto.getProcessResultDTO(); + result = getStatus(dto, result); + if (result.getScenarioTotal() > 0 && result.getScenarioTotal() == result.getScenarioSuccess()) { + result.setStatus(ApiReportStatus.SUCCESS.name()); + } + return result; + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiReportSendNoticeService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiReportSendNoticeService.java index 8bbd2b1a55..d2d68e341c 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiReportSendNoticeService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiReportSendNoticeService.java @@ -23,6 +23,7 @@ import io.metersphere.system.service.NoticeSendService; import io.metersphere.system.service.SystemParameterService; import jakarta.annotation.Resource; import org.apache.commons.beanutils.BeanMap; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; @@ -94,9 +95,13 @@ public class ApiReportSendNoticeService { Map paramMap = new HashMap(beanMap); paramMap.put("operator", user != null ? user.getName() : ""); paramMap.put("status", noticeDTO.getReportStatus()); - Environment environment = environmentMapper.selectByPrimaryKey(noticeDTO.getEnvironmentId()); - if (environment != null) { - paramMap.put("environment", environment.getName()); + + // TODO 暂时取一个环境处理 + if (CollectionUtils.isNotEmpty(noticeDTO.getEnvironmentIds())) { + Environment environment = environmentMapper.selectByPrimaryKey(noticeDTO.getEnvironmentIds().getFirst()); + if (environment != null) { + paramMap.put("environment", environment.getName()); + } } else { paramMap.put("environment", "未配置"); } diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/listener/MessageListenerTest.java b/backend/services/api-test/src/test/java/io/metersphere/api/listener/MessageListenerTest.java index 08d46736cb..c0dba4983b 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/listener/MessageListenerTest.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/listener/MessageListenerTest.java @@ -12,6 +12,8 @@ import org.mockito.InjectMocks; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import java.util.ArrayList; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @AutoConfigureMockMvc @@ -31,7 +33,7 @@ public class MessageListenerTest { api.setReportStatus("exampleReportStatus"); api.setUserId("exampleUserId"); api.setProjectId("exampleProjectId"); - api.setEnvironmentId("exampleEnvironmentId"); + api.setEnvironmentIds(new ArrayList<>(){{this.add("exampleEnvironmentId");}}); api.setReportId("exampleReportId"); ConsumerRecord record = new ConsumerRecord<>(KafkaTopicConstants.API_REPORT_TASK_TOPIC, 0, 0, "123", JSON.toJSONString(api)); @@ -47,7 +49,7 @@ public class MessageListenerTest { scenario.setReportStatus("exampleReportStatus"); scenario.setUserId("exampleUserId"); scenario.setProjectId("exampleProjectId"); - scenario.setEnvironmentId("exampleEnvironmentId"); + api.setEnvironmentIds(new ArrayList<>(){{this.add("exampleEnvironmentId");}}); scenario.setReportId("exampleReportId"); ConsumerRecord scenarioRecord = new ConsumerRecord<>(KafkaTopicConstants.API_REPORT_TASK_TOPIC, 0, 0, "123", JSON.toJSONString(scenario)); @@ -63,7 +65,7 @@ public class MessageListenerTest { testCase.setReportStatus("exampleReportStatus"); testCase.setUserId("exampleUserId"); testCase.setProjectId("exampleProjectId"); - testCase.setEnvironmentId("exampleEnvironmentId"); + api.setEnvironmentIds(new ArrayList<>(){{this.add("exampleEnvironmentId");}}); testCase.setReportId("exampleReportId"); ConsumerRecord testCaseRecord = new ConsumerRecord<>(KafkaTopicConstants.API_REPORT_TASK_TOPIC, 0, 0, "123", JSON.toJSONString(testCase));