[ Service ] [ Executor ] 初步重构Executor部分的代码
This commit is contained in:
@@ -5,8 +5,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type OctopusFunc interface {
|
||||||
|
Exec(baseFuncName string, funcArgs ...string) []string
|
||||||
|
|
||||||
|
Deploy(appFuncName string, funcArgs ...string) (bool, []string)
|
||||||
|
}
|
||||||
|
|
||||||
type AppFunc interface {
|
type AppFunc interface {
|
||||||
Deploy(appFuncName string, funcArgs ...string) []string
|
Deploy(appFuncName string, funcArgs ...string) (bool, []string)
|
||||||
}
|
}
|
||||||
|
|
||||||
var AppExecuteErrorLogPrefix = []string{"App指令执行错误! => "}
|
var AppExecuteErrorLogPrefix = []string{"App指令执行错误! => "}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ type ExecutionMessage struct {
|
|||||||
NeedResultReplay bool `json:"needResultReplay"`
|
NeedResultReplay bool `json:"needResultReplay"`
|
||||||
DurationTask bool `json:"durationTask,default:false"`
|
DurationTask bool `json:"durationTask,default:false"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
BaseFuncContent []string `json:"baseFuncContent"`
|
FuncContent []string `json:"funcContent"`
|
||||||
SingleLineCommand []string `json:"singleLineCommand"`
|
SingleLineCommand []string `json:"singleLineCommand"`
|
||||||
MultiLineCommand [][]string `json:"multiLineCommand"`
|
MultiLineCommand [][]string `json:"multiLineCommand"`
|
||||||
PipeLineCommand [][]string `json:"pipeLineCommand"`
|
PipeLineCommand [][]string `json:"pipeLineCommand"`
|
||||||
@@ -32,9 +32,18 @@ func Execute(em *ExecutionMessage) ([]string, error) {
|
|||||||
|
|
||||||
if strings.HasPrefix(em.Type, "BASE") {
|
if strings.HasPrefix(em.Type, "BASE") {
|
||||||
// base function
|
// base function
|
||||||
resultLog = AgentOsOperatorCache.Exec(em.BaseFuncContent[0], em.BaseFuncContent[1:]...)
|
resultLog = AgentOsOperatorCache.Exec(em.FuncContent[0], em.FuncContent[1:]...)
|
||||||
err = nil
|
err = nil
|
||||||
|
|
||||||
|
} else if strings.HasPrefix(em.Type, "APP") {
|
||||||
|
// app function
|
||||||
|
ok, resultLog := AgentOsOperatorCache.Deploy(em.FuncContent[0], em.FuncContent[1:]...)
|
||||||
|
if ok {
|
||||||
|
return resultLog, nil
|
||||||
|
} else {
|
||||||
|
return resultLog, nil
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// shell command
|
// shell command
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package io.wdd.func.script.service;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
public interface FuncService {
|
||||||
|
|
||||||
|
List<String> callBaseFuncService(String agentTopicName, String baseFunctionName, List<String> funcArgs);
|
||||||
|
|
||||||
|
|
||||||
|
List<String> callAppFuncService(String agentTopicName, String appFunctionName, List<String> funcArgs);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package io.wdd.func.script.service;
|
||||||
|
|
||||||
|
import io.wdd.rpc.execute.ExecutionMessageType;
|
||||||
|
import io.wdd.rpc.execute.ExecutionService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class FuncServiceImpl implements FuncService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ExecutionService executionService;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> callBaseFuncService(String agentTopicName, String baseFunctionName, List<String> funcArgs) {
|
||||||
|
|
||||||
|
return this.syncCallFunction(
|
||||||
|
agentTopicName,
|
||||||
|
ExecutionMessageType.BASE,
|
||||||
|
baseFunctionName,
|
||||||
|
funcArgs
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> callAppFuncService(String agentTopicName, String appFunctionName, List<String> funcArgs) {
|
||||||
|
|
||||||
|
return this.syncCallFunction(
|
||||||
|
agentTopicName,
|
||||||
|
ExecutionMessageType.APP,
|
||||||
|
appFunctionName,
|
||||||
|
funcArgs
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List<String> syncCallFunction(String agentTopicName, ExecutionMessageType emType, String funcName, List<String> funcArgs) {
|
||||||
|
|
||||||
|
// 重新构造内容
|
||||||
|
funcArgs.add(
|
||||||
|
0,
|
||||||
|
funcName
|
||||||
|
);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
ArrayList<String> resultLog = executionService.SendCommandToAgent(
|
||||||
|
agentTopicName,
|
||||||
|
emType.toString(),
|
||||||
|
funcArgs,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
"",
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
return resultLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ package io.wdd.func.xray.service;
|
|||||||
import io.wdd.common.utils.TimeUtils;
|
import io.wdd.common.utils.TimeUtils;
|
||||||
import io.wdd.func.oss.config.OctopusObjectSummary;
|
import io.wdd.func.oss.config.OctopusObjectSummary;
|
||||||
import io.wdd.func.xray.beans.node.ProxyNode;
|
import io.wdd.func.xray.beans.node.ProxyNode;
|
||||||
import io.wdd.rpc.execute.service.SyncExecutionService;
|
import io.wdd.rpc.execute.ExecutionService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -83,7 +83,7 @@ public class XrayCallAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
SyncExecutionService executionService;
|
ExecutionService executionService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 为代理链的每一个节点 构建Xray配置更新命令,然后发送至对应的Agent中
|
* 为代理链的每一个节点 构建Xray配置更新命令,然后发送至对应的Agent中
|
||||||
@@ -131,17 +131,18 @@ public class XrayCallAgent {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 向Agent发送命令,执行更新操作!
|
// 向Agent发送命令,执行更新操作!
|
||||||
String resultKey = executionService.SyncSendCommandToAgent(
|
executionService.SendCommandToAgent(
|
||||||
proxyNode.getAgentTopicName(),
|
proxyNode.getAgentTopicName(),
|
||||||
updateCommandType,
|
updateCommandType,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
updateXrayCommandList,
|
updateXrayCommandList,
|
||||||
false,
|
false,
|
||||||
null,
|
null,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
return resultKey;
|
return "";
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|||||||
@@ -8,15 +8,16 @@ public interface OctopusAgentService {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有Agent的版本信息,附带最新的版本信息
|
* 获取所有Agent的版本信息,附带最新的版本信息
|
||||||
* 超时时间为 5s
|
* 超时时间为 5s
|
||||||
|
*
|
||||||
* @return key - AgentTopicName value - version Info
|
* @return key - AgentTopicName value - version Info
|
||||||
*/
|
*/
|
||||||
Map<String, String> getAllAgentVersion();
|
Map<String, String> getAllAgentVersion();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有Agent的核心信息,方便更新系统信息
|
* 获取所有Agent的核心信息,方便更新系统信息
|
||||||
*
|
*
|
||||||
* @return agent-topic-name value -agentServerInfo
|
* @return agent-topic-name value -agentServerInfo
|
||||||
*/
|
*/
|
||||||
@@ -24,9 +25,9 @@ public interface OctopusAgentService {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行 Agent 关键操作的接口
|
* 执行 Agent 关键操作的接口
|
||||||
* 关机
|
* 关机
|
||||||
* */
|
*/
|
||||||
String shutdownAgentDanger(String agentTopicName);
|
String shutdownAgentDanger(String agentTopicName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,12 @@ import io.wdd.common.utils.TimeUtils;
|
|||||||
import io.wdd.rpc.message.OctopusMessage;
|
import io.wdd.rpc.message.OctopusMessage;
|
||||||
import io.wdd.rpc.message.OctopusMessageType;
|
import io.wdd.rpc.message.OctopusMessageType;
|
||||||
import io.wdd.rpc.message.handler.async.AsyncWaitOctopusMessageResultService;
|
import io.wdd.rpc.message.handler.async.AsyncWaitOctopusMessageResultService;
|
||||||
import io.wdd.rpc.message.handler.async.OctopusMessageSynScReplayContend;
|
import io.wdd.rpc.message.handler.async.OctopusMessageSyncReplayContend;
|
||||||
import io.wdd.rpc.message.sender.OMessageToAgentSender;
|
import io.wdd.rpc.message.sender.OMessageToAgentSender;
|
||||||
import io.wdd.server.beans.vo.ServerInfoVO;
|
import io.wdd.server.beans.vo.ServerInfoVO;
|
||||||
import io.wdd.server.config.ServerCommonPool;
|
import io.wdd.server.config.ServerCommonPool;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -26,12 +25,12 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static io.wdd.rpc.message.handler.sync.OMessageHandlerServer.LATEST_VERSION;
|
import static io.wdd.rpc.message.handler.sync.OMessageToServerListener.LATEST_VERSION;
|
||||||
import static io.wdd.rpc.message.handler.sync.OMessageHandlerServer.OCTOPUS_MESSAGE_FROM_AGENT;
|
import static io.wdd.rpc.message.handler.sync.OMessageToServerListener.OCTOPUS_MESSAGE_FROM_AGENT;
|
||||||
import static io.wdd.rpc.status.CommonAndStatusCache.ALL_AGENT_TOPIC_NAME_SET;
|
import static io.wdd.rpc.status.CommonAndStatusCache.ALL_AGENT_TOPIC_NAME_SET;
|
||||||
import static io.wdd.rpc.status.CommonAndStatusCache.ALL_HEALTHY_AGENT_TOPIC_NAME_LIST;
|
import static io.wdd.rpc.status.CommonAndStatusCache.ALL_HEALTHY_AGENT_TOPIC_NAME_LIST;
|
||||||
|
|
||||||
@Service
|
//@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class OctopusAgentServiceImpl implements OctopusAgentService {
|
public class OctopusAgentServiceImpl implements OctopusAgentService {
|
||||||
|
|
||||||
@@ -70,7 +69,7 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 构造 异步结果监听内容
|
// 构造 异步结果监听内容
|
||||||
OctopusMessageSynScReplayContend agentReplayContend = OctopusMessageSynScReplayContend.build(
|
OctopusMessageSyncReplayContend agentReplayContend = OctopusMessageSyncReplayContend.build(
|
||||||
ALL_HEALTHY_AGENT_TOPIC_NAME_LIST.size(),
|
ALL_HEALTHY_AGENT_TOPIC_NAME_LIST.size(),
|
||||||
CurrentAppOctopusMessageType,
|
CurrentAppOctopusMessageType,
|
||||||
currentTime
|
currentTime
|
||||||
@@ -147,16 +146,16 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 构造结果
|
// 构造结果
|
||||||
OctopusMessageSynScReplayContend octopusMessageSynScReplayContend = OctopusMessageSynScReplayContend.build(
|
OctopusMessageSyncReplayContend octopusMessageSyncReplayContend = OctopusMessageSyncReplayContend.build(
|
||||||
ALL_HEALTHY_AGENT_TOPIC_NAME_LIST.size(),
|
ALL_HEALTHY_AGENT_TOPIC_NAME_LIST.size(),
|
||||||
CurrentAppOctopusMessageType,
|
CurrentAppOctopusMessageType,
|
||||||
currentTime
|
currentTime
|
||||||
);
|
);
|
||||||
|
|
||||||
CountDownLatch countDownLatch = octopusMessageSynScReplayContend.getCountDownLatch();
|
CountDownLatch countDownLatch = octopusMessageSyncReplayContend.getCountDownLatch();
|
||||||
|
|
||||||
// 调用后台接收处理所有的Replay信息
|
// 调用后台接收处理所有的Replay信息
|
||||||
asyncWaitOctopusMessageResultService.waitFor(octopusMessageSynScReplayContend);
|
asyncWaitOctopusMessageResultService.waitFor(octopusMessageSyncReplayContend);
|
||||||
|
|
||||||
/* CompletableFuture<Void> getAllAgentCoreInfoFuture = waitCollectAllAgentCoreInfo(
|
/* CompletableFuture<Void> getAllAgentCoreInfoFuture = waitCollectAllAgentCoreInfo(
|
||||||
result,
|
result,
|
||||||
@@ -176,10 +175,10 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
|||||||
// 超时,或者 全部信息已经收集
|
// 超时,或者 全部信息已经收集
|
||||||
|
|
||||||
// 此处调用,即可中断 异步任务的收集工作
|
// 此处调用,即可中断 异步任务的收集工作
|
||||||
asyncWaitOctopusMessageResultService.stopWaiting(octopusMessageSynScReplayContend);
|
asyncWaitOctopusMessageResultService.stopWaiting(octopusMessageSyncReplayContend);
|
||||||
|
|
||||||
// 处理结果
|
// 处理结果
|
||||||
octopusMessageSynScReplayContend
|
octopusMessageSyncReplayContend
|
||||||
.getReplayOMList()
|
.getReplayOMList()
|
||||||
.stream()
|
.stream()
|
||||||
.forEach(
|
.forEach(
|
||||||
@@ -207,7 +206,7 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// help gc
|
// help gc
|
||||||
octopusMessageSynScReplayContend = null;
|
octopusMessageSyncReplayContend = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -265,7 +264,7 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
|||||||
|
|
||||||
// 不是当前应用需要的的OM,将信息放置与Cache队列的末尾
|
// 不是当前应用需要的的OM,将信息放置与Cache队列的末尾
|
||||||
|
|
||||||
OCTOPUS_MESSAGE_FROM_AGENT.offer(message);
|
OCTOPUS_MESSAGE_FROM_AGENT.add(message);
|
||||||
|
|
||||||
// 返回,继续死循环
|
// 返回,继续死循环
|
||||||
continue;
|
continue;
|
||||||
@@ -362,7 +361,7 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
|||||||
|
|
||||||
// OctopusMessageType判断
|
// OctopusMessageType判断
|
||||||
boolean OMTypeEqual = message
|
boolean OMTypeEqual = message
|
||||||
.getType()
|
.getOctopusMessageType()
|
||||||
.equals(CurrentAppOctopusMessageType);
|
.equals(CurrentAppOctopusMessageType);
|
||||||
|
|
||||||
return startTimeEqual && OMTypeEqual;
|
return startTimeEqual && OMTypeEqual;
|
||||||
@@ -411,7 +410,7 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
|||||||
|
|
||||||
return OctopusMessage
|
return OctopusMessage
|
||||||
.builder()
|
.builder()
|
||||||
.type(CurrentAppOctopusMessageType)
|
.octopusMessageType(CurrentAppOctopusMessageType)
|
||||||
.uuid(agentTopicName)
|
.uuid(agentTopicName)
|
||||||
.init_time(currentTime)
|
.init_time(currentTime)
|
||||||
.content(ops)
|
.content(ops)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package io.wdd.rpc.execute.config;
|
package io.wdd.rpc.config;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -6,14 +6,12 @@ import io.wdd.common.response.R;
|
|||||||
import io.wdd.rpc.agent.OctopusAgentService;
|
import io.wdd.rpc.agent.OctopusAgentService;
|
||||||
import io.wdd.server.beans.vo.ServerInfoVO;
|
import io.wdd.server.beans.vo.ServerInfoVO;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@RestController
|
//@RestController
|
||||||
@RequestMapping("/octopus/server/agent")
|
//@RequestMapping("/octopus/server/agent")
|
||||||
@Api(value = "处理Agent核心内容的Controller", tags = "Agent")
|
@Api(value = "处理Agent核心内容的Controller", tags = "Agent")
|
||||||
public class AgentController {
|
public class AgentController {
|
||||||
|
|
||||||
@@ -22,7 +20,7 @@ public class AgentController {
|
|||||||
|
|
||||||
@GetMapping("/version")
|
@GetMapping("/version")
|
||||||
@ApiOperation("[版本] - 所有OctopusAgent")
|
@ApiOperation("[版本] - 所有OctopusAgent")
|
||||||
public R<Map<String, String>> getAllAgentVersion(){
|
public R<Map<String, String>> getAllAgentVersion() {
|
||||||
|
|
||||||
return R.ok(octopusAgentService.getAllAgentVersion());
|
return R.ok(octopusAgentService.getAllAgentVersion());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import io.swagger.annotations.Api;
|
|||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import io.swagger.annotations.ApiParam;
|
import io.swagger.annotations.ApiParam;
|
||||||
import io.wdd.common.response.R;
|
import io.wdd.common.response.R;
|
||||||
import io.wdd.rpc.execute.service.AsyncExecutionService;
|
import io.wdd.rpc.execute.ExecutionService;
|
||||||
import io.wdd.rpc.execute.service.SyncExecutionService;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
@@ -14,25 +13,19 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static io.wdd.rpc.status.CommonAndStatusCache.ALL_AGENT_TOPIC_NAME_LIST;
|
|
||||||
import static io.wdd.rpc.status.CommonAndStatusCache.ALL_HEALTHY_AGENT_TOPIC_NAME_LIST;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/octopus/server/executor")
|
@RequestMapping("/octopus/server/executor")
|
||||||
@Api(value = "Agent执行命令的Controller", tags = "Execution")
|
@Api(value = "Agent执行命令的Controller", tags = "Execution")
|
||||||
public class ExecutionController {
|
public class ExecutionController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
SyncExecutionService syncExecutionService;
|
ExecutionService executionService;
|
||||||
@Resource
|
|
||||||
AsyncExecutionService asyncExecutionService;
|
|
||||||
|
|
||||||
@PostMapping("/command/one")
|
@PostMapping("/command/one")
|
||||||
@ApiOperation("[命令] [异步]- 单台主机")
|
@ApiOperation("[命令] [异步]- 单台主机")
|
||||||
public R<String> patchCommandToAgent(
|
public R<ArrayList<String>> patchCommandToAgent(
|
||||||
@RequestParam(value = "topicName") @ApiParam(name = "topicName", value = "目标主机名称") String topicName,
|
@RequestParam(value = "topicName") @ApiParam(name = "topicName", value = "目标主机名称") String topicName,
|
||||||
@RequestParam(value = "commandList", required = false) @Nullable List<String> commandList,
|
@RequestParam(value = "commandList", required = false) @Nullable List<String> commandList,
|
||||||
@RequestParam(value = "completeCommandList", required = false)
|
@RequestParam(value = "completeCommandList", required = false)
|
||||||
@@ -41,19 +34,7 @@ public class ExecutionController {
|
|||||||
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
||||||
) {
|
) {
|
||||||
|
|
||||||
ArrayList<String> streamKeyList = asyncExecutionService
|
return R.ok(null);
|
||||||
.AsyncSendCommandToAgentComplete(
|
|
||||||
topicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
completeCommandList,
|
|
||||||
false,
|
|
||||||
null,
|
|
||||||
isDurationTask
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
return R.ok(streamKeyList.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/command/batch")
|
@PostMapping("/command/batch")
|
||||||
@@ -68,15 +49,7 @@ public class ExecutionController {
|
|||||||
@RequestParam(value = "type", required = false) @Nullable String type,
|
@RequestParam(value = "type", required = false) @Nullable String type,
|
||||||
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
||||||
) {
|
) {
|
||||||
|
return R.ok(null);
|
||||||
List<ArrayList<String>> arrayListList = asyncExecutionService.AsyncSendCommandToAgentComplete(
|
|
||||||
topicNameList,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
completeCommandList,
|
|
||||||
isDurationTask
|
|
||||||
);
|
|
||||||
return R.ok(arrayListList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -91,13 +64,7 @@ public class ExecutionController {
|
|||||||
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
||||||
) {
|
) {
|
||||||
|
|
||||||
return R.ok(asyncExecutionService.AsyncSendCommandToAgentComplete(
|
return R.ok(null);
|
||||||
ALL_AGENT_TOPIC_NAME_LIST,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
completeCommandList,
|
|
||||||
isDurationTask
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/command/healthy")
|
@PostMapping("/command/healthy")
|
||||||
@@ -111,15 +78,26 @@ public class ExecutionController {
|
|||||||
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
||||||
) {
|
) {
|
||||||
|
|
||||||
return R.ok(asyncExecutionService.AsyncSendCommandToAgentComplete(
|
// List<ArrayList<String>> pathResult = syncExecutionService
|
||||||
ALL_HEALTHY_AGENT_TOPIC_NAME_LIST,
|
// .SyncSendCommandToAgentComplete(
|
||||||
type,
|
// ALL_HEALTHY_AGENT_TOPIC_NAME_LIST,
|
||||||
commandList,
|
// type,
|
||||||
completeCommandList,
|
// null,
|
||||||
isDurationTask
|
// commandList,
|
||||||
));
|
// completeCommandList,
|
||||||
|
// false,
|
||||||
|
// null,
|
||||||
|
// isDurationTask
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// return R.ok(pathResult);
|
||||||
|
return R.ok(null);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/command/sync/one")
|
@PostMapping("/command/sync/one")
|
||||||
@ApiOperation("[命令] [同步] - 单机-等待命令结果")
|
@ApiOperation("[命令] [同步] - 单机-等待命令结果")
|
||||||
public R<List<String>> SyncPatchCommandToAgent(
|
public R<List<String>> SyncPatchCommandToAgent(
|
||||||
@@ -131,19 +109,25 @@ public class ExecutionController {
|
|||||||
@RequestParam(value = "type", required = false) @ApiParam(name = "type", value = "执行命令类型") @Nullable String type
|
@RequestParam(value = "type", required = false) @ApiParam(name = "type", value = "执行命令类型") @Nullable String type
|
||||||
) {
|
) {
|
||||||
|
|
||||||
return R.ok(
|
ArrayList<String> resultLog = executionService
|
||||||
Collections.singletonList(syncExecutionService.SyncSendCommandToAgentComplete(
|
.SendCommandToAgent(
|
||||||
topicName,
|
topicName,
|
||||||
type,
|
type,
|
||||||
|
null,
|
||||||
commandList,
|
commandList,
|
||||||
completeCommandList
|
completeCommandList,
|
||||||
))
|
false,
|
||||||
);
|
null,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
return R.ok(resultLog);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/command/sync/batch")
|
@PostMapping("/command/sync/batch")
|
||||||
@ApiOperation("[命令] [同步] - 批量-等待命令结果")
|
@ApiOperation("[命令] [同步] - 批量-等待命令结果")
|
||||||
public R<List<String>> SyncPatchCommandToAgentBatch(
|
public R<List<ArrayList<String>>> SyncPatchCommandToAgentBatch(
|
||||||
@RequestParam(value = "topicNameList")
|
@RequestParam(value = "topicNameList")
|
||||||
@ApiParam(name = "topicNameList", value = "目标机器列表") List<String> topicNameList,
|
@ApiParam(name = "topicNameList", value = "目标机器列表") List<String> topicNameList,
|
||||||
@RequestParam(value = "commandList", required = false)
|
@RequestParam(value = "commandList", required = false)
|
||||||
@@ -154,20 +138,28 @@ public class ExecutionController {
|
|||||||
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
||||||
) {
|
) {
|
||||||
|
|
||||||
return R.ok(
|
// List<ArrayList<String>> pathResult = syncExecutionService
|
||||||
syncExecutionService.SyncSendCommandToAgentComplete(
|
// .SyncSendCommandToAgentComplete(
|
||||||
topicNameList,
|
// topicNameList,
|
||||||
type,
|
// type,
|
||||||
commandList,
|
// null,
|
||||||
completeCommandList,
|
// commandList,
|
||||||
isDurationTask
|
// completeCommandList,
|
||||||
)
|
// false,
|
||||||
);
|
// null,
|
||||||
|
// isDurationTask
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// return R.ok(pathResult);
|
||||||
|
return R.ok(null);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/command/sync/all")
|
@PostMapping("/command/sync/all")
|
||||||
@ApiOperation("[命令] [同步] - 全部-同步等待命令结果")
|
@ApiOperation("[命令] [同步] - 全部-同步等待命令结果")
|
||||||
public R<List<String>> SyncPatchCommandToAgentAll(
|
public R<List<ArrayList<String>>> SyncPatchCommandToAgentAll(
|
||||||
@RequestParam(value = "commandList", required = false)
|
@RequestParam(value = "commandList", required = false)
|
||||||
@ApiParam(name = "commandList", value = "命令行") @Nullable List<String> commandList,
|
@ApiParam(name = "commandList", value = "命令行") @Nullable List<String> commandList,
|
||||||
@RequestParam(value = "completeCommandList", required = false)
|
@RequestParam(value = "completeCommandList", required = false)
|
||||||
@@ -176,20 +168,59 @@ public class ExecutionController {
|
|||||||
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
||||||
) {
|
) {
|
||||||
|
|
||||||
return R.ok(
|
// List<ArrayList<String>> pathResult = syncExecutionService
|
||||||
syncExecutionService.SyncSendCommandToAgentComplete(
|
// .SyncSendCommandToAgentComplete(
|
||||||
ALL_AGENT_TOPIC_NAME_LIST,
|
// ALL_AGENT_TOPIC_NAME_LIST,
|
||||||
type,
|
// type,
|
||||||
commandList,
|
// null,
|
||||||
completeCommandList,
|
// commandList,
|
||||||
isDurationTask
|
// completeCommandList,
|
||||||
)
|
// false,
|
||||||
);
|
// null,
|
||||||
|
// isDurationTask
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// return R.ok(pathResult);
|
||||||
|
return R.ok(null);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/command/sync/healthy")
|
||||||
|
@ApiOperation("[命令] [同步] - 健康的主机")
|
||||||
|
public R<List<ArrayList<String>>> SyncPatchCommandToHealthyAgent(
|
||||||
|
@RequestParam(value = "commandList", required = false)
|
||||||
|
@ApiParam(name = "commandList", value = "命令行") @Nullable List<String> commandList,
|
||||||
|
@RequestParam(value = "completeCommandList", required = false)
|
||||||
|
@ApiParam(name = "completeCommandList", value = "完整命令行,优先,可为空") @Nullable List<List<String>> completeCommandList,
|
||||||
|
@RequestParam(value = "type", required = false) @Nullable String type,
|
||||||
|
@ApiParam(name = "isDurationTask", value = "是否是持久化任务") @RequestParam(value = "isDurationTask", defaultValue = "false", required = false) boolean isDurationTask
|
||||||
|
) {
|
||||||
|
|
||||||
|
// List<ArrayList<String>> pathResult = syncExecutionService
|
||||||
|
// .SyncSendCommandToAgentComplete(
|
||||||
|
// ALL_HEALTHY_AGENT_TOPIC_NAME_LIST,
|
||||||
|
// type,
|
||||||
|
// null,
|
||||||
|
// commandList,
|
||||||
|
// completeCommandList,
|
||||||
|
// false,
|
||||||
|
// null,
|
||||||
|
// isDurationTask
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// return R.ok(pathResult);
|
||||||
|
return R.ok(null);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/agentStatusStream")
|
@PostMapping("/agentStatusStream")
|
||||||
@ApiOperation("切换Console查看Agent状态日志")
|
@ApiOperation("切换Console查看Agent状态日志")
|
||||||
|
@Deprecated
|
||||||
public R<String> getAgentStatusStrem(
|
public R<String> getAgentStatusStrem(
|
||||||
@RequestParam(value = "streamKey") @ApiParam(value = "status的Stream Key") String streamKey
|
@RequestParam(value = "streamKey") @ApiParam(value = "status的Stream Key") String streamKey
|
||||||
) {
|
) {
|
||||||
@@ -199,82 +230,4 @@ public class ExecutionController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// auth required
|
|
||||||
// @PostMapping("/function/update")
|
|
||||||
// @ApiOperation("升级")
|
|
||||||
// public R<List<String>> AgentUpdate(
|
|
||||||
// @RequestParam(value = "topicNameList")
|
|
||||||
// @ApiParam(name = "topicNameList", value = "目标机器列表") List<String> topicNameList
|
|
||||||
// ) {
|
|
||||||
//
|
|
||||||
// return R.ok(
|
|
||||||
// syncExecutionService
|
|
||||||
// .SyncSendCommandToAgent(
|
|
||||||
// topicNameList,
|
|
||||||
// "AgentUpdate",
|
|
||||||
// null,
|
|
||||||
// false,
|
|
||||||
// null,
|
|
||||||
// true
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @PostMapping("/function/reboot")
|
|
||||||
// @ApiOperation("重启")
|
|
||||||
// public R<List<String>> AgentReboot(
|
|
||||||
// @RequestParam(value = "topicNameList")
|
|
||||||
// @ApiParam(name = "topicNameList", value = "目标机器列表") List<String> topicNameList
|
|
||||||
// ) {
|
|
||||||
//
|
|
||||||
// return R.ok(
|
|
||||||
// asyncExecutionService
|
|
||||||
// .SyncSendCommandToAgent(
|
|
||||||
// topicNameList,
|
|
||||||
// "AgentReboot",
|
|
||||||
// null,
|
|
||||||
// false,
|
|
||||||
// null,
|
|
||||||
// true
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @PostMapping("/function/shutdown")
|
|
||||||
// @ApiOperation("关闭")
|
|
||||||
// public R<List<String>> AgentShutdown(
|
|
||||||
// @RequestParam(value = "topicNameList")
|
|
||||||
// @ApiParam(name = "topicNameList", value = "目标机器列表") List<String> topicNameList
|
|
||||||
// ) {
|
|
||||||
//
|
|
||||||
// return R.ok(
|
|
||||||
// syncExecutionService
|
|
||||||
// .SyncSendCommandToAgent(
|
|
||||||
// topicNameList,
|
|
||||||
// "AgentShutdown",
|
|
||||||
// null,
|
|
||||||
// false,
|
|
||||||
// null,
|
|
||||||
// true
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @PostMapping("/function/bootUp")
|
|
||||||
// @ApiOperation("重新部署")
|
|
||||||
// public R<List<String>> AgentBootUp(
|
|
||||||
// @RequestParam(value = "topicNameList")
|
|
||||||
// @ApiParam(name = "topicNameList", value = "目标机器列表") List<String> topicNameList
|
|
||||||
// ) {
|
|
||||||
//
|
|
||||||
// return R.ok(
|
|
||||||
// asyncExecutionService
|
|
||||||
// .SyncSendCommandToAgent(
|
|
||||||
// topicNameList,
|
|
||||||
// "AgentBootUp",
|
|
||||||
// null,
|
|
||||||
// false,
|
|
||||||
// null,
|
|
||||||
// true
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ import io.wdd.rpc.beans.request.MetricQueryEntity;
|
|||||||
import io.wdd.rpc.scheduler.service.status.AgentAliveStatusMonitorService;
|
import io.wdd.rpc.scheduler.service.status.AgentAliveStatusMonitorService;
|
||||||
import io.wdd.rpc.status.beans.AgentStatus;
|
import io.wdd.rpc.status.beans.AgentStatus;
|
||||||
import io.wdd.rpc.status.service.SyncStatusService;
|
import io.wdd.rpc.status.service.SyncStatusService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -18,9 +20,9 @@ import java.util.Map;
|
|||||||
import static io.wdd.rpc.status.CommonAndStatusCache.*;
|
import static io.wdd.rpc.status.CommonAndStatusCache.*;
|
||||||
|
|
||||||
|
|
||||||
@RestController
|
//@RestController
|
||||||
@Api(value = "Agent运行状态Controller", tags = "Status")
|
@Api(value = "Agent运行状态Controller", tags = "Status")
|
||||||
@RequestMapping("/octopus/server/status")
|
//@RequestMapping("/octopus/server/status")
|
||||||
public class StatusController {
|
public class StatusController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
|||||||
@@ -33,10 +33,15 @@ public class ExecutionMessage {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于区分 ExecutionMessage的类型
|
* 用于区分 ExecutionMessage的类型
|
||||||
* 直接执行预定函数,则为 Nacos配置中的 方法名称,例如 AgentUpdate AgentReboot
|
* BASE APP
|
||||||
*/
|
*/
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行功能脚本时需要的参数
|
||||||
|
*/
|
||||||
|
private List<String> funcContent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 只有一行的命令行
|
* 只有一行的命令行
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package io.wdd.rpc.execute;
|
||||||
|
|
||||||
|
public enum ExecutionMessageType {
|
||||||
|
|
||||||
|
|
||||||
|
// 基础类型,执行基础脚本类
|
||||||
|
BASE,
|
||||||
|
|
||||||
|
// 应用类,执行特定功能
|
||||||
|
APP,
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package io.wdd.rpc.execute;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ExecutionService {
|
||||||
|
|
||||||
|
|
||||||
|
ArrayList<String> SendCommandToAgent(
|
||||||
|
String agentTopicName,
|
||||||
|
String type,
|
||||||
|
List<String> funcContent,
|
||||||
|
List<String> commandList,
|
||||||
|
List<List<String>> commandListComplete,
|
||||||
|
boolean needResultReplay,
|
||||||
|
String resultKey,
|
||||||
|
boolean durationTask
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
package io.wdd.rpc.execute;
|
||||||
|
|
||||||
|
import io.wdd.common.utils.TimeUtils;
|
||||||
|
import io.wdd.rpc.message.OctopusMessage;
|
||||||
|
import io.wdd.rpc.message.OctopusMessageType;
|
||||||
|
import io.wdd.rpc.message.sender.OMessageToAgentSender;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static io.wdd.rpc.status.CommonAndStatusCache.ALL_AGENT_TOPIC_NAME_SET;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class ExecutionServiceImpl implements ExecutionService {
|
||||||
|
|
||||||
|
private static final String MANUAL_COMMAND_TYPE = "manual-command";
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
OMessageToAgentSender oMessageToAgentSender;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayList<String> SendCommandToAgent(String agentTopicName, String type, List<String> funcContent, List<String> commandList, List<List<String>> commandListComplete, boolean needResultReplay, String resultKey, boolean durationTask) {
|
||||||
|
|
||||||
|
ArrayList<String> commandResultLog = null;
|
||||||
|
|
||||||
|
// 归一化type
|
||||||
|
if (StringUtils.isEmpty(type)) {
|
||||||
|
type = MANUAL_COMMAND_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造 Execution Command对应的消息体
|
||||||
|
ExecutionMessage executionMessage = this
|
||||||
|
.generateExecutionMessage(
|
||||||
|
type,
|
||||||
|
commandList,
|
||||||
|
resultKey,
|
||||||
|
commandListComplete,
|
||||||
|
needResultReplay,
|
||||||
|
durationTask
|
||||||
|
);
|
||||||
|
OctopusMessage octopusMessage = this.generateOctopusMessage(
|
||||||
|
agentTopicName,
|
||||||
|
executionMessage
|
||||||
|
);
|
||||||
|
|
||||||
|
// send the message
|
||||||
|
oMessageToAgentSender.send(octopusMessage);
|
||||||
|
|
||||||
|
|
||||||
|
// 需要返回结果
|
||||||
|
if (!durationTask) {
|
||||||
|
|
||||||
|
synchronized (octopusMessage) {
|
||||||
|
try {
|
||||||
|
octopusMessage.wait(10000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换结果
|
||||||
|
commandResultLog = (ArrayList<String>) octopusMessage.getResult();
|
||||||
|
|
||||||
|
// debug
|
||||||
|
log.debug(
|
||||||
|
"执行命令 {} 的结果为 {} 内容为 {}",
|
||||||
|
executionMessage.getSingleLineCommand() == null ? executionMessage.getMultiLineCommand() : executionMessage.getSingleLineCommand(),
|
||||||
|
octopusMessage.getResultCode(),
|
||||||
|
octopusMessage.getResult()
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return commandResultLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private OctopusMessage generateOctopusMessage(String agentTopicName, ExecutionMessage executionMessage) {
|
||||||
|
|
||||||
|
return OctopusMessage
|
||||||
|
.builder()
|
||||||
|
.octopusMessageType(OctopusMessageType.EXECUTOR)
|
||||||
|
.init_time(TimeUtils.currentFormatTime())
|
||||||
|
.uuid(agentTopicName)
|
||||||
|
.content(
|
||||||
|
executionMessage
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExecutionMessage generateExecutionMessage(String type, List<String> commandList, String resultKey, List<List<String>> commandListComplete, boolean needResultReplay, boolean durationTask) {
|
||||||
|
|
||||||
|
return ExecutionMessage
|
||||||
|
.builder()
|
||||||
|
.resultKey(resultKey)
|
||||||
|
.type(type)
|
||||||
|
.singleLineCommand(commandList)
|
||||||
|
.multiLineCommand(commandListComplete)
|
||||||
|
.needResultReplay(needResultReplay)
|
||||||
|
.durationTask(durationTask)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean validateCommandInfo(String agentTopicName, String type) {
|
||||||
|
|
||||||
|
// 检查agentTopicName是否存在
|
||||||
|
if (!ALL_AGENT_TOPIC_NAME_SET.contains(agentTopicName)) {
|
||||||
|
log.error(
|
||||||
|
"agentTopicName异常! 输入为 => {}",
|
||||||
|
agentTopicName
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
//throw new MyRuntimeException("agentTopicName异常!" + agentTopicName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package io.wdd.rpc.execute.config;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.experimental.SuperBuilder;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
@SuperBuilder(toBuilder = true)
|
|
||||||
public class CommandReaderConfig {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消费者类型:独立消费、消费组消费
|
|
||||||
*/
|
|
||||||
private String consumerType;
|
|
||||||
/**
|
|
||||||
* 消费组
|
|
||||||
*/
|
|
||||||
private String group;
|
|
||||||
/**
|
|
||||||
* 消费组中的某个消费者
|
|
||||||
*/
|
|
||||||
private String consumerName;
|
|
||||||
|
|
||||||
private String streamKey;
|
|
||||||
|
|
||||||
private String recordId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行的结果对象,保存在此处
|
|
||||||
*/
|
|
||||||
private ArrayList<String> ExecutionResult;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
//package io.wdd.rpc.execute.config;
|
|
||||||
//
|
|
||||||
//import org.springframework.context.annotation.Bean;
|
|
||||||
//import org.springframework.context.annotation.Configuration;
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//@Configuration
|
|
||||||
//public class CommandReaderConfigBean {
|
|
||||||
//
|
|
||||||
// // todo must support for multi thread
|
|
||||||
// // its not thread safe now
|
|
||||||
// @Bean
|
|
||||||
// public CommandReaderConfig commandReaderConfig() {
|
|
||||||
//
|
|
||||||
// return CommandReaderConfig
|
|
||||||
// .builder()
|
|
||||||
// .consumerName(REDIS_STREAM_LISTENER_CONSUMER_NAME)
|
|
||||||
// .streamKey("ccc")
|
|
||||||
// .consumerType(REDIS_STREAM_LISTENER_CONSUMER_NAME)
|
|
||||||
// .group("ccc")
|
|
||||||
// .ExecutionResult(null)
|
|
||||||
// .build();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package io.wdd.rpc.execute.config;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.wdd.server.beans.po.ExecutionLogPO;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
@ApiModel("Execution模快持久化Bean对象")
|
|
||||||
public class ExecutionLog extends ExecutionLogPO {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package io.wdd.rpc.execute.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class ExecutionResultStringDeserializer {
|
|
||||||
|
|
||||||
public static ArrayList<String> format(String executionResultString) {
|
|
||||||
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY,
|
|
||||||
true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
String tmp = objectMapper.readValue(executionResultString,
|
|
||||||
new TypeReference<String>() {
|
|
||||||
});
|
|
||||||
|
|
||||||
return objectMapper.readValue(tmp,
|
|
||||||
new TypeReference<ArrayList<String>>() {
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (JsonProcessingException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
//package io.wdd.rpc.execute.result;
|
|
||||||
//
|
|
||||||
//import io.wdd.rpc.execute.config.CommandReaderConfig;
|
|
||||||
//import io.wdd.server.utils.SpringUtils;
|
|
||||||
//import lombok.SneakyThrows;
|
|
||||||
//import lombok.extern.slf4j.Slf4j;
|
|
||||||
//import org.springframework.data.redis.connection.stream.ReadOffset;
|
|
||||||
//import org.springframework.data.redis.connection.stream.StreamOffset;
|
|
||||||
//import org.springframework.data.redis.stream.StreamMessageListenerContainer;
|
|
||||||
//import org.springframework.stereotype.Component;
|
|
||||||
//
|
|
||||||
//import java.util.ArrayList;
|
|
||||||
//import java.util.HashMap;
|
|
||||||
//import java.util.concurrent.TimeUnit;
|
|
||||||
//
|
|
||||||
//import static io.wdd.rpc.execute.result.RedisStreamReaderConfig.EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER;
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//@Component
|
|
||||||
//@Slf4j
|
|
||||||
//public class BuildStreamReader {
|
|
||||||
//
|
|
||||||
// private final HashMap<String, StreamMessageListenerContainer> REDIS_STREAM_LISTENER_CONTAINER_CACHE = new HashMap<>(16);
|
|
||||||
// private RedisStreamReaderConfig redisStreamReaderConfig;
|
|
||||||
//
|
|
||||||
// private StreamMessageListenerContainer streamMessageListenerContainer;
|
|
||||||
//
|
|
||||||
// private CommandReaderConfig commandReaderConfig;
|
|
||||||
//
|
|
||||||
// public void buildStreamReader(CommandReaderConfig commandReaderConfig) {
|
|
||||||
//
|
|
||||||
// // prepare the environment
|
|
||||||
// prepareExecutionEnv();
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// // just modify the redis listener container and it's ok
|
|
||||||
// modifyExecutionStreamReader(commandReaderConfig);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @SneakyThrows
|
|
||||||
// private void modifyExecutionStreamReader(CommandReaderConfig commandReaderConfig) {
|
|
||||||
//
|
|
||||||
// // stop the old stream listener container
|
|
||||||
// if (this.streamMessageListenerContainer.isRunning()) {
|
|
||||||
// this.streamMessageListenerContainer.stop();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // modify container
|
|
||||||
// this.streamMessageListenerContainer.receive(
|
|
||||||
// StreamOffset.create(
|
|
||||||
// commandReaderConfig.getStreamKey(),
|
|
||||||
// ReadOffset.lastConsumed()),
|
|
||||||
//
|
|
||||||
// new CommandResultReader(
|
|
||||||
// commandReaderConfig
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// // very important
|
|
||||||
// TimeUnit.MILLISECONDS.sleep(500);
|
|
||||||
// this.streamMessageListenerContainer.start();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void prepareExecutionEnv() {
|
|
||||||
//
|
|
||||||
// getRedisStreamListenerContainer();
|
|
||||||
//
|
|
||||||
// getRedisStreamReaderConfig();
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void getRedisStreamReaderConfig() {
|
|
||||||
//
|
|
||||||
// this.commandReaderConfig = SpringUtils.getBean("commandReaderConfig",
|
|
||||||
// CommandReaderConfig.class);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void getRedisStreamListenerContainer() {
|
|
||||||
//
|
|
||||||
// this.streamMessageListenerContainer = SpringUtils.getBean(
|
|
||||||
// EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER,
|
|
||||||
// StreamMessageListenerContainer.class
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void registerStreamReader(String redisStreamListenerContainerBeanName, String streamKey) {
|
|
||||||
// registerStreamReader(redisStreamListenerContainerBeanName,
|
|
||||||
// streamKey,
|
|
||||||
// null);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void registerStreamReader(String redisStreamListenerContainerBeanName, String streamKey, ArrayList<String> ExecutionResult) {
|
|
||||||
//
|
|
||||||
// // prepare the environment
|
|
||||||
// prepareEnv();
|
|
||||||
//
|
|
||||||
// // oldStreamKey equals streamKey don't need to do anything , just return
|
|
||||||
// if (redisStreamReaderConfig.getStreamKey()
|
|
||||||
// .equals(streamKey)) {
|
|
||||||
// log.debug("redis listener container not change !");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // destroy the old REDIS_STREAM_LISTENER_CONTAINER
|
|
||||||
// destroyStreamReader(streamKey);
|
|
||||||
//
|
|
||||||
// // modify the configuration ==> streamKey
|
|
||||||
// modifyStreamReader(streamKey,
|
|
||||||
// ExecutionResult);
|
|
||||||
//
|
|
||||||
// // re-create the REDIS_STREAM_LISTENER_CONTAINER
|
|
||||||
// createStreamReader(redisStreamListenerContainerBeanName,
|
|
||||||
// streamKey);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void prepareEnv() {
|
|
||||||
//
|
|
||||||
// getRedisStreamConfig();
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void getRedisStreamConfig() {
|
|
||||||
//
|
|
||||||
// this.redisStreamReaderConfig = SpringUtils.getBean("redisStreamReaderConfig",
|
|
||||||
// RedisStreamReaderConfig.class);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// private void createStreamReader(String redisStreamListenerContainerBeanName, String streamKey) {
|
|
||||||
//
|
|
||||||
// log.debug("start to create the redis stream listener container");
|
|
||||||
// // create the lazy bean
|
|
||||||
//
|
|
||||||
// StreamMessageListenerContainer streamMessageListenerContainer = SpringUtils.getBean(redisStreamListenerContainerBeanName,
|
|
||||||
// StreamMessageListenerContainer.class);
|
|
||||||
//
|
|
||||||
// REDIS_STREAM_LISTENER_CONTAINER_CACHE.put(streamKey,
|
|
||||||
// streamMessageListenerContainer);
|
|
||||||
//
|
|
||||||
// // very important
|
|
||||||
// log.debug("start the listener container");
|
|
||||||
// streamMessageListenerContainer.start();
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void modifyStreamReader(String streamKey, ArrayList<String> executionResult) {
|
|
||||||
//
|
|
||||||
// log.debug("start to modify the redis stream listener container stream key");
|
|
||||||
// String oldStreamKey = redisStreamReaderConfig.getStreamKey();
|
|
||||||
//
|
|
||||||
// log.debug("change stream key from [{}] to [{}]",
|
|
||||||
// oldStreamKey,
|
|
||||||
// streamKey);
|
|
||||||
//
|
|
||||||
// log.debug("start to set the Redis Stream Reader key");
|
|
||||||
// redisStreamReaderConfig.setStreamKey(streamKey);
|
|
||||||
//
|
|
||||||
// log.debug("start to set the Redis Stream Execution Result Container");
|
|
||||||
// redisStreamReaderConfig.setExecutionResult(executionResult);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// private void destroyStreamReader(String streamKey) {
|
|
||||||
//
|
|
||||||
// String oldStreamKey = redisStreamReaderConfig.getStreamKey();
|
|
||||||
//
|
|
||||||
// if (REDIS_STREAM_LISTENER_CONTAINER_CACHE.containsKey(oldStreamKey)) {
|
|
||||||
//
|
|
||||||
// StreamMessageListenerContainer streamMessageListenerContainer = REDIS_STREAM_LISTENER_CONTAINER_CACHE.get(oldStreamKey);
|
|
||||||
//
|
|
||||||
// log.debug("destroyed old redis stream listener container is [ {} ]",
|
|
||||||
// streamMessageListenerContainer);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// // double destroy
|
|
||||||
// SpringUtils.destroyBean(streamMessageListenerContainer);
|
|
||||||
// streamMessageListenerContainer.stop();
|
|
||||||
// // help gc
|
|
||||||
// streamMessageListenerContainer = null;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
package io.wdd.rpc.execute.result;
|
|
||||||
|
|
||||||
import io.wdd.rpc.execute.config.CommandReaderConfig;
|
|
||||||
import io.wdd.rpc.execute.config.ExecutionResultStringDeserializer;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.data.redis.connection.stream.MapRecord;
|
|
||||||
import org.springframework.data.redis.connection.stream.RecordId;
|
|
||||||
import org.springframework.data.redis.stream.StreamListener;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Slf4j
|
|
||||||
public class CommandResultReader implements StreamListener<String, MapRecord<String, String, String>> {
|
|
||||||
|
|
||||||
// https://medium.com/nerd-for-tech/event-driven-architecture-with-redis-streams-using-spring-boot-a81a1c9a4cde
|
|
||||||
|
|
||||||
//https://segmentfault.com/a/1190000040946712
|
|
||||||
|
|
||||||
//https://docs.spring.io/spring-data/redis/docs/2.5.5/reference/html/#redis.streams.receive.containers
|
|
||||||
|
|
||||||
|
|
||||||
private CommandReaderConfig commandReaderConfig;
|
|
||||||
|
|
||||||
public CommandResultReader(String consumerType, String group, String consumerName) {
|
|
||||||
new CommandResultReader(consumerType,
|
|
||||||
group,
|
|
||||||
consumerName,
|
|
||||||
null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommandResultReader(String consumerType, String group, String consumerName, ArrayList<String> executionResult) {
|
|
||||||
this.commandReaderConfig = CommandReaderConfig
|
|
||||||
.builder()
|
|
||||||
.consumerName(consumerName)
|
|
||||||
.group(group)
|
|
||||||
.consumerType(consumerType)
|
|
||||||
.ExecutionResult(executionResult)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public CommandResultReader(CommandReaderConfig commandReaderConfig) {
|
|
||||||
|
|
||||||
this.commandReaderConfig = commandReaderConfig;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMessage(MapRecord<String, String, String> message) {
|
|
||||||
|
|
||||||
String streamKey = message.getStream();
|
|
||||||
RecordId messageId = message.getId();
|
|
||||||
String key = (String) message.getValue()
|
|
||||||
.keySet()
|
|
||||||
.toArray()[0];
|
|
||||||
String value = message.getValue()
|
|
||||||
.get(key);
|
|
||||||
|
|
||||||
|
|
||||||
ArrayList<String> executionResultFormat = ExecutionResultStringDeserializer.format(value);
|
|
||||||
|
|
||||||
// 赋值给外部的结果,是的执行的结果可以被拿到
|
|
||||||
this.commandReaderConfig.setExecutionResult(executionResultFormat);
|
|
||||||
this.commandReaderConfig.setRecordId(String.valueOf(messageId));
|
|
||||||
|
|
||||||
log.info("Octopus Agent [ {} ] execution of [ {} ] Time is [ {} ] stream recordId is [{}]",
|
|
||||||
streamKey,
|
|
||||||
executionResultFormat.get(1),
|
|
||||||
key,
|
|
||||||
messageId);
|
|
||||||
// print to console
|
|
||||||
executionResultFormat
|
|
||||||
.stream()
|
|
||||||
.forEach(
|
|
||||||
System.out::println
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
//package io.wdd.rpc.execute.result;
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//import io.wdd.rpc.scheduler.service.status.AgentStatusStreamReader;
|
|
||||||
//import lombok.Getter;
|
|
||||||
//import lombok.Setter;
|
|
||||||
//import lombok.extern.slf4j.Slf4j;
|
|
||||||
//import org.springframework.context.annotation.Bean;
|
|
||||||
//import org.springframework.context.annotation.Configuration;
|
|
||||||
//import org.springframework.context.annotation.Lazy;
|
|
||||||
//import org.springframework.context.annotation.Scope;
|
|
||||||
//import org.springframework.data.redis.connection.RedisConnectionFactory;
|
|
||||||
//import org.springframework.data.redis.connection.stream.MapRecord;
|
|
||||||
//import org.springframework.data.redis.connection.stream.ReadOffset;
|
|
||||||
//import org.springframework.data.redis.connection.stream.StreamOffset;
|
|
||||||
//import org.springframework.data.redis.stream.StreamMessageListenerContainer;
|
|
||||||
//
|
|
||||||
//import javax.annotation.Resource;
|
|
||||||
//import java.time.Duration;
|
|
||||||
//import java.util.ArrayList;
|
|
||||||
//
|
|
||||||
//@Configuration
|
|
||||||
//@Slf4j
|
|
||||||
//@Getter
|
|
||||||
//@Setter
|
|
||||||
//public class RedisStreamReaderConfig {
|
|
||||||
//
|
|
||||||
// @Resource
|
|
||||||
// private RedisConnectionFactory redisConnectionFactory;
|
|
||||||
//
|
|
||||||
// public static final String COMMAND_RESULT_REDIS_STREAM_LISTENER_CONTAINER = "commandResultRedisStreamListenerContainer";
|
|
||||||
//
|
|
||||||
// public static final String EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER = "executionResultRedisStreamListenerContainer";
|
|
||||||
//
|
|
||||||
// public static final String AGENT_STATUS_REDIS_STREAM_LISTENER_CONTAINER = "agentStatusRedisStreamListenerContainer";
|
|
||||||
//
|
|
||||||
// public static final String REDIS_STREAM_LISTENER_CONSUMER_NAME = "OctopusServer";
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * used in old model
|
|
||||||
// */
|
|
||||||
// private String streamKey = "cccc";
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * no use
|
|
||||||
// */
|
|
||||||
// private ArrayList<String> executionResult = null;
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// @Bean(value = EXECUTION_RESULT_REDIS_STREAM_LISTENER_CONTAINER)
|
|
||||||
// @Lazy
|
|
||||||
// public StreamMessageListenerContainer<String, MapRecord<String, String, String>> executionResultRedisStreamListenerContainer(){
|
|
||||||
//
|
|
||||||
// StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, MapRecord<String, String, String>> options = StreamMessageListenerContainer.StreamMessageListenerContainerOptions
|
|
||||||
// .builder()
|
|
||||||
// .pollTimeout(Duration.ofSeconds(2))
|
|
||||||
// .build();
|
|
||||||
//
|
|
||||||
// StreamMessageListenerContainer<String, MapRecord<String, String, String>> listenerContainer = StreamMessageListenerContainer.create(redisConnectionFactory, options);
|
|
||||||
//
|
|
||||||
// return listenerContainer;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// @Bean(value = COMMAND_RESULT_REDIS_STREAM_LISTENER_CONTAINER)
|
|
||||||
// @Scope("prototype")
|
|
||||||
// @Lazy
|
|
||||||
// public StreamMessageListenerContainer<String, MapRecord<String, String, String>> commandResultRedisStreamListenerContainer(){
|
|
||||||
//
|
|
||||||
// StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, MapRecord<String, String, String>> options = StreamMessageListenerContainer.StreamMessageListenerContainerOptions
|
|
||||||
// .builder()
|
|
||||||
// .pollTimeout(Duration.ofSeconds(2))
|
|
||||||
// .build();
|
|
||||||
//
|
|
||||||
// StreamMessageListenerContainer<String, MapRecord<String, String, String>> listenerContainer = StreamMessageListenerContainer.create(redisConnectionFactory, options);
|
|
||||||
//
|
|
||||||
// // todo 此部分可以被移出到另外的位置,会更加方便,就不需要对此Bean进行创建和销毁了
|
|
||||||
// listenerContainer.receive(
|
|
||||||
//
|
|
||||||
// StreamOffset.create(streamKey, ReadOffset.lastConsumed()),
|
|
||||||
//
|
|
||||||
// new CommandResultReader(
|
|
||||||
// REDIS_STREAM_LISTENER_CONSUMER_NAME,
|
|
||||||
// streamKey,
|
|
||||||
// REDIS_STREAM_LISTENER_CONSUMER_NAME,
|
|
||||||
// executionResult
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// return listenerContainer;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Bean(value = AGENT_STATUS_REDIS_STREAM_LISTENER_CONTAINER)
|
|
||||||
// @Scope("prototype")
|
|
||||||
// @Lazy
|
|
||||||
// public StreamMessageListenerContainer<String, MapRecord<String, String, String>> agentStatusRedisStreamListenerContainer(){
|
|
||||||
//
|
|
||||||
// StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, MapRecord<String, String, String>> options = StreamMessageListenerContainer.StreamMessageListenerContainerOptions
|
|
||||||
// .builder()
|
|
||||||
// .pollTimeout(Duration.ofSeconds(2))
|
|
||||||
// .build();
|
|
||||||
//
|
|
||||||
// StreamMessageListenerContainer<String, MapRecord<String, String, String>> listenerContainer = StreamMessageListenerContainer.create(redisConnectionFactory, options);
|
|
||||||
//
|
|
||||||
// listenerContainer.receive(
|
|
||||||
//
|
|
||||||
// StreamOffset.create(streamKey, ReadOffset.lastConsumed()),
|
|
||||||
//
|
|
||||||
// new AgentStatusStreamReader(
|
|
||||||
// REDIS_STREAM_LISTENER_CONSUMER_NAME,
|
|
||||||
// REDIS_STREAM_LISTENER_CONSUMER_NAME,
|
|
||||||
// REDIS_STREAM_LISTENER_CONSUMER_NAME)
|
|
||||||
//
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// return listenerContainer;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
@@ -1,92 +1,16 @@
|
|||||||
package io.wdd.rpc.execute.service;
|
package io.wdd.rpc.execute.service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import io.wdd.rpc.message.OctopusMessage;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
|
||||||
* 同步命令执行的核心类
|
|
||||||
* 需要等待命令执行完毕,完后返回相应的结果
|
|
||||||
*/
|
|
||||||
public interface AsyncExecutionService {
|
public interface AsyncExecutionService {
|
||||||
|
|
||||||
/**
|
List<OctopusMessage> AsyncCallSendCommandToAgent(
|
||||||
* ------------------------ Sync Command Executor ------------------------------
|
List<String> agentTopicNameList,
|
||||||
*/
|
|
||||||
ArrayList<String> AsyncSendCommandToAgent(String agentTopicName, List<String> commandList);
|
|
||||||
|
|
||||||
ArrayList<String> AsyncSendCommandToAgent(String agentTopicName, String type, List<String> commandList);
|
|
||||||
|
|
||||||
List<ArrayList<String>> AsyncSendCommandToAgent(List<String> agentTopicNameList, String type, List<String> commandList);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 调用 单行命令脚本的 最底层函数
|
|
||||||
*
|
|
||||||
* @param agentTopicName
|
|
||||||
* @param type
|
|
||||||
* @param commandList
|
|
||||||
* @param needResultReplay
|
|
||||||
* @param futureKey
|
|
||||||
* @param durationTask
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ArrayList<String> AsyncSendCommandToAgent(
|
|
||||||
String agentTopicName,
|
|
||||||
String type,
|
|
||||||
List<String> commandList,
|
|
||||||
boolean needResultReplay,
|
|
||||||
String futureKey,
|
|
||||||
boolean durationTask
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* -------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
ArrayList<String> AsyncSendCommandToAgentComplete(String agentTopicName, String type, List<String> commandList, List<List<String>> completeCommandList);
|
|
||||||
|
|
||||||
List<ArrayList<String>> AsyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<String> commandList, List<List<String>> completeCommandList, boolean isDurationTask);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通常为 页面定时脚本任务调用
|
|
||||||
*
|
|
||||||
* @param agentTopicNameList 目标Agent的TopicName列表
|
|
||||||
* @param type 任务类型
|
|
||||||
* @param completeCommandList 完整的类型
|
|
||||||
* @return 每个Agent只返回一个 ResultKey(Script脚本的结果全部拼接到一起),全部的resultKey
|
|
||||||
*/
|
|
||||||
List<ArrayList<String>> AsyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<List<String>> completeCommandList);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通常为 页面定时脚本任务调用
|
|
||||||
*
|
|
||||||
* @param agentTopicNameList 目标Agent的TopicName列表
|
|
||||||
* @param type 任务类型
|
|
||||||
* @param completeCommandList 完整的类型
|
|
||||||
* @param atnFutureKey 由于脚本任务为延迟调用,故需要提前生成未来的ResultKey
|
|
||||||
* @return 每个Agent只返回一个 ResultKey(Script脚本的结果全部拼接到一起),全部的resultKey
|
|
||||||
*/
|
|
||||||
List<ArrayList<String>> AsyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<List<String>> completeCommandList, HashMap<String, String> atnFutureKey);
|
|
||||||
|
|
||||||
|
|
||||||
ArrayList<String> AsyncSendCommandToAgent(String agentTopicName, String type, List<String> commandList, List<List<String>> commandListComplete, String futureKey);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 调用 完整脚本的 最底层函数
|
|
||||||
*
|
|
||||||
* @param agentTopicName
|
|
||||||
* @param type
|
|
||||||
* @param commandList
|
|
||||||
* @param commandListComplete
|
|
||||||
* @param futureKey
|
|
||||||
* @param durationTask
|
|
||||||
* @return resultKey 本次操作在Redis中记录的结果Key
|
|
||||||
*/
|
|
||||||
ArrayList<String> AsyncSendCommandToAgentComplete(
|
|
||||||
String agentTopicName,
|
|
||||||
String type,
|
String type,
|
||||||
|
List<String> funcContent,
|
||||||
List<String> commandList,
|
List<String> commandList,
|
||||||
List<List<String>> commandListComplete,
|
List<List<String>> commandListComplete,
|
||||||
boolean needResultReplay,
|
boolean needResultReplay,
|
||||||
@@ -94,4 +18,30 @@ public interface AsyncExecutionService {
|
|||||||
boolean durationTask
|
boolean durationTask
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步命令调用的方法
|
||||||
|
*
|
||||||
|
* @param agentTopicName
|
||||||
|
* @param type
|
||||||
|
* @param funcContent
|
||||||
|
* @param commandList
|
||||||
|
* @param commandListComplete
|
||||||
|
* @param needResultReplay
|
||||||
|
* @param futureKey
|
||||||
|
* @param durationTask
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
OctopusMessage AsyncCallSendCommandToAgent(
|
||||||
|
String agentTopicName,
|
||||||
|
String type,
|
||||||
|
List<String> funcContent,
|
||||||
|
List<String> commandList,
|
||||||
|
List<List<String>> commandListComplete,
|
||||||
|
boolean needResultReplay,
|
||||||
|
String futureKey,
|
||||||
|
boolean durationTask
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,256 +1,152 @@
|
|||||||
package io.wdd.rpc.execute.service;
|
package io.wdd.rpc.execute.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.wdd.common.utils.TimeUtils;
|
||||||
|
import io.wdd.rpc.execute.ExecutionMessage;
|
||||||
import io.wdd.rpc.message.OctopusMessage;
|
import io.wdd.rpc.message.OctopusMessage;
|
||||||
import io.wdd.rpc.message.OctopusMessageType;
|
import io.wdd.rpc.message.OctopusMessageType;
|
||||||
import io.wdd.rpc.message.handler.async.AsyncWaitOctopusMessageResultService;
|
import io.wdd.rpc.message.sender.OMessageToAgentSender;
|
||||||
import io.wdd.rpc.message.handler.async.OctopusMessageSynScReplayContend;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
import static io.wdd.rpc.status.CommonAndStatusCache.ALL_AGENT_TOPIC_NAME_SET;
|
||||||
|
|
||||||
|
|
||||||
|
//@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AsyncExecutionServiceImpl implements AsyncExecutionService {
|
public class AsyncExecutionServiceImpl implements AsyncExecutionService {
|
||||||
|
|
||||||
private static final boolean COMMAND_EXEC_NEED_REPLAY = true;
|
private static final String MANUAL_COMMAND_TYPE = "manual-command";
|
||||||
|
|
||||||
private static final OctopusMessageType CurrentAppOctopusMessageType = OctopusMessageType.EXECUTOR;
|
|
||||||
@Resource
|
@Resource
|
||||||
AsyncWaitOctopusMessageResultService asyncWaitOctopusMessageResultService;
|
OMessageToAgentSender oMessageToAgentSender;
|
||||||
@Resource
|
@Resource
|
||||||
SyncExecutionService asyncExecutionService;
|
ObjectMapper objectMapper;
|
||||||
|
@Resource
|
||||||
|
RedisTemplate redisTemplate;
|
||||||
|
|
||||||
/**
|
|
||||||
* 一个命令执行的最长等待时间
|
|
||||||
*/
|
|
||||||
int processMaxWaitSeconds = 10;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayList<String> AsyncSendCommandToAgent(String agentTopicName, List<String> commandList) {
|
public List<OctopusMessage> AsyncCallSendCommandToAgent(List<String> agentTopicNameList, String type, List<String> funcContent, List<String> commandList, List<List<String>> commandListComplete, boolean needResultReplay, String futureKey, boolean durationTask) {
|
||||||
|
|
||||||
return this.AsyncSendCommandToAgentComplete(
|
|
||||||
agentTopicName,
|
|
||||||
null,
|
|
||||||
commandList,
|
|
||||||
null,
|
|
||||||
COMMAND_EXEC_NEED_REPLAY,
|
|
||||||
null,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayList<String> AsyncSendCommandToAgent(String agentTopicName, String type, List<String> commandList) {
|
|
||||||
|
|
||||||
|
|
||||||
return this.AsyncSendCommandToAgentComplete(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
null,
|
|
||||||
COMMAND_EXEC_NEED_REPLAY,
|
|
||||||
null,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ArrayList<String>> AsyncSendCommandToAgent(List<String> agentTopicNameList, String type, List<String> commandList) {
|
|
||||||
|
|
||||||
return agentTopicNameList
|
return agentTopicNameList
|
||||||
.stream()
|
.stream()
|
||||||
.map(
|
.map(
|
||||||
agentTopicName -> this.AsyncSendCommandToAgentComplete(
|
agentTopicName -> {
|
||||||
agentTopicName,
|
return this.AsyncCallSendCommandToAgent(
|
||||||
type,
|
agentTopicName,
|
||||||
commandList,
|
type,
|
||||||
null,
|
funcContent,
|
||||||
COMMAND_EXEC_NEED_REPLAY,
|
commandList,
|
||||||
null,
|
commandListComplete,
|
||||||
false
|
needResultReplay,
|
||||||
)
|
futureKey,
|
||||||
|
durationTask
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayList<String> AsyncSendCommandToAgent(String agentTopicName, String type, List<String> commandList, boolean needResultReplay, String futureKey, boolean durationTask) {
|
public OctopusMessage AsyncCallSendCommandToAgent(String agentTopicName, String type, List<String> funcContent, List<String> commandList, List<List<String>> commandListComplete, boolean needResultReplay, String futureKey, boolean durationTask) {
|
||||||
|
|
||||||
return this.AsyncSendCommandToAgentComplete(
|
// 检查agentTopicName是否存在
|
||||||
agentTopicName,
|
if (!ALL_AGENT_TOPIC_NAME_SET.contains(agentTopicName)) {
|
||||||
type,
|
log.error(
|
||||||
commandList,
|
"agentTopicName异常! 输入为 => {}",
|
||||||
null,
|
agentTopicName
|
||||||
COMMAND_EXEC_NEED_REPLAY,
|
|
||||||
futureKey,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayList<String> AsyncSendCommandToAgentComplete(String agentTopicName, String type, List<String> commandList, List<List<String>> completeCommandList) {
|
|
||||||
return this.AsyncSendCommandToAgentComplete(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
completeCommandList,
|
|
||||||
COMMAND_EXEC_NEED_REPLAY,
|
|
||||||
null,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ArrayList<String>> AsyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<String> commandList, List<List<String>> completeCommandList, boolean isDurationTask) {
|
|
||||||
return agentTopicNameList
|
|
||||||
.stream()
|
|
||||||
.map(
|
|
||||||
agentTopicName -> this.AsyncSendCommandToAgentComplete(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
completeCommandList,
|
|
||||||
COMMAND_EXEC_NEED_REPLAY,
|
|
||||||
null,
|
|
||||||
isDurationTask
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ArrayList<String>> AsyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<List<String>> completeCommandList) {
|
|
||||||
|
|
||||||
return agentTopicNameList
|
|
||||||
.stream()
|
|
||||||
.map(
|
|
||||||
agentTopicName -> this.AsyncSendCommandToAgentComplete(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
null,
|
|
||||||
completeCommandList,
|
|
||||||
COMMAND_EXEC_NEED_REPLAY,
|
|
||||||
null,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ArrayList<String>> AsyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<List<String>> completeCommandList, HashMap<String, String> atnFutureKey) {
|
|
||||||
return agentTopicNameList
|
|
||||||
.stream()
|
|
||||||
.map(
|
|
||||||
agentTopicName -> this.AsyncSendCommandToAgentComplete(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
null,
|
|
||||||
completeCommandList,
|
|
||||||
COMMAND_EXEC_NEED_REPLAY,
|
|
||||||
atnFutureKey.get(agentTopicName),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayList<String> AsyncSendCommandToAgent(String agentTopicName, String type, List<String> commandList, List<List<String>> commandListComplete, String futureKey) {
|
|
||||||
return this.AsyncSendCommandToAgentComplete(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
commandListComplete,
|
|
||||||
COMMAND_EXEC_NEED_REPLAY,
|
|
||||||
futureKey,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayList<String> AsyncSendCommandToAgentComplete(String agentTopicName, String type, List<String> commandList, List<List<String>> commandListComplete, boolean needResultReplay, String futureKey, boolean durationTask) {
|
|
||||||
|
|
||||||
OctopusMessage octopusMessage = asyncExecutionService.AsyncCallSendCommandToAgent(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
commandListComplete,
|
|
||||||
needResultReplay,
|
|
||||||
futureKey,
|
|
||||||
durationTask
|
|
||||||
);
|
|
||||||
|
|
||||||
LocalDateTime initTime = octopusMessage.getInit_time();
|
|
||||||
|
|
||||||
// OM 中的result保存
|
|
||||||
ArrayList<String> result = new ArrayList<>();
|
|
||||||
|
|
||||||
// 构造消息等待对象
|
|
||||||
int commandCount = 1;
|
|
||||||
if (null != commandListComplete) {
|
|
||||||
commandCount = Math.max(
|
|
||||||
commandListComplete.size(),
|
|
||||||
1
|
|
||||||
);
|
);
|
||||||
|
return null;
|
||||||
|
//throw new MyRuntimeException("agentTopicName异常!" + agentTopicName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构造回复信息的内容
|
// 归一化type
|
||||||
OctopusMessageSynScReplayContend executionReplayContent = OctopusMessageSynScReplayContend.build(
|
if (StringUtils.isEmpty(type)) {
|
||||||
commandCount,
|
type = MANUAL_COMMAND_TYPE;
|
||||||
CurrentAppOctopusMessageType,
|
}
|
||||||
initTime
|
|
||||||
|
String resultKey = futureKey;
|
||||||
|
// 判定是否是 FutureKey
|
||||||
|
if (null == futureKey) {
|
||||||
|
resultKey = ExecutionMessage.GetResultKey(agentTopicName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造 Execution Command对应的消息体
|
||||||
|
ExecutionMessage executionMessage = this
|
||||||
|
.generateExecutionMessage(
|
||||||
|
type,
|
||||||
|
commandList,
|
||||||
|
resultKey,
|
||||||
|
commandListComplete,
|
||||||
|
needResultReplay,
|
||||||
|
durationTask
|
||||||
|
);
|
||||||
|
OctopusMessage octopusMessage = this.generateOctopusMessage(
|
||||||
|
agentTopicName,
|
||||||
|
executionMessage
|
||||||
);
|
);
|
||||||
CountDownLatch countDownLatch = executionReplayContent.getCountDownLatch();
|
|
||||||
|
|
||||||
// 开始等待结果
|
// send the message
|
||||||
asyncWaitOctopusMessageResultService.waitFor(executionReplayContent);
|
oMessageToAgentSender.send(octopusMessage);
|
||||||
|
|
||||||
|
// set up the stream read group
|
||||||
|
String group = redisTemplate
|
||||||
|
.opsForStream()
|
||||||
|
.createGroup(
|
||||||
|
resultKey,
|
||||||
|
resultKey
|
||||||
|
);
|
||||||
|
|
||||||
|
log.debug(
|
||||||
|
"set consumer group [{}] for the stream key with => [ {} ]",
|
||||||
|
group,
|
||||||
|
resultKey
|
||||||
|
);
|
||||||
|
|
||||||
|
// help gc
|
||||||
|
executionMessage = null;
|
||||||
|
|
||||||
|
return octopusMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OctopusMessage generateOctopusMessage(String agentTopicName, ExecutionMessage executionMessage) {
|
||||||
|
|
||||||
// 监听结果
|
|
||||||
try {
|
try {
|
||||||
boolean await = countDownLatch.await(
|
|
||||||
processMaxWaitSeconds,
|
|
||||||
TimeUnit.SECONDS
|
|
||||||
);
|
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
return OctopusMessage
|
||||||
throw new RuntimeException(e);
|
.builder()
|
||||||
} finally {
|
.octopusMessageType(OctopusMessageType.EXECUTOR)
|
||||||
|
.init_time(TimeUtils.currentFormatTime())
|
||||||
// 等待所有的结果返回
|
.uuid(agentTopicName)
|
||||||
// 停止等待结果
|
.content(
|
||||||
asyncWaitOctopusMessageResultService.stopWaiting(executionReplayContent);
|
objectMapper.writeValueAsString(executionMessage)
|
||||||
|
|
||||||
// 解析结果
|
|
||||||
executionReplayContent
|
|
||||||
.getReplayOMList()
|
|
||||||
.stream()
|
|
||||||
.map(
|
|
||||||
om -> {
|
|
||||||
log.debug(
|
|
||||||
"replay message is => {}",
|
|
||||||
om
|
|
||||||
);
|
|
||||||
|
|
||||||
return (ArrayList<String>) om.getResult();
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
.forEachOrdered(
|
.build();
|
||||||
singleResult -> result.addAll(singleResult)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回 执行的结果
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExecutionMessage generateExecutionMessage(String type, List<String> commandList, String resultKey, List<List<String>> commandListComplete, boolean needResultReplay, boolean durationTask) {
|
||||||
|
|
||||||
|
return ExecutionMessage
|
||||||
|
.builder()
|
||||||
|
.resultKey(resultKey)
|
||||||
|
.type(type)
|
||||||
|
.singleLineCommand(commandList)
|
||||||
|
.multiLineCommand(commandListComplete)
|
||||||
|
.needResultReplay(needResultReplay)
|
||||||
|
.durationTask(durationTask)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,82 +1,18 @@
|
|||||||
package io.wdd.rpc.execute.service;
|
package io.wdd.rpc.execute.service;
|
||||||
|
|
||||||
import io.wdd.rpc.message.OctopusMessage;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步命令执行的核心类
|
||||||
|
* 需要等待命令执行完毕,完后返回相应的结果
|
||||||
|
*/
|
||||||
public interface SyncExecutionService {
|
public interface SyncExecutionService {
|
||||||
|
|
||||||
String SyncSendCommandToAgent(String agentTopicName, String command);
|
List<ArrayList<String>> SyncSendCommandToAgentComplete(
|
||||||
|
List<String> agentTopicNameList,
|
||||||
String SyncSendCommandToAgent(String agentTopicName, List<String> commandList);
|
|
||||||
|
|
||||||
String SyncSendCommandToAgent(String agentTopicName, String type, List<String> commandList);
|
|
||||||
|
|
||||||
List<String> SyncSendCommandToAgent(List<String> agentTopicNameList, String type, List<String> commandList, boolean needResultReplay, String futureKey, boolean durationTask);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 调用 单行命令脚本的 最底层函数
|
|
||||||
*
|
|
||||||
* @param agentTopicName
|
|
||||||
* @param type
|
|
||||||
* @param commandList
|
|
||||||
* @param needResultReplay
|
|
||||||
* @param futureKey
|
|
||||||
* @param durationTask
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
String SyncSendCommandToAgent(
|
|
||||||
String agentTopicName,
|
|
||||||
String type,
|
|
||||||
List<String> commandList,
|
|
||||||
boolean needResultReplay,
|
|
||||||
String futureKey,
|
|
||||||
boolean durationTask
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* -------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
String SyncSendCommandToAgentComplete(String agentTopicName, String type, List<String> commandList, List<List<String>> commandListComplete);
|
|
||||||
|
|
||||||
|
|
||||||
List<String> SyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<String> commandList, List<List<String>> commandListComplete, boolean isDurationTask);
|
|
||||||
|
|
||||||
|
|
||||||
List<String> SyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<List<String>> completeCommandList);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通常为 页面定时脚本任务调用
|
|
||||||
*
|
|
||||||
* @param agentTopicNameList 目标Agent的TopicName列表
|
|
||||||
* @param type 任务类型
|
|
||||||
* @param completeCommandList 完整的类型
|
|
||||||
* @param atnFutureKey 由于脚本任务为延迟调用,故需要提前生成未来的ResultKey
|
|
||||||
* @return 每个Agent只返回一个 ResultKey(Script脚本的结果全部拼接到一起),全部的resultKey
|
|
||||||
*/
|
|
||||||
List<String> SyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<List<String>> completeCommandList, HashMap<String, String> atnFutureKey);
|
|
||||||
|
|
||||||
|
|
||||||
String SyncSendCommandToAgent(String agentTopicName, String type, List<String> commandList, List<List<String>> commandListComplete, String futureKey);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 调用 完整脚本的 最底层函数
|
|
||||||
*
|
|
||||||
* @param agentTopicName
|
|
||||||
* @param type
|
|
||||||
* @param commandList
|
|
||||||
* @param commandListComplete
|
|
||||||
* @param futureKey
|
|
||||||
* @param durationTask
|
|
||||||
* @return resultKey 本次操作在Redis中记录的结果Key
|
|
||||||
*/
|
|
||||||
String SyncSendCommandToAgent(
|
|
||||||
String agentTopicName,
|
|
||||||
String type,
|
String type,
|
||||||
|
List<String> funcContent,
|
||||||
List<String> commandList,
|
List<String> commandList,
|
||||||
List<List<String>> commandListComplete,
|
List<List<String>> commandListComplete,
|
||||||
boolean needResultReplay,
|
boolean needResultReplay,
|
||||||
@@ -86,20 +22,21 @@ public interface SyncExecutionService {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同步命令调用的方法
|
* 调用 完整脚本的 最底层函数
|
||||||
*
|
*
|
||||||
* @param agentTopicName
|
* @param agentTopicName
|
||||||
* @param type
|
* @param type
|
||||||
|
* @param funcContent
|
||||||
* @param commandList
|
* @param commandList
|
||||||
* @param commandListComplete
|
* @param commandListComplete
|
||||||
* @param needResultReplay
|
|
||||||
* @param futureKey
|
* @param futureKey
|
||||||
* @param durationTask
|
* @param durationTask
|
||||||
* @return
|
* @return resultKey 本次操作在Redis中记录的结果Key
|
||||||
*/
|
*/
|
||||||
OctopusMessage AsyncCallSendCommandToAgent(
|
ArrayList<String> SyncSendCommandToAgentComplete(
|
||||||
String agentTopicName,
|
String agentTopicName,
|
||||||
String type,
|
String type,
|
||||||
|
List<String> funcContent,
|
||||||
List<String> commandList,
|
List<String> commandList,
|
||||||
List<List<String>> commandListComplete,
|
List<List<String>> commandListComplete,
|
||||||
boolean needResultReplay,
|
boolean needResultReplay,
|
||||||
|
|||||||
@@ -1,370 +1,135 @@
|
|||||||
package io.wdd.rpc.execute.service;
|
package io.wdd.rpc.execute.service;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import io.wdd.common.utils.TimeUtils;
|
|
||||||
import io.wdd.rpc.execute.ExecutionMessage;
|
|
||||||
import io.wdd.rpc.execute.config.ExecutionLog;
|
|
||||||
import io.wdd.rpc.message.OctopusMessage;
|
import io.wdd.rpc.message.OctopusMessage;
|
||||||
import io.wdd.rpc.message.OctopusMessageType;
|
import io.wdd.rpc.message.OctopusMessageType;
|
||||||
import io.wdd.rpc.message.sender.OMessageToAgentSender;
|
import io.wdd.rpc.message.handler.async.AsyncWaitOctopusMessageResultService;
|
||||||
|
import io.wdd.rpc.message.handler.async.OctopusMessageSyncReplayContend;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.HashMap;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static io.wdd.rpc.status.CommonAndStatusCache.ALL_AGENT_TOPIC_NAME_SET;
|
//@Service
|
||||||
|
|
||||||
|
|
||||||
@Service
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SyncExecutionServiceImpl implements SyncExecutionService {
|
public class SyncExecutionServiceImpl implements SyncExecutionService {
|
||||||
|
|
||||||
private static final String MANUAL_COMMAND_TYPE = "manual-command";
|
private static final boolean COMMAND_EXEC_NEED_REPLAY = true;
|
||||||
|
|
||||||
|
private static final OctopusMessageType CurrentAppOctopusMessageType = OctopusMessageType.EXECUTOR;
|
||||||
@Resource
|
@Resource
|
||||||
OMessageToAgentSender oMessageToAgentSender;
|
AsyncWaitOctopusMessageResultService asyncWaitOctopusMessageResultService;
|
||||||
@Resource
|
@Resource
|
||||||
ObjectMapper objectMapper;
|
AsyncExecutionService asyncExecutionService;
|
||||||
@Resource
|
|
||||||
RedisTemplate redisTemplate;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String SyncSendCommandToAgent(String agentTopicName, String command) {
|
|
||||||
return this.SyncSendCommandToAgent(
|
|
||||||
agentTopicName,
|
|
||||||
List.of(command)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String SyncSendCommandToAgent(String agentTopicName, List<String> commandList) {
|
|
||||||
return this.SyncSendCommandToAgent(
|
|
||||||
agentTopicName,
|
|
||||||
MANUAL_COMMAND_TYPE,
|
|
||||||
commandList
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String SyncSendCommandToAgent(String agentTopicName, String type, List<String> commandList) {
|
|
||||||
|
|
||||||
return SyncSendCommandToAgent(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
false,
|
|
||||||
null,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String SyncSendCommandToAgent(String agentTopicName, String type, List<String> commandList, boolean needResultReplay, String futureKey, boolean durationTask) {
|
|
||||||
|
|
||||||
return this.SyncSendCommandToAgent(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
null,
|
|
||||||
needResultReplay,
|
|
||||||
futureKey,
|
|
||||||
durationTask
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String SyncSendCommandToAgentComplete(String agentTopicName, String type, List<String> commandList, List<List<String>> commandListComplete) {
|
|
||||||
|
|
||||||
return this.SyncSendCommandToAgent(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
commandListComplete,
|
|
||||||
false,
|
|
||||||
null,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> SyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<String> commandList, List<List<String>> commandListComplete, boolean isDurationTask) {
|
|
||||||
return agentTopicNameList
|
|
||||||
.stream()
|
|
||||||
.map(
|
|
||||||
agentTopicName -> this.SyncSendCommandToAgent(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
commandListComplete,
|
|
||||||
false,
|
|
||||||
null,
|
|
||||||
isDurationTask
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String SyncSendCommandToAgent(String agentTopicName, String type, List<String> commandList, List<List<String>> commandListComplete, String futureKey) {
|
|
||||||
|
|
||||||
return this.SyncSendCommandToAgent(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
commandListComplete,
|
|
||||||
false,
|
|
||||||
futureKey,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String SyncSendCommandToAgent(String agentTopicName, String type, List<String> commandList, List<List<String>> commandListComplete, boolean needResultReplay, String futureKey, boolean durationTask) {
|
|
||||||
|
|
||||||
String resultKey = futureKey;
|
|
||||||
// 判定是否是 FutureKey
|
|
||||||
if (null == futureKey) {
|
|
||||||
resultKey = ExecutionMessage.GetResultKey(agentTopicName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 调用最底层的方法
|
|
||||||
this.AsyncCallSendCommandToAgent(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
commandListComplete,
|
|
||||||
needResultReplay,
|
|
||||||
futureKey,
|
|
||||||
durationTask
|
|
||||||
);
|
|
||||||
|
|
||||||
return resultKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OctopusMessage AsyncCallSendCommandToAgent(String agentTopicName, String type, List<String> commandList, List<List<String>> commandListComplete, boolean needResultReplay, String futureKey, boolean durationTask) {
|
|
||||||
|
|
||||||
// 检查agentTopicName是否存在
|
|
||||||
if (!ALL_AGENT_TOPIC_NAME_SET.contains(agentTopicName)) {
|
|
||||||
log.error(
|
|
||||||
"agentTopicName异常! 输入为 => {}",
|
|
||||||
agentTopicName
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
//throw new MyRuntimeException("agentTopicName异常!" + agentTopicName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 归一化type
|
|
||||||
if (StringUtils.isEmpty(type)) {
|
|
||||||
type = MANUAL_COMMAND_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
String resultKey = futureKey;
|
|
||||||
// 判定是否是 FutureKey
|
|
||||||
if (null == futureKey) {
|
|
||||||
resultKey = ExecutionMessage.GetResultKey(agentTopicName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构造 Execution Command对应的消息体
|
|
||||||
ExecutionMessage executionMessage = this
|
|
||||||
.generateExecutionMessage(
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
resultKey,
|
|
||||||
commandListComplete,
|
|
||||||
needResultReplay,
|
|
||||||
durationTask
|
|
||||||
);
|
|
||||||
OctopusMessage octopusMessage = this.generateOctopusMessage(
|
|
||||||
agentTopicName,
|
|
||||||
executionMessage
|
|
||||||
);
|
|
||||||
|
|
||||||
// send the message
|
|
||||||
oMessageToAgentSender.send(octopusMessage);
|
|
||||||
|
|
||||||
// set up the stream read group
|
|
||||||
String group = redisTemplate
|
|
||||||
.opsForStream()
|
|
||||||
.createGroup(
|
|
||||||
resultKey,
|
|
||||||
resultKey
|
|
||||||
);
|
|
||||||
|
|
||||||
log.debug(
|
|
||||||
"set consumer group [{}] for the stream key with => [ {} ]",
|
|
||||||
group,
|
|
||||||
resultKey
|
|
||||||
);
|
|
||||||
|
|
||||||
// change the redis stream listener container
|
|
||||||
// createStreamReader.registerStreamReader(COMMAND_RESULT_REDIS_STREAM_LISTENER_CONTAINER, resultKey);
|
|
||||||
|
|
||||||
// construct the persistent Bean
|
|
||||||
/*ExecutionLog executionLog = buildPersistentLogBeanFromOctopusMessage(
|
|
||||||
octopusMessage,
|
|
||||||
executionMessage
|
|
||||||
);*/
|
|
||||||
// send resultKey to ExecutionResultDaemonHandler
|
|
||||||
// 当批量执行,产生大量的resultKey的时候,会出现线程爆炸,导致所有的全部失效
|
|
||||||
/*WAIT_EXECUTION_RESULT_LIST.put(
|
|
||||||
resultKey,
|
|
||||||
executionLog
|
|
||||||
);*/
|
|
||||||
|
|
||||||
// help gc
|
|
||||||
executionMessage = null;
|
|
||||||
|
|
||||||
return octopusMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
private OctopusMessage generateOctopusMessage(String agentTopicName, ExecutionMessage executionMessage) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
return OctopusMessage
|
|
||||||
.builder()
|
|
||||||
.type(OctopusMessageType.EXECUTOR)
|
|
||||||
.init_time(TimeUtils.currentFormatTime())
|
|
||||||
.uuid(agentTopicName)
|
|
||||||
.content(
|
|
||||||
objectMapper.writeValueAsString(executionMessage)
|
|
||||||
)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
} catch (JsonProcessingException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private ExecutionLog buildPersistentLogBeanFromOctopusMessage(OctopusMessage octopusMessage, ExecutionMessage executionMessage) {
|
|
||||||
ExecutionLog executionLog = new ExecutionLog();
|
|
||||||
executionLog.setAgentTopicName(octopusMessage.getUuid());
|
|
||||||
executionLog.setResultKey((String) octopusMessage.getContent());
|
|
||||||
executionLog.setCommandList(String.valueOf(executionMessage.getSingleLineCommand()));
|
|
||||||
executionLog.setType(executionMessage.getType());
|
|
||||||
executionLog.setResultKey(executionMessage.getResultKey());
|
|
||||||
return executionLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> SyncSendCommandToAgent(List<String> agentagentTopicNameList, String type, List<String> commandList, boolean needResultReplay, String futureKey, boolean durationTask) {
|
|
||||||
|
|
||||||
return agentagentTopicNameList
|
|
||||||
.stream()
|
|
||||||
.map(
|
|
||||||
agentTopicName -> this
|
|
||||||
.SyncSendCommandToAgent
|
|
||||||
(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
commandList,
|
|
||||||
null,
|
|
||||||
needResultReplay,
|
|
||||||
futureKey,
|
|
||||||
durationTask
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param agentTopicNameList 目标Agent的TopicName列表
|
* 一个命令执行的最长等待时间
|
||||||
* @param type 任务类型
|
|
||||||
* @param completeCommandList 完整的类型
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
|
int processMaxWaitSeconds = 10;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> SyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<List<String>> completeCommandList) {
|
public List<ArrayList<String>> SyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<String> funcContent, List<String> commandList, List<List<String>> commandListComplete, boolean needResultReplay, String futureKey, boolean durationTask) {
|
||||||
|
|
||||||
return agentTopicNameList
|
return agentTopicNameList
|
||||||
.stream()
|
.stream()
|
||||||
.map(
|
.map(
|
||||||
agentTopicName -> this.SyncSendCommandToAgentComplete(
|
agentTopicName -> {
|
||||||
agentTopicName,
|
return this.SyncSendCommandToAgentComplete(
|
||||||
type,
|
agentTopicName,
|
||||||
null,
|
type,
|
||||||
completeCommandList
|
null,
|
||||||
)
|
commandList,
|
||||||
|
commandListComplete,
|
||||||
|
needResultReplay,
|
||||||
|
futureKey,
|
||||||
|
durationTask
|
||||||
|
);
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> SyncSendCommandToAgentComplete(List<String> agentTopicNameList, String type, List<List<String>> completeCommandList, HashMap<String, String> atnFutureKey) {
|
public ArrayList<String> SyncSendCommandToAgentComplete(String agentTopicName, String type, List<String> funcContent, List<String> commandList, List<List<String>> commandListComplete, boolean needResultReplay, String futureKey, boolean durationTask) {
|
||||||
|
|
||||||
return agentTopicNameList
|
// 异步访问
|
||||||
.stream()
|
OctopusMessage octopusMessage = asyncExecutionService.AsyncCallSendCommandToAgent(
|
||||||
.map(
|
agentTopicName,
|
||||||
agentTopicName -> this.SyncSendCommandToAgent(
|
|
||||||
agentTopicName,
|
|
||||||
type,
|
|
||||||
null,
|
|
||||||
completeCommandList,
|
|
||||||
atnFutureKey.getOrDefault(
|
|
||||||
agentTopicName,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
private OctopusMessage generateOctopusMessage(String agentTopicName, String resultKey, String type, List<String> commandList, List<List<String>> commandListComplete) {
|
|
||||||
|
|
||||||
|
|
||||||
ExecutionMessage executionMessage = this.generateExecutionMessage(
|
|
||||||
type,
|
type,
|
||||||
|
null,
|
||||||
commandList,
|
commandList,
|
||||||
resultKey,
|
|
||||||
commandListComplete,
|
commandListComplete,
|
||||||
false,
|
needResultReplay,
|
||||||
false
|
futureKey,
|
||||||
|
durationTask
|
||||||
);
|
);
|
||||||
|
|
||||||
String executionMessageString;
|
LocalDateTime initTime = octopusMessage.getInit_time();
|
||||||
|
|
||||||
try {
|
// OM 中的result保存
|
||||||
executionMessageString = objectMapper.writeValueAsString(executionMessage);
|
ArrayList<String> result = new ArrayList<>();
|
||||||
|
|
||||||
} catch (JsonProcessingException e) {
|
// 构造消息等待对象
|
||||||
throw new RuntimeException(e);
|
int commandCount = 1;
|
||||||
|
if (null != commandListComplete) {
|
||||||
|
commandCount = Math.max(
|
||||||
|
commandListComplete.size(),
|
||||||
|
1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return OctopusMessage
|
// 构造回复信息的内容
|
||||||
.builder()
|
OctopusMessageSyncReplayContend executionReplayContent = OctopusMessageSyncReplayContend.build(
|
||||||
.type(OctopusMessageType.EXECUTOR)
|
commandCount,
|
||||||
.init_time(LocalDateTime.now())
|
CurrentAppOctopusMessageType,
|
||||||
.content(executionMessageString)
|
initTime
|
||||||
.uuid(agentTopicName)
|
);
|
||||||
.build();
|
CountDownLatch countDownLatch = executionReplayContent.getCountDownLatch();
|
||||||
|
|
||||||
|
// 开始等待结果
|
||||||
|
asyncWaitOctopusMessageResultService.waitFor(executionReplayContent);
|
||||||
|
|
||||||
|
// 监听结果
|
||||||
|
try {
|
||||||
|
boolean await = countDownLatch.await(
|
||||||
|
processMaxWaitSeconds,
|
||||||
|
TimeUnit.SECONDS
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
|
||||||
|
// 等待所有的结果返回
|
||||||
|
// 停止等待结果
|
||||||
|
asyncWaitOctopusMessageResultService.stopWaiting(executionReplayContent);
|
||||||
|
|
||||||
|
// 解析结果
|
||||||
|
executionReplayContent
|
||||||
|
.getReplayOMList()
|
||||||
|
.stream()
|
||||||
|
.map(
|
||||||
|
om -> {
|
||||||
|
log.debug(
|
||||||
|
"replay message is => {}",
|
||||||
|
om
|
||||||
|
);
|
||||||
|
|
||||||
|
return (ArrayList<String>) om.getResult();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.forEachOrdered(
|
||||||
|
singleResult -> result.addAll(singleResult)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回 执行的结果
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExecutionMessage generateExecutionMessage(String type, List<String> commandList, String resultKey, List<List<String>> commandListComplete, boolean needResultReplay, boolean durationTask) {
|
|
||||||
|
|
||||||
return ExecutionMessage
|
|
||||||
.builder()
|
|
||||||
.resultKey(resultKey)
|
|
||||||
.type(type)
|
|
||||||
.singleLineCommand(commandList)
|
|
||||||
.multiLineCommand(commandListComplete)
|
|
||||||
.needResultReplay(needResultReplay)
|
|
||||||
.durationTask(durationTask)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ public class AcceptAgentInitInfo {
|
|||||||
|
|
||||||
OctopusMessage octopusMessage = OctopusMessage
|
OctopusMessage octopusMessage = OctopusMessage
|
||||||
.builder()
|
.builder()
|
||||||
.type(OctopusMessageType.INIT)
|
.octopusMessageType(OctopusMessageType.INIT)
|
||||||
// should be the OctopusExchange Name
|
// should be the OctopusExchange Name
|
||||||
.content(serverInfoContent)
|
.content(serverInfoContent)
|
||||||
.init_time(TimeUtils.currentFormatTime())
|
.init_time(TimeUtils.currentFormatTime())
|
||||||
|
|||||||
@@ -15,32 +15,36 @@ import java.time.LocalDateTime;
|
|||||||
@SuperBuilder(toBuilder = true)
|
@SuperBuilder(toBuilder = true)
|
||||||
public class OctopusMessage {
|
public class OctopusMessage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应该为64位的UUID
|
||||||
|
*/
|
||||||
String uuid;
|
String uuid;
|
||||||
|
|
||||||
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
LocalDateTime init_time;
|
LocalDateTime init_time;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行操作的类型
|
* 执行操作的类型
|
||||||
*/
|
*/
|
||||||
OctopusMessageType type;
|
OctopusMessageType octopusMessageType;
|
||||||
|
|
||||||
|
|
||||||
// server send message content
|
// server send message content
|
||||||
Object content;
|
Object content;
|
||||||
|
|
||||||
// agent reply message content
|
|
||||||
Object result;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行结果的状态Code
|
|
||||||
*/
|
|
||||||
String ResultCode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Agent 完成操作的时间
|
* Agent 完成操作的时间
|
||||||
*/
|
*/
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
LocalDateTime ac_time;
|
LocalDateTime ac_time;
|
||||||
|
|
||||||
|
|
||||||
|
// agent reply message content
|
||||||
|
Object result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行结果的状态Code
|
||||||
|
*/
|
||||||
|
String resultCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ package io.wdd.rpc.message.handler.async;
|
|||||||
import io.wdd.rpc.message.OctopusMessage;
|
import io.wdd.rpc.message.OctopusMessage;
|
||||||
import io.wdd.server.config.ServerCommonPool;
|
import io.wdd.server.config.ServerCommonPool;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static io.wdd.rpc.message.handler.sync.OMessageHandlerServer.OCTOPUS_MESSAGE_FROM_AGENT;
|
import static io.wdd.rpc.message.handler.sync.OMessageHandler.GenerateOMessageMatchKey;
|
||||||
|
import static io.wdd.rpc.message.handler.sync.OMessageToServerListener.OCTOPUS_MESSAGE_FROM_AGENT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从Agent收集返回信息的统一处理地点
|
* 从Agent收集返回信息的统一处理地点
|
||||||
@@ -18,41 +18,10 @@ import static io.wdd.rpc.message.handler.sync.OMessageHandlerServer.OCTOPUS_MESS
|
|||||||
* <p>
|
* <p>
|
||||||
* 调用结束之后,需要从 REPLAY_WAITING_TARGET 中移除此部分内容
|
* 调用结束之后,需要从 REPLAY_WAITING_TARGET 中移除此部分内容
|
||||||
*/
|
*/
|
||||||
@Service
|
//@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AsyncWaitOctopusMessageResultService {
|
public class AsyncWaitOctopusMessageResultService {
|
||||||
|
|
||||||
/**
|
|
||||||
* 为了避免线程不安全的问题,增加一层缓存,仅仅由当前类操作此部分
|
|
||||||
* KEY -> replayMatchKey
|
|
||||||
* VALUE -> OctopusMessageSynScReplayContend - 包含countDownLatch 和 result
|
|
||||||
*/
|
|
||||||
private static final HashMap<String, OctopusMessageSynScReplayContend> OM_REPLAY_WAITING_TARGET_MAP = new HashMap<>();
|
|
||||||
|
|
||||||
public void waitFor(OctopusMessageSynScReplayContend OctopusMessageSynScReplayContend) {
|
|
||||||
|
|
||||||
// 向 REPLAY_CACHE_MAP中写入 Key
|
|
||||||
OM_REPLAY_WAITING_TARGET_MAP.put(
|
|
||||||
OctopusMessageSynScReplayContend.getReplayMatchKey(),
|
|
||||||
OctopusMessageSynScReplayContend
|
|
||||||
);
|
|
||||||
|
|
||||||
// 在调用线程的countDownLunch结束之后,关闭
|
|
||||||
// 清除 REPLAY_CACHE_MAP 中的队列
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopWaiting(OctopusMessageSynScReplayContend OctopusMessageSynScReplayContend) {
|
|
||||||
|
|
||||||
// 在调用线程的countDownLunch结束之后,关闭 清除 REPLAY_CACHE_MAP 中的队列
|
|
||||||
OctopusMessageSynScReplayContend contend = OM_REPLAY_WAITING_TARGET_MAP.get(OctopusMessageSynScReplayContend.getReplayMatchKey());
|
|
||||||
|
|
||||||
// 移除该内容
|
|
||||||
OM_REPLAY_WAITING_TARGET_MAP.remove(OctopusMessageSynScReplayContend.getReplayMatchKey());
|
|
||||||
|
|
||||||
// help gc
|
|
||||||
contend = null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void daemonHandleReplayOMFromAgent() {
|
public void daemonHandleReplayOMFromAgent() {
|
||||||
@@ -65,6 +34,13 @@ public class AsyncWaitOctopusMessageResultService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为了避免线程不安全的问题,增加一层缓存,仅仅由当前类操作此部分
|
||||||
|
* KEY -> replayMatchKey
|
||||||
|
* VALUE -> OctopusMessageSyncReplayContend - 包含countDownLatch 和 result
|
||||||
|
*/
|
||||||
|
private static final HashMap<String, OctopusMessageSyncReplayContend> OM_REPLAY_WAITING_TARGET_MAP = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 操作 OCTOPUS_MESSAGE_FROM_AGENT 获取相应的Message放入内容中
|
* 操作 OCTOPUS_MESSAGE_FROM_AGENT 获取相应的Message放入内容中
|
||||||
*/
|
*/
|
||||||
@@ -88,8 +64,8 @@ public class AsyncWaitOctopusMessageResultService {
|
|||||||
OctopusMessage replayOMessage = OCTOPUS_MESSAGE_FROM_AGENT.poll();
|
OctopusMessage replayOMessage = OCTOPUS_MESSAGE_FROM_AGENT.poll();
|
||||||
|
|
||||||
// 构造 replayMatchKey
|
// 构造 replayMatchKey
|
||||||
String matchKey = OctopusMessageSynScReplayContend.generateMatchKey(
|
String matchKey = GenerateOMessageMatchKey(
|
||||||
replayOMessage.getType(),
|
replayOMessage.getOctopusMessageType(),
|
||||||
replayOMessage.getInit_time()
|
replayOMessage.getInit_time()
|
||||||
);
|
);
|
||||||
if (!OM_REPLAY_WAITING_TARGET_MAP.containsKey(matchKey)) {
|
if (!OM_REPLAY_WAITING_TARGET_MAP.containsKey(matchKey)) {
|
||||||
@@ -97,7 +73,7 @@ public class AsyncWaitOctopusMessageResultService {
|
|||||||
|
|
||||||
// todo 错误的数据需要放置于某处
|
// todo 错误的数据需要放置于某处
|
||||||
log.debug(
|
log.debug(
|
||||||
"等待队列力没有该回复的结果key =>",
|
"等待队列里面没有该回复的结果key =>",
|
||||||
matchKey
|
matchKey
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -105,12 +81,12 @@ public class AsyncWaitOctopusMessageResultService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Map中包含有Key,那么放置进去
|
// Map中包含有Key,那么放置进去
|
||||||
OctopusMessageSynScReplayContend replayContend = OM_REPLAY_WAITING_TARGET_MAP.get(matchKey);
|
OctopusMessageSyncReplayContend replayContend = OM_REPLAY_WAITING_TARGET_MAP.get(matchKey);
|
||||||
|
|
||||||
replayContend
|
replayContend
|
||||||
.getReplayOMList()
|
.getReplayOMList()
|
||||||
.add(replayOMessage);
|
.add(replayOMessage);
|
||||||
|
|
||||||
|
|
||||||
// 需要操作countDown
|
// 需要操作countDown
|
||||||
replayContend
|
replayContend
|
||||||
.getCountDownLatch()
|
.getCountDownLatch()
|
||||||
@@ -119,6 +95,30 @@ public class AsyncWaitOctopusMessageResultService {
|
|||||||
// 结束操作,继续循环
|
// 结束操作,继续循环
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void waitFor(OctopusMessageSyncReplayContend OctopusMessageSyncReplayContend) {
|
||||||
|
|
||||||
|
// 向 REPLAY_CACHE_MAP中写入 Key
|
||||||
|
OM_REPLAY_WAITING_TARGET_MAP.put(
|
||||||
|
OctopusMessageSyncReplayContend.getReplayMatchKey(),
|
||||||
|
OctopusMessageSyncReplayContend
|
||||||
|
);
|
||||||
|
|
||||||
|
// 在调用线程的countDownLunch结束之后,关闭
|
||||||
|
// 清除 REPLAY_CACHE_MAP 中的队列
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopWaiting(OctopusMessageSyncReplayContend OctopusMessageSyncReplayContend) {
|
||||||
|
|
||||||
|
// 在调用线程的countDownLunch结束之后,关闭 清除 REPLAY_CACHE_MAP 中的队列
|
||||||
|
OctopusMessageSyncReplayContend contend = OM_REPLAY_WAITING_TARGET_MAP.get(OctopusMessageSyncReplayContend.getReplayMatchKey());
|
||||||
|
|
||||||
|
// 移除该内容
|
||||||
|
OM_REPLAY_WAITING_TARGET_MAP.remove(OctopusMessageSyncReplayContend.getReplayMatchKey());
|
||||||
|
|
||||||
|
// help gc
|
||||||
|
contend = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,14 @@ import java.time.LocalDateTime;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
import static io.wdd.rpc.message.handler.sync.OMessageHandler.GenerateOMessageMatchKey;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@SuperBuilder(toBuilder = true)
|
@SuperBuilder(toBuilder = true)
|
||||||
@ApiModel("众多业务调用RPC,异步等待需要确定返回消息是谁的")
|
@ApiModel("众多业务调用RPC,异步等待需要确定返回消息是谁的")
|
||||||
public class OctopusMessageSynScReplayContend {
|
public class OctopusMessageSyncReplayContend {
|
||||||
|
|
||||||
@ApiModelProperty("rpc消息的类型")
|
@ApiModelProperty("rpc消息的类型")
|
||||||
OctopusMessageType type;
|
OctopusMessageType type;
|
||||||
@@ -37,34 +39,23 @@ public class OctopusMessageSynScReplayContend {
|
|||||||
@ApiModelProperty("回复的结果列表, 临时保存")
|
@ApiModelProperty("回复的结果列表, 临时保存")
|
||||||
ArrayList<OctopusMessage> replayOMList;
|
ArrayList<OctopusMessage> replayOMList;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param messageType
|
|
||||||
* @param messageInitTime 必须使用 TimeUtils.currentFormatTime();
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String generateMatchKey(OctopusMessageType messageType, LocalDateTime messageInitTime) {
|
|
||||||
|
|
||||||
String relayMatchKey = messageType.toString() + messageInitTime.toString();
|
|
||||||
|
|
||||||
return relayMatchKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execution模块使用的模板
|
* Execution模块使用的模板
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static OctopusMessageSynScReplayContend build(int waitForReplayNum, OctopusMessageType currentOMType, LocalDateTime currentTime) {
|
public static OctopusMessageSyncReplayContend build(int waitForReplayNum, OctopusMessageType currentOMType, LocalDateTime currentTime) {
|
||||||
|
|
||||||
CountDownLatch latch = null;
|
CountDownLatch latch = null;
|
||||||
if (waitForReplayNum != 0) {
|
if (waitForReplayNum != 0) {
|
||||||
latch = new CountDownLatch(waitForReplayNum);
|
latch = new CountDownLatch(waitForReplayNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new OctopusMessageSynScReplayContend(
|
return new OctopusMessageSyncReplayContend(
|
||||||
currentOMType,
|
currentOMType,
|
||||||
currentTime,
|
currentTime,
|
||||||
generateMatchKey(
|
GenerateOMessageMatchKey(
|
||||||
currentOMType,
|
currentOMType,
|
||||||
currentTime
|
currentTime
|
||||||
),
|
),
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
package io.wdd.rpc.message.handler.sync;
|
||||||
|
|
||||||
|
import io.wdd.rpc.message.OctopusMessage;
|
||||||
|
import io.wdd.rpc.message.OctopusMessageType;
|
||||||
|
import io.wdd.server.config.ServerCommonPool;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import static io.wdd.rpc.message.handler.sync.OMessageToServerListener.FROM_AGENT_MATCH_TO_AGENT_MAP;
|
||||||
|
import static io.wdd.rpc.message.handler.sync.OMessageToServerListener.OCTOPUS_MESSAGE_FROM_AGENT;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j(topic = "Octopus Message Handler")
|
||||||
|
public class OMessageHandler {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建 发送和接收 OctopusMessage之间的比对关系
|
||||||
|
*
|
||||||
|
* @param messageType
|
||||||
|
* @param messageInitTime 必须使用 TimeUtils.currentFormatTime();
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String GenerateOMessageMatchKey(OctopusMessageType messageType, LocalDateTime messageInitTime) {
|
||||||
|
|
||||||
|
String relayMatchKey = messageType.toString() + messageInitTime.toString();
|
||||||
|
|
||||||
|
return relayMatchKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void daemonHandleReplayOMFromAgent() {
|
||||||
|
|
||||||
|
// 异步任务启动
|
||||||
|
CompletableFuture.runAsync(
|
||||||
|
() -> doHandleOMessageFromAgent(),
|
||||||
|
ServerCommonPool.pool
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析所有从Agent传回的消息,中央集中化处理
|
||||||
|
*/
|
||||||
|
private void doHandleOMessageFromAgent() {
|
||||||
|
|
||||||
|
// 死循环,不断的轮询 OCTOPUS_MESSAGE_FROM_AGENT
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
if (OCTOPUS_MESSAGE_FROM_AGENT.isEmpty()) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
OCTOPUS_MESSAGE_FROM_AGENT.wait(5000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
// 返回,继续死循环
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拿到消息
|
||||||
|
OctopusMessage replayOMessage = OCTOPUS_MESSAGE_FROM_AGENT.poll();
|
||||||
|
|
||||||
|
// 构造 replayMatchKey
|
||||||
|
String matchKey = GenerateOMessageMatchKey(
|
||||||
|
replayOMessage.getOctopusMessageType(),
|
||||||
|
replayOMessage.getInit_time()
|
||||||
|
);
|
||||||
|
if (!FROM_AGENT_MATCH_TO_AGENT_MAP.containsKey(matchKey)) {
|
||||||
|
// 没有这个Key,说明等待结果已经超时了,直接丢弃,然后继续循环
|
||||||
|
// todo 错误的数据需要放置于某处
|
||||||
|
log.debug(
|
||||||
|
"等待队列里面没有该回复的结果key =>",
|
||||||
|
matchKey
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 归还信息
|
||||||
|
// 拿到原始信息
|
||||||
|
OctopusMessage originOMessage = FROM_AGENT_MATCH_TO_AGENT_MAP.get(matchKey);
|
||||||
|
originOMessage.setResultCode(replayOMessage.getResultCode());
|
||||||
|
originOMessage.setResult(replayOMessage.getResult());
|
||||||
|
|
||||||
|
|
||||||
|
// 通知等待线程
|
||||||
|
originOMessage.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void waitFor(OctopusMessage octopusMessage) {
|
||||||
|
|
||||||
|
// 构建 MatchKey
|
||||||
|
String matchKey = GenerateOMessageMatchKey(
|
||||||
|
octopusMessage.getOctopusMessageType(),
|
||||||
|
octopusMessage.getInit_time()
|
||||||
|
);
|
||||||
|
|
||||||
|
// 开始等待
|
||||||
|
FROM_AGENT_MATCH_TO_AGENT_MAP.put(
|
||||||
|
matchKey,
|
||||||
|
octopusMessage
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopWaiting(OctopusMessage octopusMessage) {
|
||||||
|
|
||||||
|
// 构建 MatchKey
|
||||||
|
String matchKey = GenerateOMessageMatchKey(
|
||||||
|
octopusMessage.getOctopusMessageType(),
|
||||||
|
octopusMessage.getInit_time()
|
||||||
|
);
|
||||||
|
|
||||||
|
// 开始等待
|
||||||
|
FROM_AGENT_MATCH_TO_AGENT_MAP.remove(matchKey);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package io.wdd.rpc.message.handler.sync;
|
package io.wdd.rpc.message.handler.sync;
|
||||||
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import io.wdd.common.handler.MyRuntimeException;
|
import io.wdd.common.handler.MyRuntimeException;
|
||||||
import io.wdd.rpc.message.OctopusMessage;
|
import io.wdd.rpc.message.OctopusMessage;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -14,16 +13,20 @@ import org.springframework.data.redis.core.RedisTemplate;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import static io.wdd.common.utils.OctopusObjectMapperConfig.OctopusObjectMapper;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@Slf4j(topic = "Octopus Message Handler")
|
@Slf4j(topic = "Octopus Message Listener")
|
||||||
public class OMessageHandlerServer {
|
public class OMessageToServerListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redis Key 用于保存Agent的最新版本
|
* Redis Key 用于保存Agent的最新版本
|
||||||
* 由 GitHubAction发送至 RabbitMQ中,然后此处获取处理,发送至Redis中
|
* 由 GitHubAction发送至 RabbitMQ中,然后此处获取处理,发送至Redis中
|
||||||
*/
|
*/
|
||||||
public static final String LATEST_VERSION = "LATEST_VERSION";
|
public static final String LATEST_VERSION = "LATEST_VERSION";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储所有的从 Agent过来的 OctopusMessage
|
* 存储所有的从 Agent过来的 OctopusMessage
|
||||||
* 各个业务模块需要自己手动去获取自己需要的内容
|
* 各个业务模块需要自己手动去获取自己需要的内容
|
||||||
@@ -32,10 +35,20 @@ public class OMessageHandlerServer {
|
|||||||
public static ArrayDeque<OctopusMessage> OCTOPUS_MESSAGE_FROM_AGENT = new ArrayDeque<>(
|
public static ArrayDeque<OctopusMessage> OCTOPUS_MESSAGE_FROM_AGENT = new ArrayDeque<>(
|
||||||
128
|
128
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送出去的OctopusMessage需要和返回回来的内容对比
|
||||||
|
* 返回来的OM反序列化之后就不是原对象,需要进行 通过MatchKey比较
|
||||||
|
* <p>
|
||||||
|
* omMatchKey -- OctopusMessage
|
||||||
|
*/
|
||||||
|
public static HashMap<String, OctopusMessage> FROM_AGENT_MATCH_TO_AGENT_MAP = new HashMap<>();
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
RedisTemplate redisTemplate;
|
RedisTemplate redisTemplate;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
ObjectMapper objectMapper;
|
OMessageHandler oMessageHandler;
|
||||||
|
|
||||||
@RabbitHandler
|
@RabbitHandler
|
||||||
@RabbitListener(queues = "${octopus.message.octopus_to_server}"
|
@RabbitListener(queues = "${octopus.message.octopus_to_server}"
|
||||||
@@ -45,7 +58,7 @@ public class OMessageHandlerServer {
|
|||||||
OctopusMessage octopusMessage;
|
OctopusMessage octopusMessage;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
octopusMessage = objectMapper.readValue(
|
octopusMessage = OctopusObjectMapper.readValue(
|
||||||
message.getBody(),
|
message.getBody(),
|
||||||
OctopusMessage.class
|
OctopusMessage.class
|
||||||
);
|
);
|
||||||
@@ -70,6 +83,7 @@ public class OMessageHandlerServer {
|
|||||||
"开始向Redis中缓存Agent的最新版本 => {}",
|
"开始向Redis中缓存Agent的最新版本 => {}",
|
||||||
latestVersion
|
latestVersion
|
||||||
);
|
);
|
||||||
|
|
||||||
redisTemplate
|
redisTemplate
|
||||||
.opsForValue()
|
.opsForValue()
|
||||||
.set(
|
.set(
|
||||||
@@ -82,11 +96,9 @@ public class OMessageHandlerServer {
|
|||||||
// 将收到的消息,直接存储到 缓存队列中
|
// 将收到的消息,直接存储到 缓存队列中
|
||||||
log.debug("cache the octopus message to inner cache list !");
|
log.debug("cache the octopus message to inner cache list !");
|
||||||
OCTOPUS_MESSAGE_FROM_AGENT.offer(octopusMessage);
|
OCTOPUS_MESSAGE_FROM_AGENT.offer(octopusMessage);
|
||||||
|
oMessageHandler.waitFor(octopusMessage);
|
||||||
|
|
||||||
// collect all message from agent and log to somewhere
|
// 唤醒等待线程
|
||||||
|
OCTOPUS_MESSAGE_FROM_AGENT.notify();
|
||||||
// 1. send some info to the specific topic name
|
|
||||||
// 2. judge from which agent the message are
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.wdd.rpc.message.sender;
|
package io.wdd.rpc.message.sender;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.wdd.common.handler.MyRuntimeException;
|
import io.wdd.common.handler.MyRuntimeException;
|
||||||
import io.wdd.rpc.init.InitRabbitMQConfig;
|
import io.wdd.rpc.init.InitRabbitMQConfig;
|
||||||
@@ -14,6 +15,8 @@ import org.springframework.stereotype.Component;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static io.wdd.common.utils.OctopusObjectMapperConfig.OctopusObjectMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* adaptor
|
* adaptor
|
||||||
* provide override method to convert Object and send to rabbitmq
|
* provide override method to convert Object and send to rabbitmq
|
||||||
@@ -34,25 +37,38 @@ public class OMessageToAgentSender {
|
|||||||
/**
|
/**
|
||||||
* send to Queue -- InitFromServer
|
* send to Queue -- InitFromServer
|
||||||
*
|
*
|
||||||
* @param message octopus message
|
* @param octopusMessage octopus octopusMessage
|
||||||
*/
|
*/
|
||||||
public void sendINIT(OctopusMessage message) {
|
public void sendINIT(OctopusMessage octopusMessage) {
|
||||||
|
|
||||||
// only accept INIT type message
|
// only accept INIT type octopusMessage
|
||||||
if (!OctopusMessageType.INIT.equals(message.getType())) {
|
if (!OctopusMessageType.INIT.equals(octopusMessage.getOctopusMessageType())) {
|
||||||
throw new MyRuntimeException("To Agent Order method usage wrong !");
|
throw new MyRuntimeException("To Agent Order method usage wrong !");
|
||||||
}
|
}
|
||||||
|
|
||||||
// send to Queue -- InitFromServer
|
// send to Queue -- InitFromServer
|
||||||
log.info(
|
log.info(
|
||||||
"send INIT OrderCommand to Agent = {}",
|
"send INIT OrderCommand to Agent = {}",
|
||||||
message
|
octopusMessage
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 统一处理Content
|
||||||
|
if (octopusMessage.getContent() instanceof String) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
String contendString = OctopusObjectMapper.writeValueAsString(octopusMessage.getContent());
|
||||||
|
|
||||||
|
octopusMessage.setContent(contendString);
|
||||||
|
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rabbitTemplate.convertAndSend(
|
rabbitTemplate.convertAndSend(
|
||||||
initRabbitMQConfig.INIT_EXCHANGE,
|
initRabbitMQConfig.INIT_EXCHANGE,
|
||||||
initRabbitMQConfig.INIT_FROM_SERVER_KEY,
|
initRabbitMQConfig.INIT_FROM_SERVER_KEY,
|
||||||
writeData(message)
|
writeData(octopusMessage)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -66,6 +82,19 @@ public class OMessageToAgentSender {
|
|||||||
octopusMessage.getUuid()
|
octopusMessage.getUuid()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 统一处理Content
|
||||||
|
if (!(octopusMessage.getContent() instanceof String)) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
String contendString = OctopusObjectMapper.writeValueAsString(octopusMessage.getContent());
|
||||||
|
|
||||||
|
octopusMessage.setContent(contendString);
|
||||||
|
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rabbitTemplate.convertAndSend(
|
rabbitTemplate.convertAndSend(
|
||||||
initRabbitMQConfig.OCTOPUS_EXCHANGE,
|
initRabbitMQConfig.OCTOPUS_EXCHANGE,
|
||||||
octopusMessage.getUuid() + "*",
|
octopusMessage.getUuid() + "*",
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
package io.wdd.rpc.scheduler.job;
|
//package io.wdd.rpc.scheduler.job;
|
||||||
|
//
|
||||||
import io.wdd.rpc.scheduler.config.QuartzLogOperator;
|
//import io.wdd.rpc.scheduler.config.QuartzLogOperator;
|
||||||
import io.wdd.rpc.scheduler.service.status.AgentAliveStatusMonitorService;
|
//import io.wdd.rpc.scheduler.service.status.AgentAliveStatusMonitorService;
|
||||||
import org.quartz.JobExecutionContext;
|
//import org.quartz.JobExecutionContext;
|
||||||
import org.quartz.JobExecutionException;
|
//import org.quartz.JobExecutionException;
|
||||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
//import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||||
|
//
|
||||||
import javax.annotation.Resource;
|
//import javax.annotation.Resource;
|
||||||
|
//
|
||||||
public class AgentAliveStatusMonitorJob extends QuartzJobBean {
|
//public class AgentAliveStatusMonitorJob extends QuartzJobBean {
|
||||||
|
//
|
||||||
@Resource
|
// @Resource
|
||||||
AgentAliveStatusMonitorService agentAliveStatusMonitorService;
|
// AgentAliveStatusMonitorService agentAliveStatusMonitorService;
|
||||||
|
//
|
||||||
@Resource
|
// @Resource
|
||||||
QuartzLogOperator quartzLogOperator;
|
// QuartzLogOperator quartzLogOperator;
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
// protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||||
|
//
|
||||||
// get the jobMetaMap
|
// // get the jobMetaMap
|
||||||
//JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
|
// //JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
|
||||||
|
//
|
||||||
// actually execute the monitor service
|
// // actually execute the monitor service
|
||||||
agentAliveStatusMonitorService.collectAllAgentAliveStatus();
|
// agentAliveStatusMonitorService.collectAllAgentAliveStatus();
|
||||||
|
//
|
||||||
// log to somewhere
|
// // log to somewhere
|
||||||
quartzLogOperator.save();
|
// quartzLogOperator.save();
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -1,29 +1,21 @@
|
|||||||
package io.wdd.rpc.scheduler.job;
|
package io.wdd.rpc.scheduler.job;
|
||||||
|
|
||||||
import io.wdd.rpc.scheduler.service.status.AgentMetricStatusCollectService;
|
//public class AgentMetricStatusJob extends QuartzJobBean {
|
||||||
import org.quartz.JobExecutionContext;
|
//
|
||||||
import org.quartz.JobExecutionException;
|
// @Resource
|
||||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
// AgentMetricStatusCollectService agentMetricStatusCollectService;
|
||||||
|
//
|
||||||
import javax.annotation.Resource;
|
// @Override
|
||||||
|
// protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||||
|
//
|
||||||
public class AgentMetricStatusJob extends QuartzJobBean {
|
// // 从JobDetailContext中获取相应的信息
|
||||||
|
//// JobDataMap jobDataMap = jobExecutionContext
|
||||||
@Resource
|
//// .getJobDetail()
|
||||||
AgentMetricStatusCollectService agentMetricStatusCollectService;
|
//// .getJobDataMap();
|
||||||
|
//
|
||||||
@Override
|
// // 执行Agent Metric 状态收集任务
|
||||||
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
// agentMetricStatusCollectService.collectHealthyAgentMetric();
|
||||||
|
//
|
||||||
// 从JobDetailContext中获取相应的信息
|
// }
|
||||||
// JobDataMap jobDataMap = jobExecutionContext
|
//
|
||||||
// .getJobDetail()
|
//}
|
||||||
// .getJobDataMap();
|
|
||||||
|
|
||||||
// 执行Agent Metric 状态收集任务
|
|
||||||
agentMetricStatusCollectService.collectHealthyAgentMetric();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
package io.wdd.rpc.scheduler.service;
|
package io.wdd.rpc.scheduler.service;
|
||||||
|
|
||||||
|
|
||||||
import io.wdd.rpc.scheduler.job.AgentAliveStatusMonitorJob;
|
|
||||||
import io.wdd.rpc.scheduler.job.AgentMetricStatusJob;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
|
||||||
@Component
|
//@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class BuildStatusScheduleTask {
|
public class BuildStatusScheduleTask {
|
||||||
|
|
||||||
@@ -31,10 +28,10 @@ public class BuildStatusScheduleTask {
|
|||||||
private void buildAllPreScheduledTask() {
|
private void buildAllPreScheduledTask() {
|
||||||
|
|
||||||
// Agent存活健康状态检查
|
// Agent存活健康状态检查
|
||||||
buildMonitorAllAgentAliveStatusScheduleTask();
|
// buildMonitorAllAgentAliveStatusScheduleTask();
|
||||||
|
|
||||||
// Agent运行信息检查 Metric
|
// Agent运行信息检查 Metric
|
||||||
buildAgentMetricScheduleTask();
|
// buildAgentMetricScheduleTask();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,43 +42,19 @@ public class BuildStatusScheduleTask {
|
|||||||
* <p>
|
* <p>
|
||||||
* 2023年7月10日 更改为按照cron表达式进行执行
|
* 2023年7月10日 更改为按照cron表达式进行执行
|
||||||
*/
|
*/
|
||||||
public void buildAgentMetricScheduleTask() {
|
// public void buildAgentMetricScheduleTask() {
|
||||||
|
//
|
||||||
// 2023年7月10日 更改为按照cron表达式进行执行
|
// // 2023年7月10日 更改为按照cron表达式进行执行
|
||||||
octopusQuartzService.addMission(
|
// octopusQuartzService.addMission(
|
||||||
AgentMetricStatusJob.class,
|
// AgentMetricStatusJob.class,
|
||||||
"agentRunMetricStatusJob",
|
// "agentRunMetricStatusJob",
|
||||||
JOB_GROUP_NAME,
|
// JOB_GROUP_NAME,
|
||||||
metricReportStartDelaySeconds,
|
// metricReportStartDelaySeconds,
|
||||||
metricReportCronExpress,
|
// metricReportCronExpress,
|
||||||
null
|
// null
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
// 计算 Metric检测的时间间隔
|
// }
|
||||||
/*int metricReportTimesCount = 19;
|
|
||||||
try {
|
|
||||||
CronExpression cronExpression = new CronExpression(healthyCronTimeExpress);
|
|
||||||
|
|
||||||
Date now = new Date();
|
|
||||||
Date nextValidTime = cronExpression.getNextValidTimeAfter(now);
|
|
||||||
long totalSeconds = (nextValidTime.getTime() - now.getTime()) / 1000;
|
|
||||||
metricReportTimesCount = (int) (totalSeconds / metricReportTimePinch) - 1;
|
|
||||||
|
|
||||||
*//*System.out.println("totalSeconds = " + totalSeconds);
|
|
||||||
System.out.println("metricReportTimesCount = " + metricReportTimesCount);*//*
|
|
||||||
|
|
||||||
} catch (ParseException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap<String, Integer> map = new HashMap<String, Integer>();
|
|
||||||
map.put(METRIC_REPORT_TIME_PINCH, metricReportTimePinch);
|
|
||||||
map.put(METRIC_REPORT_TIMES_COUNT, metricReportTimesCount);*/
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Agent存活健康状态检查
|
* Agent存活健康状态检查
|
||||||
@@ -90,19 +63,19 @@ public class BuildStatusScheduleTask {
|
|||||||
* 延迟触发时间 healthyCheckStartDelaySeconds
|
* 延迟触发时间 healthyCheckStartDelaySeconds
|
||||||
* 定时任务间隔 healthyCronTimeExpress
|
* 定时任务间隔 healthyCronTimeExpress
|
||||||
*/
|
*/
|
||||||
private void buildMonitorAllAgentAliveStatusScheduleTask() {
|
// private void buildMonitorAllAgentAliveStatusScheduleTask() {
|
||||||
|
//
|
||||||
// build the Job
|
// // build the Job
|
||||||
octopusQuartzService.addMission(
|
// octopusQuartzService.addMission(
|
||||||
AgentAliveStatusMonitorJob.class,
|
// AgentAliveStatusMonitorJob.class,
|
||||||
"monitorAllAgentAliveStatusJob",
|
// "monitorAllAgentAliveStatusJob",
|
||||||
JOB_GROUP_NAME,
|
// JOB_GROUP_NAME,
|
||||||
healthyCheckStartDelaySeconds,
|
// healthyCheckStartDelaySeconds,
|
||||||
healthyCronTimeExpress,
|
// healthyCronTimeExpress,
|
||||||
null
|
// null
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,29 @@
|
|||||||
package io.wdd.rpc.scheduler.service.script;
|
package io.wdd.rpc.scheduler.service.script;
|
||||||
|
|
||||||
|
|
||||||
import io.wdd.rpc.execute.service.SyncExecutionService;
|
import io.wdd.rpc.execute.ExecutionMessage;
|
||||||
|
import io.wdd.rpc.execute.service.AsyncExecutionService;
|
||||||
|
import io.wdd.rpc.message.OctopusMessage;
|
||||||
import io.wdd.rpc.scheduler.beans.ScriptSchedulerDTO;
|
import io.wdd.rpc.scheduler.beans.ScriptSchedulerDTO;
|
||||||
import io.wdd.rpc.scheduler.config.QuartzSchedulerUtils;
|
import io.wdd.rpc.scheduler.config.QuartzSchedulerUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1.
|
* 1.
|
||||||
*/
|
*/
|
||||||
@Service
|
//@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public class AgentApplyScheduledScript {
|
public class AgentApplyScheduledScript {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
SyncExecutionService asyncExecutionService;
|
AsyncExecutionService asyncExecutionService;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
QuartzSchedulerUtils quartzSchedulerUtils;
|
QuartzSchedulerUtils quartzSchedulerUtils;
|
||||||
@@ -46,13 +48,35 @@ public class AgentApplyScheduledScript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 发送命令到Agent中
|
// 发送命令到Agent中
|
||||||
List<String> resultKeyList = asyncExecutionService
|
String finalScriptType = scriptType;
|
||||||
.SyncSendCommandToAgentComplete(
|
List<String> resultKeyList = targetMachineList
|
||||||
targetMachineList,
|
.stream()
|
||||||
scriptType,
|
.map(
|
||||||
completeCommandList,
|
targetMachine -> {
|
||||||
futureResultKeyMap
|
OctopusMessage octopusMessage = asyncExecutionService
|
||||||
);
|
.AsyncCallSendCommandToAgent(
|
||||||
|
targetMachine,
|
||||||
|
finalScriptType,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
completeCommandList,
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
String resultKey = ((ExecutionMessage) octopusMessage.getContent()).getResultKey();
|
||||||
|
|
||||||
|
// 构建Map
|
||||||
|
futureResultKeyMap.put(
|
||||||
|
targetMachine,
|
||||||
|
resultKey
|
||||||
|
);
|
||||||
|
|
||||||
|
return resultKey;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// 将 resultKeyList 放入这个DTO中
|
// 将 resultKeyList 放入这个DTO中
|
||||||
scriptSchedulerDTO.setResultKeyList(resultKeyList);
|
scriptSchedulerDTO.setResultKeyList(resultKeyList);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import io.wdd.rpc.status.beans.AgentStatus;
|
|||||||
import io.wdd.rpc.status.service.SyncStatusService;
|
import io.wdd.rpc.status.service.SyncStatusService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
@@ -19,7 +18,7 @@ import static io.wdd.rpc.status.CommonAndStatusCache.ALL_HEALTHY_AGENT_TOPIC_NAM
|
|||||||
/**
|
/**
|
||||||
* 定时任务 收集Agent的运行Metric的实际执行类
|
* 定时任务 收集Agent的运行Metric的实际执行类
|
||||||
*/
|
*/
|
||||||
@Service
|
//@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AgentMetricStatusCollectService {
|
public class AgentMetricStatusCollectService {
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class OctopusStatusMessage {
|
|||||||
|
|
||||||
return OctopusMessage
|
return OctopusMessage
|
||||||
.builder()
|
.builder()
|
||||||
.type(OctopusMessageType.STATUS)
|
.octopusMessageType(OctopusMessageType.STATUS)
|
||||||
.uuid(agentTopicName)
|
.uuid(agentTopicName)
|
||||||
.init_time(currentTime)
|
.init_time(currentTime)
|
||||||
.content(ops)
|
.content(ops)
|
||||||
|
|||||||
@@ -6,12 +6,11 @@ import io.wdd.rpc.beans.request.MetricQueryEntity;
|
|||||||
import io.wdd.rpc.message.OctopusMessage;
|
import io.wdd.rpc.message.OctopusMessage;
|
||||||
import io.wdd.rpc.message.OctopusMessageType;
|
import io.wdd.rpc.message.OctopusMessageType;
|
||||||
import io.wdd.rpc.message.handler.async.AsyncWaitOctopusMessageResultService;
|
import io.wdd.rpc.message.handler.async.AsyncWaitOctopusMessageResultService;
|
||||||
import io.wdd.rpc.message.handler.async.OctopusMessageSynScReplayContend;
|
import io.wdd.rpc.message.handler.async.OctopusMessageSyncReplayContend;
|
||||||
import io.wdd.rpc.message.sender.OMessageToAgentSender;
|
import io.wdd.rpc.message.sender.OMessageToAgentSender;
|
||||||
import io.wdd.rpc.status.beans.AgentStatus;
|
import io.wdd.rpc.status.beans.AgentStatus;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -27,7 +26,7 @@ import static io.wdd.common.utils.OctopusObjectMapperConfig.OctopusObjectMapper;
|
|||||||
import static io.wdd.rpc.status.OctopusStatusMessage.*;
|
import static io.wdd.rpc.status.OctopusStatusMessage.*;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
//@Service
|
||||||
public class SyncStatusServiceImpl implements SyncStatusService {
|
public class SyncStatusServiceImpl implements SyncStatusService {
|
||||||
|
|
||||||
private static final OctopusMessageType CurrentAppOctopusMessageType = OctopusMessageType.STATUS;
|
private static final OctopusMessageType CurrentAppOctopusMessageType = OctopusMessageType.STATUS;
|
||||||
@@ -64,7 +63,7 @@ public class SyncStatusServiceImpl implements SyncStatusService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 同步收集消息
|
// 同步收集消息
|
||||||
OctopusMessageSynScReplayContend statusSyncReplayContend = OctopusMessageSynScReplayContend.build(
|
OctopusMessageSyncReplayContend statusSyncReplayContend = OctopusMessageSyncReplayContend.build(
|
||||||
agentTopicNameList.size(),
|
agentTopicNameList.size(),
|
||||||
CurrentAppOctopusMessageType,
|
CurrentAppOctopusMessageType,
|
||||||
currentTime
|
currentTime
|
||||||
@@ -128,7 +127,7 @@ public class SyncStatusServiceImpl implements SyncStatusService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 同步等待结果, 并且解析结果
|
// 同步等待结果, 并且解析结果
|
||||||
OctopusMessageSynScReplayContend metricSyncReplayContend = OctopusMessageSynScReplayContend.build(
|
OctopusMessageSyncReplayContend metricSyncReplayContend = OctopusMessageSyncReplayContend.build(
|
||||||
agentTopicNameList.size(),
|
agentTopicNameList.size(),
|
||||||
CurrentAppOctopusMessageType,
|
CurrentAppOctopusMessageType,
|
||||||
currentTime
|
currentTime
|
||||||
|
|||||||
@@ -83,14 +83,16 @@ mybatis-plus:
|
|||||||
banner: false
|
banner: false
|
||||||
configuration:
|
configuration:
|
||||||
# 希望知道所有的sql是怎么执行的, 配置输出日志
|
# 希望知道所有的sql是怎么执行的, 配置输出日志
|
||||||
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
|
# log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
|
||||||
# 数据库下划线--实体类也是下划线 需要为false
|
# 数据库下划线--实体类也是下划线 需要为false
|
||||||
map-underscore-to-camel-case: true
|
map-underscore-to-camel-case: true
|
||||||
# 一级缓存的 缓存级别默认为 session,如果要关闭一级缓存可以设置为 statement
|
# 一级缓存的 缓存级别默认为 session,如果要关闭一级缓存可以设置为 statement
|
||||||
local-cache-scope: session
|
local-cache-scope: session
|
||||||
# 是否开启二级缓存
|
# 是否开启二级缓存
|
||||||
cache-enabled: false
|
cache-enabled: false
|
||||||
|
# 分页插件配置
|
||||||
|
interceptor: com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor
|
||||||
# 默认地址为 classpath*:/mapper/**/*.xml
|
# 默认地址为 classpath*:/mapper/**/*.xml
|
||||||
# mapper-locations: classpath*:/real-mappers/**/*.xml
|
# mapper-locations: classpath*:/real-mappers/**/*.xml
|
||||||
|
|
||||||
@@ -162,6 +164,6 @@ oss:
|
|||||||
# 开启debug模式
|
# 开启debug模式
|
||||||
logging:
|
logging:
|
||||||
level:
|
level:
|
||||||
io.wdd: debug
|
io.wdd.rpc.execute: debug
|
||||||
debug: true
|
debug: true
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.wdd.server;
|
package io.wdd.server;
|
||||||
|
|
||||||
import io.wdd.rpc.execute.service.SyncExecutionService;
|
import io.wdd.rpc.execute.service.AsyncExecutionService;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ class ServerApplicationTests {
|
|||||||
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
SyncExecutionService asyncExecutionService;
|
AsyncExecutionService asyncExecutionService;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCoreExecutionCompleteScript() {
|
void testCoreExecutionCompleteScript() {
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
package io.wdd.server;
|
package io.wdd.server;
|
||||||
|
|
||||||
import io.wdd.rpc.status.AgentHealthyStatusEnum;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
|
||||||
@@ -13,33 +8,6 @@ public class SimpleTest {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
|
||||||
HashMap<String, String> map = new HashMap<>();
|
|
||||||
|
|
||||||
HashMap<String, List<String>> hashMap = new HashMap<>();
|
|
||||||
|
|
||||||
hashMap.put(
|
|
||||||
"HEALTHY",
|
|
||||||
new ArrayList<>(
|
|
||||||
List.of(
|
|
||||||
"Tokyo-amd64-07-f66a41",
|
|
||||||
"Tokyo-amd64-03-dc543f"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
hashMap
|
|
||||||
.get(AgentHealthyStatusEnum.FAILED.getStatus())
|
|
||||||
.stream()
|
|
||||||
.forEach(
|
|
||||||
agentTopicName -> {
|
|
||||||
map.put(
|
|
||||||
agentTopicName,
|
|
||||||
"0"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CompletableFutureTest() {
|
private void CompletableFutureTest() {
|
||||||
|
|||||||
Reference in New Issue
Block a user