diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/HostConnectLogController.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/HostConnectLogController.java index ccdb0a94..1b42485b 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/HostConnectLogController.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/HostConnectLogController.java @@ -49,6 +49,14 @@ public class HostConnectLogController { return hostConnectLogService.getHostConnectLogPage(request); } + @IgnoreLog(IgnoreLogMode.RET) + @PostMapping("/session") + @Operation(summary = "分页查询主机连接会话") + @PreAuthorize("@ss.hasPermission('asset:host-connect-session:management:query')") + public List getHostConnectSessions(@Validated @RequestBody HostConnectLogQueryRequest request) { + return hostConnectLogService.getHostConnectSessions(request); + } + @IgnoreLog(IgnoreLogMode.RET) @PostMapping("/latest-connect") @Operation(summary = "查询用户最近连接的主机") @@ -83,7 +91,7 @@ public class HostConnectLogController { @OperatorLog(HostConnectLogOperatorType.FORCE_OFFLINE) @PutMapping("/force-offline") @Operation(summary = "强制断开主机连接") - @PreAuthorize("@ss.hasPermission('asset:host-connect-log:management:force-offline')") + @PreAuthorize("@ss.hasPermission('asset:host-connect-log:management:force-offline', 'asset:host-connect-session:management:force-offline')") public Integer forceOffline(@Validated(Id.class) @RequestBody HostConnectLogQueryRequest request) { return hostConnectLogService.forceOffline(request); } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/dto/HostTerminalConnectDTO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/dto/HostTerminalConnectDTO.java index 6c12f5e6..37c828f5 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/dto/HostTerminalConnectDTO.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/dto/HostTerminalConnectDTO.java @@ -23,6 +23,9 @@ import lombok.NoArgsConstructor; @Schema(name = "HostTerminalConnectDTO", description = "主机终端连接参数") public class HostTerminalConnectDTO { + @Schema(description = "logId") + private Long logId; + @Schema(description = "连接类型") private String connectType; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostConnectLogQueryRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostConnectLogQueryRequest.java index 9cb62906..ca839977 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostConnectLogQueryRequest.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostConnectLogQueryRequest.java @@ -7,6 +7,7 @@ import lombok.*; import javax.validation.constraints.Size; import java.util.Date; +import java.util.List; /** * 主机连接日志 查询请求对象 @@ -26,6 +27,9 @@ public class HostConnectLogQueryRequest extends PageRequest { @Schema(description = "id") private Long id; + @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/handler/host/terminal/TerminalMessageDispatcher.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/TerminalMessageDispatcher.java index a76dc6a5..4198ae34 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/TerminalMessageDispatcher.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/TerminalMessageDispatcher.java @@ -65,7 +65,7 @@ public class TerminalMessageDispatcher extends AbstractWebSocketHandler { String id = session.getId(); log.info("TerminalMessageDispatcher-afterConnectionClosed id: {}, code: {}, reason: {}", id, status.getCode(), status.getReason()); // 关闭会话 - terminalManager.closeAll(id); + terminalManager.closeSession(id); } } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java index 608d3410..c9ada7e6 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java @@ -75,10 +75,11 @@ public class TerminalCheckHandler extends AbstractTerminalHandler extra = Maps.newMap(4); extra.put(ExtraFieldConst.ERROR_MESSAGE, this.getConnectErrorMessage(e)); - hostConnectLogService.updateStatusByToken(sessionId, HostConnectStatusEnum.FAILED, extra); + hostConnectLogService.updateStatusById(connect.getLogId(), HostConnectStatusEnum.FAILED, extra); } // 返回连接状态 this.send(channel, @@ -108,6 +108,7 @@ public class TerminalConnectHandler extends AbstractTerminalHandler session = channelSessions.remove(channelId); + if (!Maps.isEmpty(session)) { + session.values().forEach(Streams::close); + } + } + + /** + * 通过 channel + sessionId 关闭会话 * * @param channelId channelId * @param sessionId sessionId @@ -71,16 +84,12 @@ public class TerminalManager { } /** - * 关闭全部会话 + * 获取全部会话 * - * @param channelId channelId + * @return session */ - public void closeAll(String channelId) { - // 获取并移除 - ConcurrentHashMap session = channelSessions.remove(channelId); - if (!Maps.isEmpty(session)) { - session.values().forEach(Streams::close); - } + public MultiConcurrentHashMap getChannelSessions() { + return channelSessions; } } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/TerminalConfig.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/TerminalConfig.java index a7ba3298..6305a8e4 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/TerminalConfig.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/TerminalConfig.java @@ -22,6 +22,9 @@ import lombok.NoArgsConstructor; @Schema(name = "TerminalConfig", description = "主机终端连接参数") public class TerminalConfig { + @Schema(description = "logId") + private Long logId; + @Schema(description = "主机id") private Long hostId; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/ITerminalSession.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/ITerminalSession.java index 211bbd4b..b8b9da80 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/ITerminalSession.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/ITerminalSession.java @@ -43,4 +43,11 @@ public interface ITerminalSession extends SafeCloseable { */ void forceOffline(); + /** + * 是否已关闭 + * + * @return closed + */ + boolean isClosed(); + } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/TerminalSession.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/TerminalSession.java index eeada7e2..6f995a93 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/TerminalSession.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/TerminalSession.java @@ -31,6 +31,7 @@ public abstract class TerminalSession implements ITerminalSession { @Getter protected final TerminalConfig config; + @Getter protected volatile boolean closed; protected volatile boolean forceOffline; @@ -68,7 +69,7 @@ public abstract class TerminalSession implements ITerminalSession { if (this.checkAndClose()) { // 修改状态 SpringHolder.getBean(HostConnectLogService.class) - .updateStatusByToken(sessionId, HostConnectStatusEnum.COMPLETE, null); + .updateStatusById(config.getLogId(), HostConnectStatusEnum.COMPLETE, null); } } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/HostConnectLogService.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/HostConnectLogService.java index e1e34585..243316ab 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/HostConnectLogService.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/HostConnectLogService.java @@ -21,12 +21,13 @@ import java.util.concurrent.Future; public interface HostConnectLogService { /** - * 创建 + * 创建主机连接日志 * * @param type type * @param request request + * @return id */ - void create(HostConnectTypeEnum type, HostConnectLogCreateRequest request); + Long create(HostConnectTypeEnum type, HostConnectLogCreateRequest request); /** * 分页查询主机连接日志 @@ -36,15 +37,23 @@ public interface HostConnectLogService { */ DataGrid getHostConnectLogPage(HostConnectLogQueryRequest request); + /** + * 分页查询主机连接会话 + * + * @param request request + * @return rows + */ + List getHostConnectSessions(HostConnectLogQueryRequest request); + /** * 更新连接状态 * - * @param token token + * @param id id * @param status status * @param extra extra * @return effect */ - Integer updateStatusByToken(String token, HostConnectStatusEnum status, Map extra); + Integer updateStatusById(Long id, HostConnectStatusEnum status, Map extra); /** * 查询用户最近连接的主机 diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostConnectLogServiceImpl.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostConnectLogServiceImpl.java index e4195810..e6c063fd 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostConnectLogServiceImpl.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostConnectLogServiceImpl.java @@ -6,6 +6,7 @@ import com.orion.lang.constant.Const; import com.orion.lang.define.wrapper.DataGrid; import com.orion.lang.utils.Arrays1; import com.orion.lang.utils.Valid; +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.security.core.utils.SecurityUtils; @@ -19,6 +20,7 @@ import com.orion.ops.module.asset.entity.vo.HostConnectLogVO; import com.orion.ops.module.asset.enums.HostConnectStatusEnum; import com.orion.ops.module.asset.enums.HostConnectTypeEnum; import com.orion.ops.module.asset.handler.host.terminal.manager.TerminalManager; +import com.orion.ops.module.asset.handler.host.terminal.model.TerminalConfig; import com.orion.ops.module.asset.handler.host.terminal.session.ITerminalSession; import com.orion.ops.module.asset.service.HostConnectLogService; import lombok.extern.slf4j.Slf4j; @@ -26,11 +28,11 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; +import java.util.stream.Collectors; /** * 主机连接日志 服务实现类 @@ -50,7 +52,7 @@ public class HostConnectLogServiceImpl implements HostConnectLogService { private TerminalManager terminalManager; @Override - public void create(HostConnectTypeEnum type, HostConnectLogCreateRequest request) { + public Long create(HostConnectTypeEnum type, HostConnectLogCreateRequest request) { HostConnectLogDO record = HostConnectLogConvert.MAPPER.to(request); record.setType(type.name()); String status = request.getStatus(); @@ -62,6 +64,7 @@ public class HostConnectLogServiceImpl implements HostConnectLogService { record.setEndTime(new Date()); } hostConnectLogDAO.insert(record); + return record.getId(); } @Override @@ -79,17 +82,47 @@ public class HostConnectLogServiceImpl implements HostConnectLogService { } @Override - public Integer updateStatusByToken(String token, HostConnectStatusEnum status, Map partial) { - log.info("HostConnectLogService-updateStatusByToken start token: {}, status: {}", token, status); + public List getHostConnectSessions(HostConnectLogQueryRequest request) { + // 查询全部 + List idList = terminalManager.getChannelSessions() + .values() + .stream() + .map(ConcurrentHashMap::values) + .flatMap(Collection::stream) + .filter(s -> !s.isClosed()) + .map(ITerminalSession::getConfig) + .filter(Objects::nonNull) + .map(TerminalConfig::getLogId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (idList.isEmpty()) { + return Lists.empty(); + } + // 条件 + request.setIdList(idList); + request.setStatus(HostConnectStatusEnum.CONNECTING.name()); + LambdaQueryWrapper wrapper = this.buildQueryWrapper(request); + // 查询 + return hostConnectLogDAO.of(wrapper) + .list(s -> { + HostConnectLogVO vo = HostConnectLogConvert.MAPPER.to(s); + vo.setExtra(JSON.parseObject(s.getExtraInfo(), HostConnectLogExtraDTO.class)); + return vo; + }); + } + + @Override + public Integer updateStatusById(Long id, HostConnectStatusEnum status, Map partial) { + log.info("HostConnectLogService-updateStatusByToken start id: {}, status: {}", id, status); // 查询 HostConnectLogDO record = hostConnectLogDAO.of() .createWrapper() - .eq(HostConnectLogDO::getToken, token) + .eq(HostConnectLogDO::getId, id) .orderByDesc(HostConnectLogDO::getId) .then() .getOne(); if (record == null) { - log.info("HostConnectLogService-updateStatusByToken no record token: {}", token); + log.info("HostConnectLogService-updateStatusByToken no record id: {}", id); return Const.N_0; } return this.updateStatus(record, status, partial); @@ -189,6 +222,7 @@ public class HostConnectLogServiceImpl implements HostConnectLogService { private LambdaQueryWrapper buildQueryWrapper(HostConnectLogQueryRequest request) { return hostConnectLogDAO.wrapper() .eq(HostConnectLogDO::getId, request.getId()) + .in(HostConnectLogDO::getId, request.getIdList()) .eq(HostConnectLogDO::getUserId, request.getUserId()) .eq(HostConnectLogDO::getHostId, request.getHostId()) .like(HostConnectLogDO::getHostAddress, request.getHostAddress())