diff --git a/test-test/src/main/java/com/test/test/controller/PerformanceTestController.java b/test-test/src/main/java/com/test/test/controller/PerformanceTestController.java index 5ad62bb..102eda1 100644 --- a/test-test/src/main/java/com/test/test/controller/PerformanceTestController.java +++ b/test-test/src/main/java/com/test/test/controller/PerformanceTestController.java @@ -6,20 +6,16 @@ import com.test.test.domain.PerformanceTest; import com.test.test.domain.TestCase; import com.test.test.domain.qo.PerformanceTestQO; import com.test.test.domain.vo.PerformanceTestVO; +import com.test.test.service.IPerformanceTestCaseReportService; import com.test.test.service.IPerformanceTestService; import com.test.test.service.ITestCaseService; +import com.test.test.task.DynamicTaskManager; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import com.test.common.annotation.Log; import com.test.common.core.controller.BaseController; import com.test.common.core.domain.AjaxResult; @@ -29,19 +25,24 @@ import com.test.common.core.page.TableDataInfo; /** * 性能测试Controller - * + * * @author test * @date 2025-04-14 */ @RestController @RequestMapping("/test/performanceTest") @Slf4j -public class PerformanceTestController extends BaseController -{ +public class PerformanceTestController extends BaseController { + @Value("${test.jmeterHomePath:/opt/apache-jmeter}") + private String jmeterHomePath; @Autowired private IPerformanceTestService performanceTestService; @Autowired private ITestCaseService testCaseService; + @Autowired + private IPerformanceTestCaseReportService performanceTestCaseReportService; + @Autowired + private DynamicTaskManager dynamicTaskManager; /** @@ -49,16 +50,14 @@ public class PerformanceTestController extends BaseController */ // @PreAuthorize("@ss.hasPermi('system:test:list')") @GetMapping("/list") - public TableDataInfo list(PerformanceTest performanceTest) - { + public TableDataInfo list(PerformanceTest performanceTest) { startPage(); List list = performanceTestService.selectPerformanceTestList(performanceTest); return getDataTable(list); } @GetMapping("/testCaseList") - public TableDataInfo testCaseList(TestCase testCase) - { + public TableDataInfo testCaseList(TestCase testCase) { startPage(); List testCaseList = testCaseService.selectTestCaseList(testCase); return getDataTable(testCaseList); @@ -70,8 +69,7 @@ public class PerformanceTestController extends BaseController // @PreAuthorize("@ss.hasPermi('system:test:export')") @Log(title = "性能测试", businessType = BusinessType.EXPORT) @PostMapping("/export") - public void export(HttpServletResponse response, PerformanceTest performanceTest) - { + public void export(HttpServletResponse response, PerformanceTest performanceTest) { List list = performanceTestService.selectPerformanceTestList(performanceTest); ExcelUtil util = new ExcelUtil(PerformanceTest.class); util.exportExcel(response, list, "性能测试数据"); @@ -82,8 +80,7 @@ public class PerformanceTestController extends BaseController */ // @PreAuthorize("@ss.hasPermi('system:test:query')") @GetMapping(value = "/{id}") - public AjaxResult getInfo(@PathVariable("id") Long id) - { + public AjaxResult getInfo(@PathVariable("id") Long id) { return success(performanceTestService.selectPerformanceTestById(id)); } @@ -93,16 +90,23 @@ public class PerformanceTestController extends BaseController // @PreAuthorize("@ss.hasPermi('system:test:add')") @Log(title = "性能测试", businessType = BusinessType.INSERT) @PostMapping("/add") - public AjaxResult add(@RequestBody PerformanceTestQO performanceTestQO) - { + public AjaxResult add(@RequestBody PerformanceTestQO performanceTestQO) { try { Long l = performanceTestService.insertPerformanceTest(performanceTestQO); - if (l > 0){ - return success(l); + // 获取新增的任务完整信息 + PerformanceTestVO newTaskVo = performanceTestService.selectPerformanceTestById(l); + PerformanceTest entity = new PerformanceTest(); + entity.setId(newTaskVo.getId()); + entity.setCrontab(newTaskVo.getCrontab()); + entity.setCrontabStatus(newTaskVo.getCrontabStatus()); + entity.setDelFlag(newTaskVo.getDelFlag()); + // 如果任务是定时任务且状态为启用,则添加到定时任务管理器 + if (entity.getCrontabStatus() == 1) { + dynamicTaskManager.addNewTask(entity); } - return error("新增失败!"); + return success(l); } catch (Exception e) { - log.info("新增失败!",e); + log.info("新增失败!", e); return error("新增失败!"); } } @@ -111,21 +115,32 @@ public class PerformanceTestController extends BaseController /** * 新增保存并执行性能测试 */ - // @PreAuthorize("@ss.hasPermi('system:test:add')") @Log(title = "性能测试", businessType = BusinessType.INSERT) @PostMapping("/addAndExecute") - public AjaxResult addAndExecute(@RequestBody PerformanceTestQO performanceTestQO) - { + public AjaxResult addAndExecute(@RequestBody PerformanceTestQO performanceTestQO) { try { Long l = performanceTestService.insertPerformanceTest(performanceTestQO); - if (l > 0){ - //todo 执行逻辑 - return success(l); + // 获取新增的任务完整信息 + PerformanceTestVO newTaskVo = performanceTestService.selectPerformanceTestById(l); + PerformanceTest entity = new PerformanceTest(); + entity.setId(newTaskVo.getId()); + entity.setCrontab(newTaskVo.getCrontab()); + entity.setCrontabStatus(newTaskVo.getCrontabStatus()); + entity.setDelFlag(newTaskVo.getDelFlag()); + // 如果任务是定时任务且状态为启用,则添加到定时任务管理器 + if (entity.getCrontabStatus() == 1) { + dynamicTaskManager.addNewTask(entity); + } + // 执行性能测试 + try { + Long l1 = performanceTestCaseReportService.executePerformanceTestAndReport(l, jmeterHomePath, 2); + return success(l1); + } catch (Exception e) { + log.error("执行失败!", e); + return error("执行失败!"); } - return error("新增并执行失败!"); - } catch (Exception e) { - log.info("新增并执行失败!",e); + log.error("新增并执行失败!", e); return error("新增并执行失败!"); } } @@ -136,36 +151,56 @@ public class PerformanceTestController extends BaseController // @PreAuthorize("@ss.hasPermi('system:test:edit')") @Log(title = "性能测试", businessType = BusinessType.UPDATE) @PutMapping - public AjaxResult edit(@RequestBody PerformanceTestQO performanceTestQO) - { + public AjaxResult edit(@RequestBody PerformanceTestQO performanceTestQO) { try { + PerformanceTestVO originalTask = performanceTestService.selectPerformanceTestById(performanceTestQO.getId()); Long l = performanceTestService.updatePerformanceTest(performanceTestQO); - if (l > 0){ - return success(l); + PerformanceTestVO updatedTask = performanceTestService.selectPerformanceTestById(performanceTestQO.getId()); + // 如果crontab或crontab_status被修改了,则更新定时任务 + if (!updatedTask.getCrontab().equals(originalTask.getCrontab()) + || updatedTask.getCrontabStatus() != originalTask.getCrontabStatus()) { + PerformanceTest entity = new PerformanceTest(); + entity.setId(updatedTask.getId()); + entity.setCrontab(updatedTask.getCrontab()); + entity.setCrontabStatus(updatedTask.getCrontabStatus()); + entity.setDelFlag(updatedTask.getDelFlag()); + dynamicTaskManager.updateTask(entity); } - return error("修改失败!"); - + return success(l); } catch (Exception e) { - log.info("修改失败!",e); + log.error("修改失败!", e); return error("修改失败!"); } } - @Log(title = "性能测试", businessType = BusinessType.UPDATE) - @PutMapping("editAndExecute") - public AjaxResult editAndExecute(@RequestBody PerformanceTestQO performanceTestQO) - { - try { - Long l = performanceTestService.updatePerformanceTest(performanceTestQO); - if (l > 0){ - //todo 执行逻辑 - return success(l); - } - return error("修改并执行失败!"); + @Log(title = "性能测试", businessType = BusinessType.UPDATE) + @PutMapping("/editAndExecute") + public AjaxResult editAndExecute(@RequestBody PerformanceTestQO performanceTestQO) { + try { + PerformanceTestVO originalTask = performanceTestService.selectPerformanceTestById(performanceTestQO.getId()); + Long l = performanceTestService.updatePerformanceTest(performanceTestQO); + PerformanceTestVO updatedTask = performanceTestService.selectPerformanceTestById(performanceTestQO.getId()); + // 如果crontab或crontab_status被修改了,则更新定时任务 + if (!updatedTask.getCrontab().equals(originalTask.getCrontab()) + || updatedTask.getCrontabStatus() != originalTask.getCrontabStatus()) { + PerformanceTest entity = new PerformanceTest(); + entity.setId(updatedTask.getId()); + entity.setCrontab(updatedTask.getCrontab()); + entity.setCrontabStatus(updatedTask.getCrontabStatus()); + entity.setDelFlag(updatedTask.getDelFlag()); + dynamicTaskManager.updateTask(entity); + } + try { + Long l1 = performanceTestCaseReportService.executePerformanceTestAndReport(l, jmeterHomePath, 2); + return success(l1); + } catch (Exception e) { + log.error("执行失败!", e); + return error("执行失败!"); + } } catch (Exception e) { - log.info("修改并执行失败!",e); + log.error("修改并执行失败!", e); return error("修改并执行失败!"); } } @@ -175,9 +210,18 @@ public class PerformanceTestController extends BaseController */ // @PreAuthorize("@ss.hasPermi('system:test:remove')") @Log(title = "性能测试", businessType = BusinessType.UPDATE) - @PutMapping("/{ids}") - public AjaxResult remove(@PathVariable Long[] ids) - { + @PutMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) { return toAjax(performanceTestService.deletePerformanceTestByIds(ids)); } + + /** + * 删除性能测试 + */ + // @PreAuthorize("@ss.hasPermi('system:test:remove')") + @GetMapping("/executeNow") + public AjaxResult executeNow(@RequestParam Long id) { + Long l1 = performanceTestCaseReportService.executePerformanceTestAndReport(id, jmeterHomePath, 2); + return success(l1); + } } diff --git a/test-test/src/main/java/com/test/test/service/impl/PerformanceTestServiceImpl.java b/test-test/src/main/java/com/test/test/service/impl/PerformanceTestServiceImpl.java index bacaf8a..a3d243d 100644 --- a/test-test/src/main/java/com/test/test/service/impl/PerformanceTestServiceImpl.java +++ b/test-test/src/main/java/com/test/test/service/impl/PerformanceTestServiceImpl.java @@ -59,11 +59,11 @@ public class PerformanceTestServiceImpl implements IPerformanceTestService for (PerformanceTestCase testCase : performanceTestCaseList) { PerformanceTestCaseVO performanceTestCaseVO = new PerformanceTestCaseVO(); BeanUtils.copyProperties(testCase, performanceTestCaseVO); - performanceTestCaseVOList.add(performanceTestCaseVO); - } - for (PerformanceTestCaseVO performanceTestCaseVO : performanceTestCaseVOList) { TestCase caseEntity = testCaseMapper.selectTestCaseById(performanceTestCaseVO.getTestCaseId()); - performanceTestCaseVO.setTestCaseName(caseEntity.getName()); + if (caseEntity!=null){ + performanceTestCaseVOList.add(performanceTestCaseVO); + performanceTestCaseVO.setTestCaseName(caseEntity.getName()); + } } return performanceTestVO; } @@ -111,7 +111,6 @@ public class PerformanceTestServiceImpl implements IPerformanceTestService for (PerformanceTestCaseQO performanceTestCaseQO : performanceTestCaseQOList) { PerformanceTestCase performanceTestCase = new PerformanceTestCase(); performanceTestCaseQO.setPerformanceId(id); - performanceTestCaseQO.setStatus(performanceTestCaseQO.getStatus()); BeanUtils.copyProperties(performanceTestCaseQO,performanceTestCase); performanceTestCaseMapper.insertPerformanceTestCase(performanceTestCase); } diff --git a/test-test/src/main/java/com/test/test/task/DynamicTaskManager.java b/test-test/src/main/java/com/test/test/task/DynamicTaskManager.java new file mode 100644 index 0000000..8eff020 --- /dev/null +++ b/test-test/src/main/java/com/test/test/task/DynamicTaskManager.java @@ -0,0 +1,143 @@ +package com.test.test.task; + +import com.test.test.domain.PerformanceTest; +import com.test.test.mapper.PerformanceTestMapper; +import com.test.test.service.IPerformanceTestCaseReportService; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.support.CronTrigger; +import org.springframework.stereotype.Component; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class DynamicTaskManager { + + + @Value("${test.jmeterHomePath:/opt/apache-jmeter}") + private String jmeterHomePath; + + @Resource + private PerformanceTestMapper performanceTestMapper; + + @Resource + private TaskScheduler taskScheduler; + + @Resource + private IPerformanceTestCaseReportService performanceTestCaseReportService; + + private final Map> scheduledTasks = new ConcurrentHashMap<>(); + private final Map taskCache = new ConcurrentHashMap<>(); + + @PostConstruct + public void init() { + loadTasks(); // 初始加载 +// taskScheduler.scheduleWithFixedDelay(this::refreshTasks, 60000); // 每1分钟刷新 + } + + public void updateTask(PerformanceTest task) { + log.info("update task {}", task.getId()); + Long taskId = task.getId(); + // 先取消现有任务 + if (scheduledTasks.containsKey(taskId)) { + scheduledTasks.get(taskId).cancel(true); + scheduledTasks.remove(taskId); + taskCache.remove(taskId); + } + + // 如果任务状态是启用(1)且没有被删除,则重新调度 + if (task.getCrontabStatus() == 1 && "0".equals(task.getDelFlag())) { + log.info("启动任务:{}", task.getId()); + scheduleTask(task); + } + } + + /** + * 添加新任务到定时调度 + * @param task 性能测试任务 + */ + public void addNewTask(PerformanceTest task) { + // 只有当任务状态是启用(1)且没有被删除时才创建定时任务 + if (task.getCrontabStatus() == 1 && "0".equals(task.getDelFlag())) { + log.info("加入定时任务:{}", task.getId()); + scheduleTask(task); + } + } + + private void loadTasks() { + PerformanceTest performanceTest =new PerformanceTest(); + performanceTest.setCrontabStatus(1); + performanceTest.setDelFlag("0"); + List tasks = performanceTestMapper.selectPerformanceTestList(performanceTest); + tasks.forEach(this::scheduleTask); + } + + private void scheduleTask(PerformanceTest task) { + try { + CronTrigger trigger = new CronTrigger(task.getCrontab()); + ScheduledFuture future = taskScheduler.schedule( + () -> executeTask(task), trigger + ); + scheduledTasks.put(task.getId(), future); + taskCache.put(task.getId(), task); + } catch (IllegalArgumentException e) { + // 处理无效cron表达式 + log.error("无效的cron表达式: " + task.getCrontab()); + } + } + + private void executeTask(PerformanceTest task) { + // 执行业务逻辑 + log.info("执行任务: " + task.getId()); + try{ + performanceTestCaseReportService.executePerformanceTestAndReport(task.getId(),jmeterHomePath,1); + } catch (Exception e) { + log.error("执行失败!",e); + } + } + + private void refreshTasks() { + PerformanceTest performanceTest =new PerformanceTest(); + performanceTest.setCrontabStatus(1); + performanceTest.setDelFlag("0"); + List currentTasks = performanceTestMapper.selectPerformanceTestList(performanceTest); + Set currentIds = currentTasks.stream() + .map(PerformanceTest::getId) + .collect(Collectors.toSet()); + + // 处理新增或更新的任务 + currentTasks.forEach(task -> { + Long taskId = task.getId(); + if (!scheduledTasks.containsKey(taskId)) { + scheduleTask(task); // 新增任务 + } else { + PerformanceTest cached = taskCache.get(taskId); + if (!task.getCrontab().equals(cached.getCrontab())) { + // 取消旧任务并重新调度 + scheduledTasks.get(taskId).cancel(true); + scheduleTask(task); + } + } + }); + + // 移除已禁用或删除的任务 + new HashSet<>(scheduledTasks.keySet()).forEach(existingId -> { + if (!currentIds.contains(existingId)) { + scheduledTasks.get(existingId).cancel(true); + scheduledTasks.remove(existingId); + taskCache.remove(existingId); + } + }); + } +} \ No newline at end of file