diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+
diff --git a/bocloud.tse.booter/pom.xml b/bocloud.tse.booter/pom.xml
new file mode 100644
index 0000000..f16fb5d
--- /dev/null
+++ b/bocloud.tse.booter/pom.xml
@@ -0,0 +1,150 @@
+
+ 4.0.0
+
+ com.bocloud
+ bocloud.tse
+ 6.5.0-LTS-SZ
+
+ bocloud.tse.booter
+ ${bocloud.booter.version}
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.hibernate.validator
+ hibernate-validator
+
+
+
+
+
+ com.freedom
+ megatron.microservice
+
+
+ com.bocloud
+ bocloud.tse.scheduler
+
+
+ com.google.code.gson
+ gson
+
+
+
+
+ com.google.code.gson
+ gson
+ 2.8.2
+
+
+
+ org.slf4j
+ slf4j-api
+ 2.0.7
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.11.0
+
+ true
+ 21
+ 21
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.3.0
+
+
+
+ com.bocloud.tse.booter.Application
+ true
+ false
+ libs/
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.6.1
+
+
+
+ copy-dependencies
+
+
+ jar
+ jar
+ runtime
+ ${project.build.directory}/libs
+
+
+
+
+
+
+
+
+ bocloud.booter.tomcat
+
+ 6.5.0-LTS-SZ
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.hibernate.validator
+ hibernate-validator
+
+
+
+
+
+
+ bocloud.booter.tongweb
+
+ 6.5.0-LTS-SZ-TONGWEB
+
+
+
+ com.tongweb
+ tongweb-embed
+ 7.0.E.2
+
+
+ com.tongweb.springboot
+ tongweb-spring-boot-starter
+ 2.x.0.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.hibernate.validator
+ hibernate-validator
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/Application.java b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/Application.java
new file mode 100644
index 0000000..bbafc00
--- /dev/null
+++ b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/Application.java
@@ -0,0 +1,19 @@
+package com.bocloud.tse.booter;
+
+import org.springframework.amqp.rabbit.annotation.EnableRabbit;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication
+@EnableRabbit
+@EnableScheduling
+@ComponentScan(value = {"com.bocloud", "com.megatron"})
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/config/RabbitMQConfiguration.java b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/config/RabbitMQConfiguration.java
new file mode 100644
index 0000000..7c1e805
--- /dev/null
+++ b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/config/RabbitMQConfiguration.java
@@ -0,0 +1,129 @@
+package com.bocloud.tse.booter.config;
+
+import java.util.Map;
+
+import com.bocloud.tse.scheduler.worker.listener.TaskResultListener;
+import org.springframework.amqp.core.AcknowledgeMode;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.DirectExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.TopicExchange;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.core.RabbitAdmin;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
+import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
+import org.springframework.amqp.support.converter.MessageConverter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+
+import com.bocloud.tse.scheduler.listener.TaskActionListener;
+import com.megatron.common.utils.MapTools;
+import com.megatron.framework.core.CurrentService;
+
+/**
+ * rabbitmq相关配置
+ */
+@Configuration
+@ConfigurationProperties(prefix = "spring.rabbitmq")
+public class RabbitMQConfiguration {
+
+ @Autowired
+ private ConnectionFactory connectionFactory;
+ private Map arguments = MapTools.simpleMap("x-ha-policy", "all");
+
+ /**
+ * 声明任务动作队列
+ */
+ @Bean
+ public Queue declareTaskActionQueue(CurrentService service) {
+ return new Queue("task.action.queue.tse." + service.getService().getHost() + "_" + service.getService().getPort(), true, false, true, arguments);
+ }
+
+ /**
+ * 定义direct exchange
+ */
+ @Bean
+ public DirectExchange defineDirectExchange() {
+ return new DirectExchange("bocloud.direct.exchange", true, true, arguments);
+ }
+
+ @Bean
+ public Queue declareTaskResultQueue(CurrentService service) {
+ return new Queue("task.result.queue." + service.getService().getHost() + "_" + service.getService().getPort(),
+ true, false, true, arguments);
+ }
+
+ /**
+ * 定义topic exchange
+ */
+ @Bean
+ public TopicExchange defineTopicExchange() {
+ return new TopicExchange("bocloud.topic.exchange", true, true, arguments);
+ }
+
+ /**
+ * 任务动作队列绑定bocloud.topic.exchange
+ */
+ @Bean
+ public Binding bindingTaskActionQueue(CurrentService service) {
+ return BindingBuilder.bind(declareTaskActionQueue(service)).to(defineTopicExchange())
+ .with("topic.task.action.#");
+ }
+
+ /**
+ * 绑定任务执行结果队列
+ *
+ * @param service
+ * @return
+ */
+ @Bean
+ public Binding bindingTaskResultQueue(CurrentService service) {
+ return BindingBuilder.bind(declareTaskResultQueue(service)).to(defineDirectExchange()).withQueueName();
+ }
+ @Bean
+ public SimpleMessageListenerContainer autoActionListener(CurrentService service,
+ TaskActionListener taskActionListener) {
+ SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
+ container.setQueues(declareTaskActionQueue(service));
+ container.setAcknowledgeMode(AcknowledgeMode.AUTO); // 设置确认模式自动确认
+ container.setMessageListener(taskActionListener);
+ return container;
+ }
+
+ @Bean
+ public SimpleMessageListenerContainer autoTaskResultListener(CurrentService service,
+ TaskResultListener taskResultListener) {
+ SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
+ container.setQueues(declareTaskResultQueue(service));
+ container.setAcknowledgeMode(AcknowledgeMode.AUTO); // 设置确认模式自动确认
+ container.setMessageListener(taskResultListener);
+ return container;
+ }
+ @Bean
+ public MessageConverter messageConverter() {
+ return new Jackson2JsonMessageConverter();
+ }
+
+ @Bean
+ @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+ public RabbitTemplate amqpTemplate() {
+ RabbitTemplate amqpTemplate = new RabbitTemplate(connectionFactory);
+ amqpTemplate.setMessageConverter(messageConverter());
+ amqpTemplate.setExchange(defineDirectExchange().getName());
+ return amqpTemplate;
+ }
+
+ @Bean
+ @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+ public RabbitAdmin rabbitAdmin() {
+ RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
+ return rabbitAdmin;
+ }
+
+}
diff --git a/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/config/SwaggerConfiguration.java b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/config/SwaggerConfiguration.java
new file mode 100644
index 0000000..4983b1c
--- /dev/null
+++ b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/config/SwaggerConfiguration.java
@@ -0,0 +1,21 @@
+package com.bocloud.tse.booter.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Contact;
+import io.swagger.v3.oas.models.info.Info;
+
+@Configuration
+public class SwaggerConfiguration {
+
+ @Bean
+ public OpenAPI openAPI() {
+ Contact contact = new Contact().name("未伟").email("weiwei@beyondcent.com").url("http://www.bocloud.com/");
+ Info info = new Info().title("任务引擎服务API接口文档").description("任务引擎服务API接口文档")
+ .termsOfService("http://www.bocloud.com/").contact(contact).version("1.0");
+ return new OpenAPI().info(info);
+ }
+
+}
diff --git a/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/config/WebInterceptorConfiguration.java b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/config/WebInterceptorConfiguration.java
new file mode 100644
index 0000000..c0954b7
--- /dev/null
+++ b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/config/WebInterceptorConfiguration.java
@@ -0,0 +1,60 @@
+package com.bocloud.tse.booter.config;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.bocloud.cmp.boot.config.PagerArgumentResolver;
+import com.bocloud.cmp.boot.interceptor.AccessInterceptor;
+import com.bocloud.cmp.boot.interceptor.LogInterceptor;
+import com.megatron.framework.core.InterceptorBridge;
+import com.megatron.framework.core.config.InterceptorConfiguration;
+import com.megatron.framework.core.domain.InterceptorEntity;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 拦截器配置类
+ */
+@Slf4j
+@Component
+public class WebInterceptorConfiguration implements InterceptorConfiguration {
+
+ private static final String[] ACCESS_EXCLUDES = new String[] {"/status", "/status/db", "/status/**",
+ "/v1/status/**", "/login", "/sso", "/v1/logview", "/v1/logzip", "/v1/config/**", "/v1/plugins/**", "/*/*.css",
+ "/*/*.js", "/*/*.png", "/*/*.jpg", "/*/*.jpeg", "/*.html", "/*/*.html", "/swagger-resources/**", "/favicon.ico",
+ "/webjars/**", "/v3/**", "/swagger-ui.html/**", "**/api-docs", "/error", "/favicon.ico"};
+ private static final String[] LOG_EXCLUDES = new String[] {"/*/*.css", "/*/*.js", "/*/*.png", "/*/*.jpg",
+ "/*/*.jpeg", "/*.html", "/*/*.html", "/swagger-resources/**", "/favicon.ico", "/webjars/**", "/v3/**",
+ "/swagger-ui.html/**", "**/api-docs", "/error", "/favicon.ico"};
+ private static final String[] INCLUDES = new String[] {"/**"};
+ private final LogInterceptor logInterceptor;
+ private final AccessInterceptor accessInterceptor;
+
+ @Autowired
+ public WebInterceptorConfiguration(AccessInterceptor accessInterceptor, LogInterceptor logInterceptor) {
+ this.logInterceptor = logInterceptor;
+ this.accessInterceptor = accessInterceptor;
+ }
+
+ @Override
+ public InterceptorBridge buildBridge() {
+ log.info("start to build interceptors...");
+ InterceptorBridge bridge = new InterceptorBridge();
+ InterceptorEntity accessEntity = InterceptorEntity.builder().interceptor(accessInterceptor).includes(INCLUDES)
+ .excludes(ACCESS_EXCLUDES).order(0).build();
+ InterceptorEntity auditLogEntity = InterceptorEntity.builder().interceptor(logInterceptor).includes(INCLUDES)
+ .excludes(LOG_EXCLUDES).order(1).build();
+ List interceptors = new ArrayList<>();
+ interceptors.add(accessEntity);
+ interceptors.add(auditLogEntity);
+ bridge.setInterceptors(interceptors);
+ bridge.setResolvers(Collections.singletonList(new PagerArgumentResolver()));
+ bridge.setMessageConverters(new ArrayList<>(0));
+ log.info("build interceptors success!!!");
+ return bridge;
+ }
+}
diff --git a/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/controller/EngineController.java b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/controller/EngineController.java
new file mode 100644
index 0000000..0f27ae5
--- /dev/null
+++ b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/controller/EngineController.java
@@ -0,0 +1,74 @@
+package com.bocloud.tse.booter.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.bocloud.tse.intf.EngineService;
+import com.bocloud.tse.model.EngineModule;
+import com.bocloud.tse.scheduler.core.JobScheduler;
+import com.megatron.common.model.GeneralResult;
+import com.megatron.common.model.RequestContext;
+import com.megatron.common.utils.Common;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+@RestController
+@RequestMapping("/v1/engines")
+@Tag(name = "任务引擎管理")
+public class EngineController {
+
+ @Autowired
+ private EngineService engineService;
+ @Autowired
+ private JobScheduler scheduler;
+
+ @Operation(summary = "任务引擎列表")
+ @GetMapping
+ public GeneralResult> services() {
+ return engineService.services();
+ }
+
+ @Operation(summary = "任务引擎状态")
+ @GetMapping("/status")
+ public GeneralResult status() {
+ return new GeneralResult<>(true, scheduler.isRunning(), "任务引擎状态查询成功");
+ }
+
+ @Operation(summary = "任务引擎操作(开启/关闭)")
+ @PostMapping("/action")
+ public GeneralResult> action(@RequestBody EngineModule module) {
+ GeneralResult> result = engineService.action(module);
+ if (result.isSuccess() && engineService.checkInstance(module.getInstance())) {
+ String action = module.getAction();
+ if ("start".equals(action) && !scheduler.isRunning()) {
+ scheduler.switchOn();
+ } else if ("stop".equals(action) && scheduler.isRunning()) {
+ scheduler.switchOff();
+ }
+ }
+ return result;
+ }
+
+ @PutMapping(value = "/exclude")
+ @Operation(tags = { "CMC", "CSC" }, summary = "任务引擎排除")
+ public GeneralResult taskExclude(@RequestParam(value = "instance") String instance,
+ @Value(Common.REQ_CONTEXT) RequestContext context) {
+ return engineService.exclude(instance, context.getTarget());
+ }
+
+ @PutMapping(value = "/recover")
+ @Operation(tags = { "CMC", "CSC" }, summary = "任务引擎恢复")
+ public GeneralResult taskRecover(@RequestParam(value = "instance") String instance,
+ @Value(Common.REQ_CONTEXT) RequestContext context) {
+ return engineService.recover(instance, context.getTarget());
+ }
+
+}
diff --git a/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/controller/SchedulerController.java b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/controller/SchedulerController.java
new file mode 100644
index 0000000..b598950
--- /dev/null
+++ b/bocloud.tse.booter/src/main/java/com/bocloud/tse/booter/controller/SchedulerController.java
@@ -0,0 +1,93 @@
+package com.bocloud.tse.booter.controller;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.alibaba.fastjson.JSONObject;
+import com.bocloud.tse.intf.TaskInstanceService;
+import com.bocloud.tse.model.Job;
+import com.bocloud.tse.scheduler.core.JobChannel;
+import com.bocloud.tse.scheduler.core.JobScheduler;
+import com.bocloud.tse.scheduler.core.TaskCache;
+import com.bocloud.tse.scheduler.executor.NodeExecutor;
+import com.bocloud.tse.scheduler.executor.TaskExecutor;
+import com.megatron.common.model.GeneralResult;
+import com.megatron.common.model.Result;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+/**
+ * 状态控制器
+ */
+@RestController
+@RequestMapping("/v1")
+@Tag(name = "任务状态管理")
+public class SchedulerController {
+
+ @Autowired
+ private JobScheduler scheduler;
+ @Autowired
+ private TaskInstanceService instanceService;
+ @Autowired
+ private JobChannel channel;
+
+ private TaskCache cache = TaskCache.instance();
+
+ @GetMapping("/status/task/total")
+ @Operation(tags = { "CMC" }, summary = "任务整体信息")
+ public GeneralResult