diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java b/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java index 93a7675139..cae71a145e 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java @@ -1,9 +1,6 @@ package io.metersphere.project.controller; -import io.metersphere.project.dto.environment.EnvironmentFilterRequest; -import io.metersphere.project.dto.environment.EnvironmentImportRequest; -import io.metersphere.project.dto.environment.EnvironmentInfoDTO; -import io.metersphere.project.dto.environment.EnvironmentRequest; +import io.metersphere.project.dto.environment.*; import io.metersphere.project.dto.environment.datasource.DataSource; import io.metersphere.project.dto.environment.ssl.KeyStoreEntry; import io.metersphere.project.service.CommandService; @@ -57,6 +54,12 @@ public class EnvironmentController { return environmentService.get(id); } + @GetMapping("/scripts/{projectId}") + @Operation(summary = "项目管理-环境-环境目录-接口插件前端配置脚本列表") + @RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ) + public List getPluginScripts(@PathVariable String projectId) { + return environmentService.getPluginScripts(projectId); + } @PostMapping("/add") @Operation(summary = "项目管理-环境-环境目录-新增") diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java index fcdc53de13..ea2bf27069 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java @@ -15,6 +15,7 @@ import lombok.Data; import java.io.Serial; import java.io.Serializable; import java.util.List; +import java.util.Map; @Data public class EnvironmentConfig implements Serializable { @@ -38,6 +39,8 @@ public class EnvironmentConfig implements Serializable { private EnvironmentPostScript postScript; @Schema(description = "全局断言") private MsAssertionConfig assertions; + @Schema(description = "插件自定义的配置项,key为插件ID,value 为对应配置") + private Map pluginConfigMap; public EnvironmentConfig() { diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentPluginScriptDTO.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentPluginScriptDTO.java new file mode 100644 index 0000000000..b7f86b0d4a --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentPluginScriptDTO.java @@ -0,0 +1,16 @@ +package io.metersphere.project.dto.environment; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * @Author: jianxing + * @CreateTime: 2024-01-30 13:57 + */ +@Data +public class EnvironmentPluginScriptDTO { + @Schema(description = "插件ID") + private String pluginId; + @Schema(description = "脚本内容") + private Object script; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java index b8b4fef0a7..c3bfb6b033 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java @@ -18,6 +18,7 @@ import io.metersphere.sdk.file.MinioRepository; import io.metersphere.sdk.mapper.EnvironmentBlobMapper; import io.metersphere.sdk.mapper.EnvironmentMapper; import io.metersphere.sdk.util.*; +import io.metersphere.system.domain.PluginScript; import io.metersphere.system.dto.sdk.BaseSystemConfigDTO; import io.metersphere.system.dto.sdk.OptionDTO; import io.metersphere.system.dto.sdk.request.PosRequest; @@ -26,7 +27,9 @@ import io.metersphere.system.log.constants.OperationLogModule; import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.log.dto.LogDTO; import io.metersphere.system.log.service.OperationLogService; +import io.metersphere.system.service.ApiPluginService; import io.metersphere.system.service.JdbcDriverPluginService; +import io.metersphere.system.service.PluginScriptService; import io.metersphere.system.service.SystemParameterService; import io.metersphere.system.uid.IDGenerator; import io.metersphere.system.utils.ServiceUtils; @@ -34,6 +37,7 @@ import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import org.pf4j.PluginWrapper; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -63,6 +67,12 @@ public class EnvironmentService { private OperationLogService operationLogService; @Resource private ExtEnvironmentMapper extEnvironmentMapper; + @Resource + private ProjectService projectService; + @Resource + private ApiPluginService apiPluginService; + @Resource + private PluginScriptService pluginScriptService; public static final Long ORDER_STEP = 5000L; private static final String USERNAME = "user"; @@ -367,4 +377,23 @@ public class EnvironmentService { extEnvironmentMapper::getLastPos, environmentMapper::updateByPrimaryKeySelective); } + + public List getPluginScripts(String projectId) { + Project project = projectService.checkProjectNotExist(projectId); + // 查询组织下有权限的接口插件ID + List orgApiPluginIds = apiPluginService.getOrgApiPluginWrappers(project.getOrganizationId()) + .stream() + .map(PluginWrapper::getPluginId) + .collect(Collectors.toList()); + // 查询环境页面脚本 + List pluginScripts = pluginScriptService.getByPluginIdsAndScriptId(orgApiPluginIds, "environment"); + + // 返回环境脚本列表 + return pluginScripts.stream().map(pluginScript -> { + EnvironmentPluginScriptDTO envPluginScript = new EnvironmentPluginScriptDTO(); + envPluginScript.setPluginId(pluginScript.getPluginId()); + envPluginScript.setScript(JSON.parseObject(new String(pluginScript.getScript()))); + return envPluginScript; + }).toList(); + } } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/ProjectService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/ProjectService.java index cb0d2ea8d7..0fdec1412b 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/ProjectService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/ProjectService.java @@ -129,10 +129,12 @@ public class ProjectService { } } - public void checkProjectNotExist(String id) { - if (projectMapper.selectByPrimaryKey(id) == null) { + public Project checkProjectNotExist(String id) { + Project project = projectMapper.selectByPrimaryKey(id); + if (project == null) { throw new MSException(Translator.get("project_is_not_exist")); } + return project; } private List getPoolIds(String projectId) { diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java index fd96cae49d..49c7d28a59 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java @@ -34,10 +34,13 @@ import io.metersphere.sdk.util.CommonBeanFactory; import io.metersphere.sdk.util.JSON; import io.metersphere.system.base.BaseTest; import io.metersphere.system.controller.handler.ResultHolder; +import io.metersphere.system.domain.Plugin; +import io.metersphere.system.dto.request.PluginUpdateRequest; import io.metersphere.system.dto.sdk.OptionDTO; import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.dto.table.TableBatchProcessDTO; import io.metersphere.system.log.constants.OperationLogType; +import io.metersphere.system.service.PluginService; import jakarta.annotation.Resource; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.*; @@ -65,7 +68,10 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; +import static io.metersphere.sdk.constants.InternalUserRole.ADMIN; +import static io.metersphere.sdk.constants.PermissionConstants.PROJECT_ENVIRONMENT_READ; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -88,6 +94,7 @@ public class EnvironmentControllerTests extends BaseTest { private static final String validate = prefix + "/database/validate"; private static final String getOptions = prefix + "/database/driver-options/"; + private static final String SCRIPTS = prefix + "/scripts/{0}"; private static final ResultMatcher BAD_REQUEST_MATCHER = status().isBadRequest(); private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError(); private static String MOCKID; @@ -97,6 +104,8 @@ public class EnvironmentControllerTests extends BaseTest { private EnvironmentMapper environmentMapper; @Resource private EnvironmentBlobMapper environmentBlobMapper; + @Resource + private PluginService pluginService; @Value("${spring.datasource.url}") private String dburl; @Value("${spring.datasource.username}") @@ -809,7 +818,7 @@ public class EnvironmentControllerTests extends BaseTest { Assertions.assertNotNull(response); Assertions.assertEquals("environmentId1", response.getId()); //校验权限 - requestGetPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ, get + DEFAULT_PROJECT_ID); + requestGetPermissionTest(PROJECT_ENVIRONMENT_READ, get + DEFAULT_PROJECT_ID); EnvironmentExample environmentExample = new EnvironmentExample(); environmentExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andMockEqualTo(true); List environmentList = environmentMapper.selectByExample(environmentExample); @@ -842,7 +851,7 @@ public class EnvironmentControllerTests extends BaseTest { dataSource.setDriver("com.mysql.cj.jdbc.Driver"); this.requestPost(validate, dataSource, status().isOk()); //校验权限 - requestPostPermissionsTest(Arrays.asList(PermissionConstants.PROJECT_ENVIRONMENT_READ, PermissionConstants.PROJECT_ENVIRONMENT_READ_ADD, PermissionConstants.PROJECT_ENVIRONMENT_READ_UPDATE), + requestPostPermissionsTest(Arrays.asList(PROJECT_ENVIRONMENT_READ, PermissionConstants.PROJECT_ENVIRONMENT_READ_ADD, PermissionConstants.PROJECT_ENVIRONMENT_READ_UPDATE), validate, dataSource); } @@ -872,7 +881,7 @@ public class EnvironmentControllerTests extends BaseTest { Assertions.assertNotNull(optionDTOS); //校验权限 - requestGetPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ, getOptions + DEFAULT_PROJECT_ID); + requestGetPermissionTest(PROJECT_ENVIRONMENT_READ, getOptions + DEFAULT_PROJECT_ID); } @Test @@ -1039,7 +1048,7 @@ public class EnvironmentControllerTests extends BaseTest { Assertions.assertEquals(1, response.size()); environmentDTO.setProjectId(DEFAULT_PROJECT_ID); //校验权限 - requestPostPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ, list, environmentDTO); + requestPostPermissionTest(PROJECT_ENVIRONMENT_READ, list, environmentDTO); //项目不存在 返回内容为[] environmentDTO.setProjectId("ceshi"); @@ -1172,5 +1181,33 @@ public class EnvironmentControllerTests extends BaseTest { .andExpect(ERROR_REQUEST_MATCHER); } + @Test + @Order(16) + public void testScripts() throws Exception { + Plugin plugin = addEnvScriptsTestPlugin(); + MvcResult mvcResult = requestGetWithOkAndReturn(SCRIPTS, DEFAULT_PROJECT_ID); + List envScripts = getResultDataArray(mvcResult, EnvironmentPluginScriptDTO.class); + Assertions.assertEquals(envScripts.size(), 1); + Assertions.assertEquals(envScripts.get(0).getPluginId(), "tcp-sampler"); + Assertions.assertEquals(((Map) envScripts.get(0).getScript()).get("id"), "environment"); + + pluginService.delete(plugin.getId()); + requestGetPermissionTest(PROJECT_ENVIRONMENT_READ, SCRIPTS, DEFAULT_PROJECT_ID); + } + + public Plugin addEnvScriptsTestPlugin() throws Exception { + PluginUpdateRequest request = new PluginUpdateRequest(); + File jarFile = new File( + this.getClass().getClassLoader().getResource("file/tcp-sampler-v3.x-jar-with-dependencies.jar") + .getPath() + ); + FileInputStream inputStream = new FileInputStream(jarFile); + MockMultipartFile mockMultipartFile = new MockMultipartFile(jarFile.getName(), jarFile.getName(), "jar", inputStream); + request.setName("测试获取环境脚本插件"); + request.setGlobal(true); + request.setEnable(true); + request.setCreateUser(ADMIN.name()); + return pluginService.add(request, mockMultipartFile); + } } diff --git a/backend/services/project-management/src/test/resources/file/tcp-sampler-v3.x-jar-with-dependencies.jar b/backend/services/project-management/src/test/resources/file/tcp-sampler-v3.x-jar-with-dependencies.jar new file mode 100644 index 0000000000..3c0fe0ccbe Binary files /dev/null and b/backend/services/project-management/src/test/resources/file/tcp-sampler-v3.x-jar-with-dependencies.jar differ diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/PluginScriptService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/PluginScriptService.java index 4c636fb0e4..bc1efce051 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/PluginScriptService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/PluginScriptService.java @@ -85,4 +85,13 @@ public class PluginScriptService { return scriptMap; } + + public List getByPluginIdsAndScriptId(List pluginIds, String scriptId) { + if (CollectionUtils.isEmpty(pluginIds)) { + return Collections.emptyList(); + } + PluginScriptExample example = new PluginScriptExample(); + example.createCriteria().andScriptIdEqualTo(scriptId); + return pluginScriptMapper.selectByExampleWithBLOBs(example); + } } diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/PluginControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/PluginControllerTests.java index bded5ca02b..96d44abcc9 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/PluginControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/PluginControllerTests.java @@ -316,6 +316,11 @@ public class PluginControllerTests extends BaseTest { public void getScript() throws Exception { // @@请求成功 MvcResult mvcResult = this.requestGetWithOk(SCRIPT_GET, this.addPlugin.getId(), "connect").andReturn(); + + // 增加覆盖率 + pluginScriptService.getByPluginIdsAndScriptId(List.of(), "connect"); + pluginScriptService.getByPluginIdsAndScriptId(List.of(addPlugin.getId()), "connect"); + // 校验数据是否正确 Assertions.assertTrue(StringUtils.isNotBlank(getResultData(mvcResult, String.class))); // @@校验权限