From 81ae46c181176265f115af9abc2263dd06d1e00a Mon Sep 17 00:00:00 2001 From: lijiahang Date: Wed, 13 Mar 2024 14:49:47 +0800 Subject: [PATCH] =?UTF-8?q?:hammer:=20=E6=89=B9=E9=87=8F=E6=89=A7=E8=A1=8C?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/constant/ExtraFieldConst.java | 2 + .../asset/controller/ExecController.java | 24 +++- .../asset/controller/ExecLogController.java | 30 +++++ .../define/operator/ExecOperatorType.java | 10 +- .../request/exec/ExecLogQueryRequest.java | 7 ++ .../asset/entity/vo/ExecLogStatusVO.java | 34 ++++++ .../asset/enums/ExecHostStatusEnum.java | 26 ++++- .../module/asset/enums/ExecStatusEnum.java | 15 ++- .../host/exec/handler/ExecCommandHandler.java | 93 +++++++++------- .../host/exec/handler/ExecTaskHandler.java | 57 ++++++---- .../exec/handler/IExecCommandHandler.java | 15 +++ .../host/exec/handler/IExecTaskHandler.java | 14 +++ .../host/exec/manager/ExecManager.java | 49 +++++++++ .../transfer/handler/TransferHandler.java | 1 + .../module/asset/service/ExecLogService.java | 9 ++ .../ops/module/asset/service/ExecService.java | 12 +- .../service/impl/ExecHostLogServiceImpl.java | 4 + .../service/impl/ExecLogServiceImpl.java | 62 ++++++++++- .../asset/service/impl/ExecServiceImpl.java | 104 +++++++++++++++++- .../service/impl/HostSftpLogServiceImpl.java | 5 +- .../controller/OperatorLogController.java | 1 + 21 files changed, 486 insertions(+), 88 deletions(-) create mode 100644 orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/ExecLogStatusVO.java create mode 100644 orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/manager/ExecManager.java diff --git a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/ExtraFieldConst.java b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/ExtraFieldConst.java index 90eb93ce..ae955d69 100644 --- a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/ExtraFieldConst.java +++ b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/ExtraFieldConst.java @@ -41,4 +41,6 @@ public interface ExtraFieldConst extends FieldConst { String HOST_NAME = "hostName"; + String LOG_ID = "logId"; + } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/ExecController.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/ExecController.java index 91eba4a5..f0467d51 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/ExecController.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/ExecController.java @@ -2,6 +2,7 @@ package com.orion.ops.module.asset.controller; import com.orion.lang.define.wrapper.HttpWrapper; import com.orion.ops.framework.biz.operator.log.core.annotation.OperatorLog; +import com.orion.ops.framework.common.utils.Valid; import com.orion.ops.framework.web.core.annotation.RestWrapper; import com.orion.ops.module.asset.define.operator.ExecOperatorType; import com.orion.ops.module.asset.entity.request.exec.ExecCommandRequest; @@ -47,15 +48,26 @@ public class ExecController { return execService.execCommand(request); } - @OperatorLog(ExecOperatorType.INTERRUPT_COMMAND) - @PostMapping("/interrupt-command") + @OperatorLog(ExecOperatorType.INTERRUPT_EXEC) + @PostMapping("/interrupt") @Operation(summary = "中断执行命令") - @PreAuthorize("@ss.hasPermission('asset:exec:interrupt-command')") - public HttpWrapper interruptCommand(@RequestBody ExecInterruptRequest request) { - execService.interruptCommand(request); + @PreAuthorize("@ss.hasPermission('asset:exec:interrupt-exec')") + public HttpWrapper interruptExec(@RequestBody ExecInterruptRequest request) { + Long logId = Valid.notNull(request.getLogId()); + execService.interruptExec(logId); return HttpWrapper.ok(); } - // log + @OperatorLog(ExecOperatorType.INTERRUPT_HOST) + @PostMapping("/interrupt-host") + @Operation(summary = "中断执行命令") + @PreAuthorize("@ss.hasPermission('asset:exec:interrupt-exec')") + public HttpWrapper interruptHostExec(@RequestBody ExecInterruptRequest request) { + Long hostLogId = Valid.notNull(request.getHostLogId()); + execService.interruptHostExec(hostLogId); + return HttpWrapper.ok(); + } + + // TODO tail log } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/ExecLogController.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/ExecLogController.java index 9f6f0ba7..40da47b4 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/ExecLogController.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/ExecLogController.java @@ -2,6 +2,7 @@ package com.orion.ops.module.asset.controller; import com.orion.lang.define.wrapper.DataGrid; import com.orion.ops.framework.biz.operator.log.core.annotation.OperatorLog; +import com.orion.ops.framework.common.validator.group.Batch; import com.orion.ops.framework.common.validator.group.Page; import com.orion.ops.framework.log.core.annotation.IgnoreLog; import com.orion.ops.framework.log.core.enums.IgnoreLogMode; @@ -9,7 +10,9 @@ import com.orion.ops.framework.web.core.annotation.RestWrapper; import com.orion.ops.module.asset.define.operator.ExecOperatorType; import com.orion.ops.module.asset.entity.request.exec.ExecLogQueryRequest; import com.orion.ops.module.asset.entity.vo.ExecHostLogVO; +import com.orion.ops.module.asset.entity.vo.ExecLogStatusVO; import com.orion.ops.module.asset.entity.vo.ExecLogVO; +import com.orion.ops.module.asset.enums.ExecSourceEnum; import com.orion.ops.module.asset.service.ExecHostLogService; import com.orion.ops.module.asset.service.ExecLogService; import io.swagger.v3.oas.annotations.Operation; @@ -59,6 +62,7 @@ public class ExecLogController { @Operation(summary = "分页查询执行日志") @PreAuthorize("@ss.hasPermission('asset:exec-log:query')") public DataGrid getExecLogPage(@Validated(Page.class) @RequestBody ExecLogQueryRequest request) { + request.setSource(ExecSourceEnum.BATCH.name()); return execLogService.getExecLogPage(request); } @@ -70,6 +74,14 @@ public class ExecLogController { return execHostLogService.getExecHostLogList(logId); } + @IgnoreLog(IgnoreLogMode.RET) + @GetMapping("/status") + @Operation(summary = "查询执行日志状态") + @PreAuthorize("@ss.hasPermission('asset:exec-log:query')") + public ExecLogStatusVO getExecLogStatus(@Validated(Batch.class) @RequestBody ExecLogQueryRequest request) { + return execLogService.getExecLogStatus(request.getIdList()); + } + @OperatorLog(ExecOperatorType.DELETE_LOG) @DeleteMapping("/delete") @Operation(summary = "删除执行日志") @@ -88,6 +100,7 @@ public class ExecLogController { return execLogService.deleteExecLogByIdList(idList); } + @OperatorLog(ExecOperatorType.DELETE_HOST_LOG) @DeleteMapping("/delete-host") @Operation(summary = "删除执行主机日志") @Parameter(name = "id", description = "id", required = true) @@ -96,5 +109,22 @@ public class ExecLogController { return execHostLogService.deleteExecHostLogById(id); } + @PostMapping("/query-count") + @Operation(summary = "查询执行日志数量") + @PreAuthorize("@ss.hasPermission('asset:exec-log:management:clear')") + public Long getExecLogCount(@RequestBody ExecLogQueryRequest request) { + request.setSource(ExecSourceEnum.BATCH.name()); + return execLogService.queryExecLogCount(request); + } + + @OperatorLog(ExecOperatorType.CLEAR_LOG) + @PostMapping("/clear") + @Operation(summary = "清空执行日志") + @PreAuthorize("@ss.hasPermission('asset:exec-log:management:clear')") + public Integer clearExecLog(@RequestBody ExecLogQueryRequest request) { + request.setSource(ExecSourceEnum.BATCH.name()); + return execLogService.clearExecLog(request); + } + } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/operator/ExecOperatorType.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/operator/ExecOperatorType.java index dbf90606..b7682240 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/operator/ExecOperatorType.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/operator/ExecOperatorType.java @@ -19,7 +19,11 @@ public class ExecOperatorType extends InitializingOperatorTypes { public static final String EXEC_COMMAND = "exec:exec-command"; - public static final String INTERRUPT_COMMAND = "exec:interrupt-command"; + public static final String INTERRUPT_EXEC = "exec:interrupt-exec"; + + public static final String INTERRUPT_HOST = "exec:interrupt-host"; + + public static final String DELETE_HOST_LOG = "exec:delete-host-log"; public static final String DELETE_LOG = "exec:delete-log"; @@ -29,7 +33,9 @@ public class ExecOperatorType extends InitializingOperatorTypes { public OperatorType[] types() { return new OperatorType[]{ new OperatorType(M, EXEC_COMMAND, "执行主机命令"), - new OperatorType(M, INTERRUPT_COMMAND, "中断执行命令"), + new OperatorType(M, INTERRUPT_EXEC, "中断执行命令"), + new OperatorType(M, INTERRUPT_HOST, "中断主机执行命令 ${logId} ${hostName}"), + new OperatorType(H, DELETE_HOST_LOG, "删除主机执行日志 ${logId} ${hostName}"), new OperatorType(H, DELETE_LOG, "删除执行日志 ${count} 条"), new OperatorType(H, CLEAR_LOG, "清理执行日志 ${count} 条"), }; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/exec/ExecLogQueryRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/exec/ExecLogQueryRequest.java index 4000bcb6..87f97582 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/exec/ExecLogQueryRequest.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/exec/ExecLogQueryRequest.java @@ -2,11 +2,14 @@ package com.orion.ops.module.asset.entity.request.exec; import com.fasterxml.jackson.annotation.JsonFormat; import com.orion.ops.framework.common.entity.PageRequest; +import com.orion.ops.framework.common.validator.group.Batch; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Size; import java.util.Date; +import java.util.List; /** * 批量执行日志 查询请求对象 @@ -26,6 +29,10 @@ public class ExecLogQueryRequest extends PageRequest { @Schema(description = "id") private Long id; + @NotEmpty(groups = Batch.class) + @Schema(description = "id") + private List idList; + @Schema(description = "执行用户id") private Long userId; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/ExecLogStatusVO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/ExecLogStatusVO.java new file mode 100644 index 00000000..3dcf174a --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/ExecLogStatusVO.java @@ -0,0 +1,34 @@ +package com.orion.ops.module.asset.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 批量执行日志状态 视图响应对象 + * + * @author Jiahang Li + * @version 1.0.1 + * @since 2024-3-11 11:31 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "ExecLogStatusVO", description = "批量执行日志状态 视图响应对象") +public class ExecLogStatusVO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "执行状态列表") + private List logList; + + @Schema(description = "主机状态列表") + private List hostList; + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecHostStatusEnum.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecHostStatusEnum.java index 65628fae..dce4250b 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecHostStatusEnum.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecHostStatusEnum.java @@ -1,5 +1,12 @@ package com.orion.ops.module.asset.enums; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + /** * 批量执行主机状态 * @@ -7,35 +14,44 @@ package com.orion.ops.module.asset.enums; * @version 1.0.0 * @since 2024/3/11 17:08 */ +@Getter +@AllArgsConstructor public enum ExecHostStatusEnum { /** * 等待中 */ - WAITING, + WAITING(true), /** * 执行中 */ - RUNNING, + RUNNING(true), /** * 执行完成 */ - COMPLETED, + COMPLETED(false), /** * 执行失败 */ - FAILED, + FAILED(false), /** * 中断执行 */ - INTERRUPTED, + INTERRUPTED(false), ; + private final boolean closeable; + + public static final List CLOSEABLE_STATUS = Arrays.stream(ExecHostStatusEnum.values()) + .filter(ExecHostStatusEnum::isCloseable) + .map(Enum::name) + .collect(Collectors.toList()); + public static ExecHostStatusEnum of(String status) { if (status == null) { return null; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecStatusEnum.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecStatusEnum.java index f1223ecd..4367595f 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecStatusEnum.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/ExecStatusEnum.java @@ -1,5 +1,8 @@ package com.orion.ops.module.asset.enums; +import lombok.AllArgsConstructor; +import lombok.Getter; + /** * 批量执行状态 * @@ -7,30 +10,34 @@ package com.orion.ops.module.asset.enums; * @version 1.0.0 * @since 2024/3/11 17:08 */ +@Getter +@AllArgsConstructor public enum ExecStatusEnum { /** * 等待中 */ - WAITING, + WAITING(true), /** * 执行中 */ - RUNNING, + RUNNING(true), /** * 执行完成 */ - COMPLETED, + COMPLETED(false), /** * 执行失败 */ - FAILED, + FAILED(false), ; + private final boolean closeable; + public static ExecStatusEnum of(String status) { if (status == null) { return null; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/ExecCommandHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/ExecCommandHandler.java index cca68f82..5370752d 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/ExecCommandHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/ExecCommandHandler.java @@ -15,6 +15,7 @@ import com.orion.ops.module.asset.enums.ExecHostStatusEnum; import com.orion.ops.module.asset.handler.host.exec.dto.ExecCommandHostDTO; import com.orion.ops.module.asset.service.HostTerminalService; import com.orion.spring.SpringHolder; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import java.io.IOException; @@ -39,10 +40,13 @@ public class ExecCommandHandler implements IExecCommandHandler { private final ExecHostLogDAO execHostLogDAO = SpringHolder.getBean(ExecHostLogDAO.class); - private final ExecCommandHostDTO command; + private final ExecCommandHostDTO execHostCommand; private final TimeoutChecker timeoutChecker; + @Getter + private ExecHostStatusEnum status; + private SessionStore sessionStore; private CommandExecutor executor; @@ -53,39 +57,44 @@ public class ExecCommandHandler implements IExecCommandHandler { private volatile boolean interrupted; - public ExecCommandHandler(ExecCommandHostDTO command, TimeoutChecker timeoutChecker) { - this.command = command; + public ExecCommandHandler(ExecCommandHostDTO execHostCommand, TimeoutChecker timeoutChecker) { + this.status = ExecHostStatusEnum.WAITING; + this.execHostCommand = execHostCommand; this.timeoutChecker = timeoutChecker; } @Override public void run() { - Long id = command.getHostLogId(); - log.info("ExecCommandHandler run start id: {}, info: {}", id, JSON.toJSONString(command)); + Long id = execHostCommand.getHostLogId(); + Exception ex = null; + log.info("ExecCommandHandler run start id: {}, info: {}", id, JSON.toJSONString(execHostCommand)); + // 更新状态 + this.updateStatus(ExecHostStatusEnum.RUNNING, null); try { - // 更新状态 - this.updateStatus(ExecHostStatusEnum.RUNNING, null); // 执行命令 this.execCommand(); - if (executor.isTimeout()) { - // 更新状态 - this.updateStatus(ExecHostStatusEnum.FAILED, new TimeoutException()); - } else { - // 更新状态 - this.updateStatus(ExecHostStatusEnum.COMPLETED, null); - } log.info("ExecCommandHandler run complete id: {}", id); } catch (Exception e) { log.error("ExecCommandHandler run error id: {}", id, e); - // TODO - if (this.interrupted) { - this.updateStatus(ExecHostStatusEnum.INTERRUPTED, null); - } else { - this.updateStatus(ExecHostStatusEnum.FAILED, e); - } + ex = e; } finally { Streams.close(this); } + // 执行回调 + if (this.interrupted) { + // TODO 测试 + // 中断执行 + this.updateStatus(ExecHostStatusEnum.INTERRUPTED, null); + } else if (ex != null) { + // 执行失败 + this.updateStatus(ExecHostStatusEnum.FAILED, ex); + } else if (executor.isTimeout()) { + // 更新执行超时 + this.updateStatus(ExecHostStatusEnum.FAILED, new TimeoutException()); + } else { + // 更新执行完成 + this.updateStatus(ExecHostStatusEnum.COMPLETED, null); + } } /** @@ -95,13 +104,12 @@ public class ExecCommandHandler implements IExecCommandHandler { */ private void execCommand() throws Exception { // 打开日志流 - this.logOutputStream = fileClient.getContentOutputStream(command.getLogPath()); + this.logOutputStream = fileClient.getContentOutputStream(execHostCommand.getLogPath()); // 打开会话 - this.sessionStore = hostTerminalService.openSessionStore(command.getHostId()); - this.executor = sessionStore.getCommandExecutor(Strings.replaceCRLF(command.getCommand())); - // TODO 超时 + this.sessionStore = hostTerminalService.openSessionStore(execHostCommand.getHostId()); + this.executor = sessionStore.getCommandExecutor(Strings.replaceCRLF(execHostCommand.getCommand())); // 执行命令 - executor.timeout(command.getTimeout(), TimeUnit.SECONDS, timeoutChecker); + executor.timeout(execHostCommand.getTimeout(), TimeUnit.SECONDS, timeoutChecker); executor.merge(); executor.transfer(logOutputStream); executor.connect(); @@ -115,9 +123,10 @@ public class ExecCommandHandler implements IExecCommandHandler { * @param ex ex */ private void updateStatus(ExecHostStatusEnum status, Exception ex) { - Long id = command.getHostLogId(); + this.status = status; + Long id = execHostCommand.getHostLogId(); String statusName = status.name(); - log.info("ExecCommandHandler.updateStatus id: {}, status: {}", id, statusName); + log.info("ExecCommandHandler.updateStatus start id: {}, status: {}", id, statusName); ExecHostLogDO update = new ExecHostLogDO(); update.setId(id); update.setStatus(statusName); @@ -136,7 +145,8 @@ public class ExecCommandHandler implements IExecCommandHandler { // 中断 update.setFinishTime(new Date()); } - execHostLogDAO.updateById(update); + int effect = execHostLogDAO.updateById(update); + log.info("ExecCommandHandler.updateStatus finish id: {}, effect: {}", id, effect); } @Override @@ -146,6 +156,8 @@ public class ExecCommandHandler implements IExecCommandHandler { @Override public void interrupted() { + log.info("ExecCommandHandler.interrupted id: {}, interrupted: {}, closed: {}", + execHostCommand.getHostLogId(), interrupted, closed); if (this.interrupted || this.closed) { return; } @@ -154,6 +166,20 @@ public class ExecCommandHandler implements IExecCommandHandler { this.close(); } + @Override + public void close() { + log.info("ExecCommandHandler.closed id: {}, closed: {}", + execHostCommand.getHostLogId(), closed); + if (this.closed) { + return; + } + this.closed = true; + Streams.close(executor); + Streams.close(sessionStore); + Streams.close(logOutputStream); + // TODO 关闭日志 + } + /** * 获取错误信息 * @@ -175,15 +201,8 @@ public class ExecCommandHandler implements IExecCommandHandler { } @Override - public void close() { - if (this.closed) { - return; - } - this.closed = true; - Streams.close(executor); - Streams.close(sessionStore); - Streams.close(logOutputStream); - // TODO 关闭日志 + public Long getHostId() { + return execHostCommand.getHostId(); } } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/ExecTaskHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/ExecTaskHandler.java index 34bfca3a..af1e52ac 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/ExecTaskHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/ExecTaskHandler.java @@ -11,7 +11,9 @@ import com.orion.ops.module.asset.entity.domain.ExecLogDO; import com.orion.ops.module.asset.enums.ExecStatusEnum; import com.orion.ops.module.asset.handler.host.exec.dto.ExecCommandDTO; import com.orion.ops.module.asset.handler.host.exec.dto.ExecCommandHostDTO; +import com.orion.ops.module.asset.handler.host.exec.manager.ExecManager; import com.orion.spring.SpringHolder; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import java.util.Date; @@ -30,29 +32,31 @@ public class ExecTaskHandler implements IExecTaskHandler { private static final ExecLogDAO execLogDAO = SpringHolder.getBean(ExecLogDAO.class); - private final ExecCommandDTO command; + private static final ExecManager execManager = SpringHolder.getBean(ExecManager.class); + + private final ExecCommandDTO execCommand; private TimeoutChecker timeoutChecker; - private List handlers; + @Getter + private List handlers; - public ExecTaskHandler(ExecCommandDTO command) { - this.command = command; + public ExecTaskHandler(ExecCommandDTO execCommand) { + this.execCommand = execCommand; this.handlers = Lists.newList(); } - // TODO manager - @Override public void run() { - Long id = command.getLogId(); + Long id = execCommand.getLogId(); + // 添加任务 + execManager.addTask(id, this); log.info("ExecTaskHandler.run start id: {}", id); + // 更新状态 + this.updateStatus(ExecStatusEnum.RUNNING); try { - // TODO 添加 - // 更新状态 - this.updateStatus(ExecStatusEnum.RUNNING); // 执行命令 - this.runHostCommand(command.getHosts()); + this.runHostCommand(execCommand.getHosts()); // 更新状态-执行完成 log.info("ExecTaskHandler.run completed id: {}", id); this.updateStatus(ExecStatusEnum.COMPLETED); @@ -60,12 +64,20 @@ public class ExecTaskHandler implements IExecTaskHandler { // 更新状态-执行失败 this.updateStatus(ExecStatusEnum.FAILED); log.error("ExecTaskHandler.run error id: {}", id, e); - // TODO 移除 } finally { - this.close(); + // 释放资源 + Streams.close(this); + // 移除任务 + execManager.removeTask(id); } } + @Override + public void interrupted() { + log.info("ExecTaskHandler-interrupted id: {}", execCommand.getLogId()); + handlers.forEach(IExecCommandHandler::interrupted); + } + /** * 执行主机命令 * @@ -74,7 +86,7 @@ public class ExecTaskHandler implements IExecTaskHandler { */ private void runHostCommand(List hosts) throws Exception { // 超时检查 - if (command.getTimeout() != 0) { + if (execCommand.getTimeout() != 0) { this.timeoutChecker = TimeoutChecker.create(Const.MS_S_1); AssetThreadPools.TIMEOUT_CHECK.execute(this.timeoutChecker); } @@ -90,11 +102,15 @@ public class ExecTaskHandler implements IExecTaskHandler { } } - - private Integer updateStatus(ExecStatusEnum status) { - Long id = command.getLogId(); + /** + * 更新状态 + * + * @param status status + */ + private void updateStatus(ExecStatusEnum status) { + Long id = execCommand.getLogId(); String statusName = status.name(); - log.info("ExecTaskHandler-updateStatus id: {}, status: {}", id, statusName); + log.info("ExecTaskHandler-updateStatus start id: {}, status: {}", id, statusName); ExecLogDO update = new ExecLogDO(); update.setId(id); update.setStatus(statusName); @@ -108,13 +124,16 @@ public class ExecTaskHandler implements IExecTaskHandler { // 执行失败 update.setFinishTime(new Date()); } - return execLogDAO.updateById(update); + int effect = execLogDAO.updateById(update); + log.info("ExecTaskHandler-updateStatus finish id: {}, effect: {}", id, effect); } @Override public void close() { + log.info("ExecTaskHandler-close id: {}", execCommand.getLogId()); Streams.close(timeoutChecker); this.handlers.forEach(Streams::close); + // TODO 关闭日志 } } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/IExecCommandHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/IExecCommandHandler.java index 55510f3f..4932221d 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/IExecCommandHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/IExecCommandHandler.java @@ -1,6 +1,7 @@ package com.orion.ops.module.asset.handler.host.exec.handler; import com.orion.lang.able.SafeCloseable; +import com.orion.ops.module.asset.enums.ExecHostStatusEnum; /** * 命令执行器定义 @@ -23,4 +24,18 @@ public interface IExecCommandHandler extends Runnable, SafeCloseable { */ void interrupted(); + /** + * 获取当前状态 + * + * @return status + */ + ExecHostStatusEnum getStatus(); + + /** + * 获取主机 id + * + * @return hostId + */ + Long getHostId(); + } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/IExecTaskHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/IExecTaskHandler.java index 5cb36685..d67550b0 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/IExecTaskHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/handler/IExecTaskHandler.java @@ -2,6 +2,8 @@ package com.orion.ops.module.asset.handler.host.exec.handler; import com.orion.lang.able.SafeCloseable; +import java.util.List; + /** * 执行任务处理器 * @@ -11,4 +13,16 @@ import com.orion.lang.able.SafeCloseable; */ public interface IExecTaskHandler extends Runnable, SafeCloseable { + /** + * 获取主机执行器 + * + * @return handlers + */ + List getHandlers(); + + /** + * 中断执行 + */ + void interrupted(); + } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/manager/ExecManager.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/manager/ExecManager.java new file mode 100644 index 00000000..2186c0ac --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/manager/ExecManager.java @@ -0,0 +1,49 @@ +package com.orion.ops.module.asset.handler.host.exec.manager; + +import com.orion.ops.module.asset.handler.host.exec.handler.IExecTaskHandler; +import org.springframework.stereotype.Component; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * 执行管理器 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/3/13 11:20 + */ +@Component +public class ExecManager { + + private final ConcurrentHashMap execTasks = new ConcurrentHashMap<>(); + + /** + * 添加任务 + * + * @param id id + * @param task task + */ + public void addTask(Long id, IExecTaskHandler task) { + execTasks.put(id, task); + } + + /** + * 获取任务 + * + * @param id id + * @return task + */ + public IExecTaskHandler getTask(Long id) { + return execTasks.get(id); + } + + /** + * 移除任务 + * + * @param id id + */ + public void removeTask(Long id) { + execTasks.remove(id); + } + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/transfer/handler/TransferHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/transfer/handler/TransferHandler.java index f6160743..d0d9eea3 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/transfer/handler/TransferHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/transfer/handler/TransferHandler.java @@ -135,6 +135,7 @@ public class TransferHandler implements ITransferHandler { @Override public void close() { + log.info("TransferHandler.close channelId: {}", channel.getId()); sessions.values().forEach(Streams::close); } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/ExecLogService.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/ExecLogService.java index 9b4a5956..536335b9 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/ExecLogService.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/ExecLogService.java @@ -2,6 +2,7 @@ package com.orion.ops.module.asset.service; import com.orion.lang.define.wrapper.DataGrid; import com.orion.ops.module.asset.entity.request.exec.ExecLogQueryRequest; +import com.orion.ops.module.asset.entity.vo.ExecLogStatusVO; import com.orion.ops.module.asset.entity.vo.ExecLogVO; import java.util.List; @@ -31,6 +32,14 @@ public interface ExecLogService { */ DataGrid getExecLogPage(ExecLogQueryRequest request); + /** + * 获取执行日志状态 + * + * @param idList idList + * @return status + */ + ExecLogStatusVO getExecLogStatus(List idList); + /** * 查询批量执行日志数量 * diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/ExecService.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/ExecService.java index 887504dc..9a499071 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/ExecService.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/ExecService.java @@ -1,7 +1,6 @@ package com.orion.ops.module.asset.service; import com.orion.ops.module.asset.entity.request.exec.ExecCommandRequest; -import com.orion.ops.module.asset.entity.request.exec.ExecInterruptRequest; import com.orion.ops.module.asset.entity.vo.ExecVO; /** @@ -24,8 +23,15 @@ public interface ExecService { /** * 中断命令执行 * - * @param request request + * @param logId logId */ - void interruptCommand(ExecInterruptRequest request); + void interruptExec(Long logId); + + /** + * 中断命令执行 + * + * @param hostLogId hostLogId + */ + void interruptHostExec(Long hostLogId); } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecHostLogServiceImpl.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecHostLogServiceImpl.java index b2c49d6c..28419404 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecHostLogServiceImpl.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecHostLogServiceImpl.java @@ -2,6 +2,7 @@ package com.orion.ops.module.asset.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.orion.lang.utils.collect.Lists; +import com.orion.ops.framework.biz.operator.log.core.utils.OperatorLogs; import com.orion.ops.framework.common.constant.ErrorMessage; import com.orion.ops.framework.common.utils.Valid; import com.orion.ops.module.asset.convert.ExecHostLogConvert; @@ -67,6 +68,9 @@ public class ExecHostLogServiceImpl implements ExecHostLogService { // 删除 int effect = execHostLogDAO.deleteById(id); log.info("ExecHostLogService-deleteExecHostLogById id: {}, effect: {}", id, effect); + // 设置日志参数 + OperatorLogs.add(OperatorLogs.LOG_ID, record.getLogId()); + OperatorLogs.add(OperatorLogs.HOST_NAME, record.getHostName()); return effect; } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecLogServiceImpl.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecLogServiceImpl.java index c3433108..a7be646e 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecLogServiceImpl.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecLogServiceImpl.java @@ -4,18 +4,25 @@ import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.orion.lang.define.wrapper.DataGrid; import com.orion.lang.utils.Arrays1; +import com.orion.lang.utils.collect.Lists; import com.orion.ops.framework.biz.operator.log.core.utils.OperatorLogs; import com.orion.ops.framework.common.constant.ErrorMessage; import com.orion.ops.framework.common.utils.Valid; +import com.orion.ops.module.asset.convert.ExecHostLogConvert; import com.orion.ops.module.asset.convert.ExecLogConvert; +import com.orion.ops.module.asset.dao.ExecHostLogDAO; import com.orion.ops.module.asset.dao.ExecLogDAO; +import com.orion.ops.module.asset.entity.domain.ExecHostLogDO; import com.orion.ops.module.asset.entity.domain.ExecLogDO; -import com.orion.ops.module.asset.entity.domain.HostConnectLogDO; import com.orion.ops.module.asset.entity.request.exec.ExecLogQueryRequest; +import com.orion.ops.module.asset.entity.vo.ExecHostLogVO; +import com.orion.ops.module.asset.entity.vo.ExecLogStatusVO; import com.orion.ops.module.asset.entity.vo.ExecLogVO; +import com.orion.ops.module.asset.service.ExecHostLogService; import com.orion.ops.module.asset.service.ExecLogService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.List; @@ -35,6 +42,12 @@ public class ExecLogServiceImpl implements ExecLogService { @Resource private ExecLogDAO execLogDAO; + @Resource + private ExecHostLogDAO execHostLogDAO; + + @Resource + private ExecHostLogService execHostLogService; + @Override public ExecLogVO getExecLogById(Long id) { // 查询 @@ -54,32 +67,71 @@ public class ExecLogServiceImpl implements ExecLogService { .dataGrid(ExecLogConvert.MAPPER::to); } + @Override + public ExecLogStatusVO getExecLogStatus(List idList) { + // 查询执行状态 + List logList = execLogDAO.of() + .createWrapper() + .select(ExecLogDO::getId, ExecLogDO::getStatus, ExecLogDO::getFinishTime) + .in(ExecLogDO::getId, idList) + .then() + .list(ExecLogConvert.MAPPER::to); + // 查询主机状态 + List hostList = execHostLogDAO.of() + .createWrapper() + .select(ExecHostLogDO::getId, + ExecHostLogDO::getStatus, + ExecHostLogDO::getFinishTime, + ExecHostLogDO::getExitStatus, + ExecHostLogDO::getErrorMessage) + .in(ExecHostLogDO::getLogId, idList) + .then() + .list(ExecHostLogConvert.MAPPER::to); + // 返回 + return ExecLogStatusVO.builder() + .logList(logList) + .hostList(hostList) + .build(); + } + @Override public Long queryExecLogCount(ExecLogQueryRequest request) { return execLogDAO.selectCount(this.buildQueryWrapper(request)); } @Override + @Transactional(rollbackFor = Exception.class) public Integer deleteExecLogById(Long id) { log.info("ExecLogService-deleteExecLogById id: {}", id); // 检查数据是否存在 ExecLogDO record = execLogDAO.selectById(id); Valid.notNull(record, ErrorMessage.DATA_ABSENT); - // 删除 + // 删除执行日志 int effect = execLogDAO.deleteById(id); + // 删除主机日志 + execHostLogService.deleteExecHostLogByLogId(Lists.singleton(id)); log.info("ExecLogService-deleteExecLogById id: {}, effect: {}", id, effect); + // 设置日志参数 + OperatorLogs.add(OperatorLogs.COUNT, effect); return effect; } @Override + @Transactional(rollbackFor = Exception.class) public Integer deleteExecLogByIdList(List idList) { log.info("ExecLogService-deleteExecLogByIdList idList: {}", idList); + // 删除执行日志 int effect = execLogDAO.deleteBatchIds(idList); + // 删除主机日志 + execHostLogService.deleteExecHostLogByLogId(idList); log.info("ExecLogService-deleteExecLogByIdList effect: {}", effect); + // 设置日志参数 + OperatorLogs.add(OperatorLogs.COUNT, effect); return effect; } @Override + @Transactional(rollbackFor = Exception.class) public Integer clearExecLog(ExecLogQueryRequest request) { log.info("ExecLogService.clearExecLog start {}", JSON.toJSONString(request)); // 查询 @@ -91,10 +143,10 @@ public class ExecLogServiceImpl implements ExecLogService { .collect(Collectors.toList()); int effect = 0; if (!idList.isEmpty()) { - // 删除 + // 删除执行日志 effect = execLogDAO.delete(wrapper); - - // TODO + // 删除主机日志 + execHostLogService.deleteExecHostLogByLogId(idList); } log.info("ExecLogService.clearExecLog finish {}", effect); // 设置日志参数 diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecServiceImpl.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecServiceImpl.java index f2ec2340..9cfd96af 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecServiceImpl.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecServiceImpl.java @@ -2,6 +2,7 @@ package com.orion.ops.module.asset.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.orion.lang.id.UUIds; import com.orion.lang.utils.Strings; import com.orion.lang.utils.collect.Maps; @@ -23,7 +24,6 @@ import com.orion.ops.module.asset.entity.domain.ExecHostLogDO; import com.orion.ops.module.asset.entity.domain.ExecLogDO; import com.orion.ops.module.asset.entity.domain.HostDO; import com.orion.ops.module.asset.entity.request.exec.ExecCommandRequest; -import com.orion.ops.module.asset.entity.request.exec.ExecInterruptRequest; import com.orion.ops.module.asset.entity.vo.ExecVO; import com.orion.ops.module.asset.enums.ExecHostStatusEnum; import com.orion.ops.module.asset.enums.ExecSourceEnum; @@ -32,6 +32,9 @@ import com.orion.ops.module.asset.enums.HostConfigTypeEnum; import com.orion.ops.module.asset.handler.host.exec.ExecTaskExecutors; import com.orion.ops.module.asset.handler.host.exec.dto.ExecCommandDTO; import com.orion.ops.module.asset.handler.host.exec.dto.ExecCommandHostDTO; +import com.orion.ops.module.asset.handler.host.exec.handler.IExecCommandHandler; +import com.orion.ops.module.asset.handler.host.exec.handler.IExecTaskHandler; +import com.orion.ops.module.asset.handler.host.exec.manager.ExecManager; import com.orion.ops.module.asset.service.AssetAuthorizedDataService; import com.orion.ops.module.asset.service.ExecService; import lombok.extern.slf4j.Slf4j; @@ -74,6 +77,9 @@ public class ExecServiceImpl implements ExecService { @Resource private AssetAuthorizedDataService assetAuthorizedDataService; + @Resource + private ExecManager execManager; + @Override @Transactional(rollbackFor = Exception.class) public ExecVO execCommand(ExecCommandRequest request) { @@ -85,6 +91,7 @@ public class ExecServiceImpl implements ExecService { // 检查主机权限 List authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedHostId(userId, HostConfigTypeEnum.SSH); hostIdList.removeIf(s -> !authorizedHostIdList.contains(s)); + log.info("ExecService.startExecCommand host hostList: {}", hostIdList); Valid.notEmpty(hostIdList, ErrorMessage.CHECK_AUTHORIZED_HOST); List hosts = hostDAO.selectBatchIds(hostIdList); // 插入日志 @@ -100,7 +107,7 @@ public class ExecServiceImpl implements ExecService { execLogDAO.insert(execLog); Long execId = execLog.getId(); // 获取内置参数 - Map builtinsParams = getBaseBuiltinsParams(user, execId, request.getParameter()); + Map builtinsParams = this.getBaseBuiltinsParams(user, execId, request.getParameter()); // 设置主机日志 List execHostLogs = hosts.stream() .map(s -> { @@ -143,8 +150,99 @@ public class ExecServiceImpl implements ExecService { } @Override - public void interruptCommand(ExecInterruptRequest request) { + @Transactional(rollbackFor = Exception.class) + public void interruptExec(Long logId) { + log.info("ExecService.interruptExec start logId: {}", logId); + // 获取执行记录 + ExecLogDO execLog = execLogDAO.selectById(logId); + Valid.notNull(execLog, ErrorMessage.DATA_ABSENT); + // 检查状态 + if (!ExecStatusEnum.of(execLog.getStatus()).isCloseable()) { + return; + } + // 中断执行 + IExecTaskHandler task = execManager.getTask(logId); + if (task != null) { + log.info("ExecService.interruptExec interrupted logId: {}", logId); + // 中断 + task.interrupted(); + } else { + log.info("ExecService.interruptExec updateStatus start logId: {}", logId); + // 不存在则直接修改状态 + ExecLogDO updateExec = new ExecLogDO(); + updateExec.setId(logId); + updateExec.setStatus(ExecStatusEnum.COMPLETED.name()); + updateExec.setFinishTime(new Date()); + int effect = execLogDAO.updateById(updateExec); + // 更新主机状态 + ExecHostLogDO updateHost = new ExecHostLogDO(); + updateHost.setStatus(ExecHostStatusEnum.INTERRUPTED.name()); + updateHost.setFinishTime(new Date()); + LambdaQueryWrapper updateHostWrapper = execHostLogDAO.lambda() + .eq(ExecHostLogDO::getLogId, logId) + .in(ExecHostLogDO::getStatus, ExecHostStatusEnum.CLOSEABLE_STATUS); + effect += execHostLogDAO.update(updateHost, updateHostWrapper); + log.info("ExecService.interruptExec updateStatus finish logId: {}, effect: {}", logId, effect); + } + } + @Override + @Transactional(rollbackFor = Exception.class) + public void interruptHostExec(Long hostLogId) { + log.info("ExecService.interruptHostExec start hostLogId: {}", hostLogId); + // 获取执行记录 + ExecHostLogDO hostLog = execHostLogDAO.selectById(hostLogId); + Valid.notNull(hostLog, ErrorMessage.DATA_ABSENT); + Long logId = hostLog.getLogId(); + // 添加日志参数 + OperatorLogs.add(OperatorLogs.LOG_ID, logId); + OperatorLogs.add(OperatorLogs.HOST_NAME, hostLog.getHostName()); + // 检查状态 + if (!ExecHostStatusEnum.of(hostLog.getStatus()).isCloseable()) { + return; + } + // 中断执行 + IExecTaskHandler task = execManager.getTask(logId); + if (task != null) { + log.info("ExecService.interruptHostExec interrupted logId: {}, hostLogId: {}", logId, hostLogId); + IExecCommandHandler handler = task.getHandlers() + .stream() + .filter(s -> s.getHostId().equals(hostLog.getHostId())) + .findFirst() + .orElse(null); + // 中断 + if (handler != null) { + handler.interrupted(); + } + } else { + log.info("ExecService.interruptHostExec updateStatus start logId: {}, hostLogId: {}", logId, hostLogId); + // 不存在则直接修改状态 + ExecHostLogDO updateHost = new ExecHostLogDO(); + updateHost.setId(hostLogId); + updateHost.setStatus(ExecHostStatusEnum.INTERRUPTED.name()); + updateHost.setFinishTime(new Date()); + int effect = execHostLogDAO.updateById(updateHost); + // 查询执行状态 + ExecLogDO execLog = execLogDAO.selectById(logId); + if (ExecStatusEnum.of(execLog.getStatus()).isCloseable()) { + // 状态可修改则需要检查其他主机任务是否已经完成 + Long closeableCount = execHostLogDAO.of() + .createWrapper() + .eq(ExecHostLogDO::getLogId, logId) + .in(ExecHostLogDO::getStatus, ExecHostStatusEnum.CLOSEABLE_STATUS) + .then() + .count(); + if (closeableCount == 0) { + // 修改任务状态 + ExecLogDO updateExec = new ExecLogDO(); + updateExec.setId(logId); + updateExec.setStatus(ExecStatusEnum.COMPLETED.name()); + updateExec.setFinishTime(new Date()); + effect += execLogDAO.updateById(updateExec); + } + } + log.info("ExecService.interruptHostExec updateStatus finish logId: {}, hostLogId: {}, effect: {}", logId, hostLogId, effect); + } } /** diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostSftpLogServiceImpl.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostSftpLogServiceImpl.java index 0d7c376c..acbc96a0 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostSftpLogServiceImpl.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostSftpLogServiceImpl.java @@ -54,12 +54,9 @@ public class HostSftpLogServiceImpl implements HostSftpLogService { return vo; }).collect(Collectors.toList()); // 返回 - DataGrid result = new DataGrid<>(); - result.setRows(rows); + DataGrid result = new DataGrid<>(rows, dataGrid.getTotal()); result.setPage(dataGrid.getPage()); result.setLimit(dataGrid.getLimit()); - result.setSize(dataGrid.getSize()); - result.setTotal(dataGrid.getTotal()); return result; } diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/OperatorLogController.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/OperatorLogController.java index ee76bc90..e04c9523 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/OperatorLogController.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/OperatorLogController.java @@ -59,6 +59,7 @@ public class OperatorLogController { @PostMapping("/query-count") @Operation(summary = "查询操作日志数量") + @PreAuthorize("@ss.hasPermission('infra:operator-log:clear')") public Long getOperatorLogCount(@RequestBody OperatorLogQueryRequest request) { return operatorLogService.getOperatorLogCount(request); }