mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-02 03:48:05 +08:00
commit
33f5ee3103
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,15 +1,22 @@
|
||||
# 版本日志
|
||||
|
||||
## 2.3.3
|
||||
## 2.4.0
|
||||
|
||||
### 新增功能
|
||||
|
||||
1. 首页进程列表显示属于Jpom项目名称(〓下页)
|
||||
1. 首页进程列表显示属于Jpom项目名称(感谢@〓下页)
|
||||
2. 多节点统一管理(插件模式)
|
||||
3. 证书解析支持cer 证书(感谢@JAVA jesion)
|
||||
4. 新增记录用户操作日志[采用H2数据库](感谢@〓下页)
|
||||
5. 节点分发功能、合并管理项目
|
||||
|
||||
### 解决BUG、优化功能
|
||||
|
||||
1. 解析端口信息兼容`:::8084`(感谢@Agoni 、)
|
||||
2. 进程id解析端口、解析项目名称带缓存
|
||||
3. 项目分组变更,项目列表及时刷新(感谢@〓下页)
|
||||
4. 批量上传文件数量进度显示(感谢@群友)
|
||||
5. linux udp端口信息解析失败(感谢@Ruby)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
|
24
FQA.md
24
FQA.md
@ -8,7 +8,7 @@
|
||||
|
||||
修改管理程序命令文件中 --jpom.log=/jpom/log/
|
||||
|
||||
### 如何修改回话超时时长
|
||||
### 如何修改会话超时时长
|
||||
|
||||
在管理程序命令文件中 ARGS 变量添加 --tomcat.sessionTimeOut=1800
|
||||
|
||||
@ -71,4 +71,24 @@
|
||||
|
||||
![jpom](/doc/error/can't-open-socket-file.jpg)
|
||||
|
||||
针对以上两个问题,Jpom目前采用略过这些进程的解决办法,请更新到2.3.1以上。
|
||||
针对以上两个问题,Jpom目前采用略过这些进程的解决办法,请更新到2.3.1以上。
|
||||
|
||||
|
||||
### SpringBoot 读取jar包同路径配置文件失败
|
||||
|
||||
由于目前Jpom 启动下面的方式限制SpringBoot未能读取到对应配置文件,目前解决方案是在配置项目的args参数解决
|
||||
|
||||
> --spring.config.location=D:\config\config.properties
|
||||
|
||||
|
||||
### windows 环境 com.sun.tools.attach.AttachNotSupportedException: no providers installed 之类异常
|
||||
|
||||
> 问题原因${JAVA_HOME}/jre/bin/attach.dll 文件没有找到,检查当前Jdk环境是否安装完整
|
||||
|
||||
### 常见问题未知问题
|
||||
|
||||
https://github.com/alibaba/arthas/issues/347
|
||||
|
||||
### windows 环境项目在运行中不能删除文件
|
||||
|
||||
> 由于系统原因,暂时还没有找到解决办法
|
12
PLANS.md
12
PLANS.md
@ -1,6 +1,10 @@
|
||||
### 开发计划
|
||||
|
||||
1. 主要管理页面兼容移动端
|
||||
2. ssl 到期提醒、快捷续签
|
||||
3. 多机统一管理
|
||||
4. 程序宕机处理
|
||||
1. 程序宕机处理
|
||||
2. 主要管理页面兼容移动端
|
||||
3. ssl 到期提醒、快捷续签
|
||||
|
||||
### 待优化解决
|
||||
|
||||
1. 支持更多压缩包
|
||||
2. 项目监控完善
|
69
README.md
69
README.md
@ -31,7 +31,7 @@
|
||||
|
||||
> 当多个项目运行在同一台服务器时,运维人员通常也不只一个,如果每个人都登录服务器管理项目,难免会造成一些不必要的麻烦,甚至给服务器的安全性带来问题(服务器密码知道的人越多,越容易泄露),因为不需要登录服务器管理项目,维护人员不需要知道服务器的登录密码,只需要有Jpom的账号就行,Jpom本身可以通过权限管理,给不同用户不同的权限,这样也使得项目的稳定性得到提升。
|
||||
|
||||
> Jpom可以在Linux和Windows服务器上运行
|
||||
> Jpom可以在Linux和Windows服务器上运行,并且Jpom采用多节点模式,随时开启关闭节点服务器,节点分发减少运维人员上传、修改操作
|
||||
|
||||
### Jpom 目标
|
||||
|
||||
@ -42,47 +42,76 @@
|
||||
1. 创建、修改、删除项目、Jar包管理
|
||||
2. 实时查看控制台日志、备份日志、删除日志、导出日志
|
||||
3. cpu、ram 监控、导出堆栈信息、查看项目进程端口、服务器状态监控
|
||||
4. 多用户管理,用户项目权限独立(上传、删除权限可控制)
|
||||
5. 系统路径白名单模式,杜绝用户误操作系统文件
|
||||
6. 在线管理Nginx配置、ssl证书文件
|
||||
7. Jpom完全不依赖数据库,随装随用
|
||||
4. 多节点管理、多节点自动分发
|
||||
5. 多用户管理,用户项目权限独立(上传、删除权限可控制),完善的操作日志
|
||||
6. 系统路径白名单模式,杜绝用户误操作系统文件
|
||||
7. 在线管理Nginx配置、ssl证书文件
|
||||
8. [阿里云 CodePipeline + Oss在线管理](/doc/CodePipeline-Oss.md)
|
||||
|
||||
#### 基本操作演示
|
||||
|
||||
<img src="http://s.keepbx.cn/jpom-demo-gif.gif" ></img>
|
||||
![jpom-server](http://s.keepbx.cn/jpom-server.gif)
|
||||
|
||||
![jpom-node-agent](http://s.keepbx.cn/jpom-node-agent.gif)
|
||||
|
||||
### 下载安装
|
||||
|
||||
1. 下载安装包 [https://gitee.com/keepbx/Jpom/attach_files](https://gitee.com/keepbx/Jpom/attach_files)
|
||||
2. 上传到服务解压对应路径
|
||||
3. 命令运行(Jpom.sh、Jpom.bat)
|
||||
2. 解压文件
|
||||
3. 安装插件端
|
||||
1. agent-x.x.x-release 目录为插件端的全部安装文件
|
||||
2. 上传到对应服务器
|
||||
3. 命令运行(Agent.sh、Agent.bat)
|
||||
4. 安装服务端
|
||||
1. server-x.x.x-release 目录为服务端的全部安装文件
|
||||
2. 上传到对应服务器
|
||||
3. 命令运行(Server.sh、Server.bat)
|
||||
|
||||
### 编译安装
|
||||
|
||||
1. 访问[Jpom](https://gitee.com/keepbx/Jpom)的码云主页,拉取最新完整代码(建议使用master分支)
|
||||
2. 进入项目目录执行:`mvn clean package`
|
||||
3. 然后在目录中查看 target/jpom-x.x.x-release
|
||||
4. 打包上传服务器运行
|
||||
5. 命令运行(Jpom.sh、Jpom.bat)
|
||||
3. 安装插件端
|
||||
1. 查看插件端安装包 modules/agent/target/agent-x.x.x-release
|
||||
2. 打包上传服务器运行
|
||||
3. 命令运行(Agent.sh、Agent.bat)
|
||||
4. 安装服务端
|
||||
1. 查看插件端安装包 modules/server/target/server-x.x.x-release
|
||||
2. 打包上传服务器运行
|
||||
3. 命令运行(Server.sh、Server.bat)
|
||||
|
||||
### 编译运行
|
||||
|
||||
1. 访问[Jpom](https://gitee.com/keepbx/Jpom)的码云主页,拉取最新完整代码(建议使用master分支)
|
||||
2. 运行`cn.keepbx.jpom.JpomApplication`
|
||||
3. 浏览器访问(如:http://127.0.0.1:2122)
|
||||
2. 运行插件端
|
||||
1. 运行`cn.keepbx.jpom.JpomAgentApplication`
|
||||
2. 注意控制台打印的默认账号密码信息
|
||||
3. 运行服务端
|
||||
1. 运行`cn.keepbx.jpom.JpomServerApplication`
|
||||
2. 浏览器访问(如:http://127.0.0.1:2122)
|
||||
|
||||
### 管理命令
|
||||
1. windows中Jpom.bat
|
||||
1. windows中Agent.bat 、Server.bat
|
||||
```
|
||||
Jpom.bat 启动管理面板(按照面板提示输入操作)
|
||||
# 服务端
|
||||
Server.bat 启动管理面板(按照面板提示输入操作)
|
||||
|
||||
# 插件端
|
||||
Agent.bat 启动管理面板(按照面板提示输入操作)
|
||||
```
|
||||
2. linux中Jpom.sh
|
||||
2. linux中Agent.sh 、Server.sh
|
||||
```
|
||||
Jpom.sh start 启动Jpom
|
||||
Jpom.sh stop 停止Jpom
|
||||
Jpom.sh restart 重启Jpom
|
||||
Jpom.sh status 查看Jpom运行状态
|
||||
# 服务端
|
||||
Server.sh start 启动Jpom服务端
|
||||
Server.sh stop 停止Jpom服务端
|
||||
Server.sh restart 重启Jpom服务端
|
||||
Server.sh status 查看Jpom服务端运行状态
|
||||
|
||||
# 插件端
|
||||
Agent.sh start 启动Jpom插件端
|
||||
Agent.sh stop 停止Jpom插件端
|
||||
Agent.sh restart 重启Jpom插件端
|
||||
Agent.sh status 查看Jpom插件端运行状态
|
||||
```
|
||||
|
||||
### 视频教程
|
||||
|
@ -1,21 +1,28 @@
|
||||
### 用户权限具体差异对比
|
||||
|
||||
| 功能 | 系统管理员 | 普通管理员 | 非管理员 |
|
||||
| -- | -- | -- | -- |
|
||||
| 查看项目 | √ | √ | √ |
|
||||
| 创建项目 | √ | √ | × |
|
||||
| 修改项目 | √ | √ | 授权项目 |
|
||||
| 删除项目 | √ | √ | × |
|
||||
| 修改自身昵称、密码 | √ | √ | √ |
|
||||
| 查看用户列表 | √ | √ | × |
|
||||
| 重置用户密码 | √ | × | × |
|
||||
| 创建用户、修改用户 | √ | √ | × |
|
||||
| 修改系统白名单 | √ | × | × |
|
||||
| 查看、修改阿里云OSS配置 | √ | × | × |
|
||||
| nginx管理 | √ | √ | × |
|
||||
| nginx静态资源配置 | √ | x | × |
|
||||
| 证书管理 | √ | √ | × |
|
||||
| 删除证书 | √ | x | × |
|
||||
| 功能 | 系统管理员 | 节点管理员 | 非管理员 | 服务管理员 |
|
||||
| -- | -- | -- | -- | -- |
|
||||
| 创建、修改、删除节点 | √ | × | × | × |
|
||||
| 创建、修改、删除节点分发 | √ | × | × | √ |
|
||||
| 查看操作日志 | √ | √ | √ | √ |
|
||||
| 分发白名单 | √ | × | × | × |
|
||||
| 分发文件 | √ | × | × | √ |
|
||||
| 查看项目 | √ | √ | √ | × |
|
||||
| 创建项目 | √ | √ | × | × |
|
||||
| 修改项目 | √ | √ | 授权项目 | × |
|
||||
| 删除项目 | √ | √ | × | × |
|
||||
| 上传、删除项目jar | √ | 单独授权 | 单独授权 | × |
|
||||
| 修改自身昵称、密码 | √ | √ | √ | √ |
|
||||
| 查看用户列表 | √ | x | × | √ |
|
||||
| 重置用户密码 | √ | × | × | × |
|
||||
| 创建用户、修改用户 | √ | × | × | √ |
|
||||
| 修改系统白名单 | √ | × | × | × |
|
||||
| 查看、修改阿里云OSS配置 | √ | × | × | × |
|
||||
| nginx管理 | √ | √ | × | × |
|
||||
| nginx静态资源配置 | √ | x | × | × |
|
||||
| 证书管理 | √ | √ | × | × |
|
||||
| 删除证书 | √ | × | × | × |
|
||||
|
||||
|
||||
### 防暴力登录账号机制
|
||||
|
||||
|
101
modules/agent/pom.xml
Normal file
101
modules/agent/pom.xml
Normal file
@ -0,0 +1,101 @@
|
||||
<?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>
|
||||
<artifactId>jpom</artifactId>
|
||||
<groupId>cn.keepbx</groupId>
|
||||
<version>2.4.0</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>cn.keepbx.jpom</groupId>
|
||||
<artifactId>agent</artifactId>
|
||||
<version>2.4.0</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.keepbx.jpom</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${pom.version}</version>
|
||||
</dependency>
|
||||
<!-- 文件编码识别-->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.jchardet</groupId>
|
||||
<artifactId>jchardet</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>2.8.3</version>
|
||||
</dependency>
|
||||
<!--nginx-->
|
||||
<dependency>
|
||||
<groupId>com.github.odiszapc</groupId>
|
||||
<artifactId>nginxparser</artifactId>
|
||||
<version>0.9.6</version>
|
||||
</dependency>
|
||||
<!-- 证书解密-->
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>1.61</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.18</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>cn.keepbx.jpom.JpomAgentApplication</mainClass>
|
||||
<!-- 是否指定项目classpath下的依赖 -->
|
||||
<addClasspath>true</addClasspath>
|
||||
<!-- 指定依赖的时候声明前缀 -->
|
||||
<classpathPrefix>./</classpathPrefix>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<!-- 项目版本号 -->
|
||||
<Jpom-Project-Version>${project.version}</Jpom-Project-Version>
|
||||
<!-- 打包时间 -->
|
||||
<Jpom-Timestamp>${maven.build.timestamp}</Jpom-Timestamp>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
<descriptors>
|
||||
<descriptor>script/release.xml</descriptor>
|
||||
</descriptors>
|
||||
<outputDirectory>target</outputDirectory>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
119
modules/agent/script/Agent.bat
Normal file
119
modules/agent/script/Agent.bat
Normal file
@ -0,0 +1,119 @@
|
||||
@REM The MIT License (MIT)
|
||||
@REM
|
||||
@REM Copyright (c) 2019 码之科技工作室
|
||||
@REM
|
||||
@REM Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
@REM this software and associated documentation files (the "Software"), to deal in
|
||||
@REM the Software without restriction, including without limitation the rights to
|
||||
@REM use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
@REM the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
@REM subject to the following conditions:
|
||||
@REM
|
||||
@REM The above copyright notice and this permission notice shall be included in all
|
||||
@REM copies or substantial portions of the Software.
|
||||
@REM
|
||||
@REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
@REM IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
@REM FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
@REM COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
@REM IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
@REM CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@REM
|
||||
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
set Tag=KeepBx-Agent-System-JpomAgentApplication
|
||||
set MainClass=cn.keepbx.jpom.JpomAgentApplication
|
||||
set CloseMainClass=cn.keepbx.jpom.JpomClose
|
||||
set basePath=%~dp0
|
||||
set Lib=%basePath%lib\
|
||||
set Log=%basePath%agent.log
|
||||
set LogBack=%basePath%log\
|
||||
set JVM=-server
|
||||
set ARGS= --jpom.applicationTag=%Tag% --jpom.log=%basePath%log --server.port=2123
|
||||
|
||||
color 0a
|
||||
TITLE Jpom管理系统BAT控制台
|
||||
echo. ***** Jpom管理系统BAT控制台 *****
|
||||
::*************************************************************************************************************
|
||||
echo.
|
||||
echo. [1] 启动 start
|
||||
echo. [2] 关闭 stop
|
||||
echo. [3] 查看运行状态 status
|
||||
echo. [4] 重启 restart
|
||||
echo. [5] 帮助 use
|
||||
echo. [0] 退 出 0
|
||||
echo.
|
||||
|
||||
echo.请输入选择的序号:
|
||||
set /p ID=
|
||||
IF "%id%"=="1" goto start
|
||||
IF "%id%"=="2" goto stop
|
||||
IF "%id%"=="3" goto status
|
||||
IF "%id%"=="4" goto restart
|
||||
IF "%id%"=="5" goto use
|
||||
IF "%id%"=="0" EXIT
|
||||
PAUSE
|
||||
echo 即将关闭窗口
|
||||
timeout 3
|
||||
EXIT 1
|
||||
|
||||
@REM 启动
|
||||
:start
|
||||
if "%JAVA_HOME%"=="" (
|
||||
echo 请配置【JAVA_HOME】环境变量
|
||||
PAUSE
|
||||
EXIT 2
|
||||
)
|
||||
rem 备份日志
|
||||
if exist %Log% (
|
||||
if not exist %LogBack% (
|
||||
echo %LogBack%
|
||||
md %LogBack%
|
||||
)
|
||||
move %Log% %LogBack%%date:~0,4%%date:~5,2%%date:~8,2%0%time:~1,1%%time:~3,2%%time:~6,2%.log
|
||||
del %Log%
|
||||
)
|
||||
set TEMPCLASSPATH=
|
||||
for /f "delims=" %%I in ('dir /B %Lib%') do (set TEMPCLASSPATH=!TEMPCLASSPATH!%Lib%%%I;)
|
||||
REM echo 启动成功,关闭窗口不影响运行
|
||||
echo 启动中.....关闭窗口不影响运行
|
||||
javaw %JVM% -classpath %TEMPCLASSPATH%"%JAVA_HOME%"\lib\tools.jar -Dapplication=%Tag% -Dbasedir=%basePath% %MainClass% %ARGS% >> %Log%
|
||||
timeout 3
|
||||
goto:eof
|
||||
|
||||
@REM 关闭Jpom
|
||||
:stop
|
||||
set TEMPCLASSPATH=
|
||||
for /f "delims=" %%I in ('dir /B %Lib%') do (set TEMPCLASSPATH=!TEMPCLASSPATH!%Lib%%%I;)
|
||||
java -classpath %TEMPCLASSPATH%"%JAVA_HOME%"\lib\tools.jar %CloseMainClass% %ARGS% --jpom.applicationTag=%Tag% --event=stop
|
||||
goto:eof
|
||||
|
||||
@REM 查看Jpom运行状态
|
||||
:status
|
||||
set TEMPCLASSPATH=
|
||||
for /f "delims=" %%I in ('dir /B %Lib%') do (set TEMPCLASSPATH=!TEMPCLASSPATH!%Lib%%%I;)
|
||||
java -classpath %TEMPCLASSPATH%"%JAVA_HOME%"\lib\tools.jar %CloseMainClass% %ARGS% --jpom.applicationTag=%Tag% --event=status
|
||||
goto:eof
|
||||
|
||||
@REM 重启Jpom
|
||||
:restart
|
||||
echo 停止中....
|
||||
call:stop
|
||||
timeout 3
|
||||
echo 启动中....
|
||||
call:start
|
||||
goto:eof
|
||||
|
||||
@REM 重新加载Nginx
|
||||
:reloadNginx
|
||||
nginx -s reload
|
||||
goto:eof
|
||||
|
||||
@REM 提示用法
|
||||
:use
|
||||
echo please use (start|stop|restart|status)
|
||||
goto:eof
|
||||
|
||||
|
152
modules/agent/script/Agent.sh
Normal file
152
modules/agent/script/Agent.sh
Normal file
@ -0,0 +1,152 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2019 码之科技工作室
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
# the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#!/bin/bash
|
||||
|
||||
Tag="KeepBx-Agent-System-JpomAgentApplication"
|
||||
MainClass="cn.keepbx.jpom.JpomAgentApplication"
|
||||
# 自动获取当前路径
|
||||
Path=$(cd `dirname $0`; pwd)"/"
|
||||
Lib="${Path}lib/"
|
||||
Log="${Path}agent.log"
|
||||
LogBack="${Path}log/"
|
||||
JVM="-server "
|
||||
# 修改项目端口号 日志路径
|
||||
ARGS="--jpom.applicationTag=${Tag} --server.port=2123 --jpom.log=${Path}log"
|
||||
|
||||
echo ${Tag}
|
||||
echo ${Path}
|
||||
RETVAL="0"
|
||||
|
||||
# 启动程序
|
||||
function start() {
|
||||
if [[ -z "${JAVA_HOME}" ]] ; then
|
||||
echo "请配置【JAVA_HOME】环境变量"
|
||||
exit 2
|
||||
fi
|
||||
echo ${Log}
|
||||
# 备份日志
|
||||
if [[ -f ${Log} ]]; then
|
||||
if [[ ! -d ${LogBack} ]];then
|
||||
mkdir ${LogBack}
|
||||
fi
|
||||
cur_dateTime="`date +%Y-%m-%d_%H:%M:%S`.log"
|
||||
mv ${Log} ${LogBack}${cur_dateTime}
|
||||
echo "mv to $LogBack$cur_dateTime"
|
||||
touch ${Log}
|
||||
fi
|
||||
# classPath
|
||||
CLASSPATH=`listDir ${Lib}`
|
||||
nohup java ${JVM} -classpath ${CLASSPATH}${JAVA_HOME}/lib/tools.jar -Dapplication=${Tag} -Dbasedir=${Path} ${MainClass} ${ARGS} >> ${Log} 2>&1 &
|
||||
if [[ -f ${Log} ]]; then
|
||||
tail -f ${Log}
|
||||
else
|
||||
sleep 3
|
||||
if [[ -f ${Log} ]]; then
|
||||
tail -f ${Log}
|
||||
else
|
||||
echo "还没有生成日志文件:${Log}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 拼接所有文件
|
||||
function listDir()
|
||||
{
|
||||
ALL=""
|
||||
for file in `ls $1`
|
||||
do
|
||||
#得到文件的完整的目录
|
||||
ALL="${ALL}${1}/${file}:"
|
||||
done
|
||||
echo ${ALL}
|
||||
}
|
||||
|
||||
# 停止程序
|
||||
function stop() {
|
||||
pid=$(ps -ef | grep -v 'grep' | egrep ${Tag}| awk '{printf $2 " "}')
|
||||
if [[ "$pid" != "" ]]; then
|
||||
echo -n "boot ( pid $pid) is running"
|
||||
echo
|
||||
echo -n $"Shutting down boot: wait"
|
||||
kill $(pgrep -f ${Tag}) 2>/dev/null
|
||||
sleep 3
|
||||
pid=$(ps -ef | grep -v 'grep' | egrep ${Tag}| awk '{printf $2 " "}')
|
||||
if [[ "$pid" != "" ]]; then
|
||||
echo "kill boot process"
|
||||
kill -9 "$pid"
|
||||
fi
|
||||
else
|
||||
echo "boot is stopped"
|
||||
fi
|
||||
|
||||
status
|
||||
}
|
||||
|
||||
# 获取程序状态
|
||||
function status()
|
||||
{
|
||||
pid=$(ps -ef | grep -v 'grep' | egrep ${Tag}| awk '{printf $2 " "}')
|
||||
#echo "$pid"
|
||||
if [[ "$pid" != "" ]]; then
|
||||
echo "boot is running,pid is $pid"
|
||||
else
|
||||
echo "boot is stopped"
|
||||
fi
|
||||
}
|
||||
|
||||
# 重新加载nginx
|
||||
function reloadNginx(){
|
||||
nginx -t
|
||||
nginx -s reload
|
||||
}
|
||||
|
||||
# 提示使用语法
|
||||
function usage()
|
||||
{
|
||||
echo "Usage: $0 {start|stop|restart|status|reloadNginx}"
|
||||
RETVAL="2"
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
RETVAL="0"
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
restart)
|
||||
stop
|
||||
start
|
||||
;;
|
||||
reloadNginx)
|
||||
reloadNginx
|
||||
;;
|
||||
status)
|
||||
status
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
exit $RETVAL
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<assembly>
|
||||
|
||||
<id>release</id>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<formats>
|
||||
@ -11,16 +10,16 @@
|
||||
<fileSets>
|
||||
<!-- 打包Jpom 管理命令文件-->
|
||||
<fileSet>
|
||||
<directory>${basedir}/script/</directory>
|
||||
<directory>script/</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>Jpom.sh</include>
|
||||
<include>Jpom.bat</include>
|
||||
<include>Agent.sh</include>
|
||||
<include>Agent.bat</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<!--复制外部配置文件-->
|
||||
<fileSet>
|
||||
<directory>${basedir}/src/main/resources/bin/</directory>
|
||||
<directory>src/main/resources/bin/</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>extConfig.yml</include>
|
@ -0,0 +1,44 @@
|
||||
package cn.keepbx.jpom;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.jiangzeyin.common.ApplicationBuilder;
|
||||
import cn.jiangzeyin.common.EnableCommonBoot;
|
||||
import cn.keepbx.jpom.common.JpomApplicationEvent;
|
||||
import cn.keepbx.jpom.common.Type;
|
||||
import cn.keepbx.jpom.common.interceptor.AuthorizeInterceptor;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
|
||||
/**
|
||||
* jpom 启动类
|
||||
* Created by jiangzeyin on 2017/9/14.
|
||||
*
|
||||
* @author jiangzeyin
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@ServletComponentScan
|
||||
@EnableCommonBoot
|
||||
public class JpomAgentApplication extends BaseJpomApplication {
|
||||
|
||||
public JpomAgentApplication() {
|
||||
super(Type.Agent, JpomAgentApplication.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动执行
|
||||
*
|
||||
* @param args 参数
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
JpomAgentApplication.args = args;
|
||||
ApplicationBuilder.createBuilder(JpomAgentApplication.class)
|
||||
.addHttpMessageConverter(new StringHttpMessageConverter(CharsetUtil.CHARSET_UTF_8))
|
||||
// 拦截器
|
||||
.addInterceptor(AuthorizeInterceptor.class)
|
||||
//
|
||||
.addApplicationEventClient(new JpomApplicationEvent())
|
||||
.run(args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package cn.keepbx.jpom.common;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.keepbx.jpom.model.Role;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.service.manage.ProjectInfoService;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* agent 端
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/17
|
||||
*/
|
||||
public abstract class BaseAgentController extends BaseJpomController {
|
||||
@Resource
|
||||
protected ProjectInfoService projectInfoService;
|
||||
|
||||
protected String getUserName() {
|
||||
return getUserName(getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取server 端操作人
|
||||
*
|
||||
* @param request req
|
||||
* @return name
|
||||
*/
|
||||
public static String getUserName(HttpServletRequest request) {
|
||||
String name = ServletUtil.getHeaderIgnoreCase(request, ConfigBean.JPOM_SERVER_USER_NAME);
|
||||
name = CharsetUtil.convert(name, CharsetUtil.CHARSET_ISO_8859_1, CharsetUtil.CHARSET_UTF_8);
|
||||
return StrUtil.emptyToDefault(name, StrUtil.DASHED);
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作的人员是否为系统管理员
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
protected Role getUserRole() {
|
||||
String val = ServletUtil.getHeaderIgnoreCase(getRequest(), ConfigBean.JPOM_SERVER_SYSTEM_USER_ROLE);
|
||||
try {
|
||||
return Role.valueOf(val);
|
||||
} catch (Exception e) {
|
||||
return Role.User;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isSystemUser() {
|
||||
return getUserRole() == Role.System;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取拦截器中缓存的项目信息
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
protected ProjectInfoModel getProjectInfoModel() {
|
||||
ProjectInfoModel projectInfoModel = tryGetProjectInfoModel();
|
||||
Objects.requireNonNull(projectInfoModel, "获取项目信息失败");
|
||||
return projectInfoModel;
|
||||
}
|
||||
|
||||
protected ProjectInfoModel tryGetProjectInfoModel() {
|
||||
ProjectInfoModel projectInfoModel = null;
|
||||
String id = getParameter("id");
|
||||
if (StrUtil.isNotEmpty(id)) {
|
||||
projectInfoModel = projectInfoService.getItem(id);
|
||||
}
|
||||
return projectInfoModel;
|
||||
}
|
||||
}
|
@ -7,18 +7,16 @@ import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.JarClassLoader;
|
||||
import cn.hutool.core.text.StrSpliter;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.system.OsInfo;
|
||||
import cn.hutool.system.SystemUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import cn.keepbx.jpom.BaseJpomApplication;
|
||||
import cn.keepbx.jpom.common.commander.impl.LinuxProjectCommander;
|
||||
import cn.keepbx.jpom.common.commander.impl.WindowsProjectCommander;
|
||||
import cn.keepbx.jpom.model.RunMode;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.model.system.NetstatModel;
|
||||
import cn.keepbx.jpom.service.manage.ConsoleService;
|
||||
import cn.keepbx.jpom.service.manage.ProjectInfoService;
|
||||
import cn.keepbx.jpom.system.JpomRuntimeException;
|
||||
import cn.keepbx.jpom.util.CommandUtil;
|
||||
@ -28,7 +26,6 @@ import com.sun.tools.attach.VirtualMachine;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -44,9 +41,12 @@ import java.util.jar.Manifest;
|
||||
*/
|
||||
public abstract class AbstractProjectCommander {
|
||||
|
||||
public static final String RUNING_TAG = "running";
|
||||
public static final String STOP_TAG = "stopped";
|
||||
|
||||
private static AbstractProjectCommander abstractProjectCommander = null;
|
||||
protected Charset charset;
|
||||
public static final OsInfo OS_INFO = SystemUtil.getOsInfo();
|
||||
|
||||
|
||||
/**
|
||||
* 进程id 对应Jpom 名称
|
||||
*/
|
||||
@ -56,14 +56,6 @@ public abstract class AbstractProjectCommander {
|
||||
*/
|
||||
private static final LRUCache<Integer, Integer> PID_PORT = new LRUCache<>(100, TimeUnit.MINUTES.toMillis(10));
|
||||
|
||||
protected AbstractProjectCommander(Charset charset) {
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
public Charset getCharset() {
|
||||
return charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例化Commander
|
||||
*
|
||||
@ -73,14 +65,14 @@ public abstract class AbstractProjectCommander {
|
||||
if (abstractProjectCommander != null) {
|
||||
return abstractProjectCommander;
|
||||
}
|
||||
if (OS_INFO.isLinux()) {
|
||||
if (BaseJpomApplication.OS_INFO.isLinux()) {
|
||||
// Linux系统
|
||||
abstractProjectCommander = new LinuxProjectCommander(CharsetUtil.CHARSET_UTF_8);
|
||||
} else if (OS_INFO.isWindows()) {
|
||||
abstractProjectCommander = new LinuxProjectCommander();
|
||||
} else if (BaseJpomApplication.OS_INFO.isWindows()) {
|
||||
// Windows系统
|
||||
abstractProjectCommander = new WindowsProjectCommander(CharsetUtil.CHARSET_GBK);
|
||||
abstractProjectCommander = new WindowsProjectCommander();
|
||||
} else {
|
||||
throw new JpomRuntimeException("不支持的:" + OS_INFO.getName());
|
||||
throw new JpomRuntimeException("不支持的:" + BaseJpomApplication.OS_INFO.getName());
|
||||
}
|
||||
return abstractProjectCommander;
|
||||
}
|
||||
@ -168,7 +160,7 @@ public abstract class AbstractProjectCommander {
|
||||
return "没有jar包,请先到文件管理中上传程序的jar";
|
||||
}
|
||||
//
|
||||
if (projectInfoModel.getRunMode() == ProjectInfoModel.RunMode.ClassPath) {
|
||||
if (projectInfoModel.getRunMode() == RunMode.ClassPath) {
|
||||
JarClassLoader jarClassLoader = JarClassLoader.load(FileUtil.file(projectInfoModel.getLib()));
|
||||
// 判断主类
|
||||
try {
|
||||
@ -227,9 +219,9 @@ public abstract class AbstractProjectCommander {
|
||||
File backPath = projectInfoModel.getLogBack();
|
||||
backPath = new File(backPath, DateTime.now().toString(DatePattern.PURE_DATETIME_FORMAT) + ".log");
|
||||
FileUtil.copy(file, backPath, true);
|
||||
if (OS_INFO.isLinux()) {
|
||||
if (BaseJpomApplication.OS_INFO.isLinux()) {
|
||||
CommandUtil.execCommand("cp /dev/null " + projectInfoModel.getLog());
|
||||
} else if (OS_INFO.isWindows()) {
|
||||
} else if (BaseJpomApplication.OS_INFO.isWindows()) {
|
||||
// 清空日志
|
||||
String r = CommandUtil.execSystemCommand("echo \"\" > " + file.getAbsolutePath());
|
||||
if (StrUtil.isEmpty(r)) {
|
||||
@ -247,9 +239,9 @@ public abstract class AbstractProjectCommander {
|
||||
public String status(String tag) throws Exception {
|
||||
VirtualMachine virtualMachine = JvmUtil.getVirtualMachine(tag);
|
||||
if (virtualMachine == null) {
|
||||
return ConsoleService.STOP_TAG;
|
||||
return AbstractProjectCommander.STOP_TAG;
|
||||
}
|
||||
return StrUtil.format("{}:{}", ConsoleService.RUNING_TAG, virtualMachine.id());
|
||||
return StrUtil.format("{}:{}", AbstractProjectCommander.RUNING_TAG, virtualMachine.id());
|
||||
}
|
||||
|
||||
//---------------------------------------------------- 基本操作----end
|
||||
@ -378,7 +370,7 @@ public abstract class AbstractProjectCommander {
|
||||
* @return int
|
||||
*/
|
||||
protected static int parsePid(String result) {
|
||||
if (result.startsWith(ConsoleService.RUNING_TAG)) {
|
||||
if (result.startsWith(AbstractProjectCommander.RUNING_TAG)) {
|
||||
return Convert.toInt(result.split(":")[1]);
|
||||
}
|
||||
return 0;
|
||||
@ -393,7 +385,7 @@ public abstract class AbstractProjectCommander {
|
||||
*/
|
||||
public boolean isRun(String tag) throws Exception {
|
||||
String result = status(tag);
|
||||
return result.contains(ConsoleService.RUNING_TAG);
|
||||
return result.contains(AbstractProjectCommander.RUNING_TAG);
|
||||
}
|
||||
|
||||
/***
|
@ -1,5 +1,6 @@
|
||||
package cn.keepbx.jpom.common.commander;
|
||||
|
||||
import cn.keepbx.jpom.BaseJpomApplication;
|
||||
import cn.keepbx.jpom.common.commander.impl.LinuxSystemCommander;
|
||||
import cn.keepbx.jpom.common.commander.impl.WindowsSystemCommander;
|
||||
import cn.keepbx.jpom.model.system.ProcessModel;
|
||||
@ -11,30 +12,38 @@ import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 系统监控基类
|
||||
* 系统监控命令
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/15
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
public abstract class AbstractSystemCommander {
|
||||
|
||||
private static AbstractSystemCommander abstractSystemCommander = null;
|
||||
|
||||
public static AbstractSystemCommander getInstance() {
|
||||
if (abstractSystemCommander != null) {
|
||||
return abstractSystemCommander;
|
||||
}
|
||||
if (AbstractProjectCommander.OS_INFO.isLinux()) {
|
||||
if (BaseJpomApplication.OS_INFO.isLinux()) {
|
||||
// Linux系统
|
||||
abstractSystemCommander = new LinuxSystemCommander();
|
||||
} else if (AbstractProjectCommander.OS_INFO.isWindows()) {
|
||||
} else if (BaseJpomApplication.OS_INFO.isWindows()) {
|
||||
// Windows系统
|
||||
abstractSystemCommander = new WindowsSystemCommander();
|
||||
} else {
|
||||
throw new JpomRuntimeException("不支持的:" + AbstractProjectCommander.OS_INFO.getName());
|
||||
throw new JpomRuntimeException("不支持的:" + BaseJpomApplication.OS_INFO.getName());
|
||||
}
|
||||
return abstractSystemCommander;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取整个服务器监控信息
|
||||
*
|
||||
* @return data
|
||||
*/
|
||||
public abstract JSONObject getAllMonitor();
|
||||
|
||||
/**
|
||||
* 获取当前服务器的所有进程列表
|
||||
*
|
||||
@ -50,12 +59,13 @@ public abstract class AbstractSystemCommander {
|
||||
*/
|
||||
public abstract ProcessModel getPidInfo(int pid);
|
||||
|
||||
/**
|
||||
* 获取整个服务器监控信息
|
||||
*
|
||||
* @return data
|
||||
*/
|
||||
public abstract JSONObject getAllMonitor();
|
||||
protected static JSONObject putObject(String name, Object value, String type) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", name);
|
||||
jsonObject.put("value", value);
|
||||
jsonObject.put("type", type);
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* 磁盘占用
|
||||
@ -77,12 +87,4 @@ public abstract class AbstractSystemCommander {
|
||||
array.add(putObject("空闲磁盘", freeSpace / 1024f, "disk"));
|
||||
return array;
|
||||
}
|
||||
|
||||
protected static JSONObject putObject(String name, Object value, String type) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", name);
|
||||
jsonObject.put("value", value);
|
||||
jsonObject.put("type", type);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
@ -2,12 +2,12 @@ package cn.keepbx.jpom.common.commander.impl;
|
||||
|
||||
import cn.hutool.core.text.StrSpliter;
|
||||
import cn.hutool.core.thread.GlobalThreadPool;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.model.system.NetstatModel;
|
||||
import cn.keepbx.jpom.util.CommandUtil;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -18,10 +18,6 @@ import java.util.List;
|
||||
*/
|
||||
public class LinuxProjectCommander extends AbstractProjectCommander {
|
||||
|
||||
public LinuxProjectCommander(Charset charset) {
|
||||
super(charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String start(ProjectInfoModel projectInfoModel) throws Exception {
|
||||
String msg = checkStart(projectInfoModel);
|
||||
@ -79,8 +75,13 @@ public class LinuxProjectCommander extends AbstractProjectCommander {
|
||||
netstatModel.setSend(list.get(2));
|
||||
netstatModel.setLocal(list.get(3));
|
||||
netstatModel.setForeign(list.get(4));
|
||||
netstatModel.setStatus(list.get(5));
|
||||
netstatModel.setName(list.get(6));
|
||||
if ("tcp".equalsIgnoreCase(netstatModel.getProtocol())) {
|
||||
netstatModel.setStatus(list.get(5));
|
||||
netstatModel.setName(list.get(6));
|
||||
} else {
|
||||
netstatModel.setStatus(StrUtil.DASHED);
|
||||
netstatModel.setName(list.get(5));
|
||||
}
|
||||
array.add(netstatModel);
|
||||
}
|
||||
return array;
|
@ -14,28 +14,10 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/15
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
public class LinuxSystemCommander extends AbstractSystemCommander {
|
||||
|
||||
@Override
|
||||
public List<ProcessModel> getProcessList() {
|
||||
String s = CommandUtil.execSystemCommand("top -b -n 1 | grep java");
|
||||
return formatLinuxTop(s, false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ProcessModel getPidInfo(int pid) {
|
||||
String command = "top -b -n 1 -p " + pid;
|
||||
String internal = CommandUtil.execCommand(command);
|
||||
List<ProcessModel> processModels = formatLinuxTop(internal, true);
|
||||
if (processModels == null || processModels.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return processModels.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getAllMonitor() {
|
||||
String result = CommandUtil.execCommand("top -b -n 1");
|
||||
@ -62,6 +44,25 @@ public class LinuxSystemCommander extends AbstractSystemCommander {
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProcessModel> getProcessList() {
|
||||
String s = CommandUtil.execSystemCommand("top -b -n 1 | grep java");
|
||||
return formatLinuxTop(s, false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ProcessModel getPidInfo(int pid) {
|
||||
String command = "top -b -n 1 -p " + pid;
|
||||
String internal = CommandUtil.execCommand(command);
|
||||
List<ProcessModel> processModels = formatLinuxTop(internal, true);
|
||||
if (processModels == null || processModels.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return processModels.get(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将linux的top信息转为集合
|
||||
*
|
||||
@ -119,14 +120,17 @@ public class LinuxSystemCommander extends AbstractSystemCommander {
|
||||
}
|
||||
|
||||
private static String formSize(String val) {
|
||||
if (val.endsWith("g")) {
|
||||
return String.format("%.2f MB", Convert.toDouble(val.replace("g", "")) * 1024);
|
||||
} else {
|
||||
return Convert.toLong(val) / 1024 + " MB";
|
||||
if (StrUtil.endWithIgnoreCase(val, "g")) {
|
||||
String newVal = val.substring(0, val.length() - 1);
|
||||
return String.format("%.2f MB", Convert.toDouble(newVal, 0D) * 1024);
|
||||
}
|
||||
if (StrUtil.endWithIgnoreCase(val, "m")) {
|
||||
String newVal = val.substring(0, val.length() - 1);
|
||||
return Convert.toLong(newVal, 0L) / 1024 + " MB";
|
||||
}
|
||||
return Convert.toLong(val, 0L) / 1024 + " MB";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取内存信息
|
||||
*
|
@ -8,7 +8,6 @@ import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.model.system.NetstatModel;
|
||||
import cn.keepbx.jpom.util.CommandUtil;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -19,10 +18,6 @@ import java.util.List;
|
||||
*/
|
||||
public class WindowsProjectCommander extends AbstractProjectCommander {
|
||||
|
||||
public WindowsProjectCommander(Charset charset) {
|
||||
super(charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String start(ProjectInfoModel projectInfoModel) throws Exception {
|
||||
String msg = checkStart(projectInfoModel);
|
@ -19,8 +19,10 @@ import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* windows 系统查询命令
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/15
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
public class WindowsSystemCommander extends AbstractSystemCommander {
|
||||
|
||||
@ -28,31 +30,7 @@ public class WindowsSystemCommander extends AbstractSystemCommander {
|
||||
* 锁定查看进程信息
|
||||
*/
|
||||
private static final AtomicBoolean ATOMIC_BOOLEAN = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
public List<ProcessModel> getProcessList() {
|
||||
if (ATOMIC_BOOLEAN.get()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
ATOMIC_BOOLEAN.set(true);
|
||||
String s = CommandUtil.execSystemCommand("tasklist /V | findstr java");
|
||||
return formatWindowsProcess(s, false);
|
||||
} finally {
|
||||
ATOMIC_BOOLEAN.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessModel getPidInfo(int pid) {
|
||||
String command = "tasklist /V /FI \"pid eq " + pid + "\"";
|
||||
String result = CommandUtil.execCommand(command);
|
||||
List<ProcessModel> array = formatWindowsProcess(result, true);
|
||||
if (array == null || array.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return array.get(0);
|
||||
}
|
||||
private static List<ProcessModel> lastResult;
|
||||
|
||||
/**
|
||||
* 获取windows 监控
|
||||
@ -89,6 +67,34 @@ public class WindowsSystemCommander extends AbstractSystemCommander {
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProcessModel> getProcessList() {
|
||||
if (ATOMIC_BOOLEAN.get()) {
|
||||
// 返回上一次结果
|
||||
return lastResult;
|
||||
}
|
||||
try {
|
||||
ATOMIC_BOOLEAN.set(true);
|
||||
String s = CommandUtil.execSystemCommand("tasklist /V | findstr java");
|
||||
lastResult = formatWindowsProcess(s, false);
|
||||
return lastResult;
|
||||
} finally {
|
||||
ATOMIC_BOOLEAN.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessModel getPidInfo(int pid) {
|
||||
String command = "tasklist /V /FI \"pid eq " + pid + "\"";
|
||||
String result = CommandUtil.execCommand(command);
|
||||
List<ProcessModel> array = formatWindowsProcess(result, true);
|
||||
if (array == null || array.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return array.get(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将windows的tasklist转为集合
|
||||
*
|
||||
@ -160,5 +166,4 @@ public class WindowsSystemCommander extends AbstractSystemCommander {
|
||||
}
|
||||
return "未知";
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* 系统实体信息
|
||||
* Jpom 管理项目实现管理的工具包
|
||||
* <p>
|
||||
* The MIT License(MIT)
|
||||
* <p>
|
||||
@ -25,4 +25,4 @@
|
||||
*
|
||||
* @author jiangzeyin
|
||||
*/
|
||||
package cn.keepbx.jpom.model.system;
|
||||
package cn.keepbx.jpom.common.commander;
|
@ -0,0 +1,49 @@
|
||||
package cn.keepbx.jpom.common.interceptor;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.jiangzeyin.common.interceptor.BaseInterceptor;
|
||||
import cn.jiangzeyin.common.interceptor.InterceptorPattens;
|
||||
import cn.keepbx.jpom.system.AgentAuthorize;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 授权拦截
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/17
|
||||
*/
|
||||
@InterceptorPattens()
|
||||
public class AuthorizeInterceptor extends BaseInterceptor {
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
super.preHandle(request, response, handler);
|
||||
if (handler instanceof HandlerMethod) {
|
||||
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
||||
NotAuthorize notAuthorize = handlerMethod.getMethodAnnotation(NotAuthorize.class);
|
||||
if (notAuthorize == null) {
|
||||
String authorize = ServletUtil.getHeaderIgnoreCase(request, ConfigBean.JPOM_AGENT_AUTHORIZE);
|
||||
if (StrUtil.isEmpty(authorize)) {
|
||||
this.error(response);
|
||||
return false;
|
||||
}
|
||||
if (!AgentAuthorize.getInstance().checkAuthorize(authorize)) {
|
||||
this.error(response);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void error(HttpServletResponse response) {
|
||||
ServletUtil.write(response, JsonMessage.getString(ConfigBean.AUTHORIZE_ERROR, "授权信息错误"), MediaType.APPLICATION_JSON_UTF8_VALUE);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package cn.keepbx.jpom.common.interceptor;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 不需要授权
|
||||
* Created by jiangzeyin on 2019/4/17.
|
||||
*/
|
||||
@Documented
|
||||
@Target(ElementType.METHOD)
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface NotAuthorize {
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
package cn.keepbx.jpom.controller;
|
||||
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.keepbx.jpom.BaseJpomApplication;
|
||||
import cn.keepbx.jpom.common.BaseAgentController;
|
||||
import cn.keepbx.jpom.common.interceptor.NotAuthorize;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.model.system.JpomManifest;
|
||||
import cn.keepbx.jpom.service.WhitelistDirectoryService;
|
||||
import cn.keepbx.jpom.service.manage.ProjectInfoService;
|
||||
import cn.keepbx.jpom.util.JvmUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 首页
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/17
|
||||
*/
|
||||
@RestController
|
||||
public class IndexController extends BaseAgentController {
|
||||
@Resource
|
||||
private WhitelistDirectoryService whitelistDirectoryService;
|
||||
@Resource
|
||||
private ProjectInfoService projectInfoService;
|
||||
|
||||
@RequestMapping(value = {"index", "", "index.html", "/"}, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@NotAuthorize
|
||||
public String index() {
|
||||
return "Jpom-Agent";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "info", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String info() {
|
||||
int code;
|
||||
if (whitelistDirectoryService.isInstalled()) {
|
||||
code = 200;
|
||||
} else {
|
||||
code = 201;
|
||||
}
|
||||
return JsonMessage.getString(code, "", JpomManifest.getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回节点项目状态信息
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@RequestMapping(value = "status", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String status() {
|
||||
List<ProjectInfoModel> projectInfoModels = projectInfoService.list();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("javaVirtualCount", JvmUtil.getJavaVirtualCount());
|
||||
jsonObject.put("osName", BaseJpomApplication.OS_INFO.getName());
|
||||
jsonObject.put("jpomVersion", JpomManifest.getInstance().getVersion());
|
||||
if (projectInfoModels == null) {
|
||||
jsonObject.put("count", 0);
|
||||
jsonObject.put("runCount", 0);
|
||||
jsonObject.put("stopCount", 0);
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
int count = 0, runCount = 0, stopCount = 0;
|
||||
for (ProjectInfoModel projectInfoModel : projectInfoModels) {
|
||||
count++;
|
||||
if (projectInfoModel.isStatus(true)) {
|
||||
runCount++;
|
||||
} else {
|
||||
stopCount++;
|
||||
}
|
||||
}
|
||||
jsonObject.put("count", count);
|
||||
jsonObject.put("runCount", runCount);
|
||||
jsonObject.put("stopCount", stopCount);
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
jsonArray.add(jsonObject);
|
||||
return JsonMessage.getString(200, "", jsonArray);
|
||||
}
|
||||
}
|
@ -1,34 +1,26 @@
|
||||
package cn.keepbx.jpom.controller;
|
||||
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.jiangzeyin.controller.base.AbstractController;
|
||||
import cn.keepbx.jpom.common.commander.AbstractSystemCommander;
|
||||
import cn.keepbx.jpom.model.system.ProcessModel;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 欢迎页
|
||||
*
|
||||
* @author Administrator
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping(value = "/")
|
||||
public class WelcomeController extends BaseController {
|
||||
|
||||
@RequestMapping(value = "welcome", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
public String welcome() {
|
||||
return "welcome";
|
||||
}
|
||||
@RestController
|
||||
public class WelcomeController extends AbstractController {
|
||||
|
||||
@RequestMapping(value = "getTop", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
public String getTop() {
|
||||
JSONObject topInfo = AbstractSystemCommander.getInstance().getAllMonitor();
|
||||
return JsonMessage.getString(200, "", topInfo);
|
||||
@ -38,6 +30,9 @@ public class WelcomeController extends BaseController {
|
||||
@ResponseBody
|
||||
public String getProcessList() {
|
||||
List<ProcessModel> array = AbstractSystemCommander.getInstance().getProcessList();
|
||||
return JsonMessage.getString(200, "", array);
|
||||
if (array != null && !array.isEmpty()) {
|
||||
return JsonMessage.getString(200, "", array);
|
||||
}
|
||||
return JsonMessage.getString(402, "没有获取到进程信息");
|
||||
}
|
||||
}
|
@ -5,18 +5,16 @@ import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.interceptor.ProjectPermission;
|
||||
import cn.keepbx.jpom.common.BaseAgentController;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.service.manage.ConsoleService;
|
||||
import cn.keepbx.jpom.service.manage.ProjectInfoService;
|
||||
import cn.keepbx.jpom.service.oss.OssManagerService;
|
||||
import cn.keepbx.jpom.socket.CommandOp;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
@ -27,48 +25,43 @@ import java.io.File;
|
||||
* @author jiangzeyin
|
||||
* @date 2018/9/29
|
||||
*/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping(value = "/manage/")
|
||||
public class BuildController extends BaseController {
|
||||
public class BuildController extends BaseAgentController {
|
||||
|
||||
@Resource
|
||||
private OssManagerService ossManagerService;
|
||||
@Resource
|
||||
private ProjectInfoService projectInfoService;
|
||||
@Resource
|
||||
private ConsoleService consoleService;
|
||||
|
||||
@RequestMapping(value = "build", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
@RequestMapping(value = "build_data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String build(String id) {
|
||||
ProjectInfoModel projectInfoModel = projectInfoService.getItem(id);
|
||||
JSONArray jsonArray = null;
|
||||
if (projectInfoModel != null && StrUtil.isNotEmpty(projectInfoModel.getBuildTag())) {
|
||||
JSONArray jsonArray = ossManagerService.list(projectInfoModel.getBuildTag());
|
||||
setAttribute("array", jsonArray);
|
||||
setAttribute("id", id);
|
||||
jsonArray = ossManagerService.list(projectInfoModel.getBuildTag());
|
||||
}
|
||||
return "manage/build";
|
||||
return JsonMessage.getString(200, "", jsonArray);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "build_download", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
@RequestMapping(value = "build_download", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String buildDownload(String id, String key) {
|
||||
if (!getUser().isProject(id)) {
|
||||
return "redirect:error";
|
||||
if (StrUtil.isEmpty(key)) {
|
||||
return JsonMessage.getString(401, "key 错误");
|
||||
}
|
||||
String url = null;
|
||||
try {
|
||||
ProjectInfoModel projectInfoModel = projectInfoService.getItem(id);
|
||||
if (projectInfoModel == null) {
|
||||
return "redirect:error";
|
||||
if (projectInfoModel != null) {
|
||||
url = ossManagerService.getUrl(key).toString();
|
||||
}
|
||||
return "redirect:" + ossManagerService.getUrl(key);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error("获取下载地址失败", e);
|
||||
return "redirect:error";
|
||||
}
|
||||
return JsonMessage.getString(200, "", url);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "build_install", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@ProjectPermission
|
||||
public String buildInstall(String key) throws Exception {
|
||||
ProjectInfoModel projectInfoModel = getProjectInfoModel();
|
||||
if (StrUtil.isEmpty(projectInfoModel.getBuildTag())) {
|
||||
@ -86,7 +79,7 @@ public class BuildController extends BaseController {
|
||||
// 修改使用状态
|
||||
projectInfoModel.setUseLibDesc("build");
|
||||
projectInfoService.updateItem(projectInfoModel);
|
||||
String result = consoleService.execCommand(ConsoleService.CommandOp.restart, projectInfoModel);
|
||||
String result = consoleService.execCommand(CommandOp.restart, projectInfoModel);
|
||||
return JsonMessage.getString(200, "安装成功,已自动重启,当前状态是:" + result);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package cn.keepbx.jpom.controller.manage;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.PatternPool;
|
||||
@ -8,100 +9,54 @@ import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.BaseAgentController;
|
||||
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
|
||||
import cn.keepbx.jpom.model.Role;
|
||||
import cn.keepbx.jpom.model.RunMode;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.model.data.UserModel;
|
||||
import cn.keepbx.jpom.service.manage.ProjectInfoService;
|
||||
import cn.keepbx.jpom.service.system.WhitelistDirectoryService;
|
||||
import cn.keepbx.jpom.socket.LogWebSocketHandle;
|
||||
import cn.keepbx.jpom.service.WhitelistDirectoryService;
|
||||
import cn.keepbx.jpom.socket.CommonSocketConfig;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 项目管理
|
||||
* 编辑项目
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2018/9/29
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping(value = "/manage/")
|
||||
public class EditProjectController extends BaseController {
|
||||
@Resource
|
||||
private ProjectInfoService projectInfoService;
|
||||
public class EditProjectController extends BaseAgentController {
|
||||
@Resource
|
||||
private WhitelistDirectoryService whitelistDirectoryService;
|
||||
|
||||
/**
|
||||
* 修改项目页面
|
||||
*
|
||||
* @param id 项目Id
|
||||
* @return json
|
||||
* @throws IOException IO
|
||||
*/
|
||||
@RequestMapping(value = "editProject", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
public String editProject(String id) throws IOException {
|
||||
ProjectInfoModel projectInfo = projectInfoService.getItem(id);
|
||||
|
||||
// 白名单
|
||||
JSONArray jsonArray = whitelistDirectoryService.getProjectDirectory();
|
||||
setAttribute("whitelistDirectory", jsonArray);
|
||||
|
||||
if (projectInfo != null && jsonArray != null) {
|
||||
for (Object obj : jsonArray) {
|
||||
String path = obj.toString();
|
||||
String lib = projectInfo.getLib();
|
||||
if (lib.startsWith(path)) {
|
||||
String itemWhitelistDirectory = lib.substring(0, path.length());
|
||||
lib = lib.substring(path.length());
|
||||
setAttribute("itemWhitelistDirectory", itemWhitelistDirectory);
|
||||
projectInfo.setLib(lib);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
setAttribute("item", projectInfo);
|
||||
// 运行模式
|
||||
ProjectInfoModel.RunMode[] runModes = ProjectInfoModel.RunMode.values();
|
||||
setAttribute("runModes", runModes);
|
||||
//
|
||||
HashSet<String> hashSet = projectInfoService.getAllGroup();
|
||||
if (hashSet.isEmpty()) {
|
||||
hashSet.add("默认");
|
||||
}
|
||||
setAttribute("groups", hashSet);
|
||||
return "manage/editProject";
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础检查
|
||||
*
|
||||
* @param projectInfo 项目实体
|
||||
* @param whitelistDirectory 白名单
|
||||
* @param previewData 预检查数据
|
||||
* @return null 检查正常
|
||||
*/
|
||||
private String checkParameter(ProjectInfoModel projectInfo, String whitelistDirectory) {
|
||||
private String checkParameter(ProjectInfoModel projectInfo, String whitelistDirectory, boolean previewData) {
|
||||
String id = projectInfo.getId();
|
||||
if (StrUtil.isEmptyOrUndefined(id)) {
|
||||
return JsonMessage.getString(400, "项目id不能为空");
|
||||
}
|
||||
if (Validator.isChinese(id)) {
|
||||
return JsonMessage.getString(401, "项目id不能包含中文");
|
||||
if (!Validator.isGeneral(id, 2, 20)) {
|
||||
return JsonMessage.getString(401, "项目id 长度范围2-20(英文字母 、数字和下划线)");
|
||||
}
|
||||
if (LogWebSocketHandle.SYSTEM_ID.equals(id)) {
|
||||
return JsonMessage.getString(401, "项目id " + LogWebSocketHandle.SYSTEM_ID + " 关键词被系统占用");
|
||||
if (CommonSocketConfig.SYSTEM_ID.equals(id)) {
|
||||
return JsonMessage.getString(401, "项目id " + CommonSocketConfig.SYSTEM_ID + " 关键词被系统占用");
|
||||
}
|
||||
// 防止和Jpom冲突
|
||||
if (StrUtil.isNotEmpty(ConfigBean.getInstance().applicationTag) && ConfigBean.getInstance().applicationTag.equalsIgnoreCase(id)) {
|
||||
@ -109,33 +64,49 @@ public class EditProjectController extends BaseController {
|
||||
}
|
||||
// 运行模式
|
||||
String runMode = getParameter("runMode");
|
||||
ProjectInfoModel.RunMode runMode1 = ProjectInfoModel.RunMode.ClassPath;
|
||||
RunMode runMode1 = RunMode.ClassPath;
|
||||
try {
|
||||
runMode1 = ProjectInfoModel.RunMode.valueOf(runMode);
|
||||
runMode1 = RunMode.valueOf(runMode);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
projectInfo.setRunMode(runMode1);
|
||||
// 监测
|
||||
if (runMode1 == ProjectInfoModel.RunMode.ClassPath) {
|
||||
if (runMode1 == RunMode.ClassPath) {
|
||||
if (StrUtil.isEmpty(projectInfo.getMainClass())) {
|
||||
return JsonMessage.getString(401, "ClassPath 模式 MainClass必填");
|
||||
}
|
||||
} else if (runMode1 == ProjectInfoModel.RunMode.Jar) {
|
||||
} else if (runMode1 == RunMode.Jar) {
|
||||
projectInfo.setMainClass("");
|
||||
}
|
||||
//
|
||||
if (!whitelistDirectoryService.checkProjectDirectory(whitelistDirectory)) {
|
||||
return JsonMessage.getString(401, "请选择正确的项目路径,或者还没有配置白名单");
|
||||
// 判断是否为分发添加
|
||||
String strOutGivingProject = getParameter("outGivingProject");
|
||||
boolean outGivingProject = Boolean.valueOf(strOutGivingProject);
|
||||
// 检查权限
|
||||
Role role = getUserRole();
|
||||
if (outGivingProject) {
|
||||
if (role != Role.System && role != Role.NodeManage) {
|
||||
return JsonMessage.getString(405, "没有权限操作分发项目管理");
|
||||
}
|
||||
}
|
||||
projectInfo.setOutGivingProject(outGivingProject);
|
||||
if (!previewData) {
|
||||
// 不是预检查数据才效验白名单
|
||||
if (!whitelistDirectoryService.checkProjectDirectory(whitelistDirectory)) {
|
||||
if (outGivingProject) {
|
||||
if (role == Role.System) {
|
||||
whitelistDirectoryService.addProjectWhiteList(whitelistDirectory);
|
||||
} else {
|
||||
return JsonMessage.getString(405, "对应白名单还没有添加,请联系管理员添加");
|
||||
}
|
||||
} else {
|
||||
return JsonMessage.getString(401, "请选择正确的项目路径,或者还没有配置白名单");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String lib = projectInfo.getLib();
|
||||
if (StrUtil.isEmpty(lib)) {
|
||||
return JsonMessage.getString(401, "项目Jar路径不能为空");
|
||||
}
|
||||
if (StrUtil.SLASH.equals(lib)) {
|
||||
return JsonMessage.getString(401, "项目Jar路径不能为顶级目录");
|
||||
}
|
||||
if (Validator.isChinese(lib)) {
|
||||
return JsonMessage.getString(401, "项目Jar路径中不能包含中文");
|
||||
if (StrUtil.isEmpty(lib) || StrUtil.SLASH.equals(lib) || Validator.isChinese(lib)) {
|
||||
return JsonMessage.getString(401, "项目Jar路径不能为空,不能为顶级目录,不能包含中文");
|
||||
}
|
||||
if (!checkPathSafe(lib)) {
|
||||
return JsonMessage.getString(401, "项目Jar路径存在提升目录问题");
|
||||
@ -143,21 +114,20 @@ public class EditProjectController extends BaseController {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存项目
|
||||
*
|
||||
* @param projectInfo 项目实体
|
||||
* @return json
|
||||
*/
|
||||
|
||||
@RequestMapping(value = "saveProject", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
public String saveProject(ProjectInfoModel projectInfo, String whitelistDirectory) {
|
||||
String error = checkParameter(projectInfo, whitelistDirectory);
|
||||
// 预检查数据
|
||||
String strPreviewData = getParameter("previewData");
|
||||
boolean previewData = Convert.toBool(strPreviewData, false);
|
||||
//
|
||||
String error = checkParameter(projectInfo, whitelistDirectory, previewData);
|
||||
if (error != null) {
|
||||
return error;
|
||||
}
|
||||
String lib = projectInfo.getLib();
|
||||
String id = projectInfo.getId();
|
||||
//
|
||||
String lib = projectInfo.getLib();
|
||||
lib = String.format("%s/%s", whitelistDirectory, lib);
|
||||
lib = FileUtil.normalize(lib);
|
||||
// 重复lib
|
||||
@ -191,53 +161,63 @@ public class EditProjectController extends BaseController {
|
||||
if (id.contains(StrUtil.SPACE) || lib.contains(StrUtil.SPACE)) {
|
||||
return JsonMessage.getString(401, "项目Id、项目Jar不能包含空格");
|
||||
}
|
||||
return save(projectInfo);
|
||||
return save(projectInfo, previewData);
|
||||
}
|
||||
|
||||
private String save(ProjectInfoModel projectInfo) {
|
||||
/**
|
||||
* 保存项目
|
||||
*
|
||||
* @param projectInfo 项目
|
||||
* @param previewData 是否是预检查
|
||||
* @return 错误信息
|
||||
*/
|
||||
private String save(ProjectInfoModel projectInfo, boolean previewData) {
|
||||
String edit = getParameter("edit");
|
||||
ProjectInfoModel exits = projectInfoService.getItem(projectInfo.getId());
|
||||
try {
|
||||
UserModel userName = getUser();
|
||||
JsonMessage jsonMessage = checkPath(projectInfo);
|
||||
if (jsonMessage != null) {
|
||||
return jsonMessage.toString();
|
||||
}
|
||||
if (exits == null) {
|
||||
if (!userName.isManage()) {
|
||||
return JsonMessage.getString(400, "管理员才能创建项目!");
|
||||
}
|
||||
// 检查运行中的tag 是否被占用
|
||||
if (AbstractProjectCommander.getInstance().isRun(projectInfo.getId())) {
|
||||
return JsonMessage.getString(400, "当前项目id已经被正在运行的程序占用");
|
||||
}
|
||||
projectInfo.setCreateTime(DateUtil.now());
|
||||
this.modify(projectInfo);
|
||||
projectInfoService.addItem(projectInfo);
|
||||
return JsonMessage.getString(200, "新增成功!");
|
||||
if (previewData) {
|
||||
// 预检查数据
|
||||
return JsonMessage.getString(200, "");
|
||||
} else {
|
||||
projectInfo.setCreateTime(DateUtil.now());
|
||||
this.modify(projectInfo);
|
||||
projectInfoService.addItem(projectInfo);
|
||||
return JsonMessage.getString(200, "新增成功!");
|
||||
}
|
||||
}
|
||||
//
|
||||
// 新增但是下面id 已经存在
|
||||
if (!"on".equalsIgnoreCase(edit)) {
|
||||
return JsonMessage.getString(400, "项目id已经存在啦");
|
||||
}
|
||||
if (!userName.isProject(projectInfo.getId())) {
|
||||
return JsonMessage.getString(400, "你没有对应操作权限操作!");
|
||||
if (previewData) {
|
||||
// 预检查数据
|
||||
return JsonMessage.getString(200, "");
|
||||
} else {
|
||||
this.modify(exits);
|
||||
exits.setLog(projectInfo.getLog());
|
||||
exits.setName(projectInfo.getName());
|
||||
exits.setGroup(projectInfo.getGroup());
|
||||
exits.setMainClass(projectInfo.getMainClass());
|
||||
exits.setLib(projectInfo.getLib());
|
||||
exits.setJvm(projectInfo.getJvm());
|
||||
exits.setArgs(projectInfo.getArgs());
|
||||
exits.setBuildTag(projectInfo.getBuildTag());
|
||||
exits.setRunMode(projectInfo.getRunMode());
|
||||
exits.setToken(projectInfo.getToken());
|
||||
//
|
||||
moveTo(exits, projectInfo);
|
||||
projectInfoService.updateItem(exits);
|
||||
return JsonMessage.getString(200, "修改成功");
|
||||
}
|
||||
this.modify(exits);
|
||||
exits.setLog(projectInfo.getLog());
|
||||
exits.setName(projectInfo.getName());
|
||||
exits.setGroup(projectInfo.getGroup());
|
||||
exits.setMainClass(projectInfo.getMainClass());
|
||||
exits.setLib(projectInfo.getLib());
|
||||
exits.setJvm(projectInfo.getJvm());
|
||||
exits.setArgs(projectInfo.getArgs());
|
||||
exits.setBuildTag(projectInfo.getBuildTag());
|
||||
exits.setRunMode(projectInfo.getRunMode());
|
||||
exits.setToken(projectInfo.getToken());
|
||||
//
|
||||
moveTo(exits, projectInfo);
|
||||
projectInfoService.updateItem(exits);
|
||||
return JsonMessage.getString(200, "修改成功");
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
return JsonMessage.getString(500, e.getMessage());
|
||||
@ -250,52 +230,7 @@ public class EditProjectController extends BaseController {
|
||||
* @param exits 项目
|
||||
*/
|
||||
private void modify(ProjectInfoModel exits) {
|
||||
UserModel userName = getUser();
|
||||
exits.logModifyUser(userName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证lib 暂时用情况
|
||||
*
|
||||
* @param id 项目Id
|
||||
* @param newLib 新lib
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "judge_lib.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
public String saveProject(String id, String newLib) {
|
||||
File file = new File(newLib);
|
||||
// 填写的jar路径是一个存在的文件
|
||||
if (file.exists() && file.isFile()) {
|
||||
return JsonMessage.getString(400, "填写jar目录当前是一个已经存在的文件,请修改");
|
||||
}
|
||||
ProjectInfoModel exits = projectInfoService.getItem(id);
|
||||
if (exits == null) {
|
||||
// 创建项目 填写的jar路径是已经存在的文件夹
|
||||
if (file.exists()) {
|
||||
return JsonMessage.getString(401, "填写jar目录当前已经在,创建成功后会自动同步文件");
|
||||
}
|
||||
} else {
|
||||
// 已经存在的项目
|
||||
File oldLib = new File(exits.getLib());
|
||||
Path newPath = file.toPath();
|
||||
Path oldPath = oldLib.toPath();
|
||||
if (newPath.equals(oldPath)) {
|
||||
// 新 旧没有变更
|
||||
return JsonMessage.getString(200, "");
|
||||
}
|
||||
if (file.exists()) {
|
||||
if (oldLib.exists()) {
|
||||
// 新旧jar路径都存在,会自动覆盖新的jar路径中的文件
|
||||
return JsonMessage.getString(401, "原jar目录已经存在并且新的jar目录已经存在,保存将覆盖新文件夹并会自动同步原jar目录");
|
||||
}
|
||||
return JsonMessage.getString(401, "填写jar目录当前已经在,创建成功后会自动同步文件");
|
||||
}
|
||||
}
|
||||
if (Validator.isChinese(newLib)) {
|
||||
return JsonMessage.getString(401, "不建议使用中文目录");
|
||||
}
|
||||
return JsonMessage.getString(200, "");
|
||||
exits.setModifyUser(getUserName());
|
||||
}
|
||||
|
||||
private void moveTo(ProjectInfoModel old, ProjectInfoModel news) {
|
||||
@ -352,4 +287,61 @@ public class EditProjectController extends BaseController {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "deleteProject", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String deleteProject() {
|
||||
ProjectInfoModel projectInfoModel = tryGetProjectInfoModel();
|
||||
if (projectInfoModel == null) {
|
||||
return JsonMessage.getString(200, "项目不存在");
|
||||
}
|
||||
try {
|
||||
// 运行判断
|
||||
if (projectInfoModel.isStatus(true)) {
|
||||
return JsonMessage.getString(401, "不能删除正在运行的项目");
|
||||
}
|
||||
String userId = getUserName();
|
||||
projectInfoService.deleteProject(projectInfoModel, userId);
|
||||
return JsonMessage.getString(200, "删除成功!");
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
return JsonMessage.getString(500, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "judge_lib.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String saveProject(String id, String newLib) {
|
||||
File file = new File(newLib);
|
||||
// 填写的jar路径是一个存在的文件
|
||||
if (file.exists() && file.isFile()) {
|
||||
return JsonMessage.getString(400, "填写jar目录当前是一个已经存在的文件,请修改");
|
||||
}
|
||||
ProjectInfoModel exits = projectInfoService.getItem(id);
|
||||
if (exits == null) {
|
||||
// 创建项目 填写的jar路径是已经存在的文件夹
|
||||
if (file.exists()) {
|
||||
return JsonMessage.getString(401, "填写jar目录当前已经在,创建成功后会自动同步文件");
|
||||
}
|
||||
} else {
|
||||
// 已经存在的项目
|
||||
File oldLib = new File(exits.getLib());
|
||||
Path newPath = file.toPath();
|
||||
Path oldPath = oldLib.toPath();
|
||||
if (newPath.equals(oldPath)) {
|
||||
// 新 旧没有变更
|
||||
return JsonMessage.getString(200, "");
|
||||
}
|
||||
if (file.exists()) {
|
||||
if (oldLib.exists()) {
|
||||
// 新旧jar路径都存在,会自动覆盖新的jar路径中的文件
|
||||
return JsonMessage.getString(401, "原jar目录已经存在并且新的jar目录已经存在,保存将覆盖新文件夹并会自动同步原jar目录");
|
||||
}
|
||||
return JsonMessage.getString(401, "填写jar目录当前已经在,创建成功后会自动同步文件");
|
||||
}
|
||||
}
|
||||
if (Validator.isChinese(newLib)) {
|
||||
return JsonMessage.getString(401, "不建议使用中文目录");
|
||||
}
|
||||
return JsonMessage.getString(200, "");
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.keepbx.jpom.controller.manage.file;
|
||||
package cn.keepbx.jpom.controller.manage;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
@ -8,53 +8,34 @@ import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.jiangzeyin.controller.multipart.MultipartFileBuilder;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.interceptor.ProjectPermission;
|
||||
import cn.keepbx.jpom.common.BaseAgentController;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.service.manage.ProjectInfoService;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
import cn.keepbx.jpom.service.manage.ConsoleService;
|
||||
import cn.keepbx.jpom.socket.CommandOp;
|
||||
import cn.keepbx.jpom.system.AgentConfigBean;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 文件管理
|
||||
* 项目文件管理
|
||||
*
|
||||
* @author Administrator
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/17
|
||||
*/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping(value = "/manage/file/")
|
||||
public class ProjectFileControl extends BaseController {
|
||||
|
||||
public class ProjectFileControl extends BaseAgentController {
|
||||
@Resource
|
||||
private ProjectInfoService projectInfoService;
|
||||
private ConsoleService consoleService;
|
||||
|
||||
/**
|
||||
* 文件管理页面
|
||||
*
|
||||
* @param id 项目id
|
||||
*/
|
||||
@RequestMapping(value = "list.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
public String fileManage(String id) {
|
||||
setAttribute("id", id);
|
||||
return "manage/filemanage";
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出目录下的文件
|
||||
*
|
||||
* @param id 项目id
|
||||
*/
|
||||
@RequestMapping(value = "getFileList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@ProjectPermission
|
||||
public String getFileList(String id) {
|
||||
// 查询项目路径
|
||||
ProjectInfoModel pim = projectInfoService.getItem(id);
|
||||
@ -107,21 +88,15 @@ public class ProjectFileControl extends BaseController {
|
||||
return arrayFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "upload", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@ProjectPermission(checkUpload = true)
|
||||
public String upload() throws Exception {
|
||||
ProjectInfoModel pim = getProjectInfoModel();
|
||||
MultipartFileBuilder multipartFileBuilder = createMultipart()
|
||||
.addFieldName("file");
|
||||
String type = getParameter("type");
|
||||
if ("unzip".equals(type)) {
|
||||
multipartFileBuilder.setSavePath(ConfigBean.getInstance().getTempPathName());
|
||||
multipartFileBuilder.setInputStreamType("zip");
|
||||
multipartFileBuilder.setSavePath(AgentConfigBean.getInstance().getTempPathName());
|
||||
String path = multipartFileBuilder.save();
|
||||
//
|
||||
File lib = new File(pim.getLib());
|
||||
@ -142,17 +117,49 @@ public class ProjectFileControl extends BaseController {
|
||||
// 修改使用状态
|
||||
pim.setUseLibDesc("upload");
|
||||
projectInfoService.updateItem(pim);
|
||||
//
|
||||
String after = getParameter("after");
|
||||
if ("restart".equalsIgnoreCase(after)) {
|
||||
String result = consoleService.execCommand(CommandOp.restart, pim);
|
||||
return JsonMessage.getString(200, "上传成功并重启:" + result);
|
||||
}
|
||||
|
||||
return JsonMessage.getString(200, "上传成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @param id 项目id
|
||||
* @return File
|
||||
*/
|
||||
|
||||
@RequestMapping(value = "deleteFile", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String deleteFile(String filename, String type) {
|
||||
ProjectInfoModel pim = getProjectInfoModel();
|
||||
if ("clear".equalsIgnoreCase(type)) {
|
||||
// 清空文件
|
||||
File file = new File(pim.getLib());
|
||||
if (FileUtil.clean(file)) {
|
||||
return JsonMessage.getString(200, "清除成功");
|
||||
}
|
||||
if (pim.isStatus(true)) {
|
||||
return JsonMessage.getString(501, "文件被占用,请先停止项目");
|
||||
}
|
||||
return JsonMessage.getString(500, "删除失败:" + file.getAbsolutePath());
|
||||
} else {
|
||||
// 删除文件
|
||||
String fileName = pathSafe(filename);
|
||||
if (StrUtil.isEmpty(fileName)) {
|
||||
return JsonMessage.getString(405, "非法操作");
|
||||
}
|
||||
File file = FileUtil.file(pim.getLib(), fileName);
|
||||
if (file.exists()) {
|
||||
if (FileUtil.del(file)) {
|
||||
return JsonMessage.getString(200, "删除成功");
|
||||
}
|
||||
} else {
|
||||
return JsonMessage.getString(404, "文件不存在");
|
||||
}
|
||||
return JsonMessage.getString(500, "删除失败");
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "download", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public String download(String id, String filename) {
|
||||
filename = pathSafe(filename);
|
||||
if (StrUtil.isEmpty(filename)) {
|
||||
@ -171,51 +178,4 @@ public class ProjectFileControl extends BaseController {
|
||||
}
|
||||
return "下载失败。请刷新页面后重试";
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除文件
|
||||
*
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "clear", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@ProjectPermission(checkDelete = true)
|
||||
public String clear() {
|
||||
ProjectInfoModel pim = getProjectInfoModel();
|
||||
File file = new File(pim.getLib());
|
||||
if (FileUtil.clean(file)) {
|
||||
return JsonMessage.getString(200, "清除成功");
|
||||
}
|
||||
if (pim.isStatus(true)) {
|
||||
return JsonMessage.getString(501, "文件被占用,请先停止项目");
|
||||
}
|
||||
return JsonMessage.getString(500, "删除失败:" + file.getAbsolutePath());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param filename 文件名称
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "deleteFile", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@ProjectPermission(checkDelete = true)
|
||||
public String deleteFile(String filename) {
|
||||
String fileName = pathSafe(filename);
|
||||
if (StrUtil.isEmpty(fileName)) {
|
||||
return JsonMessage.getString(405, "非法操作");
|
||||
}
|
||||
ProjectInfoModel pim = getProjectInfoModel();
|
||||
File file = FileUtil.file(pim.getLib(), fileName);
|
||||
if (file.exists()) {
|
||||
if (FileUtil.del(file)) {
|
||||
return JsonMessage.getString(200, "删除成功");
|
||||
}
|
||||
} else {
|
||||
return JsonMessage.getString(404, "文件不存在");
|
||||
}
|
||||
return JsonMessage.getString(500, "删除失败");
|
||||
}
|
||||
}
|
@ -3,59 +3,124 @@ package cn.keepbx.jpom.controller.manage;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.Role;
|
||||
import cn.keepbx.jpom.common.BaseAgentController;
|
||||
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
|
||||
import cn.keepbx.jpom.common.interceptor.ProjectPermission;
|
||||
import cn.keepbx.jpom.common.interceptor.UrlPermission;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.model.data.UserModel;
|
||||
import cn.keepbx.jpom.service.manage.ProjectInfoService;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 项目管理
|
||||
* 管理的信息获取接口
|
||||
*
|
||||
* @author Administrator
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping(value = "/manage/")
|
||||
public class ProjectManageControl extends BaseController {
|
||||
|
||||
@Resource
|
||||
private ProjectInfoService projectInfoService;
|
||||
public class ProjectListController extends BaseAgentController {
|
||||
|
||||
/**
|
||||
* 展示项目页面
|
||||
* 获取项目的信息
|
||||
*
|
||||
* @return page
|
||||
* @param id id
|
||||
* @return item
|
||||
* @see ProjectInfoModel
|
||||
*/
|
||||
@RequestMapping(value = "projectInfo", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
public String projectInfo() {
|
||||
HashSet hashSet = projectInfoService.getAllGroup();
|
||||
setAttribute("groups", hashSet);
|
||||
return "manage/projectInfo";
|
||||
@RequestMapping(value = "getProjectItem", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String getProjectItem(String id) {
|
||||
return JsonMessage.getString(200, "", projectInfoService.getItem(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取正在运行的项目的端口和进程id
|
||||
* 获取所有的分组
|
||||
*
|
||||
* @param ids ids
|
||||
* @return array
|
||||
*/
|
||||
@RequestMapping(value = "getProjectGroup", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String getProjectGroup() {
|
||||
HashSet<String> strings = projectInfoService.getAllGroup();
|
||||
return JsonMessage.getString(200, "", strings);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目的进程id
|
||||
*
|
||||
* @param id 项目id
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "getProjectStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String getProjectStatus(String id) {
|
||||
if (StrUtil.isEmpty(id)) {
|
||||
return JsonMessage.getString(405, "项目id 不正确");
|
||||
}
|
||||
int pid = 0;
|
||||
try {
|
||||
pid = AbstractProjectCommander.getInstance().getPid(id);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error("获取项目pid 失败", e);
|
||||
}
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("pId", pid);
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 程序项目信息
|
||||
*
|
||||
* @param group 分组
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "getProjectInfo", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String getProjectInfo(String group, String notStatus) {
|
||||
try {
|
||||
boolean status = StrUtil.isEmpty(notStatus);
|
||||
// 查询数据
|
||||
List<ProjectInfoModel> projectInfoModels = projectInfoService.list();
|
||||
// 转换为数据
|
||||
JSONArray array = new JSONArray();
|
||||
for (ProjectInfoModel projectInfoModel : projectInfoModels) {
|
||||
if (StrUtil.isNotEmpty(group) && !group.equals(projectInfoModel.getGroup())) {
|
||||
continue;
|
||||
}
|
||||
JSONObject object = projectInfoModel.toJson();
|
||||
if (status) {
|
||||
object.put("status", projectInfoModel.isStatus(true));
|
||||
}
|
||||
array.add(object);
|
||||
}
|
||||
array.sort((oo1, oo2) -> {
|
||||
JSONObject o1 = (JSONObject) oo1;
|
||||
JSONObject o2 = (JSONObject) oo2;
|
||||
String group1 = o1.getString("group");
|
||||
String group2 = o2.getString("group");
|
||||
if (group1 == null || group2 == null) {
|
||||
return -1;
|
||||
}
|
||||
return group1.compareTo(group2);
|
||||
});
|
||||
return JsonMessage.getString(200, "查询成功!", array);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
return JsonMessage.getString(500, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目的运行端口
|
||||
*
|
||||
* @param ids ids
|
||||
* @return obj
|
||||
*/
|
||||
@RequestMapping(value = "getProjectPort", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
public String getProjectPort(String ids) {
|
||||
public String getProjectGroup(String ids) {
|
||||
if (StrUtil.isEmpty(ids)) {
|
||||
return JsonMessage.getString(400, "");
|
||||
}
|
||||
@ -83,76 +148,14 @@ public class ProjectManageControl extends BaseController {
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有项目
|
||||
*
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "getProjectInfo", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
public String getProjectInfo(String group) {
|
||||
try {
|
||||
UserModel userName = getUser();
|
||||
// 查询数据
|
||||
List<ProjectInfoModel> projectInfoModels = projectInfoService.list();
|
||||
// 转换为数据
|
||||
JSONArray array = new JSONArray();
|
||||
for (ProjectInfoModel projectInfoModel : projectInfoModels) {
|
||||
if (StrUtil.isNotEmpty(group) && !group.equals(projectInfoModel.getGroup())) {
|
||||
continue;
|
||||
}
|
||||
String id = projectInfoModel.getId();
|
||||
JSONObject object = projectInfoModel.toJson();
|
||||
object.put("manager", userName.isProject(id));
|
||||
object.put("status", projectInfoModel.isStatus(true));
|
||||
array.add(object);
|
||||
}
|
||||
array.sort((oo1, oo2) -> {
|
||||
JSONObject o1 = (JSONObject) oo1;
|
||||
JSONObject o2 = (JSONObject) oo2;
|
||||
String group1 = o1.getString("group");
|
||||
String group2 = o2.getString("group");
|
||||
if (group1 == null || group2 == null) {
|
||||
return -1;
|
||||
}
|
||||
return group1.compareTo(group2);
|
||||
});
|
||||
return JsonMessage.getString(200, "查询成功!", array);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
return JsonMessage.getString(500, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除项目
|
||||
*
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "deleteProject", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@ProjectPermission
|
||||
@UrlPermission(Role.Manage)
|
||||
public String deleteProject() {
|
||||
ProjectInfoModel projectInfoModel = getProjectInfoModel();
|
||||
UserModel userModel = getUser();
|
||||
try {
|
||||
// 运行判断
|
||||
if (projectInfoModel.isStatus(true)) {
|
||||
return JsonMessage.getString(401, "不能删除正在运行的项目");
|
||||
}
|
||||
String userId;
|
||||
if (userModel.isSystemUser()) {
|
||||
userId = UserModel.SYSTEM_OCCUPY_NAME;
|
||||
} else {
|
||||
userId = userModel.getId();
|
||||
}
|
||||
projectInfoService.deleteProject(projectInfoModel, userId);
|
||||
return JsonMessage.getString(200, "删除成功!");
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
return JsonMessage.getString(500, e.getMessage());
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * 获取运行方式
|
||||
// *
|
||||
// * @return array
|
||||
// */
|
||||
// @RequestMapping(value = "getRunModes", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
// public String getRunModes() {
|
||||
// ProjectInfoModel.RunMode[] runModes = ProjectInfoModel.RunMode.values();
|
||||
// return JsonMessage.getString(200, "", runModes);
|
||||
// }
|
||||
}
|
@ -1,50 +1,38 @@
|
||||
package cn.keepbx.jpom.controller.manage.recover;
|
||||
package cn.keepbx.jpom.controller.manage;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.BaseJpomController;
|
||||
import cn.keepbx.jpom.model.data.ProjectRecoverModel;
|
||||
import cn.keepbx.jpom.model.data.UserModel;
|
||||
import cn.keepbx.jpom.service.manage.ProjectRecoverService;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 项目管理
|
||||
* 回收站管理
|
||||
*
|
||||
* @author Administrator
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping(value = "/manage/recover")
|
||||
public class ProjectRecoverControl extends BaseController {
|
||||
|
||||
public class ProjectRecoverControl extends BaseJpomController {
|
||||
@Resource
|
||||
private ProjectRecoverService projectRecoverService;
|
||||
|
||||
/**
|
||||
* 展示项目页面
|
||||
*
|
||||
* @return page
|
||||
*/
|
||||
@RequestMapping(value = "list.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
@RequestMapping(value = "list_data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String projectInfo() {
|
||||
UserModel userModel = getUser();
|
||||
if (userModel.isManage()) {
|
||||
List<ProjectRecoverModel> projectInfoModels = projectRecoverService.list();
|
||||
setAttribute("array", projectInfoModels);
|
||||
}
|
||||
return "manage/project_recover";
|
||||
List<ProjectRecoverModel> projectInfoModels = projectRecoverService.list();
|
||||
return JsonMessage.getString(200, "", projectInfoModels);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "data.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@RequestMapping(value = "item_data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String project(String id) throws IOException {
|
||||
if (StrUtil.isEmpty(id)) {
|
||||
return JsonMessage.getString(400, "项目id错误");
|
||||
@ -52,5 +40,4 @@ public class ProjectRecoverControl extends BaseController {
|
||||
ProjectRecoverModel item = projectRecoverService.getItem(id);
|
||||
return JsonMessage.getString(200, "", item);
|
||||
}
|
||||
|
||||
}
|
@ -5,72 +5,78 @@ import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.BaseAgentController;
|
||||
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
|
||||
import cn.keepbx.jpom.common.interceptor.ProjectPermission;
|
||||
import cn.keepbx.jpom.controller.manage.file.ProjectFileControl;
|
||||
import cn.keepbx.jpom.controller.manage.ProjectFileControl;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.service.manage.ProjectInfoService;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 控制台日志备份管理
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/3/7
|
||||
* @date 2019/4/17
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping(value = "/manage/log")
|
||||
public class LogBackController extends BaseController {
|
||||
@Resource
|
||||
private ProjectInfoService projectInfoService;
|
||||
@RestController
|
||||
@RequestMapping(value = "manage/log")
|
||||
public class LogBackController extends BaseAgentController {
|
||||
|
||||
@RequestMapping(value = "export.html", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
@ProjectPermission
|
||||
public String export() {
|
||||
ProjectInfoModel pim = getProjectInfoModel();
|
||||
File file = new File(pim.getLog());
|
||||
if (!file.exists()) {
|
||||
return JsonMessage.getString(400, "没有日志文件:" + file.getPath());
|
||||
}
|
||||
HttpServletResponse response = getResponse();
|
||||
ServletUtil.write(response, file);
|
||||
return JsonMessage.getString(200, "");
|
||||
@RequestMapping(value = "logSize", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String logSize(String id) {
|
||||
ProjectInfoModel projectInfoModel = getProjectInfoModel();
|
||||
//获取日志备份路径
|
||||
File logBack = projectInfoModel.getLogBack();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
boolean logBackBool = logBack.exists() && logBack.isDirectory();
|
||||
jsonObject.put("logBack", logBackBool);
|
||||
String info = projectInfoService.getLogSize(id);
|
||||
jsonObject.put("logSize", info);
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "logBack", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
public String console(String id) {
|
||||
// 查询项目路径
|
||||
ProjectInfoModel pim = projectInfoService.getItem(id);
|
||||
if (pim != null) {
|
||||
File logBack = pim.getLogBack();
|
||||
if (logBack.exists() && logBack.isDirectory()) {
|
||||
File[] filesAll = logBack.listFiles();
|
||||
if (filesAll != null) {
|
||||
JSONArray jsonArray = ProjectFileControl.parseInfo(filesAll, true);
|
||||
setAttribute("array", jsonArray);
|
||||
}
|
||||
@RequestMapping(value = "resetLog", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String resetLog() {
|
||||
ProjectInfoModel pim = getProjectInfoModel();
|
||||
try {
|
||||
String msg = AbstractProjectCommander.getInstance().backLog(pim);
|
||||
if (msg.contains("ok")) {
|
||||
return JsonMessage.getString(200, "重置成功");
|
||||
}
|
||||
setAttribute("id", pim.getId());
|
||||
setAttribute("logPath", pim.getLog());
|
||||
setAttribute("logBackPath", logBack.getAbsolutePath());
|
||||
return JsonMessage.getString(201, "重置失败:" + msg);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
return JsonMessage.getString(500, "重置日志失败");
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "logBack_delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String clear(String name) {
|
||||
name = pathSafe(name);
|
||||
if (StrUtil.isEmpty(name)) {
|
||||
return JsonMessage.getString(405, "非法操作:" + name);
|
||||
}
|
||||
ProjectInfoModel pim = getProjectInfoModel();
|
||||
File logBack = pim.getLogBack();
|
||||
if (logBack.exists() && logBack.isDirectory()) {
|
||||
logBack = FileUtil.file(logBack, name);
|
||||
if (logBack.exists()) {
|
||||
FileUtil.del(logBack);
|
||||
return JsonMessage.getString(200, "删除成功");
|
||||
}
|
||||
return JsonMessage.getString(500, "没有对应文件");
|
||||
} else {
|
||||
return JsonMessage.getString(500, "没有对应文件夹");
|
||||
}
|
||||
return "manage/logBack";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "logBack_download", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
@ProjectPermission
|
||||
public String download(String key) {
|
||||
key = pathSafe(key);
|
||||
if (StrUtil.isEmpty(key)) {
|
||||
@ -91,58 +97,36 @@ public class LogBackController extends BaseController {
|
||||
return "下载失败。请刷新页面后重试";
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "logBack_delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@ProjectPermission(checkDelete = true)
|
||||
public String clear(String name) {
|
||||
name = pathSafe(name);
|
||||
if (StrUtil.isEmpty(name)) {
|
||||
return JsonMessage.getString(405, "非法操作:" + name);
|
||||
}
|
||||
@RequestMapping(value = "logBack", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String console() {
|
||||
// 查询项目路径
|
||||
ProjectInfoModel pim = getProjectInfoModel();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
|
||||
File logBack = pim.getLogBack();
|
||||
if (logBack.exists() && logBack.isDirectory()) {
|
||||
logBack = FileUtil.file(logBack, name);
|
||||
if (logBack.exists()) {
|
||||
FileUtil.del(logBack);
|
||||
return JsonMessage.getString(200, "删除成功");
|
||||
File[] filesAll = logBack.listFiles();
|
||||
if (filesAll != null) {
|
||||
JSONArray jsonArray = ProjectFileControl.parseInfo(filesAll, true);
|
||||
jsonObject.put("array", jsonArray);
|
||||
}
|
||||
return JsonMessage.getString(500, "没有对应文件");
|
||||
} else {
|
||||
return JsonMessage.getString(500, "没有对应文件夹");
|
||||
}
|
||||
jsonObject.put("id", pim.getId());
|
||||
jsonObject.put("logPath", pim.getLog());
|
||||
jsonObject.put("logBackPath", logBack.getAbsolutePath());
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "logSize", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@RequestMapping(value = "export.html", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public String logSize(String id) {
|
||||
String info = projectInfoService.getLogSize(id);
|
||||
if (info != null) {
|
||||
return JsonMessage.getString(200, "ok", info);
|
||||
}
|
||||
return JsonMessage.getString(500, "获取日志大小失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置日志
|
||||
*
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "resetLog", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@ProjectPermission
|
||||
public String resetLog() {
|
||||
public String export() {
|
||||
ProjectInfoModel pim = getProjectInfoModel();
|
||||
try {
|
||||
String msg = AbstractProjectCommander.getInstance().backLog(pim);
|
||||
if (msg.contains("ok")) {
|
||||
return JsonMessage.getString(200, "重置成功");
|
||||
}
|
||||
return JsonMessage.getString(201, "重置失败:" + msg);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
return JsonMessage.getString(500, "重置日志失败");
|
||||
File file = new File(pim.getLog());
|
||||
if (!file.exists()) {
|
||||
return JsonMessage.getString(400, "没有日志文件:" + file.getPath());
|
||||
}
|
||||
HttpServletResponse response = getResponse();
|
||||
ServletUtil.write(response, file);
|
||||
return JsonMessage.getString(200, "");
|
||||
}
|
||||
}
|
@ -4,21 +4,21 @@ import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.BaseAgentController;
|
||||
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
|
||||
import cn.keepbx.jpom.common.commander.AbstractSystemCommander;
|
||||
import cn.keepbx.jpom.model.system.NetstatModel;
|
||||
import cn.keepbx.jpom.model.system.ProcessModel;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
import cn.keepbx.jpom.system.AgentConfigBean;
|
||||
import cn.keepbx.jpom.util.CommandUtil;
|
||||
import cn.keepbx.jpom.util.JvmUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
@ -32,27 +32,28 @@ import java.util.List;
|
||||
*
|
||||
* @author Administrator
|
||||
*/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping(value = "/manage/")
|
||||
public class InternalController extends BaseController {
|
||||
public class InternalController extends BaseAgentController {
|
||||
|
||||
/**
|
||||
* 获取内存信息
|
||||
*/
|
||||
@RequestMapping(value = "internal", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
@RequestMapping(value = "internal_data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String getInternal(String tag) throws Exception {
|
||||
setAttribute("tag", tag);
|
||||
int pid = AbstractProjectCommander.getInstance().getPid(tag);
|
||||
if (pid > 0) {
|
||||
ProcessModel item = AbstractSystemCommander.getInstance().getPidInfo(pid);
|
||||
setAttribute("item", item);
|
||||
JSONObject beanMem = getBeanMem(tag);
|
||||
setAttribute("beanMem", beanMem);
|
||||
//获取端口信息
|
||||
List<NetstatModel> port = AbstractProjectCommander.getInstance().listNetstat(pid);
|
||||
setAttribute("port", port);
|
||||
if (pid <= 0) {
|
||||
return JsonMessage.getString(400, "");
|
||||
}
|
||||
return "manage/internal";
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
ProcessModel item = AbstractSystemCommander.getInstance().getPidInfo(pid);
|
||||
jsonObject.put("process", item);
|
||||
JSONObject beanMem = getBeanMem(tag);
|
||||
jsonObject.put("beanMem", beanMem);
|
||||
//获取端口信息
|
||||
List<NetstatModel> netstatModels = AbstractProjectCommander.getInstance().listNetstat(pid);
|
||||
jsonObject.put("netstat", netstatModels);
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,10 +107,10 @@ public class InternalController extends BaseController {
|
||||
/**
|
||||
* 导出堆栈信息
|
||||
*/
|
||||
@RequestMapping(value = "stack", method = RequestMethod.GET)
|
||||
@RequestMapping(value = "internal_stack", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public String stack(String tag) throws Exception {
|
||||
String fileName = ConfigBean.getInstance().getTempPathName() + "/" + tag + "_java_cpu.txt";
|
||||
String fileName = AgentConfigBean.getInstance().getTempPathName() + "/" + tag + "_java_cpu.txt";
|
||||
fileName = FileUtil.normalize(fileName);
|
||||
try {
|
||||
int pid = AbstractProjectCommander.getInstance().getPid(tag);
|
||||
@ -121,7 +122,7 @@ public class InternalController extends BaseController {
|
||||
downLoad(getResponse(), fileName);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
getResponse().sendRedirect("internal?tag=" + tag);
|
||||
// getResponse().sendRedirect("internal?tag=" + tag);
|
||||
}
|
||||
return JsonMessage.getString(200, "");
|
||||
}
|
||||
@ -129,10 +130,10 @@ public class InternalController extends BaseController {
|
||||
/**
|
||||
* 导出内存信息
|
||||
*/
|
||||
@RequestMapping(value = "ram", method = RequestMethod.GET)
|
||||
@RequestMapping(value = "internal_ram", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public String ram(String tag) throws Exception {
|
||||
String fileName = ConfigBean.getInstance().getTempPathName() + "/" + tag + "_java_ram.txt";
|
||||
String fileName = AgentConfigBean.getInstance().getTempPathName() + "/" + tag + "_java_ram.txt";
|
||||
fileName = FileUtil.normalize(fileName);
|
||||
try {
|
||||
int pid = AbstractProjectCommander.getInstance().getPid(tag);
|
||||
@ -144,7 +145,7 @@ public class InternalController extends BaseController {
|
||||
downLoad(getResponse(), fileName);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
getResponse().sendRedirect("internal?tag=" + tag);
|
||||
// getResponse().sendRedirect("internal?tag=" + tag);
|
||||
}
|
||||
return JsonMessage.getString(200, "");
|
||||
}
|
@ -2,39 +2,30 @@ package cn.keepbx.jpom.controller.system;
|
||||
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.Role;
|
||||
import cn.keepbx.jpom.common.interceptor.UrlPermission;
|
||||
import cn.keepbx.jpom.common.BaseAgentController;
|
||||
import cn.keepbx.jpom.service.oss.OssManagerService;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyun.oss.OSSClient;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 阿里云oss 配置
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/3/5
|
||||
* @date 2019/4/17
|
||||
*/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping(value = "/system")
|
||||
public class AliOssController extends BaseController {
|
||||
public class AliOssController extends BaseAgentController {
|
||||
@Resource
|
||||
private OssManagerService ossManagerService;
|
||||
|
||||
/**
|
||||
* 页面
|
||||
*/
|
||||
@RequestMapping(value = "alioss", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
@RequestMapping(value = "alioss_config", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String whitelistDirectory() {
|
||||
setAttribute("item", ossManagerService.getConfig());
|
||||
return "system/alioss";
|
||||
return JsonMessage.getString(200, "", ossManagerService.getConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,8 +39,6 @@ public class AliOssController extends BaseController {
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "alioss_submit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@UrlPermission(Role.System)
|
||||
public String aliOssSubmit(String endpoint, String accessKeyId, String accessKeySecret, String bucketName, String keyPrefix) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("endpoint", endpoint);
|
@ -1,4 +1,4 @@
|
||||
package cn.keepbx.jpom.controller.system.ssl;
|
||||
package cn.keepbx.jpom.controller.system;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.Validator;
|
||||
@ -8,22 +8,17 @@ import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.jiangzeyin.controller.multipart.MultipartFileBuilder;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.Role;
|
||||
import cn.keepbx.jpom.common.interceptor.UrlPermission;
|
||||
import cn.keepbx.jpom.common.BaseAgentController;
|
||||
import cn.keepbx.jpom.model.data.CertModel;
|
||||
import cn.keepbx.jpom.model.data.UserModel;
|
||||
import cn.keepbx.jpom.service.WhitelistDirectoryService;
|
||||
import cn.keepbx.jpom.service.system.CertService;
|
||||
import cn.keepbx.jpom.service.system.WhitelistDirectoryService;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import cn.keepbx.jpom.system.AgentConfigBean;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
@ -39,22 +34,15 @@ import java.util.zip.ZipFile;
|
||||
*
|
||||
* @author Arno
|
||||
*/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping(value = "/system/certificate")
|
||||
public class CertificateController extends BaseController {
|
||||
public class CertificateController extends BaseAgentController {
|
||||
|
||||
@Resource
|
||||
private CertService certService;
|
||||
@Resource
|
||||
private WhitelistDirectoryService whitelistDirectoryService;
|
||||
|
||||
@RequestMapping(value = "/list.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
public String certificate() {
|
||||
JSONArray jsonArray = whitelistDirectoryService.getCertificateDirectory();
|
||||
setAttribute("certificate", jsonArray);
|
||||
return "system/certificate";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存证书
|
||||
@ -62,8 +50,6 @@ public class CertificateController extends BaseController {
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "/saveCertificate", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@UrlPermission(Role.Manage)
|
||||
public String saveCertificate() {
|
||||
String data = getParameter("data");
|
||||
JSONObject jsonObject = JSONObject.parseObject(data);
|
||||
@ -110,7 +96,7 @@ public class CertificateController extends BaseController {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error("证书文件", e);
|
||||
return JsonMessage.getString(400, e.getMessage());
|
||||
return JsonMessage.getString(400, "解析证书文件失败:" + e.getMessage());
|
||||
}
|
||||
return JsonMessage.getString(200, "提交成功");
|
||||
}
|
||||
@ -148,7 +134,7 @@ public class CertificateController extends BaseController {
|
||||
String certPath = null;
|
||||
String pemPath = null, keyPath = null;
|
||||
try {
|
||||
String path = ConfigBean.getInstance().getTempPathName();
|
||||
String path = AgentConfigBean.getInstance().getTempPathName();
|
||||
MultipartFileBuilder cert = createMultipart().addFieldName("file").setSavePath(path);
|
||||
certPath = cert.save();
|
||||
ZipFile zipFile = new ZipFile(certPath);
|
||||
@ -165,6 +151,13 @@ public class CertificateController extends BaseController {
|
||||
FileUtil.writeFromStream(inputStream, filePathItem);
|
||||
pemPath = filePathItem;
|
||||
}
|
||||
// cer 文件
|
||||
if (pemPath == null && StrUtil.endWith(keyName, ".cer", true)) {
|
||||
String filePathItem = String.format("%s/%s/%s", path, certModel.getId(), keyName);
|
||||
InputStream inputStream = zipFile.getInputStream(zipEntry);
|
||||
FileUtil.writeFromStream(inputStream, filePathItem);
|
||||
pemPath = filePathItem;
|
||||
}
|
||||
//
|
||||
if (keyPath == null && StrUtil.endWith(keyName, ".key", true)) {
|
||||
String filePathItem = String.format("%s/%s/%s", path, certModel.getId(), keyName);
|
||||
@ -231,8 +224,6 @@ public class CertificateController extends BaseController {
|
||||
* 证书列表
|
||||
*/
|
||||
@RequestMapping(value = "/getCertList", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@UrlPermission(Role.Manage)
|
||||
public String getCertList() {
|
||||
List<CertModel> array = certService.list();
|
||||
return JsonMessage.getString(200, "", array);
|
||||
@ -245,14 +236,11 @@ public class CertificateController extends BaseController {
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "/delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@UrlPermission(Role.System)
|
||||
public String delete(String id) {
|
||||
if (StrUtil.isEmpty(id)) {
|
||||
return JsonMessage.getString(400, "删除失败");
|
||||
}
|
||||
UserModel userModel = getUser();
|
||||
if (!userModel.isSystemUser()) {
|
||||
if (!isSystemUser()) {
|
||||
return JsonMessage.getString(400, "你没有操作权限");
|
||||
}
|
||||
boolean b = certService.delete(id);
|
||||
@ -267,8 +255,6 @@ public class CertificateController extends BaseController {
|
||||
* 导出证书
|
||||
*/
|
||||
@RequestMapping(value = "/export", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@UrlPermission(Role.Manage)
|
||||
public String export(String id) {
|
||||
CertModel item = certService.getItem(id);
|
||||
if (null == item) {
|
@ -1,18 +1,13 @@
|
||||
package cn.keepbx.jpom.controller.system.nginx;
|
||||
package cn.keepbx.jpom.controller.system;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.Role;
|
||||
import cn.keepbx.jpom.common.interceptor.UrlPermission;
|
||||
import cn.keepbx.jpom.model.data.CertModel;
|
||||
import cn.keepbx.jpom.model.data.UserModel;
|
||||
import cn.keepbx.jpom.service.system.CertService;
|
||||
import cn.keepbx.jpom.common.BaseAgentController;
|
||||
import cn.keepbx.jpom.service.WhitelistDirectoryService;
|
||||
import cn.keepbx.jpom.service.system.NginxService;
|
||||
import cn.keepbx.jpom.service.system.WhitelistDirectoryService;
|
||||
import cn.keepbx.jpom.util.CommandUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
@ -21,10 +16,10 @@ import com.github.odiszapc.nginxparser.NgxConfig;
|
||||
import com.github.odiszapc.nginxparser.NgxEntry;
|
||||
import com.github.odiszapc.nginxparser.NgxParam;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
@ -34,64 +29,53 @@ import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* nginx 管理
|
||||
* nginx 列表
|
||||
*
|
||||
* @author Arno
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/17
|
||||
*/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping("/system/nginx")
|
||||
public class NginxController extends BaseController {
|
||||
|
||||
|
||||
@Resource
|
||||
private WhitelistDirectoryService whitelistDirectoryService;
|
||||
@Resource
|
||||
private CertService certService;
|
||||
public class NginxController extends BaseAgentController {
|
||||
|
||||
@Resource
|
||||
private NginxService nginxService;
|
||||
|
||||
@RequestMapping(value = "list.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
public String ngx() {
|
||||
JSONArray ngxDirectory = whitelistDirectoryService.getNgxDirectory();
|
||||
setAttribute("nginx", ngxDirectory);
|
||||
List<CertModel> certList = certService.list();
|
||||
setAttribute("cert", certList);
|
||||
return "system/nginx";
|
||||
}
|
||||
@Resource
|
||||
private WhitelistDirectoryService whitelistDirectoryService;
|
||||
|
||||
/**
|
||||
* 配置列表
|
||||
*/
|
||||
@RequestMapping(value = "list_data.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@UrlPermission(Role.Manage)
|
||||
public String list() {
|
||||
JSONArray array = nginxService.list();
|
||||
return JsonMessage.getString(200, "", array);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "item.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
public String setting(String path, String name, String type) {
|
||||
JSONArray ngxDirectory = whitelistDirectoryService.getNgxDirectory();
|
||||
setAttribute("nginx", ngxDirectory);
|
||||
List<CertModel> certList = certService.list();
|
||||
setAttribute("cert", certList);
|
||||
setAttribute("type", type);
|
||||
name = pathSafe(name);
|
||||
if (StrUtil.isNotEmpty(path) && whitelistDirectoryService.checkNgxDirectory(path)) {
|
||||
File file = FileUtil.file(path, name);
|
||||
/**
|
||||
* 获取配置文件信息页面
|
||||
*
|
||||
* @param path 白名单路径
|
||||
* @param name 名称
|
||||
* @return 页面
|
||||
*/
|
||||
@RequestMapping(value = "item_data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String itemData(String path, String name) {
|
||||
String newName = pathSafe(name);
|
||||
if (whitelistDirectoryService.checkNgxDirectory(path)) {
|
||||
File file = FileUtil.file(path, newName);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
String string = FileUtil.readUtf8String(file);
|
||||
jsonObject.put("context", string);
|
||||
jsonObject.put("name", nginxService.paresName(path, file.getAbsolutePath()));
|
||||
jsonObject.put("whitePath", path);
|
||||
setAttribute("data", jsonObject);
|
||||
return JsonMessage.getString(200, "", jsonObject);
|
||||
// setAttribute("data", jsonObject);
|
||||
}
|
||||
return "system/nginxSetting";
|
||||
return JsonMessage.getString(400, "错误");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 新增或修改配置
|
||||
*
|
||||
@ -100,7 +84,6 @@ public class NginxController extends BaseController {
|
||||
*/
|
||||
@RequestMapping(value = "updateNgx", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@UrlPermission(Role.Manage)
|
||||
public String updateNgx(String name, String whitePath, String context, String genre) {
|
||||
if (StrUtil.isEmpty(name)) {
|
||||
return JsonMessage.getString(400, "请填写文件名");
|
||||
@ -186,7 +169,7 @@ public class NginxController extends BaseController {
|
||||
* @return false 不正确
|
||||
*/
|
||||
private boolean checkRootRole(NgxBlock ngxBlock) {
|
||||
UserModel userModel = getUser();
|
||||
// UserModel userModel = getUser();
|
||||
List<NgxEntry> locationAll = ngxBlock.findAll(NgxBlock.class, "location");
|
||||
if (locationAll != null) {
|
||||
for (NgxEntry ngxEntry1 : locationAll) {
|
||||
@ -195,7 +178,7 @@ public class NginxController extends BaseController {
|
||||
if (locationMain == null) {
|
||||
locationMain = ngxBlock1.findParam("alias");
|
||||
}
|
||||
if (locationMain != null && !userModel.isSystemUser()) {
|
||||
if (locationMain != null && !isSystemUser()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -210,7 +193,6 @@ public class NginxController extends BaseController {
|
||||
*/
|
||||
@RequestMapping(value = "delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@UrlPermission(Role.Manage)
|
||||
public String delete(String path, String name) {
|
||||
if (!whitelistDirectoryService.checkNgxDirectory(path)) {
|
||||
return JsonMessage.getString(400, "非法操作");
|
||||
@ -230,5 +212,4 @@ public class NginxController extends BaseController {
|
||||
String msg = this.reloadNginx();
|
||||
return JsonMessage.getString(200, "删除成功" + msg);
|
||||
}
|
||||
|
||||
}
|
@ -3,59 +3,36 @@ package cn.keepbx.jpom.controller.system;
|
||||
import cn.hutool.core.text.StrSpliter;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.Role;
|
||||
import cn.keepbx.jpom.common.interceptor.UrlPermission;
|
||||
import cn.keepbx.jpom.service.system.WhitelistDirectoryService;
|
||||
import cn.keepbx.jpom.system.ExtConfigBean;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import cn.keepbx.jpom.common.BaseJpomController;
|
||||
import cn.keepbx.jpom.model.data.AgentWhitelist;
|
||||
import cn.keepbx.jpom.service.WhitelistDirectoryService;
|
||||
import cn.keepbx.jpom.system.AgentExtConfigBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 白名单目录
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/2/28
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping(value = "/system")
|
||||
public class WhitelistDirectoryController extends BaseController {
|
||||
public class WhitelistDirectoryController extends BaseJpomController {
|
||||
|
||||
@Resource
|
||||
private WhitelistDirectoryService whitelistDirectoryService;
|
||||
|
||||
/**
|
||||
* 页面
|
||||
*/
|
||||
@RequestMapping(value = "whitelistDirectory", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
|
||||
public String whitelistDirectory() {
|
||||
JSONArray jsonArray = whitelistDirectoryService.getProjectDirectory();
|
||||
setAttribute("project", whitelistDirectoryService.convertToLine(jsonArray));
|
||||
//
|
||||
jsonArray = whitelistDirectoryService.getCertificateDirectory();
|
||||
setAttribute("certificate", whitelistDirectoryService.convertToLine(jsonArray));
|
||||
jsonArray = whitelistDirectoryService.getNgxDirectory();
|
||||
setAttribute("nginx", whitelistDirectoryService.convertToLine(jsonArray));
|
||||
return "system/whitelistDirectory";
|
||||
@RequestMapping(value = "whitelistDirectory_data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public String whiteListDirectoryData() {
|
||||
AgentWhitelist agentWhitelist = whitelistDirectoryService.getWhitelist();
|
||||
return JsonMessage.getString(200, "", agentWhitelist);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存接口
|
||||
*
|
||||
* @param project 项目
|
||||
* @param certificate 证书
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "whitelistDirectory_submit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@ResponseBody
|
||||
@UrlPermission(Role.System)
|
||||
public String whitelistDirectorySubmit(String project, String certificate, String nginx) {
|
||||
//
|
||||
List<String> certificateList = null;
|
||||
@ -72,11 +49,10 @@ public class WhitelistDirectoryController extends BaseController {
|
||||
return JsonMessage.getString(401, "nginx路径白名单不能为空");
|
||||
}
|
||||
}
|
||||
JsonMessage jsonMessage = save(project, certificateList, nList);
|
||||
return jsonMessage.toString();
|
||||
return save(project, certificateList, nList).toString();
|
||||
}
|
||||
|
||||
public JsonMessage save(String project, List<String> certificate, List<String> nginx) {
|
||||
private JsonMessage save(String project, List<String> certificate, List<String> nginx) {
|
||||
if (StrUtil.isEmpty(project)) {
|
||||
return new JsonMessage(401, "项目路径白名单不能为空");
|
||||
}
|
||||
@ -87,10 +63,11 @@ public class WhitelistDirectoryController extends BaseController {
|
||||
return save(list, certificate, nginx);
|
||||
}
|
||||
|
||||
|
||||
private JsonMessage save(List<String> projects, List<String> certificate, List<String> nginx) {
|
||||
JSONArray projectArray;
|
||||
List<String> projectArray;
|
||||
{
|
||||
projectArray = covertToArray(projects);
|
||||
projectArray = AgentWhitelist.covertToArray(projects);
|
||||
if (projectArray == null) {
|
||||
return new JsonMessage(401, "项目路径白名单不能位于Jpom目录下");
|
||||
}
|
||||
@ -102,9 +79,9 @@ public class WhitelistDirectoryController extends BaseController {
|
||||
return new JsonMessage(401, "白名单目录中不能存在包含关系:" + error);
|
||||
}
|
||||
}
|
||||
JSONArray certificateArray = null;
|
||||
List<String> certificateArray = null;
|
||||
if (certificate != null && !certificate.isEmpty()) {
|
||||
certificateArray = covertToArray(certificate);
|
||||
certificateArray = AgentWhitelist.covertToArray(certificate);
|
||||
if (certificateArray == null) {
|
||||
return new JsonMessage(401, "证书路径白名单不能位于Jpom目录下");
|
||||
}
|
||||
@ -116,9 +93,9 @@ public class WhitelistDirectoryController extends BaseController {
|
||||
return new JsonMessage(401, "证书目录中不能存在包含关系:" + error);
|
||||
}
|
||||
}
|
||||
JSONArray nginxArray = null;
|
||||
List<String> nginxArray = null;
|
||||
if (nginx != null && !nginx.isEmpty()) {
|
||||
nginxArray = covertToArray(nginx);
|
||||
nginxArray = AgentWhitelist.covertToArray(nginx);
|
||||
if (nginxArray == null) {
|
||||
return new JsonMessage(401, "nginx路径白名单不能位于Jpom目录下");
|
||||
}
|
||||
@ -130,37 +107,17 @@ public class WhitelistDirectoryController extends BaseController {
|
||||
return new JsonMessage(401, "nginx目录中不能存在包含关系:" + error);
|
||||
}
|
||||
}
|
||||
JSONObject jsonObject = whitelistDirectoryService.getWhitelist();
|
||||
if (jsonObject == null) {
|
||||
jsonObject = new JSONObject();
|
||||
AgentWhitelist agentWhitelist = whitelistDirectoryService.getWhitelist();
|
||||
if (agentWhitelist == null) {
|
||||
agentWhitelist = new AgentWhitelist();
|
||||
}
|
||||
jsonObject.put("project", projectArray);
|
||||
jsonObject.put("certificate", certificateArray);
|
||||
jsonObject.put("nginx", nginxArray);
|
||||
whitelistDirectoryService.saveWhitelistDirectory(jsonObject);
|
||||
agentWhitelist.setProject(projectArray);
|
||||
agentWhitelist.setCertificate(certificateArray);
|
||||
agentWhitelist.setNginx(nginxArray);
|
||||
whitelistDirectoryService.saveWhitelistDirectory(agentWhitelist);
|
||||
return new JsonMessage(200, "保存成功");
|
||||
}
|
||||
|
||||
private JSONArray covertToArray(List<String> list) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (String s : list) {
|
||||
String val = String.format("/%s/", s);
|
||||
val = pathSafe(val);
|
||||
if (StrUtil.SLASH.equals(val)) {
|
||||
continue;
|
||||
}
|
||||
if (array.contains(val)) {
|
||||
continue;
|
||||
}
|
||||
// 判断是否保护jpom 路径
|
||||
if (val.startsWith(ExtConfigBean.getInstance().getPath())) {
|
||||
return null;
|
||||
}
|
||||
array.add(val);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查白名单包含关系
|
||||
*
|
||||
@ -168,17 +125,17 @@ public class WhitelistDirectoryController extends BaseController {
|
||||
* @param start 检查的坐标
|
||||
* @return null 正常
|
||||
*/
|
||||
private String findStartsWith(JSONArray jsonArray, int start) {
|
||||
if (!ExtConfigBean.getInstance().whitelistDirectoryCheckStartsWith) {
|
||||
private String findStartsWith(List<String> jsonArray, int start) {
|
||||
if (!AgentExtConfigBean.getInstance().whitelistDirectoryCheckStartsWith) {
|
||||
return null;
|
||||
}
|
||||
String str = jsonArray.getString(start);
|
||||
String str = jsonArray.get(start);
|
||||
int len = jsonArray.size();
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (i == start) {
|
||||
continue;
|
||||
}
|
||||
String findStr = jsonArray.getString(i);
|
||||
String findStr = jsonArray.get(i);
|
||||
if (findStr.startsWith(str)) {
|
||||
return str;
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
package cn.keepbx.jpom.model.data;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.BCUtil;
|
||||
import cn.hutool.crypto.KeyUtil;
|
||||
import cn.hutool.crypto.asymmetric.KeyType;
|
||||
import cn.hutool.crypto.asymmetric.RSA;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
@ -13,10 +15,9 @@ import cn.keepbx.jpom.service.system.CertService;
|
||||
import cn.keepbx.jpom.system.JpomRuntimeException;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Date;
|
||||
|
||||
@ -26,7 +27,8 @@ import java.util.Date;
|
||||
* @author Arno
|
||||
*/
|
||||
public class CertModel extends BaseModel {
|
||||
private String name;
|
||||
|
||||
private static final String KEY = "Jpom 管理系统";
|
||||
/**
|
||||
* 证书文件
|
||||
*/
|
||||
@ -52,13 +54,6 @@ public class CertModel extends BaseModel {
|
||||
*/
|
||||
private String whitePath;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getWhitePath() {
|
||||
return whitePath;
|
||||
@ -143,22 +138,27 @@ public class CertModel extends BaseModel {
|
||||
if (!FileUtil.exist(file)) {
|
||||
return null;
|
||||
}
|
||||
PrivateKey privateKey = BCUtil.readPrivateKey(ResourceUtil.getStream(key));
|
||||
PublicKey publicKey = BCUtil.readPublicKey(ResourceUtil.getStream(file));
|
||||
RSA rsa = new RSA(privateKey, publicKey);
|
||||
String str = UserModel.SYSTEM_OCCUPY_NAME;
|
||||
String encryptStr = rsa.encryptBase64(str, KeyType.PublicKey);
|
||||
String decryptStr = rsa.decryptStr(encryptStr, KeyType.PrivateKey);
|
||||
if (!str.equals(decryptStr)) {
|
||||
throw new JpomRuntimeException("证书和私钥证书不匹配");
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = ResourceUtil.getStream(key);
|
||||
PrivateKey privateKey = BCUtil.readPrivateKey(inputStream);
|
||||
IoUtil.close(inputStream);
|
||||
inputStream = ResourceUtil.getStream(file);
|
||||
PublicKey publicKey = BCUtil.readPublicKey(inputStream);
|
||||
IoUtil.close(inputStream);
|
||||
RSA rsa = new RSA(privateKey, publicKey);
|
||||
String encryptStr = rsa.encryptBase64(KEY, KeyType.PublicKey);
|
||||
String decryptStr = rsa.decryptStr(encryptStr, KeyType.PrivateKey);
|
||||
if (!KEY.equals(decryptStr)) {
|
||||
throw new JpomRuntimeException("证书和私钥证书不匹配");
|
||||
}
|
||||
} finally {
|
||||
IoUtil.close(inputStream);
|
||||
}
|
||||
try {
|
||||
BufferedInputStream inStream = FileUtil.getInputStream(file);
|
||||
// 创建X509工厂类
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
inputStream = ResourceUtil.getStream(file);
|
||||
// 创建证书对象
|
||||
X509Certificate oCert = (X509Certificate) cf.generateCertificate(inStream);
|
||||
inStream.close();
|
||||
X509Certificate oCert = (X509Certificate) KeyUtil.readX509Certificate(inputStream);
|
||||
//到期时间
|
||||
Date expirationTime = oCert.getNotAfter();
|
||||
//生效日期
|
||||
@ -174,6 +174,8 @@ public class CertModel extends BaseModel {
|
||||
return jsonObject;
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
} finally {
|
||||
IoUtil.close(inputStream);
|
||||
}
|
||||
return null;
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
package cn.keepbx.jpom.model.data;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.keepbx.jpom.BaseJpomApplication;
|
||||
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
|
||||
import cn.keepbx.jpom.model.BaseModel;
|
||||
import cn.keepbx.jpom.model.RunMode;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -15,7 +17,6 @@ import java.util.List;
|
||||
* @author jiangzeyin
|
||||
*/
|
||||
public class ProjectInfoModel extends BaseModel {
|
||||
private String name;
|
||||
/**
|
||||
* 分组
|
||||
*/
|
||||
@ -50,6 +51,18 @@ public class ProjectInfoModel extends BaseModel {
|
||||
private String modifyUser;
|
||||
|
||||
private RunMode runMode;
|
||||
/**
|
||||
* 节点分发项目,不允许在项目管理中编辑
|
||||
*/
|
||||
private boolean outGivingProject;
|
||||
|
||||
public boolean isOutGivingProject() {
|
||||
return outGivingProject;
|
||||
}
|
||||
|
||||
public void setOutGivingProject(boolean outGivingProject) {
|
||||
this.outGivingProject = outGivingProject;
|
||||
}
|
||||
|
||||
public RunMode getRunMode() {
|
||||
if (runMode == null) {
|
||||
@ -64,7 +77,7 @@ public class ProjectInfoModel extends BaseModel {
|
||||
|
||||
public String getModifyUser() {
|
||||
if (StrUtil.isEmpty(modifyUser)) {
|
||||
return UserModel.SYSTEM_OCCUPY_NAME;
|
||||
return StrUtil.DASHED;
|
||||
}
|
||||
return modifyUser;
|
||||
}
|
||||
@ -73,15 +86,6 @@ public class ProjectInfoModel extends BaseModel {
|
||||
this.modifyUser = modifyUser;
|
||||
}
|
||||
|
||||
public void logModifyUser(UserModel userModel) {
|
||||
// 隐藏系统管理员登录名
|
||||
if (userModel.isSystemUser()) {
|
||||
this.setModifyUser(UserModel.SYSTEM_OCCUPY_NAME);
|
||||
} else {
|
||||
this.setModifyUser(userModel.getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目是否正在运行
|
||||
*
|
||||
@ -150,14 +154,6 @@ public class ProjectInfoModel extends BaseModel {
|
||||
this.jvm = jvm;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
if (StrUtil.isEmpty(group)) {
|
||||
return "默认";
|
||||
@ -197,12 +193,20 @@ public class ProjectInfoModel extends BaseModel {
|
||||
*/
|
||||
public static List<File> listJars(ProjectInfoModel projectInfoModel) {
|
||||
File fileLib = new File(projectInfoModel.getLib());
|
||||
return FileUtil.loopFiles(fileLib, pathname -> {
|
||||
if (!pathname.isFile()) {
|
||||
return false;
|
||||
File[] files = fileLib.listFiles();
|
||||
List<File> files1 = new ArrayList<>();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (!file.isFile()) {
|
||||
continue;
|
||||
}
|
||||
if (!StrUtil.endWith(file.getName(), ".jar", true)) {
|
||||
continue;
|
||||
}
|
||||
files1.add(file);
|
||||
}
|
||||
return StrUtil.endWith(pathname.getName(), ".jar", true);
|
||||
});
|
||||
}
|
||||
return files1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,7 +235,7 @@ public class ProjectInfoModel extends BaseModel {
|
||||
File file = files.get(i);
|
||||
classPath.append(file.getAbsolutePath());
|
||||
if (i != len - 1) {
|
||||
classPath.append(AbstractProjectCommander.OS_INFO.isWindows() ? ";" : ":");
|
||||
classPath.append(BaseJpomApplication.OS_INFO.isWindows() ? ";" : ":");
|
||||
}
|
||||
}
|
||||
return classPath.toString();
|
||||
@ -290,18 +294,4 @@ public class ProjectInfoModel extends BaseModel {
|
||||
public void setArgs(String args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行方式
|
||||
*/
|
||||
public enum RunMode {
|
||||
/**
|
||||
* java -classpath
|
||||
*/
|
||||
ClassPath,
|
||||
/**
|
||||
* java -jar
|
||||
*/
|
||||
Jar,
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package cn.keepbx.jpom.model.system;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.keepbx.jpom.model.BaseJsonModel;
|
||||
|
||||
/**
|
||||
@ -10,8 +11,8 @@ import cn.keepbx.jpom.model.BaseJsonModel;
|
||||
*/
|
||||
public class NetstatModel extends BaseJsonModel {
|
||||
private String protocol;
|
||||
private String receive = "-";
|
||||
private String send = "-";
|
||||
private String receive = StrUtil.DASHED;
|
||||
private String send = StrUtil.DASHED;
|
||||
private String local;
|
||||
private String foreign;
|
||||
private String status;
|
@ -104,7 +104,6 @@ public class ProcessModel extends BaseJsonModel {
|
||||
DefaultSystemLog.ERROR().error("解析进程失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getCommand() {
|
@ -0,0 +1,110 @@
|
||||
package cn.keepbx.jpom.service;
|
||||
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.keepbx.jpom.common.BaseDataService;
|
||||
import cn.keepbx.jpom.model.data.AgentWhitelist;
|
||||
import cn.keepbx.jpom.system.AgentConfigBean;
|
||||
import cn.keepbx.jpom.util.JsonFileUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 白名单服务
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/2/28
|
||||
*/
|
||||
@Service
|
||||
public class WhitelistDirectoryService extends BaseDataService {
|
||||
|
||||
public AgentWhitelist getWhitelist() {
|
||||
try {
|
||||
JSONObject jsonObject = getJSONObject(AgentConfigBean.WHITELIST_DIRECTORY);
|
||||
if (jsonObject == null) {
|
||||
return null;
|
||||
}
|
||||
return jsonObject.toJavaObject(AgentWhitelist.class);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单项添加白名单
|
||||
*
|
||||
* @param item 白名单
|
||||
*/
|
||||
public void addProjectWhiteList(String item) {
|
||||
AgentWhitelist agentWhitelist = getWhitelist();
|
||||
if (agentWhitelist == null) {
|
||||
agentWhitelist = new AgentWhitelist();
|
||||
}
|
||||
List<String> project = agentWhitelist.getProject();
|
||||
if (project == null) {
|
||||
project = new ArrayList<>();
|
||||
}
|
||||
project.add(item);
|
||||
saveWhitelistDirectory(agentWhitelist);
|
||||
}
|
||||
|
||||
public boolean isInstalled() {
|
||||
AgentWhitelist agentWhitelist = getWhitelist();
|
||||
if (agentWhitelist == null) {
|
||||
return false;
|
||||
}
|
||||
List<String> project = agentWhitelist.getProject();
|
||||
return project != null && !project.isEmpty();
|
||||
}
|
||||
|
||||
private List<String> getNgxDirectory() {
|
||||
AgentWhitelist agentWhitelist = getWhitelist();
|
||||
if (agentWhitelist == null) {
|
||||
return null;
|
||||
}
|
||||
return agentWhitelist.getNginx();
|
||||
}
|
||||
|
||||
public boolean checkProjectDirectory(String path) {
|
||||
AgentWhitelist agentWhitelist = getWhitelist();
|
||||
if (agentWhitelist == null) {
|
||||
return false;
|
||||
}
|
||||
List<String> list = agentWhitelist.getProject();
|
||||
return AgentWhitelist.checkPath(list, path);
|
||||
}
|
||||
|
||||
public boolean checkNgxDirectory(String path) {
|
||||
List<String> list = getNgxDirectory();
|
||||
return AgentWhitelist.checkPath(list, path);
|
||||
}
|
||||
|
||||
private List<String> getCertificateDirectory() {
|
||||
AgentWhitelist agentWhitelist = getWhitelist();
|
||||
if (agentWhitelist == null) {
|
||||
return null;
|
||||
}
|
||||
return agentWhitelist.getCertificate();
|
||||
}
|
||||
|
||||
public boolean checkCertificateDirectory(String path) {
|
||||
List<String> list = getCertificateDirectory();
|
||||
if (list == null) {
|
||||
return false;
|
||||
}
|
||||
return AgentWhitelist.checkPath(list, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存白名单
|
||||
*
|
||||
* @param jsonObject 实体
|
||||
*/
|
||||
public void saveWhitelistDirectory(AgentWhitelist jsonObject) {
|
||||
String path = getDataFilePath(AgentConfigBean.WHITELIST_DIRECTORY);
|
||||
JsonFileUtil.saveJson(path, jsonObject.toJson());
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package cn.keepbx.jpom.service.manage;
|
||||
|
||||
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.socket.CommandOp;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -14,32 +15,12 @@ import javax.annotation.Resource;
|
||||
*/
|
||||
@Service
|
||||
public class ConsoleService {
|
||||
public static final String RUNING_TAG = "running";
|
||||
public static final String STOP_TAG = "stopped";
|
||||
|
||||
|
||||
@Resource
|
||||
private ProjectInfoService projectInfoService;
|
||||
|
||||
|
||||
public enum CommandOp {
|
||||
/**
|
||||
* 启动
|
||||
*/
|
||||
start,
|
||||
stop,
|
||||
restart,
|
||||
status,
|
||||
/**
|
||||
* 运行日志
|
||||
*/
|
||||
showlog,
|
||||
/**
|
||||
* 查看内存信息
|
||||
*/
|
||||
top
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行shell命令
|
||||
*
|
@ -5,7 +5,7 @@ import cn.hutool.core.io.FileUtil;
|
||||
import cn.keepbx.jpom.common.BaseOperService;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.model.data.ProjectRecoverModel;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
import cn.keepbx.jpom.system.AgentConfigBean;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -32,7 +32,7 @@ public class ProjectInfoService extends BaseOperService<ProjectInfoModel> {
|
||||
*/
|
||||
@Override
|
||||
public List<ProjectInfoModel> list() {
|
||||
JSONObject jsonObject = getJSONObject(ConfigBean.PROJECT);
|
||||
JSONObject jsonObject = getJSONObject(AgentConfigBean.PROJECT);
|
||||
JSONArray jsonArray = formatToArray(jsonObject);
|
||||
return jsonArray.toJavaList(ProjectInfoModel.class);
|
||||
}
|
||||
@ -56,7 +56,7 @@ public class ProjectInfoService extends BaseOperService<ProjectInfoModel> {
|
||||
@Override
|
||||
public void addItem(ProjectInfoModel projectInfo) {
|
||||
// 保存
|
||||
saveJson(ConfigBean.PROJECT, projectInfo.toJson());
|
||||
saveJson(AgentConfigBean.PROJECT, projectInfo.toJson());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,7 +65,7 @@ public class ProjectInfoService extends BaseOperService<ProjectInfoModel> {
|
||||
* @param projectInfo 项目
|
||||
*/
|
||||
public void deleteProject(ProjectInfoModel projectInfo, String userId) throws Exception {
|
||||
deleteJson(ConfigBean.PROJECT, projectInfo.getId());
|
||||
deleteJson(AgentConfigBean.PROJECT, projectInfo.getId());
|
||||
// 添加回收记录
|
||||
ProjectRecoverModel projectRecoverModel = new ProjectRecoverModel(projectInfo);
|
||||
projectRecoverModel.setDelUser(userId);
|
||||
@ -80,7 +80,7 @@ public class ProjectInfoService extends BaseOperService<ProjectInfoModel> {
|
||||
@Override
|
||||
public boolean updateItem(ProjectInfoModel projectInfo) throws Exception {
|
||||
projectInfo.setModifyTime(DateUtil.now());
|
||||
updateJson(ConfigBean.PROJECT, projectInfo.toJson());
|
||||
updateJson(AgentConfigBean.PROJECT, projectInfo.toJson());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ public class ProjectInfoService extends BaseOperService<ProjectInfoModel> {
|
||||
*/
|
||||
@Override
|
||||
public ProjectInfoModel getItem(String id) {
|
||||
return getJsonObjectById(ConfigBean.PROJECT, id, ProjectInfoModel.class);
|
||||
return getJsonObjectById(AgentConfigBean.PROJECT, id, ProjectInfoModel.class);
|
||||
}
|
||||
|
||||
public String getLogSize(String id) {
|
@ -3,7 +3,7 @@ package cn.keepbx.jpom.service.manage;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.keepbx.jpom.common.BaseOperService;
|
||||
import cn.keepbx.jpom.model.data.ProjectRecoverModel;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
import cn.keepbx.jpom.system.AgentConfigBean;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -26,7 +26,7 @@ public class ProjectRecoverService extends BaseOperService<ProjectRecoverModel>
|
||||
*/
|
||||
@Override
|
||||
public List<ProjectRecoverModel> list() {
|
||||
JSONObject jsonObject = getJSONObject(ConfigBean.PROJECT_RECOVER);
|
||||
JSONObject jsonObject = getJSONObject(AgentConfigBean.PROJECT_RECOVER);
|
||||
JSONArray jsonArray = formatToArray(jsonObject);
|
||||
return jsonArray.toJavaList(ProjectRecoverModel.class);
|
||||
}
|
||||
@ -41,7 +41,7 @@ public class ProjectRecoverService extends BaseOperService<ProjectRecoverModel>
|
||||
public void addItem(ProjectRecoverModel projectInfo) {
|
||||
projectInfo.setDelTime(DateUtil.now());
|
||||
// 保存
|
||||
saveJson(ConfigBean.PROJECT_RECOVER, projectInfo.toJson());
|
||||
saveJson(AgentConfigBean.PROJECT_RECOVER, projectInfo.toJson());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,7 +52,7 @@ public class ProjectRecoverService extends BaseOperService<ProjectRecoverModel>
|
||||
*/
|
||||
@Override
|
||||
public ProjectRecoverModel getItem(String id) throws IOException {
|
||||
return getJsonObjectById(ConfigBean.PROJECT_RECOVER, id, ProjectRecoverModel.class);
|
||||
return getJsonObjectById(AgentConfigBean.PROJECT_RECOVER, id, ProjectRecoverModel.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -3,7 +3,7 @@ package cn.keepbx.jpom.service.oss;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.keepbx.jpom.common.BaseDataService;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
import cn.keepbx.jpom.system.AgentConfigBean;
|
||||
import cn.keepbx.jpom.util.JsonFileUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
@ -31,7 +31,7 @@ import java.util.concurrent.TimeUnit;
|
||||
public class OssManagerService extends BaseDataService {
|
||||
|
||||
public File download(String key) {
|
||||
File file = ConfigBean.getInstance().getTempPath();
|
||||
File file = AgentConfigBean.getInstance().getTempPath();
|
||||
//getTempPath();
|
||||
file = FileUtil.file(file, key);
|
||||
OSSClient ossClient = getOSSClient(getConfig());
|
||||
@ -98,7 +98,7 @@ public class OssManagerService extends BaseDataService {
|
||||
}
|
||||
|
||||
public JSONObject getConfig() {
|
||||
return getJSONObject(ConfigBean.ALI_OSS);
|
||||
return getJSONObject(AgentConfigBean.ALI_OSS);
|
||||
}
|
||||
|
||||
private String getBucketName() {
|
||||
@ -112,7 +112,7 @@ public class OssManagerService extends BaseDataService {
|
||||
}
|
||||
|
||||
public void save(JSONObject jsonObject) {
|
||||
String path = getDataFilePath(ConfigBean.ALI_OSS);
|
||||
String path = getDataFilePath(AgentConfigBean.ALI_OSS);
|
||||
JsonFileUtil.saveJson(path, jsonObject);
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.keepbx.jpom.common.BaseOperService;
|
||||
import cn.keepbx.jpom.model.data.CertModel;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
import cn.keepbx.jpom.system.AgentConfigBean;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -27,7 +27,7 @@ public class CertService extends BaseOperService<CertModel> {
|
||||
*/
|
||||
@Override
|
||||
public void addItem(CertModel certModel) {
|
||||
saveJson(ConfigBean.CERT, certModel.toJson());
|
||||
saveJson(AgentConfigBean.CERT, certModel.toJson());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,7 +37,7 @@ public class CertService extends BaseOperService<CertModel> {
|
||||
*/
|
||||
@Override
|
||||
public List<CertModel> list() {
|
||||
JSONObject jsonObject = getJSONObject(ConfigBean.CERT);
|
||||
JSONObject jsonObject = getJSONObject(AgentConfigBean.CERT);
|
||||
if (jsonObject == null) {
|
||||
return null;
|
||||
}
|
||||
@ -47,7 +47,7 @@ public class CertService extends BaseOperService<CertModel> {
|
||||
|
||||
@Override
|
||||
public CertModel getItem(String id) {
|
||||
return getJsonObjectById(ConfigBean.CERT, id, CertModel.class);
|
||||
return getJsonObjectById(AgentConfigBean.CERT, id, CertModel.class);
|
||||
}
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ public class CertService extends BaseOperService<CertModel> {
|
||||
return true;
|
||||
}
|
||||
String keyPath = certModel.getCert();
|
||||
deleteJson(ConfigBean.CERT, id);
|
||||
deleteJson(AgentConfigBean.CERT, id);
|
||||
if (StrUtil.isNotEmpty(keyPath)) {
|
||||
// 删除证书文件
|
||||
File parentFile = FileUtil.file(keyPath).getParentFile();
|
||||
@ -84,7 +84,7 @@ public class CertService extends BaseOperService<CertModel> {
|
||||
@Override
|
||||
public boolean updateItem(CertModel certModel) {
|
||||
try {
|
||||
updateJson(ConfigBean.CERT, certModel.toJson());
|
||||
updateJson(AgentConfigBean.CERT, certModel.toJson());
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
return false;
|
@ -6,6 +6,8 @@ import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.keepbx.jpom.common.BaseOperService;
|
||||
import cn.keepbx.jpom.model.data.AgentWhitelist;
|
||||
import cn.keepbx.jpom.service.WhitelistDirectoryService;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.odiszapc.nginxparser.NgxBlock;
|
||||
@ -31,7 +33,11 @@ public class NginxService extends BaseOperService {
|
||||
|
||||
@Override
|
||||
public JSONArray list() {
|
||||
JSONArray ngxDirectory = whitelistDirectoryService.getNgxDirectory();
|
||||
AgentWhitelist agentWhitelist = whitelistDirectoryService.getWhitelist();
|
||||
if (agentWhitelist == null) {
|
||||
return null;
|
||||
}
|
||||
List<String> ngxDirectory = agentWhitelist.getNginx();
|
||||
if (ngxDirectory == null) {
|
||||
return null;
|
||||
}
|
@ -5,12 +5,11 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||
|
||||
/**
|
||||
* socket 配置
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/19
|
||||
*/
|
||||
@Configuration
|
||||
public class WebSocketConfig {
|
||||
public class AgentWebSocketConfig {
|
||||
@Bean
|
||||
public ServerEndpointExporter serverEndpointExporter() {
|
||||
return new ServerEndpointExporter();
|
@ -2,15 +2,16 @@ package cn.keepbx.jpom.socket;
|
||||
|
||||
import cn.hutool.core.exceptions.ExceptionUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.JsonMessage;
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.model.data.UserModel;
|
||||
import cn.keepbx.jpom.service.manage.ConsoleService;
|
||||
import cn.keepbx.jpom.service.manage.ProjectInfoService;
|
||||
import cn.keepbx.jpom.service.user.UserService;
|
||||
import cn.keepbx.jpom.system.TopManager;
|
||||
import cn.keepbx.jpom.util.SocketSessionUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -19,61 +20,37 @@ import javax.websocket.server.PathParam;
|
||||
import javax.websocket.server.ServerEndpoint;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* socket 消息控制器
|
||||
* 插件端socket
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2017/9/8
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
@ServerEndpoint(value = "/console/{userInfo}/{projectId}")
|
||||
@ServerEndpoint(value = "/console/{projectId}/{optUser}")
|
||||
@Component
|
||||
public class LogWebSocketHandle {
|
||||
public class AgentWebSocketHandle {
|
||||
|
||||
public static final String SYSTEM_ID = "system";
|
||||
private ConsoleService consoleService;
|
||||
private static volatile AtomicInteger onlineCount = new AtomicInteger();
|
||||
private static final ConcurrentHashMap<String, UserModel> USER = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentHashMap<String, String> USER = new ConcurrentHashMap<>();
|
||||
private static ProjectInfoService projectInfoService;
|
||||
|
||||
/**
|
||||
* 新的WebSocket请求开启
|
||||
*
|
||||
* @param userInfo 用户授权信息
|
||||
* @param projectId 项目id
|
||||
* @param session 回话
|
||||
*/
|
||||
@OnOpen
|
||||
public void onOpen(@PathParam("userInfo") String userInfo, @PathParam("projectId") String projectId, Session session) {
|
||||
if (consoleService == null) {
|
||||
consoleService = SpringUtil.getBean(ConsoleService.class);
|
||||
}
|
||||
// 通过用户名和密码的Md5值判断是否是登录的
|
||||
public void onOpen(@PathParam("projectId") String projectId, @PathParam("optUser") String urlOptUser, Session session) {
|
||||
try {
|
||||
ProjectInfoService projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
|
||||
UserService userService = SpringUtil.getBean(UserService.class);
|
||||
UserModel userModel = userService.checkUser(userInfo);
|
||||
if (userModel == null) {
|
||||
SocketSessionUtil.send(session, "用户名或密码错误!");
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
// 判断项目
|
||||
if (!SYSTEM_ID.equals(projectId)) {
|
||||
if (!CommonSocketConfig.SYSTEM_ID.equals(projectId)) {
|
||||
if (projectInfoService == null) {
|
||||
projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
|
||||
}
|
||||
ProjectInfoModel projectInfoModel = projectInfoService.getItem(projectId);
|
||||
if (projectInfoModel == null) {
|
||||
SocketSessionUtil.send(session, "获取项目信息错误");
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
if (!userModel.isProject(projectInfoModel.getId())) {
|
||||
SocketSessionUtil.send(session, "没有项目权限");
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
SocketSessionUtil.send(session, StrUtil.format("欢迎加入:{} 回话id:{} 当前会话总数:{}", userModel.getName(), session.getId(), onlineCount.incrementAndGet()));
|
||||
USER.put(session.getId(), userModel);
|
||||
String optUser = URLUtil.decode(urlOptUser);
|
||||
USER.put(session.getId(), optUser);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error("socket 错误", e);
|
||||
try {
|
||||
@ -85,26 +62,42 @@ public class LogWebSocketHandle {
|
||||
}
|
||||
}
|
||||
|
||||
private String getOptUserName(Session session) {
|
||||
String name = USER.get(session.getId());
|
||||
return StrUtil.emptyToDefault(name, StrUtil.DASHED);
|
||||
}
|
||||
|
||||
private boolean silentMsg(CommandOp commandOp, Session session) {
|
||||
if (commandOp == CommandOp.heart) {
|
||||
return true;
|
||||
}
|
||||
if (commandOp == CommandOp.top) {
|
||||
TopManager.addMonitor(session);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@OnMessage
|
||||
public void onMessage(String message, Session session) throws Exception {
|
||||
JSONObject json = JSONObject.parseObject(message);
|
||||
String op = json.getString("op");
|
||||
if ("heart".equals(op)) {
|
||||
return;
|
||||
}
|
||||
UserModel userModel = USER.get(session.getId());
|
||||
if (userModel == null) {
|
||||
SocketSessionUtil.send(session, "回话信息失效,刷新网页再试");
|
||||
CommandOp commandOp = CommandOp.valueOf(op);
|
||||
if (silentMsg(commandOp, session)) {
|
||||
return;
|
||||
}
|
||||
String projectId = json.getString("projectId");
|
||||
ProjectInfoService projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
|
||||
projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
|
||||
ProjectInfoModel projectInfoModel = projectInfoService.getItem(projectId);
|
||||
ConsoleService.CommandOp commandOp = ConsoleService.CommandOp.valueOf(op);
|
||||
if (projectInfoModel == null && commandOp != ConsoleService.CommandOp.top) {
|
||||
if (projectInfoModel == null) {
|
||||
SocketSessionUtil.send(session, "没有对应项目");
|
||||
return;
|
||||
}
|
||||
runMsg(commandOp, session, projectInfoModel, json);
|
||||
}
|
||||
|
||||
private void runMsg(CommandOp commandOp, Session session, ProjectInfoModel projectInfoModel, JSONObject reqJson) throws Exception {
|
||||
ConsoleService consoleService = SpringUtil.getBean(ConsoleService.class);
|
||||
JSONObject resultData = null;
|
||||
String strResult;
|
||||
boolean logUser = false;
|
||||
@ -115,7 +108,7 @@ public class LogWebSocketHandle {
|
||||
case restart:
|
||||
logUser = true;
|
||||
strResult = consoleService.execCommand(commandOp, projectInfoModel);
|
||||
if (strResult.contains(ConsoleService.RUNING_TAG)) {
|
||||
if (strResult.contains(AbstractProjectCommander.RUNING_TAG)) {
|
||||
resultData = JsonMessage.toJson(200, "操作成功:" + strResult);
|
||||
} else {
|
||||
resultData = JsonMessage.toJson(400, strResult);
|
||||
@ -125,7 +118,7 @@ public class LogWebSocketHandle {
|
||||
logUser = true;
|
||||
// 停止项目
|
||||
strResult = consoleService.execCommand(commandOp, projectInfoModel);
|
||||
if (strResult.contains(ConsoleService.STOP_TAG)) {
|
||||
if (strResult.contains(AbstractProjectCommander.STOP_TAG)) {
|
||||
resultData = JsonMessage.toJson(200, "操作成功");
|
||||
} else {
|
||||
resultData = JsonMessage.toJson(500, strResult);
|
||||
@ -134,7 +127,7 @@ public class LogWebSocketHandle {
|
||||
case status:
|
||||
// 获取项目状态
|
||||
strResult = consoleService.execCommand(commandOp, projectInfoModel);
|
||||
if (strResult.contains(ConsoleService.RUNING_TAG)) {
|
||||
if (strResult.contains(AbstractProjectCommander.RUNING_TAG)) {
|
||||
resultData = JsonMessage.toJson(200, "运行中", strResult);
|
||||
} else {
|
||||
resultData = JsonMessage.toJson(404, "未运行", strResult);
|
||||
@ -146,15 +139,13 @@ public class LogWebSocketHandle {
|
||||
try {
|
||||
FileTailWatcher.addWatcher(log, session);
|
||||
} catch (IOException io) {
|
||||
DefaultSystemLog.ERROR().error(io.getMessage(), io);
|
||||
SocketSessionUtil.send(session, io.getMessage());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case top:
|
||||
TopManager.addMonitor(session);
|
||||
break;
|
||||
default:
|
||||
resultData = JsonMessage.toJson(404, "不支持的方式:" + op);
|
||||
resultData = JsonMessage.toJson(404, "不支持的方式:" + commandOp.name());
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -165,19 +156,28 @@ public class LogWebSocketHandle {
|
||||
} finally {
|
||||
if (logUser) {
|
||||
// 记录操作人
|
||||
projectInfoModel = projectInfoService.getItem(projectId);
|
||||
projectInfoModel.logModifyUser(userModel);
|
||||
projectInfoModel = projectInfoService.getItem(projectInfoModel.getId());
|
||||
String name = getOptUserName(session);
|
||||
projectInfoModel.setModifyUser(name);
|
||||
projectInfoService.updateItem(projectInfoModel);
|
||||
}
|
||||
}
|
||||
//
|
||||
if (resultData != null) {
|
||||
resultData.put("op", op);
|
||||
DefaultSystemLog.LOG().info(resultData.toString());
|
||||
SocketSessionUtil.send(session, resultData.toString());
|
||||
// resultData.put("op", commandOp.name());
|
||||
reqJson.putAll(resultData);
|
||||
DefaultSystemLog.LOG().info(reqJson.toString());
|
||||
SocketSessionUtil.send(session, reqJson.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@OnClose
|
||||
public void onClose(Session session) {
|
||||
destroy(session);
|
||||
// top
|
||||
TopManager.removeMonitor(session);
|
||||
}
|
||||
|
||||
private void destroy(Session session) {
|
||||
// 清理日志监听
|
||||
try {
|
||||
@ -185,26 +185,9 @@ public class LogWebSocketHandle {
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error("关闭异常", e);
|
||||
}
|
||||
onlineCount.getAndDecrement();
|
||||
}
|
||||
|
||||
/**
|
||||
* WebSocket请求关闭
|
||||
*/
|
||||
@OnClose
|
||||
public void onClose(Session session) {
|
||||
try {
|
||||
destroy(session);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error("关闭异常", e);
|
||||
}
|
||||
// top
|
||||
TopManager.removeMonitor(session);
|
||||
USER.remove(session.getId());
|
||||
DefaultSystemLog.LOG().info(session.getId() + " socket 关闭");
|
||||
}
|
||||
|
||||
|
||||
@OnError
|
||||
public void onError(Session session, Throwable thr) {
|
||||
// java.io.IOException: Broken pipe
|
||||
@ -212,7 +195,6 @@ public class LogWebSocketHandle {
|
||||
SocketSessionUtil.send(session, "服务端发生异常" + ExceptionUtil.stacktraceToString(thr));
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
USER.remove(session.getId());
|
||||
DefaultSystemLog.ERROR().error(session.getId() + "socket 异常", thr);
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.keepbx.jpom.util.CharsetDetector;
|
||||
import cn.keepbx.jpom.util.LimitQueue;
|
||||
import cn.keepbx.jpom.util.SocketSessionUtil;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import java.io.File;
|
||||
@ -34,7 +35,7 @@ public class FileTailWatcher implements Runnable {
|
||||
private LimitQueue limitQueue = new LimitQueue(10);
|
||||
private final RandomAccessFile randomFile;
|
||||
/**
|
||||
* 所有回话
|
||||
* 所有会话
|
||||
*/
|
||||
private Set<Session> socketSessions = new HashSet<>();
|
||||
private final String log;
|
||||
@ -48,7 +49,7 @@ public class FileTailWatcher implements Runnable {
|
||||
* 添加文件监听
|
||||
*
|
||||
* @param log 日志文件路径
|
||||
* @param session 回话
|
||||
* @param session 会话
|
||||
* @throws IOException 异常
|
||||
*/
|
||||
public static void addWatcher(String log, Session session) throws IOException {
|
||||
@ -75,7 +76,7 @@ public class FileTailWatcher implements Runnable {
|
||||
/**
|
||||
* 有客户端离线
|
||||
*
|
||||
* @param session 回话
|
||||
* @param session 会话
|
||||
*/
|
||||
public static void offline(Session session) {
|
||||
Collection<FileTailWatcher> collection = CONCURRENT_HASH_MAP.values();
|
||||
@ -95,9 +96,9 @@ public class FileTailWatcher implements Runnable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加监听回话
|
||||
* 添加监听会话
|
||||
*
|
||||
* @param session 回话
|
||||
* @param session 会话
|
||||
*/
|
||||
private void add(Session session) {
|
||||
if (this.socketSessions.add(session)) {
|
@ -0,0 +1,102 @@
|
||||
package cn.keepbx.jpom.system;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import cn.keepbx.jpom.model.system.AgentAutoUser;
|
||||
import cn.keepbx.jpom.util.JsonFileUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* agent 端授权账号信息
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/17
|
||||
*/
|
||||
@Configuration
|
||||
public class AgentAuthorize {
|
||||
|
||||
private static AgentAuthorize agentAuthorize;
|
||||
/**
|
||||
* 账号
|
||||
*/
|
||||
@Value("${jpom.authorize.agentName}")
|
||||
private String agentName;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@Value("${jpom.authorize.agentPwd:}")
|
||||
private String agentPwd;
|
||||
/**
|
||||
* 授权加密字符串
|
||||
*/
|
||||
private String authorize;
|
||||
|
||||
/**
|
||||
* 单例
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public static AgentAuthorize getInstance() {
|
||||
if (agentAuthorize == null) {
|
||||
agentAuthorize = SpringUtil.getBean(AgentAuthorize.class);
|
||||
// 登录名不能为空
|
||||
if (StrUtil.isEmpty(agentAuthorize.agentName)) {
|
||||
throw new JpomRuntimeException("agent 端登录名不能为空");
|
||||
}
|
||||
agentAuthorize.checkPwd();
|
||||
// 生成密码授权字符串
|
||||
agentAuthorize.authorize = SecureUtil.sha1(agentAuthorize.agentName + "@" + agentAuthorize.agentPwd);
|
||||
}
|
||||
return agentAuthorize;
|
||||
}
|
||||
|
||||
|
||||
public boolean checkAuthorize(String authorize) {
|
||||
return StrUtil.equals(authorize, this.authorize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否配置密码
|
||||
*/
|
||||
private void checkPwd() {
|
||||
String path = ConfigBean.getInstance().getAgentAutoAuthorizeFile(ConfigBean.getInstance().getDataPath());
|
||||
if (StrUtil.isNotEmpty(agentPwd)) {
|
||||
// 有指定密码 清除旧密码信息
|
||||
FileUtil.del(path);
|
||||
return;
|
||||
}
|
||||
if (FileUtil.exist(path)) {
|
||||
// 读取旧密码
|
||||
try {
|
||||
String json = FileUtil.readString(path, CharsetUtil.CHARSET_UTF_8);
|
||||
AgentAutoUser autoUser = JSONObject.parseObject(json, AgentAutoUser.class);
|
||||
String oldAgentPwd = autoUser.getAgentPwd();
|
||||
if (!StrUtil.equals(autoUser.getAgentName(), this.agentName)) {
|
||||
throw new JpomRuntimeException("已经存在的登录名和配置的登录名不一致");
|
||||
}
|
||||
if (StrUtil.isNotEmpty(oldAgentPwd)) {
|
||||
this.agentPwd = oldAgentPwd;
|
||||
DefaultSystemLog.LOG().info("已有授权账号:{} 密码:{},授权信息保存位置:{}", this.agentName, this.agentPwd, FileUtil.getAbsolutePath(path));
|
||||
return;
|
||||
}
|
||||
} catch (JpomRuntimeException e) {
|
||||
throw e;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
this.agentPwd = RandomUtil.randomString(10);
|
||||
AgentAutoUser autoUser = new AgentAutoUser();
|
||||
autoUser.setAgentName(this.agentName);
|
||||
autoUser.setAgentPwd(this.agentPwd);
|
||||
// 写入文件中
|
||||
JsonFileUtil.saveJson(path, autoUser.toJson());
|
||||
DefaultSystemLog.LOG().info("已经自动生成授权账号:{} 密码:{},授权信息保存位置:{}", this.agentName, this.agentPwd, FileUtil.getAbsolutePath(path));
|
||||
}
|
||||
}
|
@ -3,92 +3,58 @@ package cn.keepbx.jpom.system;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import cn.keepbx.jpom.common.BaseController;
|
||||
import cn.keepbx.jpom.common.JpomApplicationEvent;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import cn.jiangzeyin.controller.base.AbstractController;
|
||||
import cn.keepbx.jpom.common.BaseAgentController;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 配置信息静态变量类
|
||||
* 插件端配置
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/1/16
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
@Configuration
|
||||
public class ConfigBean {
|
||||
private static final String DATA = "data";
|
||||
private static ConfigBean configBean;
|
||||
/**
|
||||
* 用户数据文件
|
||||
*/
|
||||
public static final String USER = "user.json";
|
||||
/**
|
||||
* 项目数据文件
|
||||
*/
|
||||
public static final String PROJECT = "project.json";
|
||||
public class AgentConfigBean {
|
||||
/**
|
||||
* 白名单文件
|
||||
*/
|
||||
public static final String WHITELIST_DIRECTORY = "whitelistDirectory.json";
|
||||
|
||||
/**
|
||||
* 阿里oss 文件
|
||||
* 项目数据文件
|
||||
*/
|
||||
public static final String ALI_OSS = "aliOss.json";
|
||||
/**
|
||||
* 证书文件
|
||||
*/
|
||||
public static final String CERT = "cert.json";
|
||||
public static final String PROJECT = "project.json";
|
||||
|
||||
/**
|
||||
* 项目回收文件
|
||||
*/
|
||||
public static final String PROJECT_RECOVER = "project_recover.json";
|
||||
|
||||
/**
|
||||
* Jpom 程序运行的 application 标识
|
||||
* 阿里oss 文件
|
||||
*/
|
||||
@Value("${jpom.applicationTag:}")
|
||||
public String applicationTag;
|
||||
public static final String ALI_OSS = "aliOss.json";
|
||||
|
||||
/**
|
||||
* 证书文件
|
||||
*/
|
||||
public static final String CERT = "cert.json";
|
||||
|
||||
private static AgentConfigBean agentConfigBean;
|
||||
|
||||
/**
|
||||
* 单利模式
|
||||
*
|
||||
* @return config
|
||||
*/
|
||||
public static ConfigBean getInstance() {
|
||||
if (configBean == null) {
|
||||
configBean = SpringUtil.getBean(ConfigBean.class);
|
||||
public static AgentConfigBean getInstance() {
|
||||
if (agentConfigBean == null) {
|
||||
agentConfigBean = SpringUtil.getBean(AgentConfigBean.class);
|
||||
}
|
||||
return configBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目运行数据存储文件夹路径
|
||||
*
|
||||
* @return 文件夹路径
|
||||
*/
|
||||
public String getDataPath() {
|
||||
String dataPath = FileUtil.normalize(ExtConfigBean.getInstance().getPath() + "/" + DATA);
|
||||
FileUtil.mkdir(dataPath);
|
||||
return dataPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取pid文件
|
||||
*
|
||||
* @return file
|
||||
*/
|
||||
public File getPidFile() {
|
||||
return new File(getDataPath(), "pid." + JpomApplicationEvent.getPid());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前Jpom 运行信息文件
|
||||
*
|
||||
* @return file
|
||||
*/
|
||||
public File getJpomInfo() {
|
||||
return new File(getDataPath(), "jpom.info");
|
||||
return agentConfigBean;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,8 +73,9 @@ public class ConfigBean {
|
||||
* @return file
|
||||
*/
|
||||
public File getTempPath() {
|
||||
File file = new File(getDataPath());
|
||||
String userName = BaseController.getUserName();
|
||||
File file = new File(ConfigBean.getInstance().getDataPath());
|
||||
HttpServletRequest request = AbstractController.getRequestAttributes().getRequest();
|
||||
String userName = BaseAgentController.getUserName(request);
|
||||
if (StrUtil.isEmpty(userName)) {
|
||||
throw new JpomRuntimeException("没有登录");
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package cn.keepbx.jpom.system;
|
||||
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* agent 端外部配置
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
@Configuration
|
||||
public class AgentExtConfigBean {
|
||||
/**
|
||||
* 白名单路径是否判断包含关系
|
||||
*/
|
||||
@Value("${whitelistDirectory.checkStartsWith:true}")
|
||||
public boolean whitelistDirectoryCheckStartsWith;
|
||||
|
||||
/**
|
||||
* 自动备份控制台日志,防止日志文件过大,目前暂只支持linux 不停服备份 如果配置none 则不自动备份 默认10分钟扫描一次
|
||||
*/
|
||||
@Value("${log.autoBackConsoleCron:0 0/10 * * * ?}")
|
||||
public String autoBackConsoleCron;
|
||||
/**
|
||||
* 当文件多大时自动备份
|
||||
*
|
||||
* @see ch.qos.logback.core.util.FileSize
|
||||
*/
|
||||
@Value("${log.autoBackSize:50MB}")
|
||||
public String autoBackSize;
|
||||
/**
|
||||
* 控制台日志保存时长单位天
|
||||
*/
|
||||
@Value("${log.saveDays:7}")
|
||||
private int logSaveDays;
|
||||
|
||||
|
||||
/**
|
||||
* 配置错误或者没有,默认是7天
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public int getLogSaveDays() {
|
||||
if (logSaveDays <= 0) {
|
||||
return 7;
|
||||
}
|
||||
return logSaveDays;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单例
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public static AgentExtConfigBean getInstance() {
|
||||
return SpringUtil.getBean(AgentExtConfigBean.class);
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.pool.ThreadPoolService;
|
||||
import cn.keepbx.jpom.common.commander.AbstractSystemCommander;
|
||||
import cn.keepbx.jpom.model.system.ProcessModel;
|
||||
import cn.keepbx.jpom.socket.SocketSessionUtil;
|
||||
import cn.keepbx.jpom.util.SocketSessionUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import javax.websocket.Session;
|
||||
@ -37,7 +37,7 @@ public class TopManager {
|
||||
/**
|
||||
* 添加top 命令监听
|
||||
*
|
||||
* @param session 回话
|
||||
* @param session 会话
|
||||
*/
|
||||
public static void addMonitor(Session session) {
|
||||
SESSIONS.add(session);
|
||||
@ -47,7 +47,7 @@ public class TopManager {
|
||||
/**
|
||||
* 移除top 命令监控
|
||||
*
|
||||
* @param session 回话
|
||||
* @param session 会话
|
||||
*/
|
||||
public static void removeMonitor(Session session) {
|
||||
SESSIONS.remove(session);
|
||||
@ -62,7 +62,7 @@ public class TopManager {
|
||||
return;
|
||||
}
|
||||
CronUtil.remove(CRON_ID);
|
||||
CronUtil.schedule(CRON_ID, "0/10 * * * * ?", () -> {
|
||||
CronUtil.schedule(CRON_ID, "0/5 * * * * ?", () -> {
|
||||
//发送监控信息
|
||||
try {
|
||||
JSONObject topInfo = AbstractSystemCommander.getInstance().getAllMonitor();
|
||||
@ -105,13 +105,13 @@ public class TopManager {
|
||||
*/
|
||||
private static void send(String content) {
|
||||
synchronized (TopManager.class) {
|
||||
String htmlContent = content.replaceAll("\n", "<br/>");
|
||||
htmlContent = htmlContent.replaceAll(" ", " ");
|
||||
Iterator<Session> iterator = SESSIONS.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Session session = iterator.next();
|
||||
content = content.replaceAll("\n", "<br/>");
|
||||
content = content.replaceAll(" ", " ");
|
||||
try {
|
||||
SocketSessionUtil.send(session, content);
|
||||
SocketSessionUtil.send(session, htmlContent);
|
||||
} catch (IOException e) {
|
||||
DefaultSystemLog.ERROR().error("消息失败", e);
|
||||
try {
|
@ -14,7 +14,7 @@ import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
|
||||
import cn.keepbx.jpom.model.data.ProjectInfoModel;
|
||||
import cn.keepbx.jpom.service.manage.ProjectInfoService;
|
||||
import cn.keepbx.jpom.system.ExtConfigBean;
|
||||
import cn.keepbx.jpom.system.AgentExtConfigBean;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
@ -35,17 +35,18 @@ public class AutoBackLog {
|
||||
|
||||
@PreLoadMethod
|
||||
private static void startAutoBackLog() {
|
||||
// 开启秒级表达式
|
||||
CronUtil.setMatchSecond(true);
|
||||
if (projectInfoService == null) {
|
||||
projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
|
||||
}
|
||||
// 获取cron 表达式
|
||||
String cron = StrUtil.emptyToDefault(ExtConfigBean.getInstance().autoBackConsoleCron, "none");
|
||||
String cron = StrUtil.emptyToDefault(AgentExtConfigBean.getInstance().autoBackConsoleCron, "none");
|
||||
if ("none".equalsIgnoreCase(cron.trim())) {
|
||||
DefaultSystemLog.LOG().info("没有配置自动备份控制台日志表达式");
|
||||
return;
|
||||
}
|
||||
String size = StrUtil.emptyToDefault(ExtConfigBean.getInstance().autoBackSize, "50MB");
|
||||
String size = StrUtil.emptyToDefault(AgentExtConfigBean.getInstance().autoBackSize, "50MB");
|
||||
MAX_SIZE = FileSize.valueOf(size.trim());
|
||||
//
|
||||
CronUtil.schedule(ID, cron, () -> {
|
||||
@ -73,7 +74,7 @@ public class AutoBackLog {
|
||||
List<File> files = FileUtil.loopFiles(logFile, pathname -> {
|
||||
DateTime dateTime = DateUtil.date(pathname.lastModified());
|
||||
long days = DateUtil.betweenDay(dateTime, nowTime, false);
|
||||
long saveDays = ExtConfigBean.getInstance().getLogSaveDays();
|
||||
long saveDays = AgentExtConfigBean.getInstance().getLogSaveDays();
|
||||
return days > saveDays;
|
||||
});
|
||||
files.forEach(FileUtil::del);
|
@ -0,0 +1,19 @@
|
||||
package cn.keepbx.jpom.system.init;
|
||||
|
||||
import cn.jiangzeyin.common.PreLoadClass;
|
||||
import cn.jiangzeyin.common.PreLoadMethod;
|
||||
import cn.keepbx.jpom.system.AgentAuthorize;
|
||||
|
||||
/**
|
||||
* 检查授权信息
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/17
|
||||
*/
|
||||
@PreLoadClass
|
||||
public class CheckAuthorize {
|
||||
@PreLoadMethod
|
||||
private static void startAutoBackLog() {
|
||||
AgentAuthorize.getInstance();
|
||||
}
|
||||
}
|
20
modules/agent/src/main/resources/application.yml
Normal file
20
modules/agent/src/main/resources/application.yml
Normal file
@ -0,0 +1,20 @@
|
||||
#运行端口号
|
||||
server:
|
||||
port: 2123
|
||||
spring:
|
||||
application:
|
||||
name: jpomAgent
|
||||
profiles:
|
||||
active: dev
|
||||
banner:
|
||||
msg: Jpom-Agent管理系统启动中
|
||||
# session 超时时间
|
||||
tomcat:
|
||||
sessionTimeOut: 3600
|
||||
sessionCookieName: JPOMID-AGENT
|
||||
# 启动完成自动初始化指定包
|
||||
preload:
|
||||
packageName: cn.keepbx.jpom.system.init
|
||||
# 强制去掉空格
|
||||
request:
|
||||
trimAll: true
|
@ -1,16 +1,14 @@
|
||||
jpom:
|
||||
# jpom 数据存储路径, 如果调试模式运行默认路径为【/jpom/】,安装运行默认为jar包文件的父级
|
||||
path:
|
||||
authorize:
|
||||
# agent 端管理账号,必填。
|
||||
agentName: jpomAgent
|
||||
# agent 端管理密码,非必填,如果为空Jpom 会自动生成一串随机字符串当密码
|
||||
agentPwd:
|
||||
whitelistDirectory:
|
||||
# 白名单目录是否验证包含关系
|
||||
checkStartsWith: true
|
||||
user:
|
||||
# 最多能创建多少个用户
|
||||
maxCount: 10
|
||||
# 用户连续登录失败次数,超过此数将被限制登录
|
||||
alwaysLoginError: 5
|
||||
# 当ip连续登录失败,锁定对应IP时长,单位毫秒
|
||||
ipErrorLockTime: 60*60*5*1000
|
||||
log:
|
||||
# 自动备份控制台日志,防止日志文件过大,目前暂只支持linux 不停服备份
|
||||
autoBackConsoleCron: 0 0/10 * * * ?
|
103
modules/agent/src/test/java/DTest.java
Normal file
103
modules/agent/src/test/java/DTest.java
Normal file
@ -0,0 +1,103 @@
|
||||
//import cn.hutool.core.io.FileUtil;
|
||||
//import org.apache.commons.codec.binary.Base64;
|
||||
//import sun.misc.BASE64Decoder;
|
||||
//import sun.misc.BASE64Encoder;
|
||||
//
|
||||
//import java.io.BufferedInputStream;
|
||||
//import java.io.BufferedReader;
|
||||
//import java.io.File;
|
||||
//import java.io.FileReader;
|
||||
//import java.security.KeyFactory;
|
||||
//import java.security.PrivateKey;
|
||||
//import java.security.Signature;
|
||||
//import java.security.cert.Certificate;
|
||||
//import java.security.cert.CertificateFactory;
|
||||
//import java.security.cert.X509Certificate;
|
||||
//import java.security.spec.PKCS8EncodedKeySpec;
|
||||
//
|
||||
//public class DTest {
|
||||
//
|
||||
//
|
||||
// public static void main(String[] args) throws Exception {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private static void printTrack() {
|
||||
// StackTraceElement[] st = Thread.currentThread().getStackTrace();
|
||||
// StringBuilder sbf = new StringBuilder();
|
||||
// for (StackTraceElement e : st) {
|
||||
// if (sbf.length() > 0) {
|
||||
// sbf.append(" <- ");
|
||||
// sbf.append(System.getProperty("line.separator"));
|
||||
// }
|
||||
// sbf.append(java.text.MessageFormat.format("{0}.{1}() {2}"
|
||||
// , e.getClassName()
|
||||
// , e.getMethodName()
|
||||
// , e.getLineNumber()));
|
||||
// }
|
||||
// System.out.println(sbf.toString());
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private static void cert() throws Exception {
|
||||
// String plain = "aaaa";
|
||||
// File certFile = FileUtil.file("G:/soft/nginx/cert/full_chain.pem");
|
||||
// CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
// BufferedInputStream inStream = FileUtil.getInputStream(certFile);
|
||||
// // 创建证书对象
|
||||
// Certificate certificate = cf.generateCertificate(inStream);
|
||||
// inStream.close();
|
||||
//
|
||||
// String sigAlgName = ((X509Certificate) certificate).getSigAlgName();
|
||||
//
|
||||
// Signature instance = Signature.getInstance(sigAlgName);
|
||||
// PrivateKey privateKey = getPrivateKey(new File("G:/soft/nginx/cert/private.key"));
|
||||
// instance.initSign(privateKey);
|
||||
// instance.update(plain.getBytes());
|
||||
// byte[] signed = instance.sign();
|
||||
// BASE64Encoder encoder = new BASE64Encoder();
|
||||
// //签名
|
||||
// String encode = encoder.encode(signed);
|
||||
//
|
||||
// Signature signature = Signature.getInstance(sigAlgName);
|
||||
// signature.initVerify(certificate.getPublicKey());
|
||||
// signature.update(plain.getBytes());
|
||||
// BASE64Decoder decoder = new BASE64Decoder();
|
||||
// boolean verify = signature.verify(decoder.decodeBuffer(encode));
|
||||
// System.out.println(verify);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 利用java自带的方法读取openssl私钥,openssl私钥文件格式为pem,需要去除页眉页脚后,再进行base64位解码才能被java读取
|
||||
// * 注意该方法有缺陷,只是简单的根据注释将页眉页脚去掉了,不是很完善,如果页眉页脚前面有空格和注释的情况的会有问题,保留此方法是为方便弄清楚openssl私钥解析原理
|
||||
// */
|
||||
// private static PrivateKey getPrivateKey(File file) {
|
||||
// if (file == null) {
|
||||
// return null;
|
||||
// }
|
||||
// PrivateKey privKey;
|
||||
// try {
|
||||
// BufferedReader privateKey = new BufferedReader(new FileReader(
|
||||
// file));
|
||||
// String line;
|
||||
// StringBuilder strPrivateKey = new StringBuilder();
|
||||
// while ((line = privateKey.readLine()) != null) {
|
||||
// if (line.contains("--")) {//过滤掉首尾页眉页脚
|
||||
// continue;
|
||||
// }
|
||||
// strPrivateKey.append(line);
|
||||
// }
|
||||
// privateKey.close();
|
||||
// //使用base64位解码
|
||||
// byte[] privKeyByte = Base64.decodeBase64(strPrivateKey.toString());
|
||||
// //私钥需要使用pkcs8格式编码
|
||||
// PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(privKeyByte);
|
||||
// KeyFactory kf = KeyFactory.getInstance("RSA");
|
||||
// privKey = kf.generatePrivate(privKeySpec);
|
||||
// return privKey;
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//}
|
232
modules/agent/src/test/java/FileUtil.java
Normal file
232
modules/agent/src/test/java/FileUtil.java
Normal file
@ -0,0 +1,232 @@
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
public static int BUFFER_SIZE = 2048;
|
||||
|
||||
private static List<String> unTar(InputStream inputStream, String destDir) throws Exception {
|
||||
List<String> fileNames = new ArrayList<String>();
|
||||
TarArchiveInputStream tarIn = new TarArchiveInputStream(inputStream, BUFFER_SIZE);
|
||||
TarArchiveEntry entry = null;
|
||||
try {
|
||||
while ((entry = tarIn.getNextTarEntry()) != null) {
|
||||
fileNames.add(entry.getName());
|
||||
if (entry.isDirectory()) {
|
||||
//是目录
|
||||
createDirectory(destDir, entry.getName());
|
||||
//创建空目录
|
||||
} else {
|
||||
System.out.println(entry.getName());
|
||||
//是文件
|
||||
File tmpFile = new File(destDir + File.separator + entry.getName());
|
||||
//创建输出目录
|
||||
createDirectory(tmpFile.getParent() + File.separator, null);
|
||||
OutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(tmpFile);
|
||||
int length = 0;
|
||||
byte[] b = new byte[2048];
|
||||
while ((length = tarIn.read(b)) != -1) {
|
||||
out.write(b, 0, length);
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
IOUtils.closeQuietly(tarIn);
|
||||
}
|
||||
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
public static List<String> unTar(String tarFile, String destDir) throws Exception {
|
||||
File file = new File(tarFile);
|
||||
return unTar(file, destDir);
|
||||
}
|
||||
|
||||
public static List<String> unTar(File tarFile, String destDir) throws Exception {
|
||||
if (StrUtil.isBlank(destDir)) {
|
||||
destDir = tarFile.getParent();
|
||||
}
|
||||
destDir = destDir.endsWith(File.separator) ? destDir : destDir + File.separator;
|
||||
return unTar(new FileInputStream(tarFile), destDir);
|
||||
}
|
||||
|
||||
public static List<String> unTarBZip2(File tarFile, String destDir) throws Exception {
|
||||
if (StrUtil.isBlank(destDir)) {
|
||||
destDir = tarFile.getParent();
|
||||
}
|
||||
destDir = destDir.endsWith(File.separator) ? destDir : destDir + File.separator;
|
||||
return unTar(new BZip2CompressorInputStream(new FileInputStream(tarFile)), destDir);
|
||||
}
|
||||
|
||||
public static List<String> unTarBZip2(String file, String destDir) throws Exception {
|
||||
File tarFile = new File(file);
|
||||
return unTarBZip2(tarFile, destDir);
|
||||
}
|
||||
|
||||
public static List<String> unBZip2(String bzip2File, String destDir) throws IOException {
|
||||
File file = new File(bzip2File);
|
||||
return unBZip2(file, destDir);
|
||||
}
|
||||
|
||||
public static List<String> unBZip2(File srcFile, String destDir) throws IOException {
|
||||
if (StrUtil.isBlank(destDir)) {
|
||||
destDir = srcFile.getParent();
|
||||
}
|
||||
destDir = destDir.endsWith(File.separator) ? destDir : destDir + File.separator;
|
||||
List<String> fileNames = new ArrayList<>();
|
||||
InputStream is = null;
|
||||
OutputStream os = null;
|
||||
try {
|
||||
File destFile = new File(destDir, srcFile.getName());
|
||||
fileNames.add(srcFile.getName());
|
||||
is = new BZip2CompressorInputStream(new BufferedInputStream(new FileInputStream(srcFile), BUFFER_SIZE));
|
||||
os = new BufferedOutputStream(new FileOutputStream(destFile), BUFFER_SIZE);
|
||||
IOUtils.copy(is, os);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(os);
|
||||
IOUtils.closeQuietly(is);
|
||||
}
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
public static List<String> unGZ(String gzFile, String destDir) throws IOException {
|
||||
File file = new File(gzFile);
|
||||
return unGZ(file, destDir);
|
||||
}
|
||||
|
||||
public static List<String> unGZ(File srcFile, String destDir) throws IOException {
|
||||
if (StrUtil.isBlank(destDir)) {
|
||||
destDir = srcFile.getParent();
|
||||
}
|
||||
destDir = destDir.endsWith(File.separator) ? destDir : destDir + File.separator;
|
||||
List<String> fileNames = new ArrayList<String>();
|
||||
InputStream is = null;
|
||||
OutputStream os = null;
|
||||
try {
|
||||
File destFile = new File(destDir, srcFile.getName());
|
||||
fileNames.add(srcFile.getName());
|
||||
is = new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(srcFile), BUFFER_SIZE));
|
||||
os = new BufferedOutputStream(new FileOutputStream(destFile), BUFFER_SIZE);
|
||||
IOUtils.copy(is, os);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(os);
|
||||
IOUtils.closeQuietly(is);
|
||||
}
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
public static List<String> unTarGZ(File tarFile, String destDir) throws Exception {
|
||||
if (StrUtil.isBlank(destDir)) {
|
||||
destDir = tarFile.getParent();
|
||||
}
|
||||
destDir = destDir.endsWith(File.separator) ? destDir : destDir + File.separator;
|
||||
return unTar(new GzipCompressorInputStream(new FileInputStream(tarFile)), destDir);
|
||||
}
|
||||
|
||||
public static List<String> unTarGZ(String file, String destDir) throws Exception {
|
||||
File tarFile = new File(file);
|
||||
return unTarGZ(tarFile, destDir);
|
||||
}
|
||||
|
||||
public static void createDirectory(String outputDir, String subDir) {
|
||||
File file = new File(outputDir);
|
||||
if (!(subDir == null || "".equals(subDir.trim()))) {
|
||||
//子目录不为空
|
||||
file = new File(outputDir + File.separator + subDir);
|
||||
}
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> unZip(File zipfile, String destDir) throws Exception {
|
||||
if (StrUtil.isBlank(destDir)) {
|
||||
destDir = zipfile.getParent();
|
||||
}
|
||||
destDir = destDir.endsWith(File.separator) ? destDir : destDir + File.separator;
|
||||
ZipArchiveInputStream is = null;
|
||||
List<String> fileNames = new ArrayList<String>();
|
||||
|
||||
try {
|
||||
is = new ZipArchiveInputStream(new BufferedInputStream(new FileInputStream(zipfile), BUFFER_SIZE));
|
||||
ZipArchiveEntry entry = null;
|
||||
while ((entry = is.getNextZipEntry()) != null) {
|
||||
fileNames.add(entry.getName());
|
||||
if (entry.isDirectory()) {
|
||||
File directory = new File(destDir, entry.getName());
|
||||
directory.mkdirs();
|
||||
} else {
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new BufferedOutputStream(new FileOutputStream(new File(destDir, entry.getName())), BUFFER_SIZE);
|
||||
IOUtils.copy(is, os);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
IOUtils.closeQuietly(is);
|
||||
}
|
||||
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
public static List<String> unZip(String zipfile, String destDir) throws Exception {
|
||||
File zipFile = new File(zipfile);
|
||||
return unZip(zipFile, destDir);
|
||||
}
|
||||
|
||||
public static List<String> unCompress(String compressFile, String destDir) throws Exception {
|
||||
String upperName = compressFile.toUpperCase();
|
||||
List<String> ret = null;
|
||||
if (upperName.endsWith(".ZIP")) {
|
||||
ret = unZip(compressFile, destDir);
|
||||
} else if (upperName.endsWith(".TAR")) {
|
||||
ret = unTar(compressFile, destDir);
|
||||
} else if (upperName.endsWith(".TAR.BZ2")) {
|
||||
ret = unTarBZip2(compressFile, destDir);
|
||||
} else if (upperName.endsWith(".BZ2")) {
|
||||
ret = unBZip2(compressFile, destDir);
|
||||
} else if (upperName.endsWith(".TAR.GZ")) {
|
||||
ret = unTarGZ(compressFile, destDir);
|
||||
} else if (upperName.endsWith(".GZ")) {
|
||||
ret = unGZ(compressFile, destDir);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
unCompress("D:\\SystemDocument\\Desktop\\Desktop.tar.gz", "D:\\SystemDocument\\Desktop\\Desktop-test");
|
||||
//System.out.println(unZip("F:\\fileupload\\dna-sample.zip", "F:\\fileupload\\"));
|
||||
// System.out.println(unTar("F:\\fileupload\\中文test.tar", "F:\\fileupload\\"));
|
||||
|
||||
//System.out.println(unBZip2("F:\\fileupload\\中文test.xml.bz2", "F:\\fileupload\\"));
|
||||
//System.out.println(unTarBZip2("F:\\fileupload\\中文test.tar.bz2", "F:\\fileupload\\"));
|
||||
|
||||
//System.out.println(unGZ("F:\\fileupload\\test.xml.gz", "F:\\fileupload\\"));
|
||||
//System.out.println(unTarGZ("F:\\fileupload\\all.tar.gz", "F:\\fileupload\\"));
|
||||
}
|
||||
}
|
33
modules/agent/src/test/java/TestFile.java
Normal file
33
modules/agent/src/test/java/TestFile.java
Normal file
@ -0,0 +1,33 @@
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Created by jiangzeyin on 2019/4/22.
|
||||
*/
|
||||
public class TestFile {
|
||||
public static void main(String[] args) throws IOException {
|
||||
InputStream inputStream = new FileInputStream("D:\\SystemDocument\\Desktop\\Desktop.zip");
|
||||
|
||||
String code = IoUtil.readHex28Upper(inputStream);
|
||||
System.out.println(code);
|
||||
|
||||
System.out.println(FileUtil.getMimeType("D:\\SystemDocument\\Desktop\\Desktop.zip"));
|
||||
|
||||
|
||||
System.out.println(FileUtil.getMimeType("D:\\SystemDocument\\Desktop\\Desktop.tar.gz"));
|
||||
|
||||
System.out.println(FileUtil.getMimeType("D:\\SystemDocument\\Desktop\\Desktop.7z"));
|
||||
|
||||
ZipUtil.unzip(new File("D:\\SystemDocument\\Desktop\\Desktop.tar.gz"), new File("D:\\SystemDocument\\Desktop\\Desktop.7z\""));
|
||||
|
||||
ZipUtil.unzip(new File("D:\\SystemDocument\\Desktop\\Desktop.7z"), new File("D:\\SystemDocument\\Desktop\\Desktop.7z\""));
|
||||
|
||||
System.out.println(FileUtil.extName("test.zip"));
|
||||
}
|
||||
}
|
60
modules/agent/src/test/java/com/jinhill/pki/CertUtil.java
Normal file
60
modules/agent/src/test/java/com/jinhill/pki/CertUtil.java
Normal file
@ -0,0 +1,60 @@
|
||||
package com.jinhill.pki;
|
||||
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.security.Security;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
public class CertUtil {
|
||||
static {
|
||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
}
|
||||
|
||||
public static String getSubjectDN(InputStream bIn) {
|
||||
String dn = "";
|
||||
try {
|
||||
|
||||
// BouncyCastleProvider provider = new BouncyCastleProvider();
|
||||
// CertificateFactory cf = CertificateFactory.getInstance("X509",
|
||||
// provider);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509",
|
||||
"SUN");
|
||||
//android 需采用bcprov
|
||||
// CertificateFactory cf = CertificateFactory.getInstance("X.509",
|
||||
// "BC");
|
||||
X509Certificate cert = (X509Certificate) cf
|
||||
.generateCertificate(bIn);
|
||||
dn = cert.getSubjectDN().getName();
|
||||
bIn.close();
|
||||
} catch (CertificateException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return dn;
|
||||
}
|
||||
|
||||
public static String parseCertDN(String dn, String type) {
|
||||
type = type + "=";
|
||||
String[] split = dn.split(",");
|
||||
for (String x : split) {
|
||||
if (x.contains(type)) {
|
||||
x = x.trim();
|
||||
return x.substring(type.length());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// TODO Auto-generated method stub
|
||||
InputStream inputStream = ResourceUtil.getStream("D:\\jpom\\agent\\data\\temp\\系统管理员\\sdfasdf\\example.com.csr");
|
||||
getSubjectDN(inputStream);
|
||||
}
|
||||
}
|
20
modules/common/pom.xml
Normal file
20
modules/common/pom.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?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>
|
||||
<artifactId>jpom</artifactId>
|
||||
<groupId>cn.keepbx</groupId>
|
||||
<version>2.4.0</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>cn.keepbx.jpom</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>2.4.0</version>
|
||||
|
||||
<dependencies>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,69 @@
|
||||
package cn.keepbx.jpom;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.system.OsInfo;
|
||||
import cn.hutool.system.SystemUtil;
|
||||
import cn.keepbx.jpom.common.Type;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* Jpom
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
public abstract class BaseJpomApplication {
|
||||
|
||||
public static final OsInfo OS_INFO = SystemUtil.getOsInfo();
|
||||
|
||||
protected static String[] args;
|
||||
/**
|
||||
* 应用类型
|
||||
*/
|
||||
private static Type appType;
|
||||
private static Charset charset;
|
||||
|
||||
private static Class appClass;
|
||||
|
||||
/**
|
||||
* 获取程序命令行参数
|
||||
*
|
||||
* @return 数组
|
||||
*/
|
||||
public static String[] getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public BaseJpomApplication(Type appType, Class appClass) {
|
||||
BaseJpomApplication.appType = appType;
|
||||
BaseJpomApplication.appClass = appClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前系统编码
|
||||
*
|
||||
* @return charset
|
||||
*/
|
||||
public static Charset getCharset() {
|
||||
if (charset == null) {
|
||||
if (OS_INFO.isLinux()) {
|
||||
charset = CharsetUtil.CHARSET_UTF_8;
|
||||
} else {
|
||||
charset = CharsetUtil.CHARSET_GBK;
|
||||
}
|
||||
}
|
||||
return charset;
|
||||
}
|
||||
|
||||
public static Type getAppType() {
|
||||
return appType;
|
||||
}
|
||||
|
||||
public static Class getAppClass() {
|
||||
if (appClass == null) {
|
||||
return BaseJpomApplication.class;
|
||||
}
|
||||
return appClass;
|
||||
}
|
||||
}
|
109
modules/common/src/main/java/cn/keepbx/jpom/JpomClose.java
Normal file
109
modules/common/src/main/java/cn/keepbx/jpom/JpomClose.java
Normal file
@ -0,0 +1,109 @@
|
||||
package cn.keepbx.jpom;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.keepbx.jpom.util.ArgsUtil;
|
||||
import cn.keepbx.jpom.util.CommandUtil;
|
||||
import cn.keepbx.jpom.util.JvmUtil;
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 命令行关闭Jpom
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/7
|
||||
*/
|
||||
public class JpomClose {
|
||||
private static JpomClose jpomManager;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args == null || args.length <= 0) {
|
||||
Console.error("请传入正确的参数");
|
||||
return;
|
||||
}
|
||||
String tag = ArgsUtil.getArgsValue(args, "jpom.applicationTag");
|
||||
if (StrUtil.isEmpty(tag)) {
|
||||
Console.error("请传入对应:jpom.applicationTag");
|
||||
return;
|
||||
}
|
||||
// 事件
|
||||
String event = ArgsUtil.getArgsValue(args, "event");
|
||||
if ("stop".equalsIgnoreCase(event)) {
|
||||
String status = JpomClose.getInstance().status(tag);
|
||||
if (!status.contains(StrUtil.COLON)) {
|
||||
Console.error("Jpom并没有运行");
|
||||
return;
|
||||
}
|
||||
String msg = JpomClose.getInstance().stop(tag);
|
||||
Console.log(msg);
|
||||
} else if ("status".equalsIgnoreCase(event)) {
|
||||
String status = JpomClose.getInstance().status(tag);
|
||||
Console.log(status);
|
||||
} else {
|
||||
Console.error("event error:" + event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 单利模式
|
||||
*
|
||||
* @return JpomClose
|
||||
*/
|
||||
public static JpomClose getInstance() {
|
||||
if (jpomManager != null) {
|
||||
return jpomManager;
|
||||
}
|
||||
if (BaseJpomApplication.OS_INFO.isLinux()) {
|
||||
jpomManager = new Linux();
|
||||
} else {
|
||||
jpomManager = new Windows();
|
||||
}
|
||||
return jpomManager;
|
||||
}
|
||||
|
||||
|
||||
public String stop(String tag) throws IOException {
|
||||
VirtualMachine virtualMachine = JvmUtil.getVirtualMachine(tag);
|
||||
if (virtualMachine == null) {
|
||||
return null;
|
||||
}
|
||||
return virtualMachine.id();
|
||||
}
|
||||
|
||||
public String status(String tag) throws IOException {
|
||||
VirtualMachine virtualMachine = JvmUtil.getVirtualMachine(tag);
|
||||
if (virtualMachine == null) {
|
||||
return "Jpom并没有运行";
|
||||
}
|
||||
return "Jpom运行中:" + virtualMachine.id();
|
||||
}
|
||||
|
||||
|
||||
private static class Windows extends JpomClose {
|
||||
|
||||
@Override
|
||||
public String stop(String tag) throws IOException {
|
||||
String pid = super.stop(tag);
|
||||
if (pid == null) {
|
||||
return "stop";
|
||||
}
|
||||
String cmd = String.format("taskkill /F /PID %s", pid);
|
||||
return CommandUtil.execCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Linux extends JpomClose {
|
||||
|
||||
@Override
|
||||
public String stop(String tag) throws IOException {
|
||||
String pid = super.stop(tag);
|
||||
if (pid == null) {
|
||||
return "stop";
|
||||
}
|
||||
String cmd = String.format("kill %s", pid);
|
||||
return CommandUtil.execCommand(cmd);
|
||||
}
|
||||
}
|
||||
}
|
@ -60,7 +60,7 @@ public abstract class BaseDataService {
|
||||
* @param filename 文件名
|
||||
* @param json json数据
|
||||
*/
|
||||
protected void updateJson(String filename, JSONObject json) throws Exception {
|
||||
protected void updateJson(String filename, JSONObject json) {
|
||||
String key = json.getString("id");
|
||||
// 读取文件,如果不存在记录,则抛出异常
|
||||
JSONObject allData = getJSONObject(filename);
|
||||
@ -68,7 +68,7 @@ public abstract class BaseDataService {
|
||||
|
||||
// 判断是否存在数据
|
||||
if (null == data || 0 == data.keySet().size()) {
|
||||
throw new Exception("数据不存在:" + key);
|
||||
throw new JpomRuntimeException("数据不存在:" + key);
|
||||
} else {
|
||||
allData.put(key, json);
|
||||
JsonFileUtil.saveJson(getDataFilePath(filename), allData);
|
||||
@ -80,15 +80,14 @@ public abstract class BaseDataService {
|
||||
*
|
||||
* @param filename 文件
|
||||
* @param key key
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
protected void deleteJson(String filename, String key) throws Exception {
|
||||
protected void deleteJson(String filename, String key) {
|
||||
// 读取文件,如果存在记录,则抛出异常
|
||||
JSONObject allData = getJSONObject(filename);
|
||||
JSONObject data = allData.getJSONObject(key);
|
||||
// 判断是否存在数据
|
||||
if (CollUtil.isEmpty(data)) {
|
||||
throw new Exception("项目名称存不在!");
|
||||
throw new JpomRuntimeException("项目名称存不在!");
|
||||
} else {
|
||||
allData.remove(key);
|
||||
JsonFileUtil.saveJson(getDataFilePath(filename), allData);
|
@ -0,0 +1,39 @@
|
||||
package cn.keepbx.jpom.common;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.controller.base.AbstractController;
|
||||
|
||||
/**
|
||||
* controller
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
public abstract class BaseJpomController extends AbstractController {
|
||||
/**
|
||||
* 路径安全格式化
|
||||
*
|
||||
* @param path 路径
|
||||
* @return 去掉 提权字符串
|
||||
*/
|
||||
public static String pathSafe(String path) {
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
String newPath = path.replace("../", StrUtil.EMPTY);
|
||||
newPath = newPath.replace("..\\", StrUtil.EMPTY);
|
||||
newPath = newPath.replace("+", StrUtil.EMPTY);
|
||||
return FileUtil.normalize(newPath);
|
||||
}
|
||||
|
||||
protected boolean checkPathSafe(String path) {
|
||||
if (path == null) {
|
||||
return false;
|
||||
}
|
||||
String newPath = path.replace("../", StrUtil.EMPTY);
|
||||
newPath = newPath.replace("..\\", StrUtil.EMPTY);
|
||||
newPath = newPath.replace("+", StrUtil.EMPTY);
|
||||
return newPath.equals(path);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.spring.event.ApplicationEventClient;
|
||||
import cn.keepbx.jpom.BaseJpomApplication;
|
||||
import cn.keepbx.jpom.model.system.JpomManifest;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
@ -14,8 +15,6 @@ import org.springframework.context.event.ContextClosedEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.nio.channels.OverlappingFileLockException;
|
||||
@ -31,10 +30,7 @@ public class JpomApplicationEvent implements ApplicationEventClient {
|
||||
private FileLock lock;
|
||||
private FileOutputStream fileOutputStream;
|
||||
private FileChannel fileChannel;
|
||||
/**
|
||||
* 记录当前程序进程
|
||||
*/
|
||||
private static int PID = 0;
|
||||
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
@ -50,15 +46,23 @@ public class JpomApplicationEvent implements ApplicationEventClient {
|
||||
}
|
||||
// 写入Jpom 信息
|
||||
JpomManifest jpomManifest = JpomManifest.getInstance();
|
||||
File jpomInfo = ConfigBean.getInstance().getJpomInfo();
|
||||
FileUtil.writeString(jpomManifest.toString(), jpomInfo, CharsetUtil.CHARSET_UTF_8);
|
||||
// 写入全局信息
|
||||
File appJpomFile = ConfigBean.getInstance().getApplicationJpomInfo(BaseJpomApplication.getAppType());
|
||||
FileUtil.writeString(jpomManifest.toString(), appJpomFile, CharsetUtil.CHARSET_UTF_8);
|
||||
} else if (event instanceof ContextClosedEvent) {
|
||||
// 应用关闭
|
||||
this.unLockFile();
|
||||
//
|
||||
FileUtil.del(ConfigBean.getInstance().getPidFile());
|
||||
//
|
||||
File appJpomFile = ConfigBean.getInstance().getApplicationJpomInfo(BaseJpomApplication.getAppType());
|
||||
FileUtil.del(appJpomFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁进程文件
|
||||
*/
|
||||
private void unLockFile() {
|
||||
if (lock != null) {
|
||||
try {
|
||||
@ -93,23 +97,4 @@ public class JpomApplicationEvent implements ApplicationEventClient {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前程序进程id
|
||||
*
|
||||
* @return pid
|
||||
*/
|
||||
public static int getPid() {
|
||||
if (PID == 0) {
|
||||
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
|
||||
// format: "pid@hostname"
|
||||
String name = runtime.getName();
|
||||
try {
|
||||
PID = Integer.parseInt(name.substring(0, name.indexOf('@')));
|
||||
} catch (Exception e) {
|
||||
PID = -1;
|
||||
}
|
||||
}
|
||||
return PID;
|
||||
}
|
||||
}
|
18
modules/common/src/main/java/cn/keepbx/jpom/common/Type.java
Normal file
18
modules/common/src/main/java/cn/keepbx/jpom/common/Type.java
Normal file
@ -0,0 +1,18 @@
|
||||
package cn.keepbx.jpom.common;
|
||||
|
||||
/**
|
||||
* Jpom 程序类型
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/17
|
||||
*/
|
||||
public enum Type {
|
||||
/**
|
||||
* 插件端
|
||||
*/
|
||||
Agent,
|
||||
/**
|
||||
* 中心服务端
|
||||
*/
|
||||
Server
|
||||
}
|
@ -8,6 +8,15 @@ package cn.keepbx.jpom.model;
|
||||
*/
|
||||
public abstract class BaseModel extends BaseJsonModel {
|
||||
private String id;
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
@ -1,4 +1,4 @@
|
||||
package cn.keepbx.jpom.common;
|
||||
package cn.keepbx.jpom.model;
|
||||
|
||||
/**
|
||||
* 用户角色
|
||||
@ -12,9 +12,13 @@ public enum Role {
|
||||
*/
|
||||
System,
|
||||
/**
|
||||
* 普通管理员
|
||||
* 服务端管理员
|
||||
*/
|
||||
Manage,
|
||||
ServerManager,
|
||||
/**
|
||||
* 节点管理员
|
||||
*/
|
||||
NodeManage,
|
||||
/**
|
||||
* 用户
|
||||
*/
|
@ -0,0 +1,18 @@
|
||||
package cn.keepbx.jpom.model;
|
||||
|
||||
/**
|
||||
* 项目的运行方式
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/22
|
||||
*/
|
||||
public enum RunMode {
|
||||
/**
|
||||
* java -classpath
|
||||
*/
|
||||
ClassPath,
|
||||
/**
|
||||
* java -jar
|
||||
*/
|
||||
Jar,
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package cn.keepbx.jpom.model.data;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.keepbx.jpom.common.BaseJpomController;
|
||||
import cn.keepbx.jpom.model.BaseJsonModel;
|
||||
import cn.keepbx.jpom.system.ExtConfigBean;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 白名单
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
public class AgentWhitelist extends BaseJsonModel {
|
||||
private List<String> project;
|
||||
private List<String> certificate;
|
||||
private List<String> nginx;
|
||||
|
||||
public List<String> getProject() {
|
||||
return project;
|
||||
}
|
||||
|
||||
public void setProject(List<String> project) {
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
public List<String> getCertificate() {
|
||||
return certificate;
|
||||
}
|
||||
|
||||
public void setCertificate(List<String> certificate) {
|
||||
this.certificate = certificate;
|
||||
}
|
||||
|
||||
public List<String> getNginx() {
|
||||
return nginx;
|
||||
}
|
||||
|
||||
public void setNginx(List<String> nginx) {
|
||||
this.nginx = nginx;
|
||||
}
|
||||
|
||||
|
||||
public static List<String> covertToArray(List<String> list) {
|
||||
List<String> array = new ArrayList<>();
|
||||
for (String s : list) {
|
||||
String val = String.format("/%s/", s);
|
||||
val = BaseJpomController.pathSafe(val);
|
||||
if (StrUtil.SLASH.equals(val)) {
|
||||
continue;
|
||||
}
|
||||
if (array.contains(val)) {
|
||||
continue;
|
||||
}
|
||||
// 判断是否保护jpom 路径
|
||||
if (val == null || val.startsWith(ExtConfigBean.getInstance().getPath())) {
|
||||
return null;
|
||||
}
|
||||
array.add(val);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为字符串
|
||||
*
|
||||
* @param jsonArray jsonArray
|
||||
* @return str
|
||||
*/
|
||||
public static String convertToLine(List<String> jsonArray) {
|
||||
try {
|
||||
return CollUtil.join(jsonArray, "\r\n");
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.ERROR().error(e.getMessage(), e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否在白名单列表中
|
||||
*
|
||||
* @param list list
|
||||
* @param path 对应项
|
||||
* @return false 不在列表中
|
||||
*/
|
||||
public static boolean checkPath(List<String> list, String path) {
|
||||
if (list == null) {
|
||||
return false;
|
||||
}
|
||||
if (StrUtil.isEmpty(path)) {
|
||||
return false;
|
||||
}
|
||||
File file1, file2 = FileUtil.file(path);
|
||||
for (String item : list) {
|
||||
file1 = FileUtil.file(item);
|
||||
if (FileUtil.pathEquals(file1, file2)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package cn.keepbx.jpom.model.system;
|
||||
|
||||
import cn.keepbx.jpom.model.BaseJsonModel;
|
||||
|
||||
/**
|
||||
* agent 端自动生成的密码实体
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/18
|
||||
*/
|
||||
public class AgentAutoUser extends BaseJsonModel {
|
||||
|
||||
private String agentName;
|
||||
private String agentPwd;
|
||||
|
||||
public String getAgentName() {
|
||||
return agentName;
|
||||
}
|
||||
|
||||
public void setAgentName(String agentName) {
|
||||
this.agentName = agentName;
|
||||
}
|
||||
|
||||
public String getAgentPwd() {
|
||||
return agentPwd;
|
||||
}
|
||||
|
||||
public void setAgentPwd(String agentPwd) {
|
||||
this.agentPwd = agentPwd;
|
||||
}
|
||||
}
|
@ -2,10 +2,14 @@ package cn.keepbx.jpom.model.system;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.keepbx.jpom.JpomApplication;
|
||||
import cn.keepbx.jpom.common.JpomApplicationEvent;
|
||||
import cn.hutool.system.SystemUtil;
|
||||
import cn.keepbx.jpom.BaseJpomApplication;
|
||||
import cn.keepbx.jpom.common.Type;
|
||||
import cn.keepbx.jpom.system.ConfigBean;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.springframework.boot.ApplicationHome;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -20,11 +24,38 @@ import java.util.jar.Manifest;
|
||||
* @date 2019/4/7
|
||||
*/
|
||||
public class JpomManifest {
|
||||
private static final JpomManifest JPOM_MANIFEST;
|
||||
private static JpomManifest JPOM_MANIFEST;
|
||||
/**
|
||||
* 当前版本
|
||||
*/
|
||||
private String version = "dev";
|
||||
/**
|
||||
* 打包时间
|
||||
*/
|
||||
private String timeStamp;
|
||||
/**
|
||||
* 进程id
|
||||
*/
|
||||
private long pid = SystemUtil.getCurrentPID();
|
||||
/**
|
||||
* 当前运行类型
|
||||
*/
|
||||
private Type type = BaseJpomApplication.getAppType();
|
||||
/**
|
||||
* 端口号
|
||||
*/
|
||||
private int port;
|
||||
/**
|
||||
* Jpom 的数据目录
|
||||
*/
|
||||
private String dataPath;
|
||||
|
||||
static {
|
||||
private static synchronized void init() {
|
||||
if (JPOM_MANIFEST != null) {
|
||||
return;
|
||||
}
|
||||
JPOM_MANIFEST = new JpomManifest();
|
||||
File jarFile = JpomApplication.getRunPath();
|
||||
File jarFile = getRunPath();
|
||||
if (jarFile.isFile()) {
|
||||
JarFile jarFile1;
|
||||
try {
|
||||
@ -52,26 +83,15 @@ public class JpomManifest {
|
||||
* @return this
|
||||
*/
|
||||
public static JpomManifest getInstance() {
|
||||
init();
|
||||
return JPOM_MANIFEST;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前版本
|
||||
*/
|
||||
private String version = "dev";
|
||||
/**
|
||||
* 打包时间
|
||||
*/
|
||||
private String timeStamp;
|
||||
/**
|
||||
* 进程id
|
||||
*/
|
||||
private int pid;
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getPid() {
|
||||
if (pid == 0) {
|
||||
this.pid = JpomApplicationEvent.getPid();
|
||||
}
|
||||
public long getPid() {
|
||||
return pid;
|
||||
}
|
||||
|
||||
@ -109,15 +129,57 @@ public class JpomManifest {
|
||||
*/
|
||||
public void setTimeStamp(String timeStamp) {
|
||||
if (StrUtil.isNotEmpty(timeStamp)) {
|
||||
DateTime dateTime = DateUtil.parseUTC(timeStamp);
|
||||
this.timeStamp = dateTime.toStringDefaultTimeZone();
|
||||
try {
|
||||
DateTime dateTime = DateUtil.parseUTC(timeStamp);
|
||||
this.timeStamp = dateTime.toStringDefaultTimeZone();
|
||||
} catch (Exception e) {
|
||||
this.timeStamp = timeStamp;
|
||||
}
|
||||
} else {
|
||||
this.timeStamp = timeStamp;
|
||||
this.timeStamp = "dev";
|
||||
}
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* 程序运行的端口
|
||||
*
|
||||
* @return 端口
|
||||
*/
|
||||
public int getPort() {
|
||||
if (port == 0) {
|
||||
port = ConfigBean.getInstance().getPort();
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
public String getDataPath() {
|
||||
if (StrUtil.isEmpty(dataPath)) {
|
||||
dataPath = ConfigBean.getInstance().getDataPath();
|
||||
}
|
||||
return dataPath;
|
||||
}
|
||||
|
||||
public void setDataPath(String dataPath) {
|
||||
this.dataPath = dataPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前运行的路径
|
||||
*
|
||||
* @return jar 或者classPath
|
||||
*/
|
||||
public static File getRunPath() {
|
||||
ApplicationHome home = new ApplicationHome(BaseJpomApplication.getAppClass());
|
||||
String path = (home.getSource() == null ? "" : home.getSource().getAbsolutePath());
|
||||
return FileUtil.file(path);
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package cn.keepbx.jpom.socket;
|
||||
|
||||
/**
|
||||
* socket 操作枚举
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
public enum CommandOp {
|
||||
/**
|
||||
* 启动
|
||||
*/
|
||||
start,
|
||||
stop,
|
||||
restart,
|
||||
status,
|
||||
/**
|
||||
* 运行日志
|
||||
*/
|
||||
showlog,
|
||||
/**
|
||||
* 查看内存信息
|
||||
*/
|
||||
top,
|
||||
/**
|
||||
* 心跳
|
||||
*/
|
||||
heart
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package cn.keepbx.jpom.socket;
|
||||
|
||||
/**
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/19
|
||||
*/
|
||||
public class CommonSocketConfig {
|
||||
|
||||
|
||||
public static final String SYSTEM_ID = "system";
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package cn.keepbx.jpom.system;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
|
||||
/**
|
||||
* 日志接口
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/19
|
||||
*/
|
||||
public interface AopLogInterface {
|
||||
/**
|
||||
* 进入前
|
||||
*
|
||||
* @param joinPoint point
|
||||
*/
|
||||
void before(JoinPoint joinPoint);
|
||||
|
||||
/**
|
||||
* 执行后
|
||||
*
|
||||
* @param value 结果
|
||||
*/
|
||||
void afterReturning(Object value);
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
package cn.keepbx.jpom.system;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.system.SystemUtil;
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import cn.keepbx.jpom.BaseJpomApplication;
|
||||
import cn.keepbx.jpom.common.Type;
|
||||
import cn.keepbx.jpom.model.system.JpomManifest;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 配置项
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
@Configuration
|
||||
public class ConfigBean {
|
||||
/**
|
||||
* 用户角色header
|
||||
*/
|
||||
public static final String JPOM_SERVER_SYSTEM_USER_ROLE = "Jpom-Server-SystemUserRole";
|
||||
/**
|
||||
* 用户名header
|
||||
*/
|
||||
public static final String JPOM_SERVER_USER_NAME = "Jpom-Server-UserName";
|
||||
|
||||
public static final String JPOM_AGENT_AUTHORIZE = "Jpom-Agent-Authorize";
|
||||
|
||||
private static final String DATA = "data";
|
||||
|
||||
public static final int AUTHORIZE_ERROR = 900;
|
||||
|
||||
/**
|
||||
* 授权信息
|
||||
*/
|
||||
private static final String AUTHORIZE = "agent_authorize.json";
|
||||
|
||||
/**
|
||||
* Jpom 程序运行的 application 标识
|
||||
*/
|
||||
@Value("${jpom.applicationTag:}")
|
||||
public String applicationTag;
|
||||
/**
|
||||
* 程序端口
|
||||
*/
|
||||
@Value("${server.port}")
|
||||
private int port;
|
||||
|
||||
private static ConfigBean configBean;
|
||||
|
||||
/**
|
||||
* 单利模式
|
||||
*
|
||||
* @return config
|
||||
*/
|
||||
public static ConfigBean getInstance() {
|
||||
if (configBean == null) {
|
||||
configBean = SpringUtil.getBean(ConfigBean.class);
|
||||
}
|
||||
return configBean;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目运行数据存储文件夹路径
|
||||
*
|
||||
* @return 文件夹路径
|
||||
*/
|
||||
public String getDataPath() {
|
||||
String dataPath = FileUtil.normalize(ExtConfigBean.getInstance().getPath() + "/" + DATA);
|
||||
FileUtil.mkdir(dataPath);
|
||||
return dataPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取pid文件
|
||||
*
|
||||
* @return file
|
||||
*/
|
||||
public File getPidFile() {
|
||||
return new File(getDataPath(), StrUtil.format("pid.{}.{}",
|
||||
BaseJpomApplication.getAppType().name(), JpomManifest.getInstance().getPid()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前项目全局 运行信息文件路径
|
||||
*
|
||||
* @param type 程序类型
|
||||
* @return file
|
||||
*/
|
||||
public File getApplicationJpomInfo(Type type) {
|
||||
return FileUtil.file(SystemUtil.getUserInfo().getTempDir(), "jpom", type.name());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 agent 端自动生成的授权文件路径
|
||||
*
|
||||
* @param dataPath 指定数据路径
|
||||
* @return file
|
||||
*/
|
||||
public String getAgentAutoAuthorizeFile(String dataPath) {
|
||||
return FileUtil.normalize(dataPath + "/" + ConfigBean.AUTHORIZE);
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package cn.keepbx.jpom.system;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import cn.keepbx.jpom.BaseJpomApplication;
|
||||
import cn.keepbx.jpom.model.system.JpomManifest;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 外部资源配置
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2019/4/16
|
||||
*/
|
||||
@Configuration
|
||||
public class ExtConfigBean {
|
||||
static final String FILE_NAME = "extConfig.yml";
|
||||
|
||||
private static Resource resource;
|
||||
|
||||
/**
|
||||
* 动态获取外部配置文件的 resource
|
||||
*
|
||||
* @return File
|
||||
*/
|
||||
public static Resource getResource() {
|
||||
if (resource != null) {
|
||||
return resource;
|
||||
}
|
||||
File file = JpomManifest.getRunPath();
|
||||
if (file.isFile()) {
|
||||
file = file.getParentFile().getParentFile();
|
||||
file = new File(file, FILE_NAME);
|
||||
if (file.exists() && file.isFile()) {
|
||||
resource = new FileSystemResource(file);
|
||||
return ExtConfigBean.resource;
|
||||
}
|
||||
}
|
||||
resource = new ClassPathResource("/bin/" + FILE_NAME);
|
||||
return ExtConfigBean.resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单例
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public static ExtConfigBean getInstance() {
|
||||
return SpringUtil.getBean(ExtConfigBean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目运行存储路径
|
||||
*/
|
||||
@Value("${jpom.path}")
|
||||
private String path;
|
||||
|
||||
public String getPath() {
|
||||
if (StrUtil.isEmpty(path)) {
|
||||
if (JpomManifest.getInstance().isDebug()) {
|
||||
// 调试模式 为根路径的 jpom文件
|
||||
path = ("/jpom/" + BaseJpomApplication.getAppType().name() + "/").toLowerCase();
|
||||
} else {
|
||||
// 获取当前项目运行路径的父级
|
||||
File file = JpomManifest.getRunPath();
|
||||
if (!file.exists() && !file.isFile()) {
|
||||
throw new JpomRuntimeException("请配置运行路径属性【jpom.path】");
|
||||
}
|
||||
path = file.getParentFile().getParentFile().getAbsolutePath();
|
||||
}
|
||||
DefaultSystemLog.LOG().info("当前数据路径:{}", path);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getAbsolutePath() {
|
||||
return FileUtil.getAbsolutePath(FileUtil.file(getPath()));
|
||||
}
|
||||
}
|
@ -3,7 +3,8 @@ package cn.keepbx.jpom.system;
|
||||
import ch.qos.logback.core.PropertyDefinerBase;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.keepbx.jpom.JpomApplication;
|
||||
import cn.keepbx.jpom.BaseJpomApplication;
|
||||
import cn.keepbx.jpom.model.system.JpomManifest;
|
||||
import cn.keepbx.jpom.util.ArgsUtil;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.Signature;
|
||||
@ -29,6 +30,12 @@ import java.io.File;
|
||||
public class WebAopLog extends PropertyDefinerBase {
|
||||
private static final ThreadLocal<Boolean> IS_LOG = new ThreadLocal<>();
|
||||
|
||||
private static volatile AopLogInterface aopLogInterface;
|
||||
|
||||
synchronized public static void setAopLogInterface(AopLogInterface aopLogInterface) {
|
||||
WebAopLog.aopLogInterface = aopLogInterface;
|
||||
}
|
||||
|
||||
@Pointcut("execution(public * cn.keepbx.jpom.controller..*.*(..))")
|
||||
public void webLog() {
|
||||
//
|
||||
@ -36,6 +43,9 @@ public class WebAopLog extends PropertyDefinerBase {
|
||||
|
||||
@Before("webLog()")
|
||||
public void doBefore(JoinPoint joinPoint) {
|
||||
if (aopLogInterface != null) {
|
||||
aopLogInterface.before(joinPoint);
|
||||
}
|
||||
// 接收到请求,记录请求内容
|
||||
IS_LOG.set(true);
|
||||
Signature signature = joinPoint.getSignature();
|
||||
@ -53,6 +63,9 @@ public class WebAopLog extends PropertyDefinerBase {
|
||||
|
||||
@AfterReturning(returning = "ret", pointcut = "webLog()")
|
||||
public void doAfterReturning(Object ret) {
|
||||
if (aopLogInterface != null) {
|
||||
aopLogInterface.afterReturning(ret);
|
||||
}
|
||||
if (ret == null) {
|
||||
return;
|
||||
}
|
||||
@ -67,16 +80,17 @@ public class WebAopLog extends PropertyDefinerBase {
|
||||
|
||||
@Override
|
||||
public String getPropertyValue() {
|
||||
String path = ArgsUtil.getArgsValue(JpomApplication.getArgs(), "jpom.log");
|
||||
String path = ArgsUtil.getArgsValue(BaseJpomApplication.getArgs(), "jpom.log");
|
||||
if (StrUtil.isEmpty(path)) {
|
||||
//
|
||||
File file = JpomApplication.getRunPath();
|
||||
File file = JpomManifest.getRunPath();
|
||||
if (file.isFile()) {
|
||||
file = file.getParentFile().getParentFile();
|
||||
}
|
||||
file = new File(file, "log");
|
||||
path = file.getPath();
|
||||
}
|
||||
// System.out.println(path);
|
||||
// 配置默认日志路径
|
||||
DefaultSystemLog.configPath(path, false);
|
||||
return path;
|
@ -3,14 +3,21 @@ package cn.keepbx.jpom.system.init;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.system.SystemUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.jiangzeyin.common.PreLoadClass;
|
||||
import cn.jiangzeyin.common.PreLoadMethod;
|
||||
import cn.keepbx.jpom.BaseJpomApplication;
|
||||
import cn.keepbx.jpom.model.system.JpomManifest;
|
||||
import cn.keepbx.jpom.system.ExtConfigBean;
|
||||
import cn.keepbx.jpom.util.JvmUtil;
|
||||
import sun.jvmstat.monitor.MonitorException;
|
||||
import sun.jvmstat.monitor.MonitoredVm;
|
||||
import sun.jvmstat.monitor.VmIdentifier;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据目录权限检查
|
||||
@ -45,7 +52,7 @@ public class CheckPath {
|
||||
try {
|
||||
ClassUtil.loadClass(CLASS_NAME, false);
|
||||
} catch (Exception e) {
|
||||
File file = getToolsJar();
|
||||
File file = JvmUtil.getToolsJar();
|
||||
if (file.exists() && file.isFile()) {
|
||||
DefaultSystemLog.ERROR().error("Jpom未能正常加载tools.jar,请检查当前系统环境变量是否配置:JAVA_HOME,或者检查Jpom管理命令是否正确", e);
|
||||
} else {
|
||||
@ -55,8 +62,23 @@ public class CheckPath {
|
||||
}
|
||||
}
|
||||
|
||||
private static File getToolsJar() {
|
||||
File file = new File(SystemUtil.getJavaRuntimeInfo().getHomeDir());
|
||||
return new File(file.getParentFile(), "lib/tools.jar");
|
||||
|
||||
@PreLoadMethod(2)
|
||||
private static void checkDuplicateRun() {
|
||||
Class appClass = BaseJpomApplication.getAppClass();
|
||||
List<MonitoredVm> monitoredVms;
|
||||
try {
|
||||
String pid = String.valueOf(JpomManifest.getInstance().getPid());
|
||||
monitoredVms = JvmUtil.listMainClass(appClass.getName());
|
||||
monitoredVms.forEach(monitoredVm -> {
|
||||
VmIdentifier vmIdentifier = monitoredVm.getVmIdentifier();
|
||||
if (pid.equals(vmIdentifier.getUserInfo())) {
|
||||
return;
|
||||
}
|
||||
DefaultSystemLog.LOG().info("Jpom 程序建议一个机器上只运行一个对应的程序:" + BaseJpomApplication.getAppType());
|
||||
|
||||
});
|
||||
} catch (MonitorException | URISyntaxException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package cn.keepbx.jpom.util;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
|
||||
import cn.keepbx.jpom.BaseJpomApplication;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -32,7 +32,7 @@ public class CommandUtil {
|
||||
String result = "error";
|
||||
try {
|
||||
String[] cmd;
|
||||
if (AbstractProjectCommander.OS_INFO.isLinux()) {
|
||||
if (BaseJpomApplication.OS_INFO.isLinux()) {
|
||||
//执行linux系统命令
|
||||
cmd = new String[]{"/bin/sh", "-c", command};
|
||||
} else {
|
||||
@ -70,7 +70,7 @@ public class CommandUtil {
|
||||
} else {
|
||||
is = process.getErrorStream();
|
||||
}
|
||||
result = IoUtil.read(is, AbstractProjectCommander.getInstance().getCharset());
|
||||
result = IoUtil.read(is, BaseJpomApplication.getCharset());
|
||||
is.close();
|
||||
process.destroy();
|
||||
if (StrUtil.isEmpty(result) && wait != 0) {
|
@ -4,6 +4,7 @@ import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
@ -53,4 +54,13 @@ public class JsonFileUtil {
|
||||
FileUtil.writeString(newsJson, path, CharsetUtil.UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> JSONObject arrayToObjById(JSONArray array) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
array.forEach(o -> {
|
||||
JSONObject jsonObject1 = (JSONObject) o;
|
||||
jsonObject.put(jsonObject1.getString("id"), jsonObject1);
|
||||
});
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.keepbx.jpom.system.JpomRuntimeException;
|
||||
import com.sun.management.OperatingSystemMXBean;
|
||||
import com.sun.tools.attach.*;
|
||||
import sun.jvmstat.monitor.*;
|
||||
import sun.management.ConnectorAddressLink;
|
||||
|
||||
import javax.management.MBeanServerConnection;
|
||||
@ -18,8 +19,8 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryMXBean;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* jvm jmx 工具
|
||||
@ -94,6 +95,19 @@ public class JvmUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前系统运行的java 程序个数
|
||||
*
|
||||
* @return 如果发生异常则返回0
|
||||
*/
|
||||
public static int getJavaVirtualCount() {
|
||||
try {
|
||||
List<VirtualMachineDescriptor> descriptorList = VirtualMachine.list();
|
||||
return descriptorList.size();
|
||||
} catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 工具Jpom运行项目的id 获取virtualMachine
|
||||
@ -142,4 +156,40 @@ public class JvmUtil {
|
||||
}
|
||||
throw new JpomRuntimeException("JDK中" + file.getAbsolutePath() + " 文件不存在");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取jdk 中的tools jar文件路径
|
||||
*
|
||||
* @return file
|
||||
*/
|
||||
public static File getToolsJar() {
|
||||
File file = new File(SystemUtil.getJavaRuntimeInfo().getHomeDir());
|
||||
return new File(file.getParentFile(), "lib/tools.jar");
|
||||
}
|
||||
|
||||
/**
|
||||
* 工具指定的 mainClass 获取对应所有的的 MonitoredVm对象
|
||||
*
|
||||
* @param mainClass 程序运行主类
|
||||
* @return list
|
||||
* @throws MonitorException e
|
||||
* @throws URISyntaxException e
|
||||
*/
|
||||
public static List<MonitoredVm> listMainClass(String mainClass) throws MonitorException, URISyntaxException {
|
||||
List<MonitoredVm> monitoredVms = new ArrayList<>();
|
||||
MonitoredHost local = MonitoredHost.getMonitoredHost("localhost");
|
||||
// 取得所有在活动的虚拟机集合
|
||||
Set<?> vmList = new HashSet<Object>(local.activeVms());
|
||||
// 遍历集合,输出PID和进程名
|
||||
for (Object process : vmList) {
|
||||
MonitoredVm vm = local.getMonitoredVm(new VmIdentifier("//" + process));
|
||||
// 获取类名
|
||||
String processName = MonitoredVmUtil.mainClass(vm, true);
|
||||
if (!mainClass.equals(processName)) {
|
||||
continue;
|
||||
}
|
||||
monitoredVms.add(vm);
|
||||
}
|
||||
return monitoredVms;
|
||||
}
|
||||
}
|
@ -1,14 +1,13 @@
|
||||
package cn.keepbx.jpom.socket;
|
||||
package cn.keepbx.jpom.util;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.jiangzeyin.common.DefaultSystemLog;
|
||||
import cn.keepbx.jpom.util.KeyLock;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* socket 回话对象
|
||||
* socket 会话对象
|
||||
*
|
||||
* @author jiangzeyin
|
||||
* @date 2018/9/29
|
||||
@ -26,7 +25,7 @@ public class SocketSessionUtil {
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param session 回话对象
|
||||
* @param session 会话对象
|
||||
* @param msg 消息
|
||||
* @throws IOException 异常
|
||||
*/
|
||||
@ -53,6 +52,7 @@ public class SocketSessionUtil {
|
||||
try {
|
||||
session.getBasicRemote().sendText(msg);
|
||||
exception = null;
|
||||
break;
|
||||
} catch (IOException e) {
|
||||
DefaultSystemLog.ERROR().error("发送消息失败:" + tryCount, e);
|
||||
exception = e;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user