1. application.yml修改为application-dev.yml和application-prod.yml

2. 添加更多Exception拦截器
3. 编写状态模式处理task状态的更改
4. 添加StateChangeService,用以处理所有任务状态转换相关的内容
5. 添加StateEnum, ProtocolEnum,TaskTypeEnum用以处理任务和协议相关的所有状态和类型
This commit is contained in:
EnderByEndera
2024-01-11 19:49:07 +08:00
parent 930ba8b5ac
commit 0f712618f2
70 changed files with 1209 additions and 400 deletions

View File

@@ -1,20 +0,0 @@
package com.realtime.protection.server.task;
import com.realtime.protection.server.task.state.State;
public class StatusChanger {
private final State state;
public StatusChanger(State state) {
this.state = state;
}
public static StatusChanger setOriginal(State original) {
return new StatusChanger(original);
}
public Boolean changeState(State newState) {
return this.state.handle(newState);
}
}

View File

@@ -1,9 +1,14 @@
package com.realtime.protection.server.task;
import com.realtime.protection.configuration.entity.task.Task;
import com.realtime.protection.configuration.exception.DorisStartException;
import com.realtime.protection.configuration.response.ResponseResult;
import com.realtime.protection.configuration.utils.EntityUtils;
import com.realtime.protection.server.task.status.StateChangeService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@@ -13,14 +18,16 @@ import java.util.List;
public class TaskController {
private final TaskService taskService;
private final StateChangeService stateChangeService;
public TaskController(TaskService taskService) {
public TaskController(TaskService taskService, StateChangeService stateChangeService) {
this.taskService = taskService;
this.stateChangeService = stateChangeService;
}
@PostMapping("/new")
public ResponseResult newTask(@RequestBody @Valid Task task) {
Integer taskId = taskService.newTask(task);
Long taskId = taskService.newTask(task);
if (taskId > 0) {
return ResponseResult.ok()
@@ -48,7 +55,7 @@ public class TaskController {
}
@GetMapping("/{id}/query")
public ResponseResult queryTask(@PathVariable("id") @Min(1) Integer id) {
public ResponseResult queryTask(@PathVariable @Min(1) Long id) throws IllegalAccessException {
Task task = taskService.queryTask(id);
if (task == null) {
@@ -56,44 +63,39 @@ public class TaskController {
}
return ResponseResult.ok()
.setData("task_id", task.getTaskId())
.setData("task_name", task.getTaskName())
.setData("task_type", task.getTaskType())
.setData("task_status", task.getTaskStatus())
.setData("task_creator", task.getTaskCreateUsername())
.setData("task_creator_depart", task.getTaskCreateDepart())
.setData("task_start_time", task.getTaskStartTime())
.setData("task_end_time", task.getTaskEndTime())
.setData("task_static_rule_ids", task.getStaticRuleIds())
.setData("task_dynamic_rule_ids", task.getDynamicRuleIds());
.setDataMap(EntityUtils.entityToMap(task));
}
@PostMapping("/{id}/update")
public ResponseResult updateTask(@PathVariable("id") @Min(1) Integer taskId, @RequestBody @Valid Task task) {
task.setTaskId(taskId);
@PostMapping("/update")
public ResponseResult updateTask(@RequestBody @Valid Task task) {
return ResponseResult.ok()
.setData("task_id", taskId)
.setData("task_id", task.getTaskId())
.setData("success", taskService.updateTask(task));
}
@GetMapping("/{taskId}/audit/{auditStatus}")
public ResponseResult changeTaskAuditStatus(@PathVariable Integer auditStatus, @PathVariable Integer taskId) {
public ResponseResult changeTaskAuditStatus(@PathVariable @NotNull @Max(10) Integer auditStatus,
@PathVariable @NotNull @Min(1) Long taskId) {
return ResponseResult.ok()
.setData("task_id", taskId)
.setData("success", taskService.changeTaskAuditStatus(taskId, auditStatus));
.setData("success", taskService.changeTaskAuditStatus(taskId, auditStatus))
.setData("audit_status", taskService.queryTaskAuditStatus(taskId));
}
@GetMapping("/{id}/delete")
public ResponseResult deleteTask(@PathVariable("id") Integer taskId) {
@GetMapping("/{taskId}/delete")
public ResponseResult deleteTask(@PathVariable @NotNull @Min(1) Long taskId) {
return ResponseResult.ok()
.setData("task_id", taskId)
.setData("success", taskService.deleteTask(taskId));
}
@GetMapping("/{taskId}/running/{state}")
public ResponseResult changeTaskStatus(@PathVariable Integer state, @PathVariable Integer taskId) {
@GetMapping("/{taskId}/running/{stateNum}")
public ResponseResult changeTaskStatus(@PathVariable @NotNull Integer stateNum,
@PathVariable @NotNull Long taskId) throws DorisStartException {
return ResponseResult.ok()
.setData("task_id", taskId)
.setData("success", taskService.changeTaskStatus(taskId, state));
.setData("success", stateChangeService.changeState(stateNum, taskId))
.setData("status_now", taskService.queryTaskStatus(taskId));
}
}

View File

@@ -1,6 +1,7 @@
package com.realtime.protection.server.task;
import com.realtime.protection.configuration.entity.task.Task;
import com.realtime.protection.configuration.entity.task.TaskCommandInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -10,25 +11,33 @@ import java.util.List;
public interface TaskMapper {
void newTask(@Param("task") Task task);
void newTaskStaticRuleConcat(@Param("task_id") Integer taskId,
@Param("rule_ids") List<Integer> staticRuleIds);
void newTaskStaticRuleConcat(@Param("task_id") Long taskId,
@Param("rule_ids") List<Long> staticRuleIds);
void newTaskDynamicRuleConcat(@Param("task_id") Integer taskId,
@Param("rule_ids") List<Integer> dynamicRuleIds);
void newTaskDynamicRuleConcat(@Param("task_id") Long taskId,
@Param("rule_ids") List<Long> dynamicRuleIds);
List<Task> queryTasks(@Param("task_status") Integer taskStatus, @Param("task_type") String task_type,
@Param("task_name") String taskName, @Param("task_creator") String taskCreator,
@Param("page") Integer page, @Param("page_size") Integer pageSize);
Task queryTask(@Param("task_id") Integer taskId);
Task queryTask(@Param("task_id") Long taskId);
void updateTask(@Param("task") Task task);
void clearTaskConnectedStaticRule(@Param("task_id") Integer taskId);
void clearTaskConnectedStaticRule(@Param("task_id") Long taskId);
void clearTaskConnectedDynamicRule(@Param("task_id") Integer taskId);
void clearTaskConnectedDynamicRule(@Param("task_id") Long taskId);
void changeTaskAuditStatus(@Param("task_id") Integer taskId, @Param("audit_status") Integer auditStatus);
void changeTaskAuditStatus(@Param("task_id") Long taskId, @Param("audit_status") Integer auditStatus);
Boolean deleteTask(@Param("task_id") Integer taskId);
Boolean deleteTask(@Param("task_id") Long taskId);
Boolean changeTaskStatus(@Param("task_id") Long taskId, @Param("state") Integer stateNum);
List<TaskCommandInfo> getStaticCommands(@Param("task_id") Long taskId);
Integer queryTaskAuditStatus(@Param("task_id") Long taskId);
Integer queryTaskStatus(@Param("task_id") Long taskId);
}

View File

@@ -1,11 +1,8 @@
package com.realtime.protection.server.task;
import com.realtime.protection.configuration.entity.task.Task;
import com.realtime.protection.configuration.entity.task.TaskCommandInfo;
import com.realtime.protection.configuration.utils.status.AuditStatusValidator;
import com.realtime.protection.server.task.state.PauseState;
import com.realtime.protection.server.task.state.RunningState;
import com.realtime.protection.server.task.state.State;
import com.realtime.protection.server.task.state.StopState;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -20,7 +17,7 @@ public class TaskService {
}
@Transactional
public Integer newTask(Task task) {
public Long newTask(Task task) {
taskMapper.newTask(task);
taskMapper.newTaskStaticRuleConcat(task.getTaskId(), task.getStaticRuleIds());
@@ -35,7 +32,7 @@ public class TaskService {
return taskMapper.queryTasks(taskStatus, taskType, taskName, taskCreator, page, pageSize);
}
public Task queryTask(Integer id) {
public Task queryTask(Long id) {
return taskMapper.queryTask(id);
}
@@ -46,47 +43,46 @@ public class TaskService {
taskMapper.clearTaskConnectedStaticRule(task.getTaskId());
taskMapper.clearTaskConnectedDynamicRule(task.getTaskId());
taskMapper.newTaskStaticRuleConcat(task.getTaskId(), task.getStaticRuleIds());
taskMapper.newTaskDynamicRuleConcat(task.getTaskId(), task.getDynamicRuleIds());
if (task.getStaticRuleIds() != null && !task.getStaticRuleIds().isEmpty())
taskMapper.newTaskStaticRuleConcat(task.getTaskId(), task.getStaticRuleIds());
if (task.getDynamicRuleIds() != null && !task.getDynamicRuleIds().isEmpty())
taskMapper.newTaskDynamicRuleConcat(task.getTaskId(), task.getDynamicRuleIds());
return true;
}
@Transactional
public Boolean changeTaskAuditStatus(Integer taskId, Integer taskAuditStatus) {
if (AuditStatusValidator.setOriginal(taskMapper.queryTask(taskId).getTaskAuditStatus()).checkValidate(taskAuditStatus))
public Boolean changeTaskAuditStatus(Long taskId, Integer taskAuditStatus) {
Integer originalAuditStatus = taskMapper.queryTaskAuditStatus(taskId);
if (originalAuditStatus == null) {
throw new IllegalArgumentException("cannot find audit status of task " + taskId + ", maybe task doesn't exist?");
}
if (AuditStatusValidator.setOriginal(originalAuditStatus).checkValidate(taskAuditStatus))
taskMapper.changeTaskAuditStatus(taskId, taskAuditStatus);
else return false;
return true;
}
public Boolean deleteTask(Integer taskId) {
public Boolean deleteTask(Long taskId) {
return taskMapper.deleteTask(taskId);
}
@Transactional
public Boolean changeTaskStatus(Integer taskId, Integer stateNum) {
State originalState = switch (taskMapper.queryTask(taskId).getTaskStatus()) {
// 运行中
case 1 -> new RunningState();
// 暂停中
case 2 -> new PauseState();
// 停止中
case 3 -> new StopState();
default -> throw new IllegalArgumentException();
};
public Boolean changeTaskStatus(Long taskId, Integer stateNum) {
return taskMapper.changeTaskStatus(taskId, stateNum);
}
State newState = switch (stateNum) {
// 运行中
case 1 -> new RunningState();
// 暂停中
case 2 -> new PauseState();
// 停止中
case 3 -> new StopState();
default -> throw new IllegalArgumentException();
};
public List<TaskCommandInfo> getStaticCommandInfos(Long taskId) {
return taskMapper.getStaticCommands(taskId);
}
return StatusChanger.setOriginal(originalState).changeState(newState);
public Integer queryTaskAuditStatus(Long taskId) {
return taskMapper.queryTaskAuditStatus(taskId);
}
public Integer queryTaskStatus(Long taskId) {
return taskMapper.queryTaskStatus(taskId);
}
}

View File

@@ -1,19 +0,0 @@
package com.realtime.protection.server.task.state;
import com.baomidou.dynamic.datasource.annotation.DS;
public class PauseState implements State {
@Override
public Boolean handle(State newState) {
if (newState instanceof RunningState) {
return handleRun();
}
return false;
}
@DS("oracle")
private Boolean handleRun() {
return true;
}
}

View File

@@ -1,28 +0,0 @@
package com.realtime.protection.server.task.state;
public class RunningState implements State {
@Override
public Boolean handle(State newState) {
if (newState instanceof RunningState) {
return false;
}
if (newState instanceof PauseState) {
return handlePause();
}
if (newState instanceof StopState) {
return handleStop();
}
return false;
}
private Boolean handlePause() {
return true;
}
private Boolean handleStop() {
return true;
}
}

View File

@@ -1,6 +0,0 @@
package com.realtime.protection.server.task.state;
public interface State {
Boolean handle(State newState);
}

View File

@@ -1,8 +0,0 @@
package com.realtime.protection.server.task.state;
import com.realtime.protection.configuration.entity.task.Command;
import org.apache.ibatis.annotations.Param;
public interface StateMapper {
Boolean sendCommand(@Param("command") Command command);
}

View File

@@ -1,17 +0,0 @@
package com.realtime.protection.server.task.state;
public class StopState implements State {
@Override
public Boolean handle(State newState) {
if (newState instanceof RunningState) {
return handleRun();
}
return false;
}
public Boolean handleRun() {
return true;
}
}

View File

@@ -0,0 +1,46 @@
package com.realtime.protection.server.task.status;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.realtime.protection.configuration.exception.DorisStartException;
import com.realtime.protection.configuration.utils.enums.StateEnum;
import com.realtime.protection.configuration.utils.status.State;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class StateChangeService {
private final CommandService commandService;
private final TaskService taskService;
public StateChangeService(CommandService commandService, TaskService taskService) {
this.commandService = commandService;
this.taskService = taskService;
}
@DSTransactional
public Boolean changeState(Integer stateNum, Long taskId) throws DorisStartException {
Integer originalStateNum = taskService.queryTaskStatus(taskId);
if (originalStateNum == null) {
throw new IllegalArgumentException("cannot find status of task " + taskId + ", maybe task doesn't exist?");
}
State originalState = StateEnum.getStateByNum(originalStateNum);
State newState = StateEnum.getStateByNum(stateNum);
if (!originalState.handle(newState, commandService, taskService, taskId)) {
return false;
}
log.debug(String.format("successfully let task(%d) change state from %s to %s",
taskId,
originalState.getClass().getSimpleName(),
newState.getClass().getSimpleName()));
// 这里一定是handle成功的状态我们再进行task status的修改如果handle失败要么返回false要么抛出异常不会进入此处
return taskService.changeTaskStatus(taskId, stateNum);
}
}

View File

@@ -0,0 +1,89 @@
package com.realtime.protection.server.task.status;
import com.realtime.protection.configuration.entity.task.Task;
import com.realtime.protection.configuration.entity.task.TaskCommandInfo;
import com.realtime.protection.configuration.exception.DorisStartException;
import com.realtime.protection.configuration.utils.enums.TaskTypeEnum;
import com.realtime.protection.configuration.utils.status.AuditStatus;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.TaskService;
import java.util.List;
public class StateHandler {
protected Boolean handleStart(TaskService taskService, CommandService commandService, Long taskId) throws DorisStartException {
Task task = taskService.queryTask(taskId);
if (task == null) {
throw new IllegalArgumentException("invalid task id");
}
Integer taskAuditStatus = task.getTaskAuditStatus();
if (taskAuditStatus == null) {
throw new IllegalArgumentException("invalid task id, because task_audit_status is null");
}
// 如果审核状态不为已通过审核,则无效
if (taskAuditStatus != AuditStatus.AUDITED.getAuditStatus()) {
return false;
}
return switch (TaskTypeEnum.getTaskTypeByNum(task.getTaskType())) {
case STATIC -> handleStaticTaskStart(commandService, taskService, taskId);
case DYNAMIC -> handleDynamicTaskStart(commandService, taskService, taskId);
case JUDGED -> handleJudgedTaskStart(commandService, taskService, taskId);
};
}
protected Boolean handleResume(CommandService commandService, Long taskId) {
commandService.startCommandsByTaskId(taskId);
return true;
}
protected Boolean handlePause(CommandService commandService, Long taskId) {
commandService.stopCommandsByTaskId(taskId);
return true;
}
protected Boolean handleStop(CommandService commandService, Long taskId) {
commandService.removeCommandsByTaskId(taskId);
return true;
}
protected Boolean handleFinish(CommandService commandService, Long taskId) {
commandService.removeCommandsByTaskId(taskId);
return true;
}
protected Boolean handleFailed(CommandService commandService, Long taskId) {
commandService.removeCommandsByTaskId(taskId);
return true;
}
private Boolean handleJudgedTaskStart(CommandService commandService, TaskService taskService, Long taskId) {
return true;
}
private Boolean handleDynamicTaskStart(CommandService commandService, TaskService taskService, Long taskId) {
return true;
}
private Boolean handleStaticTaskStart(CommandService commandService, TaskService taskService, Long taskId) throws DorisStartException {
// 如果未能获取staticTaskCommandInfos需要报错
List<TaskCommandInfo> staticTaskCommandInfos = taskService.getStaticCommandInfos(taskId);
if (staticTaskCommandInfos == null || staticTaskCommandInfos.isEmpty()) {
throw new IllegalArgumentException("static rules are empty, need to choose at least one static rule");
}
try {
commandService.createCommands(staticTaskCommandInfos);
} catch (DorisStartException e) {
e.taskId = taskId;
throw e;
}
return true;
}
}

View File

@@ -0,0 +1,20 @@
package com.realtime.protection.server.task.status.states;
import com.realtime.protection.configuration.exception.DorisStartException;
import com.realtime.protection.configuration.utils.enums.StateEnum;
import com.realtime.protection.configuration.utils.status.State;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.TaskService;
import com.realtime.protection.server.task.status.StateHandler;
public class FailedState extends StateHandler implements State {
@Override
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) throws DorisStartException {
return switch (StateEnum.getStateEnumByState(newState)) {
case RUNNING -> handleStart(taskService, commandService, taskId);
case STOP -> handleStop(commandService, taskId);
case FAILED -> true;
default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState));
};
}
}

View File

@@ -0,0 +1,12 @@
package com.realtime.protection.server.task.status.states;
import com.realtime.protection.configuration.utils.status.State;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.TaskService;
public class FinishedState implements State {
@Override
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) {
return newState instanceof FinishedState;
}
}

View File

@@ -0,0 +1,20 @@
package com.realtime.protection.server.task.status.states;
import com.realtime.protection.configuration.utils.enums.StateEnum;
import com.realtime.protection.configuration.utils.status.State;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.TaskService;
import com.realtime.protection.server.task.status.StateHandler;
public class PauseState extends StateHandler implements State {
@Override
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) {
return switch (StateEnum.getStateEnumByState(newState)) {
case RUNNING -> handleResume(commandService, taskId);
case STOP -> handleStop(commandService, taskId);
case FINISHED -> handleFinish(commandService, taskId);
case FAILED -> handleFailed(commandService, taskId);
default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState));
};
}
}

View File

@@ -0,0 +1,19 @@
package com.realtime.protection.server.task.status.states;
import com.realtime.protection.configuration.exception.DorisStartException;
import com.realtime.protection.configuration.utils.enums.StateEnum;
import com.realtime.protection.configuration.utils.status.State;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.TaskService;
import com.realtime.protection.server.task.status.StateHandler;
public class PendingState extends StateHandler implements State {
@Override
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) throws DorisStartException {
return switch (StateEnum.getStateEnumByState(newState)) {
case RUNNING -> handleStart(taskService, commandService, taskId);
case FAILED -> handleFailed(commandService, taskId);
default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState));
};
}
}

View File

@@ -0,0 +1,21 @@
package com.realtime.protection.server.task.status.states;
import com.realtime.protection.configuration.utils.enums.StateEnum;
import com.realtime.protection.configuration.utils.status.State;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.TaskService;
import com.realtime.protection.server.task.status.StateHandler;
public class RunningState extends StateHandler implements State {
@Override
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) {
return switch(StateEnum.getStateEnumByState(newState)) {
case RUNNING -> true;
case PAUSED -> handlePause(commandService, taskId);
case STOP -> handleStop(commandService, taskId);
case FINISHED -> handleFinish(commandService, taskId);
case FAILED -> handleFailed(commandService, taskId);
default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState));
};
}
}

View File

@@ -0,0 +1,20 @@
package com.realtime.protection.server.task.status.states;
import com.realtime.protection.configuration.exception.DorisStartException;
import com.realtime.protection.configuration.utils.enums.StateEnum;
import com.realtime.protection.configuration.utils.status.State;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.TaskService;
import com.realtime.protection.server.task.status.StateHandler;
public class StopState extends StateHandler implements State {
@Override
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) throws DorisStartException {
return switch (StateEnum.getStateEnumByState(newState)) {
case RUNNING -> handleStart(taskService, commandService, taskId);
case FAILED -> handleFailed(commandService, taskId);
default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState));
};
}
}