remove 全面下降项目副本功能

This commit is contained in:
bwcx_jzy 2023-12-26 17:39:27 +08:00
parent 183f468647
commit ecad99f0a4
No known key found for this signature in database
GPG Key ID: E187D6E9DDDE8C53
33 changed files with 287 additions and 1276 deletions

View File

@ -8,6 +8,12 @@
### 🐞 解决BUG、优化功能
1. 【server】修复 项目列表批量操作弹窗定时刷新引起异常(感谢@曾梦想仗剑走天涯)
2. 【all】下降 全面下降项目副本功能(请使用 DSL 模式代替)
### ⚠️ 注意
1. 全面下降项目副本功能(请使用 DSL 模式代替)如果您当前使用到此功能请先手动备份相关数据
2. 升级后项目副本数据会被人工或者系统更新项目数据自动删除(请一定提前做好备份操作)
------

View File

@ -125,10 +125,9 @@ public abstract class AbstractProjectCommander {
* 生成可以执行的命令
*
* @param nodeProjectInfoModel 项目
* @param javaCopyItem 副本信息
* @return null 是条件不足
*/
public abstract String buildJavaCommand(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem);
public abstract String buildJavaCommand(NodeProjectInfoModel nodeProjectInfoModel);
protected String getRunJavaPath(NodeProjectInfoModel nodeProjectInfoModel, boolean w) {
// if (StrUtil.isEmpty(nodeProjectInfoModel.getJdkId())) {
@ -152,8 +151,8 @@ public abstract class AbstractProjectCommander {
* @return 结果
* @throws Exception 异常
*/
public CommandOpResult start(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) throws Exception {
return this.start(nodeProjectInfoModel, javaCopyItem, false);
public CommandOpResult start(NodeProjectInfoModel nodeProjectInfoModel) throws Exception {
return this.start(nodeProjectInfoModel, false);
}
/**
@ -164,8 +163,8 @@ public abstract class AbstractProjectCommander {
* @return 结果
* @throws Exception 异常
*/
public CommandOpResult start(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem, boolean sync) throws Exception {
String msg = checkStart(nodeProjectInfoModel, javaCopyItem);
public CommandOpResult start(NodeProjectInfoModel nodeProjectInfoModel, boolean sync) throws Exception {
String msg = checkStart(nodeProjectInfoModel);
if (msg != null) {
return CommandOpResult.of(false, msg);
}
@ -173,7 +172,7 @@ public abstract class AbstractProjectCommander {
if (runMode == RunMode.Dsl) {
//
this.runDsl(nodeProjectInfoModel, "start", (baseProcess, action) -> {
String log = nodeProjectInfoModel.getAbsoluteLog(javaCopyItem);
String log = nodeProjectInfoModel.getAbsoluteLog();
try {
DslScriptBuilder.run(baseProcess, nodeProjectInfoModel, action, log, sync);
} catch (Exception e) {
@ -183,7 +182,7 @@ public abstract class AbstractProjectCommander {
});
} else {
String command = this.buildJavaCommand(nodeProjectInfoModel, javaCopyItem);
String command = this.buildJavaCommand(nodeProjectInfoModel);
if (command == null) {
return CommandOpResult.of(false, "没有需要执行的命令");
}
@ -202,9 +201,9 @@ public abstract class AbstractProjectCommander {
});
}
//
this.loopCheckRun(nodeProjectInfoModel, javaCopyItem, true);
CommandOpResult status = this.status(nodeProjectInfoModel, javaCopyItem);
this.asyncWebHooks(nodeProjectInfoModel, javaCopyItem, "start", "result", status.msgStr());
this.loopCheckRun(nodeProjectInfoModel, true);
CommandOpResult status = this.status(nodeProjectInfoModel);
this.asyncWebHooks(nodeProjectInfoModel, "start", "result", status.msgStr());
return status;
}
@ -226,29 +225,27 @@ public abstract class AbstractProjectCommander {
* 停止
*
* @param nodeProjectInfoModel 项目
* @param javaCopyItem 副本信息
* @return 结果
* @throws Exception 异常
*/
public CommandOpResult stop(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) throws Exception {
return this.stop(nodeProjectInfoModel, javaCopyItem, false);
public CommandOpResult stop(NodeProjectInfoModel nodeProjectInfoModel) throws Exception {
return this.stop(nodeProjectInfoModel, false);
}
/**
* 停止
*
* @param nodeProjectInfoModel 项目
* @param javaCopyItem 副本信息
* @param sync dsl 是否同步执行
* @return 结果
* @throws Exception 异常
*/
public CommandOpResult stop(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem, boolean sync) throws Exception {
public CommandOpResult stop(NodeProjectInfoModel nodeProjectInfoModel, boolean sync) throws Exception {
RunMode runMode = nodeProjectInfoModel.getRunMode();
if (runMode == RunMode.File) {
return CommandOpResult.of(true, "file 类型项目没有 stop");
}
Tuple tuple = this.stopBefore(nodeProjectInfoModel, javaCopyItem);
Tuple tuple = this.stopBefore(nodeProjectInfoModel);
CommandOpResult status = tuple.get(1);
String webHook = tuple.get(0);
if (status.isSuccess()) {
@ -256,7 +253,7 @@ public abstract class AbstractProjectCommander {
if (runMode == RunMode.Dsl) {
//
this.runDsl(nodeProjectInfoModel, "stop", (process, action) -> {
String log = nodeProjectInfoModel.getAbsoluteLog(javaCopyItem);
String log = nodeProjectInfoModel.getAbsoluteLog();
try {
DslScriptBuilder.run(process, nodeProjectInfoModel, action, log, sync);
} catch (Exception e) {
@ -264,13 +261,13 @@ public abstract class AbstractProjectCommander {
}
return null;
});
boolean checkRun = this.loopCheckRun(nodeProjectInfoModel, javaCopyItem, false);
boolean checkRun = this.loopCheckRun(nodeProjectInfoModel, false);
return CommandOpResult.of(checkRun, checkRun ? "stop done" : "stop done,but unsuccessful")
.appendMsg(status.getMsgs())
.appendMsg(webHook);
} else {
//
return this.stopJava(nodeProjectInfoModel, javaCopyItem, status.getPid()).appendMsg(status.getMsgs()).appendMsg(webHook);
return this.stopJava(nodeProjectInfoModel, status.getPid()).appendMsg(status.getMsgs()).appendMsg(webHook);
}
}
return CommandOpResult.of(true).appendMsg(status.getMsgs()).appendMsg(webHook);
@ -280,12 +277,11 @@ public abstract class AbstractProjectCommander {
* 停止
*
* @param nodeProjectInfoModel 项目
* @param javaCopyItem 副本信息
* @param pid 进程ID
* @return 结果
* @throws Exception 异常
*/
public abstract CommandOpResult stopJava(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem, int pid) throws Exception;
public abstract CommandOpResult stopJava(NodeProjectInfoModel nodeProjectInfoModel, int pid) throws Exception;
/**
* 停止之前
@ -294,15 +290,15 @@ public abstract class AbstractProjectCommander {
* @return 结果
* @throws Exception 异常
*/
private Tuple stopBefore(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) throws Exception {
String beforeStop = this.webHooks(nodeProjectInfoModel, javaCopyItem, "beforeStop");
private Tuple stopBefore(NodeProjectInfoModel nodeProjectInfoModel) throws Exception {
String beforeStop = this.webHooks(nodeProjectInfoModel, "beforeStop");
// 再次查看进程信息
CommandOpResult result = this.status(nodeProjectInfoModel, javaCopyItem);
CommandOpResult result = this.status(nodeProjectInfoModel);
if (result.isSuccess()) {
// 端口号缓存
PID_PORT.remove(result.getPid());
}
this.asyncWebHooks(nodeProjectInfoModel, javaCopyItem, "stop", "result", result);
this.asyncWebHooks(nodeProjectInfoModel, "stop", "result", result);
return new Tuple(StrUtil.emptyToDefault(beforeStop, StrUtil.EMPTY), result);
}
@ -310,19 +306,18 @@ public abstract class AbstractProjectCommander {
* 执行 webhooks 通知
*
* @param nodeProjectInfoModel 项目信息
* @param javaCopyItem 副本信息
* @param type 类型
* @param other 其他参数
*/
public void asyncWebHooks(NodeProjectInfoModel nodeProjectInfoModel,
NodeProjectInfoModel.JavaCopyItem javaCopyItem,
String type, Object... other) {
String token = nodeProjectInfoModel.getToken();
Opt.ofBlankAble(token)
.ifPresent(s ->
ThreadUtil.execute(() -> {
try {
this.webHooks(nodeProjectInfoModel, javaCopyItem, type, other);
this.webHooks(nodeProjectInfoModel, type, other);
} catch (Exception e) {
log.error("project webhook", e);
}
@ -334,13 +329,12 @@ public abstract class AbstractProjectCommander {
* 执行 webhooks 通知
*
* @param nodeProjectInfoModel 项目信息
* @param javaCopyItem 副本信息
* @param type 类型
* @param other 其他参数
* @return 结果
*/
private String webHooks(NodeProjectInfoModel nodeProjectInfoModel,
NodeProjectInfoModel.JavaCopyItem javaCopyItem,
String type, Object... other) throws Exception {
String token = nodeProjectInfoModel.getToken();
IPlugin plugin = PluginFactory.getPlugin("webhook");
@ -348,9 +342,7 @@ public abstract class AbstractProjectCommander {
map.put("projectId", nodeProjectInfoModel.getId());
map.put("projectName", nodeProjectInfoModel.getName());
map.put("type", type);
if (javaCopyItem != null) {
map.put("copyId", javaCopyItem.getId());
}
for (int i = 0; i < other.length; i += 2) {
map.put(other[i].toString(), other[i + 1]);
}
@ -365,18 +357,18 @@ public abstract class AbstractProjectCommander {
* @return 结果
* @throws Exception 异常
*/
public CommandOpResult restart(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) throws Exception {
public CommandOpResult restart(NodeProjectInfoModel nodeProjectInfoModel) throws Exception {
RunMode runMode = nodeProjectInfoModel.getRunMode();
if (runMode == RunMode.File) {
return CommandOpResult.of(true, "file 类型项目没有 restart");
}
this.asyncWebHooks(nodeProjectInfoModel, javaCopyItem, "beforeRestart");
this.asyncWebHooks(nodeProjectInfoModel, "beforeRestart");
if (runMode == RunMode.Dsl) {
DslYmlDto.BaseProcess dslProcess = nodeProjectInfoModel.tryDslProcess("restart");
if (dslProcess != null) {
//
this.runDsl(nodeProjectInfoModel, "restart", (process, action) -> {
String log = nodeProjectInfoModel.getAbsoluteLog(javaCopyItem);
String log = nodeProjectInfoModel.getAbsoluteLog();
try {
DslScriptBuilder.run(process, nodeProjectInfoModel, action, log, false);
} catch (Exception e) {
@ -385,18 +377,18 @@ public abstract class AbstractProjectCommander {
return null;
});
// 等待 状态成功
boolean run = this.loopCheckRun(nodeProjectInfoModel, javaCopyItem, true);
boolean run = this.loopCheckRun(nodeProjectInfoModel, true);
return CommandOpResult.of(run, run ? "restart done" : "restart done,but unsuccessful");
//return new Tuple(run ? "restart done,but unsuccessful" : "restart done", resultMsg);
}
}
boolean run = this.isRun(nodeProjectInfoModel, javaCopyItem);
boolean run = this.isRun(nodeProjectInfoModel);
CommandOpResult stopMsg = null;
if (run) {
stopMsg = this.stop(nodeProjectInfoModel, javaCopyItem, true);
stopMsg = this.stop(nodeProjectInfoModel, true);
}
CommandOpResult startMsg = this.start(nodeProjectInfoModel, javaCopyItem);
CommandOpResult startMsg = this.start(nodeProjectInfoModel);
if (stopMsg != null) {
startMsg.appendMsg(stopMsg.getMsgs());
}
@ -410,8 +402,8 @@ public abstract class AbstractProjectCommander {
* @return null 检查一切正常
* @throws Exception 异常
*/
private String checkStart(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) throws Exception {
CommandOpResult status = this.status(nodeProjectInfoModel, javaCopyItem);
private String checkStart(NodeProjectInfoModel nodeProjectInfoModel) throws Exception {
CommandOpResult status = this.status(nodeProjectInfoModel);
if (status.isSuccess()) {
return "当前程序正在运行中,不能重复启动,PID:" + status.getPid();
}
@ -447,7 +439,7 @@ public abstract class AbstractProjectCommander {
return "当前项目类型不支持启动";
}
// 备份日志
backLog(nodeProjectInfoModel, javaCopyItem);
backLog(nodeProjectInfoModel);
return null;
}
@ -497,8 +489,8 @@ public abstract class AbstractProjectCommander {
* @param nodeProjectInfoModel 项目
* @return 结果
*/
public String backLog(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) {
File file = javaCopyItem == null ? new File(nodeProjectInfoModel.getLog()) : nodeProjectInfoModel.getLog(javaCopyItem);
public String backLog(NodeProjectInfoModel nodeProjectInfoModel) {
File file = new File(nodeProjectInfoModel.getLog());
if (!file.exists() || file.isDirectory()) {
return "not exists";
}
@ -510,7 +502,7 @@ public abstract class AbstractProjectCommander {
boolean openLogBack = this.resolveOpenLogBack(nodeProjectInfoModel);
if (openLogBack) {
// 开启日志备份才移动文件
File backPath = javaCopyItem == null ? nodeProjectInfoModel.getLogBack() : nodeProjectInfoModel.getLogBack(javaCopyItem);
File backPath = nodeProjectInfoModel.getLogBack();
backPath = new File(backPath, DateTime.now().toString(DatePattern.PURE_DATETIME_FORMAT) + ".log");
FileUtil.copy(file, backPath, true);
}
@ -528,10 +520,9 @@ public abstract class AbstractProjectCommander {
* 查询项目状态
*
* @param nodeProjectInfoModel 项目
* @param javaCopyItem 副本
* @return 状态
*/
public CommandOpResult status(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) {
public CommandOpResult status(NodeProjectInfoModel nodeProjectInfoModel) {
RunMode runMode = nodeProjectInfoModel.getRunMode();
if (runMode == RunMode.File) {
return CommandOpResult.of(false, "file 类型项目没有运行状态");
@ -549,7 +540,7 @@ public abstract class AbstractProjectCommander {
return Optional.ofNullable(status)
.map(strings -> {
String log = nodeProjectInfoModel.getAbsoluteLog(javaCopyItem);
String log = nodeProjectInfoModel.getAbsoluteLog();
FileUtil.appendLines(strings, FileUtil.file(log), fileCharset);
return strings;
})
@ -560,7 +551,7 @@ public abstract class AbstractProjectCommander {
.map(CommandOpResult::of)
.orElseGet(() -> CommandOpResult.of(false, STOP_TAG));
} else {
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();
String tag = nodeProjectInfoModel.getId();
String statusResult = this.status(tag);
CommandOpResult of = CommandOpResult.of(statusResult);
if (!of.isSuccess()) {
@ -691,41 +682,39 @@ public abstract class AbstractProjectCommander {
* @param nodeProjectInfoModel 项目
* @return true 正在运行
*/
public boolean isRun(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) {
CommandOpResult result = this.status(nodeProjectInfoModel, javaCopyItem);
public boolean isRun(NodeProjectInfoModel nodeProjectInfoModel) {
CommandOpResult result = this.status(nodeProjectInfoModel);
return result.isSuccess();
}
/***
* 阻塞检查程序状态
* @param nodeProjectInfoModel 项目
* @param javaCopyItem 副本
* @param status 要检查的状态
*
* @return 和参数status相反
*/
protected boolean loopCheckRun(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem, boolean status) {
protected boolean loopCheckRun(NodeProjectInfoModel nodeProjectInfoModel, boolean status) {
int statusWaitTime = AgentConfig.ProjectConfig.getInstance().getStatusWaitTime();
return this.loopCheckRun(nodeProjectInfoModel, javaCopyItem, statusWaitTime, status);
return this.loopCheckRun(nodeProjectInfoModel, statusWaitTime, status);
}
/***
* 阻塞检查程序状态
* @param nodeProjectInfoModel 项目
* @param javaCopyItem 副本
* @param status 要检查的状态
* @param waitTime 检查等待时间
*
* @return 如果和期望一致则返回 true反之 false
*/
protected boolean loopCheckRun(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem, int waitTime, boolean status) {
protected boolean loopCheckRun(NodeProjectInfoModel nodeProjectInfoModel, int waitTime, boolean status) {
waitTime = Math.max(waitTime, 1);
int statusDetectionInterval = AgentConfig.ProjectConfig.getInstance().getStatusDetectionInterval();
statusDetectionInterval = Math.max(statusDetectionInterval, 1);
int loopCount = (int) (TimeUnit.SECONDS.toMillis(waitTime) / 500);
int count = 0;
do {
if (this.isRun(nodeProjectInfoModel, javaCopyItem) == status) {
if (this.isRun(nodeProjectInfoModel) == status) {
// 是期望的结果
return true;
}

View File

@ -48,30 +48,30 @@ public abstract class BaseUnixProjectCommander extends AbstractProjectCommander
}
@Override
public String buildJavaCommand(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) {
public String buildJavaCommand(NodeProjectInfoModel nodeProjectInfoModel) {
String path = NodeProjectInfoModel.getClassPathLib(nodeProjectInfoModel);
if (StrUtil.isBlank(path)) {
return null;
}
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();
String tag = nodeProjectInfoModel.getId();
return StrUtil.format("nohup {} {} {} {} {} {} >> {} 2>&1 &",
getRunJavaPath(nodeProjectInfoModel, false),
Optional.ofNullable(javaCopyItem == null ? nodeProjectInfoModel.getJvm() : javaCopyItem.getJvm()).orElse(StrUtil.EMPTY),
Optional.ofNullable(nodeProjectInfoModel.getJvm()).orElse(StrUtil.EMPTY),
JvmUtil.getJpomPidTag(tag, nodeProjectInfoModel.allLib()),
path,
Optional.ofNullable(nodeProjectInfoModel.getMainClass()).orElse(StrUtil.EMPTY),
Optional.ofNullable(javaCopyItem == null ? nodeProjectInfoModel.getArgs() : javaCopyItem.getArgs()).orElse(StrUtil.EMPTY),
nodeProjectInfoModel.getAbsoluteLog(javaCopyItem));
Optional.ofNullable(nodeProjectInfoModel.getArgs()).orElse(StrUtil.EMPTY),
nodeProjectInfoModel.getAbsoluteLog());
}
@Override
public CommandOpResult stopJava(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem, int pid) throws Exception {
public CommandOpResult stopJava(NodeProjectInfoModel nodeProjectInfoModel, int pid) throws Exception {
File file = FileUtil.file(nodeProjectInfoModel.allLib());
List<String> result = new ArrayList<>();
boolean success = false;
String kill = AbstractSystemCommander.getInstance().kill(file, pid);
result.add(kill);
if (this.loopCheckRun(nodeProjectInfoModel, javaCopyItem, false)) {
if (this.loopCheckRun(nodeProjectInfoModel, false)) {
success = true;
} else {
// 强制杀进程
@ -79,13 +79,13 @@ public abstract class BaseUnixProjectCommander extends AbstractProjectCommander
String cmd = String.format("kill -9 %s", pid);
CommandUtil.asyncExeLocalCommand(file, cmd);
//
if (this.loopCheckRun(nodeProjectInfoModel, javaCopyItem, 5, false)) {
if (this.loopCheckRun(nodeProjectInfoModel, 5, false)) {
success = true;
} else {
result.add("Kill -9 not completed, kill -9 failed ");
}
}
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();
String tag = nodeProjectInfoModel.getId();
return CommandOpResult.of(success, status(tag)).appendMsg(result);
// return status(tag) + StrUtil.SPACE + kill;
}

View File

@ -51,16 +51,16 @@ public class WindowsProjectCommander extends AbstractProjectCommander {
}
@Override
public String buildJavaCommand(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) {
public String buildJavaCommand(NodeProjectInfoModel nodeProjectInfoModel) {
String classPath = NodeProjectInfoModel.getClassPathLib(nodeProjectInfoModel);
if (StrUtil.isBlank(classPath)) {
return null;
}
// 拼接命令
String jvm = javaCopyItem == null ? nodeProjectInfoModel.getJvm() : javaCopyItem.getJvm();
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();
String jvm = nodeProjectInfoModel.getJvm();
String tag = nodeProjectInfoModel.getId();
String mainClass = nodeProjectInfoModel.getMainClass();
String args = javaCopyItem == null ? nodeProjectInfoModel.getArgs() : javaCopyItem.getArgs();
String args = nodeProjectInfoModel.getArgs();
return StrUtil.format("{} {} {} {} {} {} >> {} &",
getRunJavaPath(nodeProjectInfoModel, true),
Optional.ofNullable(jvm).orElse(StrUtil.EMPTY),
@ -68,18 +68,18 @@ public class WindowsProjectCommander extends AbstractProjectCommander {
classPath,
Optional.ofNullable(mainClass).orElse(StrUtil.EMPTY),
Optional.ofNullable(args).orElse(StrUtil.EMPTY),
nodeProjectInfoModel.getAbsoluteLog(javaCopyItem));
nodeProjectInfoModel.getAbsoluteLog());
}
@Override
public CommandOpResult stopJava(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem, int pid) throws Exception {
String tag = javaCopyItem == null ? nodeProjectInfoModel.getId() : javaCopyItem.getTagId();
public CommandOpResult stopJava(NodeProjectInfoModel nodeProjectInfoModel, int pid) throws Exception {
String tag = nodeProjectInfoModel.getId();
List<String> result = new ArrayList<>();
boolean success = false;
// 如果正在运行则执行杀进程命令
String kill = AbstractSystemCommander.getInstance().kill(FileUtil.file(nodeProjectInfoModel.allLib()), pid);
result.add(kill);
if (this.loopCheckRun(nodeProjectInfoModel, javaCopyItem, false)) {
if (this.loopCheckRun(nodeProjectInfoModel, false)) {
success = true;
} else {
result.add("Kill not completed");

View File

@ -22,9 +22,7 @@
*/
package org.dromara.jpom.controller.manage;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.RegexPool;
import cn.hutool.core.lang.Validator;
@ -49,9 +47,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* 编辑项目
@ -128,37 +124,7 @@ public class ManageEditProjectController extends BaseAgentController {
Assert.state(StrUtil.isNotEmpty(lib) && !StrUtil.SLASH.equals(lib) && !Validator.isChinese(lib), "项目路径不能为空,不能为顶级目录,不能包含中文");
FileUtils.checkSlip(lib, e -> new IllegalArgumentException("项目路径存在提升目录问题"));
NodeProjectInfoModel exits = projectInfoService.getItem(projectInfo.getId());
// java 程序副本
if (runMode1 == RunMode.ClassPath || runMode1 == RunMode.Jar || runMode1 == RunMode.JarWar || runMode1 == RunMode.JavaExtDirsCp) {
String javaCopyIds = getParameter("javaCopyIds");
// TODO 删除副本验证
if (StrUtil.isEmpty(javaCopyIds)) {
projectInfo.setJavaCopyItemList(null);
} else {
String[] split = StrUtil.splitToArray(javaCopyIds, StrUtil.COMMA);
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = new ArrayList<>(split.length);
for (String copyId : split) {
String jvm = getParameter("jvm_" + copyId);
String name = getParameter("name_" + copyId);
String args = getParameter("args_" + copyId);
//
NodeProjectInfoModel.JavaCopyItem javaCopyItem = new NodeProjectInfoModel.JavaCopyItem();
javaCopyItem.setId(copyId);
javaCopyItem.setParentId(id);
javaCopyItem.setName(name);
javaCopyItem.setModifyTime(DateUtil.now());
javaCopyItem.setJvm(StrUtil.emptyToDefault(jvm, StrUtil.EMPTY));
javaCopyItem.setArgs(StrUtil.emptyToDefault(args, StrUtil.EMPTY));
javaCopyItemList.add(javaCopyItem);
}
projectInfo.setJavaCopyItemList(javaCopyItemList);
}
} else {
projectInfo.setJavaCopyItemList(null);
}
return exits;
return projectInfoService.getItem(projectInfo.getId());
}
@ -227,7 +193,7 @@ public class ManageEditProjectController extends BaseAgentController {
if (exits == null) {
// 检查运行中的tag 是否被占用
if (runMode != RunMode.File && runMode != RunMode.Dsl) {
Assert.state(!AbstractProjectCommander.getInstance().isRun(projectInfo, null), "当前项目id已经被正在运行的程序占用");
Assert.state(!AbstractProjectCommander.getInstance().isRun(projectInfo), "当前项目id已经被正在运行的程序占用");
}
if (previewData) {
// 预检查数据
@ -253,14 +219,7 @@ public class ManageEditProjectController extends BaseAgentController {
exits.setToken(projectInfo.getToken());
exits.setDslContent(projectInfo.getDslContent());
exits.setDslEnv(projectInfo.getDslEnv());
// 检查是否非法删除副本集
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = exits.getJavaCopyItemList();
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList1 = projectInfo.getJavaCopyItemList();
if (CollUtil.isNotEmpty(javaCopyItemList) && !CollUtil.containsAll(javaCopyItemList1, javaCopyItemList)) {
// 重写了 equals
return new JsonMessage<>(405, "修改中不能删除副本集、请到副本集中删除");
}
exits.setJavaCopyItemList(javaCopyItemList1);
exits.setJavaExtDirsCp(projectInfo.getJavaExtDirsCp());
// 移动到新路径
this.moveTo(exits, projectInfo);
@ -310,15 +269,8 @@ public class ManageEditProjectController extends BaseAgentController {
}
private void projectMustNotRun(NodeProjectInfoModel projectInfoModel, String msg) {
boolean run = AbstractProjectCommander.getInstance().isRun(projectInfoModel, null);
boolean run = AbstractProjectCommander.getInstance().isRun(projectInfoModel);
Assert.state(!run, msg);
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = projectInfoModel.getJavaCopyItemList();
Optional.ofNullable(javaCopyItemList).ifPresent(javaCopyItems -> {
for (NodeProjectInfoModel.JavaCopyItem javaCopyItem : javaCopyItems) {
boolean run1 = AbstractProjectCommander.getInstance().isRun(projectInfoModel, javaCopyItem);
Assert.state(!run1, msg + " 副本 " + javaCopyItem.getName());
}
});
}
/**
@ -358,33 +310,19 @@ public class ManageEditProjectController extends BaseAgentController {
* @return json
*/
@RequestMapping(value = "deleteProject", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<String> deleteProject(String copyId, String thorough) {
public IJsonMessage<String> deleteProject(String thorough) {
NodeProjectInfoModel nodeProjectInfoModel = tryGetProjectInfoModel();
if (nodeProjectInfoModel == null) {
// 返回正常 200 状态码考虑节点分发重复操作
return JsonMessage.success("项目不存在");
}
NodeProjectInfoModel.JavaCopyItem copyItem = nodeProjectInfoModel.findCopyItem(copyId);
// 运行判断
boolean run = AbstractProjectCommander.getInstance().isRun(nodeProjectInfoModel);
Assert.state(!run, "不能删除正在运行的项目");
this.thorough(thorough, nodeProjectInfoModel);
//
projectInfoService.deleteItem(nodeProjectInfoModel.getId());
if (copyItem == null) {
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = nodeProjectInfoModel.getJavaCopyItemList();
Assert.state(CollUtil.isEmpty(javaCopyItemList), "当前项目存在副本不能直接删除");
// 运行判断
boolean run = AbstractProjectCommander.getInstance().isRun(nodeProjectInfoModel, null);
Assert.state(!run, "不能删除正在运行的项目");
this.thorough(thorough, nodeProjectInfoModel, null);
//
projectInfoService.deleteItem(nodeProjectInfoModel.getId());
} else {
boolean run = AbstractProjectCommander.getInstance().isRun(nodeProjectInfoModel, copyItem);
Assert.state(!run, "不能删除正在运行的项目副本");
//
this.thorough(thorough, nodeProjectInfoModel, copyItem);
//
boolean removeCopyItem = nodeProjectInfoModel.removeCopyItem(copyId);
Assert.state(removeCopyItem, "删除对应副本集不存在");
projectInfoService.updateItem(nodeProjectInfoModel);
}
return JsonMessage.success("删除成功!");
}
@ -394,31 +332,21 @@ public class ManageEditProjectController extends BaseAgentController {
*
* @param thorough 是否彻底
* @param nodeProjectInfoModel 项目
* @param copyItem 副本
*/
private void thorough(String thorough, NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem copyItem) {
private void thorough(String thorough, NodeProjectInfoModel nodeProjectInfoModel) {
if (StrUtil.isEmpty(thorough)) {
return;
}
if (copyItem != null) {
File logBack = nodeProjectInfoModel.getLogBack(copyItem);
boolean fastDel = CommandUtil.systemFastDel(logBack);
Assert.state(!fastDel, "删除日志文件失败:" + logBack.getAbsolutePath());
File log = nodeProjectInfoModel.getLog(copyItem);
fastDel = CommandUtil.systemFastDel(log);
Assert.state(!fastDel, "删除日志文件失败:" + log.getAbsolutePath());
} else {
File logBack = nodeProjectInfoModel.getLogBack();
boolean fastDel = CommandUtil.systemFastDel(logBack);
Assert.state(!fastDel, "删除日志文件失败:" + logBack.getAbsolutePath());
File log = FileUtil.file(nodeProjectInfoModel.getAbsoluteLog(null));
fastDel = CommandUtil.systemFastDel(log);
Assert.state(!fastDel, "删除日志文件失败:" + log.getAbsolutePath());
//
File allLib = FileUtil.file(nodeProjectInfoModel.allLib());
fastDel = CommandUtil.systemFastDel(allLib);
Assert.state(!fastDel, "删除项目文件失败:" + allLib.getAbsolutePath());
}
File logBack = nodeProjectInfoModel.getLogBack();
boolean fastDel = CommandUtil.systemFastDel(logBack);
Assert.state(!fastDel, "删除日志文件失败:" + logBack.getAbsolutePath());
File log = FileUtil.file(nodeProjectInfoModel.getAbsoluteLog());
fastDel = CommandUtil.systemFastDel(log);
Assert.state(!fastDel, "删除日志文件失败:" + log.getAbsolutePath());
//
File allLib = FileUtil.file(nodeProjectInfoModel.allLib());
fastDel = CommandUtil.systemFastDel(allLib);
Assert.state(!fastDel, "删除项目文件失败:" + allLib.getAbsolutePath());
}
@RequestMapping(value = "releaseOutGiving", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)

View File

@ -26,7 +26,6 @@ import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
@ -36,7 +35,6 @@ import cn.hutool.http.HttpUtil;
import cn.keepbx.jpom.IJsonMessage;
import cn.keepbx.jpom.model.JsonMessage;
import com.alibaba.fastjson2.JSONObject;
import lombok.Lombok;
import lombok.extern.slf4j.Slf4j;
import org.dromara.jpom.common.BaseAgentController;
import org.dromara.jpom.common.commander.AbstractProjectCommander;
@ -67,8 +65,6 @@ import java.nio.charset.Charset;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
@ -145,42 +141,42 @@ public class ProjectFileControl extends BaseAgentController {
}).collect(Collectors.toList());
// 得到 当前下面文件夹下面所有的文件信息 map
Map<String, String> nowMap = CollStreamUtil.toMap(collect,
jsonObject12 -> jsonObject12.getString("name"),
jsonObject1 -> jsonObject1.getString("sha1"));
jsonObject12 -> jsonObject12.getString("name"),
jsonObject1 -> jsonObject1.getString("sha1"));
// 将需要对应的信息转为 map
Map<String, String> tryMap = CollStreamUtil.toMap(data, DiffFileVo.DiffItem::getName, DiffFileVo.DiffItem::getSha1);
// 对应需要 当前项目文件夹下没有的和文件内容有变化的
List<JSONObject> canSync = tryMap.entrySet()
.stream()
.filter(stringStringEntry -> {
String nowSha1 = nowMap.get(stringStringEntry.getKey());
if (StrUtil.isEmpty(nowSha1)) {
// 不存在
return true;
}
// 如果 文件信息一致 则过滤
return !StrUtil.equals(stringStringEntry.getValue(), nowSha1);
})
.map(stringStringEntry -> {
//
JSONObject item = new JSONObject();
item.put("name", stringStringEntry.getKey());
item.put("sha1", stringStringEntry.getValue());
return item;
})
.collect(Collectors.toList());
.stream()
.filter(stringStringEntry -> {
String nowSha1 = nowMap.get(stringStringEntry.getKey());
if (StrUtil.isEmpty(nowSha1)) {
// 不存在
return true;
}
// 如果 文件信息一致 则过滤
return !StrUtil.equals(stringStringEntry.getValue(), nowSha1);
})
.map(stringStringEntry -> {
//
JSONObject item = new JSONObject();
item.put("name", stringStringEntry.getKey());
item.put("sha1", stringStringEntry.getValue());
return item;
})
.collect(Collectors.toList());
// 对比项目文件夹下有对但是需要对应对信息里面没有对此类文件需要删除
List<JSONObject> delArray = nowMap.entrySet()
.stream()
.filter(stringStringEntry -> !tryMap.containsKey(stringStringEntry.getKey()))
.map(stringStringEntry -> {
//
JSONObject item = new JSONObject();
item.put("name", stringStringEntry.getKey());
item.put("sha1", stringStringEntry.getValue());
return item;
})
.collect(Collectors.toList());
.stream()
.filter(stringStringEntry -> !tryMap.containsKey(stringStringEntry.getKey()))
.map(stringStringEntry -> {
//
JSONObject item = new JSONObject();
item.put("name", stringStringEntry.getKey());
item.put("sha1", stringStringEntry.getValue());
return item;
})
.collect(Collectors.toList());
//
JSONObject result = new JSONObject();
result.put("diff", canSync);
@ -194,19 +190,8 @@ public class ProjectFileControl extends BaseAgentController {
// 判断是否需要先关闭项目
boolean closeFirst = BooleanUtil.toBoolean(closeFirstStr);
if (closeFirst) {
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.stop, projectInfoModel, null);
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.stop, projectInfoModel);
Assert.state(result.isSuccess(), "关闭项目失败:" + result.msgStr());
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = projectInfoModel.getJavaCopyItemList();
Optional.ofNullable(javaCopyItemList).ifPresent(javaCopyItems -> {
try {
for (NodeProjectInfoModel.JavaCopyItem javaCopyItem : javaCopyItems) {
CommandOpResult result1 = consoleService.execCommand(ConsoleCommandOp.stop, projectInfoModel, javaCopyItem);
Assert.state(result1.isSuccess(), "关闭项目副本" + javaCopyItem.getName() + " - " + javaCopyItem.getId() + "失败:" + result1.msgStr());
}
} catch (Exception e) {
throw Lombok.sneakyThrow(e);
}
});
}
String clearType = getParameter("clearType");
// 判断是否需要清空
@ -217,10 +202,10 @@ public class ProjectFileControl extends BaseAgentController {
@RequestMapping(value = "upload-sharding", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<CommandOpResult> uploadSharding(MultipartFile file,
String sliceId,
Integer totalSlice,
Integer nowSlice,
String fileSumMd5) throws Exception {
String sliceId,
Integer totalSlice,
Integer nowSlice,
String fileSumMd5) throws Exception {
String tempPathName = agentConfig.getFixedTempPathName();
this.uploadSharding(file, tempPathName, sliceId, totalSlice, nowSlice, fileSumMd5);
@ -229,12 +214,12 @@ public class ProjectFileControl extends BaseAgentController {
@RequestMapping(value = "sharding-merge", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<CommandOpResult> shardingMerge(String type,
String levelName,
Integer stripComponents,
String sliceId,
Integer totalSlice,
String fileSumMd5,
String after) throws Exception {
String levelName,
Integer stripComponents,
String sliceId,
Integer totalSlice,
String fileSumMd5,
String after) throws Exception {
String tempPathName = agentConfig.getFixedTempPathName();
File successFile = this.shardingTryMerge(tempPathName, sliceId, totalSlice, fileSumMd5);
// 处理上传文件
@ -276,7 +261,7 @@ public class ProjectFileControl extends BaseAgentController {
FileUtil.move(file, lib, true);
}
AbstractProjectCommander.getInstance().asyncWebHooks(pim, null, "fileChange",
"changeEvent", "upload", "levelName", levelName, "fileType", type, "fileName", file.getName());
"changeEvent", "upload", "levelName", levelName, "fileType", type, "fileName", file.getName());
//
JsonMessage<CommandOpResult> resultJsonMessage = this.saveProjectFileAfter(after, pim);
if (resultJsonMessage != null) {
@ -293,49 +278,23 @@ public class ProjectFileControl extends BaseAgentController {
return null;
}
//
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = pim.getJavaCopyItemList();
//
AfterOpt afterOpt = BaseEnum.getEnum(AfterOpt.class, Convert.toInt(after, AfterOpt.No.getCode()));
if ("restart".equalsIgnoreCase(after) || afterOpt == AfterOpt.Restart) {
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.restart, pim, null);
// 自动处理副本集
if (javaCopyItemList != null) {
ThreadUtil.execute(() -> javaCopyItemList.forEach(javaCopyItem -> {
try {
consoleService.execCommand(ConsoleCommandOp.restart, pim, javaCopyItem);
} catch (Exception e) {
log.error("重启副本集失败", e);
}
}));
}
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.restart, pim);
return new JsonMessage<>(result.isSuccess() ? 200 : 405, "上传成功并重启", result);
} else if (afterOpt == AfterOpt.Order_Restart || afterOpt == AfterOpt.Order_Must_Restart) {
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.restart, pim, null);
if (javaCopyItemList != null) {
int sleepTime = getParameterInt("sleepTime", 30);
ThreadUtil.execute(() -> {
// 副本
for (NodeProjectInfoModel.JavaCopyItem javaCopyItem : javaCopyItemList) {
if (!this.restart(pim, javaCopyItem, afterOpt)) {
return;
}
// 休眠x秒 等待之前项目正常启动
try {
TimeUnit.SECONDS.sleep(sleepTime);
} catch (InterruptedException ignored) {
}
}
});
}
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.restart, pim);
return new JsonMessage<>(result.isSuccess() ? 200 : 405, "上传成功并重启", result);
}
return null;
}
private boolean restart(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem, AfterOpt afterOpt) {
private boolean restart(NodeProjectInfoModel nodeProjectInfoModel, AfterOpt afterOpt) {
try {
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.restart, nodeProjectInfoModel, javaCopyItem);
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.restart, nodeProjectInfoModel);
if (result.isSuccess()) {
return true;
}
@ -357,10 +316,10 @@ public class ProjectFileControl extends BaseAgentController {
// 清空文件
if (FileUtil.clean(file)) {
AbstractProjectCommander.getInstance().asyncWebHooks(pim, null, "fileChange",
"changeEvent", "delete", "levelName", levelName, "deleteType", type, "fileName", filename);
"changeEvent", "delete", "levelName", levelName, "deleteType", type, "fileName", filename);
return JsonMessage.success("清除成功");
}
boolean run = AbstractProjectCommander.getInstance().isRun(pim, null);
boolean run = AbstractProjectCommander.getInstance().isRun(pim);
Assert.state(!run, "文件被占用,请先停止项目");
return new JsonMessage<>(500, "删除失败:" + file.getAbsolutePath());
} else {
@ -369,7 +328,7 @@ public class ProjectFileControl extends BaseAgentController {
file = FileUtil.file(file, filename);
if (FileUtil.del(file)) {
AbstractProjectCommander.getInstance().asyncWebHooks(pim, null, "fileChange",
"changeEvent", "delete", "levelName", levelName, "deleteType", type, "fileName", filename);
"changeEvent", "delete", "levelName", levelName, "deleteType", type, "fileName", filename);
return JsonMessage.success("删除成功");
}
return new JsonMessage<>(500, "删除失败");
@ -446,7 +405,7 @@ public class ProjectFileControl extends BaseAgentController {
try {
FileUtil.writeString(fileText, FileUtil.file(pim.allLib(), filePath, filename), charset);
AbstractProjectCommander.getInstance().asyncWebHooks(pim, null, "fileChange",
"changeEvent", "edit", "levelName", filePath, "fileName", filename);
"changeEvent", "edit", "levelName", filePath, "fileName", filename);
return JsonMessage.success("文件写入成功");
} finally {
ProjectFileBackupUtil.checkDiff(pim, backupId);
@ -523,7 +482,7 @@ public class ProjectFileControl extends BaseAgentController {
FileUtil.move(downloadFile, file, true);
}
AbstractProjectCommander.getInstance().asyncWebHooks(pim, null, "fileChange",
"changeEvent", "remoteDownload", "levelName", levelName, "fileName", file.getName(), "url", url);
"changeEvent", "remoteDownload", "levelName", levelName, "fileName", file.getName(), "url", url);
return JsonMessage.success("下载成功文件大小:" + fileSize);
} catch (Exception e) {
log.error("下载远程文件异常", e);
@ -556,7 +515,7 @@ public class ProjectFileControl extends BaseAgentController {
FileUtil.touch(file);
}
AbstractProjectCommander.getInstance().asyncWebHooks(projectInfoModel, null, "fileChange",
"changeEvent", "newFileOrFolder", "levelName", levelName, "fileName", filename, "folder", folder);
"changeEvent", "newFileOrFolder", "levelName", levelName, "fileName", filename, "folder", folder);
return JsonMessage.success("操作成功");
}
@ -580,7 +539,7 @@ public class ProjectFileControl extends BaseAgentController {
FileUtil.rename(file, newname, false);
AbstractProjectCommander.getInstance().asyncWebHooks(projectInfoModel, null, "fileChange",
"changeEvent", "rename", "levelName", levelName, "fileName", filename, "newname", newname);
"changeEvent", "rename", "levelName", levelName, "fileName", filename, "newname", newname);
return JsonMessage.success("操作成功");
}

View File

@ -22,7 +22,6 @@
*/
package org.dromara.jpom.controller.manage;
import cn.hutool.core.io.FileUtil;
import cn.keepbx.jpom.IJsonMessage;
import cn.keepbx.jpom.model.JsonMessage;
import lombok.extern.slf4j.Slf4j;
@ -31,12 +30,10 @@ import org.dromara.jpom.common.commander.AbstractProjectCommander;
import org.dromara.jpom.model.RunMode;
import org.dromara.jpom.model.data.NodeProjectInfoModel;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.util.List;
/**
@ -64,19 +61,9 @@ public class ProjectListController extends BaseAgentController {
RunMode runMode = nodeProjectInfoModel.getRunMode();
if (runMode != RunMode.Dsl && runMode != RunMode.File) {
// 返回实际执行的命令
String command = AbstractProjectCommander.getInstance().buildJavaCommand(nodeProjectInfoModel, null);
String command = AbstractProjectCommander.getInstance().buildJavaCommand(nodeProjectInfoModel);
nodeProjectInfoModel.setRunCommand(command);
}
//
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = nodeProjectInfoModel.getJavaCopyItemList();
if (javaCopyItemList != null) {
for (NodeProjectInfoModel.JavaCopyItem javaCopyItem : javaCopyItemList) {
File logBack = nodeProjectInfoModel.getLogBack(javaCopyItem);
File log = nodeProjectInfoModel.getLog(javaCopyItem);
javaCopyItem.setLogBack(FileUtil.getAbsolutePath(logBack));
javaCopyItem.setLog(FileUtil.getAbsolutePath(log));
}
}
}
return JsonMessage.success("", nodeProjectInfoModel);
}
@ -97,24 +84,4 @@ public class ProjectListController extends BaseAgentController {
return new JsonMessage<>(500, "查询异常:" + e.getMessage());
}
}
/**
* 展示项目页面
*/
@RequestMapping(value = "project_copy_list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<List<NodeProjectInfoModel.JavaCopyItem>> projectCopyList(String id) {
NodeProjectInfoModel nodeProjectInfoModel = projectInfoService.getItem(id);
Assert.notNull(nodeProjectInfoModel, "没有对应项目");
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = nodeProjectInfoModel.getJavaCopyItemList();
Assert.notEmpty(javaCopyItemList, "对应项目没有副本集");
// JSONArray array = new JSONArray();
// for (NodeProjectInfoModel.JavaCopyItem javaCopyItem : javaCopyItemList) {
// JSONObject object = javaCopyItem.toJson();
// boolean run = AbstractProjectCommander.getInstance().isRun(nodeProjectInfoModel, javaCopyItem);
// object.put("status", run);
// array.add(object);
// }
return JsonMessage.success("", javaCopyItemList);
}
}

View File

@ -43,8 +43,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 项目文件管理
*
@ -76,28 +74,13 @@ public class ProjectStatusController extends BaseAgentController {
try {
CommandUtil.openCache();
try {
CommandOpResult status = AbstractProjectCommander.getInstance().status(nodeProjectInfoModel, null);
CommandOpResult status = AbstractProjectCommander.getInstance().status(nodeProjectInfoModel);
jsonObject.put("pId", status.getPid());
jsonObject.put("pIds", status.getPids());
jsonObject.put("statusMsg", status.getStatusMsg());
} catch (Exception e) {
log.error("获取项目pid 失败", e);
}
//
if (StrUtil.isNotEmpty(getCopy)) {
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = nodeProjectInfoModel.getJavaCopyItemList();
JSONArray copys = new JSONArray();
if (javaCopyItemList != null) {
for (NodeProjectInfoModel.JavaCopyItem javaCopyItem : javaCopyItemList) {
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("copyId", javaCopyItem.getId());
boolean run = AbstractProjectCommander.getInstance().isRun(nodeProjectInfoModel, javaCopyItem);
jsonObject1.put("status", run);
copys.add(jsonObject1);
}
}
jsonObject.put("copys", copys);
}
} finally {
CommandUtil.closeCache();
}
@ -123,7 +106,7 @@ public class ProjectStatusController extends BaseAgentController {
try {
NodeProjectInfoModel projectInfoServiceItem = projectInfoService.getItem(item);
itemObj.put("name", projectInfoServiceItem.getName());
CommandOpResult commandOpResult = AbstractProjectCommander.getInstance().status(projectInfoServiceItem, null);
CommandOpResult commandOpResult = AbstractProjectCommander.getInstance().status(projectInfoServiceItem);
int pid = commandOpResult.getPid();
//
itemObj.put("pid", pid);
@ -148,60 +131,12 @@ public class ProjectStatusController extends BaseAgentController {
}
/**
* 获取项目的运行端口
*
* @param id 项目id
* @param copyIds 副本 ids ["aa","ss"]
* @return obj
*/
@RequestMapping(value = "getProjectCopyPort", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<JSONObject> getProjectPort(String id, String copyIds) {
if (StrUtil.isEmpty(copyIds) || StrUtil.isEmpty(id)) {
return new JsonMessage<>(400, "参数异常");
}
NodeProjectInfoModel nodeProjectInfoModel = getProjectInfoModel();
JSONArray jsonArray = JSONArray.parseArray(copyIds);
JSONObject jsonObject = new JSONObject();
try {
CommandUtil.openCache();
for (Object object : jsonArray) {
String item = object.toString();
NodeProjectInfoModel.JavaCopyItem copyItem = nodeProjectInfoModel.findCopyItem(item);
JSONObject itemObj = new JSONObject();
if (copyItem != null) {
try {
CommandOpResult status = AbstractProjectCommander.getInstance().status(nodeProjectInfoModel, copyItem);
int pid = status.getPid();
String port = AbstractProjectCommander.getInstance().getMainPort(pid);
itemObj.put("port", port);
itemObj.put("pid", pid);
itemObj.put("pids", status.getPids());
itemObj.put("statusMsg", status.getStatusMsg());
} catch (Exception e) {
log.error("获取端口错误", e);
itemObj.put("error", e.getMessage());
}
} else {
itemObj.put("error", "对应的副本不存在");
}
jsonObject.put(item, itemObj);
}
} finally {
CommandUtil.closeCache();
}
return JsonMessage.success("", jsonObject);
}
@RequestMapping(value = "restart", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<CommandOpResult> restart(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确") String id, String copyId) {
public IJsonMessage<CommandOpResult> restart(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确") String id) {
NodeProjectInfoModel item = projectInfoService.getItem(id);
Assert.notNull(item, "没有找到对应的项目");
NodeProjectInfoModel.JavaCopyItem copyItem = item.findCopyItem(copyId);
try {
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.restart, item, copyItem);
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.restart, item);
// boolean status = AbstractProjectCommander.getInstance().isRun(item, copyItem);
return new JsonMessage<>(result.isSuccess() ? 200 : 201, result.isSuccess() ? "操作成功" : "操作失败:" + result.msgStr(), result);
@ -214,13 +149,12 @@ public class ProjectStatusController extends BaseAgentController {
@RequestMapping(value = "stop", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<CommandOpResult> stop(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确") String id, String copyId) {
public IJsonMessage<CommandOpResult> stop(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确") String id) {
NodeProjectInfoModel item = projectInfoService.getItem(id);
Assert.notNull(item, "没有找到对应的项目");
NodeProjectInfoModel.JavaCopyItem copyItem = item.findCopyItem(copyId);
try {
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.stop, item, copyItem);
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.stop, item);
return new JsonMessage<>(result.isSuccess() ? 200 : 201, result.isSuccess() ? "操作成功" : "操作失败:" + result.msgStr(), result);
} catch (Exception e) {
log.error("关闭项目异常", e);
@ -230,13 +164,12 @@ public class ProjectStatusController extends BaseAgentController {
@RequestMapping(value = "start", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<CommandOpResult> start(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确") String id, String copyId) {
public IJsonMessage<CommandOpResult> start(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "项目id 不正确") String id) {
NodeProjectInfoModel item = projectInfoService.getItem(id);
Assert.notNull(item, "没有找到对应的项目");
NodeProjectInfoModel.JavaCopyItem copyItem = item.findCopyItem(copyId);
try {
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.start, item, copyItem);
CommandOpResult result = consoleService.execCommand(ConsoleCommandOp.start, item);
return new JsonMessage<>(result.isSuccess() ? 200 : 201, result.isSuccess() ? "操作成功" : "操作失败:" + result.msgStr(), result);
} catch (Exception e) {
log.error("获取项目pid 失败", e);

View File

@ -53,26 +53,24 @@ import java.util.List;
public class LogBackController extends BaseAgentController {
@RequestMapping(value = "logSize", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<JSONObject> logSize(String id, String copyId) {
public IJsonMessage<JSONObject> logSize(String id) {
NodeProjectInfoModel nodeProjectInfoModel = getProjectInfoModel();
JSONObject jsonObject = new JSONObject();
//
NodeProjectInfoModel.JavaCopyItem copyItem = nodeProjectInfoModel.findCopyItem(copyId);
//获取日志备份路径
File logBack = copyItem == null ? nodeProjectInfoModel.getLogBack() : nodeProjectInfoModel.getLogBack(copyItem);
File logBack = nodeProjectInfoModel.getLogBack();
boolean logBackBool = logBack.exists() && logBack.isDirectory();
jsonObject.put("logBack", logBackBool);
String info = projectInfoService.getLogSize(nodeProjectInfoModel, copyItem);
String info = projectInfoService.getLogSize(nodeProjectInfoModel);
jsonObject.put("logSize", info);
return JsonMessage.success("", jsonObject);
}
@RequestMapping(value = "resetLog", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<String> resetLog(String copyId) {
public IJsonMessage<String> resetLog() {
NodeProjectInfoModel pim = getProjectInfoModel();
NodeProjectInfoModel.JavaCopyItem copyItem = pim.findCopyItem(copyId);
try {
String msg = AbstractProjectCommander.getInstance().backLog(pim, copyItem);
String msg = AbstractProjectCommander.getInstance().backLog(pim);
if (msg.contains("ok")) {
return JsonMessage.success("重置成功");
}
@ -84,11 +82,10 @@ public class LogBackController extends BaseAgentController {
}
@RequestMapping(value = "logBack_delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<String> clear(String name, String copyId) {
public IJsonMessage<String> clear(String name) {
Assert.hasText(name, "没有对应到文件");
NodeProjectInfoModel pim = getProjectInfoModel();
NodeProjectInfoModel.JavaCopyItem copyItem = pim.findCopyItem(copyId);
File logBack = copyItem == null ? pim.getLogBack() : pim.getLogBack(copyItem);
File logBack = pim.getLogBack();
if (logBack.exists() && logBack.isDirectory()) {
logBack = FileUtil.file(logBack, name);
if (logBack.exists()) {
@ -102,12 +99,11 @@ public class LogBackController extends BaseAgentController {
}
@RequestMapping(value = "logBack_download", method = RequestMethod.GET)
public void download(String key, String copyId, HttpServletResponse response) {
public void download(String key, HttpServletResponse response) {
Assert.hasText(key, "请选择对应到文件");
try {
NodeProjectInfoModel pim = getProjectInfoModel();
NodeProjectInfoModel.JavaCopyItem copyItem = pim.findCopyItem(copyId);
File logBack = copyItem == null ? pim.getLogBack() : pim.getLogBack(copyItem);
File logBack = pim.getLogBack();
if (logBack.exists() && logBack.isDirectory()) {
logBack = FileUtil.file(logBack, key);
ServletUtil.write(response, logBack);
@ -121,13 +117,13 @@ public class LogBackController extends BaseAgentController {
}
@RequestMapping(value = "logBack", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage<JSONObject> console(String copyId) {
public IJsonMessage<JSONObject> console() {
// 查询项目路径
NodeProjectInfoModel pim = getProjectInfoModel();
NodeProjectInfoModel.JavaCopyItem copyItem = pim.findCopyItem(copyId);
JSONObject jsonObject = new JSONObject();
File logBack = copyItem == null ? pim.getLogBack() : pim.getLogBack(copyItem);
File logBack = pim.getLogBack();
if (logBack.exists() && logBack.isDirectory()) {
File[] filesAll = logBack.listFiles();
if (filesAll != null) {
@ -136,17 +132,17 @@ public class LogBackController extends BaseAgentController {
}
}
jsonObject.put("id", pim.getId());
jsonObject.put("logPath", copyItem == null ? pim.getLog() : pim.getLog(copyItem));
jsonObject.put("logPath", pim.getLog());
jsonObject.put("logBackPath", logBack.getAbsolutePath());
return JsonMessage.success("", jsonObject);
}
@RequestMapping(value = "export.html", method = RequestMethod.GET)
@ResponseBody
public void export(String copyId, HttpServletResponse response) {
public void export(HttpServletResponse response) {
NodeProjectInfoModel pim = getProjectInfoModel();
NodeProjectInfoModel.JavaCopyItem copyItem = pim.findCopyItem(copyId);
File file = copyItem == null ? new File(pim.getLog()) : pim.getLog(copyItem);
File file = new File(pim.getLog());
if (!file.exists()) {
ServletUtil.write(response, JsonMessage.getString(400, "没有日志文件:" + file.getPath()), MediaType.APPLICATION_JSON_VALUE);
return;

View File

@ -27,7 +27,6 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.keepbx.jpom.model.BaseJsonModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.jpom.model.RunMode;
@ -35,7 +34,10 @@ import org.dromara.jpom.system.JpomRuntimeException;
import org.springframework.util.Assert;
import java.io.File;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
@ -70,8 +72,6 @@ public class NodeProjectInfoModel extends BaseWorkspaceModel {
* java main 方法参数
*/
private String args;
private List<JavaCopyItem> javaCopyItemList;
/**
* WebHooks
*/
@ -109,14 +109,6 @@ public class NodeProjectInfoModel extends BaseWorkspaceModel {
*/
private String dslEnv;
public List<JavaCopyItem> getJavaCopyItemList() {
return javaCopyItemList;
}
public void setJavaCopyItemList(List<JavaCopyItem> javaCopyItemList) {
this.javaCopyItemList = javaCopyItemList;
}
public String getJavaExtDirsCp() {
return StrUtil.emptyToDefault(javaExtDirsCp, StrUtil.EMPTY);
}
@ -249,23 +241,10 @@ public class NodeProjectInfoModel extends BaseWorkspaceModel {
return StrUtil.emptyToDefault(this.log, StrUtil.EMPTY);
}
/**
* 副本的控制台日志文件
*
* @param javaCopyItem 副本信息
* @return file
*/
public File getLog(JavaCopyItem javaCopyItem) {
String log1 = getLog();
Assert.hasText(log1, "log path error");
File file = FileUtil.file(log1);
return FileUtil.file(file.getParentFile(), getId() + "_" + javaCopyItem.getId() + ".log");
}
public String getAbsoluteLog(JavaCopyItem javaCopyItem) {
public String getAbsoluteLog() {
String pathname = getLog();
Assert.hasText(pathname, "log path error");
File file = javaCopyItem == null ? new File(pathname) : getLog(javaCopyItem);
File file = new File(pathname);
// auto create dir
FileUtil.mkParentDirs(file);
return file.getAbsolutePath();
@ -277,10 +256,6 @@ public class NodeProjectInfoModel extends BaseWorkspaceModel {
return new File(log1 + "_back");
}
public File getLogBack(JavaCopyItem javaCopyItem) {
return new File(getLog(javaCopyItem) + "_back");
}
/**
* 默认
*
@ -294,33 +269,6 @@ public class NodeProjectInfoModel extends BaseWorkspaceModel {
return StrUtil.emptyToDefault(token, StrUtil.EMPTY);
}
public JavaCopyItem findCopyItem(String copyId) {
if (StrUtil.isEmpty(copyId)) {
return null;
}
List<JavaCopyItem> javaCopyItemList = getJavaCopyItemList();
if (CollUtil.isEmpty(javaCopyItemList)) {
return null;
}
Optional<JavaCopyItem> first = javaCopyItemList.stream().filter(javaCopyItem -> StrUtil.equals(javaCopyItem.getId(), copyId)).findFirst();
return first.orElse(null);
}
public boolean removeCopyItem(String copyId) {
if (StrUtil.isEmpty(copyId) || CollUtil.isEmpty(javaCopyItemList)) {
return true;
}
int size = javaCopyItemList.size();
List<JavaCopyItem> collect = javaCopyItemList.stream().filter(javaCopyItem -> !StrUtil.equals(javaCopyItem.getId(), copyId)).collect(Collectors.toList());
if (size - 1 == collect.size()) {
this.javaCopyItemList = collect;
return true;
} else {
return false;
}
}
public DslYmlDto dslConfig() {
String dslContent = this.getDslContent();
if (StrUtil.isEmpty(dslContent)) {
@ -354,76 +302,4 @@ public class NodeProjectInfoModel extends BaseWorkspaceModel {
Assert.notNull(build, "yml 还未配置");
return build.runProcess(opt);
}
@EqualsAndHashCode(callSuper = true)
@Data
public static class JavaCopyItem extends BaseJsonModel {
/**
* 名称
*/
private String name;
private String parentId;
/**
* id
*/
private String id;
/**
* jvm 参数
*/
private String jvm;
/**
* java main 方法参数
*/
private String args;
private String modifyTime;
/**
* 日志
*/
private String log;
/**
* 日志备份
*/
private String logBack;
public String getTagId() {
return getTagId(this.getParentId(), id);
}
/**
* 创建进程标记
*
* @param id 父级项目ID
* @param copyId 副本ID
* @return 运行ID
*/
public static String getTagId(String id, String copyId) {
if (StrUtil.isEmpty(copyId)) {
return id;
}
return StrUtil.format("{}:{}", id, copyId);
}
/**
* 请勿随意修改此方法用户判断副本是否相同编辑接口需要使用到
*
* @param o 尝试
* @return bool
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
JavaCopyItem that = (JavaCopyItem) o;
return Objects.equals(parentId, that.parentId) &&
Objects.equals(id, that.id);
}
}
}

View File

@ -48,26 +48,25 @@ public class ConsoleService {
*
* @param consoleCommandOp 执行的操作
* @param nodeProjectInfoModel 项目信息
* @param copyItem 副本信息
* @return 执行结果
* @throws Exception 异常
*/
public CommandOpResult execCommand(ConsoleCommandOp consoleCommandOp, NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem copyItem) throws Exception {
public CommandOpResult execCommand(ConsoleCommandOp consoleCommandOp, NodeProjectInfoModel nodeProjectInfoModel) throws Exception {
CommandOpResult result;
AbstractProjectCommander abstractProjectCommander = AbstractProjectCommander.getInstance();
// 执行命令
switch (consoleCommandOp) {
case restart:
result = abstractProjectCommander.restart(nodeProjectInfoModel, copyItem);
result = abstractProjectCommander.restart(nodeProjectInfoModel);
break;
case start:
result = abstractProjectCommander.start(nodeProjectInfoModel, copyItem);
result = abstractProjectCommander.start(nodeProjectInfoModel);
break;
case stop:
result = abstractProjectCommander.stop(nodeProjectInfoModel, copyItem);
result = abstractProjectCommander.stop(nodeProjectInfoModel);
break;
case status: {
result = abstractProjectCommander.status(nodeProjectInfoModel, copyItem);
result = abstractProjectCommander.status(nodeProjectInfoModel);
break;
}
case top:
@ -80,10 +79,6 @@ public class ConsoleService {
// 修改 run lib 使用情况
NodeProjectInfoModel modify = projectInfoService.getItem(nodeProjectInfoModel.getId());
//
if (copyItem != null) {
NodeProjectInfoModel.JavaCopyItem copyItem1 = modify.findCopyItem(copyItem.getId());
copyItem1.setModifyTime(DateUtil.now());
}
try {
projectInfoService.updateItem(modify);
} catch (Exception ignored) {

View File

@ -68,14 +68,13 @@ public class ProjectInfoService extends BaseWorkspaceOptService<NodeProjectInfoM
* 查看项目控制台日志文件大小
*
* @param nodeProjectInfoModel 项目
* @param copyItem 副本
* @return 文件大小
*/
public String getLogSize(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem copyItem) {
public String getLogSize(NodeProjectInfoModel nodeProjectInfoModel) {
if (nodeProjectInfoModel == null) {
return null;
}
File file = copyItem == null ? new File(nodeProjectInfoModel.getLog()) : nodeProjectInfoModel.getLog(copyItem);
File file = new File(nodeProjectInfoModel.getLog());
if (file.exists()) {
long fileSize = file.length();
if (fileSize <= 0) {

View File

@ -78,16 +78,14 @@ public class AgentWebSocketConsoleHandle extends BaseAgentWebSocketHandle {
return;
}
String projectId = super.getParameters(session, "projectId");
String copyId = super.getParameters(session, "copyId");
copyId = StrUtil.nullToDefault(copyId, StrUtil.EMPTY);
// 判断项目
if (!Const.SYSTEM_ID.equals(projectId)) {
NodeProjectInfoModel nodeProjectInfoModel = this.checkProject(projectId, copyId, session);
NodeProjectInfoModel nodeProjectInfoModel = this.checkProject(projectId, session);
if (nodeProjectInfoModel == null) {
return;
}
//
SocketSessionUtil.send(session, "连接成功:" + nodeProjectInfoModel.getName() + (StrUtil.isEmpty(copyId) ? StrUtil.EMPTY : StrUtil.AT + copyId));
SocketSessionUtil.send(session, "连接成功:" + nodeProjectInfoModel.getName());
}
} catch (Exception e) {
log.error("socket 错误", e);
@ -118,22 +116,13 @@ public class AgentWebSocketConsoleHandle extends BaseAgentWebSocketHandle {
return false;
}
private NodeProjectInfoModel checkProject(String projectId, String copyId, Session session) throws IOException {
private NodeProjectInfoModel checkProject(String projectId, Session session) throws IOException {
NodeProjectInfoModel nodeProjectInfoModel = projectInfoService.getItem(projectId);
if (nodeProjectInfoModel == null) {
SocketSessionUtil.send(session, "没有对应项目:" + projectId);
session.close();
return null;
}
// 判断副本集
if (StrUtil.isNotEmpty(copyId)) {
NodeProjectInfoModel.JavaCopyItem copyItem = nodeProjectInfoModel.findCopyItem(copyId);
if (copyItem == null) {
SocketSessionUtil.send(session, "获取项目信息错误,没有对应副本:" + copyId);
session.close();
return null;
}
}
return nodeProjectInfoModel;
}
@ -146,17 +135,16 @@ public class AgentWebSocketConsoleHandle extends BaseAgentWebSocketHandle {
return;
}
String projectId = json.getString("projectId");
String copyId = json.getString("copyId");
NodeProjectInfoModel nodeProjectInfoModel = this.checkProject(projectId, copyId, session);
NodeProjectInfoModel nodeProjectInfoModel = this.checkProject(projectId, session);
if (nodeProjectInfoModel == null) {
return;
}
runMsg(consoleCommandOp, session, nodeProjectInfoModel, copyId, json);
runMsg(consoleCommandOp, session, nodeProjectInfoModel, json);
}
private void runMsg(ConsoleCommandOp consoleCommandOp, Session session, NodeProjectInfoModel nodeProjectInfoModel, String copyId, JSONObject reqJson) throws Exception {
private void runMsg(ConsoleCommandOp consoleCommandOp, Session session, NodeProjectInfoModel nodeProjectInfoModel, JSONObject reqJson) throws Exception {
//
NodeProjectInfoModel.JavaCopyItem copyItem = nodeProjectInfoModel.findCopyItem(copyId);
JsonMessage<Object> resultData = null;
CommandOpResult strResult;
boolean logUser = false;
@ -166,7 +154,7 @@ public class AgentWebSocketConsoleHandle extends BaseAgentWebSocketHandle {
case start:
case restart:
logUser = true;
strResult = consoleService.execCommand(consoleCommandOp, nodeProjectInfoModel, copyItem);
strResult = consoleService.execCommand(consoleCommandOp, nodeProjectInfoModel);
if (strResult.isSuccess()) {
resultData = new JsonMessage<>(200, "操作成功", strResult);
} else {
@ -176,7 +164,7 @@ public class AgentWebSocketConsoleHandle extends BaseAgentWebSocketHandle {
case stop: {
logUser = true;
// 停止项目
strResult = consoleService.execCommand(consoleCommandOp, nodeProjectInfoModel, copyItem);
strResult = consoleService.execCommand(consoleCommandOp, nodeProjectInfoModel);
if (strResult.isSuccess()) {
resultData = new JsonMessage<>(200, "操作成功", strResult);
} else {
@ -186,7 +174,7 @@ public class AgentWebSocketConsoleHandle extends BaseAgentWebSocketHandle {
}
case status: {
// 获取项目状态
strResult = consoleService.execCommand(consoleCommandOp, nodeProjectInfoModel, copyItem);
strResult = consoleService.execCommand(consoleCommandOp, nodeProjectInfoModel);
if (strResult.isSuccess()) {
resultData = new JsonMessage<>(200, "运行中", strResult);
} else {
@ -200,7 +188,7 @@ public class AgentWebSocketConsoleHandle extends BaseAgentWebSocketHandle {
if (StrUtil.isNotEmpty(search)) {
resultData = searchLog(session, nodeProjectInfoModel, reqJson);
} else {
showLog(session, nodeProjectInfoModel, reqJson, copyItem);
showLog(session, nodeProjectInfoModel, reqJson);
}
break;
}
@ -288,12 +276,12 @@ public class AgentWebSocketConsoleHandle extends BaseAgentWebSocketHandle {
return null;
}
private void showLog(Session session, NodeProjectInfoModel nodeProjectInfoModel, JSONObject reqJson, NodeProjectInfoModel.JavaCopyItem copyItem) throws IOException {
private void showLog(Session session, NodeProjectInfoModel nodeProjectInfoModel, JSONObject reqJson) throws IOException {
// 日志文件路径
String fileName = reqJson.getString("fileName");
File file;
if (StrUtil.isEmpty(fileName)) {
file = copyItem == null ? new File(nodeProjectInfoModel.getLog()) : nodeProjectInfoModel.getLog(copyItem);
file = new File(nodeProjectInfoModel.getLog());
} else {
file = FileUtil.file(nodeProjectInfoModel.allLib(), fileName);
}

View File

@ -99,23 +99,16 @@ public class AgentStartInit implements ILoadEvent, ISystemTask {
if (list == null) {
return;
}
list.forEach(projectInfoModel -> {
checkProject(projectInfoModel, null);
//
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = projectInfoModel.getJavaCopyItemList();
if (javaCopyItemList == null) {
return;
}
javaCopyItemList.forEach(javaCopyItem -> checkProject(projectInfoModel, javaCopyItem));
});
//
list.forEach(this::checkProject);
} catch (Exception e) {
log.error("定时备份日志失败", e);
}
});
}
private void checkProject(NodeProjectInfoModel nodeProjectInfoModel, NodeProjectInfoModel.JavaCopyItem javaCopyItem) {
File file = javaCopyItem == null ? new File(nodeProjectInfoModel.getLog()) : nodeProjectInfoModel.getLog(javaCopyItem);
private void checkProject(NodeProjectInfoModel nodeProjectInfoModel) {
File file = new File(nodeProjectInfoModel.getLog());
if (!file.exists()) {
return;
}
@ -125,13 +118,13 @@ public class AgentStartInit implements ILoadEvent, ISystemTask {
long len = file.length();
if (len > autoBackSize.toBytes()) {
try {
AbstractProjectCommander.getInstance().backLog(nodeProjectInfoModel, javaCopyItem);
AbstractProjectCommander.getInstance().backLog(nodeProjectInfoModel);
} catch (Exception e) {
log.warn("auto back log", e);
}
}
// 清理过期的文件
File logFile = javaCopyItem == null ? nodeProjectInfoModel.getLogBack() : nodeProjectInfoModel.getLogBack(javaCopyItem);
File logFile = nodeProjectInfoModel.getLogBack();
DateTime nowTime = DateTime.now();
List<File> files = FileUtil.loopFiles(logFile, pathname -> {
DateTime dateTime = DateUtil.date(pathname.lastModified());
@ -180,16 +173,8 @@ public class AgentStartInit implements ILoadEvent, ISystemTask {
AbstractProjectCommander instance = AbstractProjectCommander.getInstance();
for (NodeProjectInfoModel nodeProjectInfoModel : finalList) {
try {
if (!instance.isRun(nodeProjectInfoModel, null)) {
instance.start(nodeProjectInfoModel, null);
}
List<NodeProjectInfoModel.JavaCopyItem> javaCopyItemList = nodeProjectInfoModel.getJavaCopyItemList();
if (javaCopyItemList != null) {
for (NodeProjectInfoModel.JavaCopyItem javaCopyItem : javaCopyItemList) {
if (!instance.isRun(nodeProjectInfoModel, javaCopyItem)) {
instance.start(nodeProjectInfoModel, javaCopyItem);
}
}
if (!instance.isRun(nodeProjectInfoModel)) {
instance.start(nodeProjectInfoModel);
}
} catch (Exception e) {
log.warn("自动启动项目失败:{} {}", nodeProjectInfoModel.getId(), e.getMessage());

View File

@ -173,24 +173,24 @@ public class ProjectManageControl extends BaseServerController {
@PostMapping(value = "deleteProject", produces = MediaType.APPLICATION_JSON_VALUE)
@Feature(method = MethodFeature.DEL)
public IJsonMessage<String> deleteProject(@ValidatorItem(value = ValidatorRule.NOT_BLANK) String id,
String copyId,
HttpServletRequest request) {
NodeModel nodeModel = getNode();
if (StrUtil.isEmpty(copyId)) {
// 检查节点分发
outGivingServer.checkNodeProject(nodeModel.getId(), id, request, "当前项目存在节点分发,不能直接删除");
// 检查日志阅读
logReadServer.checkNodeProject(nodeModel.getId(), id, request, "当前项目存在日志阅读,不能直接删除");
// 项目监控
List<MonitorModel> monitorModels = monitorService.listByWorkspace(request);
if (monitorModels != null) {
boolean match = monitorModels.stream().anyMatch(monitorModel -> monitorModel.checkNodeProject(nodeModel.getId(), id));
Assert.state(!match, "当前项目存在监控项,不能直接删除");
}
// 构建
boolean releaseMethod = buildService.checkReleaseMethod(nodeModel.getId() + StrUtil.COLON + id, request, BuildReleaseMethod.Project);
Assert.state(!releaseMethod, "当前项目存在构建项,不能直接删除");
// 检查节点分发
outGivingServer.checkNodeProject(nodeModel.getId(), id, request, "当前项目存在节点分发,不能直接删除");
// 检查日志阅读
logReadServer.checkNodeProject(nodeModel.getId(), id, request, "当前项目存在日志阅读,不能直接删除");
// 项目监控
List<MonitorModel> monitorModels = monitorService.listByWorkspace(request);
if (monitorModels != null) {
boolean match = monitorModels.stream().anyMatch(monitorModel -> monitorModel.checkNodeProject(nodeModel.getId(), id));
Assert.state(!match, "当前项目存在监控项,不能直接删除");
}
// 构建
boolean releaseMethod = buildService.checkReleaseMethod(nodeModel.getId() + StrUtil.COLON + id, request, BuildReleaseMethod.Project);
Assert.state(!releaseMethod, "当前项目存在构建项,不能直接删除");
JsonMessage<String> jsonMessage = NodeForward.request(nodeModel, request, NodeUrl.Manage_DeleteProject);
if (jsonMessage.success()) {
//
@ -372,7 +372,7 @@ public class ProjectManageControl extends BaseServerController {
/**
* 重启项目
* <p>
* nodeId,id,copyId
* nodeId,id
*
* @return json
*/
@ -387,7 +387,7 @@ public class ProjectManageControl extends BaseServerController {
/**
* 启动项目
* <p>
* nodeId,id,copyId
* nodeId,id
*
* @return json
*/
@ -402,7 +402,7 @@ public class ProjectManageControl extends BaseServerController {
/**
* 关闭项目项目
* <p>
* nodeId,id,copyId
* nodeId,id
*
* @return json
*/

View File

@ -98,11 +98,9 @@ public class LogBackController extends BaseServerController {
@RequestMapping(value = "logSize", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public IJsonMessage<JSONObject> logSize(String id, String copyId) {
// JSONObject info = projectInfoCacheService.getLogSize(getNode(), id, copyId);
return NodeForward.request(getNode(), NodeUrl.Manage_Log_LogSize, "id", id, "copyId", copyId);
// return requestData.getData();
// return JsonMessage.success("", info);
public IJsonMessage<JSONObject> logSize(String id) {
return NodeForward.request(getNode(), NodeUrl.Manage_Log_LogSize, "id", id);
}
/**

View File

@ -390,20 +390,7 @@ public class OutGivingProjectEditController extends BaseServerController {
String autoStart = getParameter(StrUtil.format("{}_autoStart", nodeModel.getId()));
allData.put("autoStart", Convert.toBool(autoStart, false));
allData.put("dslEnv", getParameter(StrUtil.format("{}_dslEnv", nodeModel.getId())));
// 项目副本
String javaCopyIds = getParameter(StrUtil.format("{}_javaCopyIds", nodeModel.getId()));
allData.put("javaCopyIds", javaCopyIds);
if (StrUtil.isNotEmpty(javaCopyIds)) {
String[] split = StrUtil.splitToArray(javaCopyIds, StrUtil.COMMA);
for (String copyId : split) {
String copyJvm = getParameter(StrUtil.format("{}_jvm_{}", nodeModel.getId(), copyId));
String copyArgs = getParameter(StrUtil.format("{}_args_{}", nodeModel.getId(), copyId));
String nameArgs = getParameter(StrUtil.format("{}_name_{}", nodeModel.getId(), copyId));
allData.put("jvm_" + copyId, copyJvm);
allData.put("args_" + copyId, copyArgs);
allData.put("name_" + copyId, nameArgs);
}
}
JsonMessage<String> jsonMessage = this.sendData(nodeModel, allData, false);
Assert.state(jsonMessage.success(), nodeModel.getName() + "节点失败:" + jsonMessage.getMsg());
tuples.add(new Tuple(nodeModel, allData));

View File

@ -123,7 +123,7 @@ public class MonitorItem implements Task {
JSONObject jsonObject = jsonMessage.getData();
int pid = jsonObject.getIntValue("pId");
String statusMsg = jsonObject.getString("statusMsg");
boolean runStatus = this.checkNotify(monitorModel, nodeModel, id, null, pid > 0, statusMsg);
boolean runStatus = this.checkNotify(monitorModel, nodeModel, id, pid > 0, statusMsg);
// 检查副本
List<Boolean> booleanList = null;
JSONArray copys = jsonObject.getJSONArray("copys");
@ -131,9 +131,9 @@ public class MonitorItem implements Task {
booleanList = copys.stream()
.map(o -> {
JSONObject jsonObject1 = (JSONObject) o;
String copyId = jsonObject1.getString("copyId");
boolean status = jsonObject1.getBooleanValue("status");
return MonitorItem.this.checkNotify(monitorModel, nodeModel, id, copyId, status, StrUtil.EMPTY);
return MonitorItem.this.checkNotify(monitorModel, nodeModel, id, status, StrUtil.EMPTY);
})
.filter(aBoolean -> !aBoolean)
.collect(Collectors.toList());
@ -175,18 +175,12 @@ public class MonitorItem implements Task {
* @param monitorModel 监控信息
* @param nodeModel 节点信息
* @param id 项目id
* @param copyId 副本id
* @param runStatus 当前运行状态
*/
private boolean checkNotify(MonitorModel monitorModel, NodeModel nodeModel, String id, String copyId, boolean runStatus, String statusMsg) {
private boolean checkNotify(MonitorModel monitorModel, NodeModel nodeModel, String id, boolean runStatus, String statusMsg) {
// 获取上次状态
String projectCopyId = id;
String copyMsg = StrUtil.EMPTY;
if (StrUtil.isNotEmpty(copyId)) {
projectCopyId = StrUtil.format("{}:{}", id, copyId);
copyMsg = StrUtil.format("副本:{}", copyId);
}
boolean pre = this.getPreStatus(monitorModel.getId(), nodeModel.getId(), projectCopyId);
boolean pre = this.getPreStatus(monitorModel.getId(), nodeModel.getId(), id);
String title = null;
String context = null;
//查询项目运行状态
@ -201,7 +195,7 @@ public class MonitorItem implements Task {
if (monitorModel.autoRestart()) {
// 执行重启
try {
JsonMessage<String> reJson = NodeForward.request(nodeModel, NodeUrl.Manage_Restart, "id", id, "copyId", copyId);
JsonMessage<String> reJson = NodeForward.request(nodeModel, NodeUrl.Manage_Restart, "id", id);
if (reJson.success()) {
// 重启成功
runStatus = true;

View File

@ -22,7 +22,6 @@
*/
package org.dromara.jpom.service.node;
import cn.hutool.core.collection.CollUtil;
import cn.keepbx.jpom.model.JsonMessage;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
@ -35,8 +34,6 @@ import org.dromara.jpom.service.h2db.BaseNodeService;
import org.dromara.jpom.service.system.WorkspaceService;
import org.springframework.stereotype.Service;
import java.util.stream.Collectors;
/**
* @author bwcx_jzy
* @since 2021/12/5
@ -100,23 +97,7 @@ public class ProjectInfoCacheService extends BaseNodeService<ProjectInfoCacheMod
* @return data
*/
public JSONObject convertToRequestData(JSONObject item) {
JSONArray javaCopyItemList = item.getJSONArray("javaCopyItemList");
if (CollUtil.isNotEmpty(javaCopyItemList)) {
String javaCopyIds = javaCopyItemList.stream().map(o -> {
JSONObject javaCopyItem = (JSONObject) o;
String id = javaCopyItem.getString("id");
String name = javaCopyItem.getString("name");
String jvm = javaCopyItem.getString("jvm");
String args = javaCopyItem.getString("args");
//
item.put("jvm_" + id, jvm);
item.put("args_" + id, args);
item.put("name_" + id, name);
return id;
}).collect(Collectors.joining(","));
item.put("javaCopyIds", javaCopyIds);
item.remove("javaCopyItemList");
}
return item;
}

View File

@ -112,7 +112,7 @@ public class ServerWebSocketInterceptor implements HandshakeInterceptor {
if (dataItem == null) {
return false;
}
attributes.put("copyId", httpServletRequest.getParameter("copyId"));
attributes.put("projectId", BeanUtil.getProperty(dataItem, "projectId"));
attributes.put("dataItem", dataItem);
break;

View File

@ -50,7 +50,7 @@ public class ConsoleHandler extends BaseProxyHandler {
@Override
protected Object[] getParameters(Map<String, Object> attributes) {
return new Object[]{"projectId", attributes.get("projectId"), "copyId", attributes.get("copyId")};
return new Object[]{"projectId", attributes.get("projectId")};
}
@Override

View File

@ -74,10 +74,7 @@ export function editDispatch(params) {
* whitelistDirectory: 白名单地址
* lib: lib
* add_xxx: xxx 表示添加的节点信息
* xxx_token: xxx 节点的 webhook 地址
* xxx_jvm: jvm 参数
* xxx_args: args 参数
* xxx_javaCopyIds: xxx 节点副本 ID 如果有副本还需要加上 xxx_jvm_${副本ID} | xxx_args_${副本ID} 参数
* } params
*/
export function editDispatchProject(params) {

View File

@ -39,23 +39,6 @@ export function getRuningProjectInfo(params, noTip) {
});
}
/**
* 获取副本 端口信息
* @param {*} params
* @returns
*/
export function getRuningProjectCopyInfo(params) {
return axios({
url: "/node/manage/getProjectCopyPort",
method: "post",
data: params,
timeout: 0,
headers: {
loading: "no",
},
});
}
/**
* 获取单个项目信息
* @param {
@ -95,13 +78,9 @@ export function getProjectAccessList(nodeId) {
* group: 分组名称
* ...
* }
* @param {JSON} replicaParams {
* javaCopyIds: 副本 xx1,xx2
* jvm_xxn: 副本 n JVM 参数
* args_xxn: 副本 n args 参数
* }
*/
export function editProject(params, replicaParams) {
export function editProject(params) {
const data = {
nodeId: params.nodeId,
id: params.id,
@ -119,7 +98,6 @@ export function editProject(params, replicaParams) {
logPath: params.logPath,
autoStart: params.autoStart,
dslContent: params.dslContent,
...replicaParams,
};
return axios({
url: "/node/manage/saveProject",
@ -133,7 +111,7 @@ export function editProject(params, replicaParams) {
* @param {
* nodeId: 节点 ID
* id: 项目 ID
* copyId: copyId
* } params
*/
export function deleteProject(params) {
@ -288,39 +266,12 @@ export function deleteProjectFile(params) {
});
}
/**
* 项目回收列表
* @param {String} nodeId 节点 ID
*/
export function getRecoverList(nodeId) {
return axios({
url: "/node/manage/recover/recover-list",
method: "post",
data: { nodeId },
});
}
/**
* 获取回收项目信息
* @param {
* nodeId: 节点 ID
* id: 项目 ID
* } params
*/
export function getRecoverData(params) {
return axios({
url: "/node/manage/recover/data.json",
method: "post",
data: params,
});
}
/**
* 获取项目日志文件大小
* @param {
* nodeId: 节点 ID
* id: 项目 ID
* copyId: copyId
* } params
*/
export function getProjectLogSize(params) {
@ -339,7 +290,7 @@ export function getProjectLogSize(params) {
* @param {
* nodeId: 节点 ID
* id: 项目 ID
* copyId: copyId
* } params
*/
export function downloadProjectLogFile(params) {
@ -366,7 +317,7 @@ export function getLogBackList(params) {
* @param {
* nodeId: 节点 ID
* id: 项目 ID
* copyId: copyId
* key: 文件名
* } params
*/
@ -379,7 +330,7 @@ export function downloadProjectLogBackFile(params) {
* @param {
* nodeId: 节点 ID
* id: 项目 ID
* copyId: copyId
* name: 文件名
* } params
*/
@ -396,7 +347,7 @@ export function deleteProjectLogBackFile(params) {
* @param {
* nodeId: 节点 ID
* tag: 项目 ID
* copyId: copyId
* } params
*/
export function getInternalData(params) {
@ -428,7 +379,6 @@ export function getInternalData(params) {
// * @param {
// * nodeId: 节点 ID
// * tag: 项目 ID
// * copyId: copyId
// * } params
// */
// export function exportStack(params) {
@ -446,7 +396,6 @@ export function getInternalData(params) {
// * @param {
// * nodeId: 节点 ID
// * tag: 项目 ID
// * copyId: copyId
// * } params
// */
// export function exportRam(params) {
@ -459,21 +408,6 @@ export function getInternalData(params) {
// });
// }
/**
* 加载副本集
* @param {
* nodeId: 节点 ID
* id: 项目 ID
* } params
*/
export function getProjectReplicaList(params) {
return axios({
url: "/node/manage/project_copy_list",
method: "post",
data: params,
});
}
// /**
// * 查询节点目录是否存在
// * @param {
@ -497,7 +431,6 @@ export function getProjectReplicaList(params) {
* @param {
* nodeId: 节点 ID,
* id: 项目id
* copyId: 副本id
* } params
*/
export function restartProject(params) {
@ -517,7 +450,6 @@ export function restartProject(params) {
* @param {
* nodeId: 节点 ID,
* id: 项目id
* copyId: 副本id
* } params
*/
export function startProject(params) {
@ -537,7 +469,6 @@ export function startProject(params) {
* @param {
* nodeId: 节点 ID,
* id: 项目id
* copyId: 副本id
* } params
*/
export function stopProject(params) {

View File

@ -534,7 +534,7 @@
<template slot="title">
<ul>
<li>项目启动,停止,重启都将请求对应的地址</li>
<li>传入参数有projectIdprojectNametypecopyIdresult</li>
<li>传入参数有projectIdprojectNametyperesult</li>
<li>type 的值有stopbeforeStopstartbeforeRestart</li>
</ul>
</template>
@ -543,54 +543,6 @@
</template>
<a-input v-model="temp[`${nodeId}_token`]" placeholder="项目启动,停止,重启都将请求对应的地址,非必填GET请求" />
</a-form-model-item>
<div v-if="javaModes.includes(temp.runMode)">
<a-form-model-item>
<template slot="label">
副本
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title">
<ul>
<li>副本是指同一个项目在一个节点服务器中运行多份</li>
</ul>
</template>
<a-icon type="question-circle" theme="filled" />
</a-tooltip>
</template>
<!-- 副本信息 -->
<a-collapse v-if="temp[`${nodeId}_javaCopyItemList`] && temp[`${nodeId}_javaCopyItemList`].length">
<a-collapse-panel v-for="replica in temp[`${nodeId}_javaCopyItemList`]" :key="replica.id">
<template #header>
<a-row>
<a-col :span="18"> 副本 {{ replica.name }} {{ replica.id }} </a-col>
<a-col :span="4">
<a-tooltip placement="topLeft" title="已经添加成功的副本需要在副本管理页面去删除">
<a-button size="small" :disabled="!replica.deleteAble" type="danger" @click.stop="handleDeleteReplica(nodeId, replica)">删除</a-button>
</a-tooltip>
</a-col>
</a-row>
</template>
<a-form-model-item :label="`名称`" prop="replicaName">
<a-input v-model="replica.name" class="replica-area" placeholder="副本名称" />
</a-form-model-item>
<a-form-model-item :label="`JVM 参数`" prop="jvm">
<a-textarea v-model="replica.jvm" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m" />
</a-form-model-item>
<a-form-model-item :label="`args 参数`" prop="args">
<a-textarea v-model="replica.args" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" />
</a-form-model-item>
<!-- <a-tooltip placement="topLeft" title="已经添加成功的副本需要在副本管理页面去删除" class="replica-btn-del">
<a-button :disabled="!replica.deleteAble" type="danger" @click="handleDeleteReplica(nodeId, replica)">删除</a-button>
</a-tooltip> -->
</a-collapse-panel>
</a-collapse>
<!-- 添加副本 -->
<a-form-model-item>
<a-button type="primary" @click="handleAddReplica(nodeId)">添加副本</a-button>
</a-form-model-item>
</a-form-model-item>
</div>
</a-collapse-panel>
</a-collapse>
<a-form-model-item prop="webhook">
@ -1082,10 +1034,7 @@ export default {
intervalTime: undefined,
clearOld: false,
};
// javaCopyItemList
this.nodeList.forEach((node) => {
this.temp[`${node.id}_javaCopyItemList`] = [];
});
this.loadAccesList();
this.loadGroupList();
@ -1145,8 +1094,7 @@ export default {
this.temp[`${ele.nodeId}_args`] = res.data.args || "";
this.temp[`${ele.nodeId}_autoStart`] = res.data.autoStart;
this.temp[`${ele.nodeId}_dslEnv`] = res.data.dslEnv || "";
// javaCopyItemList
this.temp[`${ele.nodeId}_javaCopyItemList`] = res.data.javaCopyItemList || [];
this.temp = { ...this.temp };
}
});
@ -1158,25 +1106,7 @@ export default {
this.editDispatchVisible = true;
});
},
//
handleAddReplica(nodeId) {
let repliccaId = randomStr();
this.temp[`${nodeId}_javaCopyItemList`].push({
id: repliccaId,
jvm: "",
args: "",
name: "",
deleteAble: true,
});
this.temp = { ...this.temp };
},
//
handleDeleteReplica(nodeId, reeplica) {
const index = this.temp[`${nodeId}_javaCopyItemList`].findIndex((element) => element.id === reeplica.id);
const newList = this.temp[`${nodeId}_javaCopyItemList`].slice();
newList.splice(index, 1);
this.temp[`${nodeId}_javaCopyItemList`] = newList;
},
//
handleEditDispatchOk() {
//
@ -1194,28 +1124,7 @@ export default {
}
// reqId
// this.temp.reqId = this.reqId;
this.nodeList.forEach((item) => {
//console.log(item);
//delete this.temp[`add_${item.id}`];
delete tempData[`${item.id}}_javaCopyIds`];
});
//
tempData.nodeIdList.forEach((key) => {
// this.temp[`add_${key}`] = key;
//
tempData[`${key}_javaCopyIds`] = "";
const copyIds = [];
tempData[`${key}_javaCopyItemList`]?.forEach((element) => {
//this.temp[`${key}_javaCopyIds`] += `${element.id},`;
copyIds.push(element.id);
tempData[`${key}_jvm_${element.id}`] = element.jvm;
tempData[`${key}_args_${element.id}`] = element.args;
tempData[`${key}_name_${element.id}`] = element.name;
});
// ,
tempData[`${key}_javaCopyIds`] = copyIds.join(",");
// this.temp[`${key}_javaCopyIds`].substring(0, this.temp[`${key}_javaCopyIds`].length - 1);
});
tempData.nodeIds = tempData.nodeIdList.join(",");
delete tempData.nodeIdList;
//

View File

@ -198,7 +198,7 @@ export default {
const itemProjectData = this.nodeProjectList[item.nodeId].projects.filter((projectData) => {
return item.projectId === projectData.projectId;
})[0];
const socketUrl = getWebSocketUrl("/socket/console", `userId=${this.getLongTermToken}&id=${itemProjectData.id}&nodeId=${item.nodeId}&type=console&copyId=&workspaceId=${this.getWorkspaceId}`);
const socketUrl = getWebSocketUrl("/socket/console", `userId=${this.getLongTermToken}&id=${itemProjectData.id}&nodeId=${item.nodeId}&type=console&workspaceId=${this.getWorkspaceId}`);
const domId = `pre-dom-${item.nodeId},${item.projectId}`;
this.socketCache = { ...this.socketCache, [domId]: {} };
const socket = this.initWebSocket(domId, socketUrl);

View File

@ -28,8 +28,6 @@
<welcome v-if="currentId === 'welcome'" :node="node" />
<project-list v-if="currentId === 'manageList'" :node="node" />
<recover v-if="currentId === 'projectRecover'" :node="node" />
<script-template v-if="currentId === 'script'" :node="node" />
<script-log v-if="currentId === 'script-log'" :nodeId="node.id" />
<nginx-list v-if="currentId === 'nginxList'" :node="node" />
@ -48,8 +46,6 @@ import { getNodeMenu } from "@/api/menu";
import Welcome from "@/pages/node/node-layout/welcome";
import ProjectList from "@/pages/node/node-layout/project/project-list";
import Recover from "@/pages/node/node-layout/project/recover-list";
import ScriptTemplate from "@/pages/node/node-layout/other/script-list";
import ScriptLog from "@/pages/node/node-layout/other/script-log";
import NginxList from "@/pages/node/node-layout/nginx/list";
@ -65,7 +61,6 @@ export default {
components: {
Welcome,
ProjectList,
Recover,
ScriptTemplate,
NginxList,

View File

@ -1,18 +1,5 @@
<template>
<div>
<!-- <div ref="filter" class="filter"> -->
<!-- <template v-if="copyId">
<a-space>
<a-button :disabled="replicaStatus" :loading="optButtonLoading" type="primary" @click="start">启动</a-button>
<a-button :disabled="!replicaStatus" :loading="optButtonLoading" type="danger" @click="restart">重启</a-button>
<a-button :disabled="!replicaStatus" :loading="optButtonLoading" type="danger" @click="stop">停止</a-button>
<a-button type="primary" @click="handleDownload">导出日志</a-button>
<a-tag color="#87d068">文件大小: {{ project.logSize }}</a-tag>
<a-switch checked-children="自动滚动" un-checked-children="关闭滚动" v-model="logScroll" />
</a-space>
</template> -->
<!-- <template> </template> -->
<!-- </div> -->
<!-- console -->
<log-view :ref="`logView`" height="calc(100vh - 140px)">
<template slot="before">
@ -21,7 +8,7 @@
<a-button size="small" :disabled="!project.status" :loading="optButtonLoading" type="danger" @click="restart">重启</a-button>
<a-button size="small" :disabled="!project.status" :loading="optButtonLoading" type="danger" @click="stop">停止</a-button>
<a-button size="small" v-if="!copyId" type="primary" @click="goFile">文件管理</a-button>
<a-button size="small" type="primary" @click="goFile">文件管理</a-button>
<a-dropdown>
<!-- <a type="link" class="ant-dropdown-link"> 更多<a-icon type="down" /> </a> -->
@ -54,7 +41,7 @@
</log-view>
<!-- 日志备份 -->
<a-modal destroyOnClose v-model="lobbackVisible" title="日志备份列表" width="850px" :footer="null" :maskClosable="false">
<ProjectLog v-if="lobbackVisible" :nodeId="this.nodeId" :copyId="this.copyId" :projectId="this.projectId"></ProjectLog>
<ProjectLog v-if="lobbackVisible" :nodeId="this.nodeId" :projectId="this.projectId"></ProjectLog>
</a-modal>
</div>
</template>
@ -80,9 +67,6 @@ export default {
id: {
type: String,
},
copyId: {
type: String,
},
},
data() {
return {
@ -99,7 +83,7 @@ export default {
computed: {
...mapGetters(["getLongTermToken", "getWorkspaceId"]),
socketUrl() {
return getWebSocketUrl("/socket/console", `userId=${this.getLongTermToken}&id=${this.id}&nodeId=${this.nodeId}&type=console&copyId=${this.copyId || ""}&workspaceId=${this.getWorkspaceId}`);
return getWebSocketUrl("/socket/console", `userId=${this.getLongTermToken}&id=${this.id}&nodeId=${this.nodeId}&type=console&workspaceId=${this.getWorkspaceId}`);
},
},
mounted() {
@ -128,22 +112,7 @@ export default {
getProjectData(params).then((res) => {
if (res.code === 200) {
this.project = { ...this.project, ...res.data };
if (this.copyId) {
if (this.project.javaCopyItemList) {
const finds = this.project.javaCopyItemList.filter((item) => item.id === this.copyId);
if (finds.length) {
this.project = { ...this.project, log: finds[0].log, logBack: finds[0].logBack };
} else {
this.$notification.error({
message: "没有找到副本",
});
}
} else {
this.$notification.error({
message: "没有副本",
});
}
}
//
this.loadFileSize();
}
@ -211,7 +180,6 @@ export default {
const data = {
op: op,
projectId: this.projectId,
copyId: this.copyId,
};
this.socket.send(JSON.stringify(data));
if (op === "stop" || op === "start" || op === "restart") {
@ -224,7 +192,6 @@ export default {
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
};
getProjectLogSize(params).then((res) => {
if (res.code === 200) {

View File

@ -153,49 +153,7 @@
<a-form-model-item label="args 参数" prop="args" v-show="javaModes.includes(temp.runMode)">
<a-textarea v-model="temp.args" :auto-size="{ minRows: 3, maxRows: 3 }" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" />
</a-form-model-item>
<div v-if="javaModes.includes(temp.runMode)">
<!-- 副本信息 -->
<!-- <a-row> </a-row> -->
<a-form-model-item>
<template slot="label">
副本
<a-tooltip v-show="temp.type !== 'edit'">
<template slot="title"> 副本是指同一个项目在一个节点服务器中运行多份 </template>
<a-icon type="question-circle" theme="filled" />
</a-tooltip>
</template>
<a-collapse v-if="temp.javaCopyItemList && temp.javaCopyItemList.length">
<a-collapse-panel v-for="replica in temp.javaCopyItemList" :key="replica.id">
<template #header>
<a-row>
<a-col :span="4"> 副本 {{ replica.id }} </a-col>
<a-col :span="10">
<a-tooltip placement="topLeft" title="已经添加成功的副本需要在副本管理页面去删除">
<a-button size="small" :disabled="!replica.deleteAble" type="danger" @click="handleDeleteReplica(replica)">删除</a-button>
</a-tooltip>
</a-col>
</a-row>
</template>
<a-form-model-item :label="`名称`" prop="replicaName">
<a-input v-model="replica.name" class="replica-area" placeholder="副本名称" />
</a-form-model-item>
<a-form-model-item :label="`JVM 参数`" prop="jvm">
<a-textarea v-model="replica.jvm" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="jvm参数,非必填.如:-Xms512m -Xmx512m" />
</a-form-model-item>
<a-form-model-item :label="`args 参数`" prop="args">
<a-textarea v-model="replica.args" :auto-size="{ minRows: 3, maxRows: 3 }" class="replica-area" placeholder="Main 函数 args 参数,非必填. 如:--server.port=8080" />
</a-form-model-item>
<!-- <a-form-model-item> -->
<!-- </a-form-model-item> -->
</a-collapse-panel>
</a-collapse>
<!-- 添加副本 -->
<a-form-model-item>
<a-button size="small" type="primary" @click="handleAddReplica">添加副本</a-button>
</a-form-model-item>
</a-form-model-item>
</div>
<a-form-model-item prop="autoStart" v-show="noFileModes.includes(temp.runMode)">
<template slot="label">
自启动
@ -216,7 +174,7 @@
<template slot="title">
<ul>
<li>项目启动,停止,重启都将请求对应的地址</li>
<li>传入参数有projectIdprojectNametypecopyIdresult</li>
<li>传入参数有projectIdprojectNametyperesult</li>
<li>type 的值有stopbeforeStopstartbeforeRestartfileChange</li>
</ul>
</template>
@ -260,6 +218,7 @@ export default {
type: String,
default: "",
},
data: { type: Object, default: null },
},
components: {
CustomSelect,
@ -296,6 +255,7 @@ export default {
this.loadAccesList();
this.loadGroupList();
this.$refs["editProjectForm"]?.resetFields();
if (this.projectId) {
//
const params = {
@ -304,17 +264,15 @@ export default {
};
getProjectData(params).then((res) => {
if (res.code === 200) {
if (res.code === 200 && res.data) {
this.temp = {
...res.data,
type: "edit",
};
if (!this.temp.javaCopyItemList) {
this.temp = {
...this.temp,
javaCopyItemList: [],
};
}
}
if (this.data) {
//
this.temp = { ...this.temp, ...this.data, type: "add" };
}
});
} else {
@ -322,7 +280,6 @@ export default {
this.temp = {
type: "add",
logPath: "",
javaCopyItemList: [],
};
this.$nextTick(() => {
@ -367,24 +324,6 @@ export default {
});
},
//
handleAddReplica() {
let repliccaId = randomStr();
this.temp.javaCopyItemList.push({
id: repliccaId,
jvm: "",
args: "",
name: "",
deleteAble: true,
});
},
//
handleDeleteReplica(reeplica) {
const index = this.temp.javaCopyItemList.findIndex((element) => element.id === reeplica.id);
const newList = this.temp.javaCopyItemList.slice();
newList.splice(index, 1);
this.temp.javaCopyItemList = newList;
},
//
handleOk() {
if (this.temp.outGivingProject) {
@ -402,20 +341,9 @@ export default {
...this.temp,
nodeId: this.nodeId,
};
//
const replicaParams = {};
let javaCopyIds = this.temp.javaCopyItemList
.map((element) => {
//javaCopyIds += `${element.id},`;
replicaParams[`jvm_${element.id}`] = element.jvm;
replicaParams[`args_${element.id}`] = element.args;
replicaParams[`name_${element.id}`] = element.name;
return element.id;
})
.join(",");
replicaParams["javaCopyIds"] = javaCopyIds;
editProject(params, replicaParams).then((res) => {
//
delete params.javaCopyItemList;
editProject(params).then((res) => {
if (res.code === 200) {
this.$notification.success({
message: res.msg,

View File

@ -61,7 +61,7 @@ export default {
computed: {
...mapGetters(["getLongTermToken", "getWorkspaceId"]),
socketUrl() {
return getWebSocketUrl("/socket/console", `userId=${this.getLongTermToken}&id=${this.id}&nodeId=${this.nodeId}&type=console&copyId=&workspaceId=${this.getWorkspaceId}`);
return getWebSocketUrl("/socket/console", `userId=${this.getLongTermToken}&id=${this.id}&nodeId=${this.nodeId}&type=console&workspaceId=${this.getWorkspaceId}`);
},
},
mounted() {

View File

@ -3,16 +3,13 @@
<!-- 数据表格 -->
<a-table
:data-source="list"
:expandIconColumnIndex="-1"
:expandIconAsCell="false"
:expandedRowKeys="expandedRowKeys"
size="middle"
:columns="columns"
:pagination="pagination"
@change="
(pagination, filters, sorter) => {
this.listQuery = CHANGE_PAGE(this.listQuery, { pagination, sorter });
this.expandedRowKeys = [];
this.loadData();
}
"
@ -68,17 +65,7 @@
</a-tooltip>
</a-space>
</template>
<template slot="copyIcon" slot-scope="javaCopyItemList, record">
<template v-if="javaCopyItemList">
<div v-if="!expandedRowKeys.includes(record.id)" class="ant-table-row-expand-icon ant-table-row-collapsed" @click="handleExpand(record, true)"></div>
<div v-else class="ant-table-row-expand-icon ant-table-row-expanded" @click="handleExpand(record, false)"></div>
</template>
<template v-else>
<a-tooltip title="当项目存在副本集时此列将可以用于查看副本集功能,其他情况此列没有实际作用">
<a-icon type="minus-circle" />
</a-tooltip>
</template>
</template>
<a-tooltip slot="name" slot-scope="text, record" placement="topLeft" :title="`名称:${text}`" @click="handleEdit(record)">
<a-button type="link" style="padding: 0" size="small"><a-icon v-if="record.outGivingProject" type="apartment" />{{ text }} </a-button>
</a-tooltip>
@ -107,26 +94,6 @@
<span>{{ record.port || "-" }}/{{ (record.pids || [record.pid || "-"]).join(",") }}</span>
</a-tooltip>
<template slot="expandedRowRender" slot-scope="record">
<a-table :columns="copyColumns" :data-source="record.javaCopyItemList" rowKey="id" :pagination="false">
<template slot="id" slot-scope="text">
{{ text }}
<a-icon type="reload" @click="getRuningProjectCopyInfo(record)" />
</template>
<template slot="name" slot-scope="text, record">
{{ text || record.id }}
</template>
<a-switch slot="status" slot-scope="text" :checked="text" disabled checked-children="" un-checked-children="" />
<template slot="operation" slot-scope="text, copyRecord">
<a-space>
<a-button size="small" type="primary" @click="handleConsoleCopy(record, copyRecord)">控制台</a-button>
<a-button size="small" type="primary" @click="handleLogBack(record, copyRecord)">日志</a-button>
<a-button size="small" type="danger" @click="handleDeleteCopy(record, copyRecord, 'thorough')">删除</a-button>
</a-space>
</template>
</a-table>
</template>
<template slot="operation" slot-scope="text, record">
<a-space>
<a-button size="small" type="primary" @click="handleFile(record)">文件</a-button>
@ -197,6 +164,7 @@
loadData();
}
"
:data="temp"
:nodeId="temp.nodeId"
:projectId="temp.id"
/>
@ -215,17 +183,13 @@
</a-drawer>
<!-- 项目控制台组件 -->
<a-drawer destroyOnClose :title="drawerTitle" placement="right" width="85vw" :visible="drawerConsoleVisible" @close="onConsoleClose">
<console v-if="drawerConsoleVisible" :nodeId="node.id" :id="temp.id" :projectId="temp.projectId" :replica="replicaTemp" :copyId="replicaTemp ? replicaTemp.id : ''" @goFile="goFile" />
<console v-if="drawerConsoleVisible" :nodeId="node.id" :id="temp.id" :projectId="temp.projectId" :replica="replicaTemp" @goFile="goFile" />
</a-drawer>
<!-- 项目跟踪文件组件 -->
<a-drawer destroyOnClose :title="drawerTitle" placement="right" width="85vw" :visible="drawerReadFileVisible" @close="onReadFileClose">
<file-read v-if="drawerReadFileVisible" :nodeId="node.id" :readFilePath="temp.readFilePath" :id="temp.id" :projectId="temp.projectId" @goFile="goFile" />
</a-drawer>
<!-- 项目副本集组件 -->
<!-- <a-drawer :title="drawerTitle" placement="right" width="85vw" :visible="drawerReplicaVisible" @close="onReplicaClose">
<replica v-if="drawerReplicaVisible" :node="node" :project="temp" />
</a-drawer> -->
<!-- 批量操作状态 -->
<a-modal destroyOnClose v-model="batchVisible" :title="batchTitle" :footer="null" @cancel="batchClose">
<a-list bordered :data-source="selectedRows">
@ -239,7 +203,7 @@
</a-modal>
<!-- 日志备份 -->
<a-modal destroyOnClose v-model="lobbackVisible" title="日志备份列表" width="850px" :footer="null" :maskClosable="false">
<ProjectLog v-if="lobbackVisible" :nodeId="node.id" :copyId="temp.copyItem && temp.copyItem.id" :projectId="temp.projectId"></ProjectLog>
<ProjectLog v-if="lobbackVisible" :nodeId="node.id" :projectId="temp.projectId"></ProjectLog>
</a-modal>
</div>
</template>
@ -256,7 +220,6 @@ import { CHANGE_PAGE, COMPUTED_PAGINATION, PAGE_DEFAULT_LIST_QUERY, PROJECT_DSL_
import {
deleteProject,
getProjectList,
getRuningProjectCopyInfo,
getRuningProjectInfo,
javaModes,
// nodeJudgeLibExist,
@ -315,19 +278,7 @@ export default {
batchVisible: false,
batchTitle: "",
copyColumns: [
{ title: "编号", dataIndex: "id", width: "80px", ellipsis: true, scopedSlots: { customRender: "id" } },
{ title: "名称", dataIndex: "name", width: 150, ellipsis: true, scopedSlots: { customRender: "name" } },
{ title: "状态", dataIndex: "status", width: 100, ellipsis: true, scopedSlots: { customRender: "status" } },
{ title: "进程 ID", dataIndex: "pid", width: 100, ellipsis: true, scopedSlots: { customRender: "pid" } },
{ title: "端口号", dataIndex: "port", width: 100, ellipsis: true, scopedSlots: { customRender: "port" } },
{ title: "最后修改时间", dataIndex: "modifyTime", width: "180px", ellipsis: true, scopedSlots: { customRender: "modifyTime" } },
{ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, width: "150px" },
],
expandedRowKeys: [],
lobbackVisible: false,
showJavaCopyItemList: false,
};
},
computed: {
@ -364,9 +315,8 @@ export default {
},
{ title: "修改时间", sorter: true, dataIndex: "modifyTimeMillis", width: "170px", ellipsis: true, customRender: (text) => parseTime(text) },
];
this.showJavaCopyItemList && columns.unshift({ title: "", dataIndex: "javaCopyItemList", align: "center", width: "40px", scopedSlots: { customRender: "copyIcon" } });
!(this.expandedRowKeys && this.expandedRowKeys.length) &&
columns.push({ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, fixed: "right", align: "center", width: "180px" });
columns.push({ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, fixed: "right", align: "center", width: "180px" });
return columns;
},
filePath() {
@ -416,22 +366,8 @@ export default {
// //
let tempList = resultList.filter((item) => item.runMode !== "File");
let fileList = resultList.filter((item) => item.runMode === "File");
this.list = tempList.concat(fileList).map((item) => {
// javaCopyItemList
let javaCopyItemList = null;
if (item.javaCopyItemList) {
try {
javaCopyItemList = JSON.parse(item.javaCopyItemList);
javaCopyItemList = javaCopyItemList.length ? javaCopyItemList : null;
} catch (error) {
//
}
}
return { ...item, javaCopyItemList: javaCopyItemList };
});
this.showJavaCopyItemList = !!this.list.find((item) => {
return !!item.javaCopyItemList;
});
this.list = tempList.concat(fileList);
// // ID
// this.list = this.list.map((element) => {
// //element.dataId = element.id;
@ -473,7 +409,6 @@ export default {
}
});
//
this.expandedRowKeys = [];
}
this.loadGroupList();
}
@ -495,9 +430,8 @@ export default {
delete temp.id;
delete temp.createTimeMillis;
delete temp.outGivingProject;
this.temp = { ...temp, name: temp.name + "副本", id: temp.projectId + "_copy", javaCopyItemList: [], lib: temp.lib + "_copy" };
this.temp = { ...temp, name: temp.name + "副本", id: temp.projectId + "_copy", lib: temp.lib + "_copy" };
this.loadAccesList();
this.editProjectVisible = true;
},
//
@ -529,31 +463,13 @@ export default {
this.drawerConsoleVisible = true;
this.replicaTemp = null;
},
//
handleConsoleCopy(record, copyItem) {
this.checkRecord = record;
this.temp = Object.assign({}, record);
this.drawerTitle = `控制台(${this.temp.name})-${copyItem.id}`;
this.drawerConsoleVisible = true;
this.replicaTemp = copyItem;
// console.log(record, copyItem);
},
//
onConsoleClose() {
this.drawerConsoleVisible = false;
this.loadData();
},
// //
// handleReplica(record) {
// this.temp = Object.assign({}, record);
// this.drawerTitle = `(${this.temp.name})`;
// this.drawerReplicaVisible = true;
// },
//
// onReplicaClose() {
// this.drawerReplicaVisible = false;
// },
//
handleDelete(record, thorough) {
this.$confirm({
@ -787,57 +703,6 @@ export default {
}
},
//
handleExpand(item, status) {
//javaCopyItemList
if (status) {
this.expandedRowKeys.push(item.id);
this.getRuningProjectCopyInfo(item);
} else {
this.expandedRowKeys = this.expandedRowKeys.filter((item2) => item2 !== item.id);
}
},
//
getRuningProjectCopyInfo(project) {
const ids = project.javaCopyItemList.map((item) => item.id);
const tempParams = {
nodeId: this.node.id,
id: project.projectId,
copyIds: JSON.stringify(ids),
};
getRuningProjectCopyInfo(tempParams).then((res) => {
if (res.code === 200) {
this.list = this.list.map((item) => {
let javaCopyItemList = item.javaCopyItemList;
if (javaCopyItemList && item.projectId === project.projectId) {
javaCopyItemList = javaCopyItemList.map((copyItem) => {
if (res.data[copyItem.id]) {
// element.port = res.data[element.id].port;
// element.pid = res.data[element.id].pid;
// element.status = true;
return {
...copyItem,
status: res.data[copyItem.id].pid > 0,
pid: res.data[copyItem.id].pid,
pids: res.data[copyItem.id].pids,
port: res.data[copyItem.id].port,
error: res.data[copyItem.id].error,
};
}
return copyItem;
});
}
return { ...item, javaCopyItemList: javaCopyItemList };
});
this.list = this.list.map((element) => {
return element;
});
}
});
},
//
handleDeleteCopy(project, record, thorough) {
this.$confirm({
@ -850,7 +715,7 @@ export default {
const params = {
nodeId: this.node.id,
id: project.projectId,
copyId: record.id,
thorough: thorough,
};
deleteProject(params).then((res) => {
@ -859,16 +724,7 @@ export default {
message: res.msg,
});
this.list = this.list.map((item) => {
let javaCopyItemList = item.javaCopyItemList;
if (javaCopyItemList) {
javaCopyItemList = javaCopyItemList.filter((item2) => {
return item2.id !== record.id;
});
}
return { ...item, javaCopyItemList: javaCopyItemList };
});
// this.loadData();
this.loadData();
}
});
},
@ -935,8 +791,8 @@ export default {
});
},
//
handleLogBack(record, copyItem) {
this.temp = Object.assign({}, record, { copyItem: copyItem });
handleLogBack(record) {
this.temp = Object.assign({}, record);
this.lobbackVisible = true;
},
},

View File

@ -42,9 +42,6 @@ export default {
projectId: {
type: String,
},
copyId: {
type: String,
},
},
data() {
return {
@ -69,7 +66,6 @@ export default {
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
};
getProjectLogSize(params).then((res) => {
if (res.code === 200) {
@ -82,7 +78,6 @@ export default {
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
};
getLogBackList(params).then((res) => {
if (res.code === 200) {
@ -101,7 +96,6 @@ export default {
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
};
// blob
window.open(downloadProjectLogFile(params), "_blank");
@ -115,7 +109,7 @@ export default {
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
key: record.filename,
};
// blob
@ -133,7 +127,7 @@ export default {
const params = {
nodeId: this.nodeId,
id: this.projectId,
copyId: this.copyId,
name: record.filename,
};
//

View File

@ -1,147 +0,0 @@
<template>
<div class="node-full-content">
<!-- <div ref="filter" class="filter"></div> -->
<!-- 表格 -->
<a-table :data-source="list" :loading="loading" :columns="columns" :pagination="false" bordered :rowKey="(record, index) => index">
<template #title>
<a-button type="primary" @click="handleFilter">刷新</a-button>
</template>
<a-switch slot="status" slot-scope="text" :checked="text" disabled checked-children="" un-checked-children="" />
<template slot="operation" slot-scope="text, record">
<a-space>
<a-button type="primary" @click="handleConsole(record)">控制台</a-button>
<a-button type="danger" @click="handleDelete(record)">删除</a-button>
</a-space>
</template>
</a-table>
<!-- 项目控制台组件 -->
<a-drawer destroyOnClose :title="drawerTitle" placement="right" width="85vw" :visible="drawerConsoleVisible" @close="onConsoleClose">
<console v-if="drawerConsoleVisible" :nodeId="node.id" :id="project.id" :projectId="project.projectId" :replica="temp" :copyId="temp.id" />
</a-drawer>
</div>
</template>
<script>
import Console from "./project-console";
import { getProjectReplicaList, deleteProject, getRuningProjectCopyInfo } from "@/api/node-project";
export default {
props: {
node: {
type: Object,
},
project: {
type: Object,
},
},
components: {
Console,
},
data() {
return {
loading: false,
list: [],
temp: {},
drawerTitle: "",
drawerConsoleVisible: false,
columns: [
{ title: "副本编号", dataIndex: "id", width: 150, ellipsis: true, scopedSlots: { customRender: "id" } },
{ title: "状态", dataIndex: "status", width: 100, ellipsis: true, scopedSlots: { customRender: "status" } },
{ title: "进程 ID", dataIndex: "pid", width: 100, ellipsis: true, scopedSlots: { customRender: "pid" } },
{ title: "端口号", dataIndex: "port", width: 100, ellipsis: true, scopedSlots: { customRender: "port" } },
{ title: "最后修改时间", dataIndex: "modifyTime", width: 180, ellipsis: true, scopedSlots: { customRender: "modifyTime" } },
{ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, width: 220 },
],
};
},
mounted() {
this.handleFilter();
},
methods: {
//
loadData() {
this.loading = true;
this.list = [];
const params = {
nodeId: this.node.id,
id: this.project.projectId,
};
getProjectReplicaList(params).then((res) => {
if (res.code === 200) {
this.list = res.data;
this.getRuningProjectCopyInfo();
}
this.loading = false;
});
},
getRuningProjectCopyInfo() {
const ids = this.list.map((item) => item.id);
const tempParams = {
nodeId: this.node.id,
id: this.project.projectId,
copyIds: JSON.stringify(ids),
};
getRuningProjectCopyInfo(tempParams).then((res) => {
if (res.code === 200) {
this.list = this.list.map((element) => {
if (res.data[element.id]) {
element.port = res.data[element.id].port;
element.pid = res.data[element.id].pid;
element.status = true;
}
return element;
});
}
});
},
//
handleFilter() {
this.loadData();
},
//
handleConsole(record) {
this.temp = Object.assign({}, record);
this.drawerTitle = `控制台(${this.temp.tagId})`;
this.drawerConsoleVisible = true;
},
//
onConsoleClose() {
this.drawerConsoleVisible = false;
this.handleFilter();
},
//
handleDelete(record) {
this.$confirm({
title: "系统提示",
content: "真的要删除副本项目么?",
okText: "确认",
cancelText: "取消",
onOk: () => {
//
const params = {
nodeId: this.node.id,
id: this.project.projectId,
copyId: record.id,
};
deleteProject(params).then((res) => {
if (res.code === 200) {
this.$notification.success({
message: res.msg,
});
this.loadData();
}
});
},
});
},
},
};
</script>
<style scoped>
/* .filter {
margin: 0 0 10px;
} */
</style>

View File

@ -77,7 +77,7 @@ export function editDispatch(params: any) {
* xxx_token: xxx webhook
* xxx_jvm: jvm
* xxx_args: args
* xxx_javaCopyIds: xxx ID xxx_jvm_${ID} | xxx_args_${ID}
*
* } params
*/
export function editDispatchProject(params: any) {