From ce0ed0711e92f3adce800df8e36a6bba0cc81a49 Mon Sep 17 00:00:00 2001 From: wxg0103 <727495428@qq.com> Date: Mon, 13 May 2024 17:01:37 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):?= =?UTF-8?q?=20=E4=BC=98=E5=8C=96mock=E6=89=A7=E8=A1=8C=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E5=B8=A6mock=E7=9A=84=E6=9C=9F=E6=9C=9Bid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mockserver/MockServerController.java | 38 +++++++++---------- .../api/dto/mockserver/keyValueMatchRule.java | 6 ++- .../api/dto/request/http/MsHTTPElement.java | 6 ++- .../parser/jmeter/MsHTTPElementConverter.java | 9 +++-- .../ApiDefinitionImportUtilService.java | 7 +--- .../service/mockserver/MockServerService.java | 17 +++++++-- .../ApiDefinitionMockControllerTests.java | 6 +++ 7 files changed, 54 insertions(+), 35 deletions(-) diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/controller/mockserver/MockServerController.java b/backend/services/api-test/src/main/java/io/metersphere/api/controller/mockserver/MockServerController.java index c9ecead02f..74dd34391f 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/controller/mockserver/MockServerController.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/controller/mockserver/MockServerController.java @@ -11,7 +11,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping(value = "/mock-server/{projectNum}/{apiNum}/**") +@RequestMapping(value = {"/mock-server/{projectNum}/{apiNum}/{mockNum}/**", "/mock-server/{projectNum}/{apiNum}/**"}) @Tag(name = "接口测试-接口管理-接口定义-Mock") @MultipartConfig public class MockServerController { @@ -21,54 +21,54 @@ public class MockServerController { @RequestMapping(method = RequestMethod.OPTIONS) @NoResultHolder - public ResponseEntity optionsRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) { - return mockServerService.execute(HttpMethod.OPTIONS.name(), projectNum, apiNum, request); + public ResponseEntity optionsRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) { + return mockServerService.execute(HttpMethod.OPTIONS.name(), projectNum, apiNum, mockNum, request); } @RequestMapping(method = RequestMethod.HEAD) @NoResultHolder - public ResponseEntity headerRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) { - return mockServerService.execute(HttpMethod.HEAD.name(), projectNum, apiNum, request); + public ResponseEntity headerRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) { + return mockServerService.execute(HttpMethod.HEAD.name(), projectNum, apiNum, mockNum, request); } @RequestMapping(method = RequestMethod.TRACE) @NoResultHolder - public ResponseEntity traceRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) { - return mockServerService.execute(HttpMethod.TRACE.name(), projectNum, apiNum, request); + public ResponseEntity traceRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) { + return mockServerService.execute(HttpMethod.TRACE.name(), projectNum, apiNum, mockNum, request); } @GetMapping @NoResultHolder - public ResponseEntity getMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) { - return handleMockRequest(HttpMethod.GET.name(), projectNum, apiNum, request); + public ResponseEntity getMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable(required = false) String mockNum, HttpServletRequest request) { + return handleMockRequest(HttpMethod.GET.name(), projectNum, apiNum, mockNum, request); } @PostMapping @NoResultHolder - public ResponseEntity postMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) { - return handleMockRequest(HttpMethod.POST.name(), projectNum, apiNum, request); + public ResponseEntity postMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) { + return handleMockRequest(HttpMethod.POST.name(), projectNum, apiNum, mockNum, request); } @PutMapping @NoResultHolder - public ResponseEntity putMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) { - return handleMockRequest(HttpMethod.PUT.name(), projectNum, apiNum, request); + public ResponseEntity putMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) { + return handleMockRequest(HttpMethod.PUT.name(), projectNum, apiNum, mockNum, request); } @DeleteMapping @NoResultHolder - public ResponseEntity deleteMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) { - return handleMockRequest(HttpMethod.DELETE.name(), projectNum, apiNum, request); + public ResponseEntity deleteMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) { + return handleMockRequest(HttpMethod.DELETE.name(), projectNum, apiNum, mockNum, request); } @PatchMapping @NoResultHolder - public ResponseEntity patchMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) { - return handleMockRequest(HttpMethod.PATCH.name(), projectNum, apiNum, request); + public ResponseEntity patchMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) { + return handleMockRequest(HttpMethod.PATCH.name(), projectNum, apiNum, mockNum, request); } - private ResponseEntity handleMockRequest(String method, String projectNum, String apiNum, HttpServletRequest request) { - return mockServerService.execute(method, projectNum, apiNum, request); + private ResponseEntity handleMockRequest(String method, String projectNum, String apiNum, String mockNum, HttpServletRequest request) { + return mockServerService.execute(method, projectNum, apiNum, mockNum, request); } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/mockserver/keyValueMatchRule.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/mockserver/keyValueMatchRule.java index c21d55503b..4dc55aa141 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/mockserver/keyValueMatchRule.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/mockserver/keyValueMatchRule.java @@ -2,6 +2,7 @@ package io.metersphere.api.dto.mockserver; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections4.MapUtils; import java.util.List; @@ -15,8 +16,9 @@ public class keyValueMatchRule { private List matchRules; public boolean match(Map matchParam) { - if (MapUtils.isEmpty(matchParam)) { - return true; + if ((MapUtils.isEmpty(matchParam) && CollectionUtils.isNotEmpty(matchRules)) || + (CollectionUtils.isEmpty(matchRules) && MapUtils.isNotEmpty(matchParam))) { + return false; } if (isMatchAll) { for (KeyValueInfo matchRule : matchRules) { diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/MsHTTPElement.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/MsHTTPElement.java index 82f46e6b0b..04bafe0a95 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/MsHTTPElement.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/MsHTTPElement.java @@ -1,8 +1,8 @@ package io.metersphere.api.dto.request.http; -import io.metersphere.project.dto.environment.auth.HTTPAuthConfig; import io.metersphere.api.dto.request.http.body.Body; import io.metersphere.plugin.api.spi.AbstractMsProtocolTestElement; +import io.metersphere.project.dto.environment.auth.HTTPAuthConfig; import io.metersphere.sdk.constants.HttpMethodConstants; import io.metersphere.system.valid.EnumValue; import jakarta.validation.Valid; @@ -72,4 +72,8 @@ public class MsHTTPElement extends AbstractMsProtocolTestElement { * mock执行需要的接口编号 */ private Long num; + /** + * mock调试过来的mock编号 + */ + private String mockNum; } \ No newline at end of file diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java index 997f1febcb..bf7e81f020 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java @@ -105,7 +105,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter StringUtils.equalsIgnoreCase(header.getKey().trim(), ApiConstants.CONTENT_TYPE) - && StringUtils.contains(header.getValue(), contentType) + && StringUtils.contains(header.getValue(), contentType) ) .toList(); // 不包含则添加一个 @@ -475,7 +476,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter(); - apiModules = new ArrayList<>(); - importData = new ArrayList<>(); - List operationLogs = new ArrayList<>(); //数据入库 insertData(modulePathMap, idModuleMap, apiDetailWithDataUpdate, request, operationLogs); @@ -229,7 +224,7 @@ public class ApiDefinitionImportUtilService { @Transactional(rollbackFor = Exception.class) public void batchSaveLog(List operationLogs) { - SubListUtils.dealForSubList(operationLogs, 100, operationLogService::batchAdd); + operationLogService.batchAdd(operationLogs); } public Long getNextOrder(String projectId) { diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/mockserver/MockServerService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/mockserver/MockServerService.java index 1b7582d65b..78eb2ed940 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/mockserver/MockServerService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/mockserver/MockServerService.java @@ -62,9 +62,10 @@ public class MockServerService { } - public ResponseEntity execute(String method, String projectNum, String apiNum, HttpServletRequest request) { + public ResponseEntity execute(String method, String projectNum, String apiNum, String mockNum, HttpServletRequest request) { var requestHeaderMap = MockServerUtils.getHttpRequestHeader(request); String url = request.getRequestURL().toString(); + //判断根据mockNum是否可以找到对应的mock配置 如果找不到,需要拿接口下所有的mock配置进行匹配 String requestUrlSuffix = MockServerUtils.getUrlSuffix(StringUtils.joinWith("/", "/mock-server", projectNum, apiNum), request); // Try to find API definition based on projectNum and apiNum @@ -80,6 +81,13 @@ public class MockServerService { return requestNotFound(); } + if (StringUtils.isNotBlank(mockNum) && mockNum.startsWith(apiNum)) { + requestUrlSuffix = MockServerUtils.getUrlSuffix(StringUtils.joinWith("/", "/mock-server", projectNum, apiNum, mockNum), request); + } else { + mockNum = null; + } + + // Check if method and path match the API definition if (!StringUtils.equalsIgnoreCase(method, apiDefinition.getMethod()) || !MockServerUtils.checkUrlMatch(apiDefinition.getPath(), requestUrlSuffix)) { return requestNotFound(); @@ -89,7 +97,7 @@ public class MockServerService { HttpRequestParam requestMockParams = MockServerUtils.getHttpRequestParam(request, requestUrlSuffix, apiDefinition.getPath(), !isUrlParamMethod(method)); LogUtils.info("Mock [" + url + "] Header:{}", requestHeaderMap); LogUtils.info("Mock [" + url + "] request:{}", JSON.toJSONString(requestMockParams)); - ApiMockConfigDTO compareMockConfig = findMatchingMockConfig(apiDefinition.getId(), requestHeaderMap, requestMockParams); + ApiMockConfigDTO compareMockConfig = findMatchingMockConfig(apiDefinition.getId(), requestHeaderMap, requestMockParams, mockNum); if (compareMockConfig != null && !compareMockConfig.isEnable()) { return requestNotFound(); @@ -111,10 +119,13 @@ public class MockServerService { .orElse(null); } - private ApiMockConfigDTO findMatchingMockConfig(String apiId, Map requestHeaderMap, HttpRequestParam param) { + private ApiMockConfigDTO findMatchingMockConfig(String apiId, Map requestHeaderMap, HttpRequestParam param, String mockNum) { // 查询符合条件的 ApiDefinitionMockConfig 列表 ApiDefinitionMockExample mockExample = new ApiDefinitionMockExample(); mockExample.createCriteria().andApiDefinitionIdEqualTo(apiId); + if (StringUtils.isNotBlank(mockNum)) { + mockExample.getOredCriteria().forEach(criteria -> criteria.andExpectNumEqualTo(mockNum)); + } List apiDefinitionMockList = apiDefinitionMockMapper.selectByExample(mockExample); if (CollectionUtils.isEmpty(apiDefinitionMockList)) { diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionMockControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionMockControllerTests.java index 9e0c7ba827..aa452ae60b 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionMockControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionMockControllerTests.java @@ -1250,6 +1250,12 @@ public class ApiDefinitionMockControllerTests extends BaseTest { MockHttpServletRequestBuilder requestBuilder = mockServerTestService.getRequestBuilder("GET", url); ResultActions action = mockMvc.perform(requestBuilder); MockHttpServletResponse mockServerResponse = action.andReturn().getResponse(); + url = "/" + mockServerDomain + "/100001/" + apiDefinition.getNum() + "/" + mockData.getExpectNum() + apiDefinition.getPath(); + + //开始创建请求 + requestBuilder = mockServerTestService.getRequestBuilder("GET", url); + action = mockMvc.perform(requestBuilder); + mockServerResponse = action.andReturn().getResponse(); //判断响应 mockServerResponse.getContentAsString(StandardCharsets.UTF_8); mockData.setEnable(false);