🔨 批量执行.
This commit is contained in:
@@ -41,4 +41,6 @@ public interface ExtraFieldConst extends FieldConst {
|
||||
|
||||
String HOST_NAME = "hostName";
|
||||
|
||||
String LOG_ID = "logId";
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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<ExecLogVO> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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} 条"),
|
||||
};
|
||||
|
||||
@@ -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<Long> idList;
|
||||
|
||||
@Schema(description = "执行用户id")
|
||||
private Long userId;
|
||||
|
||||
|
||||
@@ -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<ExecLogVO> logList;
|
||||
|
||||
@Schema(description = "主机状态列表")
|
||||
private List<ExecHostLogVO> hostList;
|
||||
|
||||
}
|
||||
@@ -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<String> 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<ExecCommandHandler> handlers;
|
||||
@Getter
|
||||
private List<IExecCommandHandler> 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<ExecCommandHostDTO> 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 关闭日志
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
@@ -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<IExecCommandHandler> getHandlers();
|
||||
|
||||
/**
|
||||
* 中断执行
|
||||
*/
|
||||
void interrupted();
|
||||
|
||||
}
|
||||
|
||||
@@ -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<Long, IExecTaskHandler> 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<ExecLogVO> getExecLogPage(ExecLogQueryRequest request);
|
||||
|
||||
/**
|
||||
* 获取执行日志状态
|
||||
*
|
||||
* @param idList idList
|
||||
* @return status
|
||||
*/
|
||||
ExecLogStatusVO getExecLogStatus(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 查询批量执行日志数量
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Long> idList) {
|
||||
// 查询执行状态
|
||||
List<ExecLogVO> logList = execLogDAO.of()
|
||||
.createWrapper()
|
||||
.select(ExecLogDO::getId, ExecLogDO::getStatus, ExecLogDO::getFinishTime)
|
||||
.in(ExecLogDO::getId, idList)
|
||||
.then()
|
||||
.list(ExecLogConvert.MAPPER::to);
|
||||
// 查询主机状态
|
||||
List<ExecHostLogVO> 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<Long> 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);
|
||||
// 设置日志参数
|
||||
|
||||
@@ -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<Long> 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<HostDO> hosts = hostDAO.selectBatchIds(hostIdList);
|
||||
// 插入日志
|
||||
@@ -100,7 +107,7 @@ public class ExecServiceImpl implements ExecService {
|
||||
execLogDAO.insert(execLog);
|
||||
Long execId = execLog.getId();
|
||||
// 获取内置参数
|
||||
Map<String, Object> builtinsParams = getBaseBuiltinsParams(user, execId, request.getParameter());
|
||||
Map<String, Object> builtinsParams = this.getBaseBuiltinsParams(user, execId, request.getParameter());
|
||||
// 设置主机日志
|
||||
List<ExecHostLogDO> 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<ExecHostLogDO> 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,12 +54,9 @@ public class HostSftpLogServiceImpl implements HostSftpLogService {
|
||||
return vo;
|
||||
}).collect(Collectors.toList());
|
||||
// 返回
|
||||
DataGrid<HostSftpLogVO> result = new DataGrid<>();
|
||||
result.setRows(rows);
|
||||
DataGrid<HostSftpLogVO> result = new DataGrid<>(rows, dataGrid.getTotal());
|
||||
result.setPage(dataGrid.getPage());
|
||||
result.setLimit(dataGrid.getLimit());
|
||||
result.setSize(dataGrid.getSize());
|
||||
result.setTotal(dataGrid.getTotal());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user