summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshizhendong <[email protected]>2023-02-16 17:04:10 +0800
committershizhendong <[email protected]>2023-02-16 17:04:10 +0800
commitba07487a5b205b5ee968c03c48892a8ce4420306 (patch)
tree3ea5cf7a872f5128b9217497a5917de11ab0a882
parentb2281166c2b12a2064c8710c42981528c625e696 (diff)
fix: NEZ-2541 修复 terminal 复制会话异常问题
1. 参考 XShell,修复会话改为使用账号信息重新登录方式 2. 解决关闭 websocket 时,terminal session 状态更新异常问题
-rw-r--r--nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalHandler.java34
-rw-r--r--nz-admin/src/main/java/com/nis/modules/terminal/service/impl/TerminalSessionServiceImpl.java55
-rw-r--r--nz-common/src/main/java/com/nis/common/utils/RCode.java1
3 files changed, 74 insertions, 16 deletions
diff --git a/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalHandler.java b/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalHandler.java
index 1d2af4e2..2e1c5c3f 100644
--- a/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalHandler.java
+++ b/nz-admin/src/main/java/com/nis/modules/terminal/backend/TerminalHandler.java
@@ -296,40 +296,54 @@ public class TerminalHandler extends TextWebSocketHandler {
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
try {
- log.info("Connection Closed. process terminal related information begin...");
+ log.info("[afterConnectionClosed] [WebSocket connection closed] [websocket uri: {}]", session.getUri());
super.afterConnectionClosed(session, status);
+
+ TerminalClient terminalClient = TerminalSession.TERMINAL_SESSION.get(session);
+ log.info("[afterConnectionClosed] [Close terminal client connection] [clientId: {}]", ObjectUtil.isNull(terminalClient) ? null : terminalClient.getClientId());
+ if (ObjectUtil.isNull(terminalClient)) {
+ log.warn("[afterConnectionClosed] [failed to get terminal client through websocket connection.] [websocket uri: {}]", session.getUri());
+ return;
+ }
+
+ // close terminal
this.closeTerminal(session);
+ // client id
+ String clientId = terminalClient.getClientId();
+
// client 关闭后,处理 session 和 record 信息
- TerminalSessionEntity sessionEntity = (TerminalSessionEntity) TerminalSession.getTerminalAttributeInfo(uuid).get("terminalSessionEntity");
+ TerminalSessionEntity sessionEntity = (TerminalSessionEntity) TerminalSession.getTerminalAttributeInfo(clientId).get("terminalSessionEntity");
if (Tool.ObjectUtil.isNotNull(sessionEntity)) {
+ log.info("[afterConnectionClosed] [udpate session status] [session id: {}] [status: {}]", sessionEntity.getUuid(), sessionEntity.getStatus());
// 正常连接状态 关闭窗口,将状态改为 已结束,其他不做处理
if (TerminalConstant.SessionStatus.CONNECTING.getValue() == sessionEntity.getStatus()) {
sessionEntity.setStatus(TerminalConstant.SessionStatus.OVER.getValue());
}
sessionEntity.setEndTime(new Date());
-
- log.info("Connection Closed, udpate session status is over. session id: {}, entity info: {}", uuid, JSONUtil.toJsonStr(sessionEntity));
terminalSessionService.saveOrUpdate(sessionEntity);
// save Record Content After Client Closed
- TerminalHandler.saveRecordContentAfterClientClosed(uuid);
+ TerminalHandler.saveRecordContentAfterClientClosed(clientId);
+ } else {
+ log.warn("[afterConnectionClosed] [not found TerminalSessionEntity through client id.] [clientId: {}]", clientId);
}
// remove Terminal Attribute Info
- TerminalSession.removeTerminalAttributeInfo(uuid);
+ TerminalSession.removeTerminalAttributeInfo(clientId);
// monitor terminal session
- List<WebSocketSession> monitorWebSocketSessions = TerminalSession.TERMINAL_MONITORS_MAPPING.get(uuid);
+ List<WebSocketSession> monitorWebSocketSessions = TerminalSession.TERMINAL_MONITORS_MAPPING.get(clientId);
if (Tool.CollUtil.isNotEmpty(monitorWebSocketSessions)) {
+ log.info("[afterConnectionClosed] [close monitor windows] [size: {}]", monitorWebSocketSessions.size());
for (WebSocketSession socketSession : monitorWebSocketSessions) {
socketSession.sendMessage(new TextMessage("\u001B[01;31m\u001B[KConnection closed \u001B[m\u001B[K"));
}
- TerminalSession.TERMINAL_MONITORS_MAPPING.remove(uuid);
+ TerminalSession.TERMINAL_MONITORS_MAPPING.remove(clientId);
}
- log.info("Connection Closed finished.");
+ log.info("[afterConnectionClosed] [close resource finshed.] [clientId: {}]", clientId);
} catch (Exception e) {
- log.error(e, "Connection Closed error. session: {}, status: {}", session, status.toString());
+ log.error(e, "[afterConnectionClosed] [error] [session: {}] [status: {}]", JSONUtil.toJsonStr(session), JSONUtil.toJsonStr(status));
throw e;
}
}
diff --git a/nz-admin/src/main/java/com/nis/modules/terminal/service/impl/TerminalSessionServiceImpl.java b/nz-admin/src/main/java/com/nis/modules/terminal/service/impl/TerminalSessionServiceImpl.java
index 98c23bfa..9b9913fc 100644
--- a/nz-admin/src/main/java/com/nis/modules/terminal/service/impl/TerminalSessionServiceImpl.java
+++ b/nz-admin/src/main/java/com/nis/modules/terminal/service/impl/TerminalSessionServiceImpl.java
@@ -657,14 +657,57 @@ public class TerminalSessionServiceImpl extends ServiceImpl<TerminalSessionDao,
String duplicateSessionUUID = StrUtil.uuid();
log.info("[duplicateSession] [source session exists. duplicate session info] [source uuid: {}] [duplicate uuid: {}]", uuid, duplicateSessionUUID);
- // duplicate session
- TerminalSession.TERMINAL_CONNECTED_CACHE.put(duplicateSessionUUID, connObjMap);
-
- // connected last active time
- TerminalSession.TERMINAL_CONNECTED_LAST_ACTIVE_MAP.put(uuid, Tool.DateUtil.currentSeconds());
-
// terminal Connection Info
AssetAsset terminalConnInfo = (AssetAsset) connObjMap.get(TerminalSession.CONNECTION_ASSET_KEY);
+ log.info("[duplicateSession] [duplicate session source information] [asset: {}]", JSONUtil.toJsonStr(terminalConnInfo));
+
+ // SSH
+ if (TerminalConstant.ProtocolType.SSH.getValue().equals(terminalConnInfo.getAuthProtocol())) {
+ try {
+ log.info("[duplicateSession] [reopen SSH connection begin.] [duplicate uuid: {}]", duplicateSessionUUID);
+ Session session = SshUtil.getSshConnection(terminalConnInfo);
+ TerminalSession.TERMINAL_CONNECTED_CACHE.put(duplicateSessionUUID,
+ Tool.MapUtil.builder()
+ .put(TerminalSession.CONNECTION_ASSET_KEY, terminalConnInfo)
+ .put(TerminalSession.CONNECTION_CONNECTION_ENTITY_KEY, session)
+ .map());
+ TerminalSession.TERMINAL_CONNECTED_LAST_ACTIVE_MAP.put(duplicateSessionUUID, Tool.DateUtil.currentSeconds());
+ log.info("[duplicateSession] [reopen SSH connection success.] [duplicate uuid: {}]", duplicateSessionUUID);
+ } catch (Exception e) {
+ log.error(e, "[duplicateSession] [reopen SSH connection error.] [duplicate uuid: {}]", duplicateSessionUUID);
+ throw new NZException(RCode.TERMINAL_DUPLICATE_SESSION_FAILED);
+ }
+ }
+
+ // TELNET
+ if (TerminalConstant.ProtocolType.TELNET.getValue().equals(terminalConnInfo.getAuthProtocol())) {
+ try {
+ log.info("[duplicateSession] [reopen TELNET connection begin.] [duplicate uuid: {}]", duplicateSessionUUID);
+ TelnetUtil telnetUtil = new TelnetUtil();
+ telnetUtil.connect(terminalConnInfo.getManageIp(), terminalConnInfo.getAuthProtocolPort());
+ List<SysConfigEntity> configList = sysConfService.list(new LambdaQueryWrapper<SysConfigEntity>().in(SysConfigEntity::getParamKey, "terminal_telnet_user_tip", "terminal_telnet_pin_tip"));
+ Map<String, String> systemTipConfigMap = configList.stream().collect(Collectors.toMap(SysConfigEntity::getParamKey, SysConfigEntity::getParamValue));
+
+ String authUserTip = TelnetUtil.getTelenetLoginTip(terminalConnInfo.getAuthUserTip(), systemTipConfigMap, "terminal_telnet_user_tip");
+ String authPinTip = TelnetUtil.getTelenetLoginTip(terminalConnInfo.getAuthPinTip(), systemTipConfigMap, "terminal_telnet_pin_tip");
+ boolean isLogin = telnetUtil.login(terminalConnInfo.getAuthUsername(), StringUtils.str(Base64.getDecoder().decode(terminalConnInfo.getAuthPin())), authUserTip, authPinTip);
+ if (isLogin) {
+ TerminalSession.TERMINAL_CONNECTED_CACHE.put(duplicateSessionUUID,
+ Tool.MapUtil.builder()
+ .put(TerminalSession.CONNECTION_ASSET_KEY, terminalConnInfo)
+ .put(TerminalSession.CONNECTION_CONNECTION_ENTITY_KEY, telnetUtil.getTelnetClient())
+ .map());
+ TerminalSession.TERMINAL_CONNECTED_LAST_ACTIVE_MAP.put(duplicateSessionUUID, Tool.DateUtil.currentSeconds());
+ log.info("[duplicateSession] [reopen TELNET connection success.] [duplicate uuid: {}]", duplicateSessionUUID);
+ } else {
+ log.warn("[duplicateSession] [reopen TELNET connection error.] [duplicate uuid: {}]", duplicateSessionUUID);
+ throw new NZException(RCode.TERMINAL_DUPLICATE_SESSION_FAILED);
+ }
+ } catch (Exception e) {
+ log.error(e, "[duplicateSession] [reopen TELNET connection error.] [duplicate uuid: {}]", duplicateSessionUUID);
+ throw new NZException(RCode.TERMINAL_DUPLICATE_SESSION_FAILED);
+ }
+ }
// return duplicate session map
Map<Object, Object> duplicateSessionMap = Tool.MapUtil.builder()
diff --git a/nz-common/src/main/java/com/nis/common/utils/RCode.java b/nz-common/src/main/java/com/nis/common/utils/RCode.java
index ac69edc0..87e1c613 100644
--- a/nz-common/src/main/java/com/nis/common/utils/RCode.java
+++ b/nz-common/src/main/java/com/nis/common/utils/RCode.java
@@ -831,6 +831,7 @@ public enum RCode {
TERMINAL_NEW_PATH_ISNULL(611021, "File new path cannot be empty"),
TERMINAL_MKDIR_DIR_ALREADY_EXISTS(612022, "The specified file name already exists, please enter another name."),
TERMINAL_LS_FOLDER_ERROR(616023, "Cannot display remote folder"),
+ TERMINAL_DUPLICATE_SESSION_FAILED(618024, "Duplicate session failed."),
/**
* LINK