diff --git a/backend/src/main/java/io/metersphere/api/service/APITestService.java b/backend/src/main/java/io/metersphere/api/service/APITestService.java index c21fb15332..91227bb4b0 100644 --- a/backend/src/main/java/io/metersphere/api/service/APITestService.java +++ b/backend/src/main/java/io/metersphere/api/service/APITestService.java @@ -20,6 +20,7 @@ import io.metersphere.commons.utils.SessionUtils; import io.metersphere.i18n.Translator; import io.metersphere.job.QuartzManager; import io.metersphere.job.sechedule.ApiTestJob; +import io.metersphere.job.sechedule.PerformanceTestJob; import io.metersphere.service.FileService; import io.metersphere.service.ScheduleService; import org.apache.commons.lang3.StringUtils; @@ -40,6 +41,8 @@ import java.util.List; import java.util.Objects; import java.util.Random; import java.util.UUID; +import java.util.function.Consumer; +import java.util.function.Function; import java.util.stream.Collectors; @Service @@ -231,44 +234,23 @@ public class APITestService { public void updateSchedule(Schedule request) { scheduleService.editSchedule(request); - updateApiTestCronJob(request); + addOrUpdateApiTestCronJob(request); } public void createSchedule(Schedule request) { scheduleService.addSchedule(buildApiTestSchedule(request)); - updateApiTestCronJob(request); + addOrUpdateApiTestCronJob(request); } private Schedule buildApiTestSchedule(Schedule request) { - Schedule schedule = new Schedule(); - schedule.setResourceId(request.getResourceId()); - schedule.setEnable(request.getEnable()); + Schedule schedule = scheduleService.buildApiTestSchedule(request); schedule.setJob(ApiTestJob.class.getName()); - schedule.setValue(request.getValue().trim()); schedule.setGroup(ScheduleGroup.API_TEST.name()); - schedule.setKey(request.getResourceId()); schedule.setType(ScheduleType.CRON.name()); - schedule.setUserId(SessionUtils.getUser().getId()); return schedule; } - private void updateApiTestCronJob(Schedule request) { - Boolean enable = request.getEnable(); - String cronExpression = request.getValue(); - if (enable != null && enable && StringUtils.isNotBlank(cronExpression)) { - try { - QuartzManager.addOrUpdateCronJob(ApiTestJob.getJobKey(request.getResourceId()), - ApiTestJob.getTriggerKey(request.getResourceId()), ApiTestJob.class, cronExpression, QuartzManager.getDefaultJobDataMap(request.getResourceId(), cronExpression, SessionUtils.getUser().getId())); - } catch (SchedulerException e) { - LogUtil.error(e.getMessage(), e); - MSException.throwException("定时任务开启异常"); - } - } else { - try { - QuartzManager.removeJob(ApiTestJob.getJobKey(request.getResourceId()), ApiTestJob.getTriggerKey(request.getResourceId())); - } catch (Exception e) { - MSException.throwException("定时任务关闭异常"); - } - } + private void addOrUpdateApiTestCronJob(Schedule request) { + scheduleService.addOrUpdateCronJob(request, ApiTestJob.getJobKey(request.getResourceId()), ApiTestJob.getTriggerKey(request.getResourceId()), ApiTestJob.class); } } diff --git a/backend/src/main/java/io/metersphere/dto/LoadTestDTO.java b/backend/src/main/java/io/metersphere/dto/LoadTestDTO.java index 7ec60e2f4c..29b72132ba 100644 --- a/backend/src/main/java/io/metersphere/dto/LoadTestDTO.java +++ b/backend/src/main/java/io/metersphere/dto/LoadTestDTO.java @@ -1,6 +1,7 @@ package io.metersphere.dto; import io.metersphere.base.domain.LoadTest; +import io.metersphere.base.domain.Schedule; import lombok.Getter; import lombok.Setter; @@ -9,4 +10,5 @@ import lombok.Setter; public class LoadTestDTO extends LoadTest { private String projectName; private String userName; + private Schedule schedule; } diff --git a/backend/src/main/java/io/metersphere/job/sechedule/ApiTestJob.java b/backend/src/main/java/io/metersphere/job/sechedule/ApiTestJob.java index d502fec273..44643d93f9 100644 --- a/backend/src/main/java/io/metersphere/job/sechedule/ApiTestJob.java +++ b/backend/src/main/java/io/metersphere/job/sechedule/ApiTestJob.java @@ -20,7 +20,7 @@ public class ApiTestJob extends MsScheduleJob { @Override public void execute(JobExecutionContext context) throws JobExecutionException { if (StringUtils.isBlank(resourceId)) { - QuartzManager.removeJob(new JobKey(resourceId), new TriggerKey(resourceId)); + QuartzManager.removeJob(getJobKey(resourceId), getTriggerKey(resourceId)); } LogUtil.info("ApiTestSchedule Running: " + resourceId); LogUtil.info("CronExpression: " + expression); diff --git a/backend/src/main/java/io/metersphere/job/sechedule/PerformanceTestJob.java b/backend/src/main/java/io/metersphere/job/sechedule/PerformanceTestJob.java index 190c91dc12..bca394e8fa 100644 --- a/backend/src/main/java/io/metersphere/job/sechedule/PerformanceTestJob.java +++ b/backend/src/main/java/io/metersphere/job/sechedule/PerformanceTestJob.java @@ -1,12 +1,45 @@ package io.metersphere.job.sechedule; +import io.metersphere.commons.constants.ScheduleGroup; +import io.metersphere.commons.utils.CommonBeanFactory; +import io.metersphere.commons.utils.LogUtil; +import io.metersphere.job.QuartzManager; +import io.metersphere.performance.service.PerformanceTestService; +import io.metersphere.track.request.testplan.RunTestPlanRequest; +import org.apache.commons.lang3.StringUtils; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; +import org.quartz.JobKey; +import org.quartz.TriggerKey; public class PerformanceTestJob extends MsScheduleJob { + private PerformanceTestService performanceTestService; + + public PerformanceTestJob() { + this.performanceTestService = CommonBeanFactory.getBean(PerformanceTestService.class); + } + @Override public void execute(JobExecutionContext context) throws JobExecutionException { + if (StringUtils.isBlank(resourceId)) { + QuartzManager.removeJob(getJobKey(resourceId), getTriggerKey(resourceId)); + } + LogUtil.info("PerformanceTestSchedule Running: " + resourceId); + LogUtil.info("CronExpression: " + expression); + RunTestPlanRequest request = new RunTestPlanRequest(); + request.setId(resourceId); + request.setUserId(userId); + performanceTestService.run(request); } + + public static JobKey getJobKey(String testId) { + return new JobKey(testId, ScheduleGroup.PERFORMANCE_TEST.name()); + } + + public static TriggerKey getTriggerKey(String testId) { + return new TriggerKey(testId, ScheduleGroup.PERFORMANCE_TEST.name()); + } + } diff --git a/backend/src/main/java/io/metersphere/listeners/AppStartListener.java b/backend/src/main/java/io/metersphere/listener/AppStartListener.java similarity index 95% rename from backend/src/main/java/io/metersphere/listeners/AppStartListener.java rename to backend/src/main/java/io/metersphere/listener/AppStartListener.java index e87246831a..72207aaa76 100644 --- a/backend/src/main/java/io/metersphere/listeners/AppStartListener.java +++ b/backend/src/main/java/io/metersphere/listener/AppStartListener.java @@ -1,4 +1,4 @@ -package io.metersphere.listeners; +package io.metersphere.listener; import io.metersphere.service.ScheduleService; import org.springframework.boot.context.event.ApplicationReadyEvent; diff --git a/backend/src/main/java/io/metersphere/performance/controller/PerformanceTestController.java b/backend/src/main/java/io/metersphere/performance/controller/PerformanceTestController.java index a2ff77e732..78e77a9e6e 100644 --- a/backend/src/main/java/io/metersphere/performance/controller/PerformanceTestController.java +++ b/backend/src/main/java/io/metersphere/performance/controller/PerformanceTestController.java @@ -4,6 +4,7 @@ import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import io.metersphere.base.domain.FileMetadata; import io.metersphere.base.domain.LoadTest; +import io.metersphere.base.domain.Schedule; import io.metersphere.commons.constants.RoleConstants; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; @@ -117,4 +118,15 @@ public class PerformanceTestController { public void copy(@RequestBody SaveTestPlanRequest request) { performanceTestService.copy(request); } + + @PostMapping(value = "/schedule/create") + public void createSchedule(@RequestBody Schedule request) { + performanceTestService.createSchedule(request); + } + + @PostMapping(value = "/schedule/update") + public void updateSchedule(@RequestBody Schedule request) { + performanceTestService.updateSchedule(request); + } + } diff --git a/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java b/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java index 87da37f9f6..e89f46dfa5 100644 --- a/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java +++ b/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java @@ -7,6 +7,8 @@ import io.metersphere.base.mapper.ext.ExtLoadTestReportDetailMapper; import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper; import io.metersphere.commons.constants.APITestStatus; import io.metersphere.commons.constants.PerformanceTestStatus; +import io.metersphere.commons.constants.ScheduleGroup; +import io.metersphere.commons.constants.ScheduleType; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.ServiceUtils; @@ -16,9 +18,11 @@ import io.metersphere.controller.request.OrderRequest; import io.metersphere.dto.DashboardTestDTO; import io.metersphere.dto.LoadTestDTO; import io.metersphere.i18n.Translator; +import io.metersphere.job.sechedule.PerformanceTestJob; import io.metersphere.performance.engine.Engine; import io.metersphere.performance.engine.EngineFactory; import io.metersphere.service.FileService; +import io.metersphere.service.ScheduleService; import io.metersphere.service.TestResourceService; import io.metersphere.track.request.testplan.*; import org.apache.commons.collections4.ListUtils; @@ -68,6 +72,8 @@ public class PerformanceTestService { private ReportService reportService; @Resource private KafkaProperties kafkaProperties; + @Resource + private ScheduleService scheduleService; public List list(QueryTestPlanRequest request) { request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); @@ -196,6 +202,9 @@ public class PerformanceTestService { @Transactional(noRollbackFor = MSException.class)// 保存失败的信息 public String run(RunTestPlanRequest request) { final LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(request.getId()); + if (request.getUserId() != null) { + loadTest.setUserId(request.getUserId()); + } if (loadTest == null) { MSException.throwException(Translator.get("run_load_test_not_found") + request.getId()); } @@ -252,7 +261,7 @@ public class PerformanceTestService { testReport.setUpdateTime(engine.getStartTime()); testReport.setTestId(loadTest.getId()); testReport.setName(loadTest.getName()); - testReport.setUserId(SessionUtils.getUser().getId()); + testReport.setUserId(Optional.ofNullable(SessionUtils.getUser().getId()).orElse(loadTest.getUserId())); // 启动测试 try { @@ -296,7 +305,10 @@ public class PerformanceTestService { request.setId(testId); List testDTOS = extLoadTestMapper.list(request); if (!CollectionUtils.isEmpty(testDTOS)) { - return testDTOS.get(0); + LoadTestDTO loadTestDTO = testDTOS.get(0); + Schedule schedule = scheduleService.getScheduleByResource(loadTestDTO.getId(), ScheduleGroup.PERFORMANCE_TEST.name()); + loadTestDTO.setSchedule(schedule); + return loadTestDTO; } return null; } @@ -350,4 +362,26 @@ public class PerformanceTestService { }); } } + + public void updateSchedule(Schedule request) { + scheduleService.editSchedule(request); + addOrUpdatePerformanceTestCronJob(request); + } + + public void createSchedule(Schedule request) { + scheduleService.addSchedule(buildPerformanceTestSchedule(request)); + addOrUpdatePerformanceTestCronJob(request); + } + + private Schedule buildPerformanceTestSchedule(Schedule request) { + Schedule schedule = scheduleService.buildApiTestSchedule(request); + schedule.setJob(PerformanceTestJob.class.getName()); + schedule.setGroup(ScheduleGroup.PERFORMANCE_TEST.name()); + schedule.setType(ScheduleType.CRON.name()); + return schedule; + } + + private void addOrUpdatePerformanceTestCronJob(Schedule request) { + scheduleService.addOrUpdateCronJob(request, PerformanceTestJob.getJobKey(request.getResourceId()), PerformanceTestJob.getTriggerKey(request.getResourceId()), PerformanceTestJob.class); + } } diff --git a/backend/src/main/java/io/metersphere/service/ScheduleService.java b/backend/src/main/java/io/metersphere/service/ScheduleService.java index 9d5e534177..d15becdeca 100644 --- a/backend/src/main/java/io/metersphere/service/ScheduleService.java +++ b/backend/src/main/java/io/metersphere/service/ScheduleService.java @@ -4,9 +4,16 @@ import com.alibaba.fastjson.JSON; import io.metersphere.base.domain.Schedule; import io.metersphere.base.domain.ScheduleExample; import io.metersphere.base.mapper.ScheduleMapper; +import io.metersphere.commons.constants.ScheduleGroup; +import io.metersphere.commons.constants.ScheduleType; +import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.LogUtil; +import io.metersphere.commons.utils.SessionUtils; import io.metersphere.job.QuartzManager; +import io.metersphere.job.sechedule.ApiTestJob; +import org.apache.commons.lang3.StringUtils; import org.quartz.JobKey; +import org.quartz.SchedulerException; import org.quartz.TriggerKey; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -77,4 +84,33 @@ public class ScheduleService { } }); } + + public Schedule buildApiTestSchedule(Schedule request) { + Schedule schedule = new Schedule(); + schedule.setResourceId(request.getResourceId()); + schedule.setEnable(request.getEnable()); + schedule.setValue(request.getValue().trim()); + schedule.setKey(request.getResourceId()); + schedule.setUserId(SessionUtils.getUser().getId()); + return schedule; + } + + public void addOrUpdateCronJob(Schedule request, JobKey jobKey, TriggerKey triggerKey, Class clazz) { + Boolean enable = request.getEnable(); + String cronExpression = request.getValue(); + if (enable != null && enable && StringUtils.isNotBlank(cronExpression)) { + try { + QuartzManager.addOrUpdateCronJob(jobKey, triggerKey, clazz, cronExpression, QuartzManager.getDefaultJobDataMap(request.getResourceId(), cronExpression, SessionUtils.getUser().getId())); + } catch (SchedulerException e) { + LogUtil.error(e.getMessage(), e); + MSException.throwException("定时任务开启异常"); + } + } else { + try { + QuartzManager.removeJob(jobKey, triggerKey); + } catch (Exception e) { + MSException.throwException("定时任务关闭异常"); + } + } + } } diff --git a/backend/src/main/java/io/metersphere/track/request/testplan/RunTestPlanRequest.java b/backend/src/main/java/io/metersphere/track/request/testplan/RunTestPlanRequest.java index 79cde96255..c9fd036171 100644 --- a/backend/src/main/java/io/metersphere/track/request/testplan/RunTestPlanRequest.java +++ b/backend/src/main/java/io/metersphere/track/request/testplan/RunTestPlanRequest.java @@ -1,4 +1,10 @@ package io.metersphere.track.request.testplan; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter public class RunTestPlanRequest extends TestPlanRequest { + private String userId; } diff --git a/frontend/src/business/components/api/test/ApiTestConfig.vue b/frontend/src/business/components/api/test/ApiTestConfig.vue index 1c38fce1e1..47bdee48a0 100644 --- a/frontend/src/business/components/api/test/ApiTestConfig.vue +++ b/frontend/src/business/components/api/test/ApiTestConfig.vue @@ -219,10 +219,7 @@ this.saveSchedule(); }, saveSchedule() { - if (this.create) { - this.$message('请先保存测试,在设置定时任务'); - return; - } + this.checkScheduleEdit(); let param = {}; param = this.test.schedule; param.resourceId = this.test.id; @@ -278,8 +275,4 @@ .test-container .more { margin-left: 10px; } - - .schedule-config { - float: right; - } diff --git a/frontend/src/business/components/common/components/MsScheduleConfig.vue b/frontend/src/business/components/common/components/MsScheduleConfig.vue index 56900fb8d9..4dcf0dff06 100644 --- a/frontend/src/business/components/common/components/MsScheduleConfig.vue +++ b/frontend/src/business/components/common/components/MsScheduleConfig.vue @@ -32,7 +32,9 @@ checkOpen: { type: Function, default() { - return new Function() + return { + checkOpen() {return true;} + } } }, }, diff --git a/frontend/src/business/components/common/components/MsScheduleEdit.vue b/frontend/src/business/components/common/components/MsScheduleEdit.vue index f815d5bf55..16063c147b 100644 --- a/frontend/src/business/components/common/components/MsScheduleEdit.vue +++ b/frontend/src/business/components/common/components/MsScheduleEdit.vue @@ -1,7 +1,7 @@