diff --git a/common/src/main/java/io/wdd/common/beans/executor/ExecutorFunctionMessage.java b/common/src/main/java/io/wdd/common/beans/executor/ExecutorFunctionMessage.java
index cc124e8..75b7b27 100644
--- a/common/src/main/java/io/wdd/common/beans/executor/ExecutorFunctionMessage.java
+++ b/common/src/main/java/io/wdd/common/beans/executor/ExecutorFunctionMessage.java
@@ -11,7 +11,6 @@ import lombok.experimental.SuperBuilder;
@SuperBuilder(toBuilder = true)
public class ExecutorFunctionMessage {
-
String functionName;
String functionContent;
diff --git a/common/src/main/java/io/wdd/common/beans/status/OctopusStatusMessage.java b/common/src/main/java/io/wdd/common/beans/status/OctopusStatusMessage.java
new file mode 100644
index 0000000..cbf730c
--- /dev/null
+++ b/common/src/main/java/io/wdd/common/beans/status/OctopusStatusMessage.java
@@ -0,0 +1,25 @@
+package io.wdd.common.beans.status;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@SuperBuilder(toBuilder = true)
+public class OctopusStatusMessage {
+
+ /**
+ * which kind of status should be return
+ * short => short time message
+ * all => all agent status message
+ * healthy => check for healthy
+ * */
+ String type;
+
+ String agentTopicName;
+
+
+}
diff --git a/common/src/main/java/io/wdd/common/utils/TimeUtils.java b/common/src/main/java/io/wdd/common/utils/TimeUtils.java
index 1715d20..478a28e 100644
--- a/common/src/main/java/io/wdd/common/utils/TimeUtils.java
+++ b/common/src/main/java/io/wdd/common/utils/TimeUtils.java
@@ -12,35 +12,12 @@ import java.util.concurrent.TimeUnit;
public class TimeUtils {
- public static ByteBuffer currentTimeByteBuffer() {
-
- byte[] timeBytes = LocalDateTime.now(ZoneId.of("UTC+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).getBytes(StandardCharsets.UTF_8);
-
- return ByteBuffer.wrap(timeBytes);
- }
-
-
- /**
- * @return UTC+8 [ yyyy-MM-dd HH:mm:ss ] Time String
- */
- public static String currentTimeString() {
-
- return LocalDateTime.now(ZoneId.of("UTC+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
- }
-
-
- public static String localDateTimeString(LocalDateTime time) {
- return time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
- }
-
-
/**
* https://memorynotfound.com/calculate-relative-time-time-ago-java/
- *
- * calculate relative time from now on
- * like 5 days, 3 hours, 16 minutes level 3
- *
- * */
+ *
+ * calculate relative time from now on
+ * like 5 days, 3 hours, 16 minutes level 3
+ */
private static final Map times = new LinkedHashMap<>();
@@ -54,12 +31,36 @@ public class TimeUtils {
times.put("second", TimeUnit.SECONDS.toMillis(1));
}
+ public static ByteBuffer currentTimeByteBuffer() {
+
+ byte[] timeBytes = LocalDateTime.now(ZoneId.of("UTC+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).getBytes(StandardCharsets.UTF_8);
+
+ return ByteBuffer.wrap(timeBytes);
+ }
+
+ public static LocalDateTime currentTime() {
+
+ return LocalDateTime.now(ZoneId.of("UTC+8"));
+ }
+
+ /**
+ * @return UTC+8 [ yyyy-MM-dd HH:mm:ss ] Time String
+ */
+ public static String currentTimeString() {
+
+ return LocalDateTime.now(ZoneId.of("UTC+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+ }
+
+ public static String localDateTimeString(LocalDateTime time) {
+ return time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+ }
+
public static String toRelative(long duration, int maxLevel) {
StringBuilder res = new StringBuilder();
int level = 0;
- for (Map.Entry time : times.entrySet()){
+ for (Map.Entry time : times.entrySet()) {
long timeDelta = duration / time.getValue();
- if (timeDelta > 0){
+ if (timeDelta > 0) {
res.append(timeDelta)
.append(" ")
.append(time.getKey())
@@ -68,7 +69,7 @@ public class TimeUtils {
duration -= time.getValue() * timeDelta;
level++;
}
- if (level == maxLevel){
+ if (level == maxLevel) {
break;
}
}
@@ -85,12 +86,12 @@ public class TimeUtils {
return toRelative(duration, times.size());
}
- public static String toRelative(Date start, Date end){
+ public static String toRelative(Date start, Date end) {
assert start.after(end);
return toRelative(end.getTime() - start.getTime());
}
- public static String toRelative(Date start, Date end, int level){
+ public static String toRelative(Date start, Date end, int level) {
assert start.after(end);
return toRelative(end.getTime() - start.getTime(), level);
}
diff --git a/server/src/main/java/io/wdd/rpc/execute/result/CreateStreamReader.java b/server/src/main/java/io/wdd/rpc/execute/result/CreateStreamReader.java
index 273c337..1e5e870 100644
--- a/server/src/main/java/io/wdd/rpc/execute/result/CreateStreamReader.java
+++ b/server/src/main/java/io/wdd/rpc/execute/result/CreateStreamReader.java
@@ -1,5 +1,6 @@
package io.wdd.rpc.execute.result;
+import io.wdd.server.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
@@ -15,11 +16,7 @@ import static io.wdd.rpc.execute.result.RedisStreamReaderConfig.COMMAND_RESULT_R
@Component
@Slf4j
-public class CreateStreamReader implements ApplicationContextAware {
-
- private ApplicationContext applicationContext;
-
- private AutowireCapableBeanFactory beanFactory;
+public class CreateStreamReader {
private RedisStreamReaderConfig redisStreamReaderConfig;
@@ -27,11 +24,6 @@ public class CreateStreamReader implements ApplicationContextAware {
private final HashMap REDIS_STREAM_LISTENER_CONTAINER_CACHE = new HashMap<>(16);
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- this.applicationContext = applicationContext;
- }
-
public void registerStreamReader(String redisStreamListenerContainerBeanName, String streamKey) {
// prepare the environment
@@ -56,27 +48,22 @@ public class CreateStreamReader implements ApplicationContextAware {
private void prepareEnv() {
- getBeanFactory();
-
getRedisStreamConfig();
}
private void getRedisStreamConfig() {
- this.redisStreamReaderConfig = applicationContext.getBean("redisStreamReaderConfig", RedisStreamReaderConfig.class);
+ this.redisStreamReaderConfig = SpringUtils.getBean("redisStreamReaderConfig", RedisStreamReaderConfig.class);
}
- private void getBeanFactory() {
- this.beanFactory = applicationContext.getAutowireCapableBeanFactory();
- }
private void createStreamReader(String redisStreamListenerContainerBeanName, String streamKey) {
log.debug("start to create the redis stream listener container");
// create the lazy bean
- StreamMessageListenerContainer streamMessageListenerContainer = applicationContext.getBean(redisStreamListenerContainerBeanName, StreamMessageListenerContainer.class);
+ StreamMessageListenerContainer streamMessageListenerContainer = SpringUtils.getBean(redisStreamListenerContainerBeanName, StreamMessageListenerContainer.class);
REDIS_STREAM_LISTENER_CONTAINER_CACHE.put(streamKey, streamMessageListenerContainer);
@@ -112,7 +99,7 @@ public class CreateStreamReader implements ApplicationContextAware {
// double destroy
- beanFactory.destroyBean(streamMessageListenerContainer);
+ SpringUtils.destroyBean(streamMessageListenerContainer);
streamMessageListenerContainer.stop();
// help gc
streamMessageListenerContainer = null;
diff --git a/server/src/main/java/io/wdd/rpc/message/sender/ToAgentMessageSender.java b/server/src/main/java/io/wdd/rpc/message/sender/ToAgentMessageSender.java
index 794b0d7..563d5e5 100644
--- a/server/src/main/java/io/wdd/rpc/message/sender/ToAgentMessageSender.java
+++ b/server/src/main/java/io/wdd/rpc/message/sender/ToAgentMessageSender.java
@@ -12,10 +12,11 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
+import java.util.List;
/**
* adaptor
- * provide override method to convert Object and send to rabbitmq
+ * provide override method to convert Object and send to rabbitmq
*/
@Component
@Slf4j(topic = "Send Message To Octopus Agent ")
@@ -31,12 +32,11 @@ public class ToAgentMessageSender {
ObjectMapper objectMapper;
/**
- *
- * send to Queue -- InitFromServer
+ * send to Queue -- InitFromServer
*
* @param message octopus message
*/
- public void sendINIT(OctopusMessage message){
+ public void sendINIT(OctopusMessage message) {
// only accept INIT type message
if (!OctopusMessageType.INIT.equals(message.getType())) {
@@ -55,16 +55,26 @@ public class ToAgentMessageSender {
log.info("OctopusMessage {} send to agent {}", octopusMessage, octopusMessage.getUuid());
-
rabbitTemplate.convertAndSend(
initRabbitMQConfig.OCTOPUS_EXCHANGE,
- octopusMessage.getUuid()+"*",
+ octopusMessage.getUuid() + "*",
writeData(octopusMessage));
}
+
+ public void send(List octopusMessageList) {
+
+ octopusMessageList.stream().forEach(
+ octopusMessage -> {
+ this.send(octopusMessage);
+ }
+ );
+
+ }
+
@SneakyThrows
- private byte[] writeData(Object data){
+ private byte[] writeData(Object data) {
return objectMapper.writeValueAsBytes(data);
}
diff --git a/server/src/main/java/io/wdd/rpc/scheduler/beans/OctopusQuartzJob.java b/server/src/main/java/io/wdd/rpc/scheduler/beans/OctopusQuartzJob.java
new file mode 100644
index 0000000..ee06b54
--- /dev/null
+++ b/server/src/main/java/io/wdd/rpc/scheduler/beans/OctopusQuartzJob.java
@@ -0,0 +1,43 @@
+package io.wdd.rpc.scheduler.beans;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class OctopusQuartzJob implements Serializable {
+
+ public static final String JOB_KEY = "JOB_KEY";
+
+ @ApiModelProperty(value = "ID")
+ private Long id;
+
+ @ApiModelProperty(value = "用于子任务唯一标识", hidden = true)
+ private String uuid;
+
+ @ApiModelProperty(value = "任务名称")
+ private String jobName;
+
+ @ApiModelProperty(value = "Bean名称")
+ private String beanName;
+
+ @ApiModelProperty(value = "方法名称")
+ private String methodName;
+
+ @ApiModelProperty(value = "参数")
+ private String params;
+
+ @ApiModelProperty(value = "cron表达式")
+ private String cronExpression;
+
+ @ApiModelProperty(value = "状态,暂时或启动")
+ private Boolean isPause = false;
+
+ @ApiModelProperty(value = "子任务")
+ private String subTask;
+
+ @ApiModelProperty(value = "失败后暂停")
+ private Boolean pauseAfterFailure;
+
+}
diff --git a/server/src/main/java/io/wdd/rpc/scheduler/beans/OctopusQuartzLog.java b/server/src/main/java/io/wdd/rpc/scheduler/beans/OctopusQuartzLog.java
new file mode 100644
index 0000000..55bb1a8
--- /dev/null
+++ b/server/src/main/java/io/wdd/rpc/scheduler/beans/OctopusQuartzLog.java
@@ -0,0 +1,47 @@
+package io.wdd.rpc.scheduler.beans;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+public class OctopusQuartzLog implements Serializable {
+
+ @ApiModelProperty(value = "ID", hidden = true)
+ @TableId(type = IdType.ASSIGN_ID)
+ private Long id;
+
+ @ApiModelProperty(value = "任务名称", hidden = true)
+ private String jobName;
+
+ @ApiModelProperty(value = "bean名称", hidden = true)
+ private String beanName;
+
+ @ApiModelProperty(value = "方法名称", hidden = true)
+ private String methodName;
+
+ @ApiModelProperty(value = "参数", hidden = true)
+ private String params;
+
+ @ApiModelProperty(value = "cron表达式", hidden = true)
+ private String cronExpression;
+
+ @ApiModelProperty(value = "状态", hidden = true)
+ private Boolean isSuccess;
+
+ @ApiModelProperty(value = "异常详情", hidden = true)
+ private String exceptionDetail;
+
+ @ApiModelProperty(value = "执行耗时", hidden = true)
+ private Long time;
+
+ @ApiModelProperty(value = "创建时间", hidden = true)
+ private LocalDateTime createTime;
+
+
+}
diff --git a/server/src/main/java/io/wdd/rpc/scheduler/call/CallAgentQuartzService.java b/server/src/main/java/io/wdd/rpc/scheduler/call/CallAgentQuartzService.java
new file mode 100644
index 0000000..b93b84c
--- /dev/null
+++ b/server/src/main/java/io/wdd/rpc/scheduler/call/CallAgentQuartzService.java
@@ -0,0 +1,18 @@
+package io.wdd.rpc.scheduler.call;
+
+import io.wdd.common.beans.status.OctopusStatusMessage;
+import io.wdd.rpc.status.CollectAgentStatus;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+public class CallAgentQuartzService {
+
+ @Resource
+ CollectAgentStatus collectAgentStatus;
+
+
+
+
+}
diff --git a/server/src/main/java/io/wdd/rpc/scheduler/config/ExecutionJob.java b/server/src/main/java/io/wdd/rpc/scheduler/config/ExecutionJob.java
new file mode 100644
index 0000000..635f127
--- /dev/null
+++ b/server/src/main/java/io/wdd/rpc/scheduler/config/ExecutionJob.java
@@ -0,0 +1,61 @@
+package io.wdd.rpc.scheduler.config;
+
+import io.wdd.common.handler.MyRuntimeException;
+import io.wdd.rpc.scheduler.beans.OctopusQuartzJob;
+import io.wdd.server.utils.SpringUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+import org.springframework.util.ReflectionUtils;
+
+import java.lang.reflect.Method;
+
+
+@Async
+public class ExecutionJob extends QuartzJobBean {
+
+ @Override
+ protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
+
+ //通过JobExecutionContext对象得到OctopusQuartzJob实例。
+ OctopusQuartzJob octopusQuartzJob = (OctopusQuartzJob)
+ context.getMergedJobDataMap().get(
+ io.wdd.rpc.scheduler.beans.OctopusQuartzJob.JOB_KEY);
+
+ //反射获取到方法,并执行。
+ runMethod(octopusQuartzJob.getBeanName(), octopusQuartzJob.getMethodName(), octopusQuartzJob.getParams());
+ }
+
+ /***
+ * description:反射执行方法
+ *
+ * @author: zeaslity
+ */
+ public void runMethod(String beanName, String methodName, String params) {
+ Object target = SpringUtils.getBean(beanName);
+ Method method = null;
+
+ try {
+ //执行的方法只能有两种,有String参数或者无参数,毕竟前端只能传字符串参数给后端。
+ if (StringUtils.isNotBlank(params)) {
+ //反射获取到方法 两个参数 分别是方法名和参数类型
+ method = target.getClass().getDeclaredMethod(methodName, String.class);
+ } else {
+ method = target.getClass().getDeclaredMethod(methodName);
+ }
+
+ //反射执行方法
+ ReflectionUtils.makeAccessible(method);
+
+ if (StringUtils.isNotBlank(params)) {
+ method.invoke(target, params);
+ } else {
+ method.invoke(target);
+ }
+ } catch (Exception e) {
+ throw new MyRuntimeException("定时任务执行失败");
+ }
+ }
+}
diff --git a/server/src/main/java/io/wdd/rpc/scheduler/config/QuartzRunnable.java b/server/src/main/java/io/wdd/rpc/scheduler/config/QuartzRunnable.java
new file mode 100644
index 0000000..4ec96f4
--- /dev/null
+++ b/server/src/main/java/io/wdd/rpc/scheduler/config/QuartzRunnable.java
@@ -0,0 +1,49 @@
+package io.wdd.rpc.scheduler.config;
+
+import io.wdd.server.utils.SpringUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.util.ReflectionUtils;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.Callable;
+
+public class QuartzRunnable implements Callable