diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiCaseRerunService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiCaseRerunService.java new file mode 100644 index 0000000000..78c33d9ed1 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiCaseRerunService.java @@ -0,0 +1,26 @@ +package io.metersphere.api.service; + +import io.metersphere.sdk.constants.ExecTaskType; +import io.metersphere.system.domain.ExecTask; +import io.metersphere.system.invoker.TaskRerunServiceInvoker; +import io.metersphere.system.service.TaskRerunService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * @Author: jianxing + * @CreateTime: 2024-02-06 20:47 + */ +@Service +@Transactional(rollbackFor = Exception.class) +public class ApiCaseRerunService implements TaskRerunService { + + public ApiCaseRerunService() { + TaskRerunServiceInvoker.register(ExecTaskType.API_CASE, this); + } + + @Override + public void rerun(ExecTask execTask) { + // todo + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiScenarioRerunService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiScenarioRerunService.java new file mode 100644 index 0000000000..53d12bb50f --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiScenarioRerunService.java @@ -0,0 +1,26 @@ +package io.metersphere.api.service; + +import io.metersphere.sdk.constants.ExecTaskType; +import io.metersphere.system.domain.ExecTask; +import io.metersphere.system.invoker.TaskRerunServiceInvoker; +import io.metersphere.system.service.TaskRerunService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * @Author: jianxing + * @CreateTime: 2024-02-06 20:47 + */ +@Service +@Transactional(rollbackFor = Exception.class) +public class ApiScenarioRerunService implements TaskRerunService { + + public ApiScenarioRerunService() { + TaskRerunServiceInvoker.register(ExecTaskType.API_SCENARIO, this); + } + + @Override + public void rerun(ExecTask execTask) { + // todo + } +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/controller/ProjectTaskHubController.java b/backend/services/project-management/src/main/java/io/metersphere/project/controller/ProjectTaskHubController.java index bdbc7033d6..7f9e44c2ba 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/controller/ProjectTaskHubController.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/controller/ProjectTaskHubController.java @@ -97,6 +97,13 @@ public class ProjectTaskHubController { baseTaskHubService.stopTask(id, SessionUtils.getUserId(), null, SessionUtils.getCurrentProjectId()); } + @GetMapping("/exec-task/rerun/{id}") + @Operation(summary = "项目-任务中心-用例执行任务-重跑任务") + @Log(type = OperationLogType.RERUN, expression = "#msClass.projectRerunLog(#id)", msClass = BaseTaskHubLogService.class) + @RequiresPermissions(PermissionConstants.PROJECT_CASE_TASK_CENTER_EXEC_STOP) + public void rerunTask(@PathVariable String id) { + baseTaskHubService.rerunTask(id, SessionUtils.getUserId(), null, SessionUtils.getCurrentProjectId()); + } @PostMapping("/exec-task/batch-stop") @Operation(summary = "项目-任务中心-用例执行任务-批量停止任务") diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectTaskHubControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectTaskHubControllerTests.java index 7285cc0b87..9addb5ab90 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectTaskHubControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectTaskHubControllerTests.java @@ -1,6 +1,7 @@ package io.metersphere.project.controller; import io.metersphere.sdk.constants.ExecTaskType; +import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.util.JSON; import io.metersphere.system.base.BaseTest; import io.metersphere.system.controller.handler.ResultHolder; @@ -12,6 +13,7 @@ import io.metersphere.system.dto.table.TableBatchProcessDTO; import io.metersphere.system.dto.taskhub.request.ScheduleRequest; import io.metersphere.system.dto.taskhub.request.TaskHubItemBatchRequest; import io.metersphere.system.dto.taskhub.request.TaskHubItemRequest; +import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.mapper.ExecTaskItemMapper; import jakarta.annotation.Resource; import org.junit.jupiter.api.Assertions; @@ -44,6 +46,7 @@ public class ProjectTaskHubControllerTests extends BaseTest { public static final String PROJECT_STATISTICS = "/project/task-center/exec-task/statistics"; public static final String PROJECT_RESOURCE_POOL_OPTIONS = "/project/task-center/resource-pool/options"; public static final String PROJECT_TASK_STOP = "/project/task-center/exec-task/stop/"; + public static final String PROJECT_TASK_RERUN = "/project/task-center/exec-task/rerun/{0}"; public static final String PROJECT_TASK_DELETE = "/project/task-center/exec-task/delete/"; public static final String PROJECT_TASK_BATCH_STOP = "/project/task-center/exec-task/batch-stop"; public static final String PROJECT_TASK_ITEM_ORDER = "/project/task-center/exec-task/item/order"; @@ -151,6 +154,20 @@ public class ProjectTaskHubControllerTests extends BaseTest { this.requestGet(PROJECT_TASK_STOP + "pro_2"); } + /** + * 项目执行任务停止 + */ + @Test + @Order(6) + public void projectTaskRerun() throws Exception { + String taskId = "pro_1"; + this.requestGet(PROJECT_TASK_RERUN, taskId); + // @@校验权限 + requestGetPermissionTest(PermissionConstants.PROJECT_CASE_TASK_CENTER_EXEC_STOP, PROJECT_TASK_RERUN, taskId); + // @@校验日志 + checkLog(taskId, OperationLogType.RERUN); + } + /** * 系统执行任务停止 */ diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/OrganizationTaskHubController.java b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/OrganizationTaskHubController.java index 6f62393362..1725278ad6 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/OrganizationTaskHubController.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/OrganizationTaskHubController.java @@ -107,6 +107,15 @@ public class OrganizationTaskHubController { } + @GetMapping("/exec-task/rerun/{id}") + @Operation(summary = "组织-任务中心-用例执行任务-重跑任务") + @Log(type = OperationLogType.RERUN, expression = "#msClass.orgRerunLog(#id)", msClass = BaseTaskHubLogService.class) + @RequiresPermissions(PermissionConstants.ORGANIZATION_CASE_TASK_CENTER_EXEC_STOP) + public void rerunTask(@PathVariable String id) { + baseTaskHubService.rerunTask(id, SessionUtils.getUserId(), SessionUtils.getCurrentOrganizationId(), null); + } + + @PostMapping("/exec-task/batch-stop") @Operation(summary = "组织-任务中心-用例执行任务-批量停止任务") @RequiresPermissions(PermissionConstants.ORGANIZATION_CASE_TASK_CENTER_EXEC_STOP) diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/SystemTaskHubController.java b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/SystemTaskHubController.java index 3d05382291..51a749cd1b 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/SystemTaskHubController.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/SystemTaskHubController.java @@ -108,6 +108,13 @@ public class SystemTaskHubController { baseTaskHubService.stopTask(id, SessionUtils.getUserId(), null, null); } + @GetMapping("/exec-task/rerun/{id}") + @Operation(summary = "系统-任务中心-用例执行任务-重跑任务") + @Log(type = OperationLogType.RERUN, expression = "#msClass.systemRerunLog(#id)", msClass = BaseTaskHubLogService.class) + @RequiresPermissions(PermissionConstants.SYSTEM_CASE_TASK_CENTER_EXEC_STOP) + public void rerunTask(@PathVariable String id) { + baseTaskHubService.rerunTask(id, SessionUtils.getUserId(), null, null); + } @PostMapping("/exec-task/batch-stop") @Operation(summary = "系统-任务中心-用例执行任务-批量停止任务") diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/invoker/TaskRerunServiceInvoker.java b/backend/services/system-setting/src/main/java/io/metersphere/system/invoker/TaskRerunServiceInvoker.java new file mode 100644 index 0000000000..5c51732472 --- /dev/null +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/invoker/TaskRerunServiceInvoker.java @@ -0,0 +1,37 @@ +package io.metersphere.system.invoker; + +import io.metersphere.sdk.constants.ExecTaskType; +import io.metersphere.sdk.util.EnumValidator; +import io.metersphere.system.domain.ExecTask; +import io.metersphere.system.service.TaskRerunService; + +import java.util.HashMap; +import java.util.Map; + +/** + * @Author: jianxing + * @CreateTime: 2024-02-06 20:48 + */ +public class TaskRerunServiceInvoker { + + private static final Map taskRerunServiceMap = new HashMap<>(); + + public static void register(ExecTaskType execTaskType, TaskRerunService taskRerunService) { + taskRerunServiceMap.put(execTaskType, taskRerunService); + } + + private static TaskRerunService getTaskRerunService(ExecTaskType execTaskType) { + return taskRerunServiceMap.get(execTaskType); + } + + public static ExecTaskType getExecTaskType(String execTaskType) { + return EnumValidator.validateEnum(ExecTaskType.class, execTaskType); + } + + public static void rerun(ExecTask execTask) { + TaskRerunService taskRerunService = getTaskRerunService(getExecTaskType(execTask.getTaskType())); + if (taskRerunService != null) { + taskRerunService.rerun(execTask); + } + } +} diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/log/aspect/OperationLogAspect.java b/backend/services/system-setting/src/main/java/io/metersphere/system/log/aspect/OperationLogAspect.java index 9c2cc61e20..0c369c9c8c 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/log/aspect/OperationLogAspect.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/log/aspect/OperationLogAspect.java @@ -67,7 +67,7 @@ public class OperationLogAspect { private final OperationLogType[] beforeMethodNames = new OperationLogType[]{OperationLogType.UPDATE, OperationLogType.DELETE, OperationLogType.COPY , OperationLogType.RECOVER, OperationLogType.DISASSOCIATE,OperationLogType.ASSOCIATE, OperationLogType.ARCHIVED}; // 需要后置执行合并内容的 - private final OperationLogType[] postMethodNames = new OperationLogType[]{OperationLogType.ADD, OperationLogType.UPDATE}; + private final OperationLogType[] postMethodNames = new OperationLogType[]{OperationLogType.ADD, OperationLogType.UPDATE, OperationLogType.RERUN}; /** * 定义切点 @Pointcut 在注解的位置切入代码 diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/log/constants/OperationLogType.java b/backend/services/system-setting/src/main/java/io/metersphere/system/log/constants/OperationLogType.java index 1fc01db6e9..a9b8ca6b1e 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/log/constants/OperationLogType.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/log/constants/OperationLogType.java @@ -20,7 +20,8 @@ public enum OperationLogType { ASSOCIATE, QRCODE, ARCHIVED, - STOP; + STOP, + RERUN; public boolean contains(OperationLogType keyword) { return this.name().contains(keyword.name()); diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubLogService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubLogService.java index 6cb3e5a2c4..e5a86c6e53 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubLogService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubLogService.java @@ -79,7 +79,6 @@ public class BaseTaskHubLogService { return dto; } - /** * 项目停止任务日志 * @@ -102,6 +101,71 @@ public class BaseTaskHubLogService { return dto; } + /** + * 系统重跑任务日志 + * + * @param id + * @return + */ + public LogDTO systemRerunLog(String id) { + ExecTask execTask = execTaskMapper.selectByPrimaryKey(id); + LogDTO dto = null; + if (execTask != null) { + dto = new LogDTO( + OperationLogConstants.SYSTEM, + OperationLogConstants.SYSTEM, + execTask.getId(), + null, + OperationLogType.RERUN.name(), + OperationLogModule.SETTING_SYSTEM_TASK_CENTER, + execTask.getTaskName()); + } + return dto; + } + + /** + * 组织重跑任务日志 + * + * @param id + * @return + */ + public LogDTO orgRerunLog(String id) { + ExecTask execTask = execTaskMapper.selectByPrimaryKey(id); + LogDTO dto = null; + if (execTask != null) { + dto = new LogDTO( + OperationLogConstants.ORGANIZATION, + null, + execTask.getId(), + null, + OperationLogType.RERUN.name(), + OperationLogModule.SETTING_ORGANIZATION_TASK_CENTER, + execTask.getTaskName()); + } + return dto; + } + + /** + * 项目重跑任务日志 + * + * @param id + * @return + */ + public LogDTO projectRerunLog(String id) { + ExecTask execTask = execTaskMapper.selectByPrimaryKey(id); + LogDTO dto = null; + if (execTask != null) { + dto = new LogDTO( + null, + null, + execTask.getId(), + null, + OperationLogType.RERUN.name(), + OperationLogModule.PROJECT_MANAGEMENT_TASK_CENTER, + execTask.getTaskName()); + } + return dto; + } /** * 系统删除任务日志 diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubService.java index a61cf4f601..00621af461 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubService.java @@ -10,7 +10,6 @@ import io.metersphere.engine.MsHttpClient; import io.metersphere.project.domain.Project; import io.metersphere.project.domain.ProjectExample; import io.metersphere.project.mapper.ProjectMapper; -import io.metersphere.project.mapper.ProjectTestResourcePoolMapper; import io.metersphere.sdk.constants.*; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.*; @@ -32,6 +31,7 @@ import io.metersphere.system.dto.taskhub.request.ScheduleRequest; import io.metersphere.system.dto.taskhub.request.TaskHubItemBatchRequest; import io.metersphere.system.dto.taskhub.request.TaskHubItemRequest; import io.metersphere.system.dto.taskhub.response.TaskStatisticsResponse; +import io.metersphere.system.invoker.TaskRerunServiceInvoker; import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.log.dto.LogDTO; import io.metersphere.system.log.service.OperationLogService; @@ -92,8 +92,6 @@ public class BaseTaskHubService { @Resource private ExtResourcePoolMapper extResourcePoolMapper; @Resource - private ProjectTestResourcePoolMapper projectTestResourcePoolMapper; - @Resource private NodeResourcePoolService nodeResourcePoolService; @Resource private ExecTaskMapper execTaskMapper; @@ -561,6 +559,21 @@ public class BaseTaskHubService { handleStopTaskAsync(List.of(id)); } + public void rerunTask(String id, String userId, String orgId, String projectId) { + ExecTask execTask = execTaskMapper.selectByPrimaryKey(id); + if (projectId != null && !StringUtils.equals(projectId, execTask.getProjectId())) { + throw new MSException(Translator.get("no_permission_to_resource")); + } + if (orgId != null && !StringUtils.equals(orgId, execTask.getOrganizationId())) { + throw new MSException(Translator.get("no_permission_to_resource")); + } + + // 更新任务状态 + extExecTaskMapper.batchUpdateTaskStatus(List.of(id), userId, orgId, projectId, ExecStatus.RERUNNING.name()); + + TaskRerunServiceInvoker.rerun(execTask); + } + private void handleStopTaskAsync(List ids) { Thread.startVirtualThread(() -> handleStopTask(ids)); } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/TaskRerunService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/TaskRerunService.java new file mode 100644 index 0000000000..7d7060f13d --- /dev/null +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/TaskRerunService.java @@ -0,0 +1,14 @@ +package io.metersphere.system.service; + +import io.metersphere.system.domain.ExecTask; + +/** + * @Author: jianxing + * @CreateTime: 2024-02-06 20:47 + */ +public interface TaskRerunService { + /** + * 任务重跑 + */ + void rerun(ExecTask execTask); +} diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/BaseTaskHubControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/BaseTaskHubControllerTests.java index c0726cb318..3c9d846d33 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/BaseTaskHubControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/BaseTaskHubControllerTests.java @@ -1,6 +1,7 @@ package io.metersphere.system.controller; import io.metersphere.sdk.constants.ExecTaskType; +import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.util.JSON; import io.metersphere.system.base.BaseTest; import io.metersphere.system.controller.handler.ResultHolder; @@ -13,6 +14,7 @@ import io.metersphere.system.dto.table.TableBatchProcessDTO; import io.metersphere.system.dto.taskhub.request.ScheduleRequest; import io.metersphere.system.dto.taskhub.request.TaskHubItemBatchRequest; import io.metersphere.system.dto.taskhub.request.TaskHubItemRequest; +import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.mapper.ExecTaskItemMapper; import io.metersphere.system.mapper.TestResourcePoolMapper; import io.metersphere.system.service.BaseTaskHubService; @@ -56,6 +58,7 @@ public class BaseTaskHubControllerTests extends BaseTest { public static final String SYSTEM_RESOURCE_POOL_OPTIONS = "/system/task-center/resource-pool/options"; public static final String SYSTEM_RESOURCE_POOL_STATUS = "/system/task-center/resource-pool/status"; public static final String SYSTEM_TASK_STOP = "/system/task-center/exec-task/stop/"; + public static final String SYSTEM_TASK_RERUN = "/system/task-center/exec-task/rerun/{0}"; public static final String SYSTEM_TASK_DELETE = "/system/task-center/exec-task/delete/"; public static final String SYSTEM_TASK_BATCH_STOP = "/system/task-center/exec-task/batch-stop"; public static final String SYSTEM_TASK_BATCH_DELETE = "/system/task-center/exec-task/batch-delete"; @@ -212,6 +215,18 @@ public class BaseTaskHubControllerTests extends BaseTest { this.requestGet(SYSTEM_TASK_STOP + "2"); } + @Test + @Order(4) + public void systemTaskRerun() throws Exception { + String taskId = "1"; + this.requestGet(SYSTEM_TASK_RERUN, taskId); + // @@校验权限 + requestGetPermissionTest(PermissionConstants.SYSTEM_CASE_TASK_CENTER_EXEC_STOP, SYSTEM_TASK_RERUN, taskId); + // @@校验日志 + checkLog(taskId, OperationLogType.RERUN); + } + + /** * 系统任务项停止 */ @@ -349,6 +364,7 @@ public class BaseTaskHubControllerTests extends BaseTest { public static final String ORG_STATISTICS = "/organization/task-center/exec-task/statistics"; public static final String ORG_RESOURCE_POOL_OPTIONS = "/organization/task-center/resource-pool/options"; public static final String ORG_TASK_STOP = "/organization/task-center/exec-task/stop/"; + public static final String ORG_TASK_RERUN = "/organization/task-center/exec-task/rerun/{0}"; public static final String ORG_TASK_DELETE = "/organization/task-center/exec-task/delete/"; public static final String ORG_TASK_BATCH_STOP = "/organization/task-center/exec-task/batch-stop"; public static final String ORG_TASK_BATCH_DELETE = "/organization/task-center/exec-task/batch-delete"; @@ -489,6 +505,17 @@ public class BaseTaskHubControllerTests extends BaseTest { testResourcePoolMapper.deleteByPrimaryKey("2"); } + @Test + @Order(24) + public void orgTaskRerun() throws Exception { + String taskId = "1"; + this.requestGet(ORG_TASK_RERUN, taskId); + // @@校验权限 + requestGetPermissionTest(PermissionConstants.ORGANIZATION_CASE_TASK_CENTER_EXEC_STOP, ORG_TASK_RERUN, taskId); + // @@校验日志 + checkLog(taskId, OperationLogType.RERUN); + } + /** * 组织执行任务项停止 */ diff --git a/frontend/src/views/setting/system/log/components/logCards.vue b/frontend/src/views/setting/system/log/components/logCards.vue index 81425a06e4..9703276386 100644 --- a/frontend/src/views/setting/system/log/components/logCards.vue +++ b/frontend/src/views/setting/system/log/components/logCards.vue @@ -468,6 +468,10 @@ label: 'system.log.operateType.stop', value: 'STOP', }, + { + label: 'system.log.operateType.rerun', + value: 'RERUN', + }, ]; function resetFilter() { diff --git a/frontend/src/views/setting/system/log/locale/en-US.ts b/frontend/src/views/setting/system/log/locale/en-US.ts index 73cc72ccbf..1d5aa4932c 100644 --- a/frontend/src/views/setting/system/log/locale/en-US.ts +++ b/frontend/src/views/setting/system/log/locale/en-US.ts @@ -36,4 +36,5 @@ export default { 'system.log.time': 'Operation time', 'system.log.content': 'in {module} under {range}', 'system.log.operateType.stop': 'Stop', + 'system.log.operateType.rerun': 'Rerun', }; diff --git a/frontend/src/views/setting/system/log/locale/zh-CN.ts b/frontend/src/views/setting/system/log/locale/zh-CN.ts index d0fe0c353f..28433f5caf 100644 --- a/frontend/src/views/setting/system/log/locale/zh-CN.ts +++ b/frontend/src/views/setting/system/log/locale/zh-CN.ts @@ -36,4 +36,5 @@ export default { 'system.log.time': '操作时间', 'system.log.content': '{operator} 在 {range} 下的 {module} 中 ', 'system.log.operateType.stop': '停止', + 'system.log.operateType.rerun': '重跑', };