🔨 优化执行日志查看逻辑.

This commit is contained in:
lijiahang
2025-02-05 10:16:12 +08:00
parent 89f6d2cd1c
commit 972103841c
9 changed files with 222 additions and 211 deletions

View File

@@ -22,13 +22,11 @@
*/ */
package org.dromara.visor.module.asset.handler.host.exec.log; package org.dromara.visor.module.asset.handler.host.exec.log;
import cn.orionsec.kit.lang.annotation.Keep; import cn.orionsec.kit.lang.utils.Strings;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.ExtraFieldConst; import org.dromara.visor.common.constant.ExtraFieldConst;
import org.dromara.visor.common.interfaces.FileClient;
import org.dromara.visor.framework.websocket.core.utils.WebSockets; import org.dromara.visor.framework.websocket.core.utils.WebSockets;
import org.dromara.visor.module.asset.define.AssetThreadPools; import org.dromara.visor.module.asset.define.AssetThreadPools;
import org.dromara.visor.module.asset.entity.dto.ExecHostLogTailDTO;
import org.dromara.visor.module.asset.entity.dto.ExecLogTailDTO; import org.dromara.visor.module.asset.entity.dto.ExecLogTailDTO;
import org.dromara.visor.module.asset.handler.host.exec.log.constant.LogConst; import org.dromara.visor.module.asset.handler.host.exec.log.constant.LogConst;
import org.dromara.visor.module.asset.handler.host.exec.log.manager.ExecLogManager; import org.dromara.visor.module.asset.handler.host.exec.log.manager.ExecLogManager;
@@ -52,41 +50,27 @@ import javax.annotation.Resource;
@Component @Component
public class ExecLogTailHandler extends AbstractWebSocketHandler { public class ExecLogTailHandler extends AbstractWebSocketHandler {
@Keep
@Resource
private FileClient logsFileClient;
@Resource @Resource
private ExecLogManager execLogManager; private ExecLogManager execLogManager;
@Override @Override
public void afterConnectionEstablished(WebSocketSession session) { protected void handleTextMessage(WebSocketSession session, TextMessage message) {
String id = session.getId(); String id = session.getId();
log.info("ExecLogTailHandler-afterConnectionEstablished id: {}", id); String payload = message.getPayload();
// 获取参数 if (LogConst.PING_PAYLOAD.equals(payload)) {
ExecLogTailDTO info = WebSockets.getAttr(session, ExtraFieldConst.INFO); // ping
// 打开会话 WebSockets.sendText(session, LogConst.PONG_PAYLOAD);
for (ExecHostLogTailDTO host : info.getHosts()) { } else if (Strings.isInteger(payload)) {
String trackerId = this.getTrackerId(id, info, host); // 获取日志
String absolutePath = logsFileClient.getAbsolutePath(host.getPath()); ExecLogTailDTO info = WebSockets.getAttr(session, ExtraFieldConst.INFO);
// 追踪器 Long execHostId = Long.valueOf(payload);
ExecLogTracker tracker = new ExecLogTracker(trackerId, ExecLogTracker tracker = new ExecLogTracker(info.getExecId(),
absolutePath, execHostId,
WebSockets.createSyncSession(session), WebSockets.createSyncSession(session));
host); // 执行追踪器
// 执行
AssetThreadPools.EXEC_LOG.execute(tracker); AssetThreadPools.EXEC_LOG.execute(tracker);
// 添加追踪器 // 添加追踪器
execLogManager.addTracker(tracker); execLogManager.addTracker(id, tracker);
}
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
String payload = message.getPayload();
// ping
if (LogConst.PING_PAYLOAD.equals(payload)) {
WebSockets.sendText(session, LogConst.PONG_PAYLOAD);
} }
} }
@@ -99,24 +83,8 @@ public class ExecLogTailHandler extends AbstractWebSocketHandler {
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
String id = session.getId(); String id = session.getId();
log.info("ExecLogTailHandler-afterConnectionClosed id: {}, code: {}, reason: {}", id, status.getCode(), status.getReason()); log.info("ExecLogTailHandler-afterConnectionClosed id: {}, code: {}, reason: {}", id, status.getCode(), status.getReason());
// 关闭会话
ExecLogTailDTO info = WebSockets.getAttr(session, ExtraFieldConst.INFO);
// 移除追踪器 // 移除追踪器
for (ExecHostLogTailDTO host : info.getHosts()) { execLogManager.removeTrackers(id);
execLogManager.removeTracker(this.getTrackerId(id, info, host));
}
}
/**
* 获取追踪器 id
*
* @param id id
* @param info info
* @param host host
* @return trackerId
*/
private String getTrackerId(String id, ExecLogTailDTO info, ExecHostLogTailDTO host) {
return id + "_" + info.getId() + "_" + host.getId();
} }
} }

View File

@@ -28,6 +28,8 @@ import org.dromara.visor.common.constant.Const;
import org.dromara.visor.module.asset.handler.host.exec.log.tracker.IExecLogTracker; import org.dromara.visor.module.asset.handler.host.exec.log.tracker.IExecLogTracker;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -43,61 +45,58 @@ import java.util.stream.Collectors;
@Component @Component
public class ExecLogManager { public class ExecLogManager {
private final ConcurrentHashMap<String, IExecLogTracker> execTrackers = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, List<IExecLogTracker>> execTrackers = new ConcurrentHashMap<>();
/** /**
* 添加执行日志追踪器 * 添加执行日志追踪器
* *
* @param id id
* @param tracker tracker * @param tracker tracker
*/ */
public void addTracker(IExecLogTracker tracker) { public void addTracker(String id, IExecLogTracker tracker) {
execTrackers.put(tracker.getTrackerId(), tracker); execTrackers.computeIfAbsent(id, k -> new ArrayList<>()).add(tracker);
}
/**
* 获取日志追踪器
*
* @param trackerId trackerId
* @return tracker
*/
public IExecLogTracker getTracker(String trackerId) {
return execTrackers.get(trackerId);
} }
/** /**
* 移除日志追踪器 * 移除日志追踪器
* *
* @param trackerId trackerId * @param id id
*/ */
public void removeTracker(String trackerId) { public void removeTrackers(String id) {
IExecLogTracker tracker = execTrackers.remove(trackerId); // 移除并且关闭
if (tracker != null) { List<IExecLogTracker> trackers = execTrackers.remove(id);
tracker.close(); if (trackers != null) {
trackers.forEach(IExecLogTracker::close);
} }
} }
/** /**
* 异步关闭进行中的追踪器 * 异步关闭进行中的追踪器
* *
* @param path path * @param execHostId execHostId
*/ */
public void asyncCloseTailFile(String path) { public void asyncCloseTailFile(Long execHostId) {
if (path == null) { if (execHostId == null) {
return; return;
} }
// 获取当前路径的全部追踪器
List<IExecLogTracker> trackers = execTrackers.values()
.stream()
.flatMap(Collection::stream)
.filter(s -> s.getExecHostId().equals(execHostId))
.collect(Collectors.toList());
if (trackers.isEmpty()) {
return;
}
// 异步设置更新并且关闭
Threads.start(() -> { Threads.start(() -> {
try { try {
// 获取当前路径的全部追踪器
List<IExecLogTracker> trackers = execTrackers.values()
.stream()
.filter(s -> s.getPath().equals(path))
.collect(Collectors.toList());
Threads.sleep(Const.MS_S_1); Threads.sleep(Const.MS_S_1);
trackers.forEach(IExecLogTracker::setLastModify); trackers.forEach(IExecLogTracker::setLastModify);
Threads.sleep(Const.MS_S_5); Threads.sleep(Const.MS_S_5);
trackers.forEach(IExecLogTracker::close); trackers.forEach(IExecLogTracker::close);
} catch (Exception e) { } catch (Exception e) {
log.error("ExecLogManager.asyncCloseTailFile error path: {}", path, e); log.error("ExecLogManager.asyncCloseTailFile error execHostId: {}", execHostId, e);
} }
}); });
} }

View File

@@ -26,16 +26,32 @@ import cn.orionsec.kit.ext.tail.Tracker;
import cn.orionsec.kit.ext.tail.delay.DelayTrackerListener; import cn.orionsec.kit.ext.tail.delay.DelayTrackerListener;
import cn.orionsec.kit.ext.tail.mode.FileNotFoundMode; import cn.orionsec.kit.ext.tail.mode.FileNotFoundMode;
import cn.orionsec.kit.ext.tail.mode.FileOffsetMode; import cn.orionsec.kit.ext.tail.mode.FileOffsetMode;
import cn.orionsec.kit.lang.exception.argument.InvalidArgumentException;
import cn.orionsec.kit.lang.utils.Charsets;
import cn.orionsec.kit.lang.utils.io.FileReaders;
import cn.orionsec.kit.lang.utils.io.Files1;
import cn.orionsec.kit.lang.utils.io.Streams;
import cn.orionsec.kit.spring.SpringHolder; import cn.orionsec.kit.spring.SpringHolder;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import org.dromara.visor.common.constant.ErrorMessage;
import org.dromara.visor.common.interfaces.FileClient;
import org.dromara.visor.common.utils.Valid;
import org.dromara.visor.framework.websocket.core.utils.WebSockets; import org.dromara.visor.framework.websocket.core.utils.WebSockets;
import org.dromara.visor.module.asset.dao.ExecHostLogDAO;
import org.dromara.visor.module.asset.define.config.AppLogConfig; import org.dromara.visor.module.asset.define.config.AppLogConfig;
import org.dromara.visor.module.asset.entity.dto.ExecHostLogTailDTO; import org.dromara.visor.module.asset.entity.domain.ExecHostLogDO;
import org.dromara.visor.module.asset.enums.ExecHostStatusEnum;
import org.dromara.visor.module.asset.handler.host.exec.log.constant.LogConst; import org.dromara.visor.module.asset.handler.host.exec.log.constant.LogConst;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.Charset;
/** /**
* log tracker 实现类 * log tracker 实现类
* *
@@ -48,76 +64,166 @@ public class ExecLogTracker implements IExecLogTracker {
private static final AppLogConfig appLogConfig = SpringHolder.getBean(AppLogConfig.class); private static final AppLogConfig appLogConfig = SpringHolder.getBean(AppLogConfig.class);
private static final FileClient localFileClient = SpringHolder.getBean("localFileClient");
private static final ExecHostLogDAO execHostLogDAO = SpringHolder.getBean(ExecHostLogDAO.class);
private final WebSocketSession session; private final WebSocketSession session;
private final ExecHostLogTailDTO config; @Getter
private final Long execId;
@Getter @Getter
private final String trackerId; private final Long execHostId;
@Getter private Charset charset;
private final String absolutePath;
private String absolutePath;
private ExecHostLogDO execHostLog;
private RandomAccessFile file;
private DelayTrackerListener tracker; private DelayTrackerListener tracker;
private volatile boolean close; private volatile boolean close;
public ExecLogTracker(String trackerId, public ExecLogTracker(Long execId,
String absolutePath, Long execHostId,
WebSocketSession session, WebSocketSession session) {
ExecHostLogTailDTO config) { this.execId = execId;
this.trackerId = trackerId; this.execHostId = execHostId;
this.absolutePath = absolutePath;
this.session = session; this.session = session;
this.config = config;
} }
@Override @Override
public void run() { public void run() {
try { try {
this.tracker = new DelayTrackerListener(absolutePath, this); // 初始化数据
tracker.charset(config.getCharset()); this.initData();
tracker.delayMillis(appLogConfig.getTrackerDelay()); // 查看日志
tracker.offset(FileOffsetMode.LINE, appLogConfig.getTrackerOffset()); if (ExecHostStatusEnum.RUNNING.name().equals(execHostLog.getStatus())) {
tracker.notFoundMode(FileNotFoundMode.WAIT_COUNT, Const.N_10); // 追踪文件
// 开始监听文件 this.tailFile();
tracker.run(); } else {
// 直接读取文件
this.readFile();
}
} catch (InvalidArgumentException e) {
// 业务异常
log.error("exec log tracker init error id: {}", execHostId, e);
// 发送消息
this.sendMessage(e.getMessage());
} catch (Exception e) { } catch (Exception e) {
log.error("exec log tracker error path: {}", absolutePath, e); log.error("exec log tracker exec error id: {}", execHostId, e);
} finally { } finally {
// 释放资源 // 释放资源
this.close(); this.close();
} }
} }
@Override /**
public void setLastModify() { * 初始化数据
tracker.setFileLastModifyTime(); */
private void initData() {
// 读取数据
this.execHostLog = execHostLogDAO.selectByIdAndLogId(execHostId, execId);
Valid.notNull(execHostLog, ErrorMessage.DATA_ABSENT);
// 检查任务状态
Valid.neq(execHostLog.getStatus(), ExecHostStatusEnum.WAITING.name(), ErrorMessage.ILLEGAL_STATUS);
// 获取文件路径
this.absolutePath = localFileClient.getAbsolutePath(execHostLog.getLogPath());
Valid.isTrue(Files1.isFile(absolutePath), ErrorMessage.FILE_ABSENT);
// 获取编码集
this.charset = Charsets.of(this.getCharset());
} }
@Override /**
public String getPath() { * 追踪文件
return config.getPath(); */
private void tailFile() {
// 创建追踪器
this.tracker = new DelayTrackerListener(absolutePath, this);
tracker.charset(charset.name());
tracker.delayMillis(appLogConfig.getTrackerLoadInterval());
tracker.offset(FileOffsetMode.LINE, appLogConfig.getTrackerLoadLines());
tracker.notFoundMode(FileNotFoundMode.WAIT_COUNT, Const.N_10);
// 开始追踪
tracker.run();
} }
@Override /**
public void read(byte[] bytes, int len, Tracker tracker) { * 读取文件
// 发送消息 *
String message = config.getId() + LogConst.SEPARATOR + new String(bytes, 0, len); * @throws IOException IOException
*/
private void readFile() throws IOException {
this.file = Files1.openRandomAccess(absolutePath, Const.ACCESS_R);
// 获取文件位置
long pos = FileReaders.readTailLinesSeek(file, appLogConfig.getTrackerLoadLines());
// 设置文件位置
file.seek(pos);
// 读取到尾部
byte[] buffer = new byte[Const.BUFFER_KB_8];
int len;
while ((len = file.read(buffer)) != -1) {
// 发送消息
this.sendMessage(new String(buffer, 0, len, charset));
}
}
/**
* 读取参数中的编码集
*
* @return charset
*/
private String getCharset() {
JSONObject params = JSON.parseObject(execHostLog.getParameter());
if (params != null) {
String charset = params.getString(Const.CHARSET);
if (charset != null) {
return charset;
}
}
return Const.UTF_8;
}
/**
* 发送消息
*
* @param message message
*/
private void sendMessage(String message) {
try { try {
WebSockets.sendText(session, message); WebSockets.sendText(session, execHostId + LogConst.SEPARATOR + message);
} catch (Exception e) { } catch (Exception e) {
log.error("ExecLogTracker.send error", e); log.error("ExecLogTracker.send error", e);
} }
} }
@Override
public void setLastModify() {
if (tracker != null) {
tracker.setFileLastModifyTime();
}
}
@Override
public void read(byte[] bytes, int len, Tracker tracker) {
// 发送消息
this.sendMessage(new String(bytes, 0, len, charset));
}
@Override @Override
public void close() { public void close() {
log.info("ExecLogTracker.close path: {}, closed: {}", absolutePath, close); log.info("ExecLogTracker.close execHostId: {}, closed: {}", execHostId, close);
if (close) { if (close) {
return; return;
} }
this.close = true; this.close = true;
if (file != null) {
Streams.close(file);
}
if (tracker != null) { if (tracker != null) {
tracker.stop(); tracker.stop();
} }

View File

@@ -34,30 +34,23 @@ import cn.orionsec.kit.lang.able.SafeCloseable;
*/ */
public interface IExecLogTracker extends Runnable, DataHandler, SafeCloseable { public interface IExecLogTracker extends Runnable, DataHandler, SafeCloseable {
/**
* 获取 execId
*
* @return execId
*/
Long getExecId();
/**
* 获取 execHostId
*
* @return execHostId
*/
Long getExecHostId();
/** /**
* 设置最后修改时间 * 设置最后修改时间
*/ */
void setLastModify(); void setLastModify();
/**
* 获取 id
*
* @return id
*/
String getTrackerId();
/**
* 获取路径
*
* @return path
*/
String getPath();
/**
* 获取绝对路径
*
* @return 绝对路径
*/
String getAbsolutePath();
} }

View File

@@ -28,7 +28,6 @@ import org.dromara.visor.module.asset.entity.domain.ExecLogDO;
import org.dromara.visor.module.asset.entity.dto.ExecLogTailDTO; import org.dromara.visor.module.asset.entity.dto.ExecLogTailDTO;
import org.dromara.visor.module.asset.entity.request.exec.ExecLogClearRequest; import org.dromara.visor.module.asset.entity.request.exec.ExecLogClearRequest;
import org.dromara.visor.module.asset.entity.request.exec.ExecLogQueryRequest; import org.dromara.visor.module.asset.entity.request.exec.ExecLogQueryRequest;
import org.dromara.visor.module.asset.entity.request.exec.ExecLogTailRequest;
import org.dromara.visor.module.asset.entity.vo.ExecLogStatusVO; import org.dromara.visor.module.asset.entity.vo.ExecLogStatusVO;
import org.dromara.visor.module.asset.entity.vo.ExecLogVO; import org.dromara.visor.module.asset.entity.vo.ExecLogVO;
@@ -139,10 +138,10 @@ public interface ExecLogService {
/** /**
* 查看执行日志 * 查看执行日志
* *
* @param request request * @param id id
* @return token * @return token
*/ */
String getExecLogTailToken(ExecLogTailRequest request); String getExecLogTailToken(Long id);
/** /**
* 获取查看执行日志参数 * 获取查看执行日志参数

View File

@@ -24,10 +24,6 @@ package org.dromara.visor.module.asset.service;
import org.dromara.visor.common.handler.data.model.GenericsDataModel; import org.dromara.visor.common.handler.data.model.GenericsDataModel;
import org.dromara.visor.module.asset.entity.domain.HostDO; import org.dromara.visor.module.asset.entity.domain.HostDO;
import org.dromara.visor.module.asset.enums.HostTypeEnum;
import java.util.List;
import java.util.Map;
/** /**
* 主机配置 服务类 * 主机配置 服务类
@@ -36,47 +32,24 @@ import java.util.Map;
* @version 1.0.0 * @version 1.0.0
* @since 2023-9-11 14:16 * @since 2023-9-11 14:16
*/ */
// TODO 待优化
public interface HostConfigService { public interface HostConfigService {
/** /**
* 获取主机配置 * 获取主机配置
* *
* @param id id * @param id id
* @param type type * @param <T> T
* @param <T> T
* @return host * @return host
*/ */
<T extends GenericsDataModel> T getHostConfig(Long id, HostTypeEnum type); <T extends GenericsDataModel> T getHostConfig(Long id);
/**
* 构建主机配置
*
* @param host host
* @param type type
* @param <T> T
* @return host
*/
<T extends GenericsDataModel> T buildHostConfig(HostDO host, HostTypeEnum type);
/** /**
* 获取主机配置 * 获取主机配置
* *
* @param idList idList * @param host host
* @param type type * @param <T> T
* @param <T> T * @return host
* @return config
*/ */
<T extends GenericsDataModel> Map<Long, T> getHostConfigMap(List<Long> idList, HostTypeEnum type); <T extends GenericsDataModel> T getHostConfig(HostDO host);
/**
* 构建主机配置
*
* @param hostList hostList
* @param type type
* @param <T> T
* @return config
*/
<T extends GenericsDataModel> Map<Long, T> buildHostConfigMap(List<HostDO> hostList, HostTypeEnum type);
} }

View File

@@ -22,7 +22,6 @@
*/ */
package org.dromara.visor.module.asset.service.impl; package org.dromara.visor.module.asset.service.impl;
import cn.orionsec.kit.lang.function.Functions;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.ErrorMessage; import org.dromara.visor.common.constant.ErrorMessage;
import org.dromara.visor.common.handler.data.model.GenericsDataModel; import org.dromara.visor.common.handler.data.model.GenericsDataModel;
@@ -31,16 +30,10 @@ import org.dromara.visor.module.asset.dao.HostDAO;
import org.dromara.visor.module.asset.entity.domain.HostDO; import org.dromara.visor.module.asset.entity.domain.HostDO;
import org.dromara.visor.module.asset.enums.HostStatusEnum; import org.dromara.visor.module.asset.enums.HostStatusEnum;
import org.dromara.visor.module.asset.enums.HostTypeEnum; import org.dromara.visor.module.asset.enums.HostTypeEnum;
import org.dromara.visor.module.asset.handler.host.config.model.HostSshConfigModel;
import org.dromara.visor.module.asset.service.HostConfigService; import org.dromara.visor.module.asset.service.HostConfigService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* 主机配置 服务实现类 * 主机配置 服务实现类
@@ -57,48 +50,23 @@ public class HostConfigServiceImpl implements HostConfigService {
private HostDAO hostDAO; private HostDAO hostDAO;
@Override @Override
public <T extends GenericsDataModel> T getHostConfig(Long id, HostTypeEnum type) { public <T extends GenericsDataModel> T getHostConfig(Long id) {
// 查询主机 // 查询主机
HostDO host = hostDAO.selectById(id); HostDO host = hostDAO.selectById(id);
// 转换为配置 // 转换为配置
return this.buildHostConfig(host, type); return this.getHostConfig(host);
} }
@Override @Override
@SuppressWarnings("unchecked") public <T extends GenericsDataModel> T getHostConfig(HostDO host) {
public <T extends GenericsDataModel> T buildHostConfig(HostDO host, HostTypeEnum type) {
Valid.notNull(host, ErrorMessage.HOST_ABSENT); Valid.notNull(host, ErrorMessage.HOST_ABSENT);
// 检查主机类型 HostTypeEnum type = HostTypeEnum.of(host.getType());
Valid.isTrue(type.name().equals(host.getType()), ErrorMessage.HOST_TYPE_ERROR);
// 检查主机状态 // 检查主机状态
Valid.isTrue(HostStatusEnum.ENABLED.name().equals(host.getStatus()), ErrorMessage.HOST_NOT_ENABLED); Valid.isTrue(HostStatusEnum.ENABLED.name().equals(host.getStatus()), ErrorMessage.HOST_NOT_ENABLED);
// 查询主机配置 // 查询主机配置
HostSshConfigModel model = type.parse(host.getConfig()); T config = type.parse(host.getConfig());
Valid.notNull(model, ErrorMessage.CONFIG_ABSENT); Valid.notNull(config, ErrorMessage.CONFIG_ABSENT);
return (T) model; return (T) config;
}
@Override
public <T extends GenericsDataModel> Map<Long, T> getHostConfigMap(List<Long> idList, HostTypeEnum type) {
// 查询主机
Map<Long, HostDO> hostMap = hostDAO.selectBatchIds(idList)
.stream()
.collect(Collectors.toMap(HostDO::getId, Function.identity(), Functions.right()));
// 转换为配置
Map<Long, T> result = new HashMap<>();
for (Long id : idList) {
result.put(id, this.buildHostConfig(hostMap.get(id), type));
}
return result;
}
@Override
public <T extends GenericsDataModel> Map<Long, T> buildHostConfigMap(List<HostDO> hostList, HostTypeEnum type) {
Map<Long, T> result = new HashMap<>();
for (HostDO host : hostList) {
result.put(host.getId(), this.buildHostConfig(host, type));
}
return result;
} }
} }

View File

@@ -42,7 +42,10 @@ import org.dromara.visor.module.asset.entity.dto.TerminalAccessDTO;
import org.dromara.visor.module.asset.entity.dto.TerminalConnectDTO; import org.dromara.visor.module.asset.entity.dto.TerminalConnectDTO;
import org.dromara.visor.module.asset.entity.dto.TerminalTransferDTO; import org.dromara.visor.module.asset.entity.dto.TerminalTransferDTO;
import org.dromara.visor.module.asset.entity.vo.TerminalThemeVO; import org.dromara.visor.module.asset.entity.vo.TerminalThemeVO;
import org.dromara.visor.module.asset.enums.*; import org.dromara.visor.module.asset.enums.HostExtraItemEnum;
import org.dromara.visor.module.asset.enums.HostExtraSshAuthTypeEnum;
import org.dromara.visor.module.asset.enums.HostIdentityTypeEnum;
import org.dromara.visor.module.asset.enums.HostSshAuthTypeEnum;
import org.dromara.visor.module.asset.handler.host.config.model.HostSshConfigModel; import org.dromara.visor.module.asset.handler.host.config.model.HostSshConfigModel;
import org.dromara.visor.module.asset.handler.host.extra.model.HostSshExtraModel; import org.dromara.visor.module.asset.handler.host.extra.model.HostSshExtraModel;
import org.dromara.visor.module.asset.service.HostConfigService; import org.dromara.visor.module.asset.service.HostConfigService;
@@ -171,7 +174,7 @@ public class TerminalServiceImpl implements TerminalService {
// 查询主机 // 查询主机
HostDO host = hostDAO.selectById(hostId); HostDO host = hostDAO.selectById(hostId);
// 查询主机配置 // 查询主机配置
HostSshConfigModel config = hostConfigService.buildHostConfig(host, HostTypeEnum.SSH); HostSshConfigModel config = hostConfigService.getHostConfig(host);
// 获取配置 // 获取配置
return this.getHostConnectInfo(host, config, null); return this.getHostConnectInfo(host, config, null);
} }
@@ -195,7 +198,7 @@ public class TerminalServiceImpl implements TerminalService {
ErrorMessage.ANY_NO_PERMISSION, ErrorMessage.ANY_NO_PERMISSION,
DataPermissionTypeEnum.HOST_GROUP.getPermissionName()); DataPermissionTypeEnum.HOST_GROUP.getPermissionName());
// 获取主机配置 // 获取主机配置
HostSshConfigModel config = hostConfigService.buildHostConfig(host, HostTypeEnum.SSH); HostSshConfigModel config = hostConfigService.getHostConfig(host);
Valid.notNull(config, ErrorMessage.CONFIG_ABSENT); Valid.notNull(config, ErrorMessage.CONFIG_ABSENT);
// 查询主机额外配置 // 查询主机额外配置
HostSshExtraModel extra = hostExtraService.getHostExtra(userId, hostId, HostExtraItemEnum.SSH); HostSshExtraModel extra = hostExtraService.getHostExtra(userId, hostId, HostExtraItemEnum.SSH);

View File

@@ -26,6 +26,7 @@ import cn.orionsec.kit.lang.utils.Booleans;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.net.host.sftp.SftpExecutor; import cn.orionsec.kit.net.host.sftp.SftpExecutor;
import cn.orionsec.kit.net.host.sftp.SftpFile; import cn.orionsec.kit.net.host.sftp.SftpFile;
import cn.orionsec.kit.spring.SpringHolder;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import org.dromara.visor.module.asset.define.config.AppSftpConfig; import org.dromara.visor.module.asset.define.config.AppSftpConfig;
import org.dromara.visor.module.asset.handler.host.transfer.model.SftpFileBackupParams; import org.dromara.visor.module.asset.handler.host.transfer.model.SftpFileBackupParams;
@@ -39,19 +40,20 @@ import org.dromara.visor.module.asset.handler.host.transfer.model.SftpFileBackup
*/ */
public class SftpUtils { public class SftpUtils {
private static final AppSftpConfig appSftpConfig = SpringHolder.getBean(AppSftpConfig.class);
private SftpUtils() { private SftpUtils() {
} }
/** /**
* 检查上传文件是否存在 并且执行响应策略 * 检查上传文件是否存在 并且执行响应策略
* *
* @param config config
* @param executor executor * @param executor executor
* @param path path * @param path path
*/ */
public static void checkUploadFilePresent(AppSftpConfig config, SftpExecutor executor, String path) { public static void checkUploadFilePresent(SftpExecutor executor, String path) {
// 重复不备份 // 重复不备份
if (!Booleans.isTrue(config.getUploadPresentBackup())) { if (!Booleans.isTrue(appSftpConfig.getUploadPresentBackup())) {
return; return;
} }
// 检查文件是否存在 // 检查文件是否存在
@@ -59,7 +61,7 @@ public class SftpUtils {
if (file != null) { if (file != null) {
// 文件存在则备份 // 文件存在则备份
SftpFileBackupParams backupParams = new SftpFileBackupParams(file.getName()); SftpFileBackupParams backupParams = new SftpFileBackupParams(file.getName());
String target = Strings.format(config.getBackupFileName(), JSON.parseObject(JSON.toJSONString(backupParams))); String target = Strings.format(appSftpConfig.getUploadBackupFileName(), JSON.parseObject(JSON.toJSONString(backupParams)));
// 移动 // 移动
executor.move(path, target); executor.move(path, target);
} }