Compare commits

..

87 Commits
v2.5.2 ... dev

Author SHA1 Message Date
lijiahangmax
9ae3855def 🔨 主机可搜索. 2026-02-08 00:45:00 +08:00
lijiahangmax
6c3f952693 🔨 优化异常处理逻辑. 2026-02-06 00:13:08 +08:00
lijiahangmax
af330f46a1 🔨 修改字典逻辑. 2026-01-31 23:12:20 +08:00
lijiahangmax
a6cb163486 🔨 优化代码. 2026-01-25 09:43:28 +08:00
lijiahangmax
1b8e2c2fd1 🔨 修改格式化方法. 2026-01-24 10:31:28 +08:00
lijiahangmax
dfea231984 🔨 优化代码. 2026-01-23 15:16:15 +08:00
lijiahangmax
936795791b 🔨 优化代码. 2026-01-23 14:26:38 +08:00
lijiahangmax
e774531fcb 🔨 升级 fastjson. 2026-01-23 11:24:32 +08:00
lijiahangmax
238ec20b7c 🔨 升级 fastjson. 2026-01-23 11:14:44 +08:00
lijiahangmax
4da3fc9356 🚀 升级版本. 2026-01-23 11:12:34 +08:00
lijiahangmax
8a1bf72d30 :pencli2: 修改文档. 2026-01-23 10:53:37 +08:00
lijiahangmax
0dbdafe138 :pencli2: 修改文档. 2026-01-09 14:39:01 +08:00
lijiahangmax
1285db903d :pencli2: 修改文档. 2026-01-06 12:38:50 +08:00
lijiahangmax
35d3112339 :pencli2: 修改提示. 2026-01-05 17:29:36 +08:00
lijiahangmax
d49952bef4 :pencli2: 修改提示. 2026-01-05 17:26:18 +08:00
lijiahangmax
2b316febcd 🔨 安装提示. 2026-01-05 15:31:16 +08:00
lijiahangmax
e17d15c112 :pencli2: 修改提示. 2026-01-04 16:05:52 +08:00
lijiahangmax
8f0cd4ad24 :pencli2: 修改文档. 2025-12-26 14:31:04 +08:00
lijiahangmax
b207c5d253 :pencli2: 修改文档. 2025-12-22 18:23:03 +08:00
lijiahangmax
5335a8d008 🔨 替换换行符. 2025-12-21 15:55:21 +08:00
lijiahangmax
1e74659f15 🔨 优化安装逻辑. 2025-12-19 00:32:53 +08:00
lijiahangmax
58a1a7abd4 🔨 替换换行符. 2025-12-17 23:06:25 +08:00
lijiahangmax
6c125a1c0d :pencli2: 修改文档. 2025-12-16 17:52:38 +08:00
lijiahangmax
263436405c 🔨 移除无用字段. 2025-12-14 10:04:02 +08:00
lijiahangmax
2296ca46a4 🔖 升级版本. 2025-12-12 11:01:15 +08:00
lijiahangmax
ffcb3baf44 🔨 优化缓存删除逻辑. 2025-12-11 10:00:12 +08:00
lijiahangmax
501755231a 🔨 优化缓存删除逻辑. 2025-12-10 09:49:35 +08:00
lijiahangmax
f4ddeb3e6c 🔨 对外服务 api 配置. 2025-12-09 10:06:24 +08:00
lijiahangmax
40afc03203 🔨 调整列宽. 2025-12-08 16:25:55 +08:00
lijiahangmax
7c479b1720 🔨 优化保存逻辑. 2025-12-07 22:10:55 +08:00
lijiahangmax
6c6f69ae24 🔨 优化异常处理逻辑. 2025-12-04 15:31:40 +08:00
lijiahangmax
d1cb056adf 🔨 优化异常处理逻辑. 2025-12-04 15:31:11 +08:00
lijiahangmax
14dc8e0407 🔨 优化异常处理逻辑. 2025-12-03 09:45:21 +08:00
lijiahangmax
528cfc90f2 🔨 优化异常处理逻辑. 2025-12-03 09:42:21 +08:00
lijiahangmax
327bb72659 🔨 优化异常处理逻辑. 2025-12-02 10:09:26 +08:00
lijiahangmax
c6b248ab6f 🔨 优化异常处理逻辑. 2025-12-01 09:59:48 +08:00
lijiahangmax
0ece84bdf1 🔨 优化异常处理逻辑. 2025-11-28 10:27:02 +08:00
lijiahangmax
61fa7a6e32 🔨 全局异常处理. 2025-11-27 09:44:20 +08:00
lijiahangmax
21e7d29077 🔨 修改 sftp 样式. 2025-11-26 10:25:59 +08:00
lijiahangmax
ad42be8fe8 🔨 替换换行符. 2025-11-12 00:34:48 +08:00
lijiahangmax
aa913bce8d 🔖 升级版本. 2025-11-12 00:11:39 +08:00
lijiahangmax
3e3af89939 🔖 升级版本. 2025-11-11 11:30:22 +08:00
lijiahangmax
783baaf8c8 🐛 修复 sftp 下载文件失败. 2025-11-11 11:29:51 +08:00
lijiahangmax
a53565e06b 🔨 替换换行符. 2025-11-10 21:46:08 +08:00
lijiahangmax
061495eb13 🔨 修改文案. 2025-11-10 09:57:36 +08:00
lijiahangmax
6514363847 🔨 用户会话列表. 2025-11-08 09:40:44 +08:00
lijiahangmax
c3da882950 🔨 用户锁定列表. 2025-11-07 10:01:16 +08:00
lijiahangmax
6deebedc75 🔨 解锁用户. 2025-11-06 09:50:09 +08:00
lijiahangmax
2012f20a09 Merge remote-tracking branch 'origin/dev' into dev 2025-11-03 14:25:56 +08:00
lijiahangmax
2377c50187 🔨 锁定用户列表. 2025-11-03 14:25:45 +08:00
lijiahangmax
91b22297a2 🔨 修改重复提示. 2025-11-02 01:06:12 +08:00
lijiahangmax
5bbf46d141 🔨 添加规格信息. 2025-11-01 22:52:50 +08:00
lijiahangmax
3c7a0947ee 🔨 优化代码逻辑. 2025-10-31 09:39:03 +08:00
lijiahangmax
83c64dddfb 🔨 修改认证逻辑. 2025-10-30 16:42:43 +08:00
lijiahangmax
5d86c330fe 🔨 tag 管理. 2025-10-29 10:39:19 +08:00
lijiahangmax
6a13d3cb22 🔨 tag 管理. 2025-10-28 13:58:33 +08:00
lijiahangmax
3a8addb4d2 🔨 IP 请求头可配置. 2025-10-27 09:50:17 +08:00
lijiahangmax
90705781f2 🔨 优化操作日志逻辑. 2025-10-24 11:18:54 +08:00
lijiahangmax
91fecad956 🔨 升级 sql 脚本. 2025-10-21 16:56:47 +08:00
lijiahangmax
9635aa34a7 🔨 修改标题样式. 2025-10-21 13:52:02 +08:00
lijiahangmax
a2f7ab7f9c 🔨 升级版本. 2025-10-20 00:23:48 +08:00
lijiahangmax
55d0dfd27d 🔨 优化告警引擎. 2025-10-19 15:34:53 +08:00
lijiahangmax
eb18142926 🔨 可调整列宽. 2025-10-18 22:21:30 +08:00
lijiahangmax
0649c4e3de 🔨 优化错误提示. 2025-10-17 14:14:34 +08:00
lijiahangmax
f648e18557 🔨 优化数据分组逻辑. 2025-10-17 14:12:14 +08:00
lijiahangmax
9d3b46e9b3 🔨 策略描述非必填. 2025-10-15 15:07:37 +08:00
lijiahangmax
14dfe457bf 🔨 优化告警引擎. 2025-10-15 01:35:40 +08:00
lijiahangmax
9651354317 🔨 添加策略类型. 2025-10-13 18:23:07 +08:00
lijiahangmax
8929aa2f74 🔨 优化监控逻辑. 2025-10-13 17:39:00 +08:00
lijiahangmax
ea98592012 🔨 监控页面连接终端. 2025-10-10 13:26:01 +08:00
lijiahangmax
b0be444fba 🔨 优化系统配置逻辑. 2025-10-09 14:31:43 +08:00
lijiahangmax
37fc271741 🚀 升级版本. 2025-10-08 09:59:30 +08:00
lijiahangmax
0810de23ea 🔨 设置 ulimits. 2025-10-08 09:51:29 +08:00
lijiahangmax
9f2e4582cc Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	orion-visor-ui/src/api/monitor/monitor-host.ts
2025-10-08 09:44:24 +08:00
lijiahangmax
8e52631b46 🔨 修改前端逻辑. 2025-10-08 09:39:28 +08:00
lijiahangmax
7cd885a050 Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	sql/init-4-data.sql
2025-10-07 22:25:16 +08:00
lijiahangmax
3045512320 🚀 升级版本. 2025-10-07 22:24:50 +08:00
lijiahangmax
55c2199c3f 🔨 修改 sql 脚本. 2025-10-07 22:23:37 +08:00
lijiahangmax
963cd0b227 🔨 修改标签查询逻辑. 2025-10-07 16:06:00 +08:00
lijiahangmax
1d5c579e64 🔨 修改文本描述. 2025-10-07 15:46:53 +08:00
lijiahangmax
773d95207f 🔨 统一前端卡片风格. 2025-10-07 14:27:19 +08:00
lijiahangmax
2103698417 🔨 优化标签查询逻辑. 2025-10-07 14:26:40 +08:00
lijiahangmax
25082b9ea1 🔨 线程池配置化. 2025-10-07 00:28:49 +08:00
lijiahangmax
cb20d56a7b 🚀 修复告警引擎初始化异常的问题. 2025-10-07 00:28:34 +08:00
lijiahangmax
d58d46ca8c 🔨 修改 influx 查询语句. 2025-10-06 16:18:20 +08:00
lijiahangmax
29e6db75ca 🔨 登录失败提示. 2025-10-04 21:31:03 +08:00
lijiahangmax
86abf4f634 🔨 告警记录. 2025-09-29 13:35:47 +08:00
451 changed files with 5974 additions and 2943 deletions

View File

@@ -6,7 +6,13 @@ SPRING_PROFILES_ACTIVE=prod
DEMO_MODE=false DEMO_MODE=false
API_CORS=true API_CORS=true
API_IP_HEADERS=X-Forwarded-For,X-Real-IP
# api 地址 (需要改为宿主机 IP)
API_HOST=0.0.0.0
# API_URL=http://127.0.0.1:9200/orion-visor/api
# api 密钥 (建议修改)
API_EXPOSE_TOKEN=pmqeHOyZaumHm0Wt API_EXPOSE_TOKEN=pmqeHOyZaumHm0Wt
# 加密密钥 (建议修改)
SECRET_KEY=uQeacXV8b3isvKLK SECRET_KEY=uQeacXV8b3isvKLK
NGINX_SERVICE_HOST=service NGINX_SERVICE_HOST=service

View File

@@ -17,6 +17,8 @@ body:
required: true required: true
- label: 我已搜索 [issue](https://github.com/dromara/orion-visor/issues) 并没有找到相关问题 - label: 我已搜索 [issue](https://github.com/dromara/orion-visor/issues) 并没有找到相关问题
required: true required: true
- label: 我已 star 了此项目, 否则可能会被自动关闭
required: true
- type: input - type: input
id: version id: version
attributes: attributes:

View File

@@ -38,8 +38,8 @@
</a> </a>
<a target="_blank" <a target="_blank"
style="text-decoration: none !important;" style="text-decoration: none !important;"
href="https://gitcode.com/dromara/orion-visor"> href="https://atomgit.com/dromara/orion-visor">
<img src="https://gitcode.com/dromara/orion-visor/star/badge.svg" alt="star"/> <img src="https://atomgit.com/dromara/orion-visor/star/2025top.svg" alt="star" />
</a> </a>
</p> </p>
@@ -60,7 +60,7 @@
* 🔗 演示地址: [https://dv.orionsec.cn/](https://dv.orionsec.cn/) * 🔗 演示地址: [https://dv.orionsec.cn/](https://dv.orionsec.cn/)
* 🔏 演示账号: admin/admin * 🔏 演示账号: admin/admin
* ⭐ 体验后可以点一下 `star` * ⭐ 体验后可以点一下 `star`
这对我很重要! [github](https://github.com/dromara/orion-visor) [gitee](https://gitee.com/dromara/orion-visor) [gitcode](https://gitcode.com/dromara/orion-visor) 这对我很重要! [github](https://github.com/dromara/orion-visor) [gitee](https://gitee.com/dromara/orion-visor) [atomgit](https://atomgit.com/dromara/orion-visor)
* 🌈 如果本项目对你有帮助请帮忙推广一下 让更多的人知道此项目! * 🌈 如果本项目对你有帮助请帮忙推广一下 让更多的人知道此项目!
* 🎭 演示环境部分功能不可用, 完整功能请本地部署! * 🎭 演示环境部分功能不可用, 完整功能请本地部署!
@@ -70,6 +70,10 @@
# clone # clone
git clone --depth=1 https://github.com/dromara/orion-visor git clone --depth=1 https://github.com/dromara/orion-visor
cd orion-visor cd orion-visor
# 复制配置
cp .env.example .env
# 修改配置
vim .env
# 启动 # 启动
docker compose up -d docker compose up -d
# 等待后端服务启动后 (2min±) 访问 http://localhost:1081/ # 等待后端服务启动后 (2min±) 访问 http://localhost:1081/
@@ -171,6 +175,6 @@ QQ群: 755242157
![GVP](docs/assets/gvp.jpg?time=20250627 "GVP") ![GVP](docs/assets/gvp.jpg?time=20250627 "GVP")
## GitCode 最有影响力的开源项目 G-Star ## AtomGit 最有影响力的开源项目 G-Star
![GSTAR](docs/assets/gstar.jpg?time=20250627 "GSTAR") ![GSTAR](docs/assets/gstar.jpg?time=20250627 "GSTAR")

View File

@@ -1,5 +1,3 @@
version: '3.3'
services: services:
service: service:
image: registry.cn-hangzhou.aliyuncs.com/orionsec/orion-visor-service:latest image: registry.cn-hangzhou.aliyuncs.com/orionsec/orion-visor-service:latest
@@ -19,6 +17,10 @@ services:
DEMO_MODE: false DEMO_MODE: false
volumes: volumes:
- /data/orion-visor-space/docker-volumes/service/root-orion:/root/orion - /data/orion-visor-space/docker-volumes/service/root-orion:/root/orion
ulimits:
nofile:
soft: 65536
hard: 65536
healthcheck: healthcheck:
test: [ "CMD", "curl", "http://127.0.0.1:9200/orion-visor/api/server/bootstrap/health" ] test: [ "CMD", "curl", "http://127.0.0.1:9200/orion-visor/api/server/bootstrap/health" ]
interval: 15s interval: 15s
@@ -87,4 +89,4 @@ services:
networks: networks:
orion-visor-net: orion-visor-net:
driver: bridge driver: bridge

View File

@@ -1,6 +1,4 @@
version: '3.3' # latest = 2.5.7
# latest = 2.5.2
# 支持以下源 # 支持以下源
# lijiahangmax/* # lijiahangmax/*
@@ -27,16 +25,12 @@ services:
privileged: true privileged: true
ports: ports:
- "9200:9200" - "9200:9200"
ulimits:
nofile:
soft: 65536
hard: 65536
environment: environment:
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod} SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
MYSQL_HOST: ${MYSQL_HOST:-mysql} MYSQL_HOST: ${MYSQL_HOST:-mysql}
MYSQL_PORT: ${MYSQL_PORT:-3306} MYSQL_PORT: ${MYSQL_PORT:-3306}
MYSQL_DATABASE: ${MYSQL_DATABASE:-orion_visor} MYSQL_DATABASE: ${MYSQL_DATABASE:-orion_visor}
MYSQL_USER: ${MYSQL_USER:-root} MYSQL_USER: ${MYSQL_USER:-orion}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-Data@123456} MYSQL_PASSWORD: ${MYSQL_PASSWORD:-Data@123456}
REDIS_HOST: ${REDIS_HOST:-redis} REDIS_HOST: ${REDIS_HOST:-redis}
REDIS_PASSWORD: ${REDIS_PASSWORD:-Data@123456} REDIS_PASSWORD: ${REDIS_PASSWORD:-Data@123456}
@@ -53,10 +47,19 @@ services:
GUACD_DRIVE_PATH: ${GUACD_DRIVE_PATH:-/drive} GUACD_DRIVE_PATH: ${GUACD_DRIVE_PATH:-/drive}
SECRET_KEY: ${SECRET_KEY:-uQeacXV8b3isvKLK} SECRET_KEY: ${SECRET_KEY:-uQeacXV8b3isvKLK}
API_EXPOSE_TOKEN: ${API_EXPOSE_TOKEN:-pmqeHOyZaumHm0Wt} API_EXPOSE_TOKEN: ${API_EXPOSE_TOKEN:-pmqeHOyZaumHm0Wt}
API_IP_HEADERS: ${API_IP_HEADERS:-X-Forwarded-For,X-Real-IP}
# 这里需要改为具体的服务地址 (宿主机ip)
API_HOST: ${API_HOST:-0.0.0.0}
# 若 API_HOST 不满足, 可以修改这里 http://<ip>:<port>/orion-visor/api
API_URL: ${API_URL:-}
API_CORS: ${API_CORS:-true} API_CORS: ${API_CORS:-true}
DEMO_MODE: ${DEMO_MODE:-false} DEMO_MODE: ${DEMO_MODE:-false}
volumes: volumes:
- ${VOLUME_BASE:-/data/orion-visor-space/docker-volumes}/service/root-orion:/root/orion - ${VOLUME_BASE:-/data/orion-visor-space/docker-volumes}/service/root-orion:/root/orion
ulimits:
nofile:
soft: 65536
hard: 65536
restart: unless-stopped restart: unless-stopped
healthcheck: healthcheck:
test: [ "CMD", "curl", "http://127.0.0.1:9200/orion-visor/api/server/bootstrap/health" ] test: [ "CMD", "curl", "http://127.0.0.1:9200/orion-visor/api/server/bootstrap/health" ]
@@ -178,4 +181,4 @@ services:
networks: networks:
orion-visor-net: orion-visor-net:
driver: bridge driver: bridge

View File

@@ -7,7 +7,7 @@ set -e
source ./project-build.sh "$@" source ./project-build.sh "$@"
# 版本号 # 版本号
version=2.5.2 version=2.5.7
# 是否推送镜像 # 是否推送镜像
push_image=false push_image=false
# 是否构建 latest # 是否构建 latest
@@ -140,7 +140,7 @@ function modify_dockerfiles() {
if [ -f "$file" ]; then if [ -f "$file" ]; then
echo "备份并修改: $file" echo "备份并修改: $file"
cp "$file" "$file$backup_suffix" cp "$file" "$file$backup_suffix"
sed -i 's/--platform=\TARGETPLATFORM//g' "$file" sed -i "s/--platform=\$TARGETPLATFORM//g" "$file"
else else
echo "文件不存在 -> $file" echo "文件不存在 -> $file"
fi fi
@@ -189,7 +189,7 @@ function push_image_to_registry() {
# 推送版本 # 推送版本
docker push "${namespace}/${image_name}:${version}" docker push "${namespace}/${image_name}:${version}"
# 推送 latest # 推送 latest
if [ "latest_image" = true ]; then if [ "$latest_image" = true ]; then
docker push "${namespace}/${image_name}:latest" docker push "${namespace}/${image_name}:latest"
fi fi
done done

View File

@@ -4,7 +4,7 @@ set -e
# DockerContext: orion-visor # DockerContext: orion-visor
# 版本号 # 版本号
version=2.5.2 version=2.5.7
# 是否构建 service # 是否构建 service
export build_service=false export build_service=false
# 是否构建 ui # 是否构建 ui

View File

@@ -1,4 +1,4 @@
FROM --platform=$TARGETPLATFORM openjdk:8-jdk-alpine FROM --platform=$TARGETPLATFORM openjdk:8u171-jdk-alpine3.7
USER root USER root

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2023 - present Dromara, All rights reserved.
*
* https://visor.dromara.org
* https://visor.dromara.org.cn
* https://visor.orionsec.cn
*
* Members:
* Jiahang Li - ljh1553488six@139.com - author
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.visor.common.configuration;
import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.utils.IpUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
/**
* 公共配置类
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/6/20 10:34
*/
@Slf4j
@Configuration
public class CommonConfiguration {
@Value("${orion.api.ip-headers}")
private String[] ipHeaders;
/**
* 设置 IP 请求头
*/
@PostConstruct
public void setIpHeader() {
IpUtils.setIpHeader(ipHeaders);
log.info("IpUtils.setIpHeader {}", String.join(",", ipHeaders));
}
}

View File

@@ -36,7 +36,7 @@ public interface AppConst extends OrionConst {
/** /**
* 同 ${orion.version} 迭代时候需要手动更改 * 同 ${orion.version} 迭代时候需要手动更改
*/ */
String VERSION = "2.5.2"; String VERSION = "2.5.7";
/** /**
* 同 ${spring.application.name} * 同 ${spring.application.name}

View File

@@ -33,6 +33,8 @@ package org.dromara.visor.common.constant;
*/ */
public interface AutoConfigureOrderConst { public interface AutoConfigureOrderConst {
int FRAMEWORK_EXECUTOR = Integer.MIN_VALUE + 1000;
int FRAMEWORK_WEB = Integer.MIN_VALUE + 1100; int FRAMEWORK_WEB = Integer.MIN_VALUE + 1100;
int FRAMEWORK_SECURITY = Integer.MIN_VALUE + 1200; int FRAMEWORK_SECURITY = Integer.MIN_VALUE + 1200;
@@ -65,8 +67,6 @@ public interface AutoConfigureOrderConst {
int FRAMEWORK_JOB_QUARTZ = Integer.MIN_VALUE + 2610; int FRAMEWORK_JOB_QUARTZ = Integer.MIN_VALUE + 2610;
int FRAMEWORK_JOB_ASYNC = Integer.MIN_VALUE + 2620;
int FRAMEWORK_BIZ_PUSH = Integer.MIN_VALUE + 2700; int FRAMEWORK_BIZ_PUSH = Integer.MIN_VALUE + 2700;
int FRAMEWORK_BIZ_OPERATOR_LOG = Integer.MIN_VALUE + 7000; int FRAMEWORK_BIZ_OPERATOR_LOG = Integer.MIN_VALUE + 7000;

View File

@@ -34,116 +34,116 @@ public interface ConfigKeys {
/** /**
* SFTP 文件预览大小 * SFTP 文件预览大小
*/ */
String SFTP_PREVIEW_SIZE = "sftp_previewSize"; String SFTP_PREVIEW_SIZE = "sftp.preview-size";
/** /**
* SFTP 重复文件备份 * SFTP 重复文件备份
*/ */
String SFTP_UPLOAD_PRESENT_BACKUP = "sftp_uploadPresentBackup"; String SFTP_UPLOAD_PRESENT_BACKUP = "sftp.upload-present-backup";
/** /**
* SFTP 备份文件名称 * SFTP 备份文件名称
*/ */
String SFTP_UPLOAD_BACKUP_FILE_NAME = "sftp_uploadBackupFileName"; String SFTP_UPLOAD_BACKUP_FILE_NAME = "sftp.upload-backup-file-name";
/** /**
* 加密公钥 * 加密公钥
*/ */
String ENCRYPT_PUBLIC_KEY = "encrypt_publicKey"; String ENCRYPT_PUBLIC_KEY = "encrypt.public-key";
/** /**
* 加密私钥 * 加密私钥
*/ */
String ENCRYPT_PRIVATE_KEY = "encrypt_privateKey"; String ENCRYPT_PRIVATE_KEY = "encrypt.private-key";
/** /**
* 日志前端显示行数 * 日志前端显示行数
*/ */
String LOG_WEB_SCROLL_LINES = "log_webScrollLines"; String LOG_WEB_SCROLL_LINES = "log.web-scroll-lines";
/** /**
* 日志加载偏移行 * 日志加载偏移行
*/ */
String LOG_TRACKER_LOAD_LINES = "log_trackerLoadLines"; String LOG_TRACKER_LOAD_LINES = "log.tracker-load-lines";
/** /**
* 日志加载间隔毫秒 * 日志加载间隔毫秒
*/ */
String LOG_TRACKER_LOAD_INTERVAL = "log_trackerLoadInterval"; String LOG_TRACKER_LOAD_INTERVAL = "log.tracker-load-interval";
/** /**
* 是否生成详细的执行日志 * 是否生成详细的执行日志
*/ */
String LOG_EXEC_DETAIL_LOG = "log_execDetailLog"; String LOG_EXEC_DETAIL_ENABLED = "log.exec-detail.enabled";
/** /**
* 凭证有效期分 * 凭证有效期
*/ */
String LOGIN_LOGIN_SESSION_TIME = "login_loginSessionTime"; String LOGIN_LOGIN_SESSION_TIME = "login.login-session-time";
/** /**
* 允许多端登录 * 允许多端登录
*/ */
String LOGIN_ALLOW_MULTI_DEVICE = "login_allowMultiDevice"; String LOGIN_ALLOW_MULTI_DEVICE = "login.allow-multi-device";
/** /**
* 允许凭证续签 * 允许凭证续签
*/ */
String LOGIN_ALLOW_REFRESH = "login_allowRefresh"; String LOGIN_ALLOW_REFRESH = "login.allow-refresh";
/** /**
* 凭证续签最大次数 * 凭证续签最大次数
*/ */
String LOGIN_MAX_REFRESH_COUNT = "login_maxRefreshCount"; String LOGIN_MAX_REFRESH_COUNT = "login.max-refresh-count";
/** /**
* 凭证续签间隔分 * 凭证续签间隔分
*/ */
String LOGIN_REFRESH_INTERVAL = "login_refreshInterval"; String LOGIN_REFRESH_INTERVAL = "login.refresh-interval";
/** /**
* 登录失败锁定 * 登录失败锁定
*/ */
String LOGIN_LOGIN_FAILED_LOCK = "login_loginFailedLock"; String LOGIN_LOGIN_FAILED_LOCK = "login.login-failed-lock";
/** /**
* 登录失败锁定阈值 * 登录失败锁定阈值
*/ */
String LOGIN_LOGIN_FAILED_LOCK_THRESHOLD = "login_loginFailedLockThreshold"; String LOGIN_LOGIN_FAILED_LOCK_THRESHOLD = "login.login-failed-lock-threshold";
/** /**
* 登录失败锁定时间分 * 登录失败锁定时间
*/ */
String LOGIN_LOGIN_FAILED_LOCK_TIME = "login_loginFailedLockTime"; String LOGIN_LOGIN_FAILED_LOCK_TIME = "login.login-failed-lock-time";
/** /**
* 登录失败发信 * 登录失败发信
*/ */
String LOGIN_LOGIN_FAILED_SEND = "login_loginFailedSend"; String LOGIN_LOGIN_FAILED_SEND = "login.login-failed-send";
/** /**
* 登录失败发信阈值 * 登录失败发信阈值
*/ */
String LOGIN_LOGIN_FAILED_SEND_THRESHOLD = "login_loginFailedSendThreshold"; String LOGIN_LOGIN_FAILED_SEND_THRESHOLD = "login.login-failed-send-threshold";
/** /**
* 是否开启自动清理命令记录 * 是否开启自动清理命令记录
*/ */
String AUTO_CLEAR_EXEC_LOG_ENABLED = "autoClear_execLogEnabled"; String AUTO_CLEAR_EXEC_LOG_ENABLED = "auto-clear.exec-log.enabled";
/** /**
* 自动清理命令记录保留天数 * 自动清理命令记录保留天数
*/ */
String AUTO_CLEAR_EXEC_LOG_KEEP_DAYS = "autoClear_execLogKeepDays"; String AUTO_CLEAR_EXEC_LOG_KEEP_DAYS = "auto-clear.exec-log.keep-days";
/** /**
* 是否开启自动清理终端连接记录 * 是否开启自动清理终端连接记录
*/ */
String AUTO_CLEAR_TERMINAL_LOG_ENABLED = "autoClear_terminalLogEnabled"; String AUTO_CLEAR_TERMINAL_LOG_ENABLED = "auto-clear.terminal-log.enabled";
/** /**
* 自动清理终端连接记录保留天数 * 自动清理终端连接记录保留天数
*/ */
String AUTO_CLEAR_TERMINAL_LOG_KEEP_DAYS = "autoClear_terminalLogKeepDays"; String AUTO_CLEAR_TERMINAL_LOG_KEEP_DAYS = "auto-clear.terminal-log.keep-days";
} }

View File

@@ -55,4 +55,6 @@ public interface Const extends cn.orionsec.kit.lang.constant.Const, FieldConst,
int BATCH_COUNT = 500; int BATCH_COUNT = 500;
String IP_0000 = "0.0.0.0";
} }

View File

@@ -210,6 +210,12 @@ public interface ErrorMessage {
String PLEASE_SELECT_SUFFIX_FILE = "请选择 {} 类型的文件"; String PLEASE_SELECT_SUFFIX_FILE = "请选择 {} 类型的文件";
String SPEC_FORMAT_INCORRECT = "规格格式不正确";
String INFLUXDB_UNSUPPORTED = "InfluxDB 服务未开启";
String AGENT_KEY_NOT_FOUND = "未通过 agentKey 查询到对应的主机 ({})";
/** /**
* 是否为业务异常 * 是否为业务异常
* *

View File

@@ -33,6 +33,20 @@ import java.io.Serializable;
*/ */
public interface RequestIdentity extends Serializable { public interface RequestIdentity extends Serializable {
/**
* 获取请求时间戳
*
* @return timestamp
*/
Long getTimestamp();
/**
* 设置请求时间戳
*
* @param timestamp timestamp
*/
void setTimestamp(Long timestamp);
/** /**
* 获取请求地址 * 获取请求地址
* *

View File

@@ -23,7 +23,10 @@
package org.dromara.visor.common.entity; package org.dromara.visor.common.entity;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
/** /**
* 请求留痕模型 * 请求留痕模型
@@ -33,9 +36,15 @@ import lombok.Data;
* @since 2023/12/29 11:57 * @since 2023/12/29 11:57
*/ */
@Data @Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "RequestIdentityModel", description = "请求留痕模型") @Schema(name = "RequestIdentityModel", description = "请求留痕模型")
public class RequestIdentityModel implements RequestIdentity { public class RequestIdentityModel implements RequestIdentity {
@Schema(description = "时间戳")
private Long timestamp;
@Schema(description = "请求地址") @Schema(description = "请求地址")
private String address; private String address;

View File

@@ -22,7 +22,7 @@
*/ */
package org.dromara.visor.common.handler.data.model; package org.dromara.visor.common.handler.data.model;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import java.util.Map; import java.util.Map;

View File

@@ -22,7 +22,7 @@
*/ */
package org.dromara.visor.common.handler.data.strategy; package org.dromara.visor.common.handler.data.strategy;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import org.dromara.visor.common.handler.data.model.GenericsDataModel; import org.dromara.visor.common.handler.data.model.GenericsDataModel;
/** /**

View File

@@ -25,7 +25,7 @@ package org.dromara.visor.common.json;
import cn.orionsec.kit.lang.utils.Desensitizes; import cn.orionsec.kit.lang.utils.Desensitizes;
import cn.orionsec.kit.lang.utils.Objects1; import cn.orionsec.kit.lang.utils.Objects1;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import com.alibaba.fastjson.serializer.ValueFilter; import com.alibaba.fastjson2.filter.ValueFilter;
import java.util.List; import java.util.List;
@@ -55,7 +55,7 @@ public class FieldDesensitizeFilter implements ValueFilter {
} }
@Override @Override
public Object process(Object object, String name, Object value) { public Object apply(Object object, String name, Object value) {
if (Lists.isEmpty(desensitizeFields) || !desensitizeFields.contains(name)) { if (Lists.isEmpty(desensitizeFields) || !desensitizeFields.contains(name)) {
return value; return value;
} }

View File

@@ -23,7 +23,7 @@
package org.dromara.visor.common.json; package org.dromara.visor.common.json;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import com.alibaba.fastjson.serializer.PropertyFilter; import com.alibaba.fastjson2.filter.PropertyFilter;
import java.util.List; import java.util.List;

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2023 - present Dromara, All rights reserved.
*
* https://visor.dromara.org
* https://visor.dromara.org.cn
* https://visor.orionsec.cn
*
* Members:
* Jiahang Li - ljh1553488six@139.com - author
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.visor.common.mapstruct;
import java.util.Date;
/**
* date 转换器
*
* @author Jiahang Li
* @version 1.0.0
* @since 2025/3/7 17:43
*/
public class DateConversion {
private DateConversion() {
}
/**
* Long > Date
*
* @param timestamp timestamp
* @return Date
*/
public static Date longToDate(Long timestamp) {
return timestamp != null ? new Date(timestamp) : null;
}
/**
* Date > Long
*
* @param date date
* @return Long
*/
public static Long dateToLong(Date date) {
return date != null ? date.getTime() : null;
}
}

View File

@@ -22,9 +22,9 @@
*/ */
package org.dromara.visor.common.mapstruct; package org.dromara.visor.common.mapstruct;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson2.JSONObject;
/** /**
* json 转换器 * json 转换器

View File

@@ -24,7 +24,7 @@ package org.dromara.visor.common.utils;
import cn.orionsec.kit.ext.location.Region; import cn.orionsec.kit.ext.location.Region;
import cn.orionsec.kit.ext.location.region.LocationRegions; import cn.orionsec.kit.ext.location.region.LocationRegions;
import cn.orionsec.kit.web.servlet.web.Servlets; import cn.orionsec.kit.lang.utils.net.IPs;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -40,6 +40,8 @@ import java.util.Map;
*/ */
public class IpUtils { public class IpUtils {
private static String[] IP_HEADER = new String[]{"X-Forwarded-For", "X-Real-IP"};
private static final Map<String, String> CACHE = new HashMap<>(); private static final Map<String, String> CACHE = new HashMap<>();
private IpUtils() { private IpUtils() {
@@ -52,13 +54,17 @@ public class IpUtils {
* @return addr * @return addr
*/ */
public static String getRemoteAddr(HttpServletRequest request) { public static String getRemoteAddr(HttpServletRequest request) {
// 获取实际地址 X_REAL_IP 在多代理情况下会有问题 if (request == null) {
// String realIp = request.getHeader(StandardHttpHeader.X_REAL_IP); return null;
// if (!Strings.isBlank(realIp)) { } else {
// return realIp; for (String remoteAddrHeader : IP_HEADER) {
// } String addr = checkIpHeader(request.getHeader(remoteAddrHeader));
// 获取请求地址 if (addr != null) {
return Servlets.getRemoteAddr(request); return addr;
}
}
return checkIpHeader(request.getRemoteAddr());
}
} }
/** /**
@@ -112,4 +118,23 @@ public class IpUtils {
return Const.CN_UNKNOWN; return Const.CN_UNKNOWN;
} }
/**
* 检查 ip 请求头
*
* @param headerValue headerValue
* @return header
*/
private static String checkIpHeader(String headerValue) {
if (headerValue == null) {
return null;
} else {
headerValue = headerValue.split(",")[0];
return IPs.checkIp(headerValue);
}
}
public static void setIpHeader(String[] ipHeader) {
IP_HEADER = ipHeader;
}
} }

View File

@@ -64,10 +64,24 @@ public class Requests {
.map(ServletRequestAttributes::getRequest) .map(ServletRequestAttributes::getRequest)
.ifPresent(request -> { .ifPresent(request -> {
String address = IpUtils.getRemoteAddr(request); String address = IpUtils.getRemoteAddr(request);
identity.setTimestamp(System.currentTimeMillis());
identity.setAddress(address); identity.setAddress(address);
identity.setLocation(IpUtils.getLocation(address)); identity.setLocation(IpUtils.getLocation(address));
identity.setUserAgent(Servlets.getUserAgent(request)); identity.setUserAgent(Servlets.getUserAgent(request));
}); });
} }
/**
* 复制留痕信息
*
* @param source source
* @param target target
*/
public static void copyIdentity(RequestIdentityModel source, RequestIdentityModel target) {
target.setTimestamp(source.getTimestamp());
target.setAddress(source.getAddress());
target.setLocation(source.getLocation());
target.setUserAgent(source.getUserAgent());
}
} }

View File

@@ -14,11 +14,11 @@
<url>https://github.com/dromara/orion-visor</url> <url>https://github.com/dromara/orion-visor</url>
<properties> <properties>
<revision>2.5.2</revision> <revision>2.5.7</revision>
<spring.boot.version>2.7.17</spring.boot.version> <spring.boot.version>2.7.17</spring.boot.version>
<spring.boot.admin.version>2.7.15</spring.boot.admin.version> <spring.boot.admin.version>2.7.15</spring.boot.admin.version>
<flatten.maven.plugin.version>1.5.0</flatten.maven.plugin.version> <flatten.maven.plugin.version>1.5.0</flatten.maven.plugin.version>
<orion.kit.version>2.0.4</orion.kit.version> <orion.kit.version>2.0.6</orion.kit.version>
<aspectj.version>1.9.7</aspectj.version> <aspectj.version>1.9.7</aspectj.version>
<lombok.version>1.18.26</lombok.version> <lombok.version>1.18.26</lombok.version>
<springdoc.version>1.6.15</springdoc.version> <springdoc.version>1.6.15</springdoc.version>
@@ -106,6 +106,11 @@
<artifactId>orion-visor-spring-boot-starter-job</artifactId> <artifactId>orion-visor-spring-boot-starter-job</artifactId>
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-executor</artifactId>
<version>${revision}</version>
</dependency>
<dependency> <dependency>
<groupId>org.dromara.visor</groupId> <groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-websocket</artifactId> <artifactId>orion-visor-spring-boot-starter-websocket</artifactId>

View File

@@ -22,8 +22,7 @@
*/ */
package org.dromara.visor.framework.biz.operator.log.configuration; package org.dromara.visor.framework.biz.operator.log.configuration;
import com.alibaba.fastjson.serializer.SerializeFilter; import com.alibaba.fastjson2.filter.Filter;
import com.alibaba.fastjson.serializer.ValueFilter;
import org.dromara.visor.common.constant.AutoConfigureOrderConst; import org.dromara.visor.common.constant.AutoConfigureOrderConst;
import org.dromara.visor.common.json.FieldDesensitizeFilter; import org.dromara.visor.common.json.FieldDesensitizeFilter;
import org.dromara.visor.common.json.FieldIgnoreFilter; import org.dromara.visor.common.json.FieldIgnoreFilter;
@@ -55,7 +54,7 @@ import javax.annotation.Resource;
public class OrionOperatorLogAutoConfiguration { public class OrionOperatorLogAutoConfiguration {
@Resource @Resource
private ValueFilter desensitizeValueFilter; private Filter desensitizeValueFilter;
/** /**
* 操作日志委托类 * 操作日志委托类
@@ -82,7 +81,7 @@ public class OrionOperatorLogAutoConfiguration {
public OperatorLogAspect operatorLogAspect(OperatorLogConfig operatorLogConfig, public OperatorLogAspect operatorLogAspect(OperatorLogConfig operatorLogConfig,
OperatorLogFrameworkService service) { OperatorLogFrameworkService service) {
// 参数过滤器 // 参数过滤器
SerializeFilter[] serializeFilters = new SerializeFilter[]{ Filter[] serializeFilters = new Filter[]{
// 忽略字段过滤器 // 忽略字段过滤器
new FieldIgnoreFilter(operatorLogConfig.getIgnore()), new FieldIgnoreFilter(operatorLogConfig.getIgnore()),
// 脱敏字段过滤器 // 脱敏字段过滤器

View File

@@ -123,8 +123,8 @@ public class OperatorLogModel implements RequestIdentity {
private Date endTime; private Date endTime;
/** /**
* 创建时间 * 时间
*/ */
private Date createTime; private Long timestamp;
} }

View File

@@ -27,12 +27,12 @@ import cn.orionsec.kit.lang.utils.Exceptions;
import cn.orionsec.kit.lang.utils.Refs; import cn.orionsec.kit.lang.utils.Refs;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.json.matcher.ReplacementFormatters; import cn.orionsec.kit.lang.utils.json.matcher.ReplacementFormatters;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson.serializer.SerializeFilter; import com.alibaba.fastjson2.filter.Filter;
import org.dromara.visor.common.entity.RequestIdentity; import org.dromara.visor.common.entity.RequestIdentity;
import org.dromara.visor.common.enums.BooleanBit; import org.dromara.visor.common.enums.BooleanBit;
import org.dromara.visor.common.trace.TraceIdHolder;
import org.dromara.visor.common.security.LoginUser; import org.dromara.visor.common.security.LoginUser;
import org.dromara.visor.common.trace.TraceIdHolder;
import org.dromara.visor.common.utils.Requests; import org.dromara.visor.common.utils.Requests;
import org.dromara.visor.framework.biz.operator.log.configuration.config.OperatorLogConfig; import org.dromara.visor.framework.biz.operator.log.configuration.config.OperatorLogConfig;
import org.dromara.visor.framework.biz.operator.log.core.enums.ReturnType; import org.dromara.visor.framework.biz.operator.log.core.enums.ReturnType;
@@ -54,7 +54,7 @@ import java.util.Optional;
*/ */
public class OperatorLogFiller implements Gettable<OperatorLogModel> { public class OperatorLogFiller implements Gettable<OperatorLogModel> {
private static SerializeFilter[] serializeFilters; private static Filter[] serializeFilters;
private static OperatorLogConfig operatorLogConfig; private static OperatorLogConfig operatorLogConfig;
@@ -91,6 +91,7 @@ public class OperatorLogFiller implements Gettable<OperatorLogModel> {
*/ */
public OperatorLogFiller fillUsedTime(long start) { public OperatorLogFiller fillUsedTime(long start) {
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
model.setTimestamp(start);
model.setDuration((int) (end - start)); model.setDuration((int) (end - start));
model.setStartTime(new Date(start)); model.setStartTime(new Date(start));
model.setEndTime(new Date(end)); model.setEndTime(new Date(end));
@@ -274,7 +275,7 @@ public class OperatorLogFiller implements Gettable<OperatorLogModel> {
return model; return model;
} }
public static void setSerializeFilters(SerializeFilter[] serializeFilters) { public static void setSerializeFilters(Filter[] serializeFilters) {
if (OperatorLogFiller.serializeFilters != null) { if (OperatorLogFiller.serializeFilters != null) {
// unmodified // unmodified
throw Exceptions.state(); throw Exceptions.state();

View File

@@ -25,9 +25,8 @@ package org.dromara.visor.framework.biz.operator.log.core.utils;
import cn.orionsec.kit.lang.utils.Exceptions; import cn.orionsec.kit.lang.utils.Exceptions;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Maps; import cn.orionsec.kit.lang.utils.collect.Maps;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson2.filter.Filter;
import com.alibaba.fastjson.serializer.SerializeFilter;
import org.dromara.visor.common.constant.ExtraFieldConst; import org.dromara.visor.common.constant.ExtraFieldConst;
import org.dromara.visor.common.security.LoginUser; import org.dromara.visor.common.security.LoginUser;
@@ -44,7 +43,7 @@ public class OperatorLogs implements ExtraFieldConst {
private static final String UN_SAVE_FLAG = "__un__save__"; private static final String UN_SAVE_FLAG = "__un__save__";
private static SerializeFilter[] serializeFilters; private static Filter[] serializeFilters;
/** /**
* 拓展信息 * 拓展信息
@@ -98,7 +97,7 @@ public class OperatorLogs implements ExtraFieldConst {
if (obj == null) { if (obj == null) {
return; return;
} }
if (obj instanceof JSONObject || obj instanceof com.alibaba.fastjson2.JSONObject) { if (obj instanceof com.alibaba.fastjson2.JSONObject || obj instanceof com.alibaba.fastjson2.JSONObject) {
EXTRA_HOLDER.get().putAll(JSON.parseObject(toJsonString(obj))); EXTRA_HOLDER.get().putAll(JSON.parseObject(toJsonString(obj)));
} else if (obj instanceof Map) { } else if (obj instanceof Map) {
EXTRA_HOLDER.get().putAll((Map<String, ?>) obj); EXTRA_HOLDER.get().putAll((Map<String, ?>) obj);
@@ -204,7 +203,7 @@ public class OperatorLogs implements ExtraFieldConst {
.replaceAll("<br/>", "\n"); .replaceAll("<br/>", "\n");
} }
public static void setSerializeFilters(SerializeFilter[] serializeFilters) { public static void setSerializeFilters(Filter[] serializeFilters) {
if (OperatorLogs.serializeFilters != null) { if (OperatorLogs.serializeFilters != null) {
// unmodified // unmodified
throw Exceptions.state(); throw Exceptions.state();

View File

@@ -23,7 +23,7 @@
package org.dromara.visor.framework.biz.push.core.entity; package org.dromara.visor.framework.biz.push.core.entity;
import cn.orionsec.kit.lang.able.IJsonObject; import cn.orionsec.kit.lang.able.IJsonObject;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;

View File

@@ -22,7 +22,7 @@
*/ */
package org.dromara.visor.framework.biz.push.core.entity; package org.dromara.visor.framework.biz.push.core.entity;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;

View File

@@ -23,7 +23,7 @@
package org.dromara.visor.framework.biz.push.core.entity; package org.dromara.visor.framework.biz.push.core.entity;
import cn.orionsec.kit.lang.able.IJsonObject; import cn.orionsec.kit.lang.able.IJsonObject;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;

View File

@@ -23,7 +23,7 @@
package org.dromara.visor.framework.biz.push.core.entity; package org.dromara.visor.framework.biz.push.core.entity;
import cn.orionsec.kit.lang.able.IJsonObject; import cn.orionsec.kit.lang.able.IJsonObject;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;

View File

@@ -22,7 +22,7 @@
*/ */
package org.dromara.visor.framework.biz.push.core.entity; package org.dromara.visor.framework.biz.push.core.entity;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;

View File

@@ -22,7 +22,7 @@
*/ */
package org.dromara.visor.framework.biz.push.core.enums; package org.dromara.visor.framework.biz.push.core.enums;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.dromara.visor.framework.biz.push.core.message.*; import org.dromara.visor.framework.biz.push.core.message.*;

View File

@@ -48,8 +48,7 @@ public class PushMessageEventListener implements ApplicationListener<PushMessage
this.pushServiceMap = pushServiceMap; this.pushServiceMap = pushServiceMap;
} }
// FIXME @Async("pushExecutor")
@Async("asyncExecutor")
@Override @Override
public void onApplicationEvent(PushMessageEvent event) { public void onApplicationEvent(PushMessageEvent event) {
try { try {
@@ -68,4 +67,4 @@ public class PushMessageEventListener implements ApplicationListener<PushMessage
return (IPushService<T>) pushServiceMap.get(message.getChannel()); return (IPushService<T>) pushServiceMap.get(message.getChannel());
} }
} }

View File

@@ -24,7 +24,7 @@ package org.dromara.visor.framework.biz.push.core.service;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import org.dromara.visor.common.entity.PushUser; import org.dromara.visor.common.entity.PushUser;

View File

@@ -31,7 +31,7 @@ import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.codec.Base64s; import cn.orionsec.kit.lang.utils.codec.Base64s;
import cn.orionsec.kit.lang.utils.crypto.Signatures; import cn.orionsec.kit.lang.utils.crypto.Signatures;
import cn.orionsec.kit.lang.utils.math.Hex; import cn.orionsec.kit.lang.utils.math.Hex;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.ErrorMessage; import org.dromara.visor.common.constant.ErrorMessage;
import org.dromara.visor.framework.biz.push.core.annotation.MessageChannel; import org.dromara.visor.framework.biz.push.core.annotation.MessageChannel;

View File

@@ -30,7 +30,7 @@ import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.codec.Base64s; import cn.orionsec.kit.lang.utils.codec.Base64s;
import cn.orionsec.kit.lang.utils.crypto.Signatures; import cn.orionsec.kit.lang.utils.crypto.Signatures;
import cn.orionsec.kit.lang.utils.crypto.enums.SecretKeySpecMode; import cn.orionsec.kit.lang.utils.crypto.enums.SecretKeySpecMode;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.utils.Assert; import org.dromara.visor.common.utils.Assert;
import org.dromara.visor.framework.biz.push.core.annotation.MessageChannel; import org.dromara.visor.framework.biz.push.core.annotation.MessageChannel;

View File

@@ -25,7 +25,7 @@ package org.dromara.visor.framework.biz.push.core.service;
import cn.orionsec.kit.http.ok.OkRequests; import cn.orionsec.kit.http.ok.OkRequests;
import cn.orionsec.kit.http.ok.OkResponse; import cn.orionsec.kit.http.ok.OkResponse;
import cn.orionsec.kit.lang.constant.StandardContentType; import cn.orionsec.kit.lang.constant.StandardContentType;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.utils.Assert; import org.dromara.visor.common.utils.Assert;
import org.dromara.visor.framework.biz.push.core.annotation.MessageChannel; import org.dromara.visor.framework.biz.push.core.annotation.MessageChannel;

View File

@@ -28,8 +28,8 @@ import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Maps; import cn.orionsec.kit.lang.utils.collect.Maps;
import cn.orionsec.kit.lang.utils.reflect.Annotations; import cn.orionsec.kit.lang.utils.reflect.Annotations;
import cn.orionsec.kit.lang.utils.reflect.Fields; import cn.orionsec.kit.lang.utils.reflect.Fields;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import com.alibaba.fastjson.serializer.ValueFilter; import com.alibaba.fastjson2.filter.ValueFilter;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import org.dromara.visor.framework.desensitize.core.annotation.Desensitize; import org.dromara.visor.framework.desensitize.core.annotation.Desensitize;
import org.dromara.visor.framework.desensitize.core.annotation.DesensitizeObject; import org.dromara.visor.framework.desensitize.core.annotation.DesensitizeObject;
@@ -53,7 +53,7 @@ public class DesensitizeValueFilter implements ValueFilter {
private static final Map<String, Map<String, Desensitize>> DESENSITIZE_FIELDS = new HashMap<>(); private static final Map<String, Map<String, Desensitize>> DESENSITIZE_FIELDS = new HashMap<>();
@Override @Override
public Object process(Object object, String name, Object value) { public Object apply(Object object, String name, Object value) {
if (object == null || value == null) { if (object == null || value == null) {
return value; return value;
} }

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-framework</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>orion-visor-spring-boot-starter-executor</artifactId>
<name>${project.artifactId}</name>
<packaging>jar</packaging>
<description>项目线程池配置包</description>
<url>https://github.com/dromara/orion-visor</url>
<dependencies>
<!-- common -->
<dependency>
<groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-common</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2023 - present Dromara, All rights reserved.
*
* https://visor.dromara.org
* https://visor.dromara.org.cn
* https://visor.orionsec.cn
*
* Members:
* Jiahang Li - ljh1553488six@139.com - author
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.visor.framework.executor.configuration;
import org.dromara.visor.common.constant.AutoConfigureOrderConst;
import org.dromara.visor.framework.executor.configuration.config.ExecutorsConfig;
import org.dromara.visor.framework.executor.core.context.ExecutorContext;
import org.dromara.visor.framework.executor.core.utils.ExecutorUtils;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.Map;
/**
* 项目线程池配置
*
* @author Jiahang Li
* @version 1.0.0
* @since 2025/9/16 14:34
*/
@EnableAsync
@AutoConfiguration
@EnableConfigurationProperties({ExecutorsConfig.class})
@AutoConfigureOrder(AutoConfigureOrderConst.FRAMEWORK_EXECUTOR)
public class OrionExecutorAutoConfiguration {
/**
* 创建线程池上下文
*
* @param executorsConfig executorsConfig
* @param beanFactory beanFactory
* @return 线程池上下文
*/
@Bean
public ExecutorContext executorContext(ExecutorsConfig executorsConfig,
ConfigurableBeanFactory beanFactory) {
// 创建上下文
ExecutorContext context = new ExecutorContext(executorsConfig, beanFactory);
Map<String, ThreadPoolTaskExecutor> executorMap = context.init();
// 获取线程池列表
ExecutorUtils.setExecutors(executorMap);
return context;
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 2023 - present Dromara, All rights reserved.
*
* https://visor.dromara.org
* https://visor.dromara.org.cn
* https://visor.orionsec.cn
*
* Members:
* Jiahang Li - ljh1553488six@139.com - author
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.visor.framework.executor.configuration.config;
import cn.orionsec.kit.lang.define.thread.RejectPolicy;
import cn.orionsec.kit.lang.utils.Systems;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
/**
* 线程池配置
*
* @author Jiahang Li
* @version 1.0.0
* @since 2025/9/16 10:51
*/
@Data
@Builder
@AllArgsConstructor
public class ExecutorConfig {
/**
* 是否启用
*/
private boolean enabled;
/**
* 是否使用 MDC
*/
private boolean mdc;
/**
* 核心线程数
*/
private int corePoolSize;
/**
* 最大线程数
*/
private int maxPoolSize;
/**
* 队列容量
*/
private int queueCapacity;
/**
* 空闲线程存活时间
*/
private int keepAliveSeconds;
/**
* 是否允许核心线程超时
*/
private boolean allowCoreTimeout;
/**
* 是否使用同步队列
*/
private boolean synchronousQueue;
/**
* 线程名称前缀
*/
private String threadNamePrefix;
/**
* 拒绝策略
*/
private RejectPolicy rejectPolicy;
public ExecutorConfig() {
this.enabled = true;
this.corePoolSize = Systems.PROCESS_NUM;
this.maxPoolSize = Systems.PROCESS_NUM;
this.queueCapacity = 100;
this.keepAliveSeconds = 300;
this.rejectPolicy = RejectPolicy.CALLER_RUNS;
}
}

View File

@@ -20,47 +20,27 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.visor.framework.job.configuration.config; package org.dromara.visor.framework.executor.configuration.config;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Map;
/** /**
* 线程池配置 * 线程池配置
* *
* @author Jiahang Li * @author Jiahang Li
* @version 1.0.0 * @version 1.0.0
* @since 2023/7/10 15:49 * @since 2025/9/16 16:21
*/ */
@Data @Data
@ConfigurationProperties(prefix = "orion.async.executor") @ConfigurationProperties(prefix = "app")
public class AsyncExecutorConfig { public class ExecutorsConfig {
/** /**
* 核心线程数量 * 线程池配置
*/ */
private int corePoolSize; private Map<String, ExecutorConfig> executors;
/**
* 最大线程数量
*/
private int maxPoolSize;
/**
* 队列容量
*/
private int queueCapacity;
/**
* 活跃时间
*/
private int keepAliveSeconds;
public AsyncExecutorConfig() {
this.corePoolSize = 8;
this.maxPoolSize = 16;
this.queueCapacity = 200;
this.keepAliveSeconds = 300;
}
} }

View File

@@ -0,0 +1,119 @@
/*
* Copyright (c) 2023 - present Dromara, All rights reserved.
*
* https://visor.dromara.org
* https://visor.dromara.org.cn
* https://visor.orionsec.cn
*
* Members:
* Jiahang Li - ljh1553488six@139.com - author
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.visor.framework.executor.core.context;
import cn.orionsec.kit.lang.define.thread.RejectPolicy;
import cn.orionsec.kit.lang.utils.Strings;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.thread.ThreadPoolMdcTaskExecutor;
import org.dromara.visor.framework.executor.configuration.config.ExecutorConfig;
import org.dromara.visor.framework.executor.configuration.config.ExecutorsConfig;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.HashMap;
import java.util.Map;
/**
* 执行器上下文
*
* @author Jiahang Li
* @version 1.0.0
* @since 2025/9/16 16:28
*/
@Slf4j
public class ExecutorContext {
private final ExecutorsConfig executorsConfig;
private final ConfigurableBeanFactory beanFactory;
public ExecutorContext(ExecutorsConfig executorsConfig, ConfigurableBeanFactory beanFactory) {
this.executorsConfig = executorsConfig;
this.beanFactory = beanFactory;
}
/**
* 初始化
*
* @return executorMap
*/
public Map<String, ThreadPoolTaskExecutor> init() {
log.info("--------- Executors init start --------- ");
Map<String, ThreadPoolTaskExecutor> executorMap = new HashMap<>();
executorsConfig.getExecutors().forEach((beanName, config) -> {
String executorName = Strings.leftPad(beanName, 30);
// 是否启用
if (!config.isEnabled()) {
log.info("Executor [{}] is disabled.", executorName);
return;
}
// 创建线程池
ThreadPoolTaskExecutor executor = this.createTaskExecutor(config);
// 注册到容器中
beanFactory.registerSingleton(beanName, executor);
executorMap.put(beanName, executor);
log.info("Executor [{}] init success. {}", executorName, JSON.toJSONString(config));
});
log.info("--------- Executors init end --------- ");
return executorMap;
}
/**
* 创建线程池
*
* @param config config
*/
private ThreadPoolTaskExecutor createTaskExecutor(ExecutorConfig config) {
// 创建线程池
ThreadPoolTaskExecutor executor;
if (config.isMdc()) {
executor = new ThreadPoolMdcTaskExecutor();
} else {
executor = new ThreadPoolTaskExecutor();
}
// 同步队列
if (config.isSynchronousQueue()) {
config.setCorePoolSize(0);
config.setMaxPoolSize(Integer.MAX_VALUE);
config.setQueueCapacity(0);
config.setRejectPolicy(RejectPolicy.ABORT);
}
// 设置参数
executor.setCorePoolSize(config.getCorePoolSize());
executor.setMaxPoolSize(config.getMaxPoolSize());
executor.setQueueCapacity(config.getQueueCapacity());
executor.setThreadNamePrefix(config.getThreadNamePrefix());
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
executor.setAllowCoreThreadTimeOut(config.isAllowCoreTimeout());
executor.setRejectedExecutionHandler(config.getRejectPolicy().getHandler());
// 设置等待所有任务执行结束再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
// 初始化
executor.initialize();
return executor;
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 2023 - present Dromara, All rights reserved.
*
* https://visor.dromara.org
* https://visor.dromara.org.cn
* https://visor.orionsec.cn
*
* Members:
* Jiahang Li - ljh1553488six@139.com - author
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.visor.framework.executor.core.utils;
import cn.orionsec.kit.lang.able.Executable;
import cn.orionsec.kit.lang.utils.Exceptions;
import cn.orionsec.kit.lang.utils.collect.Maps;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.Map;
/**
* 线程池工具类
*
* @author Jiahang Li
* @version 1.0.0
* @since 2025/9/16 16:34
*/
public class ExecutorUtils {
private static Map<String, ThreadPoolTaskExecutor> executorMap;
private ExecutorUtils() {
}
/**
* 获取线程池
*
* @param name name
* @return executor
*/
public static ThreadPoolTaskExecutor getExecutor(String name) {
return executorMap.get(name);
}
/**
* 执行
*
* @param name name
* @param runnable runnable
*/
public static void execute(String name, Runnable runnable) {
getExecutor(name).execute(runnable);
}
/**
* 执行
*
* @param name name
* @param executable executable
*/
public static void execute(String name, Executable executable) {
getExecutor(name).execute(executable::exec);
}
public static void setExecutors(Map<String, ThreadPoolTaskExecutor> executorMap) {
if (ExecutorUtils.executorMap != null) {
// unmodified
throw Exceptions.state();
}
ExecutorUtils.executorMap = Maps.unmodified(executorMap);
}
}

View File

@@ -0,0 +1,77 @@
{
"groups": [
{
"name": "orion.executors.*",
"type": "org.dromara.visor.framework.executor.configuration.config.ExecutorConfig",
"sourceType": "org.dromara.visor.framework.executor.configuration.config.ExecutorConfig",
"description": "线程池配置项."
}
],
"properties": [
{
"name": "orion.executors",
"type": "java.util.Map<java.lang.String,org.dromara.visor.framework.executor.configuration.config.ExecutorConfig>",
"description": "线程池配置.",
"defaultValue": "{}"
},
{
"name": "orion.executors.*.enabled",
"type": "java.lang.Boolean",
"description": "是否启用.",
"defaultValue": false
},
{
"name": "orion.executors.*.corePoolSize",
"type": "java.lang.Integer",
"description": "核心线程数.",
"defaultValue": "CPU_NUM"
},
{
"name": "orion.executors.*.maxPoolSize",
"type": "java.lang.Integer",
"description": "最大线程数.",
"defaultValue": "CPU_NUM"
},
{
"name": "orion.executors.*.queueCapacity",
"type": "java.lang.Integer",
"description": "任务队列容量.",
"defaultValue": 100
},
{
"name": "orion.executors.*.keepAliveSeconds",
"type": "java.lang.Integer",
"description": "空闲线程存活时间.",
"defaultValue": 60
},
{
"name": "orion.executors.*.allowCoreTimeout",
"type": "java.lang.Boolean",
"description": "是否允许核心线程超时回收.",
"defaultValue": false
},
{
"name": "orion.executors.*.synchronousQueue",
"type": "java.lang.Boolean",
"description": "是否启用同步队列模式.",
"defaultValue": false
},
{
"name": "orion.executors.*.mdc",
"type": "java.lang.Boolean",
"description": "是否启用 MDC 上下文传递.",
"defaultValue": false
},
{
"name": "orion.executors.*.threadNamePrefix",
"type": "java.lang.String",
"description": "线程名称前缀."
},
{
"name": "orion.executors.*.rejectPolicy",
"type": "cn.orionsec.kit.lang.define.thread.RejectPolicy",
"description": "拒绝策略.",
"defaultValue": "CALLER_RUNS"
}
]
}

View File

@@ -0,0 +1 @@
org.dromara.visor.framework.executor.configuration.OrionExecutorAutoConfiguration

View File

@@ -24,6 +24,7 @@ package org.dromara.visor.framework.influxdb.core.query;
import cn.orionsec.kit.lang.utils.collect.Collections; import cn.orionsec.kit.lang.utils.collect.Collections;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import cn.orionsec.kit.lang.utils.collect.Maps;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import java.time.Instant; import java.time.Instant;
@@ -194,7 +195,7 @@ public class FluxQueryBuilder {
if (values.size() == 1) { if (values.size() == 1) {
return this.tag(key, Collections.first(values)); return this.tag(key, Collections.first(values));
} }
// // 使用 or 拼接
Collection<String> conditions = values.stream() Collection<String> conditions = values.stream()
.map(value -> String.format("r[\"%s\"] == \"%s\"", key, value)) .map(value -> String.format("r[\"%s\"] == \"%s\"", key, value))
.collect(Collectors.toList()); .collect(Collectors.toList());
@@ -204,33 +205,18 @@ public class FluxQueryBuilder {
} }
/** /**
* 过滤多个 tag * 过滤 tag
* tag 使用 and
* value 使用 or
* *
* @param tags tags * @param tags tags
* @return this * @return this
*/ */
public FluxQueryBuilder tags(Map<String, ? extends Collection<String>> tags) { public FluxQueryBuilder tags(Map<String, ? extends Collection<String>> tags) {
for (Map.Entry<String, ? extends Collection<String>> entry : tags.entrySet()) { if (Maps.isEmpty(tags)) {
String key = entry.getKey(); return this;
Collection<String> values = entry.getValue(); }
if (Collections.isEmpty(values)) { for (Map.Entry<String, ? extends Collection<String>> entry : tags.entrySet()) {
continue; this.tag(entry.getKey(), entry.getValue());
}
if (values.size() == 1) {
// 单值直接用等号
String singleValue = values.iterator().next();
this.appendFilter(String.format("r[\"%s\"] == \"%s\"", key, singleValue));
} else {
// 多值用 OR
Collection<String> conditions = values.stream()
.map(v -> String.format("r[\"%s\"] == \"%s\"", key, v))
.collect(Collectors.toList());
this.appendFilter("(" + String.join(" or ", conditions) + ")");
}
} }
this.closeFilter();
return this; return this;
} }

View File

@@ -30,7 +30,9 @@ import com.influxdb.client.write.Point;
import com.influxdb.query.FluxRecord; import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable; import com.influxdb.query.FluxTable;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import org.dromara.visor.common.constant.ErrorMessage;
import org.dromara.visor.common.entity.chart.TimeChartSeries; import org.dromara.visor.common.entity.chart.TimeChartSeries;
import org.dromara.visor.common.utils.Assert;
import org.dromara.visor.framework.influxdb.core.query.FluxQueryBuilder; import org.dromara.visor.framework.influxdb.core.query.FluxQueryBuilder;
import java.time.Instant; import java.time.Instant;
@@ -66,6 +68,7 @@ public class InfluxdbUtils {
* @param points points * @param points points
*/ */
public static void writePoints(List<Point> points) { public static void writePoints(List<Point> points) {
Assert.notNull(client, ErrorMessage.INFLUXDB_UNSUPPORTED);
try (WriteApi api = client.makeWriteApi()) { try (WriteApi api = client.makeWriteApi()) {
// 写入指标 // 写入指标
api.writePoints(points); api.writePoints(points);
@@ -79,6 +82,7 @@ public class InfluxdbUtils {
* @return points * @return points
*/ */
public static List<FluxTable> queryTable(String query) { public static List<FluxTable> queryTable(String query) {
Assert.notNull(client, ErrorMessage.INFLUXDB_UNSUPPORTED);
return client.getQueryApi().query(query); return client.getQueryApi().query(query);
} }

View File

@@ -1,96 +0,0 @@
/*
* Copyright (c) 2023 - present Dromara, All rights reserved.
*
* https://visor.dromara.org
* https://visor.dromara.org.cn
* https://visor.orionsec.cn
*
* Members:
* Jiahang Li - ljh1553488six@139.com - author
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.visor.framework.job.configuration;
import org.dromara.visor.common.constant.AutoConfigureOrderConst;
import org.dromara.visor.common.constant.Const;
import org.dromara.visor.common.thread.ThreadPoolMdcTaskExecutor;
import org.dromara.visor.framework.job.configuration.config.AsyncExecutorConfig;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import java.util.concurrent.ThreadPoolExecutor;
/**
* async 异步任务
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/6/20 10:34
*/
@EnableAsync
@AutoConfiguration
@AutoConfigureOrder(AutoConfigureOrderConst.FRAMEWORK_JOB_ASYNC)
@EnableConfigurationProperties(AsyncExecutorConfig.class)
public class OrionAsyncAutoConfiguration {
/**
* {@code @Async("asyncExecutor")}
*
* @return 支持 MDC 的异步线程池
*/
@Bean(name = "asyncExecutor")
public TaskExecutor asyncExecutor(AsyncExecutorConfig config) {
ThreadPoolMdcTaskExecutor executor = new ThreadPoolMdcTaskExecutor();
executor.setCorePoolSize(config.getCorePoolSize());
executor.setMaxPoolSize(config.getMaxPoolSize());
executor.setQueueCapacity(config.getQueueCapacity());
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
executor.setAllowCoreThreadTimeOut(true);
executor.setThreadNamePrefix("async-task-");
// 设置等待所有任务执行结束再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
// 以确保应用最后能够被关闭
executor.setAwaitTerminationSeconds(60);
// 调用者调用拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
/**
* {@code @Async("metricsExecutor")}
*
* @return 指标线程池
*/
@Bean(name = "metricsExecutor")
public TaskExecutor metricsExecutor() {
ThreadPoolMdcTaskExecutor executor = new ThreadPoolMdcTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(8);
executor.setQueueCapacity(1000);
executor.setKeepAliveSeconds(Const.MS_S_60);
executor.setAllowCoreThreadTimeOut(true);
executor.setThreadNamePrefix("metrics-task-");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}

View File

@@ -25,6 +25,8 @@ package org.dromara.visor.framework.job.configuration;
import org.dromara.visor.common.constant.AutoConfigureOrderConst; import org.dromara.visor.common.constant.AutoConfigureOrderConst;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.task.TaskSchedulingProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
@@ -40,17 +42,18 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@EnableScheduling @EnableScheduling
@AutoConfiguration @AutoConfiguration
@AutoConfigureOrder(AutoConfigureOrderConst.FRAMEWORK_JOB) @AutoConfigureOrder(AutoConfigureOrderConst.FRAMEWORK_JOB)
@EnableConfigurationProperties(TaskSchedulingProperties.class)
public class OrionSchedulerAutoConfiguration { public class OrionSchedulerAutoConfiguration {
/** /**
* @return 任务调度器 * @return 任务调度器
*/ */
@Bean @Bean
public TaskScheduler taskScheduler() { public TaskScheduler taskScheduler(TaskSchedulingProperties properties) {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(4);
scheduler.setRemoveOnCancelPolicy(true); scheduler.setRemoveOnCancelPolicy(true);
scheduler.setThreadNamePrefix("scheduling-task-"); scheduler.setPoolSize(properties.getPool().getSize());
scheduler.setThreadNamePrefix(properties.getThreadNamePrefix());
return scheduler; return scheduler;
} }

View File

@@ -1,35 +0,0 @@
{
"groups": [
{
"name": "orion.async.executor",
"type": "org.dromara.visor.framework.job.configuration.config.AsyncExecutorConfig",
"sourceType": "org.dromara.visor.framework.job.configuration.config.AsyncExecutorConfig"
}
],
"properties": [
{
"name": "orion.async.executor.core-pool-size",
"type": "java.lang.Integer",
"description": "核心线程数量.",
"defaultValue": "8"
},
{
"name": "orion.async.executor.max-pool-size",
"type": "java.lang.Integer",
"description": "最大线程数量.",
"defaultValue": "16"
},
{
"name": "orion.async.executor.queue-capacity",
"type": "java.lang.Integer",
"description": "队列容量.",
"defaultValue": "200"
},
{
"name": "orion.async.executor.keep-alive-seconds",
"type": "java.lang.Integer",
"description": "活跃时间.",
"defaultValue": "300"
}
]
}

View File

@@ -1,3 +1,2 @@
org.dromara.visor.framework.job.configuration.OrionSchedulerAutoConfiguration org.dromara.visor.framework.job.configuration.OrionSchedulerAutoConfiguration
org.dromara.visor.framework.job.configuration.OrionQuartzAutoConfiguration org.dromara.visor.framework.job.configuration.OrionQuartzAutoConfiguration
org.dromara.visor.framework.job.configuration.OrionAsyncAutoConfiguration

View File

@@ -25,10 +25,10 @@ package org.dromara.visor.framework.log.core.interceptor;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Maps; import cn.orionsec.kit.lang.utils.collect.Maps;
import cn.orionsec.kit.lang.utils.reflect.Classes; import cn.orionsec.kit.lang.utils.reflect.Classes;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson.serializer.SerializeFilter; import com.alibaba.fastjson2.filter.Filter;
import com.alibaba.fastjson.serializer.ValueFilter; import com.alibaba.fastjson2.filter.ValueFilter;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.dromara.visor.common.json.FieldDesensitizeFilter; import org.dromara.visor.common.json.FieldDesensitizeFilter;
import org.dromara.visor.common.json.FieldIgnoreFilter; import org.dromara.visor.common.json.FieldIgnoreFilter;
@@ -65,7 +65,7 @@ public abstract class AbstractLogPrinterInterceptor implements LogPrinterInterce
/** /**
* 字段过滤器 * 字段过滤器
*/ */
protected SerializeFilter[] serializeFilters; protected Filter[] serializeFilters;
/** /**
* 脱敏配置 * 脱敏配置
@@ -91,7 +91,7 @@ public abstract class AbstractLogPrinterInterceptor implements LogPrinterInterce
@Override @Override
public void init() { public void init() {
// 参数过滤器 // 参数过滤器
this.serializeFilters = new SerializeFilter[]{ this.serializeFilters = new Filter[]{
// 忽略字段过滤器 // 忽略字段过滤器
new FieldIgnoreFilter(config.getField().getIgnore()), new FieldIgnoreFilter(config.getField().getIgnore()),
// 脱敏字段过滤器 // 脱敏字段过滤器

View File

@@ -26,7 +26,7 @@ import cn.orionsec.kit.lang.utils.Exceptions;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.time.Dates; import cn.orionsec.kit.lang.utils.time.Dates;
import cn.orionsec.kit.web.servlet.web.Servlets; import cn.orionsec.kit.web.servlet.web.Servlets;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.dromara.visor.common.utils.IpUtils; import org.dromara.visor.common.utils.IpUtils;

View File

@@ -24,7 +24,7 @@ package org.dromara.visor.framework.mybatis.core.generator.core;
import cn.orionsec.kit.lang.utils.Exceptions; import cn.orionsec.kit.lang.utils.Exceptions;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.generator.config.po.TableField; import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;

View File

@@ -22,8 +22,8 @@
*/ */
package org.dromara.visor.framework.mybatis.core.type; package org.dromara.visor.framework.mybatis.core.type;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson2.JSONArray;
import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes; import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes; import org.apache.ibatis.type.MappedTypes;

View File

@@ -22,8 +22,8 @@
*/ */
package org.dromara.visor.framework.mybatis.core.type; package org.dromara.visor.framework.mybatis.core.type;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson2.JSONObject;
import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes; import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes; import org.apache.ibatis.type.MappedTypes;

View File

@@ -25,18 +25,19 @@ package ${package.ServiceImpl};
import cn.orionsec.kit.lang.define.wrapper.DataGrid; import cn.orionsec.kit.lang.define.wrapper.DataGrid;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.ErrorMessage; import org.dromara.visor.common.constant.ErrorMessage;
import org.dromara.visor.common.utils.Assert; import org.dromara.visor.common.utils.Assert;
#if($meta.enableCache) #if($meta.enableCache)
import org.dromara.visor.framework.redis.core.utils.RedisMaps; import org.dromara.visor.framework.redis.core.utils.RedisMaps;
import org.dromara.visor.framework.redis.core.utils.barrier.CacheBarriers; import org.dromara.visor.framework.redis.core.utils.RedisUtils;
#end import org.dromara.visor.framework.redis.core.utils.barrier.CacheBarriers;
#foreach($pkg in ${customModuleFilePackages}) #end
import ${pkg}.*; #foreach($pkg in ${customModuleFilePackages})
#end import ${pkg}.*;
#end
import ${package.Entity}.${entity}; import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName}; import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName}; import ${package.Service}.${table.serviceName};
@@ -59,222 +60,222 @@ import java.util.stream.Collectors;
@Service @Service
public class ${table.serviceImplName} implements ${table.serviceName} { public class ${table.serviceImplName} implements ${table.serviceName} {
@Resource @Resource
private ${type}DAO ${typeLower}DAO; private ${type}DAO ${typeLower}DAO;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long create${type}(${type}CreateRequest request) { public Long create${type}(${type}CreateRequest request) {
log.info("${type}Service-create${type} request: {}", JSON.toJSONString(request)); log.info("${type}Service-create${type} request: {}", JSON.toJSONString(request));
// 转换 // 转换
${type}DO record = ${type}Convert.MAPPER.to(request); ${type}DO record = ${type}Convert.MAPPER.to(request);
// 查询数据是否冲突 // 查询数据是否冲突
this.check${type}Present(record); this.check${type}Present(record);
// 插入 // 插入
int effect = ${typeLower}DAO.insert(record); int effect = ${typeLower}DAO.insert(record);
Long id = record.getId(); Long id = record.getId();
log.info("${type}Service-create${type} id: {}, effect: {}", id, effect); log.info("${type}Service-create${type} id: {}, effect: {}", id, effect);
#if($meta.enableCache) #if($meta.enableCache)
// 删除缓存 // 删除缓存
RedisMaps.delete(${type}CacheKeyDefine.${typeConst}); RedisUtils.delete(${type}CacheKeyDefine.${typeConst});
#end #end
return id; return id;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Integer update${type}ById(${type}UpdateRequest request) {
Long id = Assert.notNull(request.getId(), ErrorMessage.ID_MISSING);
log.info("${type}Service-update${type}ById id: {}, request: {}", id, JSON.toJSONString(request));
// 查询
${type}DO record = ${typeLower}DAO.selectById(id);
Assert.notNull(record, ErrorMessage.DATA_ABSENT);
// 转换
${type}DO updateRecord = ${type}Convert.MAPPER.to(request);
// 查询数据是否冲突
this.check${type}Present(updateRecord);
// 更新
int effect = ${typeLower}DAO.updateById(updateRecord);
log.info("${type}Service-update${type}ById effect: {}", effect);
#if($meta.enableCache)
// 删除缓存
RedisMaps.delete(${type}CacheKeyDefine.${typeConst});
#end
return effect;
}
@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));
// 条件
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(query);
// 转换
${type}DO updateRecord = ${type}Convert.MAPPER.to(update);
// 更新
int effect = ${typeLower}DAO.update(updateRecord, wrapper);
log.info("${type}Service.update${type} effect: {}", effect);
#if($meta.enableCache)
// 删除缓存
RedisMaps.delete(${type}CacheKeyDefine.${typeConst});
#end
return effect;
}
@Override
public ${type}VO get${type}ById(Long id) {
// 查询
${type}DO record = ${typeLower}DAO.selectById(id);
Assert.notNull(record, ErrorMessage.DATA_ABSENT);
// 转换
return ${type}Convert.MAPPER.to(record);
}
@Override
public List<${type}VO> get${type}ByIdList(List<Long> idList) {
// 查询
List<${type}DO> records = ${typeLower}DAO.selectBatchIds(idList);
if (records.isEmpty()) {
return Lists.empty();
} }
// 转换
return ${type}Convert.MAPPER.to(records);
}
@Override @Override
public List<${type}VO> get${type}List(${type}QueryRequest request) { @Transactional(rollbackFor = Exception.class)
// 条件 public Integer update${type}ById(${type}UpdateRequest request) {
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request); Long id = Assert.notNull(request.getId(), ErrorMessage.ID_MISSING);
// 查询 log.info("${type}Service-update${type}ById id: {}, request: {}", id, JSON.toJSONString(request));
return ${typeLower}DAO.of(wrapper) // 查询
.order(request, ${type}DO::getId) ${type}DO record = ${typeLower}DAO.selectById(id);
.list(${type}Convert.MAPPER::to); Assert.notNull(record, ErrorMessage.DATA_ABSENT);
} // 转换
${type}DO updateRecord = ${type}Convert.MAPPER.to(request);
// 查询数据是否冲突
this.check${type}Present(updateRecord);
// 更新
int effect = ${typeLower}DAO.updateById(updateRecord);
log.info("${type}Service-update${type}ById effect: {}", effect);
#if($meta.enableCache)
// 删除缓存
RedisUtils.delete(${type}CacheKeyDefine.${typeConst});
#end
return effect;
}
@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));
// 条件
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(query);
// 转换
${type}DO updateRecord = ${type}Convert.MAPPER.to(update);
// 更新
int effect = ${typeLower}DAO.update(updateRecord, wrapper);
log.info("${type}Service.update${type} effect: {}", effect);
#if($meta.enableCache)
// 删除缓存
RedisUtils.delete(${type}CacheKeyDefine.${typeConst});
#end
return effect;
}
@Override
public ${type}VO get${type}ById(Long id) {
// 查询
${type}DO record = ${typeLower}DAO.selectById(id);
Assert.notNull(record, ErrorMessage.DATA_ABSENT);
// 转换
return ${type}Convert.MAPPER.to(record);
}
@Override
public List<${type}VO> get${type}ByIdList(List<Long> idList) {
// 查询
List<${type}DO> records = ${typeLower}DAO.selectBatchIds(idList);
if (records.isEmpty()) {
return Lists.empty();
}
// 转换
return ${type}Convert.MAPPER.to(records);
}
@Override
public List<${type}VO> get${type}List(${type}QueryRequest request) {
// 条件
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request);
// 查询
return ${typeLower}DAO.of(wrapper)
.order(request, ${type}DO::getId)
.list(${type}Convert.MAPPER::to);
}
#if($meta.enableCache) #if($meta.enableCache)
@Override @Override
public List<${type}VO> get${type}ListByCache() { public List<${type}VO> get${type}ListByCache() {
// 查询缓存 // 查询缓存
List<${type}CacheDTO> list = RedisMaps.valuesJson(${type}CacheKeyDefine.${typeConst}); List<${type}CacheDTO> list = RedisMaps.valuesJson(${type}CacheKeyDefine.${typeConst});
if (list.isEmpty()) { if (list.isEmpty()) {
// 查询数据库 // 查询数据库
list = ${typeLower}DAO.of().list(${type}Convert.MAPPER::toCache); list = ${typeLower}DAO.of().list(${type}Convert.MAPPER::toCache);
// 设置屏障 防止穿透 // 设置屏障 防止穿透
CacheBarriers.checkBarrier(list, ${type}CacheDTO::new); CacheBarriers.checkBarrier(list, ${type}CacheDTO::new);
// 设置缓存 // 设置缓存
RedisMaps.putAllJson(${type}CacheKeyDefine.${typeConst}, s -> s.getId().toString(), list); RedisMaps.putAllJson(${type}CacheKeyDefine.${typeConst}, s -> s.getId().toString(), list);
} }
// 删除屏障 // 删除屏障
CacheBarriers.removeBarrier(list); CacheBarriers.removeBarrier(list);
// 转换 // 转换
return list.stream() return list.stream()
.map(${type}Convert.MAPPER::to) .map(${type}Convert.MAPPER::to)
.sorted(Comparator.comparing(${type}VO::getId).reversed()) .sorted(Comparator.comparing(${type}VO::getId).reversed())
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
#end #end
@Override @Override
public DataGrid<${type}VO> get${type}Page(${type}QueryRequest request) { public DataGrid<${type}VO> get${type}Page(${type}QueryRequest request) {
// 条件 // 条件
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request); LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request);
// 查询 // 查询
return ${typeLower}DAO.of() return ${typeLower}DAO.of()
.wrapper(wrapper) .wrapper(wrapper)
.page(request) .page(request)
.order(request, ${type}DO::getId) .order(request, ${type}DO::getId)
.dataGrid(${type}Convert.MAPPER::to); .dataGrid(${type}Convert.MAPPER::to);
} }
@Override @Override
public Long get${type}Count(${type}QueryRequest request) { public Long get${type}Count(${type}QueryRequest request) {
// 条件 // 条件
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request); LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request);
// 查询 // 查询
return ${typeLower}DAO.of() return ${typeLower}DAO.of()
.wrapper(wrapper) .wrapper(wrapper)
.countMax(request.getLimit()); .countMax(request.getLimit());
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Integer delete${type}ById(Long id) { public Integer delete${type}ById(Long id) {
log.info("${type}Service-delete${type}ById id: {}", id); log.info("${type}Service-delete${type}ById id: {}", id);
// 检查数据是否存在 // 检查数据是否存在
${type}DO record = ${typeLower}DAO.selectById(id); ${type}DO record = ${typeLower}DAO.selectById(id);
Assert.notNull(record, ErrorMessage.DATA_ABSENT); Assert.notNull(record, ErrorMessage.DATA_ABSENT);
// 删除 // 删除
int effect = ${typeLower}DAO.deleteById(id); int effect = ${typeLower}DAO.deleteById(id);
log.info("${type}Service-delete${type}ById id: {}, effect: {}", id, effect); log.info("${type}Service-delete${type}ById id: {}, effect: {}", id, effect);
#if($meta.enableCache) #if($meta.enableCache)
// 删除缓存 // 删除缓存
RedisMaps.delete(${type}CacheKeyDefine.${typeConst}, id); RedisMaps.delete(${type}CacheKeyDefine.${typeConst}, id);
#end #end
return effect; return effect;
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Integer delete${type}ByIdList(List<Long> idList) { public Integer delete${type}ByIdList(List<Long> idList) {
log.info("${type}Service-delete${type}ByIdList idList: {}", idList); log.info("${type}Service-delete${type}ByIdList idList: {}", idList);
int effect = ${typeLower}DAO.deleteBatchIds(idList); int effect = ${typeLower}DAO.deleteBatchIds(idList);
log.info("${type}Service-delete${type}ByIdList effect: {}", effect); log.info("${type}Service-delete${type}ByIdList effect: {}", effect);
#if($meta.enableCache) #if($meta.enableCache)
// 删除缓存 // 删除缓存
RedisMaps.delete(${type}CacheKeyDefine.${typeConst}, idList); RedisMaps.delete(${type}CacheKeyDefine.${typeConst}, idList);
#end #end
return effect; return effect;
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Integer delete${type}(${type}QueryRequest request) { public Integer delete${type}(${type}QueryRequest request) {
log.info("${type}Service.delete${type} request: {}", JSON.toJSONString(request)); log.info("${type}Service.delete${type} request: {}", JSON.toJSONString(request));
// 条件 // 条件
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request); LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request);
// 删除 // 删除
int effect = ${typeLower}DAO.delete(wrapper); int effect = ${typeLower}DAO.delete(wrapper);
log.info("${type}Service.delete${type} effect: {}", effect); log.info("${type}Service.delete${type} effect: {}", effect);
#if($meta.enableCache) #if($meta.enableCache)
// 删除缓存 // 删除缓存
RedisMaps.delete(${type}CacheKeyDefine.${typeConst}); RedisUtils.delete(${type}CacheKeyDefine.${typeConst});
#end #end
return effect; return effect;
} }
/** /**
* 检查对象是否存在 * 检查对象是否存在
* *
* @param domain domain * @param domain domain
*/ */
private void check${type}Present(${type}DO domain) { private void check${type}Present(${type}DO domain) {
// 构造条件 // 构造条件
LambdaQueryWrapper<${type}DO> wrapper = ${typeLower}DAO.wrapper() LambdaQueryWrapper<${type}DO> wrapper = ${typeLower}DAO.wrapper()
// 更新时忽略当前记录 // 更新时忽略当前记录
.ne(${type}DO::getId, domain.getId()) .ne(${type}DO::getId, domain.getId())
// 用其他字段做重复校验 // 用其他字段做重复校验
#foreach($field in ${table.fields}) #foreach($field in ${table.fields})
#if("$!field.propertyName" != "id") #if("$!field.propertyName" != "id")
.eq(${type}DO::get${field.capitalName}, domain.get${field.capitalName}())#if(!$foreach.hasNext);#end .eq(${type}DO::get${field.capitalName}, domain.get${field.capitalName}())#if(!$foreach.hasNext);#end
#end #end
#end #end
// 检查是否存在 // 检查是否存在
boolean present = ${typeLower}DAO.of(wrapper).present(); boolean present = ${typeLower}DAO.of(wrapper).present();
Assert.isFalse(present, ErrorMessage.DATA_PRESENT); Assert.isFalse(present, ErrorMessage.DATA_PRESENT);
} }
@Override @Override
public LambdaQueryWrapper<${type}DO> buildQueryWrapper(${type}QueryRequest request) { public LambdaQueryWrapper<${type}DO> buildQueryWrapper(${type}QueryRequest request) {
String searchValue = request.getSearchValue(); String searchValue = request.getSearchValue();
return ${typeLower}DAO.wrapper() return ${typeLower}DAO.wrapper()
#foreach($field in ${table.fields}) #foreach($field in ${table.fields})
.eq(${type}DO::get${field.capitalName}, request.get${field.capitalName}()) .eq(${type}DO::get${field.capitalName}, request.get${field.capitalName}())
#end
.and(Strings.isNotEmpty(searchValue), c -> c
#foreach($field in ${table.fields})
.eq(${type}DO::get${field.capitalName}, searchValue)#if($foreach.hasNext).or()#end
#end #end
); .and(Strings.isNotEmpty(searchValue), c -> c
} #foreach($field in ${table.fields})
.eq(${type}DO::get${field.capitalName}, searchValue)#if($foreach.hasNext).or()#end
#end
);
}
} }

View File

@@ -23,17 +23,17 @@
package ${currentPackage}; package ${currentPackage};
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.ErrorMessage; import org.dromara.visor.common.constant.ErrorMessage;
import org.dromara.visor.common.utils.Assert; import org.dromara.visor.common.utils.Assert;
#foreach($pkg in ${customModuleFilePackages}) #foreach($pkg in ${customModuleFilePackages})
import ${pkg}.*; import ${pkg}.*;
#end #end
#foreach($pkg in ${customProviderFilePackages}) #foreach($pkg in ${customProviderFilePackages})
import ${pkg}.*; import ${pkg}.*;
#end #end
import ${package.Entity}.${entity}; import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName}; import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName}; import ${package.Service}.${table.serviceName};
@@ -66,7 +66,7 @@ public class ${type}ApiImpl implements ${type}Api {
log.info("${type}Api.create${type} dto: {}", JSON.toJSONString(dto)); log.info("${type}Api.create${type} dto: {}", JSON.toJSONString(dto));
Assert.valid(dto); Assert.valid(dto);
// 转换 // 转换
${type}CreateRequest request = ${type}ProviderConvert.MAPPER.toRequest(dto); ${type}CreateRequest request = ${type}ProviderConvert.MAPPER.toRequest(dto);
// 创建 // 创建
return ${typeLower}Service.create${type}(request); return ${typeLower}Service.create${type}(request);
} }
@@ -76,7 +76,7 @@ public class ${type}ApiImpl implements ${type}Api {
log.info("${type}Api.update${type}ById dto: {}", JSON.toJSONString(dto)); log.info("${type}Api.update${type}ById dto: {}", JSON.toJSONString(dto));
Assert.valid(dto); Assert.valid(dto);
// 转换 // 转换
${type}UpdateRequest request = ${type}ProviderConvert.MAPPER.toRequest(dto); ${type}UpdateRequest request = ${type}ProviderConvert.MAPPER.toRequest(dto);
// 修改 // 修改
return ${typeLower}Service.update${type}ById(request); return ${typeLower}Service.update${type}ById(request);
} }
@@ -88,7 +88,7 @@ public class ${type}ApiImpl implements ${type}Api {
Assert.valid(update); Assert.valid(update);
// 更新 // 更新
int effect = ${typeLower}Service.update${type}(${type}ProviderConvert.MAPPER.toRequest(query), int effect = ${typeLower}Service.update${type}(${type}ProviderConvert.MAPPER.toRequest(query),
${type}ProviderConvert.MAPPER.toRequest(update)); ${type}ProviderConvert.MAPPER.toRequest(update));
log.info("${type}Api.update${type} effect: {}", effect); log.info("${type}Api.update${type} effect: {}", effect);
return effect; return effect;
} }
@@ -98,7 +98,7 @@ public class ${type}ApiImpl implements ${type}Api {
log.info("${type}Api.get${type}ById id: {}", id); log.info("${type}Api.get${type}ById id: {}", id);
Assert.notNull(id, ErrorMessage.ID_MISSING); Assert.notNull(id, ErrorMessage.ID_MISSING);
// 修改 // 修改
${type}DO record = ${typeLower}DAO.selectById(id); ${type}DO record = ${typeLower}DAO.selectById(id);
if (record == null) { if (record == null) {
return null; return null;
} }
@@ -129,14 +129,14 @@ public class ${type}ApiImpl implements ${type}Api {
} }
#if($meta.enableCache) #if($meta.enableCache)
@Override @Override
public List<${type}DTO> get${type}ListByCache() { public List<${type}DTO> get${type}ListByCache() {
return ${typeLower}Service.get${type}ListByCache() return ${typeLower}Service.get${type}ListByCache()
.stream() .stream()
.map(${type}ProviderConvert.MAPPER::to) .map(${type}ProviderConvert.MAPPER::to)
.sorted(Comparator.comparing(${type}DTO::getId)) .sorted(Comparator.comparing(${type}DTO::getId))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
#end #end
@Override @Override
@@ -186,7 +186,7 @@ public class ${type}ApiImpl implements ${type}Api {
* @return wrapper * @return wrapper
*/ */
private LambdaQueryWrapper<${type}DO> buildQueryWrapper(${type}QueryDTO dto) { private LambdaQueryWrapper<${type}DO> buildQueryWrapper(${type}QueryDTO dto) {
return ${typeLower}DAO.wrapper() return ${typeLower}DAO.wrapper()
#foreach($field in ${table.fields}) #foreach($field in ${table.fields})
.eq(${type}DO::get${field.capitalName}, dto.get${field.capitalName}())#if(!$foreach.hasNext);#end .eq(${type}DO::get${field.capitalName}, dto.get${field.capitalName}())#if(!$foreach.hasNext);#end
#end #end

View File

@@ -169,7 +169,6 @@
Message.success('删除成功'); Message.success('删除成功');
// 重新加载 // 重新加载
reload(); reload();
} catch (e) {
} finally { } finally {
setLoading(false); setLoading(false);
} }
@@ -200,7 +199,6 @@
pagination.total = data.total; pagination.total = data.total;
pagination.current = request.page; pagination.current = request.page;
pagination.pageSize = request.limit; pagination.pageSize = request.limit;
} catch (e) {
} finally { } finally {
setLoading(false); setLoading(false);
} }

View File

@@ -91,6 +91,7 @@
<a-table row-key="id" <a-table row-key="id"
#end #end
ref="tableRef" ref="tableRef"
class="table-resize"
:loading="loading" :loading="loading"
:columns="tableColumns" :columns="tableColumns"
#if($vue.enableRowSelection) #if($vue.enableRowSelection)
@@ -99,6 +100,7 @@
:data="tableRenderData" :data="tableRenderData"
:pagination="pagination" :pagination="pagination"
:bordered="false" :bordered="false"
:column-resizable="true"
@page-change="(page: number) => fetchTableData(page, pagination.pageSize)" @page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
@page-size-change="(size: number) => fetchTableData(1, size)"> @page-size-change="(size: number) => fetchTableData(1, size)">
#foreach($field in ${table.fields}) #foreach($field in ${table.fields})
@@ -200,7 +202,6 @@
selectedKeys.value = []; selectedKeys.value = [];
// 重新加载 // 重新加载
reload(); reload();
} catch (e) {
} finally { } finally {
setLoading(false); setLoading(false);
} }
@@ -218,7 +219,6 @@
Message.success('删除成功'); Message.success('删除成功');
// 重新加载 // 重新加载
reload(); reload();
} catch (e) {
} finally { } finally {
setLoading(false); setLoading(false);
} }
@@ -244,7 +244,6 @@
#if($vue.enableRowSelection) #if($vue.enableRowSelection)
selectedKeys.value = []; selectedKeys.value = [];
#end #end
} catch (e) {
} finally { } finally {
setLoading(false); setLoading(false);
} }

View File

@@ -24,7 +24,7 @@ package org.dromara.visor.framework.redis.core.utils;
import cn.orionsec.kit.lang.define.cache.key.CacheKeyDefine; import cn.orionsec.kit.lang.define.cache.key.CacheKeyDefine;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import java.util.List; import java.util.List;

View File

@@ -27,7 +27,7 @@ import cn.orionsec.kit.lang.function.Functions;
import cn.orionsec.kit.lang.utils.Objects1; import cn.orionsec.kit.lang.utils.Objects1;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import cn.orionsec.kit.lang.utils.collect.Maps; import cn.orionsec.kit.lang.utils.collect.Maps;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.HashOperations;
import java.util.List; import java.util.List;
@@ -312,6 +312,19 @@ public class RedisMaps extends RedisUtils {
return getJson(key.getKey(), hashKey, (Class<V>) key.getType()); return getJson(key.getKey(), hashKey, (Class<V>) key.getType());
} }
/**
* 获取值 json
*
* @param define define
* @param key key
* @param hashKey hashKey
* @param <V> V
* @return value
*/
public static <V> V getJson(String key, CacheKeyDefine define, Object hashKey) {
return getJson(key, hashKey, (Class<V>) define.getType());
}
/** /**
* 获取值 json * 获取值 json
* *
@@ -355,9 +368,9 @@ public class RedisMaps extends RedisUtils {
/** /**
* 获取值 json * 获取值 json
* *
* @param key key * @param key key
* @param hashKeys hashKeys * @param hashKeys hashKeys
* @param <V> V * @param <V> V
* @return values * @return values
*/ */
public static <V> List<V> multiGetJson(CacheKeyDefine key, List<?> hashKeys) { public static <V> List<V> multiGetJson(CacheKeyDefine key, List<?> hashKeys) {
@@ -367,10 +380,10 @@ public class RedisMaps extends RedisUtils {
/** /**
* 获取值 json * 获取值 json
* *
* @param key key * @param key key
* @param hashKeys hashKeys * @param hashKeys hashKeys
* @param clazz clazz * @param clazz clazz
* @param <V> V * @param <V> V
* @return values * @return values
*/ */
public static <V> List<V> multiGetJson(String key, List<?> hashKeys, Class<V> clazz) { public static <V> List<V> multiGetJson(String key, List<?> hashKeys, Class<V> clazz) {

View File

@@ -24,9 +24,9 @@ package org.dromara.visor.framework.redis.core.utils;
import cn.orionsec.kit.lang.define.cache.key.CacheKeyDefine; import cn.orionsec.kit.lang.define.cache.key.CacheKeyDefine;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson2.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;

View File

@@ -24,6 +24,7 @@ package org.dromara.visor.framework.test.core.base;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
import org.dromara.visor.common.configuration.CommonConfiguration;
import org.dromara.visor.common.configuration.SpringConfiguration; import org.dromara.visor.common.configuration.SpringConfiguration;
import org.dromara.visor.framework.datasource.configuration.OrionDataSourceAutoConfiguration; import org.dromara.visor.framework.datasource.configuration.OrionDataSourceAutoConfiguration;
import org.dromara.visor.framework.mybatis.configuration.OrionMybatisAutoConfiguration; import org.dromara.visor.framework.mybatis.configuration.OrionMybatisAutoConfiguration;
@@ -60,6 +61,7 @@ public class BaseUnitTest {
@Import({ @Import({
// spring // spring
SpringConfiguration.class, SpringConfiguration.class,
CommonConfiguration.class,
// mock // mock
OrionMockBeanTestConfiguration.class, OrionMockBeanTestConfiguration.class,
OrionMockRedisTestConfiguration.class, OrionMockRedisTestConfiguration.class,

View File

@@ -29,6 +29,7 @@ import org.dromara.visor.common.constant.AutoConfigureOrderConst;
import org.dromara.visor.common.constant.FilterOrderConst; import org.dromara.visor.common.constant.FilterOrderConst;
import org.dromara.visor.common.web.WebFilterCreator; import org.dromara.visor.common.web.WebFilterCreator;
import org.dromara.visor.framework.web.configuration.config.ExposeApiConfig; import org.dromara.visor.framework.web.configuration.config.ExposeApiConfig;
import org.dromara.visor.framework.web.configuration.config.OrionApiConfig;
import org.dromara.visor.framework.web.core.aspect.DemoDisableApiAspect; import org.dromara.visor.framework.web.core.aspect.DemoDisableApiAspect;
import org.dromara.visor.framework.web.core.aspect.ExposeApiAspect; import org.dromara.visor.framework.web.core.aspect.ExposeApiAspect;
import org.dromara.visor.framework.web.core.filter.TraceIdFilter; import org.dromara.visor.framework.web.core.filter.TraceIdFilter;
@@ -42,6 +43,7 @@ import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
@@ -67,9 +69,10 @@ import java.util.List;
* @version 1.0.0 * @version 1.0.0
* @since 2023/6/16 16:26 * @since 2023/6/16 16:26
*/ */
@DependsOn({"executorContext"})
@AutoConfiguration @AutoConfiguration
@AutoConfigureOrder(AutoConfigureOrderConst.FRAMEWORK_WEB) @AutoConfigureOrder(AutoConfigureOrderConst.FRAMEWORK_WEB)
@EnableConfigurationProperties(ExposeApiConfig.class) @EnableConfigurationProperties({ExposeApiConfig.class, OrionApiConfig.class})
public class OrionWebAutoConfiguration implements WebMvcConfigurer { public class OrionWebAutoConfiguration implements WebMvcConfigurer {
@Value("${orion.prefix}") @Value("${orion.prefix}")

View File

@@ -36,6 +36,11 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("orion.api.expose") @ConfigurationProperties("orion.api.expose")
public class ExposeApiConfig { public class ExposeApiConfig {
/**
* 对外服务地址
*/
private String host;
/** /**
* 对外服务请求头 * 对外服务请求头
*/ */

View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 2023 - present Dromara, All rights reserved.
*
* https://visor.dromara.org
* https://visor.dromara.org.cn
* https://visor.orionsec.cn
*
* Members:
* Jiahang Li - ljh1553488six@139.com - author
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.visor.framework.web.configuration.config;
import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.net.IPs;
import lombok.Data;
import org.dromara.visor.common.constant.Const;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* api 配置属性
*
* @author Jiahang Li
* @version 1.0.0
* @since 2025/12/8 14:00
*/
@Data
@ConfigurationProperties("orion.api")
public class OrionApiConfig {
private static final String URL_TEMPLATE = "http://{}:{}{}";
/**
* 公共 api 前缀
*/
private String prefix;
/**
* 服务端主机地址
*/
private String host;
/**
* 服务端口
*/
@Value("${server.port}")
private Integer port;
/**
* 服务端 url
*/
private String url;
public String getHost() {
if (Const.IP_0000.equalsIgnoreCase(host)) {
// 本机
return IPs.IP;
} else {
return host;
}
}
public String getUrl() {
if (!Strings.isBlank(url)) {
return url;
}
// 构建
return Strings.format(URL_TEMPLATE, this.getHost(), port, prefix);
}
}

View File

@@ -33,6 +33,21 @@
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"description": "是否开启 cors 过滤器." "description": "是否开启 cors 过滤器."
}, },
{
"name": "orion.api.host",
"type": "java.lang.String",
"description": "服务端主机地址."
},
{
"name": "orion.api.url",
"type": "java.lang.String",
"description": "服务端接口地址."
},
{
"name": "orion.api.ip-headers",
"type": "java.lang.String",
"description": "获取 IP 的请求头."
},
{ {
"name": "orion.api.expose.header", "name": "orion.api.expose.header",
"type": "java.lang.String", "type": "java.lang.String",

View File

@@ -26,7 +26,7 @@ import cn.orionsec.kit.lang.constant.StandardHttpHeader;
import cn.orionsec.kit.lang.utils.Exceptions; import cn.orionsec.kit.lang.utils.Exceptions;
import cn.orionsec.kit.lang.utils.Threads; import cn.orionsec.kit.lang.utils.Threads;
import cn.orionsec.kit.lang.utils.io.Streams; import cn.orionsec.kit.lang.utils.io.Streams;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import org.dromara.visor.framework.websocket.core.constant.CloseCode; import org.dromara.visor.framework.websocket.core.constant.CloseCode;

View File

@@ -24,6 +24,7 @@
<module>orion-visor-spring-boot-starter-cipher</module> <module>orion-visor-spring-boot-starter-cipher</module>
<module>orion-visor-spring-boot-starter-config</module> <module>orion-visor-spring-boot-starter-config</module>
<module>orion-visor-spring-boot-starter-job</module> <module>orion-visor-spring-boot-starter-job</module>
<module>orion-visor-spring-boot-starter-executor</module>
<module>orion-visor-spring-boot-starter-websocket</module> <module>orion-visor-spring-boot-starter-websocket</module>
<module>orion-visor-spring-boot-starter-redis</module> <module>orion-visor-spring-boot-starter-redis</module>
<module>orion-visor-spring-boot-starter-desensitize</module> <module>orion-visor-spring-boot-starter-desensitize</module>
@@ -37,4 +38,4 @@
<module>orion-visor-spring-boot-starter-biz-operator-log</module> <module>orion-visor-spring-boot-starter-biz-operator-log</module>
</modules> </modules>
</project> </project>

View File

@@ -102,6 +102,10 @@
<groupId>org.dromara.visor</groupId> <groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-job</artifactId> <artifactId>orion-visor-spring-boot-starter-job</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-executor</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.dromara.visor</groupId> <groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-websocket</artifactId> <artifactId>orion-visor-spring-boot-starter-websocket</artifactId>
@@ -199,4 +203,4 @@
</plugins> </plugins>
</build> </build>
</project> </project>

View File

@@ -1,7 +1,7 @@
spring: spring:
datasource: datasource:
druid: druid:
url: jdbc:mysql://${MYSQL_HOST:127.0.0.1}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:orion_visor}?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true url: jdbc:mysql://${MYSQL_HOST:127.0.0.1}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:orion_visor}?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&useServerPrepStmts=false
username: ${MYSQL_USER:root} username: ${MYSQL_USER:root}
password: ${MYSQL_PASSWORD:Data@123456} password: ${MYSQL_PASSWORD:Data@123456}
initial-size: 0 initial-size: 0
@@ -14,7 +14,7 @@ spring:
port: ${REDIS_PORT:6379} port: ${REDIS_PORT:6379}
password: ${REDIS_PASSWORD:Data@123456} password: ${REDIS_PASSWORD:Data@123456}
database: ${REDIS_DATABASE:1} database: ${REDIS_DATABASE:1}
data-version: ${REDIS_DATA_VERSION:1} data-version: ${REDIS_DATA_VERSION:2}
mock: false mock: false
redisson: redisson:
threads: 2 threads: 2
@@ -49,3 +49,84 @@ mybatis-plus:
configuration: configuration:
# 日志打印 # 日志打印
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
app:
executors:
# 默认异步线程池
asyncExecutor:
mdc: true
core-pool-size: 2
max-pool-size: 4
queue-capacity: 30
allow-core-timeout: false
thread-name-prefix: async-executor-
# 指标存储异步线程池
metricsExecutor:
mdc: true
core-pool-size: 2
max-pool-size: 2
queue-capacity: 1000
allow-core-timeout: true
thread-name-prefix: metrics-task-
# 推送异步线程池
pushExecutor:
mdc: true
core-pool-size: 1
max-pool-size: 1
queue-capacity: 1000
allow-core-timeout: true
thread-name-prefix: message-push-
# 探针安装线程池
agentInstallExecutor:
core-pool-size: 2
max-pool-size: 2
queue-capacity: 200
allow-core-timeout: true
thread-name-prefix: agent-install-
# 终端标准输出线程池
terminalStdoutExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: terminal-stdout-
# 终端操作线程池
terminalOperatorExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: terminal-operator-
# 终端异步保存线程池
terminalAsyncSaverExecutor:
core-pool-size: 1
max-pool-size: 1
queue-capacity: 1000
allow-core-timeout: true
thread-name-prefix: terminal-watcher-
# 批量执行超时检查线程池
execTimeoutCheckExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: timeout-check-
# 批量执行任务线程池
execTaskExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: exec-task-
# 批量执行主机命令线程池
execHostCommandExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: exec-host-
# 批量执行日志查看线程池
execLogViewExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: exec-log-
# 批量上传任务线程池
uploadTaskExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: upload-task-
# 批量上传主机线程池
uploadHostExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: upload-host-

View File

@@ -1,7 +1,7 @@
spring: spring:
datasource: datasource:
druid: druid:
url: jdbc:mysql://${MYSQL_HOST:127.0.0.1}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:orion_visor}?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true url: jdbc:mysql://${MYSQL_HOST:127.0.0.1}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:orion_visor}?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&useServerPrepStmts=false
username: ${MYSQL_USER:root} username: ${MYSQL_USER:root}
password: ${MYSQL_PASSWORD:Data@123456} password: ${MYSQL_PASSWORD:Data@123456}
# 初始连接数 # 初始连接数
@@ -25,7 +25,7 @@ spring:
port: ${REDIS_PORT:6379} port: ${REDIS_PORT:6379}
password: ${REDIS_PASSWORD:Data@123456} password: ${REDIS_PASSWORD:Data@123456}
database: ${REDIS_DATABASE:0} database: ${REDIS_DATABASE:0}
data-version: ${REDIS_DATA_VERSION:1} data-version: ${REDIS_DATA_VERSION:2}
redisson: redisson:
threads: 4 threads: 4
netty-threads: 4 netty-threads: 4
@@ -74,6 +74,13 @@ orion:
api: api:
# 是否允许跨域 # 是否允许跨域
cors: ${API_CORS:true} cors: ${API_CORS:true}
# 服务端主机地址
host: ${API_HOST:0.0.0.0}
# 服务端接口地址 默认自动生成
url: ${API_URL:}
# 获取 IP 的请求头
ip-headers: ${API_IP_HEADERS:X-Forwarded-For,X-Real-IP}
# 对外服务
expose: expose:
# 暴露接口请求头值 # 暴露接口请求头值
token: ${API_EXPOSE_TOKEN:pmqeHOyZaumHm0Wt} token: ${API_EXPOSE_TOKEN:pmqeHOyZaumHm0Wt}
@@ -84,9 +91,81 @@ orion:
aes: aes:
# 加密密钥 # 加密密钥
secret-key: ${SECRET_KEY:uQeacXV8b3isvKLK} secret-key: ${SECRET_KEY:uQeacXV8b3isvKLK}
async:
executor: app:
executors:
# 默认异步线程池
asyncExecutor:
mdc: true
core-pool-size: 8 core-pool-size: 8
max-pool-size: 16 max-pool-size: 16
queue-capacity: 200 queue-capacity: 100
keep-alive-seconds: 300 allow-core-timeout: false
thread-name-prefix: async-executor-
# 指标存储异步线程池
metricsExecutor:
mdc: true
core-pool-size: 4
max-pool-size: 4
queue-capacity: 1000
allow-core-timeout: true
thread-name-prefix: metrics-task-
# 推送异步线程池
pushExecutor:
mdc: true
core-pool-size: 4
max-pool-size: 4
queue-capacity: 1000
allow-core-timeout: true
thread-name-prefix: message-push-
# 探针安装线程池
agentInstallExecutor:
allow-core-timeout: true
thread-name-prefix: agent-install-
# 终端标准输出线程池
terminalStdoutExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: terminal-stdout-
# 终端操作线程池
terminalOperatorExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: terminal-operator-
# 终端异步保存线程池
terminalAsyncSaverExecutor:
core-pool-size: 1
max-pool-size: 1
queue-capacity: 1000
allow-core-timeout: true
thread-name-prefix: terminal-watcher-
# 批量执行超时检查线程池
execTimeoutCheckExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: timeout-check-
# 批量执行任务线程池
execTaskExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: exec-task-
# 批量执行主机命令线程池
execHostCommandExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: exec-host-
# 批量执行日志查看线程池
execLogViewExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: exec-log-
# 批量上传任务线程池
uploadTaskExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: upload-task-
# 批量上传主机线程池
uploadHostExecutor:
synchronous-queue: true
allow-core-timeout: true
thread-name-prefix: upload-host-

View File

@@ -22,6 +22,11 @@ spring:
async: async:
# 异步请求时间 30min # 异步请求时间 30min
request-timeout: 1800000 request-timeout: 1800000
task:
scheduling:
thread-name-prefix: scheduling-task-
pool:
size: 4
datasource: datasource:
druid: druid:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
@@ -170,6 +175,12 @@ orion:
prefix: ${orion.prefix}/api prefix: ${orion.prefix}/api
# 是否允许跨域 # 是否允许跨域
cors: true cors: true
# 服务端主机地址
host: 0.0.0.0
# 服务端接口地址 默认自动生成
url:
# 获取 IP 的请求头
ip-headers: X-Forwarded-For,X-Real-IP
# 对外服务 # 对外服务
expose: expose:
# 暴露接口请求头 # 暴露接口请求头
@@ -255,13 +266,6 @@ orion:
secret-key: I66AndrKWrwXjtBL secret-key: I66AndrKWrwXjtBL
use-generator-key: true use-generator-key: true
generator-key-length: 128 generator-key-length: 128
async:
# 线程池配置
executor:
core-pool-size: 2
max-pool-size: 4
queue-capacity: 30
keep-alive-seconds: 180
operator-log: operator-log:
error-message-length: 255 error-message-length: 255
user-agent-length: 128 user-agent-length: 128

View File

@@ -0,0 +1,67 @@
package org.dromara.visor.launch;
import cn.orionsec.kit.lang.define.StopWatch;
import cn.orionsec.kit.lang.utils.io.FileReaders;
import cn.orionsec.kit.lang.utils.io.FileWriters;
import cn.orionsec.kit.lang.utils.io.Files1;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* 替换 fastjson 版本
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/12/23 10:21
*/
public class ReplaceFastjson {
private static final String PATH = new File("").getAbsolutePath();
public static void main(String[] args) {
StopWatch sw = StopWatch.begin();
// 扫描文件
List<File> files = Files1.listFilesFilter(PATH, file -> file.isFile()
&& (file.getName().endsWith(".java") || file.getName().endsWith(".java.vm"))
&& !file.getAbsolutePath().contains("generated-sources")
&& !file.getAbsolutePath().contains("node_modules"), true, false);
sw.tag(" list");
// 添加头
files.forEach(ReplaceFastjson::replaceFastjson2ToFile);
sw.tag("replace");
sw.stop();
System.out.println();
System.out.println(sw);
}
/**
* 替换 license
*
* @param file file
*/
private static void replaceFastjson2ToFile(File file) {
String path = file.getAbsolutePath().substring(PATH.length());
if (path.contains("ReplaceFastjson")) {
return;
}
try {
String line = FileReaders.readLine(file);
if (line == null) {
return;
}
// 替换文件内容
byte[] bytes = new String(FileReaders.readAllBytesFast(file))
.replaceAll("com.alibaba.fastjson\\.", "com.alibaba.fastjson2.")
.replaceAll("com.alibaba.fastjson2.JSONPath", "com.alibaba.fastjson.JSONPath")
.getBytes(StandardCharsets.UTF_8);
// 写入
FileWriters.writeFast(file, bytes);
System.out.println("OK " + path);
} catch (Exception e) {
System.err.println("Failed " + path);
}
}
}

View File

@@ -39,9 +39,9 @@ import java.util.function.Function;
*/ */
public class ReplaceVersion { public class ReplaceVersion {
private static final String TARGET_VERSION = "2.5.1"; private static final String TARGET_VERSION = "2.5.6";
private static final String REPLACE_VERSION = "2.5.2"; private static final String REPLACE_VERSION = "2.5.7";
private static final String PATH = new File("").getAbsolutePath(); private static final String PATH = new File("").getAbsolutePath();

View File

@@ -48,10 +48,10 @@ public interface HostAgentApi {
/** /**
* 获取缓存名称 * 获取缓存名称
* *
* @param agentKeyList agentKeyList * @param agentKeys agentKeys
* @return nameMap * @return nameMap
*/ */
Map<String, String> getNameCacheByAgentKey(List<String> agentKeyList); Map<String, String> getNameCacheByAgentKey(List<String> agentKeys);
/** /**
* 获取缓存名称 * 获取缓存名称

View File

@@ -22,7 +22,7 @@
*/ */
package org.dromara.visor.module.asset.enums; package org.dromara.visor.module.asset.enums;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import org.dromara.visor.module.asset.entity.dto.host.HostRdpConfigDTO; import org.dromara.visor.module.asset.entity.dto.host.HostRdpConfigDTO;

View File

@@ -88,6 +88,10 @@
<groupId>org.dromara.visor</groupId> <groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-job</artifactId> <artifactId>orion-visor-spring-boot-starter-job</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-executor</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.dromara.visor</groupId> <groupId>org.dromara.visor</groupId>
<artifactId>orion-visor-spring-boot-starter-test</artifactId> <artifactId>orion-visor-spring-boot-starter-test</artifactId>
@@ -102,4 +106,4 @@
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -103,11 +103,11 @@ public class HostAgentApiImpl implements HostAgentApi {
} }
@Override @Override
public Map<String, String> getNameCacheByAgentKey(List<String> agentKeyList) { public Map<String, String> getNameCacheByAgentKey(List<String> agentKeys) {
Map<String, String> result = new HashMap<>(); Map<String, String> result = new HashMap<>();
List<String> queryList = new ArrayList<>(); List<String> queryList = new ArrayList<>();
// 查询缓存 // 查询缓存
for (String agentKey : agentKeyList) { for (String agentKey : agentKeys) {
HostBaseDTO host = AGENT_HOST_CACHE.get(agentKey); HostBaseDTO host = AGENT_HOST_CACHE.get(agentKey);
if (host != null) { if (host != null) {
result.put(agentKey, host.getName()); result.put(agentKey, host.getName());

View File

@@ -45,6 +45,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 主机探针端点 api * 主机探针端点 api
@@ -90,9 +91,8 @@ public class HostAgentController {
@PostMapping("/install") @PostMapping("/install")
@Operation(summary = "安装主机探针") @Operation(summary = "安装主机探针")
@PreAuthorize("@ss.hasPermission('asset:host:install-agent')") @PreAuthorize("@ss.hasPermission('asset:host:install-agent')")
public Boolean installAgent(@Validated @RequestBody HostAgentInstallRequest request) { public Map<String, Long> installAgent(@Validated @RequestBody HostAgentInstallRequest request) {
hostAgentService.installAgent(request); return hostAgentService.installAgent(request);
return true;
} }
@DemoDisableApi @DemoDisableApi

View File

@@ -22,7 +22,7 @@
*/ */
package org.dromara.visor.module.asset.controller; package org.dromara.visor.module.asset.controller;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson2.JSONObject;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@@ -92,14 +92,14 @@ public interface HostDAO extends IMapper<HostDO> {
/** /**
* 更新探针信息 * 更新探针信息
* *
* @param keys agentKeyList * @param agentKeys agentKeys
* @param update update * @param update update
* @return effect * @return effect
*/ */
default int updateByAgentKeys(List<String> keys, HostDO update) { default int updateByAgentKeys(List<String> agentKeys, HostDO update) {
update.setUpdateTime(new Date()); update.setUpdateTime(new Date());
// 更新 // 更新
return this.update(update, Conditions.in(HostDO::getAgentKey, keys)); return this.update(update, Conditions.in(HostDO::getAgentKey, agentKeys));
} }
} }

View File

@@ -22,12 +22,9 @@
*/ */
package org.dromara.visor.module.asset.define; package org.dromara.visor.module.asset.define;
import cn.orionsec.kit.lang.define.thread.ExecutorBuilder; import org.dromara.visor.framework.executor.core.utils.ExecutorUtils;
import cn.orionsec.kit.lang.utils.Systems;
import org.dromara.visor.common.constant.Const;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/** /**
* 执行线程池 * 执行线程池
@@ -41,13 +38,6 @@ public interface AssetThreadPools {
/** /**
* 批量执行主机命令线程池 * 批量执行主机命令线程池
*/ */
ThreadPoolExecutor AGENT_INSTALL = ExecutorBuilder.create() Executor AGENT_INSTALL = ExecutorUtils.getExecutor("agentInstallExecutor");
.namedThreadFactory("agent-install-")
.corePoolSize(Systems.PROCESS_NUM)
.maxPoolSize(Systems.PROCESS_NUM)
.keepAliveTime(Const.MS_S_60)
.workQueue(new LinkedBlockingQueue<>())
.allowCoreThreadTimeout(true)
.build();
} }

View File

@@ -29,6 +29,7 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
/** /**
* 主机探针状态 视图响应对象 * 主机探针状态 视图响应对象
@@ -61,4 +62,7 @@ public class HostAgentStatusVO implements Serializable {
@Schema(description = "探针在线状态") @Schema(description = "探针在线状态")
private Integer agentOnlineStatus; private Integer agentOnlineStatus;
@Schema(description = "探针切换在线状态时间")
private Date agentOnlineChangeTime;
} }

View File

@@ -23,6 +23,7 @@
package org.dromara.visor.module.asset.handler.agent.intstall; package org.dromara.visor.module.asset.handler.agent.intstall;
import cn.orionsec.kit.lang.utils.Exceptions; import cn.orionsec.kit.lang.utils.Exceptions;
import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.net.host.ssh.command.CommandExecutors; import cn.orionsec.kit.net.host.ssh.command.CommandExecutors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.FileConst; import org.dromara.visor.common.constant.FileConst;
@@ -50,7 +51,7 @@ public class LinuxAgentInstaller extends AbstractAgentInstaller {
sftpExecutor.write(agentHomePath + FileConst.CONFIG_YAML, this.replaceContent(params.getConfigFilePath())); sftpExecutor.write(agentHomePath + FileConst.CONFIG_YAML, this.replaceContent(params.getConfigFilePath()));
log.info("写入配置文件成功"); log.info("写入配置文件成功");
// 写入启动脚本 // 写入启动脚本
sftpExecutor.write(agentHomePath + startScriptName, this.replaceContent(params.getStartScriptPath())); sftpExecutor.write(agentHomePath + startScriptName, Strings.replaceCRLF(this.replaceContent(params.getStartScriptPath())));
log.info("写入启动脚本成功"); log.info("写入启动脚本成功");
// 上传探针文件 // 上传探针文件
sftpExecutor.uploadFile(agentHomePath + uploadAgentName, params.getAgentFilePath()); sftpExecutor.uploadFile(agentHomePath + uploadAgentName, params.getAgentFilePath());

View File

@@ -51,6 +51,16 @@ public class HostSpecExtraModel implements GenericsDataModel {
*/ */
private String sn; private String sn;
/**
* 制造商
*/
private String vendor;
/**
* 型号
*/
private String model;
/** /**
* 系统名称 * 系统名称
*/ */

View File

@@ -27,6 +27,7 @@ import org.dromara.visor.module.asset.entity.vo.HostAgentStatusVO;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 主机探针 服务类 * 主机探针 服务类
@@ -49,8 +50,9 @@ public interface HostAgentService {
* 安装探针 * 安装探针
* *
* @param request request * @param request request
* @return agentKey:installId
*/ */
void installAgent(HostAgentInstallRequest request); Map<String, Long> installAgent(HostAgentInstallRequest request);
/** /**
* 上传探针发布包 * 上传探针发布包

View File

@@ -22,7 +22,7 @@
*/ */
package org.dromara.visor.module.asset.service; package org.dromara.visor.module.asset.service;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson2.JSONObject;
import org.dromara.visor.common.handler.data.model.GenericsDataModel; import org.dromara.visor.common.handler.data.model.GenericsDataModel;
import org.dromara.visor.module.asset.entity.request.host.HostExtraUpdateRequest; import org.dromara.visor.module.asset.entity.request.host.HostExtraUpdateRequest;
import org.dromara.visor.module.asset.handler.host.extra.HostExtraItemEnum; import org.dromara.visor.module.asset.handler.host.extra.HostExtraItemEnum;

View File

@@ -106,7 +106,7 @@ public class HostAgentEndpointServiceImpl implements HostAgentEndpointService {
try { try {
// 查询主机信息 // 查询主机信息
Long hostId = hostDAO.selectIdByAgentKey(agentKey); Long hostId = hostDAO.selectIdByAgentKey(agentKey);
Assert.notNull(hostId, ErrorMessage.HOST_ABSENT); Assert.notNull(hostId, ErrorMessage.AGENT_KEY_NOT_FOUND, agentKey);
// 查询主机规格信息 // 查询主机规格信息
HostSpecExtraModel spec = hostExtraService.getHostExtra(Const.SYSTEM_USER_ID, hostId, HostExtraItemEnum.SPEC); HostSpecExtraModel spec = hostExtraService.getHostExtra(Const.SYSTEM_USER_ID, hostId, HostExtraItemEnum.SPEC);
Boolean synced = Optional.ofNullable(spec) Boolean synced = Optional.ofNullable(spec)
@@ -149,7 +149,7 @@ public class HostAgentEndpointServiceImpl implements HostAgentEndpointService {
log.info("HostAgentEndpointService setAgentOffline agentKey: {}", agentKey); log.info("HostAgentEndpointService setAgentOffline agentKey: {}", agentKey);
// 查询主机信息 // 查询主机信息
Long hostId = hostDAO.selectIdByAgentKey(agentKey); Long hostId = hostDAO.selectIdByAgentKey(agentKey);
Assert.notNull(hostId, ErrorMessage.HOST_ABSENT); Assert.notNull(hostId, ErrorMessage.AGENT_KEY_NOT_FOUND, agentKey);
// 修改缓存 // 修改缓存
ONLINE_STATUS_CACHE.put(agentKey, AgentOnlineStatusEnum.OFFLINE.getValue()); ONLINE_STATUS_CACHE.put(agentKey, AgentOnlineStatusEnum.OFFLINE.getValue());
HEARTBEAT_RECV_CACHE.put(agentKey, 0L); HEARTBEAT_RECV_CACHE.put(agentKey, 0L);
@@ -212,25 +212,25 @@ public class HostAgentEndpointServiceImpl implements HostAgentEndpointService {
/** /**
* 标记在线状态 * 标记在线状态
* *
* @param agentKeyList agentKeyList * @param agentKeys agentKeys
* @param status status * @param status status
*/ */
private void markOnlineStatus(List<String> agentKeyList, AgentOnlineStatusEnum status) { private void markOnlineStatus(List<String> agentKeys, AgentOnlineStatusEnum status) {
if (Lists.isEmpty(agentKeyList)) { if (Lists.isEmpty(agentKeys)) {
return; return;
} }
log.info("HostAgentEndpointService mark {}. count: {}, keys: {}", status, agentKeyList.size(), agentKeyList); log.info("HostAgentEndpointService mark {}. count: {}, keys: {}", status, agentKeys.size(), agentKeys);
// 更新数据 // 更新数据
HostDO update = HostDO.builder() HostDO update = HostDO.builder()
.agentOnlineStatus(status.getValue()) .agentOnlineStatus(status.getValue())
.agentOnlineChangeTime(new Date()) .agentOnlineChangeTime(new Date())
.build(); .build();
int effect = hostDAO.updateByAgentKeys(agentKeyList, update); int effect = hostDAO.updateByAgentKeys(agentKeys, update);
// 更新缓存 // 更新缓存
agentKeyList.forEach(s -> ONLINE_STATUS_CACHE.put(s, status.getValue())); agentKeys.forEach(s -> ONLINE_STATUS_CACHE.put(s, status.getValue()));
log.info("HostAgentEndpointService mark {}. effect: {}", status, effect); log.info("HostAgentEndpointService mark {}. effect: {}", status, effect);
// 插入日志 // 插入日志
List<HostAgentLogDO> logList = hostDAO.selectIdByAgentKeys(agentKeyList) List<HostAgentLogDO> logList = hostDAO.selectIdByAgentKeys(agentKeys)
.stream() .stream()
.map(s -> { .map(s -> {
HostAgentLogDO agentLog = HostAgentLogDO.builder() HostAgentLogDO agentLog = HostAgentLogDO.builder()
@@ -250,7 +250,7 @@ public class HostAgentEndpointServiceImpl implements HostAgentEndpointService {
} }
// 发送已下线事件 // 发送已下线事件
if (AgentOnlineStatusEnum.OFFLINE.equals(status)) { if (AgentOnlineStatusEnum.OFFLINE.equals(status)) {
SpringHolder.publishEvent(new AgentOfflineEvent(agentKeyList)); SpringHolder.publishEvent(new AgentOfflineEvent(agentKeys));
} }
} }

View File

@@ -22,6 +22,7 @@
*/ */
package org.dromara.visor.module.asset.service.impl; package org.dromara.visor.module.asset.service.impl;
import cn.orionsec.kit.lang.function.Functions;
import cn.orionsec.kit.lang.utils.Exceptions; import cn.orionsec.kit.lang.utils.Exceptions;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
@@ -31,7 +32,6 @@ import cn.orionsec.kit.lang.utils.io.FileReaders;
import cn.orionsec.kit.lang.utils.io.Files1; import cn.orionsec.kit.lang.utils.io.Files1;
import cn.orionsec.kit.lang.utils.io.compress.CompressTypeEnum; import cn.orionsec.kit.lang.utils.io.compress.CompressTypeEnum;
import cn.orionsec.kit.lang.utils.io.compress.FileDecompressor; import cn.orionsec.kit.lang.utils.io.compress.FileDecompressor;
import cn.orionsec.kit.lang.utils.net.IPs;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import org.dromara.visor.common.constant.ErrorMessage; import org.dromara.visor.common.constant.ErrorMessage;
@@ -41,6 +41,8 @@ import org.dromara.visor.common.utils.Assert;
import org.dromara.visor.common.utils.PathUtils; import org.dromara.visor.common.utils.PathUtils;
import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs; import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs;
import org.dromara.visor.framework.redis.core.utils.RedisStrings; import org.dromara.visor.framework.redis.core.utils.RedisStrings;
import org.dromara.visor.framework.web.configuration.config.ExposeApiConfig;
import org.dromara.visor.framework.web.configuration.config.OrionApiConfig;
import org.dromara.visor.module.asset.convert.HostConvert; import org.dromara.visor.module.asset.convert.HostConvert;
import org.dromara.visor.module.asset.dao.HostAgentLogDAO; import org.dromara.visor.module.asset.dao.HostAgentLogDAO;
import org.dromara.visor.module.asset.dao.HostDAO; import org.dromara.visor.module.asset.dao.HostDAO;
@@ -53,7 +55,6 @@ import org.dromara.visor.module.asset.enums.*;
import org.dromara.visor.module.asset.handler.agent.intstall.AgentInstaller; import org.dromara.visor.module.asset.handler.agent.intstall.AgentInstaller;
import org.dromara.visor.module.asset.handler.agent.model.AgentInstallParams; import org.dromara.visor.module.asset.handler.agent.model.AgentInstallParams;
import org.dromara.visor.module.asset.service.HostAgentService; import org.dromara.visor.module.asset.service.HostAgentService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -77,8 +78,11 @@ public class HostAgentServiceImpl implements HostAgentService {
private String localVersion; private String localVersion;
@Value("${orion.api.expose.token}") @Resource
private String exposeToken; private OrionApiConfig orionApiConfig;
@Resource
private ExposeApiConfig exposeApiConfig;
@Resource @Resource
private HostDAO hostDAO; private HostDAO hostDAO;
@@ -119,7 +123,8 @@ public class HostAgentServiceImpl implements HostAgentService {
.select(HostDO::getId, .select(HostDO::getId,
HostDO::getAgentVersion, HostDO::getAgentVersion,
HostDO::getAgentInstallStatus, HostDO::getAgentInstallStatus,
HostDO::getAgentOnlineStatus) HostDO::getAgentOnlineStatus,
HostDO::getAgentOnlineChangeTime)
.in(HostDO::getId, idList) .in(HostDO::getId, idList)
.then() .then()
.stream() .stream()
@@ -129,7 +134,7 @@ public class HostAgentServiceImpl implements HostAgentService {
} }
@Override @Override
public void installAgent(HostAgentInstallRequest request) { public Map<String, Long> installAgent(HostAgentInstallRequest request) {
// 查询主机信息 // 查询主机信息
List<Long> idList = request.getIdList(); List<Long> idList = request.getIdList();
List<HostDO> hosts = hostDAO.selectBatchIds(idList); List<HostDO> hosts = hostDAO.selectBatchIds(idList);
@@ -177,6 +182,12 @@ public class HostAgentServiceImpl implements HostAgentService {
// 执行任务 // 执行任务
AgentInstaller.start(params); AgentInstaller.start(params);
} }
// 返回
return agentLogs.stream()
.collect(Collectors.toMap(HostAgentLogDO::getAgentKey,
HostAgentLogDO::getId,
Functions.right()));
} }
@Override @Override
@@ -301,8 +312,8 @@ public class HostAgentServiceImpl implements HostAgentService {
*/ */
private Map<String, String> getReplaceVars() { private Map<String, String> getReplaceVars() {
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("SERVER_HOST", IPs.IP); map.put("SERVER_URL", orionApiConfig.getUrl());
map.put("SERVER_TOKEN", exposeToken); map.put("SERVER_TOKEN", exposeApiConfig.getToken());
return map; return map;
} }

View File

@@ -24,7 +24,7 @@ package org.dromara.visor.module.asset.service.impl;
import cn.orionsec.kit.lang.function.Functions; import cn.orionsec.kit.lang.function.Functions;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.ErrorMessage; import org.dromara.visor.common.constant.ErrorMessage;
import org.dromara.visor.common.constant.ExtraFieldConst; import org.dromara.visor.common.constant.ExtraFieldConst;

View File

@@ -22,10 +22,13 @@
*/ */
package org.dromara.visor.module.asset.service.impl; package org.dromara.visor.module.asset.service.impl;
import cn.orionsec.kit.lang.utils.Exceptions;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import com.alibaba.fastjson.JSON; import cn.orionsec.kit.lang.utils.collect.Maps;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
import org.dromara.visor.common.constant.ErrorMessage; import org.dromara.visor.common.constant.ErrorMessage;
import org.dromara.visor.common.handler.data.model.GenericsDataModel; import org.dromara.visor.common.handler.data.model.GenericsDataModel;
@@ -44,6 +47,7 @@ import org.dromara.visor.module.infra.enums.DataExtraTypeEnum;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -55,6 +59,7 @@ import java.util.stream.Collectors;
* @version 1.0.0 * @version 1.0.0
* @since 2023/12/20 12:11 * @since 2023/12/20 12:11
*/ */
@Slf4j
@Service @Service
public class HostExtraServiceImpl implements HostExtraService { public class HostExtraServiceImpl implements HostExtraService {
@@ -156,40 +161,57 @@ public class HostExtraServiceImpl implements HostExtraService {
@Override @Override
public void syncHostSpec(String key, String taskId, JSONObject spec) { public void syncHostSpec(String key, String taskId, JSONObject spec) {
try { // 查询主机id
// 查询主机id Long id = hostDAO.selectIdByAgentKey(key);
Long id = hostDAO.selectIdByAgentKey(key); Assert.notNull(id, ErrorMessage.HOST_ABSENT);
Assert.notNull(id, ErrorMessage.HOST_ABSENT); // 设置已同步标识
// 设置已同步标识 spec.put(Const.SYNCED, true);
spec.put(Const.SYNCED, true); // 查询配置信息
// 查询配置信息 String newSpec;
String newSpec; HostSpecExtraModel beforeSpec = this.getHostSpecMap(Lists.singleton(id)).get(id);
HostSpecExtraModel beforeSpec = this.getHostSpecMap(Lists.singleton(id)).get(id); if (beforeSpec == null) {
if (beforeSpec == null) { // 新增
// 新增 newSpec = spec.toString();
newSpec = spec.toString(); } else {
} else { // 合并
// 合并 JSONObject beforeSpecValue = JSON.parseObject(beforeSpec.serial());
JSONObject beforeSpecValue = JSON.parseObject(beforeSpec.serial()); spec.forEach((k, v) -> {
spec.forEach((k, v) -> { // 获取原数据
if (v != null) { Object beforeValue = beforeSpecValue.get(k);
beforeSpecValue.put(k, v); // 检查是否存在
boolean present = false;
if (beforeValue != null) {
if (beforeValue instanceof String) {
present = !Strings.isBlank((String) beforeValue);
} else if (beforeValue instanceof Collection) {
present = !Lists.isEmpty((Collection<?>) beforeValue);
} else if (beforeValue instanceof Map) {
present = !Maps.isEmpty((Map<?, ?>) beforeValue);
} else {
present = true;
} }
}); }
newSpec = beforeSpecValue.toJSONString(); // 不存在则覆盖
} if (!present && v != null) {
// 修改规格 beforeSpecValue.put(k, v);
DataExtraSetDTO update = new DataExtraSetDTO(); }
update.setUserId(Const.SYSTEM_USER_ID); });
update.setRelId(id); newSpec = beforeSpecValue.toJSONString();
update.setItem(HostExtraItemEnum.SPEC.name());
update.setValue(newSpec);
dataExtraApi.setExtraItem(update, DataExtraTypeEnum.HOST);
// 回调成功
} catch (Exception e) {
// 回调失败
throw e;
} }
// 检查是否能反解析 防止格式错误导致其他地方报错
try {
JSON.parseObject(newSpec, HostSpecExtraModel.class);
} catch (Exception e) {
log.error("HostExtraService-setHostSpec error: {}, spec: {}", e.getMessage(), newSpec, e);
throw Exceptions.app(ErrorMessage.SPEC_FORMAT_INCORRECT, e);
}
// 修改规格
DataExtraSetDTO update = new DataExtraSetDTO();
update.setUserId(Const.SYSTEM_USER_ID);
update.setRelId(id);
update.setItem(HostExtraItemEnum.SPEC.name());
update.setValue(newSpec);
dataExtraApi.setExtraItem(update, DataExtraTypeEnum.HOST);
} }
/** /**

View File

@@ -25,7 +25,7 @@ package org.dromara.visor.module.asset.service.impl;
import cn.orionsec.kit.lang.define.wrapper.DataGrid; import cn.orionsec.kit.lang.define.wrapper.DataGrid;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -110,7 +110,7 @@ public class HostIdentityServiceImpl implements HostIdentityService {
int effect = hostIdentityDAO.insert(record); int effect = hostIdentityDAO.insert(record);
log.info("HostIdentityService-createHostIdentity effect: {}", effect); log.info("HostIdentityService-createHostIdentity effect: {}", effect);
// 删除缓存 // 删除缓存
RedisMaps.delete(HostCacheKeyDefine.HOST_IDENTITY); RedisUtils.delete(HostCacheKeyDefine.HOST_IDENTITY);
return record.getId(); return record.getId();
} }
@@ -143,7 +143,7 @@ public class HostIdentityServiceImpl implements HostIdentityService {
int effect = hostIdentityDAO.update(updateRecord, wrapper); int effect = hostIdentityDAO.update(updateRecord, wrapper);
log.info("HostIdentityService-updateHostIdentityById effect: {}", effect); log.info("HostIdentityService-updateHostIdentityById effect: {}", effect);
// 删除缓存 // 删除缓存
RedisMaps.delete(HostCacheKeyDefine.HOST_IDENTITY); RedisUtils.delete(HostCacheKeyDefine.HOST_IDENTITY);
return effect; return effect;
} }
@@ -258,7 +258,7 @@ public class HostIdentityServiceImpl implements HostIdentityService {
.eq(HostIdentityDO::getName, domain.getName()); .eq(HostIdentityDO::getName, domain.getName());
// 检查是否存在 // 检查是否存在
boolean present = hostIdentityDAO.of(wrapper).present(); boolean present = hostIdentityDAO.of(wrapper).present();
Assert.isFalse(present, ErrorMessage.DATA_PRESENT); Assert.isFalse(present, ErrorMessage.NAME_PRESENT);
} }
/** /**

View File

@@ -25,7 +25,7 @@ package org.dromara.visor.module.asset.service.impl;
import cn.orionsec.kit.lang.define.wrapper.DataGrid; import cn.orionsec.kit.lang.define.wrapper.DataGrid;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.Const;
@@ -104,7 +104,7 @@ public class HostKeyServiceImpl implements HostKeyService {
log.info("HostKeyService-createHostKey effect: {}", effect); log.info("HostKeyService-createHostKey effect: {}", effect);
Long id = record.getId(); Long id = record.getId();
// 删除缓存 // 删除缓存
RedisMaps.delete(HostCacheKeyDefine.HOST_KEY); RedisUtils.delete(HostCacheKeyDefine.HOST_KEY);
return id; return id;
} }
@@ -128,7 +128,7 @@ public class HostKeyServiceImpl implements HostKeyService {
int effect = hostKeyDAO.updateById(updateRecord); int effect = hostKeyDAO.updateById(updateRecord);
// 删除缓存 // 删除缓存
if (!record.getName().equals(updateRecord.getName())) { if (!record.getName().equals(updateRecord.getName())) {
RedisMaps.delete(HostCacheKeyDefine.HOST_KEY); RedisUtils.delete(HostCacheKeyDefine.HOST_KEY);
} }
log.info("HostKeyService-updateHostKeyById effect: {}", effect); log.info("HostKeyService-updateHostKeyById effect: {}", effect);
return effect; return effect;
@@ -242,7 +242,7 @@ public class HostKeyServiceImpl implements HostKeyService {
.eq(HostKeyDO::getName, domain.getName()); .eq(HostKeyDO::getName, domain.getName());
// 检查是否存在 // 检查是否存在
boolean present = hostKeyDAO.of(wrapper).present(); boolean present = hostKeyDAO.of(wrapper).present();
Assert.isFalse(present, ErrorMessage.DATA_PRESENT); Assert.isFalse(present, ErrorMessage.NAME_PRESENT);
} }
/** /**

View File

@@ -28,7 +28,7 @@ import cn.orionsec.kit.lang.utils.Booleans;
import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Lists;
import cn.orionsec.kit.spring.SpringHolder; import cn.orionsec.kit.spring.SpringHolder;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -39,6 +39,7 @@ import org.dromara.visor.common.utils.Assert;
import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs; import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs;
import org.dromara.visor.framework.mybatis.core.query.DataQuery; import org.dromara.visor.framework.mybatis.core.query.DataQuery;
import org.dromara.visor.framework.redis.core.utils.RedisMaps; import org.dromara.visor.framework.redis.core.utils.RedisMaps;
import org.dromara.visor.framework.redis.core.utils.RedisUtils;
import org.dromara.visor.framework.redis.core.utils.barrier.CacheBarriers; import org.dromara.visor.framework.redis.core.utils.barrier.CacheBarriers;
import org.dromara.visor.module.asset.convert.HostConvert; import org.dromara.visor.module.asset.convert.HostConvert;
import org.dromara.visor.module.asset.dao.HostConfigDAO; import org.dromara.visor.module.asset.dao.HostConfigDAO;
@@ -376,7 +377,7 @@ public class HostServiceImpl implements HostService {
@Override @Override
public void clearCache() { public void clearCache() {
RedisMaps.scanKeysDelete(HostCacheKeyDefine.HOST_INFO.format("*")); RedisUtils.scanKeysDelete(HostCacheKeyDefine.HOST_INFO.format("*"));
} }
/** /**

Some files were not shown because too many files have changed in this diff Show More