diff --git a/src/main/java/com/realtime/protection/configuration/exception/GlobalExceptionHandler.java b/src/main/java/com/realtime/protection/configuration/exception/GlobalExceptionHandler.java index 870f989..d7fd655 100644 --- a/src/main/java/com/realtime/protection/configuration/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/realtime/protection/configuration/exception/GlobalExceptionHandler.java @@ -34,6 +34,7 @@ public class GlobalExceptionHandler { @Order(3) @ExceptionHandler(value = {Exception.class}) public ResponseResult handleGlobalException(Exception e) { + e.printStackTrace(); log.error("遭遇全局异常:{}", e.getMessage()); return ResponseResult.error().setMessage(e.getMessage()); } @@ -55,7 +56,7 @@ public class GlobalExceptionHandler { @ExceptionHandler(value = DuplicateKeyException.class) public ResponseResult handleDuplicateKeyException(DuplicateKeyException e) { return ResponseResult.invalid().setMessage( - "插入/更新失败,请检查当前插入字段和数据库中是否存在相同数据" + "插入/更新失败,请检查当前插入字段和数据库中是否存在相同数据 "+e.getMessage() ); } diff --git a/src/main/java/com/realtime/protection/configuration/utils/EmptyStringToNullDeserializer.java b/src/main/java/com/realtime/protection/configuration/utils/EmptyStringToNullDeserializer.java new file mode 100644 index 0000000..b7a704d --- /dev/null +++ b/src/main/java/com/realtime/protection/configuration/utils/EmptyStringToNullDeserializer.java @@ -0,0 +1,16 @@ +package com.realtime.protection.configuration.utils; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; + +public class EmptyStringToNullDeserializer extends JsonDeserializer { + @Override + public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException, IOException { + String value = p.getValueAsString(); + return value.isEmpty() ? null : value; + } +} diff --git a/src/main/java/com/realtime/protection/server/alertmessage/AlertMessageService.java b/src/main/java/com/realtime/protection/server/alertmessage/AlertMessageService.java index 4ff7f4b..21c67ed 100644 --- a/src/main/java/com/realtime/protection/server/alertmessage/AlertMessageService.java +++ b/src/main/java/com/realtime/protection/server/alertmessage/AlertMessageService.java @@ -9,6 +9,7 @@ import com.realtime.protection.configuration.utils.Counter; import com.realtime.protection.configuration.utils.enums.StateEnum; import com.realtime.protection.configuration.utils.enums.TaskTypeEnum; import com.realtime.protection.server.command.CommandService; +import com.realtime.protection.server.task.status.StateHandler; import lombok.Data; import org.springframework.stereotype.Service; @@ -24,12 +25,14 @@ public class AlertMessageService { private final CommandService commandService; private final AlertMessageMapper alertMessageMapper; private final Counter counter; + private final StateHandler stateHandler; public AlertMessageService( - CommandService commandService, AlertMessageMapper alertMessageMapper, Counter counter) { + CommandService commandService, AlertMessageMapper alertMessageMapper, Counter counter, StateHandler stateHandler) { this.commandService = commandService; this.alertMessageMapper = alertMessageMapper; this.counter = counter; + this.stateHandler = stateHandler; } @DSTransactional @@ -117,6 +120,8 @@ public class AlertMessageService { Boolean isValid, Boolean isJudged, AlertMessage alertMessage){ + List commandUUIDs = new ArrayList<>(); + for (TaskCommandInfo dynamicTaskCommandInfo : dynamicTaskCommandInfoList ){ //command入库 dynamicTaskCommandInfo.setIsValid(isValid); @@ -127,6 +132,7 @@ public class AlertMessageService { alertMessage.setCommandUUID(commandUUID); String alertMessageUUID = UUID.randomUUID().toString(); + commandUUIDs.add(commandUUID); alertMessage.setAlertMessageUUID(alertMessageUUID); alertMessage.setDisplay_id( "GJ-" @@ -137,6 +143,8 @@ public class AlertMessageService { ); alertMessageMapper.insertAlertMessage(alertMessage); } + //发送指令新建信号 + stateHandler.sendCommandDistributeSignal(commandUUIDs); } private String insertAlertMessageOnly(AlertMessage alertMessage){ diff --git a/src/main/java/com/realtime/protection/server/defense/templatenew/TemplateService.java b/src/main/java/com/realtime/protection/server/defense/templatenew/TemplateService.java index 28b7675..9b7d934 100644 --- a/src/main/java/com/realtime/protection/server/defense/templatenew/TemplateService.java +++ b/src/main/java/com/realtime/protection/server/defense/templatenew/TemplateService.java @@ -6,6 +6,7 @@ import com.realtime.protection.configuration.utils.Counter; import com.realtime.protection.configuration.utils.SqlSessionWrapper; import com.realtime.protection.configuration.utils.enums.audit.AuditStatusValidator; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import java.time.LocalDateTime; @@ -34,8 +35,11 @@ public class TemplateService { + "-" + String.format("%06d", counter.generateId("strategy_template")) ); - - templateMapper.newTemplate(template); + try { + templateMapper.newTemplate(template); + }catch (DuplicateKeyException e){ + throw new IllegalArgumentException("策略模板模板名称重复"); + } if (template.getTemplateId() == null) { return 0; diff --git a/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleController.java b/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleController.java index f51cf68..87a7df0 100644 --- a/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleController.java +++ b/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleController.java @@ -64,7 +64,7 @@ public class DynamicRuleController implements DynamicRuleControllerApi { @Override @DeleteMapping("/{id}/delete") public ResponseResult deleteDynamicRuleObject(@PathVariable Integer id) { - log.info("删除动态规则: {}", id); +// log.info("删除动态规则: {}", id); //调用service删除 dynamicRuleService.deleteDynamicRuleObject(id); diff --git a/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleMapper.java b/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleMapper.java index 7534ff7..8687773 100644 --- a/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleMapper.java +++ b/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleMapper.java @@ -77,4 +77,7 @@ public interface DynamicRuleMapper { List queryHistory(Integer id, Integer page, Integer pageSize); void removeUsedTaskId(Long taskId); + + + List queryAuditStatusByIdList(@Param("ids") List ids); } diff --git a/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleService.java b/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleService.java index ec0338b..732c84b 100644 --- a/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleService.java +++ b/src/main/java/com/realtime/protection/server/rule/dynamicrule/DynamicRuleService.java @@ -135,6 +135,21 @@ public class DynamicRuleService { } // 批量删除 public Boolean deleteDynamicRuleObjects(List dynamicRuleIds) { + + //根据是否处于已使用 审核状态 判断能否删除 + List taskStatus = dynamicRuleMapper.queryAuditStatusByIdList(dynamicRuleIds); + int index = 0; + List errorIds = new ArrayList<>(); + for(Integer status: taskStatus) { + if (status == 3) { + errorIds.add(dynamicRuleIds.get(index)); + } + index++; + } + if (!errorIds.isEmpty()){ + throw new IllegalArgumentException("动态规则使用中, 错误id:" + errorIds); + } + Function, Boolean>> deleteDynamicRuleFunction = mapper -> list -> { if (list == null || list.isEmpty()) { @@ -196,7 +211,7 @@ public class DynamicRuleService { String auditUserName, Integer auditUserId, String auditUserDepart) { Integer originalAuditStatus = dynamicRuleMapper.queryAuditStatusById(id); if (originalAuditStatus == null) { - throw new IllegalArgumentException("cannot find audit status of static rule " + id + ", maybe static rule doesn't exist?"); + throw new IllegalArgumentException("不能找到静态规则" + id ); } if (!AuditStatusValidator.setOriginal(originalAuditStatus).checkValidate(auditStatus)) { throw new IllegalArgumentException("invalid audit status"); diff --git a/src/main/java/com/realtime/protection/server/task/TaskMapper.java b/src/main/java/com/realtime/protection/server/task/TaskMapper.java index 1a5d3a3..1bd7798 100644 --- a/src/main/java/com/realtime/protection/server/task/TaskMapper.java +++ b/src/main/java/com/realtime/protection/server/task/TaskMapper.java @@ -7,6 +7,7 @@ import com.realtime.protection.configuration.entity.task.TaskCommandInfo; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; import java.time.LocalDateTime; import java.util.List; @@ -114,4 +115,11 @@ public interface TaskMapper { void updateTaskStatusLogExpireTimeBatch(List taskIds); List queryHistory(Long id, Integer page, Integer pageSize); + + @Select("SELECT task_id FROM t_task WHERE task_start_time >= NOW() " + + "AND task_status = #{stateNum} AND task_audit_status = #{AuditNum}") + List queryRunnableTasks(Integer stateNum, Integer AuditNum); + + @Update("UPDATE t_task SET task_start_time = NOW() WHERE task_id = #{taskId}") + void updateTaskStartTime(Long taskId); } diff --git a/src/main/java/com/realtime/protection/server/task/TaskService.java b/src/main/java/com/realtime/protection/server/task/TaskService.java index 012c689..e951953 100644 --- a/src/main/java/com/realtime/protection/server/task/TaskService.java +++ b/src/main/java/com/realtime/protection/server/task/TaskService.java @@ -577,4 +577,12 @@ public class TaskService { dynamicRuleMapper.insertStatusLogBatch(ids); } + + public List getRunnableTasks() { + return taskMapper.queryRunnableTasks(StateEnum.PENDING.getStateNum(),AuditStatusEnum.AUDITED.getNum()); + } + + public void updateTaskStartTime(Long taskId) { + taskMapper.updateTaskStartTime(taskId); + } } diff --git a/src/main/java/com/realtime/protection/server/task/status/StateChangeService.java b/src/main/java/com/realtime/protection/server/task/status/StateChangeService.java index b806521..16dc265 100644 --- a/src/main/java/com/realtime/protection/server/task/status/StateChangeService.java +++ b/src/main/java/com/realtime/protection/server/task/status/StateChangeService.java @@ -65,7 +65,7 @@ public class StateChangeService { return false; } - log.debug(String.format("成功使得task(%d)从%s切换为%s", + log.info(String.format("成功使得task(%d)从%s切换为%s", taskId, originalState.getClass().getSimpleName(), newState.getClass().getSimpleName())); @@ -118,24 +118,24 @@ public class StateChangeService { } } -// /** -// * 将任务切换为开始状态 -// */ -// @Scheduled(cron = "0/10 * * * * ?") -// @Async -// protected void startTasks() { -// List startedTaskIds = taskService.getFinishedTasks(); -// log.debug("成功扫描出所有需要变为开始状态的任务:{}", startedTaskIds); -// -// for (Long taskId : startedTaskIds) { -// try { -// changeState(StateEnum.RUNNING.getStateNum(), taskId, true); -// } catch (Exception e) { -// log.warn(String.format("任务%d从%s状态变为运行中RUNNING状态遭遇异常:%s", -// taskId, taskService.queryTaskStatus(taskId), e.getMessage())); -// } -// -// } -// } + /** + * 将任务切换为开始状态 + */ + @Scheduled(cron = "0/10 * * * * ?") + @Async + protected void startTasks() { + List runnableTaskIds = taskService.getRunnableTasks(); + log.debug("成功扫描出所有需要变为开始状态的任务:{}", runnableTaskIds); + + for (Long taskId : runnableTaskIds) { + try { + changeState(StateEnum.RUNNING.getStateNum(), taskId, true); + } catch (Exception e) { + log.warn(String.format("任务%d从%s状态变为运行中RUNNING状态遭遇异常:%s", + taskId, taskService.queryTaskStatus(taskId), e.getMessage())); + } + + } + } } diff --git a/src/main/java/com/realtime/protection/server/task/status/StateHandler.java b/src/main/java/com/realtime/protection/server/task/status/StateHandler.java index 26c9217..f01a015 100644 --- a/src/main/java/com/realtime/protection/server/task/status/StateHandler.java +++ b/src/main/java/com/realtime/protection/server/task/status/StateHandler.java @@ -10,17 +10,21 @@ import com.realtime.protection.server.command.CommandService; import com.realtime.protection.server.task.TaskService; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.*; import reactor.core.publisher.Mono; import org.springframework.web.reactive.function.client.WebClient; import java.time.Duration; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @Slf4j +@Component public class StateHandler { @@ -38,6 +42,7 @@ public class StateHandler { protected Boolean handleStart(TaskService taskService, CommandService commandService, Long taskId) { Task task = taskService.queryTask(taskId); + if (task == null) { throw new IllegalArgumentException("无效task_id,因为无法找到对应任务"); } @@ -52,6 +57,16 @@ public class StateHandler { if (!taskAuditStatus.equals(AuditStatusEnum.AUDITED.getNum())) { throw new IllegalArgumentException("无效的task_id,因为未通过审核"); } + /* + 什么时候会调用这个函数呢, + 1是周期函数判断出来当前时间超过了任务开始时间,且运行状态处于PENDING,审批状态为AUDITED + 2是走http接口调用,这时候有可能是任务开始时间已经过了,也有可能是任务开始时间还没到 + 任务开始时间已经过了,周期性函数已经执行转变为RUNNNING状态了,前端再请求启动。 会报错 + 所以只能是任务开始时间还没到,这时候“提前启动”就要设置任务开始时间为当前时间 + */ + if (task.getTaskStartTime().isAfter(LocalDateTime.now())) { + taskService.updateTaskStartTime(taskId); + } return switch (TaskTypeEnum.getTaskTypeByNum(task.getTaskType())) { case STATIC -> handleStaticTaskStart(commandService, taskService, task); @@ -115,8 +130,12 @@ public class StateHandler { private Boolean handleDynamicTaskStart(TaskService taskService, Task task) { // 将所有关联的动态规则审批状态修改为“已使用” taskService.updateDynamicRuleAuditStatusInTask(task.getTaskId(), AuditStatusEnum.USING); - - return sendFilters(taskService, task); + try{ + return sendFilters(taskService, task); + } catch (Exception e) { + log.error("动态任务筛选条件发送出错", e); + return true; + } // return true; } @@ -136,7 +155,7 @@ public class StateHandler { sendCommandDistributeSignal(commandUUIDs); return true; } - private Boolean sendCommandDistributeSignal(List commandUUIDs) { + public Boolean sendCommandDistributeSignal(List commandUUIDs) { List> commandIDMaps = new ArrayList<>(); for (String commandUUID : commandUUIDs) { @@ -149,6 +168,7 @@ public class StateHandler { Mono mono = client_commandDistribute.post() .uri("/rule") .bodyValue(commandIDMaps) + .accept(MediaType.APPLICATION_JSON) // 设置Accept头为application/json .exchangeToMono(res -> { if (res.statusCode().equals(HttpStatus.OK)) { return res.bodyToMono(Map.class); diff --git a/src/main/java/com/realtime/protection/server/task/status/states/FailedState.java b/src/main/java/com/realtime/protection/server/task/status/states/FailedState.java index 251b0bb..e56b73b 100644 --- a/src/main/java/com/realtime/protection/server/task/status/states/FailedState.java +++ b/src/main/java/com/realtime/protection/server/task/status/states/FailedState.java @@ -13,7 +13,7 @@ public class FailedState extends StateHandler implements State { case RUNNING -> handleStart(taskService, commandService, taskId); case STOP -> handleStop(commandService, taskService, taskId); case FINISHED -> handleFinish(commandService, taskService, taskId); - default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState)); + default -> throw new IllegalStateException("错误的状态: " + StateEnum.getStateEnumByState(newState)); }; } } diff --git a/src/main/java/com/realtime/protection/server/task/status/states/FinishedState.java b/src/main/java/com/realtime/protection/server/task/status/states/FinishedState.java index 06d9d9a..dea9dd4 100644 --- a/src/main/java/com/realtime/protection/server/task/status/states/FinishedState.java +++ b/src/main/java/com/realtime/protection/server/task/status/states/FinishedState.java @@ -10,7 +10,7 @@ public class FinishedState extends StateHandler implements State { public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) { return switch (StateEnum.getStateEnumByState(newState)) { case PENDING, FINISHED -> true; - default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState)); + default -> throw new IllegalStateException("错误的状态: " + StateEnum.getStateEnumByState(newState)); }; } } diff --git a/src/main/java/com/realtime/protection/server/task/status/states/GeneratingState.java b/src/main/java/com/realtime/protection/server/task/status/states/GeneratingState.java index 47af68d..b912af3 100644 --- a/src/main/java/com/realtime/protection/server/task/status/states/GeneratingState.java +++ b/src/main/java/com/realtime/protection/server/task/status/states/GeneratingState.java @@ -12,7 +12,7 @@ public class GeneratingState extends StateHandler implements State { case RUNNING -> true; case FAILED -> handleFailed(commandService, taskService, taskId); case FINISHED -> handleFinish(commandService, taskService, taskId); - default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState)); + default -> throw new IllegalStateException("错误的状态: " + StateEnum.getStateEnumByState(newState)); }; } } diff --git a/src/main/java/com/realtime/protection/server/task/status/states/PauseState.java b/src/main/java/com/realtime/protection/server/task/status/states/PauseState.java index 3382565..b9c09d1 100644 --- a/src/main/java/com/realtime/protection/server/task/status/states/PauseState.java +++ b/src/main/java/com/realtime/protection/server/task/status/states/PauseState.java @@ -13,7 +13,7 @@ public class PauseState extends StateHandler implements State { case STOP -> handleStop(commandService, taskService, taskId); case FINISHED -> handleFinish(commandService, taskService, taskId); case FAILED -> handleFailed(commandService, taskService, taskId); - default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState)); + default -> throw new IllegalStateException("错误的状态: " + StateEnum.getStateEnumByState(newState)); }; } } diff --git a/src/main/java/com/realtime/protection/server/task/status/states/PendingState.java b/src/main/java/com/realtime/protection/server/task/status/states/PendingState.java index 6973e63..34714fc 100644 --- a/src/main/java/com/realtime/protection/server/task/status/states/PendingState.java +++ b/src/main/java/com/realtime/protection/server/task/status/states/PendingState.java @@ -13,7 +13,7 @@ public class PendingState extends StateHandler implements State { case FAILED -> handleFailed(commandService, taskService, taskId); case RUNNING -> handleStart(taskService, commandService, taskId); case FINISHED -> handleFinish(commandService, taskService, taskId); - default -> throw new IllegalStateException(taskId + " meets unexpected value: " + default -> throw new IllegalStateException("错误的状态: " + StateEnum.getStateEnumByState(newState)); }; } diff --git a/src/main/java/com/realtime/protection/server/task/status/states/RunningState.java b/src/main/java/com/realtime/protection/server/task/status/states/RunningState.java index e36ad9a..0b3fcdb 100644 --- a/src/main/java/com/realtime/protection/server/task/status/states/RunningState.java +++ b/src/main/java/com/realtime/protection/server/task/status/states/RunningState.java @@ -13,7 +13,7 @@ public class RunningState extends StateHandler implements State { case STOP -> handleStop(commandService, taskService, taskId); case FINISHED -> handleFinish(commandService, taskService, taskId); case FAILED -> handleFailed(commandService, taskService, taskId); - default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState)); + default -> throw new IllegalStateException("错误的状态: " + StateEnum.getStateEnumByState(newState)); }; } } diff --git a/src/main/java/com/realtime/protection/server/task/status/states/StopState.java b/src/main/java/com/realtime/protection/server/task/status/states/StopState.java index f301cba..3236136 100644 --- a/src/main/java/com/realtime/protection/server/task/status/states/StopState.java +++ b/src/main/java/com/realtime/protection/server/task/status/states/StopState.java @@ -14,7 +14,7 @@ public class StopState extends StateHandler implements State { case RUNNING -> handleStart(taskService, commandService, taskId); case FAILED -> handleFailed(commandService, taskService, taskId); case FINISHED -> handleFinish(commandService, taskService, taskId); - default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState)); + default -> throw new IllegalStateException("错误的状态: " + StateEnum.getStateEnumByState(newState)); }; } } diff --git a/src/main/resources/mappers/DynamicRuleMapper.xml b/src/main/resources/mappers/DynamicRuleMapper.xml index 1347011..2c4b18e 100644 --- a/src/main/resources/mappers/DynamicRuleMapper.xml +++ b/src/main/resources/mappers/DynamicRuleMapper.xml @@ -474,5 +474,14 @@ ORDER BY effective_time DESC LIMIT ${(page - 1) * pageSize}, #{pageSize} + + \ No newline at end of file diff --git a/src/main/resources/mappers/ProtectObjectMapper.xml b/src/main/resources/mappers/ProtectObjectMapper.xml index ef48291..22e532d 100644 --- a/src/main/resources/mappers/ProtectObjectMapper.xml +++ b/src/main/resources/mappers/ProtectObjectMapper.xml @@ -134,7 +134,7 @@ - + @@ -158,7 +158,7 @@