refactor(接口测试): 增加清理场景逻辑

This commit is contained in:
wxg0103 2024-02-02 19:01:23 +08:00 committed by Craftsman
parent d01007c6a1
commit dc1a869105
16 changed files with 237 additions and 82 deletions

View File

@ -37,4 +37,6 @@ public interface ExtApiScenarioMapper {
List<ApiScenarioAssociationDTO> getAssociationPage(@Param("request") ApiScenarioAssociationPageRequest request); List<ApiScenarioAssociationDTO> getAssociationPage(@Param("request") ApiScenarioAssociationPageRequest request);
List<String> getIdsByModules(@Param("request") ScenarioSystemRequest scenarioRequest); List<String> getIdsByModules(@Param("request") ScenarioSystemRequest scenarioRequest);
List<String> selectByProjectId(String projectId);
} }

View File

@ -460,6 +460,10 @@
</if> </if>
</select> </select>
<select id="selectByProjectId" resultType="java.lang.String">
select id from api_scenario
where project_id = #{projectId}
</select>
<sql id="taskCenterFilters"> <sql id="taskCenterFilters">
<if test="${filter} != null and ${filter}.size() > 0"> <if test="${filter} != null and ${filter}.size() > 0">

View File

@ -12,7 +12,10 @@ import io.metersphere.plugin.api.dto.ParameterConfig;
import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.plugin.api.spi.AbstractMsTestElement;
import io.metersphere.project.domain.ProjectApplication; import io.metersphere.project.domain.ProjectApplication;
import io.metersphere.project.dto.customfunction.request.CustomFunctionRunRequest; import io.metersphere.project.dto.customfunction.request.CustomFunctionRunRequest;
import io.metersphere.project.service.*; import io.metersphere.project.service.FileAssociationService;
import io.metersphere.project.service.FileManagementService;
import io.metersphere.project.service.FileMetadataService;
import io.metersphere.project.service.ProjectApplicationService;
import io.metersphere.sdk.constants.ApiExecuteResourceType; import io.metersphere.sdk.constants.ApiExecuteResourceType;
import io.metersphere.sdk.constants.ApiExecuteRunMode; import io.metersphere.sdk.constants.ApiExecuteRunMode;
import io.metersphere.sdk.constants.ProjectApplicationType; import io.metersphere.sdk.constants.ProjectApplicationType;
@ -41,10 +44,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static io.metersphere.api.controller.result.ApiResultCode.RESOURCE_POOL_EXECUTE_ERROR; import static io.metersphere.api.controller.result.ApiResultCode.RESOURCE_POOL_EXECUTE_ERROR;
@ -89,7 +89,7 @@ public class ApiExecuteService {
} }
public String getJmeterHome() { public String getJmeterHome() {
String home = getClass().getResource("/").getPath() + "jmeter"; String home = Objects.requireNonNull(getClass().getResource("/")).getPath() + "jmeter";
try { try {
File file = new File(home); File file = new File(home);
if (file.exists()) { if (file.exists()) {
@ -133,10 +133,11 @@ public class ApiExecuteService {
/** /**
* 发送执行任务 * 发送执行任务
* @param reportId 报告ID *
* @param testId 资源ID * @param reportId 报告ID
* @param taskRequest 执行参数 * @param testId 资源ID
* @param executeScript 执行脚本 * @param taskRequest 执行参数
* @param executeScript 执行脚本
* @param testResourceNodeDTO 资源池 * @param testResourceNodeDTO 资源池
*/ */
private void doDebug(String reportId, private void doDebug(String reportId,
@ -175,7 +176,7 @@ public class ApiExecuteService {
/** /**
* 设置minio kafka ms 等信息 * 设置minio kafka ms 等信息
* *
* @param taskRequest * @param taskRequest 执行参数
*/ */
private void setServerInfoParam(TaskRequestDTO taskRequest) { private void setServerInfoParam(TaskRequestDTO taskRequest) {
taskRequest.setKafkaConfig(EncryptUtils.aesEncrypt(JSON.toJSONString(KafkaConfig.getKafkaConfig()))); taskRequest.setKafkaConfig(EncryptUtils.aesEncrypt(JSON.toJSONString(KafkaConfig.getKafkaConfig())));
@ -185,8 +186,9 @@ public class ApiExecuteService {
/** /**
* 公共脚本执行 * 公共脚本执行
* @param runRequest *
* @return * @param runRequest 执行参数
* @return 报告ID
*/ */
public String runScript(CustomFunctionRunRequest runRequest) { public String runScript(CustomFunctionRunRequest runRequest) {
String reportId = runRequest.getReportId(); String reportId = runRequest.getReportId();
@ -215,8 +217,8 @@ public class ApiExecuteService {
/** /**
* taskRequest 设置文件相关参数 * taskRequest 设置文件相关参数
* *
* @param request * @param request 请求参数
* @param taskRequest * @param taskRequest 执行参数
*/ */
private void setTaskFileParam(ApiResourceRunRequest request, TaskRequestDTO taskRequest) { private void setTaskFileParam(ApiResourceRunRequest request, TaskRequestDTO taskRequest) {
// 查询通过本地上传的文件 // 查询通过本地上传的文件
@ -264,7 +266,7 @@ public class ApiExecuteService {
tempFileInfo.setFileModuleRepositoryDTO(fileManagementService.getFileModuleRepositoryDTO(file.getModuleId())); tempFileInfo.setFileModuleRepositoryDTO(fileManagementService.getFileModuleRepositoryDTO(file.getModuleId()));
} }
return tempFileInfo; return tempFileInfo;
}).collect(Collectors.toList()); }).toList();
// 添加临时的文件管理的文件 // 添加临时的文件管理的文件
refFiles.addAll(refTempFiles); refFiles.addAll(refTempFiles);
@ -274,8 +276,7 @@ public class ApiExecuteService {
.filter(tempFileId -> !refTempFileIds.contains(tempFileId)) .filter(tempFileId -> !refTempFileIds.contains(tempFileId))
.map(tempFileId -> { .map(tempFileId -> {
String fileName = apiFileResourceService.getTempFileNameByFileId(tempFileId); String fileName = apiFileResourceService.getTempFileNameByFileId(tempFileId);
ApiExecuteFileInfo apiExecuteFileInfo = getApiExecuteFileInfo(tempFileId, fileName, request.getProjectId()); return getApiExecuteFileInfo(tempFileId, fileName, request.getProjectId());
return apiExecuteFileInfo;
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
taskRequest.setLocalTempFiles(localTempFiles); taskRequest.setLocalTempFiles(localTempFiles);
@ -300,9 +301,9 @@ public class ApiExecuteService {
/** /**
* 生成执行脚本 * 生成执行脚本
* *
* @param msTestElement * @param msTestElement 接口元素
* @param config * @param config 参数配置
* @return * @return 执行脚本
*/ */
private static String parseExecuteScript(AbstractMsTestElement msTestElement, ParameterConfig config) { private static String parseExecuteScript(AbstractMsTestElement msTestElement, ParameterConfig config) {
// 解析生成脚本 // 解析生成脚本
@ -314,6 +315,7 @@ public class ApiExecuteService {
public static Map<String, String> getMinio() { public static Map<String, String> getMinio() {
MinioProperties minioProperties = CommonBeanFactory.getBean(MinioProperties.class); MinioProperties minioProperties = CommonBeanFactory.getBean(MinioProperties.class);
Map<String, String> minioPros = new HashMap<>(); Map<String, String> minioPros = new HashMap<>();
assert minioProperties != null;
minioPros.put("endpoint", minioProperties.getEndpoint()); minioPros.put("endpoint", minioProperties.getEndpoint());
minioPros.put("accessKey", minioProperties.getAccessKey()); minioPros.put("accessKey", minioProperties.getAccessKey());
minioPros.put("secretKey", minioProperties.getSecretKey()); minioPros.put("secretKey", minioProperties.getSecretKey());
@ -323,8 +325,8 @@ public class ApiExecuteService {
/** /**
* 获取当前项目配置的接口默认资源池 * 获取当前项目配置的接口默认资源池
* *
* @param projectId * @param projectId 项目ID
* @param * @param resourcePoolId 资源池ID
*/ */
public TestResourceDTO getAvailableResourcePoolDTO(String projectId, String resourcePoolId) { public TestResourceDTO getAvailableResourcePoolDTO(String projectId, String resourcePoolId) {
TestResourcePool testResourcePool = testResourcePoolService.getTestResourcePool(resourcePoolId); TestResourcePool testResourcePool = testResourcePoolService.getTestResourcePool(resourcePoolId);
@ -345,7 +347,6 @@ public class ApiExecuteService {
if (resourcePoolConfig == null || StringUtils.isBlank(resourcePoolConfig.getTypeValue())) { if (resourcePoolConfig == null || StringUtils.isBlank(resourcePoolConfig.getTypeValue())) {
throw new MSException(ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG); throw new MSException(ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG);
} }
String resourcePoolId = StringUtils.isBlank(resourcePoolConfig.getTypeValue()) ? null : resourcePoolConfig.getTypeValue(); return StringUtils.isBlank(resourcePoolConfig.getTypeValue()) ? null : resourcePoolConfig.getTypeValue();
return resourcePoolId;
} }
} }

View File

@ -44,7 +44,7 @@ public class ApiFileResourceService {
/** /**
* 上传接口相关的资源文件 * 上传接口相关的资源文件
* *
* @param folder * @param folder 文件夹
* @param addFileMap key:fileId value:fileName * @param addFileMap key:fileId value:fileName
*/ */
public void uploadFileResource(String folder, Map<String, String> addFileMap) { public void uploadFileResource(String folder, Map<String, String> addFileMap) {
@ -190,10 +190,10 @@ public class ApiFileResourceService {
/** /**
* 删除资源下所有的文件或者关联关系 * 删除资源下所有的文件或者关联关系
* *
* @param apiDebugDir * @param apiDebugDir 本地上传文件目录
* @param resourceId * @param resourceId 资源ID
* @param projectId * @param projectId 项目ID
* @param operator * @param operator 操作人
*/ */
public void deleteByResourceId(String apiDebugDir, String resourceId, String projectId, String operator, String logModule) { public void deleteByResourceId(String apiDebugDir, String resourceId, String projectId, String operator, String logModule) {
// 处理本地上传的文件 // 处理本地上传的文件

View File

@ -65,8 +65,9 @@ public class ApiTaskCenterService {
/** /**
* 任务中心实时任务列表-项目级 * 任务中心实时任务列表-项目级
* @param request *
* @return * @param request 请求参数
* @return 任务中心实时任务列表
*/ */
public Pager<List<TaskCenterDTO>> getProjectPage(TaskCenterPageRequest request, String projectId) { public Pager<List<TaskCenterDTO>> getProjectPage(TaskCenterPageRequest request, String projectId) {
checkProjectExist(projectId); checkProjectExist(projectId);
@ -76,8 +77,9 @@ public class ApiTaskCenterService {
/** /**
* 任务中心实时任务列表-组织级 * 任务中心实时任务列表-组织级
* @param request *
* @returnxx * @param request 请求参数
* @returnxx 任务中心实时任务列表
*/ */
public Pager<List<TaskCenterDTO>> getOrganizationPage(TaskCenterPageRequest request, String organizationId) { public Pager<List<TaskCenterDTO>> getOrganizationPage(TaskCenterPageRequest request, String organizationId) {
checkOrganizationExist(organizationId); checkOrganizationExist(organizationId);
@ -87,8 +89,9 @@ public class ApiTaskCenterService {
/** /**
* 任务中心实时任务列表-系统级 * 任务中心实时任务列表-系统级
* @param request *
* @return * @param request 请求参数
* @return 任务中心实时任务列表
*/ */
public Pager<List<TaskCenterDTO>> getSystemPage(TaskCenterPageRequest request) { public Pager<List<TaskCenterDTO>> getSystemPage(TaskCenterPageRequest request) {
List<OptionDTO> projectList = getSystemProjectList(); List<OptionDTO> projectList = getSystemProjectList();
@ -107,7 +110,7 @@ public class ApiTaskCenterService {
if (request != null && !projectIds.isEmpty()) { if (request != null && !projectIds.isEmpty()) {
if (request.getModuleType().equals(TaskCenterResourceType.API_CASE.toString())) { if (request.getModuleType().equals(TaskCenterResourceType.API_CASE.toString())) {
list = extApiReportMapper.taskCenterlist(request, projectIds); list = extApiReportMapper.taskCenterlist(request, projectIds);
} else if (request.getModuleType().equals(TaskCenterResourceType.API_SCENARIO.toString())){ } else if (request.getModuleType().equals(TaskCenterResourceType.API_SCENARIO.toString())) {
list = extApiScenarioMapper.taskCenterlist(request, projectIds); list = extApiScenarioMapper.taskCenterlist(request, projectIds);
} }
processTaskCenter(list, projectList, projectIds); processTaskCenter(list, projectList, projectIds);
@ -136,18 +139,19 @@ public class ApiTaskCenterService {
} }
} }
private List<OptionDTO> getProjectOption(String id){ private List<OptionDTO> getProjectOption(String id) {
return baseProjectMapper.getProjectOptionsById(id); return baseProjectMapper.getProjectOptionsById(id);
} }
private List<OptionDTO> getOrgProjectList(String orgId){
private List<OptionDTO> getOrgProjectList(String orgId) {
return baseProjectMapper.getProjectOptionsByOrgId(orgId); return baseProjectMapper.getProjectOptionsByOrgId(orgId);
} }
private List<OptionDTO> getSystemProjectList(){ private List<OptionDTO> getSystemProjectList() {
return baseProjectMapper.getProjectOptions(); return baseProjectMapper.getProjectOptions();
} }
private List<OptionDTO> getOrgListByProjectIds(List<String> projectIds){ private List<OptionDTO> getOrgListByProjectIds(List<String> projectIds) {
return extOrganizationMapper.getOrgListByProjectIds(projectIds); return extOrganizationMapper.getOrgListByProjectIds(projectIds);
} }
@ -156,12 +160,11 @@ public class ApiTaskCenterService {
* *
* @param projectId 项目ID * @param projectId 项目ID
*/ */
private Project checkProjectExist(String projectId) { private void checkProjectExist(String projectId) {
Project project = projectMapper.selectByPrimaryKey(projectId); Project project = projectMapper.selectByPrimaryKey(projectId);
if (project == null) { if (project == null) {
throw new MSException(Translator.get("project_not_exist")); throw new MSException(Translator.get("project_not_exist"));
} }
return project;
} }
/** /**
@ -169,12 +172,11 @@ public class ApiTaskCenterService {
* *
* @param orgId 组织ID * @param orgId 组织ID
*/ */
private Organization checkOrganizationExist(String orgId) { private void checkOrganizationExist(String orgId) {
Organization organization = organizationMapper.selectByPrimaryKey(orgId); Organization organization = organizationMapper.selectByPrimaryKey(orgId);
if (organization == null) { if (organization == null) {
throw new MSException(Translator.get("organization_not_exist")); throw new MSException(Translator.get("organization_not_exist"));
} }
return organization;
} }
} }

View File

@ -51,6 +51,7 @@ public class ApiTestService {
ServiceUtils.checkResourceExist(null, "permission.api_plugin.name"); ServiceUtils.checkResourceExist(null, "permission.api_plugin.name");
} }
ApiPluginOptionsRequest optionsRequest = BeanUtils.copyBean(new ApiPluginOptionsRequest(), request); ApiPluginOptionsRequest optionsRequest = BeanUtils.copyBean(new ApiPluginOptionsRequest(), request);
assert pluginWrapper != null;
return ((AbstractApiPlugin) pluginWrapper.getPlugin()).getPluginOptions(optionsRequest); return ((AbstractApiPlugin) pluginWrapper.getPlugin()).getPluginOptions(optionsRequest);
} }
} }

View File

@ -1,6 +1,7 @@
package io.metersphere.api.service; package io.metersphere.api.service;
import io.metersphere.api.domain.*; import io.metersphere.api.domain.*;
import io.metersphere.api.job.ApiScenarioScheduleJob;
import io.metersphere.api.mapper.*; import io.metersphere.api.mapper.*;
import io.metersphere.api.service.schedule.SwaggerUrlImportJob; import io.metersphere.api.service.schedule.SwaggerUrlImportJob;
import io.metersphere.sdk.constants.DefaultRepositoryDir; import io.metersphere.sdk.constants.DefaultRepositoryDir;
@ -16,6 +17,7 @@ import io.metersphere.system.mapper.ScheduleMapper;
import io.metersphere.system.schedule.ScheduleService; import io.metersphere.system.schedule.ScheduleService;
import io.metersphere.system.service.CleanupProjectResourceService; import io.metersphere.system.service.CleanupProjectResourceService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotEmpty;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -82,6 +84,20 @@ public class CleanupApiResourceServiceImpl implements CleanupProjectResourceServ
private ShareInfoMapper shareInfoMapper; private ShareInfoMapper shareInfoMapper;
@Resource @Resource
private ApiDefinitionSwaggerMapper apiDefinitionSwaggerMapper; private ApiDefinitionSwaggerMapper apiDefinitionSwaggerMapper;
@Resource
private ExtApiScenarioMapper extApiScenarioMapper;
@Resource
private ApiScenarioMapper apiScenarioMapper;
@Resource
private ApiScenarioBlobMapper apiScenarioBlobMapper;
@Resource
private ApiScenarioStepMapper apiScenarioStepMapper;
@Resource
private ApiScenarioStepBlobMapper apiScenarioStepBlobMapper;
@Resource
private ApiScenarioCsvMapper apiScenarioCsvMapper;
@Resource
private ApiScenarioCsvStepMapper apiScenarioCsvStepMapper;
@Async @Async
@ -99,6 +115,66 @@ public class CleanupApiResourceServiceImpl implements CleanupProjectResourceServ
deleteShareUrl(projectId); deleteShareUrl(projectId);
//删除定时任务 //删除定时任务
deleteSchedule(projectId); deleteSchedule(projectId);
//删除场景
deleteScenario(projectId);
}
private void deleteScenario(String projectId) {
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andProjectIdEqualTo(projectId);
List<String> scenarioIds = extApiScenarioMapper.selectByProjectId(projectId);
if (CollectionUtils.isNotEmpty(scenarioIds)) {
SubListUtils.dealForSubList(scenarioIds, 500, subList -> {
cascadeDelete(subList, OperationLogConstants.SYSTEM);
});
}
}
public void cascadeDelete(@NotEmpty List<String> subList, String operator) {
ApiScenarioBlobExample example = new ApiScenarioBlobExample();
example.createCriteria().andIdIn(subList);
//删除blob
apiScenarioBlobMapper.deleteByExample(example);
ApiScenarioStepExample stepExample = new ApiScenarioStepExample();
stepExample.createCriteria().andScenarioIdIn(subList);
//删除step
apiScenarioStepMapper.deleteByExample(stepExample);
//删除step-blob
ApiScenarioStepBlobExample blobExample = new ApiScenarioStepBlobExample();
blobExample.createCriteria().andScenarioIdIn(subList);
apiScenarioStepBlobMapper.deleteByExample(blobExample);
ApiScenarioExample apiScenarioExample = new ApiScenarioExample();
apiScenarioExample.createCriteria().andIdIn(subList);
List<ApiScenario> scenarioList = apiScenarioMapper.selectByExample(apiScenarioExample);
scenarioList.forEach(scenario -> {
//删除文件
String scenarioDir = DefaultRepositoryDir.getApiDebugDir(scenario.getProjectId(), scenario.getId());
try {
apiFileResourceService.deleteByResourceId(scenarioDir, scenario.getId(), scenario.getProjectId(), operator, OperationLogModule.API_DEBUG);
} catch (Exception ignore) {
}
});
//删除csv
ApiScenarioCsvExample csvExample = new ApiScenarioCsvExample();
csvExample.createCriteria().andScenarioIdIn(subList);
List<ApiScenarioCsv> apiScenarioCsv = apiScenarioCsvMapper.selectByExample(csvExample);
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(apiScenarioCsv)) {
List<String> fileIds = apiScenarioCsv.stream().map(ApiScenarioCsv::getFileId).toList();
//删除关联关系
ApiScenarioCsvStepExample csvStepExample = new ApiScenarioCsvStepExample();
csvStepExample.createCriteria().andFileIdIn(fileIds);
apiScenarioCsvStepMapper.deleteByExample(csvStepExample);
}
apiScenarioCsvMapper.deleteByExample(csvExample);
//删除场景
apiScenarioMapper.deleteByExample(apiScenarioExample);
} }
@ -255,7 +331,13 @@ public class CleanupApiResourceServiceImpl implements CleanupProjectResourceServ
ApiDefinitionSwaggerExample swaggerExample = new ApiDefinitionSwaggerExample(); ApiDefinitionSwaggerExample swaggerExample = new ApiDefinitionSwaggerExample();
swaggerExample.createCriteria().andProjectIdEqualTo(projectId); swaggerExample.createCriteria().andProjectIdEqualTo(projectId);
apiDefinitionSwaggerMapper.deleteByExample(swaggerExample); apiDefinitionSwaggerMapper.deleteByExample(swaggerExample);
//TODO 删除场景的定时任务 // 删除场景的定时任务
scheduleExample = new ScheduleExample();
scheduleExample.createCriteria().andProjectIdEqualTo(projectId).andJobEqualTo(ApiScenarioScheduleJob.class.getName());
schedules = scheduleMapper.selectByExample(scheduleExample);
if (CollectionUtils.isNotEmpty(schedules)) {
scheduleService.deleteByResourceIds(schedules.stream().map(Schedule::getResourceId).collect(Collectors.toList()), ApiScenarioScheduleJob.class.getName());
}
} }

View File

@ -4,9 +4,9 @@ import io.metersphere.api.constants.ApiDefinitionDocType;
import io.metersphere.api.constants.ApiResourceType; import io.metersphere.api.constants.ApiResourceType;
import io.metersphere.api.controller.result.ApiResultCode; import io.metersphere.api.controller.result.ApiResultCode;
import io.metersphere.api.domain.*; import io.metersphere.api.domain.*;
import io.metersphere.api.dto.converter.ApiDefinitionImport;
import io.metersphere.api.dto.debug.ApiFileResourceUpdateRequest; import io.metersphere.api.dto.debug.ApiFileResourceUpdateRequest;
import io.metersphere.api.dto.definition.*; import io.metersphere.api.dto.definition.*;
import io.metersphere.api.dto.converter.ApiDefinitionImport;
import io.metersphere.api.dto.request.ImportRequest; import io.metersphere.api.dto.request.ImportRequest;
import io.metersphere.api.mapper.*; import io.metersphere.api.mapper.*;
import io.metersphere.api.parser.ImportParser; import io.metersphere.api.parser.ImportParser;
@ -278,9 +278,9 @@ public class ApiDefinitionService {
// 记录更新前的数据 // 记录更新前的数据
apiDefinitionLogService.batchUpdateLog(ids, userId, request.getProjectId()); apiDefinitionLogService.batchUpdateLog(ids, userId, request.getProjectId());
if (CollectionUtils.isNotEmpty(ids)) { if (CollectionUtils.isNotEmpty(ids)) {
if (request.getType().equals("tags")) { if ("tags".equals(request.getType())) {
handleTags(request, userId, ids); handleTags(request, userId, ids);
} else if (request.getType().equals("customs")) { } else if ("customs".equals(request.getType())) {
// 自定义字段处理 // 自定义字段处理
ApiDefinitionCustomFieldDTO customField = request.getCustomField(); ApiDefinitionCustomFieldDTO customField = request.getCustomField();
List<ApiDefinitionCustomField> list = new ArrayList<>(); List<ApiDefinitionCustomField> list = new ArrayList<>();

View File

@ -41,8 +41,6 @@ public class ApiReportService {
@Resource @Resource
private UserLoginService userLoginService; private UserLoginService userLoginService;
@Resource @Resource
private ApiReportStepMapper apiReportStepMapper;
@Resource
private ApiReportDetailMapper apiReportDetailMapper; private ApiReportDetailMapper apiReportDetailMapper;
@Resource @Resource
private ApiReportLogService apiReportLogService; private ApiReportLogService apiReportLogService;

View File

@ -98,7 +98,7 @@ public class ApiTestCaseService {
if (CollectionUtils.isEmpty(apiDefinitions)) { if (CollectionUtils.isEmpty(apiDefinitions)) {
throw new MSException(Translator.get("api_definition_not_exist")); throw new MSException(Translator.get("api_definition_not_exist"));
} }
return apiDefinitions.get(0); return apiDefinitions.getFirst();
} }
public void checkNameExist(ApiTestCase apiTestCase) { public void checkNameExist(ApiTestCase apiTestCase) {

View File

@ -1077,9 +1077,6 @@ public class ApiScenarioService {
/** /**
* 设置脚本解析-环境相关参数 * 设置脚本解析-环境相关参数
*
* @param refResourceMap
* @return
*/ */
private ApiScenarioParseEnvInfo getScenarioParseEnvInfo(Map<String, List<String>> refResourceMap, String currentEnvId, Boolean isCurrentEnvGrouped) { private ApiScenarioParseEnvInfo getScenarioParseEnvInfo(Map<String, List<String>> refResourceMap, String currentEnvId, Boolean isCurrentEnvGrouped) {
List<String> apiScenarioIds = refResourceMap.get(ApiScenarioStepType.API_SCENARIO.name()); List<String> apiScenarioIds = refResourceMap.get(ApiScenarioStepType.API_SCENARIO.name());
@ -1172,11 +1169,10 @@ public class ApiScenarioService {
ApiScenarioStepCommonDTO step, ApiScenarioStepCommonDTO step,
AbstractMsTestElement msTestElement) { AbstractMsTestElement msTestElement) {
// 引用的场景设置场景参数 // 引用的场景设置场景参数
if (!isScenarioStep(step.getStepType()) || !isRef(step.getRefType()) || !(msTestElement instanceof MsScenario)) { if (!isScenarioStep(step.getStepType()) || !isRef(step.getRefType()) || !(msTestElement instanceof MsScenario msScenario)) {
return; return;
} }
MsScenario msScenario = (MsScenario) msTestElement;
if (step.getConfig() != null) { if (step.getConfig() != null) {
// 设置场景步骤的运行参数 // 设置场景步骤的运行参数
msScenario.setScenarioStepConfig(JSON.parseObject(JSON.toJSONString(step.getConfig()), ScenarioStepConfig.class)); msScenario.setScenarioStepConfig(JSON.parseObject(JSON.toJSONString(step.getConfig()), ScenarioStepConfig.class));
@ -1203,9 +1199,9 @@ public class ApiScenarioService {
/** /**
* scenarioParseEnvInfo 获取对应环境组的 projectEnvMap * scenarioParseEnvInfo 获取对应环境组的 projectEnvMap
* *
* @param scenarioParseEnvInfo * @param scenarioParseEnvInfo 环境信息
* @param environmentId * @param environmentId 环境ID
* @return * @return projectEnvMap
*/ */
private Map<String, EnvironmentInfoDTO> getProjectEnvMap(ApiScenarioParseEnvInfo scenarioParseEnvInfo, String environmentId) { private Map<String, EnvironmentInfoDTO> getProjectEnvMap(ApiScenarioParseEnvInfo scenarioParseEnvInfo, String environmentId) {
Map<String, List<String>> envGroupMap = scenarioParseEnvInfo.getEnvGroupMap(); Map<String, List<String>> envGroupMap = scenarioParseEnvInfo.getEnvGroupMap();
@ -1716,6 +1712,7 @@ public class ApiScenarioService {
fileCopyRequest.setCopyfileName(copyApiFileResource.getFileId()); fileCopyRequest.setCopyfileName(copyApiFileResource.getFileId());
fileCopyRequest.setFileName(copyApiFileResource.getFileId()); fileCopyRequest.setFileName(copyApiFileResource.getFileId());
fileCopyRequest.setFolder(DefaultRepositoryDir.getApiScenarioDir(copyScenario.getProjectId(), copyScenario.getId())); fileCopyRequest.setFolder(DefaultRepositoryDir.getApiScenarioDir(copyScenario.getProjectId(), copyScenario.getId()));
assert minioRepository != null;
minioRepository.copyFile(fileCopyRequest); minioRepository.copyFile(fileCopyRequest);
} catch (Exception ignore) { } catch (Exception ignore) {
} }
@ -1732,7 +1729,7 @@ public class ApiScenarioService {
copyStep.setScenarioId(copyScenario.getId()); copyStep.setScenarioId(copyScenario.getId());
insertApiScenarioStepList.add(copyStep); insertApiScenarioStepList.add(copyStep);
//todo 刚の没提交的CSV关联表 //这块的批量复制不处理csv文件和场景的配置信息
ApiScenarioStepBlob stepBlob = apiScenarioStepBlobMap.get(step.getId()); ApiScenarioStepBlob stepBlob = apiScenarioStepBlobMap.get(step.getId());
if (stepBlob != null) { if (stepBlob != null) {

View File

@ -1,6 +1,8 @@
package io.metersphere.api.controller; package io.metersphere.api.controller;
import io.metersphere.api.domain.*; import io.metersphere.api.domain.*;
import io.metersphere.api.dto.scenario.CsvVariable;
import io.metersphere.api.job.ApiScenarioScheduleJob;
import io.metersphere.api.mapper.*; import io.metersphere.api.mapper.*;
import io.metersphere.api.service.CleanupApiReportServiceImpl; import io.metersphere.api.service.CleanupApiReportServiceImpl;
import io.metersphere.api.service.CleanupApiResourceServiceImpl; import io.metersphere.api.service.CleanupApiResourceServiceImpl;
@ -54,6 +56,12 @@ public class CleanupApiTests {
private ScheduleMapper scheduleMapper; private ScheduleMapper scheduleMapper;
@Resource @Resource
private CleanupApiReportServiceImpl cleanupApiReportServiceImpl; private CleanupApiReportServiceImpl cleanupApiReportServiceImpl;
@Resource
private ApiScenarioMapper apiScenarioMapper;
@Resource
private ApiFileResourceMapper apiFileResourceMapper;
@Resource
private ApiScenarioCsvMapper apiScenarioCsvMapper;
@Autowired @Autowired
public CleanupApiTests(ProjectServiceInvoker serviceInvoker) { public CleanupApiTests(ProjectServiceInvoker serviceInvoker) {
@ -130,7 +138,45 @@ public class CleanupApiTests {
apiDefinitionMock.setName("test"); apiDefinitionMock.setName("test");
apiDefinitionMock.setExpectNum("test"); apiDefinitionMock.setExpectNum("test");
apiDefinitionMockMapper.insertSelective(apiDefinitionMock); apiDefinitionMockMapper.insertSelective(apiDefinitionMock);
//创建场景数据
ApiScenario apiScenario = new ApiScenario();
apiScenario.setId("system-scenario-id");
apiScenario.setProjectId("test");
apiScenario.setName("场景");
apiScenario.setNum(1L);
apiScenario.setCreateTime(System.currentTimeMillis());
apiScenario.setUpdateTime(System.currentTimeMillis());
apiScenario.setCreateUser("admin");
apiScenario.setUpdateUser("admin");
apiScenario.setStatus("未规划");
apiScenario.setDeleted(false);
apiScenario.setPriority("P0");
apiScenario.setStepTotal(0);
apiScenario.setPos(64L);
apiScenario.setModuleId("test-default");
apiScenario.setVersionId("1.0");
apiScenario.setRequestPassRate(String.valueOf(0));
apiScenario.setRefId(apiScenario.getId());
apiScenario.setLatest(true);
apiScenario.setLastReportStatus("未执行");
apiScenarioMapper.insertSelective(apiScenario);
ApiFileResource apiFileResource = new ApiFileResource();
apiFileResource.setResourceId(apiScenario.getId());
apiFileResource.setFileId(IDGenerator.nextStr());
apiFileResource.setFileName("test");
apiFileResource.setResourceType("API_SCENARIO");
apiFileResource.setCreateTime(System.currentTimeMillis());
apiFileResource.setProjectId(apiScenario.getProjectId());
apiFileResourceMapper.insertSelective(apiFileResource);
ApiScenarioCsv apiScenarioCsv = new ApiScenarioCsv();
apiScenarioCsv.setId(IDGenerator.nextStr());
apiScenarioCsv.setScenarioId(apiScenario.getId());
apiScenarioCsv.setFileId("fileMetadataId");
apiScenarioCsv.setName("csv变量");
apiScenarioCsv.setScope(CsvVariable.CsvVariableScope.SCENARIO.name());
apiScenarioCsv.setProjectId("test");
apiScenarioCsvMapper.insertSelective(apiScenarioCsv);
} }
@ -160,6 +206,21 @@ public class CleanupApiTests {
schedule.setCreateTime(System.currentTimeMillis()); schedule.setCreateTime(System.currentTimeMillis());
schedule.setUpdateTime(System.currentTimeMillis()); schedule.setUpdateTime(System.currentTimeMillis());
scheduleMapper.insertSelective(schedule); scheduleMapper.insertSelective(schedule);
schedule = new Schedule();
schedule.setName("test-111");
schedule.setResourceId("test-111");
schedule.setEnable(true);
schedule.setValue("test");
schedule.setKey("test");
schedule.setCreateUser("admin");
schedule.setProjectId("test");
schedule.setConfig("config");
schedule.setJob(ApiScenarioScheduleJob.class.getName());
schedule.setType(ScheduleType.CRON.name());
schedule.setId(IDGenerator.nextStr());
schedule.setCreateTime(System.currentTimeMillis());
schedule.setUpdateTime(System.currentTimeMillis());
scheduleMapper.insertSelective(schedule);
} }
@Test @Test

View File

@ -250,7 +250,6 @@ public class EnvironmentGroupService {
} }
EnvironmentGroupRelationExample example = new EnvironmentGroupRelationExample(); EnvironmentGroupRelationExample example = new EnvironmentGroupRelationExample();
example.createCriteria().andEnvironmentGroupIdIn(envGroupIds); example.createCriteria().andEnvironmentGroupIdIn(envGroupIds);
List<EnvironmentGroupRelation> relations = environmentGroupRelationMapper.selectByExample(example); return environmentGroupRelationMapper.selectByExample(example);
return relations;
} }
} }

View File

@ -447,8 +447,7 @@ public class EnvironmentService {
} }
ProjectExample example = new ProjectExample(); ProjectExample example = new ProjectExample();
example.createCriteria().andIdIn(projectIds); example.createCriteria().andIdIn(projectIds);
List<Project> projects = projectMapper.selectByExample(example); return projectMapper.selectByExample(example);
return projects;
} }
public List<Environment> getEnvironmentsByIds(List<String> envIds) { public List<Environment> getEnvironmentsByIds(List<String> envIds) {

View File

@ -12,7 +12,10 @@ import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.CommonBeanFactory; import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.Translator; import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.*; import io.metersphere.system.domain.TestResourcePool;
import io.metersphere.system.domain.TestResourcePoolExample;
import io.metersphere.system.domain.User;
import io.metersphere.system.domain.UserRoleRelationExample;
import io.metersphere.system.dto.ProjectDTO; import io.metersphere.system.dto.ProjectDTO;
import io.metersphere.system.dto.UpdateProjectRequest; import io.metersphere.system.dto.UpdateProjectRequest;
import io.metersphere.system.dto.sdk.OptionDTO; import io.metersphere.system.dto.sdk.OptionDTO;
@ -34,6 +37,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
@Service @Service
@ -124,7 +128,7 @@ public class ProjectService {
private void checkProjectExistByName(Project project) { private void checkProjectExistByName(Project project) {
ProjectExample example = new ProjectExample(); ProjectExample example = new ProjectExample();
example.createCriteria().andNameEqualTo(project.getName()).andOrganizationIdEqualTo(project.getOrganizationId()).andIdNotEqualTo(project.getId()); example.createCriteria().andNameEqualTo(project.getName()).andOrganizationIdEqualTo(project.getOrganizationId()).andIdNotEqualTo(project.getId());
if (projectMapper.selectByExample(example).size() > 0) { if (projectMapper.countByExample(example) > 0) {
throw new MSException(Translator.get("project_name_already_exists")); throw new MSException(Translator.get("project_name_already_exists"));
} }
} }
@ -147,7 +151,7 @@ public class ProjectService {
public List<OptionDTO> getPoolOptions(String projectId, String type) { public List<OptionDTO> getPoolOptions(String projectId, String type) {
checkProjectNotExist(projectId); checkProjectNotExist(projectId);
List<String> poolIds = getPoolIds(projectId); List<String> poolIds = getPoolIds(projectId);
if(CollectionUtils.isEmpty(poolIds)){ if (CollectionUtils.isEmpty(poolIds)) {
return new ArrayList<>(); return new ArrayList<>();
} }
TestResourcePoolExample example = new TestResourcePoolExample(); TestResourcePoolExample example = new TestResourcePoolExample();
@ -175,7 +179,7 @@ public class ProjectService {
} }
public static Project checkResourceExist(String id) { public static Project checkResourceExist(String id) {
return ServiceUtils.checkResourceExist(CommonBeanFactory.getBean(ProjectMapper.class).selectByPrimaryKey(id), "permission.project.name"); return ServiceUtils.checkResourceExist(Objects.requireNonNull(CommonBeanFactory.getBean(ProjectMapper.class)).selectByPrimaryKey(id), "permission.project.name");
} }
/** /**

View File

@ -102,10 +102,10 @@ public class CommonProjectService {
/** /**
* @param addProjectDTO 添加项目的时候 默认给用户组添加管理员的权限 * @param addProjectDTO 添加项目的时候 默认给用户组添加管理员的权限
* @param createUser * @param createUser 创建人
* @param path 请求路径 * @param path 请求路径
* @param module 日志记录模块 * @param module 日志记录模块
* @return * @return ProjectDTO
*/ */
public ProjectDTO add(AddProjectRequest addProjectDTO, String createUser, String path, String module) { public ProjectDTO add(AddProjectRequest addProjectDTO, String createUser, String path, String module) {
@ -162,7 +162,12 @@ public class CommonProjectService {
/** /**
* 检查添加的人员是否存在组织中 判断传过来的用户id是否在组织下如果不存在给用户创建一个组织成员的身份 * 检查添加的人员是否存在组织中 判断传过来的用户id是否在组织下如果不存在给用户创建一个组织成员的身份
* *
* @param * @param userId 用户id
* orgId 组织id
* createUser 创建人
* nameMap 用户id和用户名的map
* path 请求路径
* module 日志记录模块
*/ */
public void checkOrgRoleExit(List<String> userId, String orgId, String createUser, Map<String, String> nameMap, String path, String module) { public void checkOrgRoleExit(List<String> userId, String orgId, String createUser, Map<String, String> nameMap, String path, String module) {
List<LogDTO> logDTOList = new ArrayList<>(); List<LogDTO> logDTOList = new ArrayList<>();
@ -199,7 +204,7 @@ public class CommonProjectService {
private void checkProjectExistByName(Project project) { private void checkProjectExistByName(Project project) {
ProjectExample example = new ProjectExample(); ProjectExample example = new ProjectExample();
example.createCriteria().andNameEqualTo(project.getName()).andOrganizationIdEqualTo(project.getOrganizationId()).andIdNotEqualTo(project.getId()); example.createCriteria().andNameEqualTo(project.getName()).andOrganizationIdEqualTo(project.getOrganizationId()).andIdNotEqualTo(project.getId());
if (projectMapper.selectByExample(example).size() > 0) { if (projectMapper.countByExample(example) > 0) {
throw new MSException(Translator.get("project_name_already_exists")); throw new MSException(Translator.get("project_name_already_exists"));
} }
} }
@ -207,7 +212,7 @@ public class CommonProjectService {
/** /**
* 检查项目是否存在 * 检查项目是否存在
* *
* @param id * @param id 项目id
*/ */
public void checkProjectNotExist(String id) { public void checkProjectNotExist(String id) {
if (projectMapper.selectByPrimaryKey(id) == null) { if (projectMapper.selectByPrimaryKey(id) == null) {
@ -379,7 +384,7 @@ public class CommonProjectService {
} }
public int delete(String id, String deleteUser) { public int delete(String id, String deleteUser) {
//TODO 删除项目删除全部资源 这里的删除只是假删除 // 删除项目删除全部资源 这里的删除只是假删除
checkProjectNotExist(id); checkProjectNotExist(id);
Project project = new Project(); Project project = new Project();
project.setId(id); project.setId(id);
@ -392,7 +397,7 @@ public class CommonProjectService {
/** /**
* 添加项目管理员 * 添加项目管理员
* *
* @param request * @param request 添加项目管理员请求
* @param createUser 创建人 * @param createUser 创建人
* @param path 请求路径 * @param path 请求路径
* @param type 操作类型 * @param type 操作类型
@ -411,7 +416,7 @@ public class CommonProjectService {
UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample();
userRoleRelationExample.createCriteria().andUserIdEqualTo(userId) userRoleRelationExample.createCriteria().andUserIdEqualTo(userId)
.andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); .andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue());
if (userRoleRelationMapper.selectByExample(userRoleRelationExample).size() == 0) { if (userRoleRelationMapper.selectByExample(userRoleRelationExample).isEmpty()) {
UserRoleRelation adminRole = new UserRoleRelation(); UserRoleRelation adminRole = new UserRoleRelation();
adminRole.setId(IDGenerator.nextStr()); adminRole.setId(IDGenerator.nextStr());
adminRole.setUserId(userId); adminRole.setUserId(userId);
@ -453,7 +458,7 @@ public class CommonProjectService {
/** /**
* 添加项目成员 * 添加项目成员
* *
* @param request * @param request 添加项目成员请求
* @param createUser 创建人 * @param createUser 创建人
* @param path 请求路径 * @param path 请求路径
* @param type 操作类型 * @param type 操作类型
@ -471,7 +476,7 @@ public class CommonProjectService {
UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample();
userRoleRelationExample.createCriteria().andUserIdEqualTo(userId) userRoleRelationExample.createCriteria().andUserIdEqualTo(userId)
.andSourceIdEqualTo(projectId); .andSourceIdEqualTo(projectId);
if (userRoleRelationMapper.selectByExample(userRoleRelationExample).size() == 0) { if (userRoleRelationMapper.selectByExample(userRoleRelationExample).isEmpty()) {
UserRoleRelation memberRole = new UserRoleRelation(); UserRoleRelation memberRole = new UserRoleRelation();
memberRole.setId(IDGenerator.nextStr()); memberRole.setId(IDGenerator.nextStr());
memberRole.setUserId(userId); memberRole.setUserId(userId);
@ -540,7 +545,7 @@ public class CommonProjectService {
/** /**
* 删除项目 一般是定时任务会触发 * 删除项目 一般是定时任务会触发
* *
* @param projects * @param projects 项目集合
*/ */
@Transactional(propagation = Propagation.REQUIRES_NEW) @Transactional(propagation = Propagation.REQUIRES_NEW)
public void deleteProject(List<Project> projects) { public void deleteProject(List<Project> projects) {
@ -566,7 +571,7 @@ public class CommonProjectService {
/** /**
* 删除自定义用户组和权限关系表项目和用户关系数据 * 删除自定义用户组和权限关系表项目和用户关系数据
* *
* @param projectId * @param projectId 项目id
*/ */
private void deleteProjectUserGroup(String projectId) { private void deleteProjectUserGroup(String projectId) {
UserRoleRelationExample userGroupExample = new UserRoleRelationExample(); UserRoleRelationExample userGroupExample = new UserRoleRelationExample();
@ -669,7 +674,7 @@ public class CommonProjectService {
/** /**
* 校验该项目是否有权限使用该资源池 * 校验该项目是否有权限使用该资源池
* *
* @param resourcePool * @param resourcePool 资源池
* @return * @return
*/ */
public boolean validateProjectResourcePool(TestResourcePool resourcePool, String projectId) { public boolean validateProjectResourcePool(TestResourcePool resourcePool, String projectId) {