diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/FilterChainUtils.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/FilterChainUtils.java index 3db7d88024..4ce025adc5 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/FilterChainUtils.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/FilterChainUtils.java @@ -112,6 +112,7 @@ public class FilterChainUtils { filterChainDefinitionMap.put("/api/doc/share/export/**", "anon"); filterChainDefinitionMap.put("/api/doc/share/stop/**", "anon"); filterChainDefinitionMap.put("/api/doc/share/download/file/**", "anon"); + filterChainDefinitionMap.put("/api/doc/share/plugin/script/**", "anon"); return filterChainDefinitionMap; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiDocShareController.java b/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiDocShareController.java index dfe782cf2c..aa26720369 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiDocShareController.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiDocShareController.java @@ -25,6 +25,7 @@ import io.metersphere.validation.groups.Created; import io.metersphere.validation.groups.Updated; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; @@ -125,26 +126,43 @@ public class ApiDocShareController { @PostMapping("/export/{type}") @Operation(summary = "接口测试-定义-分享-导出") + @Parameter(name = "type", description = "导出类型", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) public String export(@RequestBody ApiDocShareExportRequest request, @PathVariable String type) { return apiDocShareService.export(request, type, SessionUtils.getUserId()); } @GetMapping("/stop/{taskId}") @Operation(summary = "接口测试-定义-分享-导出-停止导出") + @Parameter(name = "taskId", description = "导出任务ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) public void caseStopExport(@PathVariable String taskId) { apiDefinitionExportService.stopExport(taskId, SessionUtils.getUserId()); } @GetMapping(value = "/download/file/{projectId}/{fileId}") @Operation(summary = "接口测试-定义-分享-导出-下载文件") + @Parameters({ + @Parameter(name = "projectId", description = "项目ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)), + @Parameter(name = "fileId", description = "文件ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) + }) public void downloadImgById(@PathVariable String projectId, @PathVariable String fileId, HttpServletResponse httpServletResponse) { apiDefinitionExportService.downloadFile(projectId, fileId, SessionUtils.getUserId(), httpServletResponse); } @GetMapping(value = "/get-detail/{id}") @Operation(summary = "接口测试-接口管理-获取接口详情") + @Parameter(name = "id", description = "接口定义ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) public ApiDefinitionDTO get(@PathVariable String id) { return apiDefinitionService.get(id, "admin"); } + @GetMapping("/plugin/script/{id}/{orgId}") + @Operation(summary = "获取定义的插件脚本") + @Parameters({ + @Parameter(name = "id", description = "接口定义ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)), + @Parameter(name = "orgId", description = "组织ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) + }) + public Object getApiProtocolScript(@PathVariable String id, @PathVariable String orgId) { + return apiDocShareService.getApiProtocolScript(id, orgId); + } + } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDocShareService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDocShareService.java index 8da2752cdf..eea9f8847e 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDocShareService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDocShareService.java @@ -2,18 +2,21 @@ package io.metersphere.api.service.definition; import io.metersphere.api.domain.ApiDocShare; import io.metersphere.api.domain.ApiDocShareExample; +import io.metersphere.api.dto.definition.ApiDefinitionDTO; import io.metersphere.api.dto.definition.ApiDocShareDTO; import io.metersphere.api.dto.definition.ApiDocShareDetail; import io.metersphere.api.dto.definition.request.*; import io.metersphere.api.mapper.ApiDocShareMapper; import io.metersphere.api.mapper.ExtApiDefinitionMapper; import io.metersphere.api.mapper.ExtApiDocShareMapper; +import io.metersphere.api.service.ApiTestService; import io.metersphere.sdk.constants.MsAssertionCondition; import io.metersphere.sdk.dto.CombineCondition; import io.metersphere.sdk.dto.CombineSearch; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.Translator; +import io.metersphere.system.dto.ProtocolDTO; import io.metersphere.system.dto.sdk.BaseTreeNode; import io.metersphere.system.service.UserToolService; import io.metersphere.system.uid.IDGenerator; @@ -28,6 +31,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * @author song-cc-rock @@ -49,6 +53,10 @@ public class ApiDocShareService { private ApiDefinitionModuleService apiDefinitionModuleService; @Resource private ApiDefinitionExportService apiDefinitionExportService; + @Resource + private ApiDefinitionService apiDefinitionService; + @Resource + private ApiTestService apiTestService; public static final String RANGE_ALL = "ALL"; @@ -175,6 +183,23 @@ public class ApiDocShareService { return apiDefinitionExportService.exportApiDefinition(request, type, currentUser); } + /** + * 获取接口定义的协议脚本 + * @param id 接口定义ID + * @param orgId 组织ID + * @return 协议脚本 + */ + public Object getApiProtocolScript(String id, String orgId) { + ApiDefinitionDTO apiDefinitionDTO = apiDefinitionService.get(id, "admin"); + List protocols = apiTestService.getProtocols(orgId); + List noHttpProtocols = protocols.stream().filter(protocol -> !StringUtils.equals(protocol.getProtocol(), "HTTP")).toList(); + Map protocolMap = noHttpProtocols.stream().collect(Collectors.toMap(ProtocolDTO::getProtocol, ProtocolDTO::getPluginId)); + if (!protocolMap.containsKey(apiDefinitionDTO.getProtocol())) { + return null; + } + return apiTestService.getApiProtocolScript(protocolMap.get(apiDefinitionDTO.getProtocol())); + } + /** * 构建分享额外信息 * @param docShares 分享列表 diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDocShareControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDocShareControllerTests.java index c294db512a..e9bcd2ca87 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDocShareControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDocShareControllerTests.java @@ -14,6 +14,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @@ -38,10 +40,12 @@ public class ApiDocShareControllerTests extends BaseTest { private final static String MODULE_COUNT = BASE_PATH + "module/count"; private final static String EXPORT = BASE_PATH + "export/Swagger"; private final static String DOWNLOAD = BASE_PATH + "download/file/"; - private final static String GET_DETAIL = BASE_PATH + "/get-detail/"; + private final static String GET_DETAIL = BASE_PATH + "get-detail/"; + private final static String GET_PLUGIN_SCRIPT = BASE_PATH + "plugin/script/"; @Order(1) @Test + @Sql(scripts = {"/dml/init_api_doc_share.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED)) public void addOrUpdate() throws Exception { ApiDocShareEditRequest request = new ApiDocShareEditRequest(); request.setName("share-1"); @@ -87,7 +91,8 @@ public class ApiDocShareControllerTests extends BaseTest { this.requestGetWithOk(DELETE + docShare.getId()); // 不存在的ID this.requestGet(DELETE + "not-exist-id").andExpect(status().is5xxServerError()); - this.requestGet(GET_DETAIL + "not-exist-id").andExpect(status().is5xxServerError()); + this.requestGetWithOk(GET_DETAIL + "doc-share-id"); + getPluginScript("doc-share-id", DEFAULT_ORGANIZATION_ID); } @Order(2) @@ -149,4 +154,10 @@ public class ApiDocShareControllerTests extends BaseTest { .header(SessionConstants.HEADER_TOKEN, sessionId) .header(SessionConstants.CSRF_TOKEN, csrfToken)).andReturn(); } + + private MvcResult getPluginScript(String id, String orgId) throws Exception { + return mockMvc.perform(MockMvcRequestBuilders.get(GET_PLUGIN_SCRIPT + id + "/" + orgId) + .header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken)).andReturn(); + } } diff --git a/backend/services/api-test/src/test/resources/dml/init_api_doc_share.sql b/backend/services/api-test/src/test/resources/dml/init_api_doc_share.sql new file mode 100644 index 0000000000..dd4848b516 --- /dev/null +++ b/backend/services/api-test/src/test/resources/dml/init_api_doc_share.sql @@ -0,0 +1,3 @@ +-- 插入测试数据 +INSERT INTO `api_definition` (`id`, `name`, `protocol`, `method`, `path`, `status`, `num`, `tags`, `pos`, `project_id`, `module_id`, `latest`, `version_id`, `ref_id`, `description`, `create_time`, `create_user`, `update_time`, `update_user`, `delete_user`, `delete_time`, `deleted`) VALUES +('doc-share-id', 'test1', 'HTTP', 'POST', '/api/admin/1', 'PROCESSING', 1001, '[\"test3\",\"te\"]', 1, '100001100001', 'root', b'1', '100570499574136985', '1001', NULL, 1699500298164, 'admin', 1699500298162, 'admin', NULL, NULL, b'0');