Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5113aa63bd | ||
|
|
518fd8c839 | ||
|
|
a046faaa07 | ||
|
|
dcf25392ff | ||
|
|
7f24948efa | ||
|
|
59d9739f36 | ||
|
|
26a6d08d96 | ||
|
|
cd59c51344 | ||
|
|
8dec98406d | ||
|
|
9386bfc5c1 | ||
|
|
370272ca43 | ||
|
|
5c6758c8e7 | ||
|
|
11606e25bb | ||
|
|
285f0532d3 | ||
|
|
7bfa8a73be |
12
README.md
12
README.md
@@ -66,16 +66,16 @@ git clone https://github.com/lijiahangmax/orion-visor
|
||||
cd orion-visor
|
||||
# 启动
|
||||
docker compose up -d
|
||||
# 等待后端服务启动后 (2min±) 访问 http://localhost:1081/
|
||||
```
|
||||
|
||||
## 项目文档
|
||||
|
||||
* [文档地址](https://lijiahangmax.github.io/orion-visor/#/)
|
||||
* [docker安装](https://lijiahangmax.github.io/orion-visor/#/quickstart/docker-install)
|
||||
* [普通安装](https://lijiahangmax.github.io/orion-visor/#/quickstart/install)
|
||||
* [更新日志](https://lijiahangmax.github.io/orion-visor/#/about/change-log)
|
||||
* [操作手册](https://lijiahangmax.github.io/orion-visor/#/operator/asset)
|
||||
* [常见问题](https://lijiahangmax.github.io/orion-visor/#/quickstart/faq)
|
||||
* [文档地址](https://lijiahangmax.github.io/open-orion/orion-visor/)
|
||||
* [安装文档](https://lijiahangmax.github.io/open-orion/orion-visor/quickstart/docker.html)
|
||||
* [更新日志](https://lijiahangmax.github.io/open-orion/orion-visor/update/change-log.html)
|
||||
* [操作手册](https://lijiahangmax.github.io/open-orion/orion-visor/operator/asset.html)
|
||||
* [常见问题](https://lijiahangmax.github.io/open-orion/orion-visor/support/faq.html)
|
||||
|
||||
## 技术栈
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
version: '3.3'
|
||||
services:
|
||||
orion-visor-service:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.0.3
|
||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.0.5
|
||||
ports:
|
||||
- 1081:80
|
||||
environment:
|
||||
@@ -20,7 +20,7 @@ services:
|
||||
- orion-visor-mysql
|
||||
- orion-visor-redis
|
||||
orion-visor-mysql:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.0.3
|
||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.0.5
|
||||
privileged: true
|
||||
ports:
|
||||
- 3307:3306
|
||||
@@ -34,7 +34,7 @@ services:
|
||||
- /data/orion-visor-space/docker-volumes/orion-visor-mysql/var-lib-mysql-files:/var/lib/mysql-files
|
||||
- /data/orion-visor-space/docker-volumes/orion-visor-mysql/etc-mysql:/etc/mysql
|
||||
orion-visor-redis:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.0.3
|
||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.0.5
|
||||
privileged: true
|
||||
ports:
|
||||
- 6380:6379
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#/bin/bash
|
||||
version=2.0.3
|
||||
version=2.0.5
|
||||
cp -r ../../sql ./sql
|
||||
docker build -t orion-visor-mysql:${version} .
|
||||
rm -rf ./sql
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#/bin/bash
|
||||
version=2.0.3
|
||||
version=2.0.5
|
||||
docker build -t orion-visor-redis:${version} .
|
||||
docker tag orion-visor-redis:${version} registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}
|
||||
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#/bin/bash
|
||||
version=2.0.3
|
||||
version=2.0.5
|
||||
mv ../../orion-visor-launch/target/orion-visor-launch.jar ./orion-visor-launch.jar
|
||||
mv ../../orion-visor-ui/dist ./dist
|
||||
docker build -t orion-visor-service:${version} .
|
||||
|
||||
@@ -40,6 +40,12 @@
|
||||
|
||||
------------------------------
|
||||
|
||||
<p><b>⛔⛔此页面已不再维护, 请跳转至
|
||||
<a target="_blank" href="https://lijiahangmax.github.io/open-orion/orion-visor">这里</a>
|
||||
查看最新文档 ❗</b></p>
|
||||
|
||||
------------------------------
|
||||
|
||||
**`orion-visor`** 提供一站式服务器运维解决方案。
|
||||
|
||||
* **资产管理**:支持对资产进行分组,实现对主机、密钥和身份的统一管理和授权。
|
||||
@@ -70,9 +76,8 @@ docker compose up -d
|
||||
|
||||
## 项目文档
|
||||
|
||||
* [文档地址](https://lijiahangmax.github.io/orion-visor/#/)
|
||||
* [docker安装](/quickstart/docker-install)
|
||||
* [普通安装](/quickstart/install)
|
||||
* [文档地址](/)
|
||||
* [安装文档](/quickstart/docker-install)
|
||||
* [更新日志](/about/change-log)
|
||||
* [操作手册](/operator/asset)
|
||||
* [常见问题](/quickstart/faq)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# orion-visor <small>2.0.3</small>
|
||||
# orion-visor
|
||||
|
||||
> 一款高颜值、现代化的智能运维&轻量堡垒机平台。
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
<url>https://github.com/lijiahangmax/orion-visor</url>
|
||||
|
||||
<properties>
|
||||
<revision>2.0.3</revision>
|
||||
<revision>2.0.5</revision>
|
||||
<spring.boot.version>2.7.17</spring.boot.version>
|
||||
<spring.boot.admin.version>2.7.15</spring.boot.admin.version>
|
||||
<flatten.maven.plugin.version>1.5.0</flatten.maven.plugin.version>
|
||||
<orion.kit.revision>1.0.7</orion.kit.revision>
|
||||
<orion.kit.version>1.0.7</orion.kit.version>
|
||||
<aspectj.version>1.9.7</aspectj.version>
|
||||
<lombok.version>1.18.26</lombok.version>
|
||||
<springdoc.version>1.6.15</springdoc.version>
|
||||
@@ -50,7 +50,7 @@
|
||||
<dependency>
|
||||
<groupId>io.github.lijiahangmax</groupId>
|
||||
<artifactId>orion-all</artifactId>
|
||||
<version>${orion.kit.revision}</version>
|
||||
<version>${orion.kit.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>orion-log</artifactId>
|
||||
|
||||
@@ -14,7 +14,7 @@ public interface AppConst extends OrionConst {
|
||||
/**
|
||||
* 同 ${orion.version} 迭代时候需要手动更改
|
||||
*/
|
||||
String VERSION = "2.0.3";
|
||||
String VERSION = "2.0.5";
|
||||
|
||||
String ORION_VISOR = "orion-visor";
|
||||
|
||||
|
||||
@@ -97,4 +97,6 @@ public interface ErrorMessage {
|
||||
|
||||
String PLEASE_CHECK_HOST_SSH = "请检查主机 {} 是否存在/权限/SSH配置";
|
||||
|
||||
String CLIENT_ABORT = "手动中断";
|
||||
|
||||
}
|
||||
|
||||
@@ -62,10 +62,6 @@ public class CustomFileFilter {
|
||||
if (!table.isEnableCache()) {
|
||||
files.removeIf(file -> isServerCacheFile(file.getTemplatePath()));
|
||||
}
|
||||
// 不生成导出文件
|
||||
if (!table.isEnableExport()) {
|
||||
files.removeIf(file -> isExportFile(file.getTemplatePath()));
|
||||
}
|
||||
// 不生成操作日志文件
|
||||
if (!table.isEnableOperatorLog()) {
|
||||
files.removeIf(file -> isOperatorLogFile(file.getTemplatePath()));
|
||||
|
||||
@@ -73,16 +73,6 @@ public class ServerTemplate extends Template {
|
||||
return this;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 生成导出
|
||||
// *
|
||||
// * @return this
|
||||
// */
|
||||
// public ServerTemplate enableExport() {
|
||||
// table.enableExport = true;
|
||||
// return this;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 不生成单元测试
|
||||
*
|
||||
|
||||
@@ -43,11 +43,6 @@ public class Table {
|
||||
*/
|
||||
protected boolean enableUnitTest;
|
||||
|
||||
/**
|
||||
* 是否生成导出
|
||||
*/
|
||||
protected boolean enableExport;
|
||||
|
||||
/**
|
||||
* 是否可缓存
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@ public class VueTemplate extends Template {
|
||||
public VueTemplate(Table table, String module, String feature) {
|
||||
super(table);
|
||||
table.enableVue = true;
|
||||
table.enableRowSelection = true;
|
||||
table.module = module;
|
||||
table.feature = feature;
|
||||
}
|
||||
@@ -54,12 +55,12 @@ public class VueTemplate extends Template {
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表可多选
|
||||
* 关闭列表可多选
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public VueTemplate enableRowSelection() {
|
||||
table.enableRowSelection = true;
|
||||
public VueTemplate disableRowSelection() {
|
||||
table.enableRowSelection = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,19 +68,5 @@ Authorization: {{token}}
|
||||
${httpComment} ${apiComment.batchDelete}
|
||||
DELETE {{baseUrl}}/${package.ModuleName}/${typeHyphen}/batch-delete?idList=1,2,3
|
||||
Authorization: {{token}}
|
||||
#if($meta.enableExport)
|
||||
|
||||
|
||||
${httpComment} ${apiComment.export}
|
||||
POST {{baseUrl}}/${package.ModuleName}/${typeHyphen}/export
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
#foreach($field in ${table.fields})
|
||||
"${field.propertyName}": ""#if($foreach.hasNext),#end
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
${httpComment}
|
||||
|
||||
@@ -141,19 +141,6 @@ public class ${table.controllerName} {
|
||||
public Integer batchDelete${type}(@RequestParam("idList") List<Long> idList) {
|
||||
return ${typeLower}Service.delete${type}ByIdList(idList);
|
||||
}
|
||||
#if($meta.enableExport)
|
||||
|
||||
#if($meta.enableOperatorLog)
|
||||
@OperatorLog(${type}OperatorType.EXPORT)
|
||||
#end
|
||||
@PostMapping("/export")
|
||||
@Operation(summary = "${apiComment.export}")
|
||||
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:export')")
|
||||
public void export${type}(@Validated @RequestBody ${type}QueryRequest request,
|
||||
HttpServletResponse response) throws IOException {
|
||||
${typeLower}Service.export${type}(request, response);
|
||||
}
|
||||
#end
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,6 @@ public interface ${type}Convert {
|
||||
${type}DO to(${type}QueryRequest request);
|
||||
|
||||
${type}VO to(${type}DO domain);
|
||||
#if($meta.enableExport)
|
||||
|
||||
${type}Export toExport(${type}DO domain);
|
||||
#end
|
||||
|
||||
List<${type}VO> to(List<${type}DO> list);
|
||||
|
||||
|
||||
@@ -21,10 +21,6 @@ public class ${type}OperatorType extends InitializingOperatorTypes {
|
||||
public static final String UPDATE = "${typeHyphen}:update";
|
||||
|
||||
public static final String DELETE = "${typeHyphen}:delete";
|
||||
#if($meta.enableExport)
|
||||
|
||||
public static final String EXPORT = "${typeHyphen}:export";
|
||||
#end
|
||||
|
||||
@Override
|
||||
public OperatorType[] types() {
|
||||
@@ -32,9 +28,6 @@ public class ${type}OperatorType extends InitializingOperatorTypes {
|
||||
new OperatorType(L, CREATE, "创建$!{table.comment}"),
|
||||
new OperatorType(M, UPDATE, "更新$!{table.comment}"),
|
||||
new OperatorType(H, DELETE, "删除$!{table.comment}"),
|
||||
#if($meta.enableExport)
|
||||
new OperatorType(M, EXPORT, "导出$!{table.comment}"),
|
||||
#end
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.orion.lang.define.wrapper.DataGrid;
|
||||
import com.orion.lang.utils.Strings;
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
#if($meta.enableExport)
|
||||
import com.orion.office.excel.writer.exporting.ExcelExport;
|
||||
#end
|
||||
import com.orion.visor.framework.common.constant.ErrorMessage;
|
||||
#if($meta.enableExport)
|
||||
import com.orion.visor.framework.common.utils.FileNames;
|
||||
#end
|
||||
import com.orion.visor.framework.common.utils.Valid;
|
||||
#if($meta.enableCache)
|
||||
import com.orion.visor.framework.redis.core.utils.RedisMaps;
|
||||
@@ -23,18 +17,11 @@ import ${pkg}.*;
|
||||
import ${package.Entity}.${entity};
|
||||
import ${package.Mapper}.${table.mapperName};
|
||||
import ${package.Service}.${table.serviceName};
|
||||
#if($meta.enableExport)
|
||||
import com.orion.web.servlet.web.Servlets;
|
||||
#end
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
#if($meta.enableExport)
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
#end
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -54,6 +41,7 @@ public class ${table.serviceImplName} implements ${table.serviceName} {
|
||||
private ${type}DAO ${typeLower}DAO;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long create${type}(${type}CreateRequest request) {
|
||||
log.info("${type}Service-create${type} request: {}", JSON.toJSONString(request));
|
||||
// 转换
|
||||
@@ -72,6 +60,7 @@ public class ${table.serviceImplName} implements ${table.serviceName} {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer update${type}ById(${type}UpdateRequest request) {
|
||||
Long id = Valid.notNull(request.getId(), ErrorMessage.ID_MISSING);
|
||||
log.info("${type}Service-update${type}ById id: {}, request: {}", id, JSON.toJSONString(request));
|
||||
@@ -93,6 +82,7 @@ public class ${table.serviceImplName} implements ${table.serviceName} {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer update${type}(${type}QueryRequest query, ${type}UpdateRequest update) {
|
||||
log.info("${type}Service.update${type} query: {}, update: {}", JSON.toJSONString(query), JSON.toJSONString(update));
|
||||
// 条件
|
||||
@@ -179,6 +169,7 @@ public class ${table.serviceImplName} implements ${table.serviceName} {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer delete${type}ById(Long id) {
|
||||
log.info("${type}Service-delete${type}ById id: {}", id);
|
||||
// 检查数据是否存在
|
||||
@@ -195,6 +186,7 @@ public class ${table.serviceImplName} implements ${table.serviceName} {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer delete${type}ByIdList(List<Long> idList) {
|
||||
log.info("${type}Service-delete${type}ByIdList idList: {}", idList);
|
||||
int effect = ${typeLower}DAO.deleteBatchIds(idList);
|
||||
@@ -207,6 +199,7 @@ public class ${table.serviceImplName} implements ${table.serviceName} {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer delete${type}(${type}QueryRequest request) {
|
||||
log.info("${type}Service.delete${type} request: {}", JSON.toJSONString(request));
|
||||
// 条件
|
||||
@@ -220,26 +213,6 @@ public class ${table.serviceImplName} implements ${table.serviceName} {
|
||||
#end
|
||||
return effect;
|
||||
}
|
||||
#if($meta.enableExport)
|
||||
|
||||
@Override
|
||||
public void export${type}(${type}QueryRequest request, HttpServletResponse response) throws IOException {
|
||||
log.info("${type}Service.export${type} request: {}", JSON.toJSONString(request));
|
||||
// 条件
|
||||
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request);
|
||||
// 查询
|
||||
List<${type}Export> rows = ${typeLower}DAO.of(wrapper).list(${type}Convert.MAPPER::toExport);
|
||||
log.info("${type}Service.export${type} size: {}", rows.size());
|
||||
// 导出
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ExcelExport.create(${type}Export.class)
|
||||
.addRows(rows)
|
||||
.write(out)
|
||||
.close();
|
||||
// 传输
|
||||
Servlets.transfer(response, out.toByteArray(), FileNames.exportName(${type}Export.TITLE));
|
||||
}
|
||||
#end
|
||||
|
||||
/**
|
||||
* 检查对象是否存在
|
||||
|
||||
@@ -115,16 +115,5 @@ public interface ${table.serviceName} {
|
||||
* @return effect
|
||||
*/
|
||||
Integer delete${type}(${type}QueryRequest request);
|
||||
#if($meta.enableExport)
|
||||
|
||||
/**
|
||||
* ${apiComment.export}
|
||||
*
|
||||
* @param request request
|
||||
* @param response response
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
void export${type}(${type}QueryRequest request, HttpServletResponse response) throws IOException;
|
||||
#end
|
||||
|
||||
}
|
||||
|
||||
@@ -14,12 +14,7 @@ VALUES
|
||||
(@MODULE_KEY_ID, 'operatorLogModule', '${package.ModuleName}:${typeHyphen}', '$!{table.comment}', '{}', @MODULE_KEY_MAX_SORT + 10, now(), now(), '1', '1', 0),
|
||||
(@TYPE_KEY_ID, 'operatorLogType', '${typeHyphen}:create', '创建$!{table.comment}', '{}', 10, now(), now(), '1', '1', 0),
|
||||
(@TYPE_KEY_ID, 'operatorLogType', '${typeHyphen}:update', '更新$!{table.comment}', '{}', 20, now(), now(), '1', '1', 0),
|
||||
#if($meta.enableExport)
|
||||
(@TYPE_KEY_ID, 'operatorLogType', '${typeHyphen}:delete', '删除$!{table.comment}', '{}', 30, now(), now(), '1', '1', 0),
|
||||
(@TYPE_KEY_ID, 'operatorLogType', '${typeHyphen}:export', '导出$!{table.comment}', '{}', 40, now(), now(), '1', '1', 0);
|
||||
#else
|
||||
(@TYPE_KEY_ID, 'operatorLogType', '${typeHyphen}:delete', '删除$!{table.comment}', '{}', 30, now(), now(), '1', '1', 0);
|
||||
#end
|
||||
#end
|
||||
|
||||
#if($dictMap.entrySet().size() > 0)
|
||||
|
||||
@@ -133,12 +133,4 @@ export function batchDelete${vue.featureEntity}(idList: Array<number>) {
|
||||
}
|
||||
});
|
||||
}
|
||||
#if($meta.enableExport)
|
||||
|
||||
/**
|
||||
* $apiComment.export
|
||||
*/
|
||||
export function export${vue.featureEntity}(request: ${vue.featureEntity}QueryRequest) {
|
||||
return axios.post('/${package.ModuleName}/${typeHyphen}/export', request);
|
||||
}
|
||||
#end
|
||||
|
||||
@@ -79,12 +79,16 @@
|
||||
</div>
|
||||
</template>
|
||||
<!-- table -->
|
||||
#if($vue.enableRowSelection)
|
||||
<a-table v-model:selected-keys="selectedKeys"
|
||||
row-key="id"
|
||||
#else
|
||||
<a-table row-key="id"
|
||||
#end
|
||||
ref="tableRef"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
#if($vue.enableRowSelection)
|
||||
v-model:selected-keys="selectedKeys"
|
||||
:row-selection="rowSelection"
|
||||
#end
|
||||
:data="tableRenderData"
|
||||
|
||||
@@ -6,7 +6,7 @@ const columns = [
|
||||
title: 'id',
|
||||
dataIndex: 'id',
|
||||
slotName: 'id',
|
||||
width: 70,
|
||||
width: 100,
|
||||
align: 'left',
|
||||
fixed: 'left',
|
||||
}, #foreach($field in ${table.fields})#if("$!field.propertyName" != "id"){
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.orion.visor.framework.redis.configuration.config.RedissonConfig;
|
||||
import com.orion.visor.framework.redis.core.lock.RedisLocker;
|
||||
import com.orion.visor.framework.redis.core.utils.RedisUtils;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.SingleServerConfig;
|
||||
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
||||
@@ -58,6 +59,9 @@ public class OrionRedisAutoConfiguration {
|
||||
return config -> {
|
||||
config.setThreads(redissonConfig.getThreads());
|
||||
config.setNettyThreads(redissonConfig.getNettyThreads());
|
||||
// 单机配置
|
||||
SingleServerConfig single = config.useSingleServer();
|
||||
single.setConnectionMinimumIdleSize(redissonConfig.getMinimumIdleSize());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,15 @@ public class RedissonConfig {
|
||||
*/
|
||||
private Integer nettyThreads;
|
||||
|
||||
/**
|
||||
* 最小空闲连接数
|
||||
*/
|
||||
private Integer minimumIdleSize;
|
||||
|
||||
public RedissonConfig() {
|
||||
this.threads = 16;
|
||||
this.nettyThreads = 16;
|
||||
this.minimumIdleSize = 16;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,12 @@
|
||||
"type": "java.lang.Integer",
|
||||
"description": "netty 线程数.",
|
||||
"defaultValue": "16"
|
||||
},
|
||||
{
|
||||
"name": "spring.redisson.minimum-idle-size",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "最小空闲连接数.",
|
||||
"defaultValue": "16"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -14,6 +14,7 @@ spring:
|
||||
redisson:
|
||||
threads: 2
|
||||
netty-threads: 2
|
||||
minimum-idle-size: 2
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
|
||||
@@ -24,6 +24,7 @@ spring:
|
||||
redisson:
|
||||
threads: 4
|
||||
netty-threads: 4
|
||||
minimum-idle-size: 4
|
||||
quartz:
|
||||
properties:
|
||||
org:
|
||||
|
||||
@@ -19,6 +19,9 @@ spring:
|
||||
mvc:
|
||||
pathmatch:
|
||||
matching-strategy: ANT_PATH_MATCHER
|
||||
async:
|
||||
# 异步请求时间 30min
|
||||
request-timeout: 1800000
|
||||
datasource:
|
||||
druid:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
@@ -195,7 +198,7 @@ orion:
|
||||
api:
|
||||
# 公共 api 前缀
|
||||
prefix: /orion-visor/api
|
||||
# 是否开启跨域
|
||||
# 是否允许跨域
|
||||
cors: true
|
||||
websocket:
|
||||
# 公共 websocket 前缀
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.orion.visor.module.infra.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 命令片段 对外服务类
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/6/3 11:07
|
||||
*/
|
||||
public interface CommandSnippetApi {
|
||||
|
||||
/**
|
||||
* 通过 userId 删除
|
||||
*
|
||||
* @param userIdList userIdList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteByUserIdList(List<Long> userIdList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.orion.visor.module.infra.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 路径标签 对外服务类
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/6/3 11:07
|
||||
*/
|
||||
public interface PathBookmarkApi {
|
||||
|
||||
/**
|
||||
* 通过 userId 删除
|
||||
*
|
||||
* @param userIdList userIdList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteByUserIdList(List<Long> userIdList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.orion.visor.module.asset.api.impl;
|
||||
|
||||
import com.orion.visor.module.asset.service.CommandSnippetService;
|
||||
import com.orion.visor.module.infra.api.CommandSnippetApi;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 命令片段 对外服务实现类
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/6/3 11:11
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class CommandSnippetApiImpl implements CommandSnippetApi {
|
||||
|
||||
@Resource
|
||||
private CommandSnippetService commandSnippetService;
|
||||
|
||||
@Override
|
||||
public Integer deleteByUserIdList(List<Long> userIdList) {
|
||||
return commandSnippetService.deleteByUserIdList(userIdList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.orion.visor.module.asset.api.impl;
|
||||
|
||||
import com.orion.visor.module.asset.service.PathBookmarkService;
|
||||
import com.orion.visor.module.infra.api.PathBookmarkApi;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 路径标签 对外服务实现类
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/6/3 11:11
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class PathBookmarkApiImpl implements PathBookmarkApi {
|
||||
|
||||
@Resource
|
||||
private PathBookmarkService pathBookmarkService;
|
||||
|
||||
@Override
|
||||
public Integer deleteByUserIdList(List<Long> userIdList) {
|
||||
return pathBookmarkService.deleteByUserIdList(userIdList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -98,6 +98,15 @@ public class ExecJobController {
|
||||
return execJobService.deleteExecJobById(id);
|
||||
}
|
||||
|
||||
@OperatorLog(ExecJobOperatorType.DELETE)
|
||||
@DeleteMapping("/batch-delete")
|
||||
@Operation(summary = "批量删除计划任务")
|
||||
@Parameter(name = "idList", description = "idList", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('asset:exec-job:delete')")
|
||||
public Integer batchDeleteExecJob(@RequestParam("idList") List<Long> idList) {
|
||||
return execJobService.deleteExecJobByIdList(idList);
|
||||
}
|
||||
|
||||
@OperatorLog(ExecJobOperatorType.TRIGGER)
|
||||
@PostMapping("/trigger")
|
||||
@Operation(summary = "手动触发计划任务")
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 执行模板 api
|
||||
@@ -92,5 +93,14 @@ public class ExecTemplateController {
|
||||
return execTemplateService.deleteExecTemplateById(id);
|
||||
}
|
||||
|
||||
@OperatorLog(ExecTemplateOperatorType.DELETE)
|
||||
@DeleteMapping("/batch-delete")
|
||||
@Operation(summary = "批量删除执行模板")
|
||||
@Parameter(name = "idList", description = "idList", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('asset:exec-template:delete')")
|
||||
public Integer batchDeleteExecTemplate(@RequestParam("idList") List<Long> idList) {
|
||||
return execTemplateService.deleteExecTemplateByIdList(idList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -96,5 +96,15 @@ public class HostController {
|
||||
return hostService.deleteHostById(id);
|
||||
}
|
||||
|
||||
@DemoDisableApi
|
||||
@OperatorLog(HostOperatorType.DELETE)
|
||||
@DeleteMapping("/batch-delete")
|
||||
@Operation(summary = "批量删除主机")
|
||||
@Parameter(name = "idList", description = "idList", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('asset:host:delete')")
|
||||
public Integer batchDeleteHost(@RequestParam("idList") List<Long> idList) {
|
||||
return hostService.deleteHostByIdList(idList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -97,5 +97,15 @@ public class HostIdentityController {
|
||||
return hostIdentityService.deleteHostIdentityById(id);
|
||||
}
|
||||
|
||||
@DemoDisableApi
|
||||
@OperatorLog(HostIdentityOperatorType.DELETE)
|
||||
@DeleteMapping("/batch-delete")
|
||||
@Operation(summary = "批量删除主机身份")
|
||||
@Parameter(name = "idList", description = "idList", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('asset:host-identity:delete')")
|
||||
public Integer batchDeleteHostIdentity(@RequestParam("idList") List<Long> idList) {
|
||||
return hostIdentityService.deleteHostIdentityByIdList(idList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -96,5 +96,15 @@ public class HostKeyController {
|
||||
return hostKeyService.deleteHostKeyById(id);
|
||||
}
|
||||
|
||||
@DemoDisableApi
|
||||
@OperatorLog(HostKeyOperatorType.DELETE)
|
||||
@DeleteMapping("/batch-delete")
|
||||
@Operation(summary = "批量删除主机密钥")
|
||||
@Parameter(name = "idList", description = "idList", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('asset:host-key:delete')")
|
||||
public Integer batchDeleteHostKey(@RequestParam("idList") List<Long> idList) {
|
||||
return hostKeyService.deleteHostKeyByIdList(idList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
### 分页查询 SFTP 操作日志
|
||||
POST {{baseUrl}}/asset/host-sftp-log/query
|
||||
POST {{baseUrl}}/asset/host-sftp/query-log
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
@@ -10,8 +10,12 @@ Authorization: {{token}}
|
||||
|
||||
|
||||
### 删除 SFTP 操作日志
|
||||
DELETE {{baseUrl}}/asset/host-sftp-log/delete?idList=1,2,3
|
||||
DELETE {{baseUrl}}/asset/host-sftp/delete-log?idList=1,2,3
|
||||
Authorization: {{token}}
|
||||
|
||||
|
||||
### 下载文件
|
||||
GET {{baseUrl}}/asset/host-sftp/download?channelId=123&transferToken=123
|
||||
|
||||
|
||||
###
|
||||
|
||||
@@ -5,11 +5,12 @@ import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
|
||||
import com.orion.visor.framework.common.validator.group.Page;
|
||||
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
|
||||
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
|
||||
import com.orion.visor.framework.web.core.annotation.IgnoreWrapper;
|
||||
import com.orion.visor.framework.web.core.annotation.RestWrapper;
|
||||
import com.orion.visor.module.asset.define.operator.HostTerminalOperatorType;
|
||||
import com.orion.visor.module.asset.entity.request.host.HostSftpLogQueryRequest;
|
||||
import com.orion.visor.module.asset.entity.vo.HostSftpLogVO;
|
||||
import com.orion.visor.module.asset.service.HostSftpLogService;
|
||||
import com.orion.visor.module.asset.service.HostSftpService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -17,44 +18,60 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* SFTP 操作日志服务 api
|
||||
* SFTP 操作服务 api
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023-12-26 22:09
|
||||
*/
|
||||
@Tag(name = "asset - SFTP 操作日志服务")
|
||||
@Tag(name = "asset - SFTP 操作服务")
|
||||
@Slf4j
|
||||
@Validated
|
||||
@RestWrapper
|
||||
@RestController
|
||||
@RequestMapping("/asset/host-sftp-log")
|
||||
@RequestMapping("/asset/host-sftp")
|
||||
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
|
||||
public class HostSftpLogController {
|
||||
|
||||
@Resource
|
||||
private HostSftpLogService hostSftpLogService;
|
||||
private HostSftpService hostSftpService;
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@PostMapping("/query")
|
||||
@PostMapping("/query-log")
|
||||
@Operation(summary = "分页查询 SFTP 操作日志")
|
||||
@PreAuthorize("@ss.hasAnyPermission('infra:operator-log:query', 'asset:host-sftp-log:management:query')")
|
||||
public DataGrid<HostSftpLogVO> getHostSftpLogPage(@Validated(Page.class) @RequestBody HostSftpLogQueryRequest request) {
|
||||
return hostSftpLogService.getHostSftpLogPage(request);
|
||||
return hostSftpService.getHostSftpLogPage(request);
|
||||
}
|
||||
|
||||
@OperatorLog(HostTerminalOperatorType.DELETE_SFTP_LOG)
|
||||
@DeleteMapping("/delete")
|
||||
@DeleteMapping("/delete-log")
|
||||
@Operation(summary = "删除 SFTP 操作日志")
|
||||
@Parameter(name = "idList", description = "idList", required = true)
|
||||
@PreAuthorize("@ss.hasAnyPermission('infra:operator-log:delete', 'asset:host-sftp-log:management:delete')")
|
||||
public Integer deleteHostSftpLog(@RequestParam("idList") List<Long> idList) {
|
||||
return hostSftpLogService.deleteHostSftpLog(idList);
|
||||
return hostSftpService.deleteHostSftpLog(idList);
|
||||
}
|
||||
|
||||
@PermitAll
|
||||
@IgnoreWrapper
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@GetMapping("/download")
|
||||
@Operation(summary = "下载文件")
|
||||
@Parameter(name = "channelId", description = "channelId", required = true)
|
||||
@Parameter(name = "transferToken", description = "transferToken", required = true)
|
||||
public StreamingResponseBody downloadWithTransferToken(@RequestParam("channelId") String channelId,
|
||||
@RequestParam("transferToken") String transferToken,
|
||||
HttpServletResponse response) {
|
||||
return hostSftpService.downloadWithTransferToken(channelId, transferToken, response);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import com.orion.visor.framework.mybatis.core.mapper.IMapper;
|
||||
import com.orion.visor.module.asset.entity.domain.CommandSnippetDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 命令片段 Mapper 接口
|
||||
*
|
||||
@@ -42,4 +44,16 @@ public interface CommandSnippetDAO extends IMapper<CommandSnippetDO> {
|
||||
return this.delete(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 userId 删除
|
||||
*
|
||||
* @param userIdList userIdList
|
||||
* @return effect
|
||||
*/
|
||||
default int deleteByUserIdList(List<Long> userIdList) {
|
||||
LambdaQueryWrapper<CommandSnippetDO> wrapper = this.lambda()
|
||||
.in(CommandSnippetDO::getUserId, userIdList);
|
||||
return this.delete(wrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +44,18 @@ public interface ExecJobHostDAO extends IMapper<ExecJobHostDO> {
|
||||
return this.delete(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 jobId 删除
|
||||
*
|
||||
* @param jobIdList jobIdList
|
||||
* @return effect
|
||||
*/
|
||||
default Integer deleteByJobIdList(List<Long> jobIdList) {
|
||||
LambdaQueryWrapper<ExecJobHostDO> wrapper = this.wrapper()
|
||||
.in(ExecJobHostDO::getJobId, jobIdList);
|
||||
return this.delete(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 hostId 删除
|
||||
*
|
||||
@@ -56,4 +68,16 @@ public interface ExecJobHostDAO extends IMapper<ExecJobHostDO> {
|
||||
return this.delete(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 hostId 删除
|
||||
*
|
||||
* @param hostIdList hostIdList
|
||||
* @return effect
|
||||
*/
|
||||
default Integer deleteByHostIdList(List<Long> hostIdList) {
|
||||
LambdaQueryWrapper<ExecJobHostDO> wrapper = this.wrapper()
|
||||
.in(ExecJobHostDO::getHostId, hostIdList);
|
||||
return this.delete(wrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -95,17 +95,17 @@ public interface HostConfigDAO extends IMapper<HostConfigDO> {
|
||||
/**
|
||||
* 设置 keyId 为 NULL
|
||||
*
|
||||
* @param keyId keyId
|
||||
* @param keyIdList keyIdList
|
||||
* @return effect
|
||||
*/
|
||||
int setKeyIdWithNull(@Param("keyId") Long keyId);
|
||||
int setKeyIdWithNull(@Param("keyIdList") List<Long> keyIdList);
|
||||
|
||||
/**
|
||||
* 设置 identityId 为 NULL
|
||||
*
|
||||
* @param identityId identityId
|
||||
* @param identityIdList identityIdList
|
||||
* @return effect
|
||||
*/
|
||||
int setIdentityIdWithNull(@Param("identityId") Long identityId);
|
||||
int setIdentityIdWithNull(@Param("identityIdList") List<Long> identityIdList);
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.orion.visor.framework.mybatis.core.mapper.IMapper;
|
||||
import com.orion.visor.module.asset.entity.domain.HostIdentityDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 主机身份 Mapper 接口
|
||||
@@ -20,13 +21,13 @@ public interface HostIdentityDAO extends IMapper<HostIdentityDO> {
|
||||
/**
|
||||
* 设置 keyId 为 null
|
||||
*
|
||||
* @param keyId keyId
|
||||
* @param keyIdList keyIdList
|
||||
* @return effect
|
||||
*/
|
||||
default int setKeyWithNull(@Param("keyId") Long keyId) {
|
||||
default int setKeyWithNull(List<Long> keyIdList) {
|
||||
LambdaUpdateWrapper<HostIdentityDO> updateWrapper = Wrappers.<HostIdentityDO>lambdaUpdate()
|
||||
.set(HostIdentityDO::getKeyId, null)
|
||||
.eq(HostIdentityDO::getKeyId, keyId);
|
||||
.in(HostIdentityDO::getKeyId, keyIdList);
|
||||
return this.update(null, updateWrapper);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import com.orion.visor.framework.mybatis.core.mapper.IMapper;
|
||||
import com.orion.visor.module.asset.entity.domain.PathBookmarkDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 路径标签 Mapper 接口
|
||||
*
|
||||
@@ -42,4 +44,16 @@ public interface PathBookmarkDAO extends IMapper<PathBookmarkDO> {
|
||||
return this.delete(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 userId 删除
|
||||
*
|
||||
* @param userIdList userIdList
|
||||
* @return effect
|
||||
*/
|
||||
default int deleteByUserIdList(List<Long> userIdList) {
|
||||
LambdaQueryWrapper<PathBookmarkDO> wrapper = this.lambda()
|
||||
.in(PathBookmarkDO::getUserId, userIdList);
|
||||
return this.delete(wrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.orion.visor.module.asset.handler.host.terminal;
|
||||
|
||||
import com.orion.visor.module.asset.define.AssetThreadPools;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.enums.InputTypeEnum;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.manager.TerminalManager;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.manager.HostTerminalManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
@@ -24,7 +24,7 @@ import javax.annotation.Resource;
|
||||
public class TerminalMessageDispatcher extends AbstractWebSocketHandler {
|
||||
|
||||
@Resource
|
||||
private TerminalManager terminalManager;
|
||||
private HostTerminalManager hostTerminalManager;
|
||||
|
||||
@Override
|
||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
|
||||
@@ -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.closeSession(id);
|
||||
hostTerminalManager.closeSession(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||
import com.orion.visor.framework.common.constant.ErrorMessage;
|
||||
import com.orion.visor.framework.websocket.core.utils.WebSockets;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.enums.OutputTypeEnum;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.manager.TerminalManager;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.manager.HostTerminalManager;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.model.TerminalBasePayload;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.model.TerminalConfig;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.session.ITerminalSession;
|
||||
@@ -27,7 +27,7 @@ import java.util.Map;
|
||||
public abstract class AbstractTerminalHandler<T extends TerminalBasePayload> implements ITerminalHandler<T> {
|
||||
|
||||
@Resource
|
||||
protected TerminalManager terminalManager;
|
||||
protected HostTerminalManager hostTerminalManager;
|
||||
|
||||
@Resource
|
||||
private OperatorLogFrameworkService operatorLogFrameworkService;
|
||||
@@ -75,7 +75,7 @@ public abstract class AbstractTerminalHandler<T extends TerminalBasePayload> imp
|
||||
String channelId = channel.getId();
|
||||
String sessionId = payload.getSessionId();
|
||||
// 获取会话并且设置参数
|
||||
ITerminalSession session = terminalManager.getSession(channelId, sessionId);
|
||||
ITerminalSession session = hostTerminalManager.getSession(channelId, sessionId);
|
||||
if (session != null) {
|
||||
TerminalConfig config = session.getConfig();
|
||||
extra.put(OperatorLogs.HOST_ID, config.getHostId());
|
||||
|
||||
@@ -30,7 +30,7 @@ public class SftpChangeModHandler extends AbstractTerminalHandler<SftpChangeModR
|
||||
long startTime = System.currentTimeMillis();
|
||||
// 获取会话
|
||||
String sessionId = payload.getSessionId();
|
||||
ISftpSession session = terminalManager.getSession(channel.getId(), sessionId);
|
||||
ISftpSession session = hostTerminalManager.getSession(channel.getId(), sessionId);
|
||||
String path = payload.getPath();
|
||||
Integer mod = payload.getMod();
|
||||
log.info("SftpChangeModHandler-handle start sessionId: {}, path: {}, mod: {}", sessionId, path, mod);
|
||||
|
||||
@@ -30,7 +30,7 @@ public class SftpDownloadFlatDirectoryHandler extends AbstractTerminalHandler<Sf
|
||||
public void handle(WebSocketSession channel, SftpDownloadFlatDirectoryRequest payload) {
|
||||
// 获取会话
|
||||
String sessionId = payload.getSessionId();
|
||||
ISftpSession session = terminalManager.getSession(channel.getId(), sessionId);
|
||||
ISftpSession session = hostTerminalManager.getSession(channel.getId(), sessionId);
|
||||
String[] paths = payload.getPath().split("\\|");
|
||||
log.info("SftpDownloadFlatDirectoryHandler-handle start sessionId: {}, paths: {}", sessionId, Arrays.toString(paths));
|
||||
Exception ex = null;
|
||||
|
||||
@@ -25,7 +25,7 @@ public class SftpGetContentHandler extends AbstractTerminalHandler<SftpBaseReque
|
||||
public void handle(WebSocketSession channel, SftpBaseRequest payload) {
|
||||
// 获取会话
|
||||
String sessionId = payload.getSessionId();
|
||||
ISftpSession session = terminalManager.getSession(channel.getId(), sessionId);
|
||||
ISftpSession session = hostTerminalManager.getSession(channel.getId(), sessionId);
|
||||
String path = payload.getPath();
|
||||
log.info("SftpGetContentHandler-handle start sessionId: {}, path: {}", sessionId, path);
|
||||
String content = Const.EMPTY;
|
||||
|
||||
@@ -31,7 +31,7 @@ public class SftpListHandler extends AbstractTerminalHandler<SftpListRequest> {
|
||||
public void handle(WebSocketSession channel, SftpListRequest payload) {
|
||||
// 获取会话
|
||||
String sessionId = payload.getSessionId();
|
||||
ISftpSession session = terminalManager.getSession(channel.getId(), sessionId);
|
||||
ISftpSession session = hostTerminalManager.getSession(channel.getId(), sessionId);
|
||||
String path = payload.getPath();
|
||||
log.info("SftpListHandler-handle start sessionId: {}, path: {}", sessionId, path);
|
||||
Exception ex = null;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class SftpMakeDirectoryHandler extends AbstractTerminalHandler<SftpBaseRe
|
||||
long startTime = System.currentTimeMillis();
|
||||
// 获取会话
|
||||
String sessionId = payload.getSessionId();
|
||||
ISftpSession session = terminalManager.getSession(channel.getId(), sessionId);
|
||||
ISftpSession session = hostTerminalManager.getSession(channel.getId(), sessionId);
|
||||
String path = payload.getPath();
|
||||
log.info("SftpMakeDirectoryHandler-handle start sessionId: {}, path: {}", sessionId, path);
|
||||
Exception ex = null;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class SftpMoveHandler extends AbstractTerminalHandler<SftpMoveRequest> {
|
||||
long startTime = System.currentTimeMillis();
|
||||
// 获取会话
|
||||
String sessionId = payload.getSessionId();
|
||||
ISftpSession session = terminalManager.getSession(channel.getId(), sessionId);
|
||||
ISftpSession session = hostTerminalManager.getSession(channel.getId(), sessionId);
|
||||
String path = payload.getPath();
|
||||
String target = payload.getTarget();
|
||||
log.info("SftpMoveHandler-handle start sessionId: {}, path: {}, target: {}", sessionId, path, target);
|
||||
|
||||
@@ -31,7 +31,7 @@ public class SftpRemoveHandler extends AbstractTerminalHandler<SftpBaseRequest>
|
||||
long startTime = System.currentTimeMillis();
|
||||
// 获取会话
|
||||
String sessionId = payload.getSessionId();
|
||||
ISftpSession session = terminalManager.getSession(channel.getId(), sessionId);
|
||||
ISftpSession session = hostTerminalManager.getSession(channel.getId(), sessionId);
|
||||
String[] paths = payload.getPath().split("\\|");
|
||||
log.info("SftpRemoveHandler-handle start sessionId: {}, path: {}", sessionId, Arrays.toString(paths));
|
||||
Exception ex = null;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class SftpSetContentHandler extends AbstractTerminalHandler<SftpSetConten
|
||||
long startTime = System.currentTimeMillis();
|
||||
// 获取会话
|
||||
String sessionId = payload.getSessionId();
|
||||
ISftpSession session = terminalManager.getSession(channel.getId(), sessionId);
|
||||
ISftpSession session = hostTerminalManager.getSession(channel.getId(), sessionId);
|
||||
String path = payload.getPath();
|
||||
log.info("SftpSetContentHandler-handle start sessionId: {}, path: {}", sessionId, path);
|
||||
Exception ex = null;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class SftpTouchHandler extends AbstractTerminalHandler<SftpBaseRequest> {
|
||||
long startTime = System.currentTimeMillis();
|
||||
// 获取会话
|
||||
String sessionId = payload.getSessionId();
|
||||
ISftpSession session = terminalManager.getSession(channel.getId(), sessionId);
|
||||
ISftpSession session = hostTerminalManager.getSession(channel.getId(), sessionId);
|
||||
String path = payload.getPath();
|
||||
log.info("SftpTouchHandler-handle start sessionId: {}, path: {}", sessionId, path);
|
||||
Exception ex = null;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class SftpTruncateHandler extends AbstractTerminalHandler<SftpBaseRequest
|
||||
long startTime = System.currentTimeMillis();
|
||||
// 获取会话
|
||||
String sessionId = payload.getSessionId();
|
||||
ISftpSession session = terminalManager.getSession(channel.getId(), sessionId);
|
||||
ISftpSession session = hostTerminalManager.getSession(channel.getId(), sessionId);
|
||||
String path = payload.getPath();
|
||||
log.info("SftpTruncateHandler-handle start sessionId: {}, path: {}", sessionId, path);
|
||||
Exception ex = null;
|
||||
|
||||
@@ -20,7 +20,7 @@ public class SshInputHandler extends AbstractTerminalHandler<SshInputRequest> {
|
||||
@Override
|
||||
public void handle(WebSocketSession channel, SshInputRequest payload) {
|
||||
// 获取会话
|
||||
ISshSession session = terminalManager.getSession(channel.getId(), payload.getSessionId());
|
||||
ISshSession session = hostTerminalManager.getSession(channel.getId(), payload.getSessionId());
|
||||
// 处理输入
|
||||
session.write(payload.getCommand());
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public class SshResizeHandler extends AbstractTerminalHandler<SshResizeRequest>
|
||||
@Override
|
||||
public void handle(WebSocketSession channel, SshResizeRequest payload) {
|
||||
// 获取会话
|
||||
ISshSession session = terminalManager.getSession(channel.getId(), payload.getSessionId());
|
||||
ISshSession session = hostTerminalManager.getSession(channel.getId(), payload.getSessionId());
|
||||
// 修改大小
|
||||
session.resize(payload.getCols(), payload.getRows());
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ public class TerminalCheckHandler extends AbstractTerminalHandler<TerminalCheckR
|
||||
* @return 是否存在
|
||||
*/
|
||||
private boolean checkSession(WebSocketSession channel, TerminalCheckRequest payload) {
|
||||
ITerminalSession session = terminalManager.getSession(channel.getId(), payload.getSessionId());
|
||||
ITerminalSession session = hostTerminalManager.getSession(channel.getId(), payload.getSessionId());
|
||||
if (session != null) {
|
||||
this.sendCheckFailedMessage(channel, payload, ErrorMessage.SESSION_PRESENT);
|
||||
return true;
|
||||
|
||||
@@ -20,7 +20,7 @@ public class TerminalCloseHandler extends AbstractTerminalHandler<TerminalBasePa
|
||||
public void handle(WebSocketSession channel, TerminalBasePayload payload) {
|
||||
log.info("TerminalCloseHandler-handle start sessionId: {}", payload.getSessionId());
|
||||
// 关闭会话
|
||||
terminalManager.closeSession(channel.getId(), payload.getSessionId());
|
||||
hostTerminalManager.closeSession(channel.getId(), payload.getSessionId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class TerminalConnectHandler extends AbstractTerminalHandler<TerminalConn
|
||||
// 连接主机
|
||||
ITerminalSession session = this.connect(sessionId, connect, channel, payload);
|
||||
// 添加会话到 manager
|
||||
terminalManager.addSession(session);
|
||||
hostTerminalManager.addSession(session);
|
||||
} catch (Exception e) {
|
||||
ex = e;
|
||||
// 修改连接状态为失败
|
||||
|
||||
@@ -26,7 +26,7 @@ public class TerminalPingHandler extends AbstractTerminalHandler<TerminalBasePay
|
||||
// 发送 pong
|
||||
this.send(channel, OutputTypeEnum.PONG.getType());
|
||||
// 活跃 terminal
|
||||
Map<String, ITerminalSession> sessions = terminalManager.getSession(channel.getId());
|
||||
Map<String, ITerminalSession> sessions = hostTerminalManager.getSession(channel.getId());
|
||||
if (!Maps.isEmpty(sessions)) {
|
||||
for (ITerminalSession session : sessions.values()) {
|
||||
session.keepAlive();
|
||||
|
||||
@@ -10,14 +10,14 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 终端管理器
|
||||
* 主机终端管理器
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/1/3 11:35
|
||||
*/
|
||||
@Component
|
||||
public class TerminalManager {
|
||||
public class HostTerminalManager {
|
||||
|
||||
/**
|
||||
* 会话存储器
|
||||
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.orion.lang.utils.io.Streams;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.handler.ITransferHandler;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.handler.TransferHandler;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.manager.HostTransferManager;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.model.TransferOperatorRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -13,7 +14,7 @@ import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* sftp 传输消息处理器
|
||||
@@ -26,24 +27,30 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
@Component
|
||||
public class TransferMessageDispatcher extends AbstractWebSocketHandler {
|
||||
|
||||
private final ConcurrentHashMap<String, ITransferHandler> handlers = new ConcurrentHashMap<>();
|
||||
@Resource
|
||||
private HostTransferManager hostTransferManager;
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) {
|
||||
log.info("TransferMessageHandler-afterConnectionEstablished id: {}", session.getId());
|
||||
// 添加处理器
|
||||
hostTransferManager.putHandler(session.getId(), new TransferHandler(session));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
|
||||
// 获取处理器
|
||||
ITransferHandler handler = handlers.computeIfAbsent(session.getId(), s -> new TransferHandler(session));
|
||||
ITransferHandler handler = hostTransferManager.getHandler(session.getId());
|
||||
// 处理消息
|
||||
handler.handleMessage(JSON.parseObject(message.getPayload(), TransferOperatorRequest.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
|
||||
handlers.get(session.getId()).putContent(message.getPayload().array());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) {
|
||||
log.info("TransferMessageHandler-afterConnectionEstablished id: {}", session.getId());
|
||||
// 获取处理器
|
||||
ITransferHandler handler = hostTransferManager.getHandler(session.getId());
|
||||
// 添加数据
|
||||
handler.putContent(message.getPayload().array());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,7 +63,7 @@ public class TransferMessageDispatcher extends AbstractWebSocketHandler {
|
||||
String id = session.getId();
|
||||
log.info("TransferMessageHandler-afterConnectionClosed id: {}, code: {}, reason: {}", id, status.getCode(), status.getReason());
|
||||
// 关闭会话
|
||||
Streams.close(handlers.remove(id));
|
||||
Streams.close(hostTransferManager.removeHandler(id));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@ public enum TransferOperatorType {
|
||||
UPLOAD_ERROR(TransferOperatorType.UPLOAD, "uploadError"),
|
||||
|
||||
/**
|
||||
* 开始下载
|
||||
* 初始化下载
|
||||
*/
|
||||
DOWNLOAD_START(TransferOperatorType.DOWNLOAD, "downloadStart"),
|
||||
DOWNLOAD_INIT(TransferOperatorType.DOWNLOAD, "downloadInit"),
|
||||
|
||||
/**
|
||||
* 中断下载
|
||||
@@ -45,7 +45,7 @@ public enum TransferOperatorType {
|
||||
|
||||
public static final String DOWNLOAD = "DOWNLOAD";
|
||||
|
||||
private final String operator;
|
||||
private final String kind;
|
||||
|
||||
private final String type;
|
||||
|
||||
|
||||
@@ -34,6 +34,16 @@ public enum TransferReceiverType {
|
||||
*/
|
||||
UPLOAD_ERROR("uploadError"),
|
||||
|
||||
/**
|
||||
* 开始下载
|
||||
*/
|
||||
DOWNLOAD_START("downloadStart"),
|
||||
|
||||
/**
|
||||
* 下载进度
|
||||
*/
|
||||
DOWNLOAD_PROGRESS("downloadProgress"),
|
||||
|
||||
/**
|
||||
* 下载完成
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,9 @@ package com.orion.visor.module.asset.handler.host.transfer.handler;
|
||||
|
||||
import com.orion.lang.able.SafeCloseable;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.model.TransferOperatorRequest;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.session.IDownloadSession;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 传输处理器定义
|
||||
@@ -26,4 +29,11 @@ public interface ITransferHandler extends SafeCloseable {
|
||||
*/
|
||||
void putContent(byte[] content);
|
||||
|
||||
/**
|
||||
* 获取 token sessions
|
||||
*
|
||||
* @return token sessions
|
||||
*/
|
||||
Map<String, IDownloadSession> getTokenSessions();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.orion.visor.module.asset.handler.host.transfer.handler;
|
||||
|
||||
import com.orion.lang.id.UUIds;
|
||||
import com.orion.lang.utils.Exceptions;
|
||||
import com.orion.lang.utils.io.Streams;
|
||||
import com.orion.net.host.SessionStore;
|
||||
@@ -14,6 +15,7 @@ import com.orion.visor.module.asset.handler.host.transfer.model.TransferOperator
|
||||
import com.orion.visor.module.asset.handler.host.transfer.session.*;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.utils.TransferUtils;
|
||||
import com.orion.visor.module.asset.service.HostTerminalService;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
@@ -45,10 +47,14 @@ public class TransferHandler implements ITransferHandler {
|
||||
*/
|
||||
private final ConcurrentHashMap<String, ITransferHostSession> sessions;
|
||||
|
||||
@Getter
|
||||
private final ConcurrentHashMap<String, IDownloadSession> tokenSessions;
|
||||
|
||||
public TransferHandler(WebSocketSession channel) {
|
||||
this.channel = channel;
|
||||
this.userId = WebSockets.getAttr(channel, ExtraFieldConst.USER_ID);
|
||||
this.sessions = new ConcurrentHashMap<>();
|
||||
this.tokenSessions = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,9 +79,11 @@ public class TransferHandler implements ITransferHandler {
|
||||
// 上传失败
|
||||
((IUploadSession) currentSession).uploadError();
|
||||
break;
|
||||
case DOWNLOAD_START:
|
||||
case DOWNLOAD_INIT:
|
||||
// 开始下载
|
||||
((IDownloadSession) currentSession).startDownload(payload.getPath());
|
||||
String token = UUIds.random32();
|
||||
tokenSessions.put(token, (IDownloadSession) currentSession);
|
||||
((IDownloadSession) currentSession).downloadInit(payload.getPath(), token);
|
||||
break;
|
||||
case DOWNLOAD_ABORT:
|
||||
// 中断下载
|
||||
@@ -100,7 +108,7 @@ public class TransferHandler implements ITransferHandler {
|
||||
*/
|
||||
private boolean getAndInitSession(TransferOperatorRequest payload, TransferOperatorType type) {
|
||||
Long hostId = payload.getHostId();
|
||||
String sessionKey = hostId + "_" + type.getOperator();
|
||||
String sessionKey = hostId + "_" + type.getKind();
|
||||
try {
|
||||
// 获取会话
|
||||
ITransferHostSession session = sessions.get(sessionKey);
|
||||
@@ -109,10 +117,10 @@ public class TransferHandler implements ITransferHandler {
|
||||
HostTerminalConnectDTO connectInfo = hostTerminalService.getTerminalConnectInfo(this.userId, hostId);
|
||||
SessionStore sessionStore = hostTerminalService.openSessionStore(connectInfo);
|
||||
// 打开会话并初始化
|
||||
if (TransferOperatorType.UPLOAD.equals(type.getOperator())) {
|
||||
if (TransferOperatorType.UPLOAD.equals(type.getKind())) {
|
||||
// 上传操作
|
||||
session = new UploadSession(connectInfo, sessionStore, this.channel);
|
||||
} else if (TransferOperatorType.DOWNLOAD.equals(type.getOperator())) {
|
||||
} else if (TransferOperatorType.DOWNLOAD.equals(type.getKind())) {
|
||||
// 下载操作
|
||||
session = new DownloadSession(connectInfo, sessionStore, this.channel);
|
||||
} else {
|
||||
@@ -136,6 +144,7 @@ public class TransferHandler implements ITransferHandler {
|
||||
public void close() {
|
||||
log.info("TransferHandler.close channelId: {}", channel.getId());
|
||||
sessions.values().forEach(Streams::close);
|
||||
tokenSessions.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.orion.visor.module.asset.handler.host.transfer.manager;
|
||||
|
||||
import com.orion.visor.module.asset.handler.host.transfer.handler.ITransferHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 主机传输管理器
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/6/4 17:58
|
||||
*/
|
||||
@Component
|
||||
public class HostTransferManager {
|
||||
|
||||
private final ConcurrentHashMap<String, ITransferHandler> handlers = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 添加处理器
|
||||
*
|
||||
* @param id id
|
||||
* @param handler handler
|
||||
*/
|
||||
public void putHandler(String id, ITransferHandler handler) {
|
||||
handlers.put(id, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取处理器
|
||||
*
|
||||
* @param id id
|
||||
* @return handler
|
||||
*/
|
||||
public ITransferHandler getHandler(String id) {
|
||||
return handlers.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除处理器
|
||||
*
|
||||
* @param id id
|
||||
* @return handler
|
||||
*/
|
||||
public ITransferHandler removeHandler(String id) {
|
||||
return handlers.remove(id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import lombok.NoArgsConstructor;
|
||||
@Schema(name = "FileOperatorRequest", description = "文件操作请求 实体对象")
|
||||
public class TransferOperatorRequest {
|
||||
|
||||
@Schema(description = "上传路径")
|
||||
@Schema(description = "文件路径")
|
||||
private String path;
|
||||
|
||||
@Schema(description = "type")
|
||||
|
||||
@@ -20,6 +20,9 @@ import lombok.NoArgsConstructor;
|
||||
@Schema(name = "FileOperatorResponse", description = "文件操作响应 实体对象")
|
||||
public class TransferOperatorResponse {
|
||||
|
||||
@Schema(description = "channelId")
|
||||
private String channelId;
|
||||
|
||||
@Schema(description = "type")
|
||||
private String type;
|
||||
|
||||
@@ -29,6 +32,12 @@ public class TransferOperatorResponse {
|
||||
@Schema(description = "是否成功")
|
||||
private Boolean success;
|
||||
|
||||
@Schema(description = "传输的大小")
|
||||
private Integer currentSize;
|
||||
|
||||
@Schema(description = "transferToken")
|
||||
private String transferToken;
|
||||
|
||||
@Schema(description = "消息")
|
||||
private String msg;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.orion.visor.module.asset.handler.host.transfer.session;
|
||||
|
||||
import com.orion.lang.define.wrapper.Ref;
|
||||
import com.orion.lang.utils.Threads;
|
||||
import com.orion.lang.utils.Valid;
|
||||
import com.orion.lang.utils.io.Streams;
|
||||
@@ -12,11 +13,13 @@ import com.orion.visor.module.asset.define.operator.HostTerminalOperatorType;
|
||||
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.enums.TransferReceiverType;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.utils.TransferUtils;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.socket.BinaryMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* 下载会话实现
|
||||
@@ -28,6 +31,9 @@ import java.io.InputStream;
|
||||
@Slf4j
|
||||
public class DownloadSession extends TransferHostSession implements IDownloadSession {
|
||||
|
||||
@Getter
|
||||
private String path;
|
||||
|
||||
private InputStream inputStream;
|
||||
|
||||
public DownloadSession(HostTerminalConnectDTO connectInfo, SessionStore sessionStore, WebSocketSession channel) {
|
||||
@@ -35,7 +41,8 @@ public class DownloadSession extends TransferHostSession implements IDownloadSes
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startDownload(String path) {
|
||||
public void downloadInit(String path, String token) {
|
||||
this.path = path;
|
||||
String channelId = channel.getId();
|
||||
try {
|
||||
log.info("DownloadSession.startDownload open start channelId: {}, path: {}", channelId, path);
|
||||
@@ -54,39 +61,17 @@ public class DownloadSession extends TransferHostSession implements IDownloadSes
|
||||
}
|
||||
// 打开输入流
|
||||
this.inputStream = executor.openInputStream(path);
|
||||
// 响应开始下载
|
||||
TransferUtils.sendMessage(this.channel, TransferReceiverType.DOWNLOAD_START, null, e -> {
|
||||
e.setChannelId(channelId);
|
||||
e.setTransferToken(token);
|
||||
});
|
||||
log.info("DownloadSession.startDownload open success channelId: {}, path: {}", channelId, path);
|
||||
} catch (Exception e) {
|
||||
log.error("DownloadSession.startDownload open error channelId: {}, path: {}", channelId, path, e);
|
||||
// 响应结果
|
||||
// 响应下载失败
|
||||
TransferUtils.sendMessage(this.channel, TransferReceiverType.DOWNLOAD_ERROR, e);
|
||||
return;
|
||||
}
|
||||
// 异步读取文件内容
|
||||
AssetThreadPools.TERMINAL_OPERATOR.execute(() -> {
|
||||
Exception ex = null;
|
||||
try {
|
||||
byte[] buffer = new byte[Const.BUFFER_KB_32];
|
||||
int len;
|
||||
// 响应文件内容
|
||||
while (this.inputStream != null && (len = this.inputStream.read(buffer)) != -1) {
|
||||
this.channel.sendMessage(new BinaryMessage(buffer, 0, len, true));
|
||||
}
|
||||
log.info("DownloadSession.download finish channelId: {}, path: {}", channelId, path);
|
||||
} catch (Exception e) {
|
||||
log.error("DownloadSession.download error channelId: {}, path: {}", channelId, path, e);
|
||||
ex = e;
|
||||
}
|
||||
// 关闭等待 jsch 内部处理
|
||||
Threads.sleep(100);
|
||||
this.closeStream();
|
||||
Threads.sleep(100);
|
||||
// 响应结果
|
||||
if (ex == null) {
|
||||
TransferUtils.sendMessage(this.channel, TransferReceiverType.DOWNLOAD_FINISH, null);
|
||||
} else {
|
||||
TransferUtils.sendMessage(this.channel, TransferReceiverType.DOWNLOAD_ERROR, ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -96,9 +81,72 @@ public class DownloadSession extends TransferHostSession implements IDownloadSes
|
||||
this.closeStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(OutputStream outputStream) {
|
||||
String channelId = channel.getId();
|
||||
Ref<Exception> ex = new Ref<>();
|
||||
try {
|
||||
byte[] buffer = new byte[Const.BUFFER_KB_32];
|
||||
int len;
|
||||
int i = 0;
|
||||
int size = 0;
|
||||
// 响应文件内容
|
||||
while (this.inputStream != null && (len = this.inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, len);
|
||||
size += len;
|
||||
// 不要每次都 flush 和 send > 1mb
|
||||
if (i == 32) {
|
||||
i = 0;
|
||||
}
|
||||
// 首次触发
|
||||
if (i == 0) {
|
||||
this.flushAndSendProgress(outputStream, size);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// 最后一次也要 flush
|
||||
if (i != 0) {
|
||||
this.flushAndSendProgress(outputStream, size);
|
||||
}
|
||||
log.info("DownloadSession.download finish channelId: {}, path: {}", channelId, path);
|
||||
} catch (Exception e) {
|
||||
log.error("DownloadSession.download error channelId: {}, path: {}", channelId, path, e);
|
||||
ex.set(e);
|
||||
}
|
||||
// 异步关闭
|
||||
AssetThreadPools.TERMINAL_OPERATOR.execute(() -> {
|
||||
// 关闭等待 jsch 内部处理
|
||||
Threads.sleep(100);
|
||||
this.closeStream();
|
||||
Threads.sleep(100);
|
||||
// 响应结果
|
||||
Exception e = ex.getValue();
|
||||
if (e == null) {
|
||||
TransferUtils.sendMessage(this.channel, TransferReceiverType.DOWNLOAD_FINISH, null);
|
||||
} else {
|
||||
TransferUtils.sendMessage(this.channel, TransferReceiverType.DOWNLOAD_ERROR, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷流 & 发送进度
|
||||
*
|
||||
* @param outputStream outputStream
|
||||
* @param size size
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
private void flushAndSendProgress(OutputStream outputStream, int size) throws IOException {
|
||||
// flush
|
||||
outputStream.flush();
|
||||
// send
|
||||
TransferUtils.sendMessage(this.channel, TransferReceiverType.DOWNLOAD_PROGRESS, null, e -> e.setCurrentSize(size));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeStream() {
|
||||
// 关闭 inputStream 可能会被阻塞 ???...??? 只能关闭 executor
|
||||
this.path = null;
|
||||
Streams.close(this.executor);
|
||||
this.executor = null;
|
||||
this.inputStream = null;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.orion.visor.module.asset.handler.host.transfer.session;
|
||||
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
/**
|
||||
* 下载会话定义
|
||||
*
|
||||
@@ -7,18 +9,26 @@ package com.orion.visor.module.asset.handler.host.transfer.session;
|
||||
* @version 1.0.0
|
||||
* @since 2024/2/22 22:25
|
||||
*/
|
||||
public interface IDownloadSession {
|
||||
public interface IDownloadSession extends StreamingResponseBody {
|
||||
|
||||
/**
|
||||
* 开始下载
|
||||
* 初始化下载
|
||||
*
|
||||
* @param path path
|
||||
* @param path path
|
||||
* @param token token
|
||||
*/
|
||||
void startDownload(String path);
|
||||
void downloadInit(String path, String token);
|
||||
|
||||
/**
|
||||
* 停止下载
|
||||
*/
|
||||
void abortDownload();
|
||||
|
||||
/**
|
||||
* 获取下载文件路径
|
||||
*
|
||||
* @return path
|
||||
*/
|
||||
String getPath();
|
||||
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import com.orion.visor.framework.common.constant.ErrorMessage;
|
||||
import com.orion.visor.framework.websocket.core.utils.WebSockets;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.enums.TransferReceiverType;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.model.TransferOperatorResponse;
|
||||
import org.apache.catalina.connector.ClientAbortException;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 传输工具类
|
||||
*
|
||||
@@ -28,11 +31,26 @@ public class TransferUtils {
|
||||
* @param ex ex
|
||||
*/
|
||||
public static void sendMessage(WebSocketSession channel, TransferReceiverType type, Exception ex) {
|
||||
sendMessage(channel, type, ex, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param channel channel
|
||||
* @param type type
|
||||
* @param ex ex
|
||||
* @param filler filler
|
||||
*/
|
||||
public static void sendMessage(WebSocketSession channel, TransferReceiverType type, Exception ex, Consumer<TransferOperatorResponse> filler) {
|
||||
TransferOperatorResponse resp = TransferOperatorResponse.builder()
|
||||
.type(type.getType())
|
||||
.success(ex == null)
|
||||
.msg(TransferUtils.getErrorMessage(ex))
|
||||
.build();
|
||||
if (filler != null) {
|
||||
filler.accept(resp);
|
||||
}
|
||||
WebSockets.sendText(channel, JSON.toJSONString(resp));
|
||||
}
|
||||
|
||||
@@ -45,9 +63,10 @@ public class TransferUtils {
|
||||
public static String getErrorMessage(Exception ex) {
|
||||
if (ex == null) {
|
||||
return null;
|
||||
}
|
||||
if (ex instanceof InvalidArgumentException) {
|
||||
} else if (ex instanceof InvalidArgumentException) {
|
||||
return ex.getMessage();
|
||||
} else if (ex instanceof ClientAbortException) {
|
||||
return ErrorMessage.CLIENT_ABORT;
|
||||
}
|
||||
return ErrorMessage.OPERATE_ERROR;
|
||||
}
|
||||
|
||||
@@ -46,14 +46,6 @@ public interface CommandSnippetService {
|
||||
*/
|
||||
List<CommandSnippetVO> getCommandSnippetList();
|
||||
|
||||
/**
|
||||
* 删除命令片段
|
||||
*
|
||||
* @param id id
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteCommandSnippetById(Long id);
|
||||
|
||||
/**
|
||||
* 设置分组为 null
|
||||
*
|
||||
@@ -63,6 +55,14 @@ public interface CommandSnippetService {
|
||||
*/
|
||||
Integer setGroupNull(Long userId, Long groupId);
|
||||
|
||||
/**
|
||||
* 删除命令片段
|
||||
*
|
||||
* @param id id
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteCommandSnippetById(Long id);
|
||||
|
||||
/**
|
||||
* 通过 groupId 删除
|
||||
*
|
||||
@@ -72,4 +72,12 @@ public interface CommandSnippetService {
|
||||
*/
|
||||
Integer deleteByGroupId(Long userId, Long groupId);
|
||||
|
||||
/**
|
||||
* 通过 userId 删除
|
||||
*
|
||||
* @param userIdList userIdList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteByUserIdList(List<Long> userIdList);
|
||||
|
||||
}
|
||||
|
||||
@@ -35,6 +35,14 @@ public interface ExecJobHostService {
|
||||
*/
|
||||
Integer deleteByJobId(Long jobId);
|
||||
|
||||
/**
|
||||
* 通过 jobId 删除
|
||||
*
|
||||
* @param jobIdList jobIdList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteByJobIdList(List<Long> jobIdList);
|
||||
|
||||
/**
|
||||
* 通过 hostId 删除
|
||||
*
|
||||
@@ -43,4 +51,12 @@ public interface ExecJobHostService {
|
||||
*/
|
||||
Integer deleteByHostId(Long hostId);
|
||||
|
||||
/**
|
||||
* 通过 hostId 删除
|
||||
*
|
||||
* @param hostIdList hostIdList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteByHostIdList(List<Long> hostIdList);
|
||||
|
||||
}
|
||||
|
||||
@@ -78,6 +78,14 @@ public interface ExecJobService {
|
||||
*/
|
||||
Integer deleteExecJobById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除计划任务
|
||||
*
|
||||
* @param idList idList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteExecJobByIdList(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 手动触发任务
|
||||
*
|
||||
|
||||
@@ -45,6 +45,14 @@ public interface ExecTemplateHostService {
|
||||
*/
|
||||
Integer deleteByTemplateId(Long templateId);
|
||||
|
||||
/**
|
||||
* 通过 templateId 删除
|
||||
*
|
||||
* @param templateIdList templateIdList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteByTemplateIdList(List<Long> templateIdList);
|
||||
|
||||
/**
|
||||
* 通过 hostId 删除
|
||||
*
|
||||
@@ -53,4 +61,12 @@ public interface ExecTemplateHostService {
|
||||
*/
|
||||
Integer deleteByHostId(Long hostId);
|
||||
|
||||
/**
|
||||
* 通过 hostId 删除
|
||||
*
|
||||
* @param hostIdList hostIdList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteByHostIdList(List<Long> hostIdList);
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.orion.visor.module.asset.entity.request.exec.ExecTemplateQueryRequest
|
||||
import com.orion.visor.module.asset.entity.request.exec.ExecTemplateUpdateRequest;
|
||||
import com.orion.visor.module.asset.entity.vo.ExecTemplateVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 执行模板 服务类
|
||||
*
|
||||
@@ -63,4 +65,12 @@ public interface ExecTemplateService {
|
||||
*/
|
||||
Integer deleteExecTemplateById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除执行模板
|
||||
*
|
||||
* @param idList idList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteExecTemplateByIdList(List<Long> idList);
|
||||
|
||||
}
|
||||
|
||||
@@ -64,4 +64,12 @@ public interface HostIdentityService {
|
||||
*/
|
||||
Integer deleteHostIdentityById(Long id);
|
||||
|
||||
/**
|
||||
* 通过 id 批量删除主机身份
|
||||
*
|
||||
* @param idList idList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteHostIdentityByIdList(List<Long> idList);
|
||||
|
||||
}
|
||||
|
||||
@@ -66,11 +66,19 @@ public interface HostKeyService {
|
||||
DataGrid<HostKeyVO> getHostKeyPage(HostKeyQueryRequest request);
|
||||
|
||||
/**
|
||||
* 通过 id 删除主机密钥
|
||||
* 通过 id 批量删除主机密钥
|
||||
*
|
||||
* @param id id
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteHostKeyById(Long id);
|
||||
|
||||
/**
|
||||
* 通过 id 删除主机密钥
|
||||
*
|
||||
* @param idList idList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteHostKeyByIdList(List<Long> idList);
|
||||
|
||||
}
|
||||
|
||||
@@ -64,11 +64,19 @@ public interface HostService {
|
||||
*/
|
||||
Integer deleteHostById(Long id);
|
||||
|
||||
/**
|
||||
* 通过 id 批量删除主机
|
||||
*
|
||||
* @param idList idList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteHostByIdList(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 通过 id 删除主机引用
|
||||
*
|
||||
* @param id id
|
||||
* @param idList idList
|
||||
*/
|
||||
void deleteHostRelByIdAsync(Long id);
|
||||
void deleteHostRelByIdListAsync(List<Long> idList);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,17 +3,19 @@ package com.orion.visor.module.asset.service;
|
||||
import com.orion.lang.define.wrapper.DataGrid;
|
||||
import com.orion.visor.module.asset.entity.request.host.HostSftpLogQueryRequest;
|
||||
import com.orion.visor.module.asset.entity.vo.HostSftpLogVO;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* SFTP 操作日志 服务类
|
||||
* SFTP 操作 服务类
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023-12-26 22:09
|
||||
*/
|
||||
public interface HostSftpLogService {
|
||||
public interface HostSftpService {
|
||||
|
||||
/**
|
||||
* 分页查询 SFTP 操作日志
|
||||
@@ -31,4 +33,16 @@ public interface HostSftpLogService {
|
||||
*/
|
||||
Integer deleteHostSftpLog(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 通过 transferToken 下载
|
||||
*
|
||||
* @param channelId channelId
|
||||
* @param transferToken transferToken
|
||||
* @param response response
|
||||
* @return body
|
||||
*/
|
||||
StreamingResponseBody downloadWithTransferToken(String channelId,
|
||||
String transferToken,
|
||||
HttpServletResponse response);
|
||||
|
||||
}
|
||||
@@ -46,14 +46,6 @@ public interface PathBookmarkService {
|
||||
*/
|
||||
List<PathBookmarkVO> getPathBookmarkList();
|
||||
|
||||
/**
|
||||
* 删除路径标签
|
||||
*
|
||||
* @param id id
|
||||
* @return effect
|
||||
*/
|
||||
Integer deletePathBookmarkById(Long id);
|
||||
|
||||
/**
|
||||
* 设置分组为 null
|
||||
*
|
||||
@@ -63,6 +55,14 @@ public interface PathBookmarkService {
|
||||
*/
|
||||
Integer setGroupNull(Long userId, Long groupId);
|
||||
|
||||
/**
|
||||
* 删除路径标签
|
||||
*
|
||||
* @param id id
|
||||
* @return effect
|
||||
*/
|
||||
Integer deletePathBookmarkById(Long id);
|
||||
|
||||
/**
|
||||
* 通过 groupId 删除
|
||||
*
|
||||
@@ -72,4 +72,12 @@ public interface PathBookmarkService {
|
||||
*/
|
||||
Integer deleteByGroupId(Long userId, Long groupId);
|
||||
|
||||
/**
|
||||
* 通过 userId 删除
|
||||
*
|
||||
* @param userIdList userIdList
|
||||
* @return effect
|
||||
*/
|
||||
Integer deleteByUserIdList(List<Long> userIdList);
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.orion.visor.module.asset.service.CommandSnippetGroupService;
|
||||
import com.orion.visor.module.asset.service.CommandSnippetService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Comparator;
|
||||
@@ -52,7 +51,7 @@ public class CommandSnippetServiceImpl implements CommandSnippetService {
|
||||
@Override
|
||||
public Long createCommandSnippet(CommandSnippetCreateRequest request) {
|
||||
Long userId = SecurityUtils.getLoginUserId();
|
||||
log.info("CommandSnippetService-createCommandSnippet request: {}", JSON.toJSONString(request));
|
||||
log.info("CommandSnippetService-createCommandSnippet request: {}" , JSON.toJSONString(request));
|
||||
// 转换
|
||||
CommandSnippetDO record = CommandSnippetConvert.MAPPER.to(request);
|
||||
record.setUserId(userId);
|
||||
@@ -61,7 +60,7 @@ public class CommandSnippetServiceImpl implements CommandSnippetService {
|
||||
// 插入
|
||||
int effect = commandSnippetDAO.insert(record);
|
||||
Long id = record.getId();
|
||||
log.info("CommandSnippetService-createCommandSnippet id: {}, effect: {}", id, effect);
|
||||
log.info("CommandSnippetService-createCommandSnippet id: {}, effect: {}" , id, effect);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(CommandSnippetCacheKeyDefine.SNIPPET.format(userId));
|
||||
return id;
|
||||
@@ -71,7 +70,7 @@ public class CommandSnippetServiceImpl implements CommandSnippetService {
|
||||
public Integer updateCommandSnippetById(CommandSnippetUpdateRequest request) {
|
||||
Long id = Valid.notNull(request.getId(), ErrorMessage.ID_MISSING);
|
||||
Long userId = SecurityUtils.getLoginUserId();
|
||||
log.info("CommandSnippetService-updateCommandSnippetById id: {}, request: {}", id, JSON.toJSONString(request));
|
||||
log.info("CommandSnippetService-updateCommandSnippetById id: {}, request: {}" , id, JSON.toJSONString(request));
|
||||
// 查询
|
||||
CommandSnippetDO record = commandSnippetDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
@@ -86,7 +85,7 @@ public class CommandSnippetServiceImpl implements CommandSnippetService {
|
||||
.eq(CommandSnippetDO::getId, id)
|
||||
.eq(CommandSnippetDO::getUserId, userId);
|
||||
int effect = commandSnippetDAO.update(null, update);
|
||||
log.info("CommandSnippetService-updateCommandSnippetById effect: {}", effect);
|
||||
log.info("CommandSnippetService-updateCommandSnippetById effect: {}" , effect);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(CommandSnippetCacheKeyDefine.SNIPPET.format(userId));
|
||||
return effect;
|
||||
@@ -145,29 +144,28 @@ public class CommandSnippetServiceImpl implements CommandSnippetService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer setGroupNull(Long userId, Long groupId) {
|
||||
int effect = commandSnippetDAO.setGroupIdWithNull(groupId);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(CommandSnippetCacheKeyDefine.SNIPPET.format(userId));
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteCommandSnippetById(Long id) {
|
||||
Long userId = SecurityUtils.getLoginUserId();
|
||||
log.info("CommandSnippetService-deleteCommandSnippetById id: {}", id);
|
||||
log.info("CommandSnippetService-deleteCommandSnippetById id: {}" , id);
|
||||
// 检查数据是否存在
|
||||
CommandSnippetDO record = commandSnippetDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
// 删除
|
||||
int effect = commandSnippetDAO.deleteById(id);
|
||||
log.info("CommandSnippetService-deleteCommandSnippetById id: {}, effect: {}", id, effect);
|
||||
log.info("CommandSnippetService-deleteCommandSnippetById id: {}, effect: {}" , id, effect);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(CommandSnippetCacheKeyDefine.SNIPPET.format(userId), id);
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer setGroupNull(Long userId, Long groupId) {
|
||||
int effect = commandSnippetDAO.setGroupIdWithNull(groupId);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(CommandSnippetCacheKeyDefine.SNIPPET.format(userId));
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteByGroupId(Long userId, Long groupId) {
|
||||
int effect = commandSnippetDAO.deleteByGroupId(groupId);
|
||||
@@ -176,6 +174,11 @@ public class CommandSnippetServiceImpl implements CommandSnippetService {
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteByUserIdList(List<Long> userIdList) {
|
||||
return commandSnippetDAO.deleteByUserIdList(userIdList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查对象是否存在
|
||||
*
|
||||
|
||||
@@ -49,9 +49,19 @@ public class ExecJobHostServiceImpl implements ExecJobHostService {
|
||||
return execJobHostDAO.deleteByJobId(jobId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteByJobIdList(List<Long> jobIdList) {
|
||||
return execJobHostDAO.deleteByJobIdList(jobIdList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteByHostId(Long hostId) {
|
||||
return execJobHostDAO.deleteByHostId(hostId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteByHostIdList(List<Long> hostIdList) {
|
||||
return execJobHostDAO.deleteByHostIdList(hostIdList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.orion.lang.utils.Strings;
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.lang.utils.time.cron.Cron;
|
||||
import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||
import com.orion.visor.framework.common.constant.Const;
|
||||
import com.orion.visor.framework.common.constant.ErrorMessage;
|
||||
import com.orion.visor.framework.common.utils.Valid;
|
||||
import com.orion.visor.framework.job.core.utils.QuartzUtils;
|
||||
@@ -235,19 +236,30 @@ public class ExecJobServiceImpl implements ExecJobService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer deleteExecJobById(Long id) {
|
||||
log.info("ExecJobService-deleteExecJobById id: {}", id);
|
||||
return this.deleteExecJobByIdList(Lists.singleton(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer deleteExecJobByIdList(List<Long> idList) {
|
||||
log.info("ExecJobService-deleteExecJobByIdList idList: {}", idList);
|
||||
// 检查数据是否存在
|
||||
ExecJobDO record = execJobDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
List<ExecJobDO> jobList = execJobDAO.selectBatchIds(idList);
|
||||
Valid.notEmpty(jobList, ErrorMessage.DATA_ABSENT);
|
||||
// 删除任务
|
||||
int effect = execJobDAO.deleteById(id);
|
||||
int effect = execJobDAO.deleteBatchIds(idList);
|
||||
// 删除任务主机
|
||||
effect += execJobHostService.deleteByJobId(id);
|
||||
effect += execJobHostService.deleteByJobIdList(idList);
|
||||
// 设置日志参数
|
||||
OperatorLogs.add(OperatorLogs.NAME, record.getName());
|
||||
String name = jobList.stream()
|
||||
.map(ExecJobDO::getName)
|
||||
.collect(Collectors.joining(Const.COMMA));
|
||||
OperatorLogs.add(OperatorLogs.NAME, name);
|
||||
// 设置 quartz 状态
|
||||
this.setQuartzJobStatus(record, true, false);
|
||||
log.info("ExecJobService-deleteExecJobById id: {}, effect: {}", id, effect);
|
||||
for (ExecJobDO job : jobList) {
|
||||
this.setQuartzJobStatus(job, true, false);
|
||||
}
|
||||
log.info("ExecJobService-deleteExecJobByIdList idList: {}, effect: {}", idList, effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,20 +97,40 @@ public class ExecTemplateHostServiceImpl implements ExecTemplateHostService {
|
||||
public Integer deleteByTemplateId(Long templateId) {
|
||||
LambdaQueryWrapper<ExecTemplateHostDO> wrapper = execTemplateHostDAO.lambda()
|
||||
.eq(ExecTemplateHostDO::getTemplateId, templateId);
|
||||
log.info("ExecTemplateHostService-deleteByTemplateId idList: {}", templateId);
|
||||
log.info("ExecTemplateHostService-deleteByTemplateId id: {}", templateId);
|
||||
int effect = execTemplateHostDAO.delete(wrapper);
|
||||
log.info("ExecTemplateHostService-deleteByTemplateId effect: {}", effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteByTemplateIdList(List<Long> templateIdList) {
|
||||
LambdaQueryWrapper<ExecTemplateHostDO> wrapper = execTemplateHostDAO.lambda()
|
||||
.in(ExecTemplateHostDO::getTemplateId, templateIdList);
|
||||
log.info("ExecTemplateHostService-deleteByTemplateIdList idList: {}", templateIdList);
|
||||
int effect = execTemplateHostDAO.delete(wrapper);
|
||||
log.info("ExecTemplateHostService-deleteByTemplateIdList effect: {}", effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteByHostId(Long hostId) {
|
||||
LambdaQueryWrapper<ExecTemplateHostDO> wrapper = execTemplateHostDAO.lambda()
|
||||
.eq(ExecTemplateHostDO::getHostId, hostId);
|
||||
log.info("ExecTemplateHostService-deleteByHostId idList: {}", hostId);
|
||||
log.info("ExecTemplateHostService-deleteByHostId id: {}", hostId);
|
||||
int effect = execTemplateHostDAO.delete(wrapper);
|
||||
log.info("ExecTemplateHostService-deleteByHostId effect: {}", effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteByHostIdList(List<Long> hostIdList) {
|
||||
LambdaQueryWrapper<ExecTemplateHostDO> wrapper = execTemplateHostDAO.lambda()
|
||||
.in(ExecTemplateHostDO::getHostId, hostIdList);
|
||||
log.info("ExecTemplateHostService-deleteByHostIdList id: {}", hostIdList);
|
||||
int effect = execTemplateHostDAO.delete(wrapper);
|
||||
log.info("ExecTemplateHostService-deleteByHostIdList effect: {}", effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ 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.collect.Lists;
|
||||
import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||
import com.orion.visor.framework.common.constant.Const;
|
||||
import com.orion.visor.framework.common.constant.ErrorMessage;
|
||||
import com.orion.visor.framework.common.utils.Valid;
|
||||
import com.orion.visor.framework.security.core.utils.SecurityUtils;
|
||||
@@ -21,10 +23,12 @@ import com.orion.visor.module.asset.service.ExecTemplateHostService;
|
||||
import com.orion.visor.module.asset.service.ExecTemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 执行模板 服务实现类
|
||||
@@ -126,16 +130,28 @@ public class ExecTemplateServiceImpl implements ExecTemplateService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer deleteExecTemplateById(Long id) {
|
||||
log.info("ExecTemplateService-deleteExecTemplateById id: {}", id);
|
||||
return this.deleteExecTemplateByIdList(Lists.singleton(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer deleteExecTemplateByIdList(List<Long> idList) {
|
||||
log.info("ExecTemplateService-deleteExecTemplateByIdList idList: {}", idList);
|
||||
// 检查数据是否存在
|
||||
ExecTemplateDO record = execTemplateDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
List<ExecTemplateDO> recordList = execTemplateDAO.selectBatchIds(idList);
|
||||
Valid.notEmpty(recordList, ErrorMessage.DATA_ABSENT);
|
||||
// 设置日志参数
|
||||
String name = recordList.stream()
|
||||
.map(ExecTemplateDO::getName)
|
||||
.collect(Collectors.joining(Const.COMMA));
|
||||
OperatorLogs.add(OperatorLogs.NAME, name);
|
||||
// 删除模板
|
||||
int effect = execTemplateDAO.deleteById(id);
|
||||
log.info("ExecTemplateService-deleteExecTemplateById id: {}, effect: {}", id, effect);
|
||||
int effect = execTemplateDAO.deleteBatchIds(idList);
|
||||
log.info("ExecTemplateService-deleteExecTemplateByIdList idList: {}, effect: {}", idList, effect);
|
||||
// 删除模板主机
|
||||
effect += execTemplateHostService.deleteByTemplateId(id);
|
||||
effect += execTemplateHostService.deleteByTemplateIdList(idList);
|
||||
return effect;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import com.orion.visor.module.asset.entity.request.host.HostConnectLogQueryReque
|
||||
import com.orion.visor.module.asset.entity.vo.HostConnectLogVO;
|
||||
import com.orion.visor.module.asset.enums.HostConnectStatusEnum;
|
||||
import com.orion.visor.module.asset.enums.HostConnectTypeEnum;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.manager.TerminalManager;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.manager.HostTerminalManager;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.model.TerminalConfig;
|
||||
import com.orion.visor.module.asset.handler.host.terminal.session.ITerminalSession;
|
||||
import com.orion.visor.module.asset.service.HostConnectLogService;
|
||||
@@ -49,7 +49,7 @@ public class HostConnectLogServiceImpl implements HostConnectLogService {
|
||||
private HostConnectLogDAO hostConnectLogDAO;
|
||||
|
||||
@Resource
|
||||
private TerminalManager terminalManager;
|
||||
private HostTerminalManager hostTerminalManager;
|
||||
|
||||
@Override
|
||||
public Long create(HostConnectTypeEnum type, HostConnectLogCreateRequest request) {
|
||||
@@ -84,7 +84,7 @@ public class HostConnectLogServiceImpl implements HostConnectLogService {
|
||||
@Override
|
||||
public List<HostConnectLogVO> getHostConnectSessions(HostConnectLogQueryRequest request) {
|
||||
// 查询全部
|
||||
List<Long> idList = terminalManager.getChannelSessions()
|
||||
List<Long> idList = hostTerminalManager.getChannelSessions()
|
||||
.values()
|
||||
.stream()
|
||||
.map(ConcurrentHashMap::values)
|
||||
@@ -204,7 +204,7 @@ public class HostConnectLogServiceImpl implements HostConnectLogService {
|
||||
OperatorLogs.add(OperatorLogs.HOST_NAME, record.getHostName());
|
||||
// 获取会话
|
||||
HostConnectLogExtraDTO extra = JSON.parseObject(record.getExtraInfo(), HostConnectLogExtraDTO.class);
|
||||
ITerminalSession session = terminalManager.getSession(extra.getChannelId(), extra.getSessionId());
|
||||
ITerminalSession session = hostTerminalManager.getSession(extra.getChannelId(), extra.getSessionId());
|
||||
if (session != null) {
|
||||
// 关闭会话
|
||||
session.forceOffline();
|
||||
|
||||
@@ -6,12 +6,15 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.orion.lang.define.wrapper.DataGrid;
|
||||
import com.orion.lang.utils.Strings;
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||
import com.orion.visor.framework.common.constant.Const;
|
||||
import com.orion.visor.framework.common.constant.ErrorMessage;
|
||||
import com.orion.visor.framework.common.security.PasswordModifier;
|
||||
import com.orion.visor.framework.common.utils.CryptoUtils;
|
||||
import com.orion.visor.framework.common.utils.Valid;
|
||||
import com.orion.visor.framework.redis.core.utils.RedisMaps;
|
||||
import com.orion.visor.framework.redis.core.utils.RedisUtils;
|
||||
import com.orion.visor.framework.redis.core.utils.barrier.CacheBarriers;
|
||||
import com.orion.visor.module.asset.convert.HostIdentityConvert;
|
||||
import com.orion.visor.module.asset.dao.HostConfigDAO;
|
||||
@@ -32,6 +35,7 @@ import com.orion.visor.module.infra.api.DataPermissionApi;
|
||||
import com.orion.visor.module.infra.enums.DataPermissionTypeEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Comparator;
|
||||
@@ -185,24 +189,34 @@ public class HostIdentityServiceImpl implements HostIdentityService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer deleteHostIdentityById(Long id) {
|
||||
log.info("HostIdentityService-deleteHostIdentityById id: {}", id);
|
||||
return this.deleteHostIdentityByIdList(Lists.singleton(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer deleteHostIdentityByIdList(List<Long> idList) {
|
||||
log.info("HostIdentityService-deleteHostIdentityByIdList idList: {}", idList);
|
||||
// 检查数据是否存在
|
||||
HostIdentityDO record = hostIdentityDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
List<HostIdentityDO> list = hostIdentityDAO.selectBatchIds(idList);
|
||||
Valid.notEmpty(list, ErrorMessage.DATA_ABSENT);
|
||||
// 添加日志参数
|
||||
OperatorLogs.add(OperatorLogs.NAME, record.getName());
|
||||
String name = list.stream()
|
||||
.map(HostIdentityDO::getName)
|
||||
.collect(Collectors.joining(Const.COMMA));
|
||||
OperatorLogs.add(OperatorLogs.NAME, name);
|
||||
// 删除数据库
|
||||
int effect = hostIdentityDAO.deleteById(id);
|
||||
int effect = hostIdentityDAO.deleteBatchIds(idList);
|
||||
// 删除主机配置
|
||||
hostConfigDAO.setIdentityIdWithNull(id);
|
||||
hostConfigDAO.setIdentityIdWithNull(idList);
|
||||
// 删除主机身份额外配置
|
||||
dataExtraApi.deleteHostIdentityExtra(id);
|
||||
dataExtraApi.deleteHostIdentityExtra(idList);
|
||||
// 删除数据权限
|
||||
dataPermissionApi.deleteByRelId(DataPermissionTypeEnum.HOST_IDENTITY, id);
|
||||
dataPermissionApi.deleteByRelIdList(DataPermissionTypeEnum.HOST_IDENTITY, idList);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(HostCacheKeyDefine.HOST_IDENTITY.getKey(), record.getId());
|
||||
log.info("HostIdentityService-deleteHostIdentityById effect: {}", effect);
|
||||
RedisUtils.delete(HostCacheKeyDefine.HOST_IDENTITY);
|
||||
log.info("HostIdentityService-deleteHostIdentityByIdList effect: {}", effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,15 @@ 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.Strings;
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||
import com.orion.visor.framework.common.constant.Const;
|
||||
import com.orion.visor.framework.common.constant.ErrorMessage;
|
||||
import com.orion.visor.framework.common.security.PasswordModifier;
|
||||
import com.orion.visor.framework.common.utils.CryptoUtils;
|
||||
import com.orion.visor.framework.common.utils.Valid;
|
||||
import com.orion.visor.framework.redis.core.utils.RedisMaps;
|
||||
import com.orion.visor.framework.redis.core.utils.RedisUtils;
|
||||
import com.orion.visor.framework.redis.core.utils.barrier.CacheBarriers;
|
||||
import com.orion.visor.module.asset.convert.HostKeyConvert;
|
||||
import com.orion.visor.module.asset.dao.HostConfigDAO;
|
||||
@@ -170,24 +173,33 @@ public class HostKeyServiceImpl implements HostKeyService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer deleteHostKeyById(Long id) {
|
||||
log.info("HostKeyService-deleteHostKeyById id: {}", id);
|
||||
return this.deleteHostKeyByIdList(Lists.singleton(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer deleteHostKeyByIdList(List<Long> idList) {
|
||||
log.info("HostKeyService-deleteHostKeyById idList: {}", idList);
|
||||
// 检查数据是否存在
|
||||
HostKeyDO record = hostKeyDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
List<HostKeyDO> list = hostKeyDAO.selectBatchIds(idList);
|
||||
Valid.notEmpty(list, ErrorMessage.DATA_ABSENT);
|
||||
// 添加日志参数
|
||||
OperatorLogs.add(OperatorLogs.NAME, record.getName());
|
||||
String name = list.stream()
|
||||
.map(HostKeyDO::getName)
|
||||
.collect(Collectors.joining(Const.COMMA));
|
||||
OperatorLogs.add(OperatorLogs.NAME, name);
|
||||
// 删除数据库
|
||||
int effect = hostKeyDAO.deleteById(id);
|
||||
int effect = hostKeyDAO.deleteBatchIds(idList);
|
||||
// 删除关联
|
||||
hostIdentityDAO.setKeyWithNull(id);
|
||||
hostIdentityDAO.setKeyWithNull(idList);
|
||||
// 删除主机配置
|
||||
hostConfigDAO.setKeyIdWithNull(id);
|
||||
hostConfigDAO.setKeyIdWithNull(idList);
|
||||
// 删除主机密钥额外配置
|
||||
dataExtraApi.deleteHostKeyExtra(id);
|
||||
dataExtraApi.deleteHostKeyExtra(idList);
|
||||
// 删除数据权限
|
||||
dataPermissionApi.deleteByRelId(DataPermissionTypeEnum.HOST_KEY, id);
|
||||
dataPermissionApi.deleteByRelIdList(DataPermissionTypeEnum.HOST_KEY, idList);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(HostCacheKeyDefine.HOST_KEY.getKey(), record.getId());
|
||||
RedisUtils.delete(HostCacheKeyDefine.HOST_KEY);
|
||||
log.info("HostKeyService-deleteHostKeyById effect: {}", effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
@@ -8,9 +8,11 @@ import com.orion.lang.utils.Strings;
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.spring.SpringHolder;
|
||||
import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||
import com.orion.visor.framework.common.constant.Const;
|
||||
import com.orion.visor.framework.common.constant.ErrorMessage;
|
||||
import com.orion.visor.framework.common.utils.Valid;
|
||||
import com.orion.visor.framework.redis.core.utils.RedisMaps;
|
||||
import com.orion.visor.framework.redis.core.utils.RedisUtils;
|
||||
import com.orion.visor.framework.redis.core.utils.barrier.CacheBarriers;
|
||||
import com.orion.visor.module.asset.convert.HostConvert;
|
||||
import com.orion.visor.module.asset.dao.HostConfigDAO;
|
||||
@@ -191,41 +193,49 @@ public class HostServiceImpl implements HostService {
|
||||
|
||||
@Override
|
||||
public Integer deleteHostById(Long id) {
|
||||
log.info("HostService-deleteHostById id: {}", id);
|
||||
return this.deleteHostByIdList(Lists.singleton(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteHostByIdList(List<Long> idList) {
|
||||
log.info("HostService-deleteHostByIdList idList: {}", idList);
|
||||
// 查询
|
||||
HostDO record = hostDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.HOST_ABSENT);
|
||||
List<HostDO> hosts = hostDAO.selectBatchIds(idList);
|
||||
Valid.notEmpty(hosts, ErrorMessage.HOST_ABSENT);
|
||||
// 添加日志参数
|
||||
OperatorLogs.add(OperatorLogs.NAME, record.getName());
|
||||
String name = hosts.stream()
|
||||
.map(HostDO::getName)
|
||||
.collect(Collectors.joining(Const.COMMA));
|
||||
OperatorLogs.add(OperatorLogs.NAME, name);
|
||||
// 删除
|
||||
int effect = hostDAO.deleteById(id);
|
||||
log.info("HostService-deleteHostById effect: {}", effect);
|
||||
int effect = hostDAO.deleteBatchIds(hosts);
|
||||
log.info("HostService-deleteHostByIdList effect: {}", effect);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(HostCacheKeyDefine.HOST_INFO, id);
|
||||
RedisUtils.delete(HostCacheKeyDefine.HOST_INFO);
|
||||
// 删除主机引用
|
||||
SpringHolder.getBean(HostService.class)
|
||||
.deleteHostRelByIdAsync(id);
|
||||
.deleteHostRelByIdListAsync(idList);
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Async("asyncExecutor")
|
||||
public void deleteHostRelByIdAsync(Long id) {
|
||||
log.info("HostService-deleteHostRelByIdAsync id: {}", id);
|
||||
public void deleteHostRelByIdListAsync(List<Long> idList) {
|
||||
log.info("HostService-deleteHostRelByIdListAsync idList: {}", idList);
|
||||
// 删除主机配置
|
||||
hostConfigDAO.deleteByHostId(id);
|
||||
hostConfigDAO.deleteByHostIdList(idList);
|
||||
// 删除计划任务主机
|
||||
execJobHostService.deleteByHostId(id);
|
||||
execJobHostService.deleteByHostIdList(idList);
|
||||
// 删除执行模板主机
|
||||
execTemplateHostService.deleteByHostId(id);
|
||||
execTemplateHostService.deleteByHostIdList(idList);
|
||||
// 删除分组
|
||||
dataGroupRelApi.deleteByRelId(DataGroupTypeEnum.HOST, id);
|
||||
dataGroupRelApi.deleteByRelIdList(DataGroupTypeEnum.HOST, idList);
|
||||
// 删除 tag 引用
|
||||
tagRelApi.deleteRelId(TagTypeEnum.HOST, id);
|
||||
tagRelApi.deleteRelIdList(TagTypeEnum.HOST, idList);
|
||||
// 删除收藏引用
|
||||
favoriteApi.deleteByRelId(FavoriteTypeEnum.HOST, id);
|
||||
favoriteApi.deleteByRelIdList(FavoriteTypeEnum.HOST, idList);
|
||||
// 删除额外配置
|
||||
dataExtraApi.deleteByRelId(DataExtraTypeEnum.HOST, id);
|
||||
dataExtraApi.deleteByRelIdList(DataExtraTypeEnum.HOST, idList);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,26 +2,37 @@ package com.orion.visor.module.asset.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.orion.lang.constant.StandardContentType;
|
||||
import com.orion.lang.define.wrapper.DataGrid;
|
||||
import com.orion.lang.utils.Arrays1;
|
||||
import com.orion.lang.utils.Strings;
|
||||
import com.orion.lang.utils.io.Files1;
|
||||
import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||
import com.orion.visor.framework.common.constant.Const;
|
||||
import com.orion.visor.framework.common.constant.ErrorMessage;
|
||||
import com.orion.visor.framework.common.constant.ExtraFieldConst;
|
||||
import com.orion.visor.module.asset.convert.HostSftpLogConvert;
|
||||
import com.orion.visor.module.asset.define.operator.HostTerminalOperatorType;
|
||||
import com.orion.visor.module.asset.entity.request.host.HostSftpLogQueryRequest;
|
||||
import com.orion.visor.module.asset.entity.vo.HostSftpLogVO;
|
||||
import com.orion.visor.module.asset.service.HostSftpLogService;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.handler.ITransferHandler;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.manager.HostTransferManager;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.session.IDownloadSession;
|
||||
import com.orion.visor.module.asset.service.HostSftpService;
|
||||
import com.orion.visor.module.infra.api.OperatorLogApi;
|
||||
import com.orion.visor.module.infra.entity.dto.operator.OperatorLogQueryDTO;
|
||||
import com.orion.web.servlet.web.Servlets;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* SFTP 操作日志 服务实现类
|
||||
* SFTP 操作 服务实现类
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
@@ -29,11 +40,14 @@ import java.util.List;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class HostSftpLogServiceImpl implements HostSftpLogService {
|
||||
public class HostSftpServiceImpl implements HostSftpService {
|
||||
|
||||
@Resource
|
||||
private OperatorLogApi operatorLogApi;
|
||||
|
||||
@Resource
|
||||
private HostTransferManager hostTransferManager;
|
||||
|
||||
@Override
|
||||
public DataGrid<HostSftpLogVO> getHostSftpLogPage(HostSftpLogQueryRequest request) {
|
||||
// 查询
|
||||
@@ -62,6 +76,25 @@ public class HostSftpLogServiceImpl implements HostSftpLogService {
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamingResponseBody downloadWithTransferToken(String channelId, String transferToken, HttpServletResponse response) {
|
||||
// 获取会话
|
||||
IDownloadSession session = Optional.ofNullable(channelId)
|
||||
.map(hostTransferManager::getHandler)
|
||||
.map(ITransferHandler::getTokenSessions)
|
||||
.map(s -> s.remove(transferToken))
|
||||
.orElse(null);
|
||||
// 响应会话
|
||||
if (session == null) {
|
||||
Servlets.setContentType(response, StandardContentType.TEXT_HTML);
|
||||
Servlets.setCharset(response, Const.UTF_8);
|
||||
return outputStream -> outputStream.write(Strings.bytes(ErrorMessage.SESSION_ABSENT));
|
||||
}
|
||||
// 响应文件
|
||||
Servlets.setAttachmentHeader(response, Files1.getFileName(session.getPath()));
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询对象
|
||||
*
|
||||
@@ -151,11 +151,13 @@ public class HostTerminalServiceImpl implements HostTerminalService {
|
||||
HostExtraSshAuthTypeEnum extraAuthType = HostExtraSshAuthTypeEnum.of(extra.getAuthType());
|
||||
if (HostExtraSshAuthTypeEnum.CUSTOM_KEY.equals(extraAuthType)) {
|
||||
// 验证主机密钥是否有权限
|
||||
Valid.notNull(extra.getKeyId(), ErrorMessage.KEY_ABSENT);
|
||||
Valid.isTrue(dataPermissionApi.hasPermission(DataPermissionTypeEnum.HOST_KEY, userId, extra.getKeyId()),
|
||||
ErrorMessage.ANY_NO_PERMISSION,
|
||||
DataPermissionTypeEnum.HOST_KEY.getPermissionName());
|
||||
} else if (HostExtraSshAuthTypeEnum.CUSTOM_IDENTITY.equals(extraAuthType)) {
|
||||
// 验证主机身份是否有权限
|
||||
Valid.notNull(extra.getIdentityId(), ErrorMessage.IDENTITY_ABSENT);
|
||||
Valid.isTrue(dataPermissionApi.hasPermission(DataPermissionTypeEnum.HOST_IDENTITY, userId, extra.getIdentityId()),
|
||||
ErrorMessage.ANY_NO_PERMISSION,
|
||||
DataPermissionTypeEnum.HOST_IDENTITY.getPermissionName());
|
||||
@@ -270,6 +272,7 @@ public class HostTerminalServiceImpl implements HostTerminalService {
|
||||
HostSshAuthTypeEnum authType = HostSshAuthTypeEnum.of(config.getAuthType());
|
||||
if (HostSshAuthTypeEnum.IDENTITY.equals(authType)) {
|
||||
// 身份认证
|
||||
Valid.notNull(config.getIdentityId(), ErrorMessage.IDENTITY_ABSENT);
|
||||
HostIdentityDO identity = hostIdentityDAO.selectById(config.getIdentityId());
|
||||
Valid.notNull(identity, ErrorMessage.IDENTITY_ABSENT);
|
||||
config.setUsername(identity.getUsername());
|
||||
@@ -293,6 +296,7 @@ public class HostTerminalServiceImpl implements HostTerminalService {
|
||||
} else if (HostSshAuthTypeEnum.KEY.equals(authType)) {
|
||||
// 密钥认证
|
||||
Long keyId = config.getKeyId();
|
||||
Valid.notNull(keyId, ErrorMessage.KEY_ABSENT);
|
||||
HostKeyDO key = hostKeyDAO.selectById(keyId);
|
||||
Valid.notNull(key, ErrorMessage.KEY_ABSENT);
|
||||
conn.setKeyId(keyId);
|
||||
|
||||
@@ -143,6 +143,14 @@ public class PathBookmarkServiceImpl implements PathBookmarkService {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer setGroupNull(Long userId, Long groupId) {
|
||||
int effect = pathBookmarkDAO.setGroupIdWithNull(groupId);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(PathBookmarkCacheKeyDefine.PATH_BOOKMARK.format(userId));
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deletePathBookmarkById(Long id) {
|
||||
Long userId = SecurityUtils.getLoginUserId();
|
||||
@@ -159,19 +167,16 @@ public class PathBookmarkServiceImpl implements PathBookmarkService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer setGroupNull(Long userId, Long groupId) {
|
||||
int effect = pathBookmarkDAO.setGroupIdWithNull(groupId);
|
||||
public Integer deleteByGroupId(Long userId, Long groupId) {
|
||||
int effect = pathBookmarkDAO.deleteByGroupId(groupId);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(PathBookmarkCacheKeyDefine.PATH_BOOKMARK.format(userId));
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteByGroupId(Long userId, Long groupId) {
|
||||
int effect = pathBookmarkDAO.deleteByGroupId(groupId);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(PathBookmarkCacheKeyDefine.PATH_BOOKMARK.format(userId));
|
||||
return effect;
|
||||
public Integer deleteByUserIdList(List<Long> userIdList) {
|
||||
return pathBookmarkDAO.deleteByUserIdList(userIdList);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,17 +25,21 @@
|
||||
<update id="setKeyIdWithNull">
|
||||
UPDATE host_config
|
||||
SET version = version + 1,
|
||||
config = JSON_REMOVE(config, '$.keyId')
|
||||
config = JSON_REMOVE(config, '$.keyId')
|
||||
WHERE deleted = 0
|
||||
AND JSON_CONTAINS(config, JSON_OBJECT('keyId', #{keyId}))
|
||||
<foreach collection="keyIdList" item="item" separator="OR" open="AND (" close=")">
|
||||
JSON_CONTAINS(config, JSON_OBJECT('keyId', #{item}))
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<update id="setIdentityIdWithNull">
|
||||
UPDATE host_config
|
||||
SET version = version + 1,
|
||||
config = JSON_REMOVE(config, '$.identityId')
|
||||
config = JSON_REMOVE(config, '$.identityId')
|
||||
WHERE deleted = 0
|
||||
AND JSON_CONTAINS(config, JSON_OBJECT('identityId', #{identityId}))
|
||||
<foreach collection="identityIdList" item="item" separator="OR" open="AND (" close=")">
|
||||
JSON_CONTAINS(config, JSON_OBJECT('identityId', #{item}))
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -24,6 +24,7 @@ spring:
|
||||
redisson:
|
||||
threads: 2
|
||||
netty-threads: 2
|
||||
minimum-idle-size: 2
|
||||
|
||||
mybatis-plus:
|
||||
lazy-initialization: true
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user