Agent版本更新优化

This commit is contained in:
qiminbao
2025-09-25 17:19:40 +08:00
parent 40f2ab92fa
commit ca8f8ee257
7 changed files with 156 additions and 174 deletions
@@ -5,7 +5,6 @@ import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@Data @Data
@@ -27,7 +26,7 @@ public class AgentVersionUpdateEO {
private int method; private int method;
//定时时间,执行方式为1、定时执行时该字段必传 //定时时间,执行方式为1、定时执行时该字段必传
private LocalDateTime policyTime; private long policyTime;
//时间戳 //时间戳
private long timestamp; private long timestamp;
@@ -14,9 +14,6 @@ import com.tongran.agent.client.netty.basics.AgentHandler;
import com.tongran.agent.client.netty.model.UpMsgResponse; import com.tongran.agent.client.netty.model.UpMsgResponse;
import com.tongran.agent.client.scheduler.service.AdvancedAsyncDownloader; import com.tongran.agent.client.scheduler.service.AdvancedAsyncDownloader;
import com.tongran.agent.client.scheduler.service.AppInitializer; import com.tongran.agent.client.scheduler.service.AppInitializer;
import com.tongran.agent.client.scheduler.service.AsyncCommandExecutor;
import com.tongran.agent.client.scheduler.service.Java8FileDownloader;
import com.tongran.agent.client.scheduler.task.SpecificTimeRequest;
import com.tongran.agent.client.scheduler.task.SpecificTimeTaskService; import com.tongran.agent.client.scheduler.task.SpecificTimeTaskService;
import com.tongran.agent.client.service.AgentService; import com.tongran.agent.client.service.AgentService;
import com.tongran.agent.client.utils.AgentDataUtil; import com.tongran.agent.client.utils.AgentDataUtil;
@@ -27,9 +24,8 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.LinkedHashMap;
import java.util.concurrent.CompletableFuture; import java.util.List;
import java.util.concurrent.TimeUnit;
@Component @Component
public class AgentEndpoint { public class AgentEndpoint {
@@ -300,7 +296,7 @@ public class AgentEndpoint {
GlobalConfig.DOWN_FILES.put(policy.getPolicyName(), count--); GlobalConfig.DOWN_FILES.put(policy.getPolicyName(), count--);
}else{ }else{
//所有文件下载完成,执行脚本命令 //所有文件下载完成,执行脚本命令
agentService.command(policy, clientId); agentService.command(policy, clientId,MsgEnum.执行脚本策略应答.getValue());
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@@ -338,12 +334,12 @@ public class AgentEndpoint {
} }
//判断是否需要保存文件 //判断是否需要保存文件
if(!isFalse){ if(!isFalse){
agentService.command(policy, clientId); agentService.command(policy, clientId,MsgEnum.执行脚本策略应答.getValue());
return null; return null;
}else{ }else{
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("resCode",1); json.put("resCode",1);
json.put("resMsg", "A执行脚本策略文件保存中"); json.put("resMsg", "执行脚本策略文件保存中");
return UpMsgResponse.builder().clientId(clientId).dataType(MsgEnum.执行脚本策略应答.getValue()).content(json.toString()).build(); return UpMsgResponse.builder().clientId(clientId).dataType(MsgEnum.执行脚本策略应答.getValue()).content(json.toString()).build();
} }
} }
@@ -354,96 +350,50 @@ public class AgentEndpoint {
@Override @Override
public UpMsgResponse upHandle(String data, String clientId) { public UpMsgResponse upHandle(String data, String clientId) {
AgentVersionUpdateEO versionUpdateEO = JSON.parseObject(data, AgentVersionUpdateEO.class); AgentVersionUpdateEO versionUpdateEO = JSON.parseObject(data, AgentVersionUpdateEO.class);
boolean isFalse = false; ScriptPolicyEO policy = ScriptPolicyEO.builder()
if(StringUtils.isNotBlank(versionUpdateEO.getFileUrl()) && StringUtils.isNotBlank(versionUpdateEO.getFilePath())){ .method(versionUpdateEO.getMethod())
Java8FileDownloader.DownloadResult result = Java8FileDownloader.downloadFile(versionUpdateEO.getFileUrl(), versionUpdateEO.getFilePath(), ""); .policyTime(versionUpdateEO.getPolicyTime())
// 验证下载是否完成 .build();
if (result.isSuccess()) { JSONObject jsonObject = JSONObject.parseObject(data);
boolean isComplete = Java8FileDownloader.verifyFileCompletion( if(jsonObject.containsKey("commands")) {
result.getFilePath(), result.getExpectedSize()); String commands = jsonObject.getString("commands");
if(isComplete){ List<String> commandList = JSON.parseObject(commands, new TypeReference<List<String>>() {});
isFalse = true; policy.setCommands(commandList);
System.out.println("Agent版本更新下载完成");
}else{
isFalse = false;
System.err.println("Agent版本更新下载失败");
}
}
} }
//判断文件是否保存成功 boolean isFalse = false;
if(isFalse){ if(StringUtils.isNotBlank(versionUpdateEO.getFileUrl())){
if(CollectionUtil.isNotEmpty(versionUpdateEO.getCommands())){ isFalse = true;
//执行方式:0、立即执行;1、定时执行; String finalSaveDir = versionUpdateEO.getFilePath();
if(versionUpdateEO.getMethod() == 1){ AdvancedAsyncDownloader.downloadWithProgress(versionUpdateEO.getFileUrl(), finalSaveDir, null, progress -> {
SpecificTimeRequest request = SpecificTimeRequest.builder() System.out.printf("下载进度: %.1f%%\n", progress);
.taskId("") }).thenAccept(filePath -> {
.taskName("") System.out.println("下载完成: " + filePath);
.taskData(versionUpdateEO.getCommands()) try {
.specificDateTime(versionUpdateEO.getPolicyTime()) //更改全局变量
.clientId(clientId) GlobalConfig.isCollect = false;
.dataType(MsgEnum.Agent版本更新应答.getValue()) //调用采集任务
.build(); agentService.cancelCollect();
try { //所有文件下载完成,执行脚本命令
taskService.createSpecificTimeTask(request); agentService.command(policy, clientId,MsgEnum.Agent版本更新应答.getValue());
JSONObject json = new JSONObject(); } catch (Exception e) {
json.put("resCode",1); e.printStackTrace();
json.put("resMsg", "Agent版本更新定时任务保存成功");
// Message message = Message.builder().clientId(clientId).dataType(MsgEnum.Agent更新应答.getValue()).data(json.toString()).build();
return UpMsgResponse.builder().clientId(clientId).dataType(MsgEnum.Agent版本更新应答.getValue()).content(json.toString()).build();
} catch (Exception e) {
JSONObject json = new JSONObject();
json.put("resCode",0);
json.put("resMsg", "Agent版本更新定时任务保存失败");
// Message message = Message.builder().clientId(clientId).dataType(MsgEnum.Agent更新应答.getValue()).data(json.toString()).build();
return UpMsgResponse.builder().clientId(clientId).dataType(MsgEnum.Agent版本更新应答.getValue()).content(json.toString()).build();
}
}else{
List<Map<String,String>> list = new ArrayList<>();
for (String command : versionUpdateEO.getCommands()) {
Map<String,String> map = new HashMap<>();
List<String> cmd = Arrays.asList(command.split("\\s+"));
CompletableFuture<AsyncCommandExecutor.CommandResult> future =
AsyncCommandExecutor.executeCommandAsync(
cmd,
60, TimeUnit.SECONDS);
future.thenAccept(result -> {
if (result.isSuccess()) {
System.out.println("脚本执行成功");
System.out.println("[成功resOut] " + result.getOutput());
map.put("command",command);
map.put("resOut",result.getOutput());
} else {
System.out.println("脚本执行失败");
System.out.println("[失败resOut] " + result.getOutput());
map.put("command",command);
map.put("resOut",result.getOutput());
}
}).exceptionally(ex -> {
System.err.println("执行失败: " + ex.getMessage());
map.put("command",command);
map.put("resOut","Policy execute filed");
return null;
});
list.add(map);
}
if(CollectionUtil.isNotEmpty(list)){
JSONObject json = new JSONObject();
json.put("resCode",1);
json.put("resMsg", "");
json.put("result", AgentUtil.toJsonString(list));
// Message message = Message.builder().clientId(clientId).dataType(MsgEnum.Agent版本更新应答.getValue()).data(json.toString()).build();
return UpMsgResponse.builder().clientId(clientId).dataType(MsgEnum.Agent版本更新应答.getValue()).content(json.toString()).build();
}
} }
} }).exceptionally(ex -> {
System.err.println("下载错误: " + ex.getMessage());
return null;
});
}
//判断是否需要保存文件
if(!isFalse){
agentService.command(policy, clientId,MsgEnum.Agent版本更新应答.getValue());
return null;
}else{ }else{
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("resCode",0); json.put("resCode",1);
json.put("resMsg", "Agent版本更新文件保存失败"); json.put("resMsg", "Agent版本更新文件保存");
// Message message = Message.builder().clientId(clientId).dataType(MsgEnum.Agent版本更新应答.getValue()).data(json.toString()).build();
return UpMsgResponse.builder().clientId(clientId).dataType(MsgEnum.Agent版本更新应答.getValue()).content(json.toString()).build(); return UpMsgResponse.builder().clientId(clientId).dataType(MsgEnum.Agent版本更新应答.getValue()).content(json.toString()).build();
} }
return null;
} }
} }
@@ -124,8 +124,8 @@ public class AgentDecoderHandler extends ChannelInboundHandlerAdapter {
AgentHandler msgHandler = agentDispatcherManager.getHandler(dataType + "&" + AgentDispatcher.VersionEnum.V1.value); AgentHandler msgHandler = agentDispatcherManager.getHandler(dataType + "&" + AgentDispatcher.VersionEnum.V1.value);
if (ObjectUtil.isNotEmpty(msgHandler)) { if (ObjectUtil.isNotEmpty(msgHandler)) {
UpMsgResponse response = msgHandler.upHandle(data, clientId ); UpMsgResponse response = msgHandler.upHandle(data, clientId );
AssertLog.info("<<[up-after-handle]:clientId:{},type={},[handle-content]={}", response.getClientId(), dataType, message);
if(Objects.nonNull(response)){ if(Objects.nonNull(response)){
AssertLog.info("<<[up-after-handle]:clientId:{},type={},[handle-content]={}", response.getClientId(), dataType, message);
Message agentMessage = Message.builder().build(); Message agentMessage = Message.builder().build();
agentMessage.setClientId(response.getClientId()); agentMessage.setClientId(response.getClientId());
agentMessage.setDataType(response.getDataType()); agentMessage.setDataType(response.getDataType());
@@ -68,8 +68,8 @@ public class AdvancedAsyncDownloader {
} }
}, downloadExecutor); }, downloadExecutor);
} }
private static String extractFileNameFromUrl(String fileUrl) { public static String extractFileNameFromUrl(String fileUrl) {
// 实现文件名提取逻辑 // 实现文件名提取逻辑
return fileUrl.substring(fileUrl.lastIndexOf('/') + 1); return fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
} }
@@ -2,13 +2,16 @@ package com.tongran.agent.client.scheduler.task;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.tongran.agent.client.core.enums.MsgEnum;
import com.tongran.agent.client.core.session.SessionManager; import com.tongran.agent.client.core.session.SessionManager;
import com.tongran.agent.client.netty.model.Message; import com.tongran.agent.client.netty.model.Message;
import com.tongran.agent.client.scheduler.service.AsyncCommandExecutor; import com.tongran.agent.client.scheduler.service.AsyncCommandExecutor;
import com.tongran.agent.client.utils.AgentUtil; import com.tongran.agent.client.utils.AgentUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -73,30 +76,43 @@ public class SpecificTimeTaskService {
List<Map<String,String>> list = new ArrayList<>(); List<Map<String,String>> list = new ArrayList<>();
for (String command : request.getTaskData()) { for (String command : request.getTaskData()) {
Map<String,String> map = new HashMap<>(); Map<String,String> map = new HashMap<>();
List<String> cmd = Arrays.asList(command.split("\\s+")); if(StringUtils.equals(request.getDataType(), MsgEnum.Agent版本更新应答.getValue())){
CompletableFuture<AsyncCommandExecutor.CommandResult> future = try {
AsyncCommandExecutor.executeCommandAsync( System.out.println("重启进程已启动,当前服务退出");
cmd, System.out.println("command="+command);
60, TimeUnit.SECONDS); ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c",
future.thenAccept(result -> { command);
if (result.isSuccess()) { pb.start();
System.out.println("脚本执行成功"); System.exit(0);
System.out.println("[成功resOut] " + result.getOutput()); } catch (IOException e) {
map.put("command",command); e.printStackTrace();
map.put("resOut",result.getOutput());
} else {
System.out.println("脚本执行失败");
System.out.println("[失败resOut] " + result.getOutput());
map.put("command",command);
map.put("resOut",result.getOutput());
} }
}).exceptionally(ex -> { }else{
System.err.println("执行失败: " + ex.getMessage()); List<String> cmd = Arrays.asList(command.split("\\s+"));
map.put("command",command); CompletableFuture<AsyncCommandExecutor.CommandResult> future =
map.put("resOut","Policy execute filed"); AsyncCommandExecutor.executeCommandAsync(
return null; cmd,
}); 100, TimeUnit.SECONDS);
list.add(map); future.thenAccept(result -> {
if (result.isSuccess()) {
System.out.println("脚本执行成功");
System.out.println("[成功resOut] " + result.getOutput());
map.put("command",command);
map.put("resOut",result.getOutput());
} else {
System.out.println("脚本执行失败");
System.out.println("[失败resOut] " + result.getOutput());
map.put("command",command);
map.put("resOut",result.getOutput());
}
}).exceptionally(ex -> {
System.err.println("执行失败: " + ex.getMessage());
map.put("command",command);
map.put("resOut","Policy execute filed");
return null;
});
list.add(map);
}
} }
if(CollectionUtil.isNotEmpty(list)){ if(CollectionUtil.isNotEmpty(list)){
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
@@ -15,5 +15,5 @@ public interface AgentService {
void alarmMonitor(); void alarmMonitor();
void command(ScriptPolicyEO policy, String clientId); void command(ScriptPolicyEO policy, String clientId, String dataType);
} }
@@ -24,7 +24,10 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.*; import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -675,7 +678,7 @@ public class AgentServiceImpl implements AgentService {
} }
@Override @Override
public void command(ScriptPolicyEO policy, String clientId) { public void command(ScriptPolicyEO policy, String clientId, String dataType) {
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
timestamp = Math.round(timestamp / 1000.0); timestamp = Math.round(timestamp / 1000.0);
if(CollectionUtil.isNotEmpty(policy.getCommands())){ if(CollectionUtil.isNotEmpty(policy.getCommands())){
@@ -687,6 +690,7 @@ public class AgentServiceImpl implements AgentService {
.taskData(policy.getCommands()) .taskData(policy.getCommands())
.specificDateTime(AgentUtil.toLocalDateTime(policy.getPolicyTime(),true)) .specificDateTime(AgentUtil.toLocalDateTime(policy.getPolicyTime(),true))
.clientId(clientId) .clientId(clientId)
.dataType(dataType)
.build(); .build();
try { try {
taskService.createSpecificTimeTask(request); taskService.createSpecificTimeTask(request);
@@ -716,57 +720,70 @@ public class AgentServiceImpl implements AgentService {
} }
}else{ }else{
for (String command : policy.getCommands()) { for (String command : policy.getCommands()) {
List<String> cmd = Arrays.asList(command.split("\\s+")); if(StringUtils.equals(dataType, MsgEnum.Agent版本更新应答.getValue())){
CompletableFuture<AsyncCommandExecutor.CommandResult> future = try {
AsyncCommandExecutor.executeCommandAsync( System.out.println("重启进程已启动,当前服务退出");
cmd, System.out.println("command="+command);
60, TimeUnit.SECONDS); ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c",
future.thenAccept(result -> { command);
if (result.isSuccess()) { pb.start();
System.out.println("脚本执行成功"); System.exit(0);
System.out.println("[成功resOut] " + result.getOutput()); } catch (IOException e) {
} else { e.printStackTrace();
System.out.println("脚本执行失败");
System.out.println("[失败resOut] " + result.getOutput());
} }
JSONObject rse = new JSONObject(); }else{
rse.put("command",command); List<String> cmd = Arrays.asList(command.split("\\s+"));
rse.put("resOut", result.getOutput()); CompletableFuture<AsyncCommandExecutor.CommandResult> future =
long timestamps = System.currentTimeMillis(); AsyncCommandExecutor.executeCommandAsync(
timestamps = Math.round(timestamps / 1000.0); cmd,
JSONObject json = new JSONObject(); 100, TimeUnit.SECONDS);
json.put("resCode",1); future.thenAccept(result -> {
json.put("resMsg", ""); if (result.isSuccess()) {
json.put("timestamp",timestamps); System.out.println("脚本执行成功");
json.put("result", rse.toString()); System.out.println("[成功resOut] " + result.getOutput());
// 判定客户端与服务端是否连接 } else {
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) { System.out.println("脚本执行失败");
Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.执行脚本策略应答.getValue()) System.out.println("[失败resOut] " + result.getOutput());
.data(json.toString()).build(); }
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message); JSONObject rse = new JSONObject();
AssertLog.info("发送执行脚本策略应答={}",JSON.toJSONString(message)); rse.put("command",command);
} rse.put("resOut", result.getOutput());
}).exceptionally(ex -> { long timestamps = System.currentTimeMillis();
System.err.println("执行失败: " + ex.getMessage()); timestamps = Math.round(timestamps / 1000.0);
JSONObject rse = new JSONObject(); JSONObject json = new JSONObject();
rse.put("command",command); json.put("resCode",1);
rse.put("resOut", "脚本执行失败"); json.put("resMsg", "");
long timestamps = System.currentTimeMillis(); json.put("timestamp",timestamps);
timestamps = Math.round(timestamps / 1000.0); json.put("result", rse.toString());
JSONObject json = new JSONObject(); // 判定客户端与服务端是否连接
json.put("resCode",1); if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
json.put("resMsg", ""); Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(dataType)
json.put("timestamp",timestamps); .data(json.toString()).build();
json.put("result", rse.toString()); sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
// 判定客户端与服务端是否连接 AssertLog.info("发送执行脚本策略应答={}",JSON.toJSONString(message));
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) { }
Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.执行脚本策略应答.getValue()) }).exceptionally(ex -> {
.data(json.toString()).build(); System.err.println("执行失败: " + ex.getMessage());
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message); JSONObject rse = new JSONObject();
AssertLog.info("发送执行脚本策略应答={}",JSON.toJSONString(message)); rse.put("command",command);
} rse.put("resOut", "脚本执行失败");
return null; long timestamps = System.currentTimeMillis();
}); timestamps = Math.round(timestamps / 1000.0);
JSONObject json = new JSONObject();
json.put("resCode",1);
json.put("resMsg", "");
json.put("timestamp",timestamps);
json.put("result", rse.toString());
// 判定客户端与服务端是否连接
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(dataType)
.data(json.toString()).build();
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
AssertLog.info("发送执行脚本策略应答={}",JSON.toJSONString(message));
}
return null;
});
}
} }
} }
} }