mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-02 11:58:01 +08:00
fix 构建发布项目文件采用分片上传、并且支持进度显示
This commit is contained in:
parent
c00f344874
commit
a78274d924
@ -20,6 +20,8 @@
|
||||
9. 【server】优化 分发单项的状态信息存储于日志记录中(取消 json 字段存储)
|
||||
10. 【server】优化 节点分发子项展示逻辑(同步改异步加载,避免长时间加载)
|
||||
11. 【server】优化 构建日志输出各个流程耗时
|
||||
12. 【server】优化 构建发布项目文件采用分片上传、并且支持进度显示
|
||||
13. 【agent】优化 配置文件中上传文件大小限制由 1G 改为 10MB 节省插件端占用内存大小(采用分片代替)
|
||||
|
||||
### ⚠️ 注意
|
||||
|
||||
|
@ -74,7 +74,7 @@ public abstract class BaseAgentController extends BaseJpomController {
|
||||
}
|
||||
|
||||
protected String getWorkspaceId() {
|
||||
return ServletUtil.getHeader(getRequest(), Const.WORKSPACEID_REQ_HEADER, CharsetUtil.CHARSET_UTF_8);
|
||||
return ServletUtil.getHeader(getRequest(), Const.WORKSPACE_ID_REQ_HEADER, CharsetUtil.CHARSET_UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,7 +37,9 @@ import io.jpom.system.AgentConfig;
|
||||
import io.jpom.util.SocketSessionUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.MultipartProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
import javax.websocket.*;
|
||||
import javax.websocket.server.ServerEndpoint;
|
||||
@ -58,10 +60,12 @@ public class AgentWebSocketUpdateHandle extends BaseAgentWebSocketHandle {
|
||||
private static final Map<String, UploadFileModel> UPLOAD_FILE_INFO = new HashMap<>();
|
||||
|
||||
private static AgentConfig agentConfig;
|
||||
private static MultipartProperties multipartProperties;
|
||||
|
||||
@Autowired
|
||||
public void init(AgentConfig agentConfig) {
|
||||
public void init(AgentConfig agentConfig, MultipartProperties multipartProperties) {
|
||||
AgentWebSocketUpdateHandle.agentConfig = agentConfig;
|
||||
AgentWebSocketUpdateHandle.multipartProperties = multipartProperties;
|
||||
}
|
||||
|
||||
@OnOpen
|
||||
@ -69,7 +73,8 @@ public class AgentWebSocketUpdateHandle extends BaseAgentWebSocketHandle {
|
||||
if (super.checkAuthorize(session)) {
|
||||
return;
|
||||
}
|
||||
session.setMaxBinaryMessageBufferSize(Const.DEFAULT_BUFFER_SIZE);
|
||||
DataSize maxRequestSize = multipartProperties.getMaxRequestSize();
|
||||
session.setMaxBinaryMessageBufferSize((int) maxRequestSize.toBytes());
|
||||
//
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,8 @@ spring:
|
||||
name: JPOMID-AGENT
|
||||
multipart:
|
||||
# 上传文件大小限制 12KB -- parses as 12 kilobytes 5MB -- parses as 5 megabytes 20 -- parses as 20 kilobytes
|
||||
max-request-size: 2GB
|
||||
max-file-size: 1GB
|
||||
max-request-size: 50MB
|
||||
max-file-size: 10MB
|
||||
mvc:
|
||||
throw-exception-if-no-handler-found: true
|
||||
log-request-details: true
|
||||
|
@ -64,8 +64,8 @@ spring:
|
||||
name: JPOMID-AGENT
|
||||
multipart:
|
||||
# 上传文件大小限制 12KB -- parses as 12 kilobytes 5MB -- parses as 5 megabytes 20 -- parses as 20 kilobytes
|
||||
max-request-size: 2GB
|
||||
max-file-size: 1GB
|
||||
max-request-size: 50MB
|
||||
max-file-size: 10MB
|
||||
mvc:
|
||||
throw-exception-if-no-handler-found: true
|
||||
log-request-details: true
|
||||
|
@ -31,6 +31,7 @@ import cn.hutool.extra.servlet.ServletUtil;
|
||||
import io.jpom.common.multipart.MultipartFileBuilder;
|
||||
import io.jpom.util.FileUtils;
|
||||
import lombok.Lombok;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
@ -48,7 +49,9 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* controller
|
||||
@ -56,6 +59,7 @@ import java.util.*;
|
||||
* @author jiangzeyin
|
||||
* @since 2019/4/16
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseJpomController {
|
||||
/**
|
||||
* 路径安全格式化
|
||||
@ -173,7 +177,10 @@ public abstract class BaseJpomController {
|
||||
FileUtil.del(sliceItemPath);
|
||||
// 对比文件信息
|
||||
String newSha1 = SecureUtil.sha1(successFile);
|
||||
Assert.state(StrUtil.equals(newSha1, fileSumSha1), "文件合并后异常,文件不完成可能被损坏");
|
||||
Assert.state(StrUtil.equals(newSha1, fileSumSha1), () -> {
|
||||
log.warn("文件合并异常 {}:{} -> {}", FileUtil.getAbsolutePath(successFile), newSha1, fileSumSha1);
|
||||
return "文件合并后异常,文件不完成可能被损坏";
|
||||
});
|
||||
return successFile;
|
||||
}
|
||||
|
||||
@ -311,25 +318,6 @@ public abstract class BaseJpomController {
|
||||
return ServletUtil.getClientIP(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取header
|
||||
*
|
||||
* @param request req
|
||||
* @return map
|
||||
* @author jiangzeyin
|
||||
*/
|
||||
public static Map<String, String> getHeaderMapValues(HttpServletRequest request) {
|
||||
Enumeration<String> enumeration = request.getHeaderNames();
|
||||
Map<String, String> headerMapValues = new HashMap<>(20);
|
||||
if (enumeration != null) {
|
||||
for (; enumeration.hasMoreElements(); ) {
|
||||
String name = enumeration.nextElement();
|
||||
headerMapValues.put(name, request.getHeader(name));
|
||||
}
|
||||
}
|
||||
return headerMapValues;
|
||||
}
|
||||
|
||||
public HttpServletRequest getRequest() {
|
||||
HttpServletRequest request = getRequestAttributes().getRequest();
|
||||
Objects.requireNonNull(request, "request null");
|
||||
@ -362,14 +350,6 @@ public abstract class BaseJpomController {
|
||||
return getRequest().getServletContext();
|
||||
}
|
||||
|
||||
public Object getAttribute(String name) {
|
||||
return getRequestAttributes().getAttribute(name, RequestAttributes.SCOPE_REQUEST);
|
||||
}
|
||||
|
||||
public void setAttribute(String name, Object object) {
|
||||
getRequestAttributes().setAttribute(name, object, RequestAttributes.SCOPE_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取session 字符串
|
||||
*
|
||||
|
@ -35,15 +35,15 @@ public class Const {
|
||||
/**
|
||||
* 请求 header
|
||||
*/
|
||||
public static final String WORKSPACEID_REQ_HEADER = "workspaceId";
|
||||
public static final String WORKSPACE_ID_REQ_HEADER = "workspaceId";
|
||||
/**
|
||||
* 默认的工作空间
|
||||
*/
|
||||
public static final String WORKSPACE_DEFAULT_ID = "DEFAULT";
|
||||
/**
|
||||
* websocket 传输 agent 包 buffer size
|
||||
*/
|
||||
public static final int DEFAULT_BUFFER_SIZE = 1024 * 1024;
|
||||
// /**
|
||||
// * websocket 传输 agent 包 buffer size
|
||||
// */
|
||||
// public static final int DEFAULT_BUFFER_SIZE = 1024 * 1024;
|
||||
/**
|
||||
* id 最大长度
|
||||
*/
|
||||
|
@ -45,7 +45,7 @@ public interface IWorkspaceEnvPlugin extends IDefaultPlugin {
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
default String convertRefEnvValue(Map<String, Object> parameter, String key) throws Exception {
|
||||
String workspaceId = (String) parameter.get(Const.WORKSPACEID_REQ_HEADER);
|
||||
String workspaceId = (String) parameter.get(Const.WORKSPACE_ID_REQ_HEADER);
|
||||
return this.convertRefEnvValue(workspaceId, (String) parameter.get(key));
|
||||
}
|
||||
|
||||
|
@ -24,14 +24,13 @@ package io.jpom.build;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.BetweenFormatter;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.SystemClock;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.lang.Opt;
|
||||
import cn.hutool.core.text.CharPool;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
@ -171,7 +170,6 @@ public class ReleaseManage implements Runnable {
|
||||
logRecorder.info("不存在构建产物");
|
||||
return false;
|
||||
}
|
||||
long time = SystemClock.now();
|
||||
int releaseMethod = this.buildExtraModule.getReleaseMethod();
|
||||
logRecorder.info("release method:" + BaseEnum.getDescByCode(BuildReleaseMethod.class, releaseMethod));
|
||||
|
||||
@ -192,8 +190,7 @@ public class ReleaseManage implements Runnable {
|
||||
logRecorder.info(" 没有实现的发布分发:" + releaseMethod);
|
||||
return false;
|
||||
}
|
||||
logRecorder.info("release complete : " + DateUtil.formatBetween(SystemClock.now() - time, BetweenFormatter.Level.MILLISECOND));
|
||||
|
||||
//logRecorder.info("release complete : " + DateUtil.formatBetween(SystemClock.now() - time, BetweenFormatter.Level.MILLISECOND));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -517,7 +514,12 @@ public class ReleaseManage implements Runnable {
|
||||
//
|
||||
JsonMessage<String> jsonMessage = OutGivingRun.fileUpload(file, startPath,
|
||||
projectId, false, last ? afterOpt : AfterOpt.No, nodeModel, false,
|
||||
this.buildExtraModule.getProjectUploadCloseFirst());
|
||||
this.buildExtraModule.getProjectUploadCloseFirst(), (total, progressSize) -> {
|
||||
// total, progressSize
|
||||
logRecorder.info("[SYSTEM-INFO] 上传文件进度:{} {}/{} {}", file.getName(),
|
||||
FileUtil.readableFileSize(progressSize), FileUtil.readableFileSize(total),
|
||||
NumberUtil.formatPercent(((float) progressSize / total), 0));
|
||||
});
|
||||
Assert.state(jsonMessage.success(), "同步项目文件失败:" + jsonMessage);
|
||||
if (last) {
|
||||
// 最后一个
|
||||
@ -553,12 +555,17 @@ public class ReleaseManage implements Runnable {
|
||||
zipFile = this.resultFile;
|
||||
unZip = false;
|
||||
}
|
||||
String name = zipFile.getName();
|
||||
JsonMessage<String> jsonMessage = OutGivingRun.fileUpload(zipFile,
|
||||
this.buildExtraModule.getProjectSecondaryDirectory(),
|
||||
projectId,
|
||||
unZip,
|
||||
afterOpt,
|
||||
nodeModel, clearOld, this.buildExtraModule.getProjectUploadCloseFirst());
|
||||
nodeModel, clearOld, this.buildExtraModule.getProjectUploadCloseFirst(), (total, progressSize) -> {
|
||||
logRecorder.info("[SYSTEM-INFO] 上传文件进度:{} {}/{} {}", name,
|
||||
FileUtil.readableFileSize(progressSize), FileUtil.readableFileSize(total),
|
||||
NumberUtil.formatPercent(((float) progressSize / total), 0));
|
||||
});
|
||||
if (jsonMessage.success()) {
|
||||
logRecorder.info("发布项目包成功:" + jsonMessage);
|
||||
} else {
|
||||
|
@ -65,6 +65,7 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
@ -195,7 +196,7 @@ public class NodeForward {
|
||||
long chunkSize = DataSize.ofMegabytes(fileSliceSize).toBytes();
|
||||
int total = (int) Math.ceil((double) length / chunkSize);
|
||||
Queue<Integer> queueList = new ConcurrentLinkedDeque<>();
|
||||
for (int i = 1; i <= total; i++) {
|
||||
for (int i = 0; i < total; i++) {
|
||||
queueList.offer(i);
|
||||
}
|
||||
List<Integer> success = Collections.synchronizedList(new ArrayList<>(total));
|
||||
@ -204,18 +205,16 @@ public class NodeForward {
|
||||
int concurrent = 2;
|
||||
AtomicReference<JsonMessage<T>> failureMessage = new AtomicReference<>();
|
||||
AtomicReference<JsonMessage<T>> succeedMessage = new AtomicReference<>();
|
||||
String sliceId = IdUtil.fastSimpleUUID();
|
||||
|
||||
AtomicLong atomicProgressSize = new AtomicLong(0);
|
||||
JSONObject sliceData = new JSONObject();
|
||||
sliceData.put("sliceId", sliceId);
|
||||
sliceData.put("sliceId", IdUtil.fastSimpleUUID());
|
||||
sliceData.put("totalSlice", total);
|
||||
sliceData.put("fileSumSha1", sha1);
|
||||
TransportServer transportServer = TransportServerFactory.get();
|
||||
|
||||
TypeReference<JsonMessage<T>> typeReference = new TypeReference<JsonMessage<T>>() {
|
||||
};
|
||||
|
||||
try (SyncFinisher syncFinisher = new SyncFinisher(concurrent)) {
|
||||
// 需要计算 并发数和最大任务数,如果任务数小于并发数则使用任务数
|
||||
try (SyncFinisher syncFinisher = new SyncFinisher(Math.min(concurrent, total))) {
|
||||
Runnable runnable = () -> {
|
||||
// 取出任务
|
||||
Integer currentChunk = queueList.poll();
|
||||
@ -223,14 +222,13 @@ public class NodeForward {
|
||||
return;
|
||||
}
|
||||
JSONObject uploadData = jsonObject.clone();
|
||||
long start = currentChunk * chunkSize;
|
||||
|
||||
try {
|
||||
try (FileInputStream inputStream = new FileInputStream(file)) {
|
||||
try (FileChannel inputChannel = inputStream.getChannel()) {
|
||||
//分配缓冲区,设定每次读的字节数
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate((int) chunkSize);
|
||||
inputChannel.position(start);
|
||||
// 移动到指定位置开始读取
|
||||
inputChannel.position(currentChunk * chunkSize);
|
||||
inputChannel.read(byteBuffer);
|
||||
//上面把数据写入到了buffer,所以可知上面的buffer是写模式,调用flip把buffer切换到读模式,读取数据
|
||||
byteBuffer.flip();
|
||||
@ -248,7 +246,9 @@ public class NodeForward {
|
||||
// 使用成功的个数计算
|
||||
success.add(currentChunk);
|
||||
long end = Math.min(length, ((success.size() - 1) * chunkSize) + chunkSize);
|
||||
streamProgress.accept(length, end);
|
||||
// 保存线程安全顺序回调进度信息
|
||||
atomicProgressSize.set(Math.max(end, atomicProgressSize.get()));
|
||||
streamProgress.accept(length, atomicProgressSize.get());
|
||||
succeedMessage.set(message);
|
||||
} else {
|
||||
log.warn("分片上传异常:{} {}", nodeUrl, message);
|
||||
|
@ -219,6 +219,7 @@ public class OutGivingProjectController extends BaseServerController {
|
||||
//
|
||||
boolean unzip = Convert.toBool(autoUnzip, false);
|
||||
File file = FileUtil.file(JpomApplication.getInstance().getDataPath(), ServerConst.OUTGIVING_FILE, id);
|
||||
FileUtil.mkdir(file);
|
||||
//
|
||||
File userTempPath = serverConfig.getUserTempPath();
|
||||
File successFile = this.shardingTryMerge(userTempPath.getAbsolutePath(), sliceId, totalSlice, fileSumSha1);
|
||||
|
@ -35,17 +35,17 @@ import lombok.EqualsAndHashCode;
|
||||
@Data
|
||||
public abstract class BaseWorkspaceModel extends BaseStrikeDbModel {
|
||||
|
||||
/**
|
||||
* 工作空间ID
|
||||
*
|
||||
* @see io.jpom.model.data.WorkspaceModel
|
||||
* @see io.jpom.common.Const#WORKSPACEID_REQ_HEADER
|
||||
*/
|
||||
private String workspaceId;
|
||||
/**
|
||||
* 工作空间ID
|
||||
*
|
||||
* @see io.jpom.model.data.WorkspaceModel
|
||||
* @see io.jpom.common.Const#WORKSPACE_ID_REQ_HEADER
|
||||
*/
|
||||
private String workspaceId;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ public class RepositoryModel extends BaseWorkspaceModel {
|
||||
}
|
||||
map.put("username", this.getUserName());
|
||||
map.put("password", this.getPassword());
|
||||
map.put(Const.WORKSPACEID_REQ_HEADER, this.getWorkspaceId());
|
||||
map.put(Const.WORKSPACE_ID_REQ_HEADER, this.getWorkspaceId());
|
||||
map.put("rsaFile", BuildUtil.getRepositoryRsaFile(this));
|
||||
return map;
|
||||
}
|
||||
|
@ -96,7 +96,9 @@ public class OutGivingItemRun implements Callable<OutGivingNodeProject.Status> {
|
||||
unzip,
|
||||
afterOpt,
|
||||
this.nodeModel, this.clearOld,
|
||||
this.sleepTime, this.closeFirst, this.stripComponents);
|
||||
this.sleepTime, this.closeFirst, this.stripComponents, (total, progressSize) -> {
|
||||
double floor = Math.floor(((float) progressSize / total) * 100);
|
||||
});
|
||||
result = jsonMessage.success() ? OutGivingNodeProject.Status.Ok : OutGivingNodeProject.Status.Fail;
|
||||
|
||||
JSONObject jsonObject = jsonMessage.toJson();
|
||||
|
@ -48,13 +48,16 @@ import io.jpom.model.outgiving.OutGivingNodeProject;
|
||||
import io.jpom.model.user.UserModel;
|
||||
import io.jpom.service.outgiving.DbOutGivingLogService;
|
||||
import io.jpom.service.outgiving.OutGivingServer;
|
||||
import lombok.Lombok;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -317,9 +320,10 @@ public class OutGivingRun {
|
||||
boolean unzip,
|
||||
AfterOpt afterOpt,
|
||||
NodeModel nodeModel,
|
||||
|
||||
boolean clearOld, Boolean closeFirst) {
|
||||
return fileUpload(file, levelName, projectId, unzip, afterOpt, nodeModel, clearOld, null, closeFirst);
|
||||
boolean clearOld,
|
||||
Boolean closeFirst,
|
||||
BiConsumer<Long, Long> streamProgress) {
|
||||
return fileUpload(file, levelName, projectId, unzip, afterOpt, nodeModel, clearOld, null, closeFirst, streamProgress);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -342,8 +346,9 @@ public class OutGivingRun {
|
||||
NodeModel nodeModel,
|
||||
boolean clearOld,
|
||||
Integer sleepTime,
|
||||
Boolean closeFirst) {
|
||||
return fileUpload(file, levelName, projectId, unzip, afterOpt, nodeModel, clearOld, sleepTime, closeFirst, 0);
|
||||
Boolean closeFirst,
|
||||
BiConsumer<Long, Long> streamProgress) {
|
||||
return fileUpload(file, levelName, projectId, unzip, afterOpt, nodeModel, clearOld, sleepTime, closeFirst, 0, streamProgress);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -366,9 +371,10 @@ public class OutGivingRun {
|
||||
NodeModel nodeModel,
|
||||
boolean clearOld,
|
||||
Integer sleepTime,
|
||||
Boolean closeFirst, int stripComponents) {
|
||||
Boolean closeFirst, int stripComponents,
|
||||
BiConsumer<Long, Long> streamProgress) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("file", file);
|
||||
// data.put("file", file);
|
||||
data.put("id", projectId);
|
||||
Opt.ofBlankAble(levelName).ifPresent(s -> data.put("levelName", s));
|
||||
Opt.ofNullable(sleepTime).ifPresent(integer -> data.put("sleepTime", integer));
|
||||
@ -387,6 +393,17 @@ public class OutGivingRun {
|
||||
data.put("after", afterOpt.getCode());
|
||||
}
|
||||
data.put("closeFirst", closeFirst);
|
||||
return NodeForward.request(nodeModel, NodeUrl.Manage_File_Upload, data);
|
||||
try {
|
||||
return NodeForward.requestSharding(nodeModel, NodeUrl.Manage_File_Upload_Sharding, data, file,
|
||||
sliceData -> {
|
||||
sliceData.putAll(data);
|
||||
return NodeForward.request(nodeModel, NodeUrl.Manage_File_Sharding_Merge, sliceData);
|
||||
},
|
||||
streamProgress);
|
||||
} catch (IOException e) {
|
||||
throw Lombok.sneakyThrow(e);
|
||||
}
|
||||
|
||||
//return NodeForward.request(nodeModel, NodeUrl.Manage_File_Upload, data);
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class DefaultWorkspaceEnvPlugin implements IWorkspaceEnvPlugin {
|
||||
@Override
|
||||
public Object execute(Object main, Map<String, Object> parameter) throws Exception {
|
||||
WorkspaceEnvVarService workspaceEnvVarService = SpringUtil.getBean(WorkspaceEnvVarService.class);
|
||||
String workspaceId = (String) parameter.get(Const.WORKSPACEID_REQ_HEADER);
|
||||
String workspaceId = (String) parameter.get(Const.WORKSPACE_ID_REQ_HEADER);
|
||||
String value = (String) parameter.get("value");
|
||||
return workspaceEnvVarService.convertRefEnvValue(workspaceId, value);
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ public class DbUserOperateLogService extends BaseWorkspaceService<UserOperateLog
|
||||
public String getCheckUserWorkspace(HttpServletRequest request) {
|
||||
// 忽略检查
|
||||
return BaseWorkspaceService.getWorkspaceId(request);
|
||||
// String header = ServletUtil.getHeader(request, Const.WORKSPACEID_REQ_HEADER, CharsetUtil.CHARSET_UTF_8);
|
||||
// String header = ServletUtil.getHeader(request, Const.WORKSPACE_ID_REQ_HEADER, CharsetUtil.CHARSET_UTF_8);
|
||||
// return ObjectUtil.defaultIfNull(header, StrUtil.EMPTY);
|
||||
}
|
||||
|
||||
|
@ -196,9 +196,9 @@ public abstract class BaseWorkspaceService<T extends BaseWorkspaceModel> extends
|
||||
}
|
||||
|
||||
public static String getWorkspaceId(HttpServletRequest request) {
|
||||
String workspaceId = request.getParameter(Const.WORKSPACEID_REQ_HEADER);
|
||||
String workspaceId = request.getParameter(Const.WORKSPACE_ID_REQ_HEADER);
|
||||
if (StrUtil.isEmpty(workspaceId)) {
|
||||
workspaceId = ServletUtil.getHeader(request, Const.WORKSPACEID_REQ_HEADER, CharsetUtil.CHARSET_UTF_8);
|
||||
workspaceId = ServletUtil.getHeader(request, Const.WORKSPACE_ID_REQ_HEADER, CharsetUtil.CHARSET_UTF_8);
|
||||
}
|
||||
return StrUtil.emptyToDefault(workspaceId, Const.WORKSPACE_DEFAULT_ID);
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ package io.jpom.socket;
|
||||
import io.jpom.service.node.NodeService;
|
||||
import io.jpom.service.system.SystemParametersServer;
|
||||
import io.jpom.socket.handler.*;
|
||||
import io.jpom.system.ServerConfig;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||
@ -41,13 +42,16 @@ public class ServerWebSocketConfig implements WebSocketConfigurer {
|
||||
private final ServerWebSocketInterceptor serverWebSocketInterceptor;
|
||||
private final SystemParametersServer systemParametersServer;
|
||||
private final NodeService nodeService;
|
||||
private final ServerConfig.NodeConfig nodeConfig;
|
||||
|
||||
public ServerWebSocketConfig(ServerWebSocketInterceptor serverWebSocketInterceptor,
|
||||
SystemParametersServer systemParametersServer,
|
||||
NodeService nodeService) {
|
||||
NodeService nodeService,
|
||||
ServerConfig serverConfig) {
|
||||
this.serverWebSocketInterceptor = serverWebSocketInterceptor;
|
||||
this.systemParametersServer = systemParametersServer;
|
||||
this.nodeService = nodeService;
|
||||
this.nodeConfig = serverConfig.getNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -65,7 +69,7 @@ public class ServerWebSocketConfig implements WebSocketConfigurer {
|
||||
registry.addHandler(new SshHandler(), "/socket/ssh")
|
||||
.addInterceptors(serverWebSocketInterceptor).setAllowedOrigins("*");
|
||||
// 节点升级
|
||||
registry.addHandler(new NodeUpdateHandler(nodeService, systemParametersServer), "/socket/node_update")
|
||||
registry.addHandler(new NodeUpdateHandler(nodeService, systemParametersServer, nodeConfig), "/socket/node_update")
|
||||
.addInterceptors(serverWebSocketInterceptor).setAllowedOrigins("*");
|
||||
// 脚本模板
|
||||
registry.addHandler(new ServerScriptHandler(), "/socket/script_run")
|
||||
|
@ -24,13 +24,12 @@ package io.jpom.socket.handler;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.unit.DataSize;
|
||||
import cn.hutool.core.lang.Tuple;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import io.jpom.common.Const;
|
||||
import io.jpom.common.JpomManifest;
|
||||
import io.jpom.common.JsonMessage;
|
||||
import io.jpom.common.Type;
|
||||
@ -48,6 +47,7 @@ import io.jpom.service.node.NodeService;
|
||||
import io.jpom.service.system.SystemParametersServer;
|
||||
import io.jpom.socket.BaseProxyHandler;
|
||||
import io.jpom.socket.ConsoleCommandOp;
|
||||
import io.jpom.system.ServerConfig;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import top.jpom.transport.DataContentType;
|
||||
@ -85,11 +85,15 @@ public class NodeUpdateHandler extends BaseProxyHandler {
|
||||
|
||||
private final SystemParametersServer systemParametersServer;
|
||||
private final NodeService nodeService;
|
||||
private final ServerConfig.NodeConfig nodeConfig;
|
||||
|
||||
public NodeUpdateHandler(NodeService nodeService, SystemParametersServer systemParametersServer) {
|
||||
public NodeUpdateHandler(NodeService nodeService,
|
||||
SystemParametersServer systemParametersServer,
|
||||
ServerConfig.NodeConfig nodeConfig) {
|
||||
super(null);
|
||||
this.nodeService = nodeService;
|
||||
this.systemParametersServer = systemParametersServer;
|
||||
this.nodeConfig = nodeConfig;
|
||||
//systemParametersServer = SpringUtil.getBean(SystemParametersServer.class);
|
||||
// nodeService = SpringUtil.getBean(NodeService.class);
|
||||
}
|
||||
@ -223,7 +227,7 @@ public class NodeUpdateHandler extends BaseProxyHandler {
|
||||
return;
|
||||
}
|
||||
JsonMessage<Tuple> error = JpomManifest.checkJpomJar(agentFileModel.getSavePath(), Type.Agent, false);
|
||||
if (error.getCode() != HttpStatus.HTTP_OK) {
|
||||
if (!error.success()) {
|
||||
this.onError(session, "Agent JAR 损坏请重新上传," + error.getMsg());
|
||||
return;
|
||||
}
|
||||
@ -295,7 +299,8 @@ public class NodeUpdateHandler extends BaseProxyHandler {
|
||||
try (FileInputStream fis = new FileInputStream(agentFileModel.getSavePath())) {
|
||||
// 发送文件内容
|
||||
int len;
|
||||
byte[] buffer = new byte[Const.DEFAULT_BUFFER_SIZE];
|
||||
int fileSliceSize = nodeConfig.getUploadFileSliceSize();
|
||||
byte[] buffer = new byte[(int) DataSize.ofMegabytes(fileSliceSize).toBytes()];
|
||||
while ((len = fis.read(buffer)) > 0) {
|
||||
client.send(ByteBuffer.wrap(buffer, 0, len));
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ public class OperateLogController implements AopLogInterface {
|
||||
//
|
||||
cacheInfo.userAgent = ServletUtil.getHeaderIgnoreCase(request, HttpHeaders.USER_AGENT);
|
||||
cacheInfo.workspaceId = BaseWorkspaceService.getWorkspaceId(request);
|
||||
//ServletUtil.getHeaderIgnoreCase(request, Const.WORKSPACEID_REQ_HEADER);
|
||||
//ServletUtil.getHeaderIgnoreCase(request, Const.WORKSPACE_ID_REQ_HEADER);
|
||||
//
|
||||
Map<String, Object> allData = this.buildRequestParam(request);
|
||||
//
|
||||
|
@ -6,7 +6,7 @@ jpom:
|
||||
heart-second: 30
|
||||
# 上传文件的超时时间 单位秒,最短5秒钟
|
||||
upload-file-timeout: 300
|
||||
# 节点文件分片上传大小,单位 M
|
||||
# 节点文件分片上传大小,单位 M,建议小于 5MB(需要考虑插件端上传文件大小限制)
|
||||
upload-file-slice-size: 1
|
||||
system:
|
||||
# cron 定时器是否开启匹配秒
|
||||
|
@ -6,7 +6,7 @@ jpom:
|
||||
heart-second: 30
|
||||
# 上传文件的超时时间 单位秒,最短5秒钟
|
||||
upload-file-timeout: 300
|
||||
# 节点文件分片上传大小,单位 M
|
||||
# 节点文件分片上传大小,单位 M,建议小于 5MB(需要考虑插件端上传文件大小限制)
|
||||
upload-file-slice-size: 1
|
||||
system:
|
||||
# cron 定时器是否开启匹配秒
|
||||
|
@ -44,7 +44,7 @@
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<a-tooltip slot="status" slot-scope="text, record" placement="topLeft" :title="`${statusMap[text]} ${record.statusMsg}`">
|
||||
<a-tooltip slot="status" slot-scope="text, record" placement="topLeft" :title="`${record.statusMsg}`">
|
||||
<a-tag v-if="text === 2" color="green">{{ statusMap[text] || "未知" }}</a-tag>
|
||||
<a-tag v-else-if="text === 1 || text === 0" color="orange">{{ statusMap[text] || "未知" }}</a-tag>
|
||||
<a-tag v-else-if="text === 3 || text === 4" color="red">{{ statusMap[text] || "未知" }}</a-tag>
|
||||
@ -1255,6 +1255,8 @@ export default {
|
||||
handleDispatch(record) {
|
||||
this.temp = Object.assign({ type: "upload" }, record);
|
||||
this.dispatchVisible = true;
|
||||
this.percentage = 0;
|
||||
this.fileList = [];
|
||||
this.$refs["dispatchForm"] && this.$refs["dispatchForm"].resetFields();
|
||||
},
|
||||
// 处理文件移除
|
||||
|
Loading…
Reference in New Issue
Block a user