From 331648759236dbff68382bbe17efb66322f49c9b Mon Sep 17 00:00:00 2001 From: Jianguo-Genius Date: Mon, 4 Nov 2024 17:13:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92):=20?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92=E6=89=B9=E9=87=8F=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plan/controller/TestPlanController.java | 9 ++++ .../TestPlanScheduleBatchConfigRequest.java | 25 ++++++++++ .../plan/service/TestPlanLogService.java | 21 +++++++++ .../plan/service/TestPlanScheduleService.java | 47 +++++++++++++++++++ .../plan/controller/TestPlanTests.java | 21 ++++++++- .../plan/service/TestPlanTestService.java | 5 ++ 6 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanScheduleBatchConfigRequest.java diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java index 3d2fa86476..5dd3fe8a4f 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java @@ -232,6 +232,15 @@ public class TestPlanController { return testPlanScheduleService.scheduleConfig(request, SessionUtils.getUserId()); } + @PostMapping(value = "/batch-schedule-config") + @Operation(summary = "接口测试-接口场景管理-定时任务配置") + @RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE) + @CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project") + public void batchScheduleConfig(@Validated @RequestBody TestPlanScheduleBatchConfigRequest request) { + testPlanManagementService.checkModuleIsOpen(request.getProjectId(), TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN)); + testPlanScheduleService.batchScheduleConfig(request, SessionUtils.getUserId()); + } + @GetMapping(value = "/schedule-config-delete/{testPlanId}") @Operation(summary = "接口测试-接口场景管理-删除定时任务配置") @RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE) diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanScheduleBatchConfigRequest.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanScheduleBatchConfigRequest.java new file mode 100644 index 0000000000..ca6f15629d --- /dev/null +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanScheduleBatchConfigRequest.java @@ -0,0 +1,25 @@ +package io.metersphere.plan.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.Data; + +import java.util.HashMap; +import java.util.Map; + +@Data +public class TestPlanScheduleBatchConfigRequest extends TestPlanBatchProcessRequest { + + @Schema(description = "启用/禁用") + private boolean enable; + + @Schema(description = "Cron表达式") + @NotBlank + @Size(max = 255, message = "{length.too.large}") + private String cron; + + @Schema(description = "运行配置") + private Map runConfig = new HashMap<>(); + +} diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanLogService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanLogService.java index 7d33ab9459..a51e260983 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanLogService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanLogService.java @@ -265,4 +265,25 @@ public class TestPlanLogService { return OperationLogModule.TEST_PLAN_TEST_PLAN_GROUP; } } + + public void batchScheduleLog(String projectId, List testPlanList, String operator) { + Project project = projectMapper.selectByPrimaryKey(projectId); + List list = new ArrayList<>(); + for (TestPlan testPlan : testPlanList) { + LogDTO dto = LogDTOBuilder.builder() + .projectId(project.getId()) + .organizationId(project.getOrganizationId()) + .type(OperationLogType.UPDATE.name()) + .module(getLogModule(testPlan)) + .sourceId(testPlan.getId()) + .method("POST") + .path("/test-plan/batch-schedule-config") + .sourceId(testPlan.getId()) + .content(Translator.get("test_plan_schedule") + ":" + testPlan.getName()) + .createUser(operator) + .build().getLogDTO(); + list.add(dto); + } + operationLogService.batchAdd(list); + } } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanScheduleService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanScheduleService.java index d480dcd88f..b752fea2c4 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanScheduleService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanScheduleService.java @@ -2,6 +2,7 @@ package io.metersphere.plan.service; import io.metersphere.plan.domain.TestPlan; import io.metersphere.plan.domain.TestPlanExample; +import io.metersphere.plan.dto.request.TestPlanScheduleBatchConfigRequest; import io.metersphere.plan.job.TestPlanScheduleJob; import io.metersphere.plan.mapper.TestPlanMapper; import io.metersphere.sdk.constants.ScheduleResourceType; @@ -13,6 +14,7 @@ import io.metersphere.system.dto.request.ScheduleConfig; import io.metersphere.system.dto.request.schedule.BaseScheduleConfigRequest; import io.metersphere.system.schedule.ScheduleService; import jakarta.annotation.Resource; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -27,6 +29,51 @@ public class TestPlanScheduleService { private TestPlanMapper testPlanMapper; @Resource private ScheduleService scheduleService; + @Resource + private TestPlanLogService testPlanLogService; + + public void batchScheduleConfig(TestPlanScheduleBatchConfigRequest request, String operator) { + // 目前计划的批量操作不支持全选所有页 + List ids = request.getSelectIds(); + if (CollectionUtils.isNotEmpty(ids)) { + TestPlanExample example = new TestPlanExample(); + example.createCriteria().andIdIn(ids).andGroupIdIsNotNull(); + List testPlanList = testPlanMapper.selectByExample(example); + for (TestPlan testPlan : testPlanList) { + ScheduleConfig scheduleConfig = ScheduleConfig.builder() + .resourceId(testPlan.getId()) + .key(testPlan.getId()) + .projectId(testPlan.getProjectId()) + .name(testPlan.getName()) + .enable(request.isEnable()) + .cron(request.getCron()) + .resourceType(StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_PLAN) ? ScheduleResourceType.TEST_PLAN.name() : ScheduleResourceType.TEST_PLAN_GROUP.name()) + .config(JSON.toJSONString(request.getRunConfig())) + .build(); + + if (request.isEnable() && StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) { + //配置开启的测试计划组定时任务,要将组下的所有测试计划定时任务都关闭掉 + TestPlanExample childExample = new TestPlanExample(); + childExample.createCriteria().andGroupIdEqualTo(testPlan.getId()).andStatusNotEqualTo(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED); + childExample.setOrderByClause("pos asc"); + List children = testPlanMapper.selectByExample(childExample); + for (TestPlan child : children) { + scheduleService.updateIfExist(child.getId(), false, TestPlanScheduleJob.getJobKey(testPlan.getId()), + TestPlanScheduleJob.getTriggerKey(testPlan.getId()), + TestPlanScheduleJob.class, operator); + } + } + + scheduleService.scheduleConfig( + scheduleConfig, + TestPlanScheduleJob.getJobKey(testPlan.getId()), + TestPlanScheduleJob.getTriggerKey(testPlan.getId()), + TestPlanScheduleJob.class, + operator); + } + testPlanLogService.batchScheduleLog(request.getProjectId(), testPlanList, operator); + } + } public String scheduleConfig(BaseScheduleConfigRequest request, String operator) { TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getResourceId()); diff --git a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanTests.java b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanTests.java index 2d2e2de417..8fda78d460 100644 --- a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanTests.java +++ b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanTests.java @@ -123,6 +123,7 @@ public class TestPlanTests extends BaseTest { private static final String URL_POST_TEST_PLAN_UPDATE = "/test-plan/update"; private static final String URL_POST_TEST_PLAN_BATCH_DELETE = "/test-plan/batch-delete"; private static final String URL_POST_TEST_PLAN_SCHEDULE = "/test-plan/schedule-config"; + private static final String URL_POST_TEST_PLAN_BATCH_SCHEDULE = "/test-plan/batch-schedule-config"; private static final String URL_POST_TEST_PLAN_SCHEDULE_DELETE = "/test-plan/schedule-config-delete/%s"; //测试计划资源-功能用例 @@ -1487,9 +1488,16 @@ public class TestPlanTests extends BaseTest { request.setEnable(true); request.setCron("0 0 0 * * ?"); + TestPlanScheduleBatchConfigRequest batchRequest = new TestPlanScheduleBatchConfigRequest(); + batchRequest.setProjectId(project.getId()); + batchRequest.setEnable(false); + batchRequest.setCron("0 0 0 * * ?"); + batchRequest.setSelectIds(new ArrayList<>(List.of(groupTestPlanId7, groupTestPlanId15))); + //先测试一下没有开启模块时接口能否使用 testPlanTestService.removeProjectModule(project, PROJECT_MODULE, "testPlan"); this.requestPost(URL_POST_TEST_PLAN_SCHEDULE, request).andExpect(status().is5xxServerError()); + this.requestPost(URL_POST_TEST_PLAN_BATCH_SCHEDULE, batchRequest).andExpect(status().is5xxServerError()); this.requestGet(String.format(URL_POST_TEST_PLAN_SCHEDULE_DELETE, groupTestPlanId7)).andExpect(status().is5xxServerError()); //恢复 testPlanTestService.resetProjectModule(project, PROJECT_MODULE); @@ -1508,12 +1516,21 @@ public class TestPlanTests extends BaseTest { TestPlanStatisticsResponse.class); Assertions.assertTrue(statisticsResponses.size() > 1); - //增加日志检查 LOG_CHECK_LIST.add( new CheckLogModel(groupTestPlanId7, OperationLogType.UPDATE, null) ); - + this.requestPostWithOk(URL_POST_TEST_PLAN_BATCH_SCHEDULE, batchRequest); + testPlanTestService.checkSchedule(groupTestPlanId7, batchRequest.isEnable()); + testPlanTestService.checkSchedule(groupTestPlanId15, batchRequest.isEnable()); + batchRequest.setEnable(true); + this.requestPostWithOk(URL_POST_TEST_PLAN_BATCH_SCHEDULE, batchRequest); + testPlanTestService.checkSchedule(groupTestPlanId7, batchRequest.isEnable()); + testPlanTestService.checkSchedule(groupTestPlanId15, batchRequest.isEnable()); + //增加日志检查 + LOG_CHECK_LIST.add( + new CheckLogModel(groupTestPlanId15, OperationLogType.UPDATE, null) + ); //关闭 request.setEnable(false); result = this.requestPostAndReturn(URL_POST_TEST_PLAN_SCHEDULE, request); diff --git a/backend/services/test-plan/src/test/java/io/metersphere/plan/service/TestPlanTestService.java b/backend/services/test-plan/src/test/java/io/metersphere/plan/service/TestPlanTestService.java index 2f01108e2f..4af56fd35a 100644 --- a/backend/services/test-plan/src/test/java/io/metersphere/plan/service/TestPlanTestService.java +++ b/backend/services/test-plan/src/test/java/io/metersphere/plan/service/TestPlanTestService.java @@ -471,6 +471,11 @@ public class TestPlanTestService { Assertions.assertEquals(scheduler.checkExists(TestPlanScheduleJob.getJobKey(resourceId)), isEnable); } + public void checkSchedule(String resourceId, boolean isEnable) throws Exception { + Assertions.assertEquals(extScheduleMapper.countByResourceId(resourceId), 1L); + Assertions.assertEquals(scheduler.checkExists(TestPlanScheduleJob.getJobKey(resourceId)), isEnable); + } + public void checkScheduleIsRemove(String resourceId) throws SchedulerException { Assertions.assertEquals(extScheduleMapper.countByResourceId(resourceId), 0L); Assertions.assertEquals(scheduler.checkExists(TestPlanScheduleJob.getJobKey(resourceId)), false);