性能测试-定时任务
This commit is contained in:
parent
6c4dbedf36
commit
fdfac7f038
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package io.metersphere.listeners;
|
||||
package io.metersphere.listener;
|
||||
|
||||
import io.metersphere.service.ScheduleService;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<LoadTestDTO> 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<LoadTestDTO> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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("定时任务关闭异常");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -32,7 +32,9 @@
|
|||
checkOpen: {
|
||||
type: Function,
|
||||
default() {
|
||||
return new Function()
|
||||
return {
|
||||
checkOpen() {return true;}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<el-dialog width="30%" class="schedule-edit" :title="'编辑定时任务'" :visible.sync="dialogVisible" @close="close">
|
||||
<div id="app">
|
||||
<el-form :model="schedule" :rules="rules" ref="from">
|
||||
<el-form :model="form" :rules="rules" ref="from">
|
||||
<el-form-item
|
||||
:placeholder="'请输入 Cron 表达式'"
|
||||
prop="cronValue">
|
||||
|
@ -9,7 +9,7 @@
|
|||
<el-button type="primary" @click="showCronDialog">生成 Cron</el-button>
|
||||
<el-button type="primary" @click="saveCron">保存</el-button>
|
||||
</el-form-item>
|
||||
<crontab-result :ex="schedule.value" ref="crontabResult"/>
|
||||
<crontab-result :ex="form.cronValue" ref="crontabResult"/>
|
||||
</el-form>
|
||||
<el-dialog title="生成 cron" :visible.sync="showCron" :modal="false">
|
||||
<crontab @hide="showCron=false" @fill="crontabFill" :expression="schedule.value"/>
|
||||
|
@ -41,7 +41,6 @@
|
|||
if (!cronValidate(cronValue)) {
|
||||
callback(new Error('Cron 表达式格式错误'));
|
||||
} else {
|
||||
this.schedule.value = cronValue;
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
@ -62,7 +61,6 @@
|
|||
},
|
||||
crontabFill(value) {
|
||||
//确定后回传的值
|
||||
this.schedule.value = value;
|
||||
this.form.cronValue = value;
|
||||
this.$refs['from'].validate();
|
||||
},
|
||||
|
@ -80,12 +78,14 @@
|
|||
});
|
||||
},
|
||||
close() {
|
||||
this.form.cronValue = '';
|
||||
this.$refs['from'].resetFields();
|
||||
this.form.cronValue = this.schedule.value;
|
||||
if (!this.schedule.value) {
|
||||
this.$refs.crontabResult.resultList = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
<el-button :disabled="isReadOnly" type="primary" plain @click="save">{{$t('commons.save')}}</el-button>
|
||||
<el-button :disabled="isReadOnly" type="primary" plain @click="saveAndRun">{{$t('load_test.save_and_run')}}</el-button>
|
||||
<el-button :disabled="isReadOnly" type="warning" plain @click="cancel">{{$t('commons.cancel')}}</el-button>
|
||||
|
||||
<ms-schedule-config :schedule="testPlan.schedule" :save="saveCronExpression" @scheduleChange="saveSchedule" :check-open="checkScheduleEdit"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
@ -50,10 +52,12 @@
|
|||
import MsContainer from "../../common/components/MsContainer";
|
||||
import MsMainContainer from "../../common/components/MsMainContainer";
|
||||
import {checkoutTestManagerOrTestUser} from "../../../../common/js/utils";
|
||||
import MsScheduleConfig from "../../common/components/MsScheduleConfig";
|
||||
|
||||
export default {
|
||||
name: "EditPerformanceTestPlan",
|
||||
components: {
|
||||
MsScheduleConfig,
|
||||
PerformancePressureConfig,
|
||||
PerformanceBasicConfig,
|
||||
PerformanceAdvancedConfig,
|
||||
|
@ -63,7 +67,7 @@
|
|||
data() {
|
||||
return {
|
||||
result: {},
|
||||
testPlan: {},
|
||||
testPlan: {schedule:{}},
|
||||
listProjectPath: "/project/listAll",
|
||||
savePath: "/performance/save",
|
||||
editPath: "/performance/edit",
|
||||
|
@ -103,32 +107,16 @@
|
|||
if (!checkoutTestManagerOrTestUser()) {
|
||||
this.isReadOnly = true;
|
||||
}
|
||||
|
||||
let testId = to.params.testId;
|
||||
if (testId) {
|
||||
this.testId = testId;
|
||||
this.result = this.$get('/performance/get/' + testId, response => {
|
||||
if (response.data) {
|
||||
this.testPlan = response.data;
|
||||
}
|
||||
});
|
||||
}
|
||||
this.getTest(to.params.testId);
|
||||
}
|
||||
|
||||
},
|
||||
created() {
|
||||
let testId = this.$route.params.testId;
|
||||
this.isReadOnly = false;
|
||||
if (!checkoutTestManagerOrTestUser()) {
|
||||
this.isReadOnly = true;
|
||||
}
|
||||
if (testId) {
|
||||
this.testId = testId;
|
||||
this.result = this.$get('/performance/get/' + testId, response => {
|
||||
this.testPlan = response.data;
|
||||
});
|
||||
}
|
||||
|
||||
this.getTest(this.$route.params.testId);
|
||||
this.listProjects();
|
||||
},
|
||||
mounted() {
|
||||
|
@ -148,6 +136,19 @@
|
|||
this.$store.commit("clearTest");
|
||||
}
|
||||
},
|
||||
getTest(testId) {
|
||||
if (testId) {
|
||||
this.testId = testId;
|
||||
this.result = this.$get('/performance/get/' + testId, response => {
|
||||
if (response.data) {
|
||||
this.testPlan = response.data;
|
||||
if (!this.testPlan.schedule) {
|
||||
this.testPlan.schedule = {};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
listProjects() {
|
||||
this.result = this.$get(this.listProjectPath, response => {
|
||||
this.projects = response.data;
|
||||
|
@ -251,6 +252,32 @@
|
|||
this.$nextTick(()=> {
|
||||
this.active = activeName;
|
||||
});
|
||||
},
|
||||
saveCronExpression(cronExpression) {
|
||||
this.testPlan.schedule.enable = true;
|
||||
this.testPlan.schedule.value = cronExpression;
|
||||
this.saveSchedule();
|
||||
},
|
||||
saveSchedule() {
|
||||
this.checkScheduleEdit();
|
||||
let param = {};
|
||||
param = this.testPlan.schedule;
|
||||
param.resourceId = this.testPlan.id;
|
||||
let url = '/performance/schedule/create';
|
||||
if (param.id) {
|
||||
url = '/performance/schedule/update';
|
||||
}
|
||||
this.$post(url, param, response => {
|
||||
this.$success('保存成功');
|
||||
this.getTest(this.testPlan.id);
|
||||
});
|
||||
},
|
||||
checkScheduleEdit() {
|
||||
if (!this.testPlan.id) {
|
||||
this.$message('请先保存测试');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue