[ server ] [ scheduler ]- script scheduler - 1
This commit is contained in:
@@ -10,7 +10,6 @@ import io.wdd.common.beans.rabbitmq.OctopusMessageType;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static io.wdd.agent.config.utils.NacosConfigurationCollector.ALL_FUNCTION_MAP;
|
import static io.wdd.agent.config.utils.NacosConfigurationCollector.ALL_FUNCTION_MAP;
|
||||||
@@ -31,19 +30,24 @@ public class OMHandlerExecutor extends AbstractOctopusMessageHandler {
|
|||||||
@Override
|
@Override
|
||||||
public boolean handle(OctopusMessage octopusMessage) {
|
public boolean handle(OctopusMessage octopusMessage) {
|
||||||
|
|
||||||
if (!octopusMessage.getType().equals(OctopusMessageType.EXECUTOR)) {
|
if (!octopusMessage
|
||||||
|
.getType()
|
||||||
|
.equals(OctopusMessageType.EXECUTOR)) {
|
||||||
return next.handle(octopusMessage);
|
return next.handle(octopusMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
ExecutionMessage executionMessage = objectMapper.readValue((String) octopusMessage.getContent(), new TypeReference<ExecutionMessage>() {
|
// 需要首先解析成 ExecutionMessage
|
||||||
});
|
ExecutionMessage executionMessage = objectMapper.readValue(
|
||||||
|
(String) octopusMessage.getContent(),
|
||||||
// System.out.println("executionMessage = " + executionMessage);
|
new TypeReference<ExecutionMessage>() {
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
String executionType = executionMessage.getType();
|
String executionType = executionMessage.getType();
|
||||||
|
|
||||||
|
|
||||||
if (ALL_FUNCTION_MAP.containsKey(executionType)) {
|
if (ALL_FUNCTION_MAP.containsKey(executionType)) {
|
||||||
// execute the exist function
|
// execute the exist function
|
||||||
functionExecutor.execute(executionMessage);
|
functionExecutor.execute(executionMessage);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import com.alibaba.nacos.api.NacosFactory;
|
|||||||
import com.alibaba.nacos.api.config.ConfigService;
|
import com.alibaba.nacos.api.config.ConfigService;
|
||||||
import com.alibaba.nacos.api.config.listener.Listener;
|
import com.alibaba.nacos.api.config.listener.Listener;
|
||||||
import com.alibaba.nacos.api.exception.NacosException;
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
import io.wdd.agent.executor.config.FunctionReader;
|
import io.wdd.common.utils.FunctionReader;
|
||||||
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.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
@@ -13,7 +13,6 @@ import org.springframework.stereotype.Component;
|
|||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@@ -53,9 +52,6 @@ public class NacosConfigurationCollector {
|
|||||||
@Value("${octopus.status.name}")
|
@Value("${octopus.status.name}")
|
||||||
public String appStatusDataId;
|
public String appStatusDataId;
|
||||||
|
|
||||||
@Resource
|
|
||||||
FunctionReader functionReader;
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
private void CollectAllFunctionFromNacos() {
|
private void CollectAllFunctionFromNacos() {
|
||||||
|
|
||||||
@@ -158,18 +154,19 @@ public class NacosConfigurationCollector {
|
|||||||
|
|
||||||
yaml.loadAll(allApplicationNeedToMonitorStatus).iterator().forEachRemaining(realFunction -> {
|
yaml.loadAll(allApplicationNeedToMonitorStatus).iterator().forEachRemaining(realFunction -> {
|
||||||
|
|
||||||
|
// 其实没有意义
|
||||||
if (!(realFunction instanceof LinkedHashMap)) {
|
if (!(realFunction instanceof LinkedHashMap)) {
|
||||||
System.out.println("realFunction = " + realFunction);
|
System.out.println("realFunction = " + realFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Map<String, String> stringMap = (Map<String, String>) realFunction;
|
Map<String, String> stringMap = (Map<String, String>) realFunction;
|
||||||
|
|
||||||
|
// 拿到实际的功能名称 如 AgentReboot AgentUpdate
|
||||||
Optional<String> functionName = stringMap.keySet().stream().findFirst();
|
Optional<String> functionName = stringMap.keySet().stream().findFirst();
|
||||||
|
List<List<String>> commandList = FunctionReader.ReadStringToCommandList(stringMap.get(functionName.get()));
|
||||||
List<List<String>> commandList = functionReader.ReadStringToCommandList(stringMap.get(functionName.get()));
|
|
||||||
|
|
||||||
/*log.info("Function {} , content is {}", functionName.get(), commandList);*/
|
/*log.info("Function {} , content is {}", functionName.get(), commandList);*/
|
||||||
|
|
||||||
ALL_FUNCTION_MAP.put(functionName.get(), commandList);
|
ALL_FUNCTION_MAP.put(functionName.get(), commandList);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,8 +15,9 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -39,10 +40,10 @@ public class CommandExecutor {
|
|||||||
* @param executionMessage get from EXECUTOR_HANDLERju
|
* @param executionMessage get from EXECUTOR_HANDLERju
|
||||||
*/
|
*/
|
||||||
public void execute(ExecutionMessage executionMessage) {
|
public void execute(ExecutionMessage executionMessage) {
|
||||||
|
this.execute(
|
||||||
|
executionMessage.getResultKey(),
|
||||||
this.execute(executionMessage.getResultKey(), executionMessage.getCommandList());
|
executionMessage.getCommandList()
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,14 +52,20 @@ public class CommandExecutor {
|
|||||||
|
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||||
|
|
||||||
return this.processExecute(streamKey, processBuilder);
|
return this.processExecute(
|
||||||
|
streamKey,
|
||||||
|
processBuilder
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int execute(String streamKey, String... command) {
|
public int execute(String streamKey, String... command) {
|
||||||
|
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||||
|
|
||||||
return this.processExecute(streamKey, processBuilder);
|
return this.processExecute(
|
||||||
|
streamKey,
|
||||||
|
processBuilder
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,14 +89,20 @@ public class CommandExecutor {
|
|||||||
));
|
));
|
||||||
|
|
||||||
// cache log lines
|
// cache log lines
|
||||||
logToArrayListCache.cacheLog(streamKey, process);
|
logToArrayListCache.cacheLog(
|
||||||
|
streamKey,
|
||||||
|
process
|
||||||
|
);
|
||||||
|
|
||||||
// start to send the result log
|
// start to send the result log
|
||||||
streamSender.startToWaitLog(streamKey);
|
streamSender.startToWaitLog(streamKey);
|
||||||
|
|
||||||
// todo this will stuck the process and rabbitmq message will reentry the queue
|
// todo this will stuck the process and rabbitmq message will reentry the queue
|
||||||
// get the command result must also be a timeout smaller than the process
|
// get the command result must also be a timeout smaller than the process
|
||||||
boolean waitFor = process.waitFor(50, TimeUnit.SECONDS);
|
boolean waitFor = process.waitFor(
|
||||||
|
50,
|
||||||
|
TimeUnit.SECONDS
|
||||||
|
);
|
||||||
|
|
||||||
// end send logs
|
// end send logs
|
||||||
streamSender.endWaitLog(streamKey);
|
streamSender.endWaitLog(streamKey);
|
||||||
@@ -99,27 +112,45 @@ public class CommandExecutor {
|
|||||||
processResult = process.exitValue();
|
processResult = process.exitValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("current shell command {} result is {}", processBuilder.command(), processResult);
|
log.debug(
|
||||||
|
"current shell command {} result is {}",
|
||||||
|
processBuilder.command(),
|
||||||
|
processResult
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
log.error("Shell command error ! {} + {}", e.getCause(), e.getMessage());
|
log.error(
|
||||||
|
"Shell command error ! {} + {}",
|
||||||
|
e.getCause(),
|
||||||
|
e.getMessage()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return processResult;
|
return processResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable StopStuckCommandProcess(Process process, int processMaxWaitSeconds) {
|
private Runnable StopStuckCommandProcess(Process process, int processMaxWaitSeconds) {
|
||||||
return () -> {
|
return () -> {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
log.debug("daemon thread start to wait for {} s for the result", processMaxWaitSeconds);
|
log.debug(
|
||||||
|
"daemon thread start to wait for {} s for the result",
|
||||||
|
processMaxWaitSeconds
|
||||||
|
);
|
||||||
|
|
||||||
TimeUnit.SECONDS.sleep(processMaxWaitSeconds);
|
TimeUnit.SECONDS.sleep(processMaxWaitSeconds);
|
||||||
|
|
||||||
if (process.isAlive()) {
|
if (process.isAlive()) {
|
||||||
|
|
||||||
log.warn("Command [ {} ] stuck for {} s, destroy the command process !", process.info().commandLine().get(), processMaxWaitSeconds);
|
log.warn(
|
||||||
|
"Command [ {} ] stuck for {} s, destroy the command process !",
|
||||||
|
process
|
||||||
|
.info()
|
||||||
|
.commandLine()
|
||||||
|
.get(),
|
||||||
|
processMaxWaitSeconds
|
||||||
|
);
|
||||||
|
|
||||||
// shutdown the process
|
// shutdown the process
|
||||||
process.destroyForcibly();
|
process.destroyForcibly();
|
||||||
@@ -158,7 +189,9 @@ public class CommandExecutor {
|
|||||||
TimeUnit.SECONDS.sleep(1);
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
|
||||||
// clear the log Cache Thread scope
|
// clear the log Cache Thread scope
|
||||||
logToArrayListCache.getExecutionCmdCachedLogArrayList(streamKey).clear();
|
logToArrayListCache
|
||||||
|
.getExecutionCmdCachedLogArrayList(streamKey)
|
||||||
|
.clear();
|
||||||
|
|
||||||
// clear the stream sender
|
// clear the stream sender
|
||||||
streamSender.clearLocalCache(streamKey);
|
streamSender.clearLocalCache(streamKey);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package io.wdd.agent.executor.config;
|
package io.wdd.common.utils;
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -17,7 +17,7 @@ import java.util.stream.Collectors;
|
|||||||
public class FunctionReader {
|
public class FunctionReader {
|
||||||
|
|
||||||
|
|
||||||
public List<List<String>> ReadFileToCommandList(String functionFilePath) {
|
public static List<List<String>> ReadFileToCommandList(String functionFilePath) {
|
||||||
|
|
||||||
// https://www.digitalocean.com/community/tutorials/java-read-file-line-by-line
|
// https://www.digitalocean.com/community/tutorials/java-read-file-line-by-line
|
||||||
|
|
||||||
@@ -26,7 +26,10 @@ public class FunctionReader {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
BufferedReader bufferedReader = new BufferedReader(new FileReader(functionFilePath));
|
BufferedReader bufferedReader = new BufferedReader(new FileReader(functionFilePath));
|
||||||
result = doReadContent(result, bufferedReader);
|
result = doReadContent(
|
||||||
|
result,
|
||||||
|
bufferedReader
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -38,15 +41,19 @@ public class FunctionReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<List<String>> ReadStringToCommandList(String functionContent) {
|
public static List<List<String>> ReadStringToCommandList(String functionContent) {
|
||||||
|
|
||||||
List<List<String>> result = null;
|
List<List<String>> result = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 构造一个 buffered Reader
|
||||||
BufferedReader bufferedReader = new BufferedReader(new StringReader(functionContent));
|
BufferedReader bufferedReader = new BufferedReader(new StringReader(functionContent));
|
||||||
result = doReadContent(result, bufferedReader);
|
|
||||||
|
|
||||||
|
// 执行read操作
|
||||||
|
result = doReadContent(
|
||||||
|
result,
|
||||||
|
bufferedReader
|
||||||
|
);
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@@ -56,7 +63,8 @@ public class FunctionReader {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<List<String>> doReadContent(List<List<String>> result, BufferedReader bufferedReader) throws IOException {
|
private static List<List<String>> doReadContent(List<List<String>> result, BufferedReader bufferedReader) throws IOException {
|
||||||
|
|
||||||
String line = bufferedReader.readLine();
|
String line = bufferedReader.readLine();
|
||||||
|
|
||||||
if (line != null) {
|
if (line != null) {
|
||||||
@@ -65,16 +73,19 @@ public class FunctionReader {
|
|||||||
|
|
||||||
while (line != null) {
|
while (line != null) {
|
||||||
if (!StringUtils.isEmpty(line)) {
|
if (!StringUtils.isEmpty(line)) {
|
||||||
result.add(this.SplitLineToCommandList(line));
|
result.add(SplitLineToCommandList(line));
|
||||||
}
|
}
|
||||||
line = bufferedReader.readLine();
|
line = bufferedReader.readLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> SplitLineToCommandList(String commandLine) {
|
public static List<String> SplitLineToCommandList(String commandLine) {
|
||||||
|
|
||||||
return Arrays.stream(commandLine.split(" ")).collect(Collectors.toList());
|
return Arrays
|
||||||
|
.stream(commandLine.split(" "))
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -5,6 +5,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.beans.response.R;
|
import io.wdd.common.beans.response.R;
|
||||||
|
import io.wdd.rpc.scheduler.beans.ScriptSchedulerVO;
|
||||||
import io.wdd.rpc.scheduler.service.QuartzSchedulerService;
|
import io.wdd.rpc.scheduler.service.QuartzSchedulerService;
|
||||||
import org.quartz.Trigger;
|
import org.quartz.Trigger;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -22,38 +23,63 @@ public class SchedulerController {
|
|||||||
QuartzSchedulerService octopusQuartzService;
|
QuartzSchedulerService octopusQuartzService;
|
||||||
|
|
||||||
|
|
||||||
@ApiOperation(value = "查询所有job")
|
/**
|
||||||
@GetMapping(value = "/queryAllJob")
|
* --------------------------------------------------------------
|
||||||
public R<List<Map<String, Object>>> queryAllQuartzJob() {
|
* 页面定时任务部分
|
||||||
|
* 应该只有脚本功能才可以定时,目前一阶段的功能
|
||||||
|
* */
|
||||||
|
|
||||||
return R.ok(octopusQuartzService.queryAllJob());
|
@ApiOperation(value = "新增一个定时脚本任务")
|
||||||
}
|
@PostMapping(value = "/script/create")
|
||||||
|
public R<String> createScriptScheduler(
|
||||||
|
@ApiParam(name = "scheduleScript") @RequestBody() ScriptSchedulerVO scriptSchedulerVO
|
||||||
@ApiOperation(value = "查询所有运行job")
|
|
||||||
@PostMapping(value = "/queryRunJob")
|
|
||||||
public R<List<Map<String, Object>>> queryRunQuartzJob() {
|
|
||||||
|
|
||||||
return R.ok(octopusQuartzService.queryRunJob());
|
|
||||||
}
|
|
||||||
|
|
||||||
@ApiOperation(value = "删除一个job")
|
|
||||||
@PostMapping(value = "/deleteJob/")
|
|
||||||
public R<String> deleteJob(
|
|
||||||
@ApiParam(name = "jobName") @RequestParam("jobName") String jobName
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
boolean deleteJob = octopusQuartzService.deleteJob(
|
octopusQuartzService.createScriptScheduledMission(scriptSchedulerVO);
|
||||||
jobName,
|
|
||||||
jobName
|
return R.ok("ok");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------
|
||||||
|
* 普通的定时任务查询功能
|
||||||
|
* */
|
||||||
|
|
||||||
|
@ApiOperation(value = "查询所有mission")
|
||||||
|
@GetMapping(value = "/queryAllMission")
|
||||||
|
public R<List<Map<String, Object>>> queryAllQuartzMission() {
|
||||||
|
|
||||||
|
return R.ok(octopusQuartzService.queryAllMission());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation(value = "查询所有运行mission")
|
||||||
|
@PostMapping(value = "/queryRunMission")
|
||||||
|
public R<List<Map<String, Object>>> queryRunQuartzMission() {
|
||||||
|
|
||||||
|
return R.ok(octopusQuartzService.queryRunMission());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation(value = "删除一个mission")
|
||||||
|
@PostMapping(value = "/deleteMission/")
|
||||||
|
public R<String> deleteMission(
|
||||||
|
@ApiParam(name = "missionName") @RequestParam("missionName") String missionName
|
||||||
|
) {
|
||||||
|
|
||||||
|
boolean deleteMission = octopusQuartzService.deleteMission(
|
||||||
|
missionName,
|
||||||
|
missionName
|
||||||
);
|
);
|
||||||
String result = String.format(
|
String result = String.format(
|
||||||
"删除任务[ %s ]结果为 [ %s ]",
|
"删除任务[ %s ]结果为 [ %s ]",
|
||||||
jobName,
|
missionName,
|
||||||
deleteJob
|
deleteMission
|
||||||
);
|
);
|
||||||
|
|
||||||
if (deleteJob) {
|
if (deleteMission) {
|
||||||
return R.ok(result);
|
return R.ok(result);
|
||||||
} else {
|
} else {
|
||||||
return R.failed(result);
|
return R.failed(result);
|
||||||
@@ -61,17 +87,17 @@ public class SchedulerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ApiOperation(value = "修改job的cron时间")
|
@ApiOperation(value = "修改mission的cron时间")
|
||||||
@PostMapping(value = "/updateJob/{jobName}")
|
@PostMapping(value = "/updateMission/{missionName}")
|
||||||
public void deleteJob(
|
public void deleteMission(
|
||||||
@ApiParam(name = "jobName") @RequestParam("jobName") String jobName,
|
@ApiParam(name = "missionName") @RequestParam("missionName") String missionName,
|
||||||
@ApiParam(name = "jobCronTime") @RequestParam("jobCronTime") String jobCronTime
|
@ApiParam(name = "missionCronTime") @RequestParam("missionCronTime") String missionCronTime
|
||||||
) {
|
) {
|
||||||
|
|
||||||
octopusQuartzService.updateJob(
|
octopusQuartzService.updateMission(
|
||||||
jobName,
|
missionName,
|
||||||
jobName,
|
missionName,
|
||||||
jobCronTime
|
missionCronTime
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static io.wdd.rpc.status.MonitorAllAgentStatus.ALL_AGENT_HEALTHY_STATUS_MAP;
|
import static io.wdd.rpc.scheduler.service.status.MonitorAllAgentStatus.ALL_AGENT_HEALTHY_STATUS_MAP;
|
||||||
import static io.wdd.rpc.status.MonitorAllAgentStatus.HEALTHY_STATUS_AGENT_LIST_MAP;
|
import static io.wdd.rpc.scheduler.service.status.MonitorAllAgentStatus.HEALTHY_STATUS_AGENT_LIST_MAP;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@Api("Agent运行状态Controller")
|
@Api("Agent运行状态Controller")
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package io.wdd.rpc.execute.result;
|
package io.wdd.rpc.execute.result;
|
||||||
|
|
||||||
|
|
||||||
import io.wdd.rpc.execute.config.CommandReaderConfig;
|
import io.wdd.rpc.scheduler.service.status.AgentStatusStreamReader;
|
||||||
import io.wdd.rpc.status.AgentStatusStreamReader;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static io.wdd.rpc.execute.service.ExecutionResultDaemonHandler.WAIT_EXECUTION_RESULT_LIST;
|
import static io.wdd.rpc.execute.service.ExecutionResultDaemonHandler.WAIT_EXECUTION_RESULT_LIST;
|
||||||
import static io.wdd.rpc.status.MonitorAllAgentStatus.ALL_AGENT_TOPIC_NAME_SET;
|
import static io.wdd.rpc.scheduler.service.status.MonitorAllAgentStatus.ALL_AGENT_TOPIC_NAME_SET;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package io.wdd.rpc.scheduler.beans;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@ApiModel("定时脚本任务-中间转换状态-实体类")
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder(toBuilder = true)
|
||||||
|
public class ScriptSchedulerDTO extends ScriptSchedulerVO{
|
||||||
|
|
||||||
|
List<List<String>> commandList;
|
||||||
|
|
||||||
|
List<String> targetMachineList;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package io.wdd.rpc.scheduler.beans;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder(toBuilder = true)
|
||||||
|
@ApiModel("定时脚本任务的VO实体类")
|
||||||
|
public class ScriptSchedulerVO {
|
||||||
|
|
||||||
|
public static final String SCHEDULE_MISSION_GROUP_NAME = "SCRIPT_SCHEDULER";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableId(value = "scheduler_uuid")
|
||||||
|
@Nullable
|
||||||
|
private String schedulerUuid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableField(value = "name")
|
||||||
|
@NotNull
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableField(value = "cron_express")
|
||||||
|
@NotNull
|
||||||
|
private String cronExpress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableField(value = "description")
|
||||||
|
@Nullable
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 脚本任务的内容
|
||||||
|
*/
|
||||||
|
@TableField(value = "script_content")
|
||||||
|
@NotNull
|
||||||
|
private String scriptContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行目标机器agent_topic_name列表,使用, 分隔
|
||||||
|
*/
|
||||||
|
@TableField(value = "target_machine")
|
||||||
|
@Nullable
|
||||||
|
private String targetMachine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与 execution_log表的主键对应,方便查询执行日志
|
||||||
|
*/
|
||||||
|
@TableField(value = "last_execution_id")
|
||||||
|
@Nullable
|
||||||
|
private Long lastExecutionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与 execution_log表的 result_key 对应,方便查询执行日志
|
||||||
|
*/
|
||||||
|
@TableField(value = "last_execution_result_key")
|
||||||
|
@Nullable
|
||||||
|
private String lastExecutionResultKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务上次执行状态
|
||||||
|
*/
|
||||||
|
@TableField(value = "last_execution_status")
|
||||||
|
@Nullable
|
||||||
|
private Integer lastExecutionStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定时脚本任务创建时间
|
||||||
|
*/
|
||||||
|
@TableField(value = "create_time")
|
||||||
|
@NotNull
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次更新时间
|
||||||
|
*/
|
||||||
|
@TableField(value = "update_time")
|
||||||
|
@Nullable
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务下次计划执行时间
|
||||||
|
*/
|
||||||
|
@TableField(value = "next_schedule_time")
|
||||||
|
@Nullable
|
||||||
|
private LocalDateTime nextScheduleTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务上次计划执行时间
|
||||||
|
*/
|
||||||
|
@TableField(value = "last_schedule_time")
|
||||||
|
@Nullable
|
||||||
|
private LocalDateTime lastScheduleTime;
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.wdd.rpc.scheduler.job;
|
package io.wdd.rpc.scheduler.job;
|
||||||
|
|
||||||
import io.wdd.rpc.status.AgentRuntimeMetricStatus;
|
import io.wdd.rpc.scheduler.service.status.AgentRuntimeMetricStatus;
|
||||||
import org.quartz.JobDataMap;
|
import org.quartz.JobDataMap;
|
||||||
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionContext;
|
||||||
import org.quartz.JobExecutionException;
|
import org.quartz.JobExecutionException;
|
||||||
@@ -8,8 +8,8 @@ import org.springframework.scheduling.quartz.QuartzJobBean;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
import static io.wdd.rpc.status.AgentRuntimeMetricStatus.METRIC_REPORT_TIMES_COUNT;
|
import static io.wdd.rpc.scheduler.service.status.AgentRuntimeMetricStatus.METRIC_REPORT_TIMES_COUNT;
|
||||||
import static io.wdd.rpc.status.AgentRuntimeMetricStatus.METRIC_REPORT_TIME_PINCH;
|
import static io.wdd.rpc.scheduler.service.status.AgentRuntimeMetricStatus.METRIC_REPORT_TIME_PINCH;
|
||||||
|
|
||||||
public class AgentRunMetricStatusJob extends QuartzJobBean {
|
public class AgentRunMetricStatusJob extends QuartzJobBean {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package io.wdd.rpc.scheduler.job;
|
||||||
|
|
||||||
|
|
||||||
|
import io.wdd.rpc.scheduler.beans.ScriptSchedulerDTO;
|
||||||
|
import io.wdd.rpc.scheduler.service.script.AgentApplyScheduledScript;
|
||||||
|
import io.wdd.server.beans.po.ScriptSchedulerPO;
|
||||||
|
import org.quartz.JobDataMap;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
public class AgentScriptSchedulerJob extends QuartzJobBean {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
AgentApplyScheduledScript agentApplyScheduledScript;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||||
|
|
||||||
|
// 解析 Scheduler 模块传递过来的参数
|
||||||
|
JobDataMap jobDataMap = jobExecutionContext
|
||||||
|
.getJobDetail()
|
||||||
|
.getJobDataMap();
|
||||||
|
|
||||||
|
// ScriptScheduleDTO
|
||||||
|
ScriptSchedulerDTO scriptSchedulerDTO = (ScriptSchedulerDTO) jobDataMap.get("scriptSchedulerPO");
|
||||||
|
|
||||||
|
// 调用实际任务执行器
|
||||||
|
agentApplyScheduledScript.apply(scriptSchedulerDTO);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
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.status.MonitorAllAgentStatus;
|
import io.wdd.rpc.scheduler.service.status.MonitorAllAgentStatus;
|
||||||
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;
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import java.text.ParseException;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import static io.wdd.rpc.status.AgentRuntimeMetricStatus.METRIC_REPORT_TIMES_COUNT;
|
import static io.wdd.rpc.scheduler.service.status.AgentRuntimeMetricStatus.METRIC_REPORT_TIMES_COUNT;
|
||||||
import static io.wdd.rpc.status.AgentRuntimeMetricStatus.METRIC_REPORT_TIME_PINCH;
|
import static io.wdd.rpc.scheduler.service.status.AgentRuntimeMetricStatus.METRIC_REPORT_TIME_PINCH;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -80,7 +80,7 @@ public class BuildStatusScheduleTask {
|
|||||||
|
|
||||||
// build the Job 只发送一次消息,然后让Agent获取消息 (重复间隔,重复次数) 进行相应的处理!
|
// build the Job 只发送一次消息,然后让Agent获取消息 (重复间隔,重复次数) 进行相应的处理!
|
||||||
// todo 解决创建太多对象的问题,需要缓存相应的内容
|
// todo 解决创建太多对象的问题,需要缓存相应的内容
|
||||||
octopusQuartzService.addJob(
|
octopusQuartzService.addMission(
|
||||||
AgentRunMetricStatusJob.class,
|
AgentRunMetricStatusJob.class,
|
||||||
"agentRunMetricStatusJob",
|
"agentRunMetricStatusJob",
|
||||||
JOB_GROUP_NAME,
|
JOB_GROUP_NAME,
|
||||||
@@ -101,7 +101,7 @@ public class BuildStatusScheduleTask {
|
|||||||
private void buildMonitorAllAgentStatusScheduleTask() {
|
private void buildMonitorAllAgentStatusScheduleTask() {
|
||||||
|
|
||||||
// build the Job
|
// build the Job
|
||||||
octopusQuartzService.addJob(
|
octopusQuartzService.addMission(
|
||||||
AgentStatusMonitorJob.class,
|
AgentStatusMonitorJob.class,
|
||||||
"monitorAllAgentStatusJob",
|
"monitorAllAgentStatusJob",
|
||||||
JOB_GROUP_NAME,
|
JOB_GROUP_NAME,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.wdd.rpc.scheduler.service;
|
package io.wdd.rpc.scheduler.service;
|
||||||
|
|
||||||
import io.wdd.rpc.scheduler.beans.OctopusQuartzJob;
|
import io.wdd.rpc.scheduler.beans.OctopusQuartzJob;
|
||||||
|
import io.wdd.rpc.scheduler.beans.ScriptSchedulerVO;
|
||||||
import org.quartz.Trigger;
|
import org.quartz.Trigger;
|
||||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -10,7 +11,7 @@ import java.util.Map;
|
|||||||
public interface QuartzSchedulerService {
|
public interface QuartzSchedulerService {
|
||||||
|
|
||||||
|
|
||||||
boolean addJob(OctopusQuartzJob quartzJob);
|
boolean addMission(OctopusQuartzJob quartzJob);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增加一个任务job
|
* 增加一个任务job
|
||||||
@@ -21,7 +22,7 @@ public interface QuartzSchedulerService {
|
|||||||
* @param jobRunRepeatTimes 任务运行次数(若<0,则不限次数)
|
* @param jobRunRepeatTimes 任务运行次数(若<0,则不限次数)
|
||||||
* @param jobData 任务参数
|
* @param jobData 任务参数
|
||||||
*/
|
*/
|
||||||
void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobRunTimePinch, int jobRunRepeatTimes, Map jobData);
|
void addMission(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobRunTimePinch, int jobRunRepeatTimes, Map jobData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增加一个任务job
|
* 增加一个任务job
|
||||||
@@ -33,7 +34,7 @@ public interface QuartzSchedulerService {
|
|||||||
* @param cronJobExpression 任务时间表达式
|
* @param cronJobExpression 任务时间表达式
|
||||||
* @param jobData 任务参数
|
* @param jobData 任务参数
|
||||||
*/
|
*/
|
||||||
void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int startTime, String cronJobExpression, Map jobData);
|
void addMission(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int startTime, String cronJobExpression, Map jobData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改一个任务job
|
* 修改一个任务job
|
||||||
@@ -41,7 +42,7 @@ public interface QuartzSchedulerService {
|
|||||||
* @param jobGroupName 任务组名
|
* @param jobGroupName 任务组名
|
||||||
* @param jobTime cron时间表达式
|
* @param jobTime cron时间表达式
|
||||||
*/
|
*/
|
||||||
void updateJob(String jobName, String jobGroupName, String jobTime);
|
void updateMission(String jobName, String jobGroupName, String jobTime);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,21 +52,21 @@ public interface QuartzSchedulerService {
|
|||||||
* @param jobGroupName
|
* @param jobGroupName
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean deleteJob(String jobName, String jobGroupName);
|
boolean deleteMission(String jobName, String jobGroupName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 暂停一个任务job
|
* 暂停一个任务job
|
||||||
* @param jobName
|
* @param jobName
|
||||||
* @param jobGroupName
|
* @param jobGroupName
|
||||||
*/
|
*/
|
||||||
void pauseJob(String jobName, String jobGroupName);
|
void pauseMission(String jobName, String jobGroupName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 恢复一个任务job
|
* 恢复一个任务job
|
||||||
* @param jobName
|
* @param jobName
|
||||||
* @param jobGroupName
|
* @param jobGroupName
|
||||||
*/
|
*/
|
||||||
void resumeJob(String jobName, String jobGroupName);
|
void resumeMission(String jobName, String jobGroupName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 立即执行一个任务job
|
* 立即执行一个任务job
|
||||||
@@ -78,13 +79,13 @@ public interface QuartzSchedulerService {
|
|||||||
* 获取所有任务job
|
* 获取所有任务job
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<Map<String, Object>> queryAllJob();
|
List<Map<String, Object>> queryAllMission();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取正在运行的任务job
|
* 获取正在运行的任务job
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<Map<String, Object>> queryRunJob();
|
List<Map<String, Object>> queryRunMission();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,4 +95,12 @@ public interface QuartzSchedulerService {
|
|||||||
List<Trigger> queryAllTrigger();
|
List<Trigger> queryAllTrigger();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------
|
||||||
|
* 页面定时任务部分
|
||||||
|
* 应该只有脚本功能才可以定时,目前一阶段的功能
|
||||||
|
* */
|
||||||
|
void createScriptScheduledMission(ScriptSchedulerVO scriptSchedulerVO);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
package io.wdd.rpc.scheduler.service;
|
package io.wdd.rpc.scheduler.service;
|
||||||
|
|
||||||
import io.wdd.common.handler.MyRuntimeException;
|
import io.wdd.common.handler.MyRuntimeException;
|
||||||
|
import io.wdd.common.utils.FunctionReader;
|
||||||
import io.wdd.rpc.scheduler.beans.OctopusQuartzJob;
|
import io.wdd.rpc.scheduler.beans.OctopusQuartzJob;
|
||||||
|
import io.wdd.rpc.scheduler.beans.ScriptSchedulerDTO;
|
||||||
|
import io.wdd.rpc.scheduler.beans.ScriptSchedulerVO;
|
||||||
|
import io.wdd.rpc.scheduler.job.AgentScriptSchedulerJob;
|
||||||
|
import io.wdd.server.beans.po.ScriptSchedulerPO;
|
||||||
|
import io.wdd.server.service.ScriptSchedulerService;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.beanutils.BeanUtils;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.quartz.*;
|
import org.quartz.*;
|
||||||
import org.quartz.DateBuilder.IntervalUnit;
|
import org.quartz.DateBuilder.IntervalUnit;
|
||||||
import org.quartz.impl.matchers.GroupMatcher;
|
import org.quartz.impl.matchers.GroupMatcher;
|
||||||
@@ -12,9 +22,11 @@ import org.springframework.scheduling.quartz.QuartzJobBean;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static io.wdd.rpc.scheduler.beans.ScriptSchedulerVO.SCHEDULE_MISSION_GROUP_NAME;
|
||||||
import static io.wdd.rpc.scheduler.service.BuildStatusScheduleTask.JOB_GROUP_NAME;
|
import static io.wdd.rpc.scheduler.service.BuildStatusScheduleTask.JOB_GROUP_NAME;
|
||||||
import static org.quartz.TriggerBuilder.newTrigger;
|
import static org.quartz.TriggerBuilder.newTrigger;
|
||||||
|
|
||||||
@@ -29,6 +41,113 @@ public class QuartzSchedulerServiceImpl implements QuartzSchedulerService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private Scheduler scheduler;
|
private Scheduler scheduler;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ScriptSchedulerService scriptSchedulerService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------------------------
|
||||||
|
* 页面定时任务部分
|
||||||
|
* 应该只有脚本功能才可以定时,目前一阶段的功能
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
@Override
|
||||||
|
public void createScriptScheduledMission(ScriptSchedulerVO scriptSchedulerVO) {
|
||||||
|
|
||||||
|
// validate important value
|
||||||
|
ScriptSchedulerDTO scriptSchedulerDTO = validateAndConvertToScriptSchedulerDTO(scriptSchedulerVO);
|
||||||
|
|
||||||
|
// build the job
|
||||||
|
// build the trigger
|
||||||
|
// bind job and trigger
|
||||||
|
HashMap<String, Object> dataMap = new HashMap<>();
|
||||||
|
dataMap.put("scriptSchedulerDTO", scriptSchedulerDTO);
|
||||||
|
this.addMission(
|
||||||
|
AgentScriptSchedulerJob.class,
|
||||||
|
scriptSchedulerVO.getName(),
|
||||||
|
SCHEDULE_MISSION_GROUP_NAME,
|
||||||
|
1,
|
||||||
|
scriptSchedulerVO.getScriptContent(),
|
||||||
|
dataMap
|
||||||
|
);
|
||||||
|
|
||||||
|
// persistent the script scheduled mission
|
||||||
|
// todo dto should store more info
|
||||||
|
ScriptSchedulerPO scriptSchedulerPO = convertToScriptSchedulerPO(scriptSchedulerDTO);
|
||||||
|
scriptSchedulerService.save(scriptSchedulerPO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换 中间层 --> 持久层
|
||||||
|
*
|
||||||
|
* @param dto 定时脚本任务-中间转换状态-实体类
|
||||||
|
* @return 定时脚本任务-持久化-实体类
|
||||||
|
*/
|
||||||
|
private ScriptSchedulerPO convertToScriptSchedulerPO(ScriptSchedulerDTO dto) {
|
||||||
|
// todo should be a static method
|
||||||
|
return ScriptSchedulerPO
|
||||||
|
.builder()
|
||||||
|
.cronExpress(dto.getCronExpress())
|
||||||
|
.schedulerUuid(dto.getSchedulerUuid())
|
||||||
|
.scriptContent(String.valueOf(dto.getCommandList()))
|
||||||
|
.targetMachine(String.valueOf(dto.getTargetMachineList()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换 视图层 --> 中间层
|
||||||
|
* @param scriptSchedulerVO 定时脚本任务-前端页面-实体类
|
||||||
|
* @return 定时脚本任务-中间转换状态-实体类
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
private ScriptSchedulerDTO validateAndConvertToScriptSchedulerDTO(ScriptSchedulerVO scriptSchedulerVO) {
|
||||||
|
|
||||||
|
// 验证cron表达式
|
||||||
|
if (!CronExpression.isValidExpression(scriptSchedulerVO.getCronExpress())) {
|
||||||
|
throw new MyRuntimeException("cron express wrong !");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 归一化 commandList
|
||||||
|
List<List<String>> commandList = FunctionReader.ReadStringToCommandList(scriptSchedulerVO.getScriptContent());
|
||||||
|
if (commandList.size() == 0) {
|
||||||
|
throw new MyRuntimeException("commandList parse wrong !");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行机器目标归一化
|
||||||
|
String[] targetMachineSplit = scriptSchedulerVO
|
||||||
|
.getTargetMachine()
|
||||||
|
.split(",");
|
||||||
|
if (targetMachineSplit.length == 0) {
|
||||||
|
throw new MyRuntimeException("target machine wrong !");
|
||||||
|
}
|
||||||
|
ArrayList<String> targetMachineList = new ArrayList<>();
|
||||||
|
targetMachineList.stream().forEach(
|
||||||
|
targetMachineList::add
|
||||||
|
);
|
||||||
|
|
||||||
|
// 生成DTO对象
|
||||||
|
ScriptSchedulerDTO dto = new ScriptSchedulerDTO();
|
||||||
|
BeanUtils.copyProperties(dto,scriptSchedulerVO);
|
||||||
|
|
||||||
|
// 设置属性值
|
||||||
|
dto.setCommandList(null);
|
||||||
|
dto.setTargetMachineList(targetMachineList);
|
||||||
|
|
||||||
|
// 生成 scheduler uuid
|
||||||
|
String uuid = RandomStringUtils.randomAlphabetic(32);
|
||||||
|
dto.setSchedulerUuid(uuid);
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void startScheduler() {
|
public void startScheduler() {
|
||||||
try {
|
try {
|
||||||
@@ -39,7 +158,7 @@ public class QuartzSchedulerServiceImpl implements QuartzSchedulerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addJob(OctopusQuartzJob quartzJob) {
|
public boolean addMission(OctopusQuartzJob quartzJob) {
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -56,7 +175,7 @@ public class QuartzSchedulerServiceImpl implements QuartzSchedulerService {
|
|||||||
* @param jobData 参数
|
* @param jobData 参数
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobRunTimePinch, int jobRunRepeatTimes, Map jobData) {
|
public void addMission(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobRunTimePinch, int jobRunRepeatTimes, Map jobData) {
|
||||||
try {
|
try {
|
||||||
// 任务名称和组构成任务key
|
// 任务名称和组构成任务key
|
||||||
JobDetail jobDetail = JobBuilder
|
JobDetail jobDetail = JobBuilder
|
||||||
@@ -119,7 +238,7 @@ public class QuartzSchedulerServiceImpl implements QuartzSchedulerService {
|
|||||||
* @param jobData 参数
|
* @param jobData 参数
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int startTime, String cronJobExpression, Map jobData) {
|
public void addMission(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int startTime, String cronJobExpression, Map jobData) {
|
||||||
try {
|
try {
|
||||||
// 创建jobDetail实例,绑定Job实现类
|
// 创建jobDetail实例,绑定Job实现类
|
||||||
// 指明job的名称,所在组的名称,以及绑定job类
|
// 指明job的名称,所在组的名称,以及绑定job类
|
||||||
@@ -188,7 +307,7 @@ public class QuartzSchedulerServiceImpl implements QuartzSchedulerService {
|
|||||||
* @param jobTime
|
* @param jobTime
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateJob(String jobName, String jobGroupName, String jobTime) {
|
public void updateMission(String jobName, String jobGroupName, String jobTime) {
|
||||||
try {
|
try {
|
||||||
TriggerKey triggerKey = TriggerKey.triggerKey(
|
TriggerKey triggerKey = TriggerKey.triggerKey(
|
||||||
jobName,
|
jobName,
|
||||||
@@ -223,7 +342,7 @@ public class QuartzSchedulerServiceImpl implements QuartzSchedulerService {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteJob(String jobName, String jobGroupName) {
|
public boolean deleteMission(String jobName, String jobGroupName) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
scheduler.deleteJob(new JobKey(
|
scheduler.deleteJob(new JobKey(
|
||||||
@@ -245,7 +364,7 @@ public class QuartzSchedulerServiceImpl implements QuartzSchedulerService {
|
|||||||
* @param jobGroupName
|
* @param jobGroupName
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void pauseJob(String jobName, String jobGroupName) {
|
public void pauseMission(String jobName, String jobGroupName) {
|
||||||
try {
|
try {
|
||||||
JobKey jobKey = JobKey.jobKey(
|
JobKey jobKey = JobKey.jobKey(
|
||||||
jobName,
|
jobName,
|
||||||
@@ -265,7 +384,7 @@ public class QuartzSchedulerServiceImpl implements QuartzSchedulerService {
|
|||||||
* @param jobGroupName
|
* @param jobGroupName
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void resumeJob(String jobName, String jobGroupName) {
|
public void resumeMission(String jobName, String jobGroupName) {
|
||||||
try {
|
try {
|
||||||
JobKey jobKey = JobKey.jobKey(
|
JobKey jobKey = JobKey.jobKey(
|
||||||
jobName,
|
jobName,
|
||||||
@@ -304,7 +423,7 @@ public class QuartzSchedulerServiceImpl implements QuartzSchedulerService {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Map<String, Object>> queryAllJob() {
|
public List<Map<String, Object>> queryAllMission() {
|
||||||
List<Map<String, Object>> jobList = null;
|
List<Map<String, Object>> jobList = null;
|
||||||
try {
|
try {
|
||||||
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
|
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
|
||||||
@@ -362,7 +481,7 @@ public class QuartzSchedulerServiceImpl implements QuartzSchedulerService {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Map<String, Object>> queryRunJob() {
|
public List<Map<String, Object>> queryRunMission() {
|
||||||
List<Map<String, Object>> jobList = null;
|
List<Map<String, Object>> jobList = null;
|
||||||
try {
|
try {
|
||||||
List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
|
List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
|
||||||
@@ -432,4 +551,7 @@ public class QuartzSchedulerServiceImpl implements QuartzSchedulerService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package io.wdd.rpc.scheduler.service.script;
|
||||||
|
|
||||||
|
|
||||||
|
import io.wdd.rpc.execute.service.CoreExecutionService;
|
||||||
|
import io.wdd.rpc.scheduler.beans.ScriptSchedulerDTO;
|
||||||
|
import io.wdd.server.beans.po.ScriptSchedulerPO;
|
||||||
|
import lombok.extern.log4j.Log4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Log4j
|
||||||
|
public class AgentApplyScheduledScript {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
CoreExecutionService coreExecutionService;
|
||||||
|
|
||||||
|
public void apply(ScriptSchedulerDTO scriptSchedulerDTO) {
|
||||||
|
|
||||||
|
List<List<String>> commandList = scriptSchedulerDTO.getCommandList();
|
||||||
|
List<String> targetMachineList = scriptSchedulerDTO.getTargetMachineList();
|
||||||
|
|
||||||
|
targetMachineList
|
||||||
|
.stream()
|
||||||
|
.map(
|
||||||
|
targetMachine -> {
|
||||||
|
coreExecutionService.SendCommandToAgent()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package io.wdd.rpc.status;
|
package io.wdd.rpc.scheduler.service.status;
|
||||||
|
|
||||||
|
|
||||||
import io.wdd.common.beans.status.OctopusStatusMessage;
|
import io.wdd.common.beans.status.OctopusStatusMessage;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package io.wdd.rpc.status;
|
package io.wdd.rpc.scheduler.service.status;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package io.wdd.rpc.status;
|
package io.wdd.rpc.scheduler.service.status;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package io.wdd.rpc.status;
|
package io.wdd.rpc.scheduler.service.status;
|
||||||
|
|
||||||
import io.wdd.common.beans.status.AgentHealthyStatusEnum;
|
import io.wdd.common.beans.status.AgentHealthyStatusEnum;
|
||||||
import io.wdd.common.beans.status.OctopusStatusMessage;
|
import io.wdd.common.beans.status.OctopusStatusMessage;
|
||||||
@@ -18,7 +18,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import static io.wdd.common.beans.status.OctopusStatusMessage.ALL_AGENT_STATUS_REDIS_KEY;
|
import static io.wdd.common.beans.status.OctopusStatusMessage.ALL_AGENT_STATUS_REDIS_KEY;
|
||||||
import static io.wdd.common.beans.status.OctopusStatusMessage.HEALTHY_STATUS_MESSAGE_TYPE;
|
import static io.wdd.common.beans.status.OctopusStatusMessage.HEALTHY_STATUS_MESSAGE_TYPE;
|
||||||
import static io.wdd.rpc.status.AgentRuntimeMetricStatus.ALL_HEALTHY_AGENT_TOPIC_NAMES;
|
import static io.wdd.rpc.scheduler.service.status.AgentRuntimeMetricStatus.ALL_HEALTHY_AGENT_TOPIC_NAMES;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新频率被类 BuildStatusScheduleTask.class控制
|
* 更新频率被类 BuildStatusScheduleTask.class控制
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package io.wdd.server.beans.po;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @TableName script_scheduler
|
||||||
|
*/
|
||||||
|
@TableName(value ="script_scheduler")
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder(toBuilder = true)
|
||||||
|
@ApiModel("定时脚本任务-持久化-实体类")
|
||||||
|
public class ScriptSchedulerPO implements Serializable {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableId(value = "scheduler_uuid")
|
||||||
|
private String schedulerUuid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableField(value = "name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableField(value = "cron_express")
|
||||||
|
private String cronExpress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableField(value = "description")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 脚本任务的内容
|
||||||
|
*/
|
||||||
|
@TableField(value = "script_content")
|
||||||
|
private String scriptContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行目标机器agent_topic_name列表,使用, 分隔
|
||||||
|
*/
|
||||||
|
@TableField(value = "target_machine")
|
||||||
|
private String targetMachine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与 execution_log表的主键对应,方便查询执行日志
|
||||||
|
*/
|
||||||
|
@TableField(value = "last_execution_id")
|
||||||
|
private Long lastExecutionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与 execution_log表的 result_key 对应,方便查询执行日志
|
||||||
|
*/
|
||||||
|
@TableField(value = "last_execution_result_key")
|
||||||
|
private String lastExecutionResultKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务上次执行状态
|
||||||
|
*/
|
||||||
|
@TableField(value = "last_execution_status")
|
||||||
|
private Integer lastExecutionStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定时脚本任务创建时间
|
||||||
|
*/
|
||||||
|
@TableField(value = "create_time")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次更新时间
|
||||||
|
*/
|
||||||
|
@TableField(value = "update_time")
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务下次计划执行时间
|
||||||
|
*/
|
||||||
|
@TableField(value = "next_schedule_time")
|
||||||
|
private LocalDateTime nextScheduleTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务上次计划执行时间
|
||||||
|
*/
|
||||||
|
@TableField(value = "last_schedule_time")
|
||||||
|
private LocalDateTime lastScheduleTime;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package io.wdd.server.mapper;
|
||||||
|
|
||||||
|
import io.wdd.server.beans.po.ScriptSchedulerPO;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wdd
|
||||||
|
* @description 针对表【script_scheduler】的数据库操作Mapper
|
||||||
|
* @createDate 2023-01-17 10:29:22
|
||||||
|
* @Entity io.wdd.server.beans.po.ScriptSchedulerPO
|
||||||
|
*/
|
||||||
|
public interface ScriptSchedulerMapper extends BaseMapper<ScriptSchedulerPO> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package io.wdd.server.service;
|
||||||
|
|
||||||
|
import io.wdd.server.beans.po.ScriptSchedulerPO;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wdd
|
||||||
|
* @description 针对表【script_scheduler】的数据库操作Service
|
||||||
|
* @createDate 2023-01-17 10:29:22
|
||||||
|
*/
|
||||||
|
public interface ScriptSchedulerService extends IService<ScriptSchedulerPO> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package io.wdd.server.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import io.wdd.server.beans.po.ScriptSchedulerPO;
|
||||||
|
import io.wdd.server.service.ScriptSchedulerService;
|
||||||
|
import io.wdd.server.mapper.ScriptSchedulerMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wdd
|
||||||
|
* @description 针对表【script_scheduler】的数据库操作Service实现
|
||||||
|
* @createDate 2023-01-17 10:29:22
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ScriptSchedulerServiceImpl extends ServiceImpl<ScriptSchedulerMapper, ScriptSchedulerPO>
|
||||||
|
implements ScriptSchedulerService{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
30
server/src/main/resources/mapper/ScriptSchedulerMapper.xml
Normal file
30
server/src/main/resources/mapper/ScriptSchedulerMapper.xml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="io.wdd.server.mapper.ScriptSchedulerMapper">
|
||||||
|
|
||||||
|
<resultMap id="BaseResultMap" type="io.wdd.server.beans.po.ScriptSchedulerPO">
|
||||||
|
<id property="schedulerUuid" column="scheduler_uuid" jdbcType="VARCHAR"/>
|
||||||
|
<result property="name" column="name" jdbcType="VARCHAR"/>
|
||||||
|
<result property="cronExpress" column="cron_express" jdbcType="VARCHAR"/>
|
||||||
|
<result property="description" column="description" jdbcType="VARCHAR"/>
|
||||||
|
<result property="scriptContent" column="script_content" jdbcType="VARCHAR"/>
|
||||||
|
<result property="targetMachine" column="target_machine" jdbcType="VARCHAR"/>
|
||||||
|
<result property="lastExecutionId" column="last_execution_id" jdbcType="BIGINT"/>
|
||||||
|
<result property="lastExecutionResultKey" column="last_execution_result_key" jdbcType="VARCHAR"/>
|
||||||
|
<result property="lastExecutionStatus" column="last_execution_status" jdbcType="TINYINT"/>
|
||||||
|
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||||
|
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||||
|
<result property="nextScheduleTime" column="next_schedule_time" jdbcType="TIMESTAMP"/>
|
||||||
|
<result property="lastScheduleTime" column="last_schedule_time" jdbcType="TIMESTAMP"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
scheduler_uuid,name,cron_express,
|
||||||
|
description,script_content,target_machine,
|
||||||
|
last_execution_id,last_execution_result_key,last_execution_status,
|
||||||
|
create_time,update_time,next_schedule_time,
|
||||||
|
last_schedule_time
|
||||||
|
</sql>
|
||||||
|
</mapper>
|
||||||
Reference in New Issue
Block a user