diff --git a/czsj-framework/src/main/java/com/czsj/framework/config/MyBatisConfig.java b/czsj-framework/src/main/java/com/czsj/framework/config/MyBatisConfig.java
index 0c17794..7ed07f7 100644
--- a/czsj-framework/src/main/java/com/czsj/framework/config/MyBatisConfig.java
+++ b/czsj-framework/src/main/java/com/czsj/framework/config/MyBatisConfig.java
@@ -32,101 +32,101 @@ import com.czsj.common.utils.StringUtils;
@Configuration
public class MyBatisConfig
{
- @Autowired
- private Environment env;
-
- static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
-
- public static String setTypeAliasesPackage(String typeAliasesPackage)
- {
- ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
- MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
- List allResult = new ArrayList();
- try
- {
- for (String aliasesPackage : typeAliasesPackage.split(","))
- {
- List result = new ArrayList();
- aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
- + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
- Resource[] resources = resolver.getResources(aliasesPackage);
- if (resources != null && resources.length > 0)
- {
- MetadataReader metadataReader = null;
- for (Resource resource : resources)
- {
- if (resource.isReadable())
- {
- metadataReader = metadataReaderFactory.getMetadataReader(resource);
- try
- {
- result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
- }
- catch (ClassNotFoundException e)
- {
- e.printStackTrace();
- }
- }
- }
- }
- if (result.size() > 0)
- {
- HashSet hashResult = new HashSet(result);
- allResult.addAll(hashResult);
- }
- }
- if (allResult.size() > 0)
- {
- typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
- }
- else
- {
- throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
- }
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- return typeAliasesPackage;
- }
-
- public Resource[] resolveMapperLocations(String[] mapperLocations)
- {
- ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
- List resources = new ArrayList();
- if (mapperLocations != null)
- {
- for (String mapperLocation : mapperLocations)
- {
- try
- {
- Resource[] mappers = resourceResolver.getResources(mapperLocation);
- resources.addAll(Arrays.asList(mappers));
- }
- catch (IOException e)
- {
- // ignore
- }
- }
- }
- return resources.toArray(new Resource[resources.size()]);
- }
-
- @Bean
- public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
- {
- String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
- String mapperLocations = env.getProperty("mybatis.mapperLocations");
- String configLocation = env.getProperty("mybatis.configLocation");
- typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
- VFS.addImplClass(SpringBootVFS.class);
-
- final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
- sessionFactory.setDataSource(dataSource);
- sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
- sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
- sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
- return sessionFactory.getObject();
- }
+// @Autowired
+// private Environment env;
+//
+// static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
+//
+// public static String setTypeAliasesPackage(String typeAliasesPackage)
+// {
+// ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
+// MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
+// List allResult = new ArrayList();
+// try
+// {
+// for (String aliasesPackage : typeAliasesPackage.split(","))
+// {
+// List result = new ArrayList();
+// aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+// + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
+// Resource[] resources = resolver.getResources(aliasesPackage);
+// if (resources != null && resources.length > 0)
+// {
+// MetadataReader metadataReader = null;
+// for (Resource resource : resources)
+// {
+// if (resource.isReadable())
+// {
+// metadataReader = metadataReaderFactory.getMetadataReader(resource);
+// try
+// {
+// result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
+// }
+// catch (ClassNotFoundException e)
+// {
+// e.printStackTrace();
+// }
+// }
+// }
+// }
+// if (result.size() > 0)
+// {
+// HashSet hashResult = new HashSet(result);
+// allResult.addAll(hashResult);
+// }
+// }
+// if (allResult.size() > 0)
+// {
+// typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
+// }
+// else
+// {
+// throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
+// }
+// }
+// catch (IOException e)
+// {
+// e.printStackTrace();
+// }
+// return typeAliasesPackage;
+// }
+//
+// public Resource[] resolveMapperLocations(String[] mapperLocations)
+// {
+// ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
+// List resources = new ArrayList();
+// if (mapperLocations != null)
+// {
+// for (String mapperLocation : mapperLocations)
+// {
+// try
+// {
+// Resource[] mappers = resourceResolver.getResources(mapperLocation);
+// resources.addAll(Arrays.asList(mappers));
+// }
+// catch (IOException e)
+// {
+// // ignore
+// }
+// }
+// }
+// return resources.toArray(new Resource[resources.size()]);
+// }
+//
+// @Bean
+// public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
+// {
+// String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
+// String mapperLocations = env.getProperty("mybatis.mapperLocations");
+// String configLocation = env.getProperty("mybatis.configLocation");
+// typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
+// VFS.addImplClass(SpringBootVFS.class);
+//
+// final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
+// sessionFactory.setDataSource(dataSource);
+// sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
+// sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
+// sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
+// return sessionFactory.getObject();
+// }
}
\ No newline at end of file
diff --git a/czsj-system/pom.xml b/czsj-system/pom.xml
index 881fe3a..903922c 100644
--- a/czsj-system/pom.xml
+++ b/czsj-system/pom.xml
@@ -23,6 +23,754 @@
czsj-common
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ com.microsoft.sqlserver
+ sqljdbc4
+ 4.0
+ system
+ ${basedir}/src/main/lib/sqljdbc4-4.0.jar
+
+
+
+ ch.ethz.ganymed
+ ganymed-ssh2
+ 262
+
+
+
+ com.czsj
+ czsj-core
+ 3.8.8
+ compile
+
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ ${mybatisplus.version}
+
+
+ com.baomidou
+ mybatis-plus-generator
+
+
+ slf4j-api
+ org.slf4j
+
+
+
+
+
+ com.baomidou
+ mybatis-plus
+ ${mybatisplus.version}
+
+
+
+ javax.mail
+ mail
+ 1.4.7
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.12.0
+
+
+ io.swagger
+ swagger-annotations
+ 1.6.2
+ compile
+
+
+ com.baomidou
+ mybatis-plus-extension
+ 3.3.1
+
+
+ org.apache.hadoop
+ hadoop-common
+ ${hadoop.version}
+
+
+ slf4j-log4j12
+ org.slf4j
+
+
+ com.sun.jersey
+ jersey-json
+
+
+ jsr305
+ com.google.code.findbugs
+
+
+ guava
+ com.google.guava
+
+
+ jettison
+ org.codehaus.jettison
+
+
+ jackson-core-asl
+ org.codehaus.jackson
+
+
+ jackson-mapper-asl
+ org.codehaus.jackson
+
+
+ slf4j-api
+ org.slf4j
+
+
+ commons-cli
+ commons-cli
+
+
+ commons-logging
+ commons-logging
+
+
+ commons-collections
+ commons-collections
+
+
+ commons-lang
+ commons-lang
+
+
+ curator-framework
+ org.apache.curator
+
+
+ log4j
+ log4j
+
+
+ netty
+ io.netty
+
+
+ servlet-api
+ javax.servlet
+
+
+ jsp-api
+ javax.servlet.jsp
+
+
+ jetty-util
+ org.mortbay.jetty
+
+
+ jetty
+ org.mortbay.jetty
+
+
+
+
+
+ org.apache.hive
+ hive-jdbc
+ ${hive.jdbc.version}
+
+
+ jsr305
+ com.google.code.findbugs
+
+
+ guava
+ com.google.guava
+
+
+ jettison
+ org.codehaus.jettison
+
+
+ commons-cli
+ commons-cli
+
+
+ curator-client
+ org.apache.curator
+
+
+ commons-compress
+ org.apache.commons
+
+
+ hadoop-common
+ org.apache.hadoop
+
+
+ slf4j-api
+ org.slf4j
+
+
+ hadoop-hdfs
+ org.apache.hadoop
+
+
+ snappy
+ org.iq80.snappy
+
+
+ antlr-runtime
+ org.antlr
+
+
+ hbase-client
+ org.apache.hbase
+
+
+ libthrift
+ org.apache.thrift
+
+
+ twill-common
+ org.apache.twill
+
+
+ twill-core
+ org.apache.twill
+
+
+ twill-discovery-api
+ org.apache.twill
+
+
+ twill-discovery-core
+ org.apache.twill
+
+
+ twill-zookeeper
+ org.apache.twill
+
+
+ avro
+ org.apache.avro
+
+
+ curator-recipes
+ org.apache.curator
+
+
+ hbase-common
+ org.apache.hbase
+
+
+ hbase-hadoop-compat
+ org.apache.hbase
+
+
+ hbase-hadoop2-compat
+ org.apache.hbase
+
+
+ hbase-server
+ org.apache.hbase
+
+
+ curator-framework
+ org.apache.curator
+
+
+ guice-servlet
+ com.google.inject.extensions
+
+
+ hadoop-client
+ org.apache.hadoop
+
+
+ hadoop-yarn-api
+ org.apache.hadoop
+
+
+ hadoop-yarn-common
+ org.apache.hadoop
+
+
+ jackson-core-asl
+ org.codehaus.jackson
+
+
+ jackson-mapper-asl
+ org.codehaus.jackson
+
+
+ jackson-jaxrs
+ org.codehaus.jackson
+
+
+ jackson-xc
+ org.codehaus.jackson
+
+
+ jersey-client
+ com.sun.jersey
+
+
+ jamon-runtime
+ org.jamon
+
+
+ servlet-api
+ javax.servlet
+
+
+ commons-logging
+ commons-logging
+
+
+ hadoop-annotations
+ org.apache.hadoop
+
+
+ commons-collections
+ commons-collections
+
+
+ jersey-guice
+ com.sun.jersey.contribs
+
+
+ log4j-slf4j-impl
+ org.apache.logging.log4j
+
+
+ hive-shims-common
+ org.apache.hive.shims
+
+
+ javax.servlet
+ org.eclipse.jetty.orbit
+
+
+ jsp-api
+ javax.servlet.jsp
+
+
+ jasper-compiler
+ tomcat
+
+
+ jetty-all
+ org.eclipse.jetty.aggregate
+
+
+ jetty
+ org.mortbay.jetty
+
+
+ jetty-util
+ org.mortbay.jetty
+
+
+
+
+
+ org.apache.hadoop
+ hadoop-hdfs
+ ${hadoop.version}
+
+
+ guava
+ com.google.guava
+
+
+ commons-cli
+ commons-cli
+
+
+ jackson-core-asl
+ org.codehaus.jackson
+
+
+ jackson-mapper-asl
+ org.codehaus.jackson
+
+
+ servlet-api
+ javax.servlet
+
+
+ jetty
+ org.mortbay.jetty
+
+
+ jetty-util
+ org.mortbay.jetty
+
+
+
+
+
+ org.apache.hbase
+ hbase-client
+ ${hbase.version}
+
+
+ guava
+ com.google.guava
+
+
+ commons-logging
+ commons-logging
+
+
+ hadoop-auth
+ org.apache.hadoop
+
+
+ hadoop-common
+ org.apache.hadoop
+
+
+ hadoop-mapreduce-client-core
+ org.apache.hadoop
+
+
+ hbase-annotations
+ org.apache.hbase
+
+
+ hbase-protocol
+ org.apache.hbase
+
+
+ jackson-mapper-asl
+ org.codehaus.jackson
+
+
+ slf4j-api
+ org.slf4j
+
+
+ jetty-util
+ org.mortbay.jetty
+
+
+
+
+
+ org.apache.phoenix
+ phoenix-core
+ ${phoenix.version}
+
+
+ slf4j-log4j12
+ org.slf4j
+
+
+ guava
+ com.google.guava
+
+
+ commons-cli
+ commons-cli
+
+
+ hadoop-common
+ org.apache.hadoop
+
+
+ avro
+ org.apache.avro
+
+
+ guice
+ com.google.inject
+
+
+ hadoop-yarn-api
+ org.apache.hadoop
+
+
+ hadoop-auth
+ org.apache.hadoop
+
+
+ jersey-core
+ com.sun.jersey
+
+
+ guice-servlet
+ com.google.inject.extensions
+
+
+ jersey-server
+ com.sun.jersey
+
+
+ jersey-json
+ com.sun.jersey
+
+
+ slf4j-api
+ org.slf4j
+
+
+ netty
+ io.netty
+
+
+ hbase-client
+ org.apache.hbase
+
+
+ commons-io
+ commons-io
+
+
+ hadoop-mapreduce-client-core
+ org.apache.hadoop
+
+
+ zookeeper
+ org.apache.zookeeper
+
+
+ commons-math3
+ org.apache.commons
+
+
+ hadoop-annotations
+ org.apache.hadoop
+
+
+ hadoop-hdfs
+ org.apache.hadoop
+
+
+ hadoop-yarn-client
+ org.apache.hadoop
+
+
+ hadoop-yarn-common
+ org.apache.hadoop
+
+
+ hadoop-yarn-server-common
+ org.apache.hadoop
+
+
+ javax.ws.rs-api
+ javax.ws.rs
+
+
+ htrace-core
+ org.apache.htrace
+
+
+ jline
+ jline
+
+
+ fastutil
+ it.unimi.dsi
+
+
+ commons-lang
+ commons-lang
+
+
+ jsr305
+ com.google.code.findbugs
+
+
+ hbase-common
+ org.apache.hbase
+
+
+ javax.servlet.jsp-api
+ javax.servlet.jsp
+
+
+ hbase-server
+ org.apache.hbase
+
+
+ javax.servlet-api
+ javax.servlet
+
+
+ jetty-io
+ org.eclipse.jetty
+
+
+ jetty-http
+ org.eclipse.jetty
+
+
+ jetty-security
+ org.eclipse.jetty
+
+
+ jetty-server
+ org.eclipse.jetty
+
+
+ jetty-servlet
+ org.eclipse.jetty
+
+
+ jetty-webapp
+ org.eclipse.jetty
+
+
+
+
+
+ org.mongodb
+ mongo-java-driver
+ ${mongo-java-driver.version}
+
+
+
+ ru.yandex.clickhouse
+ clickhouse-jdbc
+ 0.2.4
+
+
+ guava
+ com.google.guava
+
+
+ slf4j-api
+ org.slf4j
+
+
+
+
+
+ io.jsonwebtoken
+ jjwt
+ ${jjwt.version}
+
+
+
+ com.google.guava
+ guava
+ 29.0-jre
+
+
+ org.springframework
+ spring-webmvc
+
+
+ io.springfox
+ springfox-swagger2
+ 3.0.0
+ compile
+
+
+ net.sourceforge.jtds
+ jtds
+ 1.3.1
+
+
+ com.alibaba
+ druid
+ 1.2.8
+ compile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ com.alibaba.nacos
+ nacos-api
+ 2.0.4
+
+
+
+
+
+
+
+
+ org.quartz-scheduler
+ quartz
+
+
+ org.mapstruct
+ mapstruct
+ 1.3.1.Final
+
+
+ cn.hutool
+ hutool-all
+ ${hutool.version}
+ compile
+
+
+ org.springframework.cloud
+ spring-cloud-openfeign-core
+ 3.0.3
+
+
+ org.springframework.security.oauth
+ spring-security-oauth2
+ 2.3.4.RELEASE
+
+
+ org.springframework.amqp
+ spring-rabbit
+ 2.2.12.RELEASE
+
+
+
+
+
+ src/main/java
+
+ **/*.properties
+ **/*.xml
+
+ true
+
+
+ src/main/resources
+
+ **/*.properties
+ **/*.xml
+ **/templates/**
+
+ true
+
+
+
+
\ No newline at end of file
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/config/MybatisPlusConfig.java b/czsj-system/src/main/java/com/czsj/bigdata/config/MybatisPlusConfig.java
new file mode 100644
index 0000000..f519322
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/config/MybatisPlusConfig.java
@@ -0,0 +1,45 @@
+package com.czsj.bigdata.config;
+
+import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
+import com.baomidou.mybatisplus.core.injector.ISqlInjector;
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+/**
+ *
+ * @Author: czsj
+ * @Date: 2022/9/16 11:14
+ * @Description:
+ **/
+@EnableTransactionManagement
+@Configuration
+@MapperScan("com.czsj.bigdata.mapper")
+public class MybatisPlusConfig {
+
+ /**
+ * 分页插件
+ */
+ @Bean
+ public PaginationInterceptor paginationInterceptor() {
+
+ PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
+ return paginationInterceptor.setOverflow(true);
+ }
+
+ /**
+ * MyBatisPlus逻辑删除 ,需要在 yml 中配置开启
+ * 3.0.7.1版本的LogicSqlInjector里面什么都没做只是 extends DefaultSqlInjector
+ * 以后版本直接去的了LogicSqlInjector
+ *
+ * @return
+ */
+ @Bean
+ public ISqlInjector sqlInjector() {
+ return new DefaultSqlInjector();
+ }
+
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/conf/ExcecutorConfig.java b/czsj-system/src/main/java/com/czsj/bigdata/core/conf/ExcecutorConfig.java
new file mode 100644
index 0000000..d94879f
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/conf/ExcecutorConfig.java
@@ -0,0 +1,83 @@
+package com.czsj.bigdata.core.conf;
+
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ *
+ *
+ * @Date: 2022/1/20 22:52
+ * @Description:
+ **/
+@Component
+public class ExcecutorConfig implements InitializingBean, DisposableBean {
+
+ private static ExcecutorConfig excecutorConfig = null;
+
+ public static ExcecutorConfig getExcecutorConfig() {
+ return excecutorConfig;
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ excecutorConfig = this;
+ }
+
+ @Override
+ public void destroy() throws Exception {
+ }
+
+
+
+ @Value("${spring.datasource.url}")
+ private String url;
+
+ @Value("${spring.datasource.driver-class-name}")
+ private String driverClassname;
+
+ @Value("${spring.datasource.username}")
+ private String username;
+
+ @Value("${spring.datasource.password}")
+ private String password;
+
+
+ public static void setExcecutorConfig(ExcecutorConfig excecutorConfig) {
+ ExcecutorConfig.excecutorConfig = excecutorConfig;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getDriverClassname() {
+ return driverClassname;
+ }
+
+ public void setDriverClassname(String driverClassname) {
+ this.driverClassname = driverClassname;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/conf/JobAdminConfig.java b/czsj-system/src/main/java/com/czsj/bigdata/core/conf/JobAdminConfig.java
new file mode 100644
index 0000000..c989c31
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/conf/JobAdminConfig.java
@@ -0,0 +1,166 @@
+package com.czsj.bigdata.core.conf;
+
+
+import com.czsj.bigdata.core.scheduler.JobScheduler;
+import com.czsj.bigdata.core.util.EmailUtil;
+import com.czsj.bigdata.mapper.*;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import javax.sql.DataSource;
+
+/**
+ * xxl-job config
+ *
+ * @author xuxueli 2017-04-28
+ */
+
+@Component
+public class JobAdminConfig implements InitializingBean, DisposableBean {
+
+ private static JobAdminConfig adminConfig = null;
+
+ public static JobAdminConfig getAdminConfig() {
+ return adminConfig;
+ }
+
+
+ // ---------------------- XxlJobScheduler ----------------------
+
+ private JobScheduler xxlJobScheduler;
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ adminConfig = this;
+
+ xxlJobScheduler = new JobScheduler();
+ xxlJobScheduler.init();
+ }
+
+ @Override
+ public void destroy() throws Exception {
+ xxlJobScheduler.destroy();
+ }
+
+
+ // ---------------------- XxlJobScheduler ----------------------
+
+ // conf
+ @Value("${datax.job.i18n}")
+ private String i18n;
+
+ @Value("${datax.job.accessToken}")
+ private String accessToken;
+
+ @Value("${spring.mail.username}")
+ private String emailUserName;
+
+ @Value("${spring.mail.password}")
+ private String emailPassword;
+
+ @Value("${spring.mail.authorization}")
+ private String emailAuthorization;
+
+ @Value("${datax.job.triggerpool.fast.max}")
+ private int triggerPoolFastMax;
+
+ @Value("${datax.job.triggerpool.slow.max}")
+ private int triggerPoolSlowMax;
+
+ @Value("${datax.job.logretentiondays}")
+ private int logretentiondays;
+
+ @Value("${datasource.aes.key}")
+ private String dataSourceAESKey;
+
+
+ // dao, service
+
+ @Autowired
+ private JobLogMapper jobLogMapper;
+ @Autowired
+ private JobInfoMapper jobInfoMapper;
+ @Autowired
+ private JobRegistryMapper jobRegistryMapper;
+ @Autowired
+ private JobGroupMapper jobGroupMapper;
+ @Autowired
+ private JobLogReportMapper jobLogReportMapper;
+
+ @Autowired
+ private DataSource dataSource;
+ @Autowired
+ private JobDatasourceMapper jobDatasourceMapper;
+
+ public String getI18n() {
+ return i18n;
+ }
+
+ public String getAccessToken() {
+ return accessToken;
+ }
+
+ public String getEmailUserName() {
+ return emailUserName;
+ }
+
+ public int getTriggerPoolFastMax() {
+ return triggerPoolFastMax < 200 ? 200 : triggerPoolFastMax;
+ }
+
+ public int getTriggerPoolSlowMax() {
+ return triggerPoolSlowMax < 100 ? 100 : triggerPoolSlowMax;
+ }
+
+ public int getLogretentiondays() {
+ return logretentiondays < 7 ? -1 : logretentiondays;
+ }
+
+ public JobLogMapper getJobLogMapper() {
+ return jobLogMapper;
+ }
+
+ public JobInfoMapper getJobInfoMapper() {
+ return jobInfoMapper;
+ }
+
+ public JobRegistryMapper getJobRegistryMapper() {
+ return jobRegistryMapper;
+ }
+
+ public JobGroupMapper getJobGroupMapper() {
+ return jobGroupMapper;
+ }
+
+ public JobLogReportMapper getJobLogReportMapper() {
+ return jobLogReportMapper;
+ }
+
+ public String getEmailPassword() {
+ return emailPassword;
+ }
+
+ public DataSource getDataSource() {
+ return dataSource;
+ }
+
+ public JobDatasourceMapper getJobDatasourceMapper() {
+ return jobDatasourceMapper;
+ }
+
+ public String getDataSourceAESKey() {
+
+ return dataSourceAESKey;
+ }
+
+ public void setDataSourceAESKey(String dataSourceAESKey) {
+ this.dataSourceAESKey = dataSourceAESKey;
+ }
+
+ public String getEmailAuthorization() {
+ return emailAuthorization;
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/cron/CronExpression.java b/czsj-system/src/main/java/com/czsj/bigdata/core/cron/CronExpression.java
new file mode 100644
index 0000000..6b576b3
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/cron/CronExpression.java
@@ -0,0 +1,1657 @@
+/*
+ * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package com.czsj.bigdata.core.cron;
+
+import java.io.Serializable;
+import java.text.ParseException;
+import java.util.*;
+
+/**
+ * Provides a parser and evaluator for unix-like cron expressions. Cron
+ * expressions provide the ability to specify complex time combinations such as
+ * "At 8:00am every Monday through Friday" or "At 1:30am every
+ * last Friday of the month".
+ *
+ * Cron expressions are comprised of 6 required fields and one optional field
+ * separated by white space. The fields respectively are described as follows:
+ *
+ *
+ *
+ * Field Name |
+ * |
+ * Allowed Values |
+ * |
+ * Allowed Special Characters |
+ *
+ *
+ * Seconds |
+ *
+ * | 0-59 |
+ *
+ * | , - * / |
+ *
+ *
+ * Minutes |
+ *
+ * | 0-59 |
+ *
+ * | , - * / |
+ *
+ *
+ * Hours |
+ *
+ * | 0-23 |
+ *
+ * | , - * / |
+ *
+ *
+ * Day-of-month |
+ *
+ * | 1-31 |
+ *
+ * | , - * ? / L W |
+ *
+ *
+ * Month |
+ *
+ * | 0-11 or JAN-DEC |
+ *
+ * | , - * / |
+ *
+ *
+ * Day-of-Week |
+ *
+ * | 1-7 or SUN-SAT |
+ *
+ * | , - * ? / L # |
+ *
+ *
+ * Year (Optional) |
+ *
+ * | empty, 1970-2199 |
+ *
+ * | , - * / |
+ *
+ *
+ *
+ * The '*' character is used to specify all values. For example, "*"
+ * in the minute field means "every minute".
+ *
+ * The '?' character is allowed for the day-of-month and day-of-week fields. It
+ * is used to specify 'no specific value'. This is useful when you need to
+ * specify something in one of the two fields, but not the other.
+ *
+ * The '-' character is used to specify ranges For example "10-12" in
+ * the hour field means "the hours 10, 11 and 12".
+ *
+ * The ',' character is used to specify additional values. For example
+ * "MON,WED,FRI" in the day-of-week field means "the days Monday,
+ * Wednesday, and Friday".
+ *
+ * The '/' character is used to specify increments. For example "0/15"
+ * in the seconds field means "the seconds 0, 15, 30, and 45". And
+ * "5/15" in the seconds field means "the seconds 5, 20, 35, and
+ * 50". Specifying '*' before the '/' is equivalent to specifying 0 is
+ * the value to start with. Essentially, for each field in the expression, there
+ * is a set of numbers that can be turned on or off. For seconds and minutes,
+ * the numbers range from 0 to 59. For hours 0 to 23, for days of the month 0 to
+ * 31, and for months 0 to 11 (JAN to DEC). The "/" character simply helps you turn
+ * on every "nth" value in the given set. Thus "7/6" in the
+ * month field only turns on month "7", it does NOT mean every 6th
+ * month, please note that subtlety.
+ *
+ * The 'L' character is allowed for the day-of-month and day-of-week fields.
+ * This character is short-hand for "last", but it has different
+ * meaning in each of the two fields. For example, the value "L" in
+ * the day-of-month field means "the last day of the month" - day 31
+ * for January, day 28 for February on non-leap years. If used in the
+ * day-of-week field by itself, it simply means "7" or
+ * "SAT". But if used in the day-of-week field after another value, it
+ * means "the last xxx day of the month" - for example "6L"
+ * means "the last friday of the month". You can also specify an offset
+ * from the last day of the month, such as "L-3" which would mean the third-to-last
+ * day of the calendar month. When using the 'L' option, it is important not to
+ * specify lists, or ranges of values, as you'll get confusing/unexpected results.
+ *
+ * The 'W' character is allowed for the day-of-month field. This character
+ * is used to specify the weekday (Monday-Friday) nearest the given day. As an
+ * example, if you were to specify "15W" as the value for the
+ * day-of-month field, the meaning is: "the nearest weekday to the 15th of
+ * the month". So if the 15th is a Saturday, the trigger will fire on
+ * Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the
+ * 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th.
+ * However if you specify "1W" as the value for day-of-month, and the
+ * 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not
+ * 'jump' over the boundary of a month's days. The 'W' character can only be
+ * specified when the day-of-month is a single day, not a range or list of days.
+ *
+ * The 'L' and 'W' characters can also be combined for the day-of-month
+ * expression to yield 'LW', which translates to "last weekday of the
+ * month".
+ *
+ * The '#' character is allowed for the day-of-week field. This character is
+ * used to specify "the nth" XXX day of the month. For example, the
+ * value of "6#3" in the day-of-week field means the third Friday of
+ * the month (day 6 = Friday and "#3" = the 3rd one in the month).
+ * Other examples: "2#1" = the first Monday of the month and
+ * "4#5" = the fifth Wednesday of the month. Note that if you specify
+ * "#5" and there is not 5 of the given day-of-week in the month, then
+ * no firing will occur that month. If the '#' character is used, there can
+ * only be one expression in the day-of-week field ("3#1,6#3" is
+ * not valid, since there are two expressions).
+ *
+ *
+ *
+ * The legal characters and the names of months and days of the week are not
+ * case sensitive.
+ *
+ *
+ * NOTES:
+ *
+ * - Support for specifying both a day-of-week and a day-of-month value is
+ * not complete (you'll need to use the '?' character in one of these fields).
+ *
+ * - Overflowing ranges is supported - that is, having a larger number on
+ * the left hand side than the right. You might do 22-2 to catch 10 o'clock
+ * at night until 2 o'clock in the morning, or you might have NOV-FEB. It is
+ * very important to note that overuse of overflowing ranges creates ranges
+ * that don't make sense and no effort has been made to determine which
+ * interpretation CronExpression chooses. An example would be
+ * "0 0 14-6 ? * FRI-MON".
+ *
+ *
+ *
+ *
+ * @author Sharada Jambula, James House
+ * @author Contributions from Mads Henderson
+ * @author Refactoring from CronTrigger to CronExpression by Aaron Craven
+ *
+ * Borrowed from quartz v2.3.1
+ *
+ */
+public final class CronExpression implements Serializable, Cloneable {
+
+ private static final long serialVersionUID = 12423409423L;
+
+ protected static final int SECOND = 0;
+ protected static final int MINUTE = 1;
+ protected static final int HOUR = 2;
+ protected static final int DAY_OF_MONTH = 3;
+ protected static final int MONTH = 4;
+ protected static final int DAY_OF_WEEK = 5;
+ protected static final int YEAR = 6;
+ protected static final int ALL_SPEC_INT = 99; // '*'
+ protected static final int NO_SPEC_INT = 98; // '?'
+ protected static final Integer ALL_SPEC = ALL_SPEC_INT;
+ protected static final Integer NO_SPEC = NO_SPEC_INT;
+
+ protected static final Map monthMap = new HashMap(20);
+ protected static final Map dayMap = new HashMap(60);
+ static {
+ monthMap.put("JAN", 0);
+ monthMap.put("FEB", 1);
+ monthMap.put("MAR", 2);
+ monthMap.put("APR", 3);
+ monthMap.put("MAY", 4);
+ monthMap.put("JUN", 5);
+ monthMap.put("JUL", 6);
+ monthMap.put("AUG", 7);
+ monthMap.put("SEP", 8);
+ monthMap.put("OCT", 9);
+ monthMap.put("NOV", 10);
+ monthMap.put("DEC", 11);
+
+ dayMap.put("SUN", 1);
+ dayMap.put("MON", 2);
+ dayMap.put("TUE", 3);
+ dayMap.put("WED", 4);
+ dayMap.put("THU", 5);
+ dayMap.put("FRI", 6);
+ dayMap.put("SAT", 7);
+ }
+
+ private final String cronExpression;
+ private TimeZone timeZone = null;
+ protected transient TreeSet seconds;
+ protected transient TreeSet minutes;
+ protected transient TreeSet hours;
+ protected transient TreeSet daysOfMonth;
+ protected transient TreeSet months;
+ protected transient TreeSet daysOfWeek;
+ protected transient TreeSet years;
+
+ protected transient boolean lastdayOfWeek = false;
+ protected transient int nthdayOfWeek = 0;
+ protected transient boolean lastdayOfMonth = false;
+ protected transient boolean nearestWeekday = false;
+ protected transient int lastdayOffset = 0;
+ protected transient boolean expressionParsed = false;
+
+ public static final int MAX_YEAR = Calendar.getInstance().get(Calendar.YEAR) + 100;
+
+ /**
+ * Constructs a new CronExpression
based on the specified
+ * parameter.
+ *
+ * @param cronExpression String representation of the cron expression the
+ * new object should represent
+ * @throws ParseException
+ * if the string expression cannot be parsed into a valid
+ * CronExpression
+ */
+ public CronExpression(String cronExpression) throws ParseException {
+ if (cronExpression == null) {
+ throw new IllegalArgumentException("cronExpression cannot be null");
+ }
+
+ this.cronExpression = cronExpression.toUpperCase(Locale.US);
+
+ buildExpression(this.cronExpression);
+ }
+
+ /**
+ * Constructs a new {@code CronExpression} as a copy of an existing
+ * instance.
+ *
+ * @param expression
+ * The existing cron expression to be copied
+ */
+ public CronExpression(CronExpression expression) {
+ /*
+ * We don't call the other constructor here since we need to swallow the
+ * ParseException. We also elide some of the sanity checking as it is
+ * not logically trippable.
+ */
+ this.cronExpression = expression.getCronExpression();
+ try {
+ buildExpression(cronExpression);
+ } catch (ParseException ex) {
+ throw new AssertionError();
+ }
+ if (expression.getTimeZone() != null) {
+ setTimeZone((TimeZone) expression.getTimeZone().clone());
+ }
+ }
+
+ /**
+ * Indicates whether the given date satisfies the cron expression. Note that
+ * milliseconds are ignored, so two Dates falling on different milliseconds
+ * of the same second will always have the same result here.
+ *
+ * @param date the date to evaluate
+ * @return a boolean indicating whether the given date satisfies the cron
+ * expression
+ */
+ public boolean isSatisfiedBy(Date date) {
+ Calendar testDateCal = Calendar.getInstance(getTimeZone());
+ testDateCal.setTime(date);
+ testDateCal.set(Calendar.MILLISECOND, 0);
+ Date originalDate = testDateCal.getTime();
+
+ testDateCal.add(Calendar.SECOND, -1);
+
+ Date timeAfter = getTimeAfter(testDateCal.getTime());
+
+ return ((timeAfter != null) && (timeAfter.equals(originalDate)));
+ }
+
+ /**
+ * Returns the next date/time after the given date/time which
+ * satisfies the cron expression.
+ *
+ * @param date the date/time at which to begin the search for the next valid
+ * date/time
+ * @return the next valid date/time
+ */
+ public Date getNextValidTimeAfter(Date date) {
+ return getTimeAfter(date);
+ }
+
+ /**
+ * Returns the next date/time after the given date/time which does
+ * not satisfy the expression
+ *
+ * @param date the date/time at which to begin the search for the next
+ * invalid date/time
+ * @return the next valid date/time
+ */
+ public Date getNextInvalidTimeAfter(Date date) {
+ long difference = 1000;
+
+ //move back to the nearest second so differences will be accurate
+ Calendar adjustCal = Calendar.getInstance(getTimeZone());
+ adjustCal.setTime(date);
+ adjustCal.set(Calendar.MILLISECOND, 0);
+ Date lastDate = adjustCal.getTime();
+
+ Date newDate;
+
+ //FUTURE_TODO: (QUARTZ-481) IMPROVE THIS! The following is a BAD solution to this problem. Performance will be very bad here, depending on the cron expression. It is, however A solution.
+
+ //keep getting the next included time until it's farther than one second
+ // apart. At that point, lastDate is the last valid fire time. We return
+ // the second immediately following it.
+ while (difference == 1000) {
+ newDate = getTimeAfter(lastDate);
+ if(newDate == null)
+ break;
+
+ difference = newDate.getTime() - lastDate.getTime();
+
+ if (difference == 1000) {
+ lastDate = newDate;
+ }
+ }
+
+ return new Date(lastDate.getTime() + 1000);
+ }
+
+ /**
+ * Returns the time zone for which this CronExpression
+ * will be resolved.
+ */
+ public TimeZone getTimeZone() {
+ if (timeZone == null) {
+ timeZone = TimeZone.getDefault();
+ }
+
+ return timeZone;
+ }
+
+ /**
+ * Sets the time zone for which this CronExpression
+ * will be resolved.
+ */
+ public void setTimeZone(TimeZone timeZone) {
+ this.timeZone = timeZone;
+ }
+
+ /**
+ * Returns the string representation of the CronExpression
+ *
+ * @return a string representation of the CronExpression
+ */
+ @Override
+ public String toString() {
+ return cronExpression;
+ }
+
+ /**
+ * Indicates whether the specified cron expression can be parsed into a
+ * valid cron expression
+ *
+ * @param cronExpression the expression to evaluate
+ * @return a boolean indicating whether the given expression is a valid cron
+ * expression
+ */
+ public static boolean isValidExpression(String cronExpression) {
+
+ try {
+ new CronExpression(cronExpression);
+ } catch (ParseException pe) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static void validateExpression(String cronExpression) throws ParseException {
+
+ new CronExpression(cronExpression);
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Expression Parsing Functions
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ protected void buildExpression(String expression) throws ParseException {
+ expressionParsed = true;
+
+ try {
+
+ if (seconds == null) {
+ seconds = new TreeSet();
+ }
+ if (minutes == null) {
+ minutes = new TreeSet();
+ }
+ if (hours == null) {
+ hours = new TreeSet();
+ }
+ if (daysOfMonth == null) {
+ daysOfMonth = new TreeSet();
+ }
+ if (months == null) {
+ months = new TreeSet();
+ }
+ if (daysOfWeek == null) {
+ daysOfWeek = new TreeSet();
+ }
+ if (years == null) {
+ years = new TreeSet();
+ }
+
+ int exprOn = SECOND;
+
+ StringTokenizer exprsTok = new StringTokenizer(expression, " \t",
+ false);
+
+ while (exprsTok.hasMoreTokens() && exprOn <= YEAR) {
+ String expr = exprsTok.nextToken().trim();
+
+ // throw an exception if L is used with other days of the month
+ if(exprOn == DAY_OF_MONTH && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) {
+ throw new ParseException("Support for specifying 'L' and 'LW' with other days of the month is not implemented", -1);
+ }
+ // throw an exception if L is used with other days of the week
+ if(exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) {
+ throw new ParseException("Support for specifying 'L' with other days of the week is not implemented", -1);
+ }
+ if(exprOn == DAY_OF_WEEK && expr.indexOf('#') != -1 && expr.indexOf('#', expr.indexOf('#') +1) != -1) {
+ throw new ParseException("Support for specifying multiple \"nth\" days is not implemented.", -1);
+ }
+
+ StringTokenizer vTok = new StringTokenizer(expr, ",");
+ while (vTok.hasMoreTokens()) {
+ String v = vTok.nextToken();
+ storeExpressionVals(0, v, exprOn);
+ }
+
+ exprOn++;
+ }
+
+ if (exprOn <= DAY_OF_WEEK) {
+ throw new ParseException("Unexpected end of expression.",
+ expression.length());
+ }
+
+ if (exprOn <= YEAR) {
+ storeExpressionVals(0, "*", YEAR);
+ }
+
+ TreeSet dow = getSet(DAY_OF_WEEK);
+ TreeSet dom = getSet(DAY_OF_MONTH);
+
+ // Copying the logic from the UnsupportedOperationException below
+ boolean dayOfMSpec = !dom.contains(NO_SPEC);
+ boolean dayOfWSpec = !dow.contains(NO_SPEC);
+
+ if (!dayOfMSpec || dayOfWSpec) {
+ if (!dayOfWSpec || dayOfMSpec) {
+ throw new ParseException(
+ "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.", 0);
+ }
+ }
+ } catch (ParseException pe) {
+ throw pe;
+ } catch (Exception e) {
+ throw new ParseException("Illegal cron expression format ("
+ + e.toString() + ")", 0);
+ }
+ }
+
+ protected int storeExpressionVals(int pos, String s, int type)
+ throws ParseException {
+
+ int incr = 0;
+ int i = skipWhiteSpace(pos, s);
+ if (i >= s.length()) {
+ return i;
+ }
+ char c = s.charAt(i);
+ if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW")) && (!s.matches("^L-[0-9]*[W]?"))) {
+ String sub = s.substring(i, i + 3);
+ int sval = -1;
+ int eval = -1;
+ if (type == MONTH) {
+ sval = getMonthNumber(sub) + 1;
+ if (sval <= 0) {
+ throw new ParseException("Invalid Month value: '" + sub + "'", i);
+ }
+ if (s.length() > i + 3) {
+ c = s.charAt(i + 3);
+ if (c == '-') {
+ i += 4;
+ sub = s.substring(i, i + 3);
+ eval = getMonthNumber(sub) + 1;
+ if (eval <= 0) {
+ throw new ParseException("Invalid Month value: '" + sub + "'", i);
+ }
+ }
+ }
+ } else if (type == DAY_OF_WEEK) {
+ sval = getDayOfWeekNumber(sub);
+ if (sval < 0) {
+ throw new ParseException("Invalid Day-of-Week value: '"
+ + sub + "'", i);
+ }
+ if (s.length() > i + 3) {
+ c = s.charAt(i + 3);
+ if (c == '-') {
+ i += 4;
+ sub = s.substring(i, i + 3);
+ eval = getDayOfWeekNumber(sub);
+ if (eval < 0) {
+ throw new ParseException(
+ "Invalid Day-of-Week value: '" + sub
+ + "'", i);
+ }
+ } else if (c == '#') {
+ try {
+ i += 4;
+ nthdayOfWeek = Integer.parseInt(s.substring(i));
+ if (nthdayOfWeek < 1 || nthdayOfWeek > 5) {
+ throw new Exception();
+ }
+ } catch (Exception e) {
+ throw new ParseException(
+ "A numeric value between 1 and 5 must follow the '#' option",
+ i);
+ }
+ } else if (c == 'L') {
+ lastdayOfWeek = true;
+ i++;
+ }
+ }
+
+ } else {
+ throw new ParseException(
+ "Illegal characters for this position: '" + sub + "'",
+ i);
+ }
+ if (eval != -1) {
+ incr = 1;
+ }
+ addToSet(sval, eval, incr, type);
+ return (i + 3);
+ }
+
+ if (c == '?') {
+ i++;
+ if ((i + 1) < s.length()
+ && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\t')) {
+ throw new ParseException("Illegal character after '?': "
+ + s.charAt(i), i);
+ }
+ if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) {
+ throw new ParseException(
+ "'?' can only be specified for Day-of-Month or Day-of-Week.",
+ i);
+ }
+ if (type == DAY_OF_WEEK && !lastdayOfMonth) {
+ int val = daysOfMonth.last();
+ if (val == NO_SPEC_INT) {
+ throw new ParseException(
+ "'?' can only be specified for Day-of-Month -OR- Day-of-Week.",
+ i);
+ }
+ }
+
+ addToSet(NO_SPEC_INT, -1, 0, type);
+ return i;
+ }
+
+ if (c == '*' || c == '/') {
+ if (c == '*' && (i + 1) >= s.length()) {
+ addToSet(ALL_SPEC_INT, -1, incr, type);
+ return i + 1;
+ } else if (c == '/'
+ && ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s
+ .charAt(i + 1) == '\t')) {
+ throw new ParseException("'/' must be followed by an integer.", i);
+ } else if (c == '*') {
+ i++;
+ }
+ c = s.charAt(i);
+ if (c == '/') { // is an increment specified?
+ i++;
+ if (i >= s.length()) {
+ throw new ParseException("Unexpected end of string.", i);
+ }
+
+ incr = getNumericValue(s, i);
+
+ i++;
+ if (incr > 10) {
+ i++;
+ }
+ checkIncrementRange(incr, type, i);
+ } else {
+ incr = 1;
+ }
+
+ addToSet(ALL_SPEC_INT, -1, incr, type);
+ return i;
+ } else if (c == 'L') {
+ i++;
+ if (type == DAY_OF_MONTH) {
+ lastdayOfMonth = true;
+ }
+ if (type == DAY_OF_WEEK) {
+ addToSet(7, 7, 0, type);
+ }
+ if(type == DAY_OF_MONTH && s.length() > i) {
+ c = s.charAt(i);
+ if(c == '-') {
+ ValueSet vs = getValue(0, s, i+1);
+ lastdayOffset = vs.value;
+ if(lastdayOffset > 30)
+ throw new ParseException("Offset from last day must be <= 30", i+1);
+ i = vs.pos;
+ }
+ if(s.length() > i) {
+ c = s.charAt(i);
+ if(c == 'W') {
+ nearestWeekday = true;
+ i++;
+ }
+ }
+ }
+ return i;
+ } else if (c >= '0' && c <= '9') {
+ int val = Integer.parseInt(String.valueOf(c));
+ i++;
+ if (i >= s.length()) {
+ addToSet(val, -1, -1, type);
+ } else {
+ c = s.charAt(i);
+ if (c >= '0' && c <= '9') {
+ ValueSet vs = getValue(val, s, i);
+ val = vs.value;
+ i = vs.pos;
+ }
+ i = checkNext(i, s, val, type);
+ return i;
+ }
+ } else {
+ throw new ParseException("Unexpected character: " + c, i);
+ }
+
+ return i;
+ }
+
+ private void checkIncrementRange(int incr, int type, int idxPos) throws ParseException {
+ if (incr > 59 && (type == SECOND || type == MINUTE)) {
+ throw new ParseException("Increment > 60 : " + incr, idxPos);
+ } else if (incr > 23 && (type == HOUR)) {
+ throw new ParseException("Increment > 24 : " + incr, idxPos);
+ } else if (incr > 31 && (type == DAY_OF_MONTH)) {
+ throw new ParseException("Increment > 31 : " + incr, idxPos);
+ } else if (incr > 7 && (type == DAY_OF_WEEK)) {
+ throw new ParseException("Increment > 7 : " + incr, idxPos);
+ } else if (incr > 12 && (type == MONTH)) {
+ throw new ParseException("Increment > 12 : " + incr, idxPos);
+ }
+ }
+
+ protected int checkNext(int pos, String s, int val, int type)
+ throws ParseException {
+
+ int end = -1;
+ int i = pos;
+
+ if (i >= s.length()) {
+ addToSet(val, end, -1, type);
+ return i;
+ }
+
+ char c = s.charAt(pos);
+
+ if (c == 'L') {
+ if (type == DAY_OF_WEEK) {
+ if(val < 1 || val > 7)
+ throw new ParseException("Day-of-Week values must be between 1 and 7", -1);
+ lastdayOfWeek = true;
+ } else {
+ throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i);
+ }
+ TreeSet set = getSet(type);
+ set.add(val);
+ i++;
+ return i;
+ }
+
+ if (c == 'W') {
+ if (type == DAY_OF_MONTH) {
+ nearestWeekday = true;
+ } else {
+ throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i);
+ }
+ if(val > 31)
+ throw new ParseException("The 'W' option does not make sense with values larger than 31 (max number of days in a month)", i);
+ TreeSet set = getSet(type);
+ set.add(val);
+ i++;
+ return i;
+ }
+
+ if (c == '#') {
+ if (type != DAY_OF_WEEK) {
+ throw new ParseException("'#' option is not valid here. (pos=" + i + ")", i);
+ }
+ i++;
+ try {
+ nthdayOfWeek = Integer.parseInt(s.substring(i));
+ if (nthdayOfWeek < 1 || nthdayOfWeek > 5) {
+ throw new Exception();
+ }
+ } catch (Exception e) {
+ throw new ParseException(
+ "A numeric value between 1 and 5 must follow the '#' option",
+ i);
+ }
+
+ TreeSet set = getSet(type);
+ set.add(val);
+ i++;
+ return i;
+ }
+
+ if (c == '-') {
+ i++;
+ c = s.charAt(i);
+ int v = Integer.parseInt(String.valueOf(c));
+ end = v;
+ i++;
+ if (i >= s.length()) {
+ addToSet(val, end, 1, type);
+ return i;
+ }
+ c = s.charAt(i);
+ if (c >= '0' && c <= '9') {
+ ValueSet vs = getValue(v, s, i);
+ end = vs.value;
+ i = vs.pos;
+ }
+ if (i < s.length() && ((c = s.charAt(i)) == '/')) {
+ i++;
+ c = s.charAt(i);
+ int v2 = Integer.parseInt(String.valueOf(c));
+ i++;
+ if (i >= s.length()) {
+ addToSet(val, end, v2, type);
+ return i;
+ }
+ c = s.charAt(i);
+ if (c >= '0' && c <= '9') {
+ ValueSet vs = getValue(v2, s, i);
+ int v3 = vs.value;
+ addToSet(val, end, v3, type);
+ i = vs.pos;
+ return i;
+ } else {
+ addToSet(val, end, v2, type);
+ return i;
+ }
+ } else {
+ addToSet(val, end, 1, type);
+ return i;
+ }
+ }
+
+ if (c == '/') {
+ if ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s.charAt(i + 1) == '\t') {
+ throw new ParseException("'/' must be followed by an integer.", i);
+ }
+
+ i++;
+ c = s.charAt(i);
+ int v2 = Integer.parseInt(String.valueOf(c));
+ i++;
+ if (i >= s.length()) {
+ checkIncrementRange(v2, type, i);
+ addToSet(val, end, v2, type);
+ return i;
+ }
+ c = s.charAt(i);
+ if (c >= '0' && c <= '9') {
+ ValueSet vs = getValue(v2, s, i);
+ int v3 = vs.value;
+ checkIncrementRange(v3, type, i);
+ addToSet(val, end, v3, type);
+ i = vs.pos;
+ return i;
+ } else {
+ throw new ParseException("Unexpected character '" + c + "' after '/'", i);
+ }
+ }
+
+ addToSet(val, end, 0, type);
+ i++;
+ return i;
+ }
+
+ public String getCronExpression() {
+ return cronExpression;
+ }
+
+ public String getExpressionSummary() {
+ StringBuilder buf = new StringBuilder();
+
+ buf.append("seconds: ");
+ buf.append(getExpressionSetSummary(seconds));
+ buf.append("\n");
+ buf.append("minutes: ");
+ buf.append(getExpressionSetSummary(minutes));
+ buf.append("\n");
+ buf.append("hours: ");
+ buf.append(getExpressionSetSummary(hours));
+ buf.append("\n");
+ buf.append("daysOfMonth: ");
+ buf.append(getExpressionSetSummary(daysOfMonth));
+ buf.append("\n");
+ buf.append("months: ");
+ buf.append(getExpressionSetSummary(months));
+ buf.append("\n");
+ buf.append("daysOfWeek: ");
+ buf.append(getExpressionSetSummary(daysOfWeek));
+ buf.append("\n");
+ buf.append("lastdayOfWeek: ");
+ buf.append(lastdayOfWeek);
+ buf.append("\n");
+ buf.append("nearestWeekday: ");
+ buf.append(nearestWeekday);
+ buf.append("\n");
+ buf.append("NthDayOfWeek: ");
+ buf.append(nthdayOfWeek);
+ buf.append("\n");
+ buf.append("lastdayOfMonth: ");
+ buf.append(lastdayOfMonth);
+ buf.append("\n");
+ buf.append("years: ");
+ buf.append(getExpressionSetSummary(years));
+ buf.append("\n");
+
+ return buf.toString();
+ }
+
+ protected String getExpressionSetSummary(Set set) {
+
+ if (set.contains(NO_SPEC)) {
+ return "?";
+ }
+ if (set.contains(ALL_SPEC)) {
+ return "*";
+ }
+
+ StringBuilder buf = new StringBuilder();
+
+ Iterator itr = set.iterator();
+ boolean first = true;
+ while (itr.hasNext()) {
+ Integer iVal = itr.next();
+ String val = iVal.toString();
+ if (!first) {
+ buf.append(",");
+ }
+ buf.append(val);
+ first = false;
+ }
+
+ return buf.toString();
+ }
+
+ protected String getExpressionSetSummary(ArrayList list) {
+
+ if (list.contains(NO_SPEC)) {
+ return "?";
+ }
+ if (list.contains(ALL_SPEC)) {
+ return "*";
+ }
+
+ StringBuilder buf = new StringBuilder();
+
+ Iterator itr = list.iterator();
+ boolean first = true;
+ while (itr.hasNext()) {
+ Integer iVal = itr.next();
+ String val = iVal.toString();
+ if (!first) {
+ buf.append(",");
+ }
+ buf.append(val);
+ first = false;
+ }
+
+ return buf.toString();
+ }
+
+ protected int skipWhiteSpace(int i, String s) {
+ for (; i < s.length() && (s.charAt(i) == ' ' || s.charAt(i) == '\t'); i++) {
+ }
+
+ return i;
+ }
+
+ protected int findNextWhiteSpace(int i, String s) {
+ for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t'); i++) {
+ }
+
+ return i;
+ }
+
+ protected void addToSet(int val, int end, int incr, int type)
+ throws ParseException {
+
+ TreeSet set = getSet(type);
+
+ if (type == SECOND || type == MINUTE) {
+ if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) {
+ throw new ParseException(
+ "Minute and Second values must be between 0 and 59",
+ -1);
+ }
+ } else if (type == HOUR) {
+ if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT)) {
+ throw new ParseException(
+ "Hour values must be between 0 and 23", -1);
+ }
+ } else if (type == DAY_OF_MONTH) {
+ if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT)
+ && (val != NO_SPEC_INT)) {
+ throw new ParseException(
+ "Day of month values must be between 1 and 31", -1);
+ }
+ } else if (type == MONTH) {
+ if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT)) {
+ throw new ParseException(
+ "Month values must be between 1 and 12", -1);
+ }
+ } else if (type == DAY_OF_WEEK) {
+ if ((val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT)
+ && (val != NO_SPEC_INT)) {
+ throw new ParseException(
+ "Day-of-Week values must be between 1 and 7", -1);
+ }
+ }
+
+ if ((incr == 0 || incr == -1) && val != ALL_SPEC_INT) {
+ if (val != -1) {
+ set.add(val);
+ } else {
+ set.add(NO_SPEC);
+ }
+
+ return;
+ }
+
+ int startAt = val;
+ int stopAt = end;
+
+ if (val == ALL_SPEC_INT && incr <= 0) {
+ incr = 1;
+ set.add(ALL_SPEC); // put in a marker, but also fill values
+ }
+
+ if (type == SECOND || type == MINUTE) {
+ if (stopAt == -1) {
+ stopAt = 59;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 0;
+ }
+ } else if (type == HOUR) {
+ if (stopAt == -1) {
+ stopAt = 23;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 0;
+ }
+ } else if (type == DAY_OF_MONTH) {
+ if (stopAt == -1) {
+ stopAt = 31;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 1;
+ }
+ } else if (type == MONTH) {
+ if (stopAt == -1) {
+ stopAt = 12;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 1;
+ }
+ } else if (type == DAY_OF_WEEK) {
+ if (stopAt == -1) {
+ stopAt = 7;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 1;
+ }
+ } else if (type == YEAR) {
+ if (stopAt == -1) {
+ stopAt = MAX_YEAR;
+ }
+ if (startAt == -1 || startAt == ALL_SPEC_INT) {
+ startAt = 1970;
+ }
+ }
+
+ // if the end of the range is before the start, then we need to overflow into
+ // the next day, month etc. This is done by adding the maximum amount for that
+ // type, and using modulus max to determine the value being added.
+ int max = -1;
+ if (stopAt < startAt) {
+ switch (type) {
+ case SECOND : max = 60; break;
+ case MINUTE : max = 60; break;
+ case HOUR : max = 24; break;
+ case MONTH : max = 12; break;
+ case DAY_OF_WEEK : max = 7; break;
+ case DAY_OF_MONTH : max = 31; break;
+ case YEAR : throw new IllegalArgumentException("Start year must be less than stop year");
+ default : throw new IllegalArgumentException("Unexpected type encountered");
+ }
+ stopAt += max;
+ }
+
+ for (int i = startAt; i <= stopAt; i += incr) {
+ if (max == -1) {
+ // ie: there's no max to overflow over
+ set.add(i);
+ } else {
+ // take the modulus to get the real value
+ int i2 = i % max;
+
+ // 1-indexed ranges should not include 0, and should include their max
+ if (i2 == 0 && (type == MONTH || type == DAY_OF_WEEK || type == DAY_OF_MONTH) ) {
+ i2 = max;
+ }
+
+ set.add(i2);
+ }
+ }
+ }
+
+ TreeSet getSet(int type) {
+ switch (type) {
+ case SECOND:
+ return seconds;
+ case MINUTE:
+ return minutes;
+ case HOUR:
+ return hours;
+ case DAY_OF_MONTH:
+ return daysOfMonth;
+ case MONTH:
+ return months;
+ case DAY_OF_WEEK:
+ return daysOfWeek;
+ case YEAR:
+ return years;
+ default:
+ return null;
+ }
+ }
+
+ protected ValueSet getValue(int v, String s, int i) {
+ char c = s.charAt(i);
+ StringBuilder s1 = new StringBuilder(String.valueOf(v));
+ while (c >= '0' && c <= '9') {
+ s1.append(c);
+ i++;
+ if (i >= s.length()) {
+ break;
+ }
+ c = s.charAt(i);
+ }
+ ValueSet val = new ValueSet();
+
+ val.pos = (i < s.length()) ? i : i + 1;
+ val.value = Integer.parseInt(s1.toString());
+ return val;
+ }
+
+ protected int getNumericValue(String s, int i) {
+ int endOfVal = findNextWhiteSpace(i, s);
+ String val = s.substring(i, endOfVal);
+ return Integer.parseInt(val);
+ }
+
+ protected int getMonthNumber(String s) {
+ Integer integer = monthMap.get(s);
+
+ if (integer == null) {
+ return -1;
+ }
+
+ return integer;
+ }
+
+ protected int getDayOfWeekNumber(String s) {
+ Integer integer = dayMap.get(s);
+
+ if (integer == null) {
+ return -1;
+ }
+
+ return integer;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Computation Functions
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ public Date getTimeAfter(Date afterTime) {
+
+ // Computation is based on Gregorian year only.
+ Calendar cl = new GregorianCalendar(getTimeZone());
+
+ // move ahead one second, since we're computing the time *after* the
+ // given time
+ afterTime = new Date(afterTime.getTime() + 1000);
+ // CronTrigger does not deal with milliseconds
+ cl.setTime(afterTime);
+ cl.set(Calendar.MILLISECOND, 0);
+
+ boolean gotOne = false;
+ // loop until we've computed the next time, or we've past the endTime
+ while (!gotOne) {
+
+ //if (endTime != null && cl.getTime().after(endTime)) return null;
+ if(cl.get(Calendar.YEAR) > 2999) { // prevent endless loop...
+ return null;
+ }
+
+ SortedSet st = null;
+ int t = 0;
+
+ int sec = cl.get(Calendar.SECOND);
+ int min = cl.get(Calendar.MINUTE);
+
+ // get second.................................................
+ st = seconds.tailSet(sec);
+ if (st != null && st.size() != 0) {
+ sec = st.first();
+ } else {
+ sec = seconds.first();
+ min++;
+ cl.set(Calendar.MINUTE, min);
+ }
+ cl.set(Calendar.SECOND, sec);
+
+ min = cl.get(Calendar.MINUTE);
+ int hr = cl.get(Calendar.HOUR_OF_DAY);
+ t = -1;
+
+ // get minute.................................................
+ st = minutes.tailSet(min);
+ if (st != null && st.size() != 0) {
+ t = min;
+ min = st.first();
+ } else {
+ min = minutes.first();
+ hr++;
+ }
+ if (min != t) {
+ cl.set(Calendar.SECOND, 0);
+ cl.set(Calendar.MINUTE, min);
+ setCalendarHour(cl, hr);
+ continue;
+ }
+ cl.set(Calendar.MINUTE, min);
+
+ hr = cl.get(Calendar.HOUR_OF_DAY);
+ int day = cl.get(Calendar.DAY_OF_MONTH);
+ t = -1;
+
+ // get hour...................................................
+ st = hours.tailSet(hr);
+ if (st != null && st.size() != 0) {
+ t = hr;
+ hr = st.first();
+ } else {
+ hr = hours.first();
+ day++;
+ }
+ if (hr != t) {
+ cl.set(Calendar.SECOND, 0);
+ cl.set(Calendar.MINUTE, 0);
+ cl.set(Calendar.DAY_OF_MONTH, day);
+ setCalendarHour(cl, hr);
+ continue;
+ }
+ cl.set(Calendar.HOUR_OF_DAY, hr);
+
+ day = cl.get(Calendar.DAY_OF_MONTH);
+ int mon = cl.get(Calendar.MONTH) + 1;
+ // '+ 1' because calendar is 0-based for this field, and we are
+ // 1-based
+ t = -1;
+ int tmon = mon;
+
+ // get day...................................................
+ boolean dayOfMSpec = !daysOfMonth.contains(NO_SPEC);
+ boolean dayOfWSpec = !daysOfWeek.contains(NO_SPEC);
+ if (dayOfMSpec && !dayOfWSpec) { // get day by day of month rule
+ st = daysOfMonth.tailSet(day);
+ if (lastdayOfMonth) {
+ if(!nearestWeekday) {
+ t = day;
+ day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
+ day -= lastdayOffset;
+ if(t > day) {
+ mon++;
+ if(mon > 12) {
+ mon = 1;
+ tmon = 3333; // ensure test of mon != tmon further below fails
+ cl.add(Calendar.YEAR, 1);
+ }
+ day = 1;
+ }
+ } else {
+ t = day;
+ day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
+ day -= lastdayOffset;
+
+ Calendar tcal = Calendar.getInstance(getTimeZone());
+ tcal.set(Calendar.SECOND, 0);
+ tcal.set(Calendar.MINUTE, 0);
+ tcal.set(Calendar.HOUR_OF_DAY, 0);
+ tcal.set(Calendar.DAY_OF_MONTH, day);
+ tcal.set(Calendar.MONTH, mon - 1);
+ tcal.set(Calendar.YEAR, cl.get(Calendar.YEAR));
+
+ int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
+ int dow = tcal.get(Calendar.DAY_OF_WEEK);
+
+ if(dow == Calendar.SATURDAY && day == 1) {
+ day += 2;
+ } else if(dow == Calendar.SATURDAY) {
+ day -= 1;
+ } else if(dow == Calendar.SUNDAY && day == ldom) {
+ day -= 2;
+ } else if(dow == Calendar.SUNDAY) {
+ day += 1;
+ }
+
+ tcal.set(Calendar.SECOND, sec);
+ tcal.set(Calendar.MINUTE, min);
+ tcal.set(Calendar.HOUR_OF_DAY, hr);
+ tcal.set(Calendar.DAY_OF_MONTH, day);
+ tcal.set(Calendar.MONTH, mon - 1);
+ Date nTime = tcal.getTime();
+ if(nTime.before(afterTime)) {
+ day = 1;
+ mon++;
+ }
+ }
+ } else if(nearestWeekday) {
+ t = day;
+ day = daysOfMonth.first();
+
+ Calendar tcal = Calendar.getInstance(getTimeZone());
+ tcal.set(Calendar.SECOND, 0);
+ tcal.set(Calendar.MINUTE, 0);
+ tcal.set(Calendar.HOUR_OF_DAY, 0);
+ tcal.set(Calendar.DAY_OF_MONTH, day);
+ tcal.set(Calendar.MONTH, mon - 1);
+ tcal.set(Calendar.YEAR, cl.get(Calendar.YEAR));
+
+ int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
+ int dow = tcal.get(Calendar.DAY_OF_WEEK);
+
+ if(dow == Calendar.SATURDAY && day == 1) {
+ day += 2;
+ } else if(dow == Calendar.SATURDAY) {
+ day -= 1;
+ } else if(dow == Calendar.SUNDAY && day == ldom) {
+ day -= 2;
+ } else if(dow == Calendar.SUNDAY) {
+ day += 1;
+ }
+
+
+ tcal.set(Calendar.SECOND, sec);
+ tcal.set(Calendar.MINUTE, min);
+ tcal.set(Calendar.HOUR_OF_DAY, hr);
+ tcal.set(Calendar.DAY_OF_MONTH, day);
+ tcal.set(Calendar.MONTH, mon - 1);
+ Date nTime = tcal.getTime();
+ if(nTime.before(afterTime)) {
+ day = daysOfMonth.first();
+ mon++;
+ }
+ } else if (st != null && st.size() != 0) {
+ t = day;
+ day = st.first();
+ // make sure we don't over-run a short month, such as february
+ int lastDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
+ if (day > lastDay) {
+ day = daysOfMonth.first();
+ mon++;
+ }
+ } else {
+ day = daysOfMonth.first();
+ mon++;
+ }
+
+ if (day != t || mon != tmon) {
+ cl.set(Calendar.SECOND, 0);
+ cl.set(Calendar.MINUTE, 0);
+ cl.set(Calendar.HOUR_OF_DAY, 0);
+ cl.set(Calendar.DAY_OF_MONTH, day);
+ cl.set(Calendar.MONTH, mon - 1);
+ // '- 1' because calendar is 0-based for this field, and we
+ // are 1-based
+ continue;
+ }
+ } else if (dayOfWSpec && !dayOfMSpec) { // get day by day of week rule
+ if (lastdayOfWeek) { // are we looking for the last XXX day of
+ // the month?
+ int dow = daysOfWeek.first(); // desired
+ // d-o-w
+ int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
+ int daysToAdd = 0;
+ if (cDow < dow) {
+ daysToAdd = dow - cDow;
+ }
+ if (cDow > dow) {
+ daysToAdd = dow + (7 - cDow);
+ }
+
+ int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
+
+ if (day + daysToAdd > lDay) { // did we already miss the
+ // last one?
+ cl.set(Calendar.SECOND, 0);
+ cl.set(Calendar.MINUTE, 0);
+ cl.set(Calendar.HOUR_OF_DAY, 0);
+ cl.set(Calendar.DAY_OF_MONTH, 1);
+ cl.set(Calendar.MONTH, mon);
+ // no '- 1' here because we are promoting the month
+ continue;
+ }
+
+ // find date of last occurrence of this day in this month...
+ while ((day + daysToAdd + 7) <= lDay) {
+ daysToAdd += 7;
+ }
+
+ day += daysToAdd;
+
+ if (daysToAdd > 0) {
+ cl.set(Calendar.SECOND, 0);
+ cl.set(Calendar.MINUTE, 0);
+ cl.set(Calendar.HOUR_OF_DAY, 0);
+ cl.set(Calendar.DAY_OF_MONTH, day);
+ cl.set(Calendar.MONTH, mon - 1);
+ // '- 1' here because we are not promoting the month
+ continue;
+ }
+
+ } else if (nthdayOfWeek != 0) {
+ // are we looking for the Nth XXX day in the month?
+ int dow = daysOfWeek.first(); // desired
+ // d-o-w
+ int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
+ int daysToAdd = 0;
+ if (cDow < dow) {
+ daysToAdd = dow - cDow;
+ } else if (cDow > dow) {
+ daysToAdd = dow + (7 - cDow);
+ }
+
+ boolean dayShifted = false;
+ if (daysToAdd > 0) {
+ dayShifted = true;
+ }
+
+ day += daysToAdd;
+ int weekOfMonth = day / 7;
+ if (day % 7 > 0) {
+ weekOfMonth++;
+ }
+
+ daysToAdd = (nthdayOfWeek - weekOfMonth) * 7;
+ day += daysToAdd;
+ if (daysToAdd < 0
+ || day > getLastDayOfMonth(mon, cl
+ .get(Calendar.YEAR))) {
+ cl.set(Calendar.SECOND, 0);
+ cl.set(Calendar.MINUTE, 0);
+ cl.set(Calendar.HOUR_OF_DAY, 0);
+ cl.set(Calendar.DAY_OF_MONTH, 1);
+ cl.set(Calendar.MONTH, mon);
+ // no '- 1' here because we are promoting the month
+ continue;
+ } else if (daysToAdd > 0 || dayShifted) {
+ cl.set(Calendar.SECOND, 0);
+ cl.set(Calendar.MINUTE, 0);
+ cl.set(Calendar.HOUR_OF_DAY, 0);
+ cl.set(Calendar.DAY_OF_MONTH, day);
+ cl.set(Calendar.MONTH, mon - 1);
+ // '- 1' here because we are NOT promoting the month
+ continue;
+ }
+ } else {
+ int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w
+ int dow = daysOfWeek.first(); // desired
+ // d-o-w
+ st = daysOfWeek.tailSet(cDow);
+ if (st != null && st.size() > 0) {
+ dow = st.first();
+ }
+
+ int daysToAdd = 0;
+ if (cDow < dow) {
+ daysToAdd = dow - cDow;
+ }
+ if (cDow > dow) {
+ daysToAdd = dow + (7 - cDow);
+ }
+
+ int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
+
+ if (day + daysToAdd > lDay) { // will we pass the end of
+ // the month?
+ cl.set(Calendar.SECOND, 0);
+ cl.set(Calendar.MINUTE, 0);
+ cl.set(Calendar.HOUR_OF_DAY, 0);
+ cl.set(Calendar.DAY_OF_MONTH, 1);
+ cl.set(Calendar.MONTH, mon);
+ // no '- 1' here because we are promoting the month
+ continue;
+ } else if (daysToAdd > 0) { // are we swithing days?
+ cl.set(Calendar.SECOND, 0);
+ cl.set(Calendar.MINUTE, 0);
+ cl.set(Calendar.HOUR_OF_DAY, 0);
+ cl.set(Calendar.DAY_OF_MONTH, day + daysToAdd);
+ cl.set(Calendar.MONTH, mon - 1);
+ // '- 1' because calendar is 0-based for this field,
+ // and we are 1-based
+ continue;
+ }
+ }
+ } else { // dayOfWSpec && !dayOfMSpec
+ throw new UnsupportedOperationException(
+ "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.");
+ }
+ cl.set(Calendar.DAY_OF_MONTH, day);
+
+ mon = cl.get(Calendar.MONTH) + 1;
+ // '+ 1' because calendar is 0-based for this field, and we are
+ // 1-based
+ int year = cl.get(Calendar.YEAR);
+ t = -1;
+
+ // test for expressions that never generate a valid fire date,
+ // but keep looping...
+ if (year > MAX_YEAR) {
+ return null;
+ }
+
+ // get month...................................................
+ st = months.tailSet(mon);
+ if (st != null && st.size() != 0) {
+ t = mon;
+ mon = st.first();
+ } else {
+ mon = months.first();
+ year++;
+ }
+ if (mon != t) {
+ cl.set(Calendar.SECOND, 0);
+ cl.set(Calendar.MINUTE, 0);
+ cl.set(Calendar.HOUR_OF_DAY, 0);
+ cl.set(Calendar.DAY_OF_MONTH, 1);
+ cl.set(Calendar.MONTH, mon - 1);
+ // '- 1' because calendar is 0-based for this field, and we are
+ // 1-based
+ cl.set(Calendar.YEAR, year);
+ continue;
+ }
+ cl.set(Calendar.MONTH, mon - 1);
+ // '- 1' because calendar is 0-based for this field, and we are
+ // 1-based
+
+ year = cl.get(Calendar.YEAR);
+ t = -1;
+
+ // get year...................................................
+ st = years.tailSet(year);
+ if (st != null && st.size() != 0) {
+ t = year;
+ year = st.first();
+ } else {
+ return null; // ran out of years...
+ }
+
+ if (year != t) {
+ cl.set(Calendar.SECOND, 0);
+ cl.set(Calendar.MINUTE, 0);
+ cl.set(Calendar.HOUR_OF_DAY, 0);
+ cl.set(Calendar.DAY_OF_MONTH, 1);
+ cl.set(Calendar.MONTH, 0);
+ // '- 1' because calendar is 0-based for this field, and we are
+ // 1-based
+ cl.set(Calendar.YEAR, year);
+ continue;
+ }
+ cl.set(Calendar.YEAR, year);
+
+ gotOne = true;
+ } // while( !done )
+
+ return cl.getTime();
+ }
+
+ /**
+ * Advance the calendar to the particular hour paying particular attention
+ * to daylight saving problems.
+ *
+ * @param cal the calendar to operate on
+ * @param hour the hour to set
+ */
+ protected void setCalendarHour(Calendar cal, int hour) {
+ cal.set(Calendar.HOUR_OF_DAY, hour);
+ if (cal.get(Calendar.HOUR_OF_DAY) != hour && hour != 24) {
+ cal.set(Calendar.HOUR_OF_DAY, hour + 1);
+ }
+ }
+
+ /**
+ * NOT YET IMPLEMENTED: Returns the time before the given time
+ * that the CronExpression
matches.
+ */
+ public Date getTimeBefore(Date endTime) {
+ // FUTURE_TODO: implement QUARTZ-423
+ return null;
+ }
+
+ /**
+ * NOT YET IMPLEMENTED: Returns the final time that the
+ * CronExpression
will match.
+ */
+ public Date getFinalFireTime() {
+ // FUTURE_TODO: implement QUARTZ-423
+ return null;
+ }
+
+ protected boolean isLeapYear(int year) {
+ return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
+ }
+
+ protected int getLastDayOfMonth(int monthNum, int year) {
+
+ switch (monthNum) {
+ case 1:
+ return 31;
+ case 2:
+ return (isLeapYear(year)) ? 29 : 28;
+ case 3:
+ return 31;
+ case 4:
+ return 30;
+ case 5:
+ return 31;
+ case 6:
+ return 30;
+ case 7:
+ return 31;
+ case 8:
+ return 31;
+ case 9:
+ return 30;
+ case 10:
+ return 31;
+ case 11:
+ return 30;
+ case 12:
+ return 31;
+ default:
+ throw new IllegalArgumentException("Illegal month number: "
+ + monthNum);
+ }
+ }
+
+
+ private void readObject(java.io.ObjectInputStream stream)
+ throws java.io.IOException, ClassNotFoundException {
+
+ stream.defaultReadObject();
+ try {
+ buildExpression(cronExpression);
+ } catch (Exception ignore) {
+ } // never happens
+ }
+
+ @Override
+ @Deprecated
+ public Object clone() {
+ return new CronExpression(this);
+ }
+}
+
+class ValueSet {
+ public int value;
+
+ public int pos;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/handler/AESEncryptHandler.java b/czsj-system/src/main/java/com/czsj/bigdata/core/handler/AESEncryptHandler.java
new file mode 100644
index 0000000..4cf6bb6
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/handler/AESEncryptHandler.java
@@ -0,0 +1,50 @@
+package com.czsj.bigdata.core.handler;
+
+
+import com.czsj.bigdata.util.AESUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedTypes;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * @author water
+ * @date 20-03-17 下午5:38
+ */
+@MappedTypes({String.class})
+public class AESEncryptHandler extends BaseTypeHandler {
+
+
+ @Override
+ public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
+ if(StringUtils.isNotBlank(parameter)){
+ ps.setString(i, AESUtil.encrypt(parameter));
+ }else{
+ ps.setString(i, null);
+ }
+ }
+
+ @Override
+ public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
+ String columnValue = rs.getString(columnName);
+ return AESUtil.decrypt(columnValue);
+ }
+
+ @Override
+ public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+ String columnValue = rs.getString(columnIndex);
+ return AESUtil.decrypt(columnValue);
+ }
+
+ @Override
+ public String getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ String columnValue = cs.getString(columnIndex);
+ return AESUtil.decrypt(columnValue);
+ }
+}
\ No newline at end of file
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/kill/KillJob.java b/czsj-system/src/main/java/com/czsj/bigdata/core/kill/KillJob.java
new file mode 100644
index 0000000..3a9cdc3
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/kill/KillJob.java
@@ -0,0 +1,42 @@
+package com.czsj.bigdata.core.kill;
+
+
+
+import com.czsj.bigdata.core.trigger.JobTrigger;
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+import com.czsj.core.enums.ExecutorBlockStrategyEnum;
+import com.czsj.core.glue.GlueTypeEnum;
+
+import java.util.Date;
+
+/**
+ * datax-job trigger
+ * Created by jingwk on 2019/12/15.
+ */
+public class KillJob {
+
+ /**
+ * @param logId
+ * @param address
+ * @param processId
+ */
+ public static ReturnT trigger(long logId, Date triggerTime, String address, String processId) {
+ ReturnT triggerResult;
+ TriggerParam triggerParam = new TriggerParam();
+ triggerParam.setJobId(-1);
+ triggerParam.setExecutorHandler("killJobHandler");
+ triggerParam.setProcessId(processId);
+ triggerParam.setLogId(logId);
+ triggerParam.setGlueType(GlueTypeEnum.BEAN.getDesc());
+ triggerParam.setExecutorBlockStrategy(ExecutorBlockStrategyEnum.SERIAL_EXECUTION.getTitle());
+ triggerParam.setLogDateTime(triggerTime.getTime());
+ if (address != null) {
+ triggerResult = JobTrigger.runExecutor(triggerParam, address);
+ } else {
+ triggerResult = new ReturnT<>(ReturnT.FAIL_CODE, null);
+ }
+ return triggerResult;
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/route/ExecutorRouteStrategyEnum.java b/czsj-system/src/main/java/com/czsj/bigdata/core/route/ExecutorRouteStrategyEnum.java
new file mode 100644
index 0000000..62d1954
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/route/ExecutorRouteStrategyEnum.java
@@ -0,0 +1,49 @@
+package com.czsj.bigdata.core.route;
+
+
+import com.czsj.bigdata.core.route.strategy.*;
+import com.czsj.bigdata.core.util.I18nUtil;
+
+/**
+ * Created by xuxueli on 17/3/10.
+ */
+public enum ExecutorRouteStrategyEnum {
+
+ FIRST(I18nUtil.getString("jobconf_route_first"), new ExecutorRouteFirst()),
+ LAST(I18nUtil.getString("jobconf_route_last"), new ExecutorRouteLast()),
+ ROUND(I18nUtil.getString("jobconf_route_round"), new ExecutorRouteRound()),
+ RANDOM(I18nUtil.getString("jobconf_route_random"), new ExecutorRouteRandom()),
+ CONSISTENT_HASH(I18nUtil.getString("jobconf_route_consistenthash"), new ExecutorRouteConsistentHash()),
+ LEAST_FREQUENTLY_USED(I18nUtil.getString("jobconf_route_lfu"), new ExecutorRouteLFU()),
+ LEAST_RECENTLY_USED(I18nUtil.getString("jobconf_route_lru"), new ExecutorRouteLRU()),
+ FAILOVER(I18nUtil.getString("jobconf_route_failover"), new ExecutorRouteFailover()),
+ BUSYOVER(I18nUtil.getString("jobconf_route_busyover"), new ExecutorRouteBusyover()),
+ SHARDING_BROADCAST(I18nUtil.getString("jobconf_route_shard"), null);
+
+ ExecutorRouteStrategyEnum(String title, ExecutorRouter router) {
+ this.title = title;
+ this.router = router;
+ }
+
+ private String title;
+ private ExecutorRouter router;
+
+ public String getTitle() {
+ return title;
+ }
+ public ExecutorRouter getRouter() {
+ return router;
+ }
+
+ public static ExecutorRouteStrategyEnum match(String name, ExecutorRouteStrategyEnum defaultItem){
+ if (name != null) {
+ for (ExecutorRouteStrategyEnum item: ExecutorRouteStrategyEnum.values()) {
+ if (item.name().equals(name)) {
+ return item;
+ }
+ }
+ }
+ return defaultItem;
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/route/ExecutorRouter.java b/czsj-system/src/main/java/com/czsj/bigdata/core/route/ExecutorRouter.java
new file mode 100644
index 0000000..e41138a
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/route/ExecutorRouter.java
@@ -0,0 +1,24 @@
+package com.czsj.bigdata.core.route;
+
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+/**
+ * Created by xuxueli on 17/3/10.
+ */
+public abstract class ExecutorRouter {
+ protected static Logger logger = LoggerFactory.getLogger(ExecutorRouter.class);
+
+ /**
+ * route address
+ *
+ * @param addressList
+ * @return ReturnT.content=address
+ */
+ public abstract ReturnT route(TriggerParam triggerParam, List addressList);
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteBusyover.java b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteBusyover.java
new file mode 100644
index 0000000..d747542
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteBusyover.java
@@ -0,0 +1,49 @@
+package com.czsj.bigdata.core.route.strategy;
+
+
+
+import com.czsj.bigdata.core.route.ExecutorRouter;
+import com.czsj.bigdata.core.scheduler.JobScheduler;
+import com.czsj.bigdata.core.util.I18nUtil;
+import com.czsj.core.biz.ExecutorBiz;
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+
+import java.util.List;
+
+/**
+ * Created by xuxueli on 17/3/10.
+ */
+public class ExecutorRouteBusyover extends ExecutorRouter {
+
+ @Override
+ public ReturnT route(TriggerParam triggerParam, List addressList) {
+ StringBuilder idleBeatResultSB = new StringBuilder();
+ for (String address : addressList) {
+ // beat
+ ReturnT idleBeatResult = null;
+ try {
+ ExecutorBiz executorBiz = JobScheduler.getExecutorBiz(address);
+ idleBeatResult = executorBiz.idleBeat(triggerParam.getJobId());
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
+ idleBeatResult = new ReturnT(ReturnT.FAIL_CODE, ""+e );
+ }
+ idleBeatResultSB.append( (idleBeatResultSB.length()>0)?"
":"")
+ .append(I18nUtil.getString("jobconf_idleBeat") + ":")
+ .append("
address:").append(address)
+ .append("
code:").append(idleBeatResult.getCode())
+ .append("
msg:").append(idleBeatResult.getMsg());
+
+ // beat success
+ if (idleBeatResult.getCode() == ReturnT.SUCCESS_CODE) {
+ idleBeatResult.setMsg(idleBeatResultSB.toString());
+ idleBeatResult.setContent(address);
+ return idleBeatResult;
+ }
+ }
+
+ return new ReturnT(ReturnT.FAIL_CODE, idleBeatResultSB.toString());
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteConsistentHash.java b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteConsistentHash.java
new file mode 100644
index 0000000..9d0d027
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteConsistentHash.java
@@ -0,0 +1,86 @@
+package com.czsj.bigdata.core.route.strategy;
+
+import com.czsj.bigdata.core.route.ExecutorRouter;
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * 分组下机器地址相同,不同JOB均匀散列在不同机器上,保证分组下机器分配JOB平均;且每个JOB固定调度其中一台机器;
+ * a、virtual node:解决不均衡问题
+ * b、hash method replace hashCode:String的hashCode可能重复,需要进一步扩大hashCode的取值范围
+ * Created by xuxueli on 17/3/10.
+ */
+public class ExecutorRouteConsistentHash extends ExecutorRouter {
+
+ private static int VIRTUAL_NODE_NUM = 100;
+
+ /**
+ * get hash code on 2^32 ring (md5散列的方式计算hash值)
+ * @param key
+ * @return
+ */
+ private static long hash(String key) {
+
+ // md5 byte
+ MessageDigest md5;
+ try {
+ md5 = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("MD5 not supported", e);
+ }
+ md5.reset();
+ byte[] keyBytes = null;
+ try {
+ keyBytes = key.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Unknown string :" + key, e);
+ }
+
+ md5.update(keyBytes);
+ byte[] digest = md5.digest();
+
+ // hash code, Truncate to 32-bits
+ long hashCode = ((long) (digest[3] & 0xFF) << 24)
+ | ((long) (digest[2] & 0xFF) << 16)
+ | ((long) (digest[1] & 0xFF) << 8)
+ | (digest[0] & 0xFF);
+
+ long truncateHashCode = hashCode & 0xffffffffL;
+ return truncateHashCode;
+ }
+
+ public String hashJob(int jobId, List addressList) {
+
+ // ------A1------A2-------A3------
+ // -----------J1------------------
+ TreeMap addressRing = new TreeMap();
+ for (String address: addressList) {
+ for (int i = 0; i < VIRTUAL_NODE_NUM; i++) {
+ long addressHash = hash("SHARD-" + address + "-NODE-" + i);
+ addressRing.put(addressHash, address);
+ }
+ }
+
+ long jobHash = hash(String.valueOf(jobId));
+ SortedMap lastRing = addressRing.tailMap(jobHash);
+ if (!lastRing.isEmpty()) {
+ return lastRing.get(lastRing.firstKey());
+ }
+ return addressRing.firstEntry().getValue();
+ }
+
+ @Override
+ public ReturnT route(TriggerParam triggerParam, List addressList) {
+ String address = hashJob(triggerParam.getJobId(), addressList);
+ return new ReturnT(address);
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteFailover.java b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteFailover.java
new file mode 100644
index 0000000..dca7603
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteFailover.java
@@ -0,0 +1,50 @@
+package com.czsj.bigdata.core.route.strategy;
+
+
+
+import com.czsj.bigdata.core.route.ExecutorRouter;
+import com.czsj.bigdata.core.scheduler.JobScheduler;
+import com.czsj.bigdata.core.util.I18nUtil;
+import com.czsj.core.biz.ExecutorBiz;
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+
+import java.util.List;
+
+/**
+ * Created by xuxueli on 17/3/10.
+ */
+public class ExecutorRouteFailover extends ExecutorRouter {
+
+ @Override
+ public ReturnT route(TriggerParam triggerParam, List addressList) {
+
+ StringBuilder beatResultSB = new StringBuilder();
+ for (String address : addressList) {
+ // beat
+ ReturnT beatResult = null;
+ try {
+ ExecutorBiz executorBiz = JobScheduler.getExecutorBiz(address);
+ beatResult = executorBiz.beat();
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
+ beatResult = new ReturnT(ReturnT.FAIL_CODE, ""+e );
+ }
+ beatResultSB.append( (beatResultSB.length()>0)?"
":"")
+ .append(I18nUtil.getString("jobconf_beat") + ":")
+ .append("
address:").append(address)
+ .append("
code:").append(beatResult.getCode())
+ .append("
msg:").append(beatResult.getMsg());
+
+ // beat success
+ if (beatResult.getCode() == ReturnT.SUCCESS_CODE) {
+
+ beatResult.setMsg(beatResultSB.toString());
+ beatResult.setContent(address);
+ return beatResult;
+ }
+ }
+ return new ReturnT(ReturnT.FAIL_CODE, beatResultSB.toString());
+
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteFirst.java b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteFirst.java
new file mode 100644
index 0000000..b3e5425
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteFirst.java
@@ -0,0 +1,21 @@
+package com.czsj.bigdata.core.route.strategy;
+
+
+
+import com.czsj.bigdata.core.route.ExecutorRouter;
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+
+import java.util.List;
+
+/**
+ * Created by xuxueli on 17/3/10.
+ */
+public class ExecutorRouteFirst extends ExecutorRouter {
+
+ @Override
+ public ReturnT route(TriggerParam triggerParam, List addressList){
+ return new ReturnT(addressList.get(0));
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteLFU.java b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteLFU.java
new file mode 100644
index 0000000..e47a40f
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteLFU.java
@@ -0,0 +1,79 @@
+package com.czsj.bigdata.core.route.strategy;
+
+import com.czsj.bigdata.core.route.ExecutorRouter;
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * 单个JOB对应的每个执行器,使用频率最低的优先被选举
+ * a(*)、LFU(Least Frequently Used):最不经常使用,频率/次数
+ * b、LRU(Least Recently Used):最近最久未使用,时间
+ *
+ * Created by xuxueli on 17/3/10.
+ */
+public class ExecutorRouteLFU extends ExecutorRouter {
+
+ private static ConcurrentMap> jobLfuMap = new ConcurrentHashMap>();
+ private static long CACHE_VALID_TIME = 0;
+
+ public String route(int jobId, List addressList) {
+
+ // cache clear
+ if (System.currentTimeMillis() > CACHE_VALID_TIME) {
+ jobLfuMap.clear();
+ CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24;
+ }
+
+ // lfu item init
+ HashMap lfuItemMap = jobLfuMap.get(jobId); // Key排序可以用TreeMap+构造入参Compare;Value排序暂时只能通过ArrayList;
+ if (lfuItemMap == null) {
+ lfuItemMap = new HashMap();
+ jobLfuMap.putIfAbsent(jobId, lfuItemMap); // 避免重复覆盖
+ }
+
+ // put new
+ for (String address: addressList) {
+ if (!lfuItemMap.containsKey(address) || lfuItemMap.get(address) >1000000 ) {
+ lfuItemMap.put(address, new Random().nextInt(addressList.size())); // 初始化时主动Random一次,缓解首次压力
+ }
+ }
+ // remove old
+ List delKeys = new ArrayList<>();
+ for (String existKey: lfuItemMap.keySet()) {
+ if (!addressList.contains(existKey)) {
+ delKeys.add(existKey);
+ }
+ }
+ if (delKeys.size() > 0) {
+ for (String delKey: delKeys) {
+ lfuItemMap.remove(delKey);
+ }
+ }
+
+ // load least userd count address
+ List> lfuItemList = new ArrayList>(lfuItemMap.entrySet());
+ Collections.sort(lfuItemList, new Comparator>() {
+ @Override
+ public int compare(Map.Entry o1, Map.Entry o2) {
+ return o1.getValue().compareTo(o2.getValue());
+ }
+ });
+
+ Map.Entry addressItem = lfuItemList.get(0);
+ String minAddress = addressItem.getKey();
+ addressItem.setValue(addressItem.getValue() + 1);
+
+ return addressItem.getKey();
+ }
+
+ @Override
+ public ReturnT route(TriggerParam triggerParam, List addressList) {
+ String address = route(triggerParam.getJobId(), addressList);
+ return new ReturnT(address);
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteLRU.java b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteLRU.java
new file mode 100644
index 0000000..93f458b
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteLRU.java
@@ -0,0 +1,76 @@
+package com.czsj.bigdata.core.route.strategy;
+
+import com.czsj.bigdata.core.route.ExecutorRouter;
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * 单个JOB对应的每个执行器,最久为使用的优先被选举
+ * a、LFU(Least Frequently Used):最不经常使用,频率/次数
+ * b(*)、LRU(Least Recently Used):最近最久未使用,时间
+ *
+ * Created by xuxueli on 17/3/10.
+ */
+public class ExecutorRouteLRU extends ExecutorRouter {
+
+ private static ConcurrentMap> jobLRUMap = new ConcurrentHashMap>();
+ private static long CACHE_VALID_TIME = 0;
+
+ public String route(int jobId, List addressList) {
+
+ // cache clear
+ if (System.currentTimeMillis() > CACHE_VALID_TIME) {
+ jobLRUMap.clear();
+ CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24;
+ }
+
+ // init lru
+ LinkedHashMap lruItem = jobLRUMap.get(jobId);
+ if (lruItem == null) {
+ /**
+ * LinkedHashMap
+ * a、accessOrder:true=访问顺序排序(get/put时排序);false=插入顺序排期;
+ * b、removeEldestEntry:新增元素时将会调用,返回true时会删除最老元素;可封装LinkedHashMap并重写该方法,比如定义最大容量,超出是返回true即可实现固定长度的LRU算法;
+ */
+ lruItem = new LinkedHashMap(16, 0.75f, true);
+ jobLRUMap.putIfAbsent(jobId, lruItem);
+ }
+
+ // put new
+ for (String address: addressList) {
+ if (!lruItem.containsKey(address)) {
+ lruItem.put(address, address);
+ }
+ }
+ // remove old
+ List delKeys = new ArrayList<>();
+ for (String existKey: lruItem.keySet()) {
+ if (!addressList.contains(existKey)) {
+ delKeys.add(existKey);
+ }
+ }
+ if (delKeys.size() > 0) {
+ for (String delKey: delKeys) {
+ lruItem.remove(delKey);
+ }
+ }
+
+ // load
+ String eldestKey = lruItem.entrySet().iterator().next().getKey();
+ String eldestValue = lruItem.get(eldestKey);
+ return eldestValue;
+ }
+
+ @Override
+ public ReturnT route(TriggerParam triggerParam, List addressList) {
+ String address = route(triggerParam.getJobId(), addressList);
+ return new ReturnT(address);
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteLast.java b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteLast.java
new file mode 100644
index 0000000..ea55806
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteLast.java
@@ -0,0 +1,21 @@
+package com.czsj.bigdata.core.route.strategy;
+
+
+
+import com.czsj.bigdata.core.route.ExecutorRouter;
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+
+import java.util.List;
+
+/**
+ * Created by xuxueli on 17/3/10.
+ */
+public class ExecutorRouteLast extends ExecutorRouter {
+
+ @Override
+ public ReturnT route(TriggerParam triggerParam, List addressList) {
+ return new ReturnT(addressList.get(addressList.size()-1));
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteRandom.java b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteRandom.java
new file mode 100644
index 0000000..5104d43
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteRandom.java
@@ -0,0 +1,23 @@
+package com.czsj.bigdata.core.route.strategy;
+
+import com.czsj.bigdata.core.route.ExecutorRouter;
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Created by xuxueli on 17/3/10.
+ */
+public class ExecutorRouteRandom extends ExecutorRouter {
+
+ private static Random localRandom = new Random();
+
+ @Override
+ public ReturnT route(TriggerParam triggerParam, List addressList) {
+ String address = addressList.get(localRandom.nextInt(addressList.size()));
+ return new ReturnT(address);
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteRound.java b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteRound.java
new file mode 100644
index 0000000..b4c91a1
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/route/strategy/ExecutorRouteRound.java
@@ -0,0 +1,40 @@
+package com.czsj.bigdata.core.route.strategy;
+
+import com.czsj.bigdata.core.route.ExecutorRouter;
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+
+
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Created by xuxueli on 17/3/10.
+ */
+public class ExecutorRouteRound extends ExecutorRouter {
+
+ private static ConcurrentMap routeCountEachJob = new ConcurrentHashMap();
+ private static long CACHE_VALID_TIME = 0;
+ private static int count(int jobId) {
+ // cache clear
+ if (System.currentTimeMillis() > CACHE_VALID_TIME) {
+ routeCountEachJob.clear();
+ CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24;
+ }
+
+ // count++
+ Integer count = routeCountEachJob.get(jobId);
+ count = (count==null || count>1000000)?(new Random().nextInt(100)):++count; // 初始化时主动Random一次,缓解首次压力
+ routeCountEachJob.put(jobId, count);
+ return count;
+ }
+
+ @Override
+ public ReturnT route(TriggerParam triggerParam, List addressList) {
+ String address = addressList.get(count(triggerParam.getJobId())%addressList.size());
+ return new ReturnT(address);
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/scheduler/JobScheduler.java b/czsj-system/src/main/java/com/czsj/bigdata/core/scheduler/JobScheduler.java
new file mode 100644
index 0000000..9706ada
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/scheduler/JobScheduler.java
@@ -0,0 +1,114 @@
+package com.czsj.bigdata.core.scheduler;
+
+
+import com.czsj.bigdata.core.conf.JobAdminConfig;
+import com.czsj.bigdata.core.thread.*;
+import com.czsj.bigdata.core.util.I18nUtil;
+import com.czsj.core.biz.ExecutorBiz;
+import com.czsj.core.enums.ExecutorBlockStrategyEnum;
+import com.czsj.rpc.remoting.invoker.call.CallType;
+import com.czsj.rpc.remoting.invoker.reference.XxlRpcReferenceBean;
+import com.czsj.rpc.remoting.invoker.route.LoadBalance;
+import com.czsj.rpc.remoting.net.impl.netty_http.client.NettyHttpClient;
+import com.czsj.rpc.serialize.impl.HessianSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @author xuxueli 2018-10-28 00:18:17
+ */
+
+public class JobScheduler {
+ private static final Logger logger = LoggerFactory.getLogger(JobScheduler.class);
+
+
+ public void init() throws Exception {
+ // init i18n
+ initI18n();
+
+ // admin registry monitor run
+ JobRegistryMonitorHelper.getInstance().start();
+
+ // admin monitor run
+ JobFailMonitorHelper.getInstance().start();
+
+ // admin trigger pool start
+ JobTriggerPoolHelper.toStart();
+
+ // admin log report start
+ JobLogReportHelper.getInstance().start();
+
+ // start-schedule
+ JobScheduleHelper.getInstance().start();
+
+ logger.info(">>>>>>>>> init czsj-ground admin success.");
+ }
+
+
+ public void destroy() throws Exception {
+
+ // stop-schedule
+ JobScheduleHelper.getInstance().toStop();
+
+ // admin log report stop
+ JobLogReportHelper.getInstance().toStop();
+
+ // admin trigger pool stop
+ JobTriggerPoolHelper.toStop();
+
+ // admin monitor stop
+ JobFailMonitorHelper.getInstance().toStop();
+
+ // admin registry stop
+ JobRegistryMonitorHelper.getInstance().toStop();
+
+ }
+
+ // ---------------------- I18n ----------------------
+
+ private void initI18n() {
+ for (ExecutorBlockStrategyEnum item : ExecutorBlockStrategyEnum.values()) {
+ item.setTitle(I18nUtil.getString("jobconf_block_".concat(item.name())));
+ }
+ }
+
+ // ---------------------- executor-client ----------------------
+ private static ConcurrentMap executorBizRepository = new ConcurrentHashMap<>();
+
+ public static ExecutorBiz getExecutorBiz(String address) throws Exception {
+ // valid
+ if (address == null || address.trim().length() == 0) {
+ return null;
+ }
+
+ // load-cache
+ address = address.trim();
+ ExecutorBiz executorBiz = executorBizRepository.get(address);
+ if (executorBiz != null) {
+ return executorBiz;
+ }
+
+ // set-cache
+ XxlRpcReferenceBean referenceBean = new XxlRpcReferenceBean();
+ referenceBean.setClient(NettyHttpClient.class);
+ referenceBean.setSerializer(HessianSerializer.class);
+ referenceBean.setCallType(CallType.SYNC);
+ referenceBean.setLoadBalance(LoadBalance.ROUND);
+ referenceBean.setIface(ExecutorBiz.class);
+ referenceBean.setVersion(null);
+ referenceBean.setTimeout(3000);
+ referenceBean.setAddress(address);
+ referenceBean.setAccessToken(JobAdminConfig.getAdminConfig().getAccessToken());
+ referenceBean.setInvokeCallback(null);
+ referenceBean.setInvokerFactory(null);
+
+ executorBiz = (ExecutorBiz) referenceBean.getObject();
+
+ executorBizRepository.put(address, executorBiz);
+ return executorBiz;
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobFailMonitorHelper.java b/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobFailMonitorHelper.java
new file mode 100644
index 0000000..36a30f8
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobFailMonitorHelper.java
@@ -0,0 +1,201 @@
+package com.czsj.bigdata.core.thread;
+
+import com.czsj.bigdata.core.conf.JobAdminConfig;
+import com.czsj.bigdata.core.trigger.TriggerTypeEnum;
+import com.czsj.bigdata.core.util.EmailUtil;
+import com.czsj.bigdata.core.util.I18nUtil;
+import com.czsj.bigdata.entity.JobGroup;
+import com.czsj.bigdata.entity.JobInfo;
+import com.czsj.bigdata.entity.JobLog;
+import com.czsj.core.biz.model.ReturnT;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.mail.internet.MimeMessage;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * job monitor instance
+ *
+ * @author xuxueli 2015-9-1 18:05:56
+ */
+public class JobFailMonitorHelper {
+ private static Logger logger = LoggerFactory.getLogger(JobFailMonitorHelper.class);
+
+ private static JobFailMonitorHelper instance = new JobFailMonitorHelper();
+ public static JobFailMonitorHelper getInstance(){
+ return instance;
+ }
+
+ // ---------------------- monitor ----------------------
+
+ private Thread monitorThread;
+ private volatile boolean toStop = false;
+ public void start(){
+ monitorThread = new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+
+ // monitor
+ while (!toStop) {
+ try {
+
+ List failLogIds = JobAdminConfig.getAdminConfig().getJobLogMapper().findFailJobLogIds(1000);
+ if (failLogIds!=null && !failLogIds.isEmpty()) {
+ for (long failLogId: failLogIds) {
+
+ // lock log
+ int lockRet = JobAdminConfig.getAdminConfig().getJobLogMapper().updateAlarmStatus(failLogId, 0, -1);
+ if (lockRet < 1) {
+ continue;
+ }
+ JobLog log = JobAdminConfig.getAdminConfig().getJobLogMapper().load(failLogId);
+ JobInfo info = JobAdminConfig.getAdminConfig().getJobInfoMapper().loadById(log.getJobId());
+
+ // 1、fail retry monitor
+ if (log.getExecutorFailRetryCount() > 0) {
+ JobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount()-1), log.getExecutorShardingParam(), log.getExecutorParam());
+ String retryMsg = "
>>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_type_retry") +"<<<<<<<<<<<
";
+ log.setTriggerMsg(log.getTriggerMsg() + retryMsg);
+ JobAdminConfig.getAdminConfig().getJobLogMapper().updateTriggerInfo(log);
+ }
+
+ // 2、fail alarm monitor
+ int newAlarmStatus = 0; // 告警状态:0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败
+ if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) {
+ boolean alarmResult = true;
+ try {
+ alarmResult = failAlarm(info, log);
+ } catch (Exception e) {
+ alarmResult = false;
+ logger.error(e.getMessage(), e);
+ }
+ newAlarmStatus = alarmResult?2:3;
+ } else {
+ newAlarmStatus = 1;
+ }
+
+ JobAdminConfig.getAdminConfig().getJobLogMapper().updateAlarmStatus(failLogId, -1, newAlarmStatus);
+ }
+ }
+
+ } catch (Exception e) {
+ if (!toStop) {
+ logger.error(">>>>>>>>>>> czsj-ground, job fail monitor thread error:{0}", e);
+ }
+ }
+
+ try {
+ TimeUnit.SECONDS.sleep(10);
+ } catch (Exception e) {
+ if (!toStop) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+ }
+
+ logger.info(">>>>>>>>>>> czsj-ground, job fail monitor thread stop");
+
+ }
+ });
+ monitorThread.setDaemon(true);
+ monitorThread.setName("czsj-ground, admin JobFailMonitorHelper");
+ monitorThread.start();
+ }
+
+ public void toStop(){
+ toStop = true;
+ // interrupt and wait
+ monitorThread.interrupt();
+ try {
+ monitorThread.join();
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+
+ // ---------------------- alarm ----------------------
+
+ // email alarm template
+ private static final String mailBodyTemplate = "" + I18nUtil.getString("jobconf_monitor_detail") + ":" +
+ "
\n" +
+ " " +
+ " \n" +
+ " "+ I18nUtil.getString("jobinfo_field_jobgroup") +" | \n" +
+ " "+ I18nUtil.getString("jobinfo_field_id") +" | \n" +
+ " "+ I18nUtil.getString("jobinfo_field_jobdesc") +" | \n" +
+ " "+ I18nUtil.getString("jobconf_monitor_alarm_title") +" | \n" +
+ " "+ I18nUtil.getString("jobconf_monitor_alarm_content") +" | \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " {0} | \n" +
+ " {1} | \n" +
+ " {2} | \n" +
+ " "+ I18nUtil.getString("jobconf_monitor_alarm_type") +" | \n" +
+ " {3} | \n" +
+ "
\n" +
+ " \n" +
+ "
";
+
+ /**
+ * fail alarm
+ *
+ * @param jobLog
+ */
+ private boolean failAlarm(JobInfo info, JobLog jobLog){
+ boolean alarmResult = true;
+
+ // send monitor email
+ if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) {
+
+ // alarmContent
+ String alarmContent = "Alarm Job LogId=" + jobLog.getId();
+ if (jobLog.getTriggerCode() != ReturnT.SUCCESS_CODE) {
+ alarmContent += "
TriggerMsg=
" + jobLog.getTriggerMsg();
+ }
+ if (jobLog.getHandleCode()>0 && jobLog.getHandleCode() != ReturnT.SUCCESS_CODE) {
+ alarmContent += "
HandleCode=" + jobLog.getHandleMsg();
+ }
+
+ // email info
+ JobGroup group = JobAdminConfig.getAdminConfig().getJobGroupMapper().load(Integer.valueOf(info.getJobGroup()));
+ String personal = I18nUtil.getString("admin_name_full");
+ String title = I18nUtil.getString("jobconf_monitor");
+ String content = MessageFormat.format(mailBodyTemplate,
+ group!=null?group.getTitle():"null",
+ info.getId(),
+ info.getJobDesc(),
+ alarmContent);
+
+ Set emailSet = new HashSet(Arrays.asList(info.getAlarmEmail().split(",")));
+ for (String email: emailSet) {
+
+ // make mail
+ try {
+ EmailUtil.send(JobAdminConfig.getAdminConfig().getEmailUserName(), JobAdminConfig.getAdminConfig().getEmailPassword(),JobAdminConfig.getAdminConfig().getEmailAuthorization(),email,title,content);
+ } catch (Exception e) {
+ logger.error(">>>>>>>>>>> czsj-ground, job fail alarm email send error, JobLogId:{}", jobLog.getId(), e);
+
+ alarmResult = false;
+ }
+
+ }
+ }
+
+ // do something, custom alarm strategy, such as sms
+
+
+ return alarmResult;
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobLogReportHelper.java b/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobLogReportHelper.java
new file mode 100644
index 0000000..a52c3cb
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobLogReportHelper.java
@@ -0,0 +1,153 @@
+package com.czsj.bigdata.core.thread;
+
+
+import com.czsj.bigdata.core.conf.JobAdminConfig;
+import com.czsj.bigdata.entity.JobLogReport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * job log report helper
+ *
+ * @author xuxueli 2019-11-22
+ */
+public class JobLogReportHelper {
+ private static Logger logger = LoggerFactory.getLogger(JobLogReportHelper.class);
+
+ private static JobLogReportHelper instance = new JobLogReportHelper();
+ public static JobLogReportHelper getInstance(){
+ return instance;
+ }
+
+
+ private Thread logrThread;
+ private volatile boolean toStop = false;
+ public void start(){
+ logrThread = new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+
+ // last clean log time
+ long lastCleanLogTime = 0;
+
+
+ while (!toStop) {
+
+ // 1、log-report refresh: refresh log report in 3 days
+ try {
+
+ for (int i = 0; i < 3; i++) {
+
+ // today
+ Calendar itemDay = Calendar.getInstance();
+ itemDay.add(Calendar.DAY_OF_MONTH, -i);
+ itemDay.set(Calendar.HOUR_OF_DAY, 0);
+ itemDay.set(Calendar.MINUTE, 0);
+ itemDay.set(Calendar.SECOND, 0);
+ itemDay.set(Calendar.MILLISECOND, 0);
+
+ Date todayFrom = itemDay.getTime();
+
+ itemDay.set(Calendar.HOUR_OF_DAY, 23);
+ itemDay.set(Calendar.MINUTE, 59);
+ itemDay.set(Calendar.SECOND, 59);
+ itemDay.set(Calendar.MILLISECOND, 999);
+
+ Date todayTo = itemDay.getTime();
+
+ // refresh log-report every minute
+ JobLogReport xxlJobLogReport = new JobLogReport();
+ xxlJobLogReport.setTriggerDay(todayFrom);
+ xxlJobLogReport.setRunningCount(0);
+ xxlJobLogReport.setSucCount(0);
+ xxlJobLogReport.setFailCount(0);
+
+ Map triggerCountMap = JobAdminConfig.getAdminConfig().getJobLogMapper().findLogReport(todayFrom, todayTo);
+ if (triggerCountMap!=null && triggerCountMap.size()>0) {
+ int triggerDayCount = triggerCountMap.containsKey("triggerDayCount")? Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCount"))):0;
+ int triggerDayCountRunning = triggerCountMap.containsKey("triggerDayCountRunning")? Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountRunning"))):0;
+ int triggerDayCountSuc = triggerCountMap.containsKey("triggerDayCountSuc")? Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountSuc"))):0;
+ int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc;
+
+ xxlJobLogReport.setRunningCount(triggerDayCountRunning);
+ xxlJobLogReport.setSucCount(triggerDayCountSuc);
+ xxlJobLogReport.setFailCount(triggerDayCountFail);
+ }
+
+ // do refresh
+ int ret = JobAdminConfig.getAdminConfig().getJobLogReportMapper().update(xxlJobLogReport);
+ if (ret < 1) {
+ JobAdminConfig.getAdminConfig().getJobLogReportMapper().save(xxlJobLogReport);
+ }
+ }
+
+ } catch (Exception e) {
+ if (!toStop) {
+ logger.error(">>>>>>>>>>> czsj-ground, job log report thread error:{}", e);
+ }
+ }
+
+ // 2、log-clean: switch open & once each day
+ if (JobAdminConfig.getAdminConfig().getLogretentiondays()>0
+ && System.currentTimeMillis() - lastCleanLogTime > 24*60*60*1000) {
+
+ // expire-time
+ Calendar expiredDay = Calendar.getInstance();
+ expiredDay.add(Calendar.DAY_OF_MONTH, -1 * JobAdminConfig.getAdminConfig().getLogretentiondays());
+ expiredDay.set(Calendar.HOUR_OF_DAY, 0);
+ expiredDay.set(Calendar.MINUTE, 0);
+ expiredDay.set(Calendar.SECOND, 0);
+ expiredDay.set(Calendar.MILLISECOND, 0);
+ Date clearBeforeTime = expiredDay.getTime();
+
+ // clean expired log
+ List logIds = null;
+ do {
+ logIds = JobAdminConfig.getAdminConfig().getJobLogMapper().findClearLogIds(0, 0, clearBeforeTime, 0, 1000);
+ if (logIds!=null && logIds.size()>0) {
+ JobAdminConfig.getAdminConfig().getJobLogMapper().clearLog(logIds);
+ }
+ } while (logIds!=null && logIds.size()>0);
+
+ // update clean time
+ lastCleanLogTime = System.currentTimeMillis();
+ }
+
+ try {
+ TimeUnit.MINUTES.sleep(1);
+ } catch (Exception e) {
+ if (!toStop) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+ }
+
+ logger.info(">>>>>>>>>>> czsj-ground, job log report thread stop");
+
+ }
+ });
+ logrThread.setDaemon(true);
+ logrThread.setName("czsj-ground, admin JobLogReportHelper");
+ logrThread.start();
+ }
+
+ public void toStop(){
+ toStop = true;
+ // interrupt and wait
+ logrThread.interrupt();
+ try {
+ logrThread.join();
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobRegistryMonitorHelper.java b/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobRegistryMonitorHelper.java
new file mode 100644
index 0000000..dc0d675
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobRegistryMonitorHelper.java
@@ -0,0 +1,109 @@
+package com.czsj.bigdata.core.thread;
+
+
+import com.czsj.bigdata.core.conf.JobAdminConfig;
+import com.czsj.bigdata.entity.JobGroup;
+import com.czsj.bigdata.entity.JobRegistry;
+import com.czsj.core.enums.RegistryConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * job registry instance
+ * @author xuxueli 2016-10-02 19:10:24
+ */
+public class JobRegistryMonitorHelper {
+ private static Logger logger = LoggerFactory.getLogger(JobRegistryMonitorHelper.class);
+
+ private static JobRegistryMonitorHelper instance = new JobRegistryMonitorHelper();
+ public static JobRegistryMonitorHelper getInstance(){
+ return instance;
+ }
+
+ private Thread registryThread;
+ private volatile boolean toStop = false;
+ public void start(){
+ registryThread = new Thread(() -> {
+ while (!toStop) {
+ try {
+ // auto registry group
+ List groupList = JobAdminConfig.getAdminConfig().getJobGroupMapper().findByAddressType(0);
+ if (groupList!=null && !groupList.isEmpty()) {
+
+ // remove dead address (admin/executor)
+ List ids = JobAdminConfig.getAdminConfig().getJobRegistryMapper().findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
+ if (ids!=null && ids.size()>0) {
+ JobAdminConfig.getAdminConfig().getJobRegistryMapper().removeDead(ids);
+ }
+
+ // fresh online address (admin/executor)
+ HashMap> appAddressMap = new HashMap<>();
+ List list = JobAdminConfig.getAdminConfig().getJobRegistryMapper().findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
+ if (list != null) {
+ for (JobRegistry item: list) {
+ if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
+ String appName = item.getRegistryKey();
+ List registryList = appAddressMap.get(appName);
+ if (registryList == null) {
+ registryList = new ArrayList<>();
+ }
+
+ if (!registryList.contains(item.getRegistryValue())) {
+ registryList.add(item.getRegistryValue());
+ }
+ appAddressMap.put(appName, registryList);
+ }
+ }
+ }
+
+ // fresh group address
+ for (JobGroup group: groupList) {
+ List registryList = appAddressMap.get(group.getAppName());
+ String addressListStr = null;
+ if (registryList!=null && !registryList.isEmpty()) {
+ Collections.sort(registryList);
+ addressListStr = "";
+ for (String item:registryList) {
+ addressListStr += item + ",";
+ }
+ addressListStr = addressListStr.substring(0, addressListStr.length()-1);
+ }
+ group.setAddressList(addressListStr);
+ JobAdminConfig.getAdminConfig().getJobGroupMapper().update(group);
+ }
+ }
+ } catch (Exception e) {
+ if (!toStop) {
+ logger.error(">>>>>>>>>>> czsj-ground, job registry monitor thread error:{}", e);
+ }
+ }
+ try {
+ TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
+ } catch (InterruptedException e) {
+ if (!toStop) {
+ logger.error(">>>>>>>>>>> czsj-ground, job registry monitor thread error:{}", e);
+ }
+ }
+ }
+ logger.info(">>>>>>>>>>> czsj-ground, job registry monitor thread stop");
+ });
+ registryThread.setDaemon(true);
+ registryThread.setName("czsj-ground, admin JobRegistryMonitorHelper");
+ registryThread.start();
+ }
+
+ public void toStop(){
+ toStop = true;
+ // interrupt and wait
+ registryThread.interrupt();
+ try {
+ registryThread.join();
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobScheduleHelper.java b/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobScheduleHelper.java
new file mode 100644
index 0000000..18dc931
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobScheduleHelper.java
@@ -0,0 +1,350 @@
+package com.czsj.bigdata.core.thread;
+
+
+import com.czsj.bigdata.core.conf.JobAdminConfig;
+import com.czsj.bigdata.core.cron.CronExpression;
+import com.czsj.bigdata.core.trigger.TriggerTypeEnum;
+import com.czsj.bigdata.entity.JobInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.text.ParseException;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author xuxueli 2019-05-21
+ */
+public class JobScheduleHelper {
+ private static Logger logger = LoggerFactory.getLogger(JobScheduleHelper.class);
+
+ private static JobScheduleHelper instance = new JobScheduleHelper();
+
+ public static JobScheduleHelper getInstance() {
+ return instance;
+ }
+
+ public static final long PRE_READ_MS = 5000; // pre read
+
+ private Thread scheduleThread;
+ private Thread ringThread;
+ private volatile boolean scheduleThreadToStop = false;
+ private volatile boolean ringThreadToStop = false;
+ private volatile static Map> ringData = new ConcurrentHashMap<>();
+
+ public void start() {
+
+ // schedule thread
+ scheduleThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+
+ try {
+ TimeUnit.MILLISECONDS.sleep(5000 - System.currentTimeMillis() % 1000);
+ } catch (InterruptedException e) {
+ if (!scheduleThreadToStop) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ logger.info(">>>>>>>>> init czsj-ground admin scheduler success.");
+
+ // pre-read count: treadpool-size * trigger-qps (each trigger cost 50ms, qps = 1000/50 = 20)
+ int preReadCount = (JobAdminConfig.getAdminConfig().getTriggerPoolFastMax() + JobAdminConfig.getAdminConfig().getTriggerPoolSlowMax()) * 20;
+
+ while (!scheduleThreadToStop) {
+
+ // Scan Job
+ long start = System.currentTimeMillis();
+
+ Connection conn = null;
+ Boolean connAutoCommit = null;
+ PreparedStatement preparedStatement = null;
+
+ boolean preReadSuc = true;
+ try {
+
+ conn = JobAdminConfig.getAdminConfig().getDataSource().getConnection();
+ connAutoCommit = conn.getAutoCommit();
+ conn.setAutoCommit(false);
+ preparedStatement = conn.prepareStatement("select * from job_lock where lock_name = 'schedule_lock' for update");
+ preparedStatement.execute();
+
+ // tx start
+
+ // 1、pre read
+ long nowTime = System.currentTimeMillis();
+ List scheduleList = JobAdminConfig.getAdminConfig().getJobInfoMapper().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount);
+ if (scheduleList != null && scheduleList.size() > 0) {
+ // 2、push time-ring
+ for (JobInfo jobInfo : scheduleList) {
+
+ // time-ring jump
+ if (nowTime > jobInfo.getTriggerNextTime() + PRE_READ_MS) {
+ // 2.1、trigger-expire > 5s:pass && make next-trigger-time
+ logger.warn(">>>>>>>>>>> czsj-ground, schedule misfire, jobId = " + jobInfo.getId());
+ // fresh next
+ refreshNextValidTime(jobInfo, new Date());
+ } else if (nowTime > jobInfo.getTriggerNextTime()) {
+ // 2.2、trigger-expire < 5s:direct-trigger && make next-trigger-time
+
+ // 1、trigger
+ JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.CRON, -1, null, null);
+ logger.debug(">>>>>>>>>>> czsj-ground, schedule push trigger : jobId = " + jobInfo.getId());
+
+ // 2、fresh next
+ refreshNextValidTime(jobInfo, new Date());
+
+ // next-trigger-time in 5s, pre-read again
+ if (jobInfo.getTriggerStatus() == 1 && nowTime + PRE_READ_MS > jobInfo.getTriggerNextTime()) {
+
+ // 1、make ring second
+ int ringSecond = (int) ((jobInfo.getTriggerNextTime() / 1000) % 60);
+
+ // 2、push time ring
+ pushTimeRing(ringSecond, jobInfo.getId());
+
+ // 3、fresh next
+ refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime()));
+
+ }
+
+ } else {
+ // 2.3、trigger-pre-read:time-ring trigger && make next-trigger-time
+
+ // 1、make ring second
+ int ringSecond = (int) ((jobInfo.getTriggerNextTime() / 1000) % 60);
+
+ // 2、push time ring
+ pushTimeRing(ringSecond, jobInfo.getId());
+
+ // 3、fresh next
+ refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime()));
+
+ }
+
+ }
+
+ // 3、update trigger info
+ for (JobInfo jobInfo : scheduleList) {
+ JobAdminConfig.getAdminConfig().getJobInfoMapper().scheduleUpdate(jobInfo);
+ }
+
+ } else {
+ preReadSuc = false;
+ }
+
+ // tx stop
+
+
+ } catch (Exception e) {
+ if (!scheduleThreadToStop) {
+ logger.error(">>>>>>>>>>> czsj-ground, JobScheduleHelper#scheduleThread error:{}", e);
+ }
+ } finally {
+
+ // commit
+ if (conn != null) {
+ try {
+ conn.commit();
+ } catch (SQLException e) {
+ if (!scheduleThreadToStop) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ try {
+ conn.setAutoCommit(connAutoCommit);
+ } catch (SQLException e) {
+ if (!scheduleThreadToStop) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ if (!scheduleThreadToStop) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ // close PreparedStatement
+ if (null != preparedStatement) {
+ try {
+ preparedStatement.close();
+ } catch (SQLException e) {
+ if (!scheduleThreadToStop) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ }
+ }
+ long cost = System.currentTimeMillis() - start;
+
+
+ // Wait seconds, align second
+ if (cost < 1000) { // scan-overtime, not wait
+ try {
+ // pre-read period: success > scan each second; fail > skip this period;
+ TimeUnit.MILLISECONDS.sleep((preReadSuc ? 1000 : PRE_READ_MS) - System.currentTimeMillis() % 1000);
+ } catch (InterruptedException e) {
+ if (!scheduleThreadToStop) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ }
+
+ logger.info(">>>>>>>>>>> czsj-ground, JobScheduleHelper#scheduleThread stop");
+ }
+ });
+ scheduleThread.setDaemon(true);
+ scheduleThread.setName("czsj-ground, admin JobScheduleHelper#scheduleThread");
+ scheduleThread.start();
+
+
+ // ring thread
+ ringThread = new Thread(() -> {
+
+ // align second
+ try {
+ TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
+ } catch (InterruptedException e) {
+ if (!ringThreadToStop) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+ while (!ringThreadToStop) {
+
+ try {
+ // second data
+ List ringItemData = new ArrayList<>();
+ int nowSecond = Calendar.getInstance().get(Calendar.SECOND); // 避免处理耗时太长,跨过刻度,向前校验一个刻度;
+ for (int i = 0; i < 2; i++) {
+ List tmpData = ringData.remove((nowSecond + 60 - i) % 60);
+ if (tmpData != null) {
+ ringItemData.addAll(tmpData);
+ }
+ }
+
+ // ring trigger
+ logger.debug(">>>>>>>>>>> czsj-ground, time-ring beat : " + nowSecond + " = " + Arrays.asList(ringItemData));
+ if (ringItemData.size() > 0) {
+ // do trigger
+ for (int jobId : ringItemData) {
+ // do trigger
+ JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);
+ }
+ // clear
+ ringItemData.clear();
+ }
+ } catch (Exception e) {
+ if (!ringThreadToStop) {
+ logger.error(">>>>>>>>>>> czsj-ground, JobScheduleHelper#ringThread error:{}", e);
+ }
+ }
+
+ // next second, align second
+ try {
+ TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
+ } catch (InterruptedException e) {
+ if (!ringThreadToStop) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ }
+ logger.info(">>>>>>>>>>> czsj-ground, JobScheduleHelper#ringThread stop");
+ });
+ ringThread.setDaemon(true);
+ ringThread.setName("czsj-ground, admin JobScheduleHelper#ringThread");
+ ringThread.start();
+ }
+
+ private void refreshNextValidTime(JobInfo jobInfo, Date fromTime) throws ParseException {
+ Date nextValidTime = new CronExpression(jobInfo.getJobCron()).getNextValidTimeAfter(fromTime);
+ if (nextValidTime != null) {
+ jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
+ jobInfo.setTriggerNextTime(nextValidTime.getTime());
+ } else {
+ jobInfo.setTriggerStatus(0);
+ jobInfo.setTriggerLastTime(0);
+ jobInfo.setTriggerNextTime(0);
+ }
+ }
+
+ private void pushTimeRing(int ringSecond, int jobId) {
+ // push async ring
+ List ringItemData = ringData.get(ringSecond);
+ if (ringItemData == null) {
+ ringItemData = new ArrayList();
+ ringData.put(ringSecond, ringItemData);
+ }
+ ringItemData.add(jobId);
+
+ logger.debug(">>>>>>>>>>> czsj-ground, schedule push time-ring : " + ringSecond + " = " + Arrays.asList(ringItemData));
+ }
+
+ public void toStop() {
+
+ // 1、stop schedule
+ scheduleThreadToStop = true;
+ try {
+ TimeUnit.SECONDS.sleep(1); // wait
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage(), e);
+ }
+ if (scheduleThread.getState() != Thread.State.TERMINATED) {
+ // interrupt and wait
+ scheduleThread.interrupt();
+ try {
+ scheduleThread.join();
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+ // if has ring data
+ boolean hasRingData = false;
+ if (!ringData.isEmpty()) {
+ for (int second : ringData.keySet()) {
+ List tmpData = ringData.get(second);
+ if (tmpData != null && tmpData.size() > 0) {
+ hasRingData = true;
+ break;
+ }
+ }
+ }
+ if (hasRingData) {
+ try {
+ TimeUnit.SECONDS.sleep(8);
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+ // stop ring (wait job-in-memory stop)
+ ringThreadToStop = true;
+ try {
+ TimeUnit.SECONDS.sleep(1);
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage(), e);
+ }
+ if (ringThread.getState() != Thread.State.TERMINATED) {
+ // interrupt and wait
+ ringThread.interrupt();
+ try {
+ ringThread.join();
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+ logger.info(">>>>>>>>>>> czsj-ground, JobScheduleHelper stop");
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobTriggerPoolHelper.java b/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobTriggerPoolHelper.java
new file mode 100644
index 0000000..1e0c3d4
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/thread/JobTriggerPoolHelper.java
@@ -0,0 +1,133 @@
+package com.czsj.bigdata.core.thread;
+
+import com.czsj.bigdata.core.conf.JobAdminConfig;
+import com.czsj.bigdata.core.trigger.JobTrigger;
+import com.czsj.bigdata.core.trigger.TriggerTypeEnum;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * job trigger thread pool helper
+ *
+ * @author xuxueli 2018-07-03 21:08:07
+ */
+public class JobTriggerPoolHelper {
+ private static Logger logger = LoggerFactory.getLogger(JobTriggerPoolHelper.class);
+
+
+ // ---------------------- trigger pool ----------------------
+
+ // fast/slow thread pool
+ private ThreadPoolExecutor fastTriggerPool = null;
+ private ThreadPoolExecutor slowTriggerPool = null;
+
+ public void start() {
+ fastTriggerPool = new ThreadPoolExecutor(
+ 10,
+ JobAdminConfig.getAdminConfig().getTriggerPoolFastMax(),
+ 60L,
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue(1000),
+ new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "czsj-ground, admin JobTriggerPoolHelper-fastTriggerPool-" + r.hashCode());
+ }
+ });
+
+ slowTriggerPool = new ThreadPoolExecutor(
+ 10,
+ JobAdminConfig.getAdminConfig().getTriggerPoolSlowMax(),
+ 60L,
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue(2000),
+ new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "czsj-ground, admin JobTriggerPoolHelper-slowTriggerPool-" + r.hashCode());
+ }
+ });
+ }
+
+
+ public void stop() {
+ //triggerPool.shutdown();
+ fastTriggerPool.shutdownNow();
+ slowTriggerPool.shutdownNow();
+ logger.info(">>>>>>>>> czsj-ground trigger thread pool shutdown success.");
+ }
+
+
+ // job timeout count
+ private volatile long minTim = System.currentTimeMillis() / 60000; // ms > min
+ private volatile ConcurrentMap jobTimeoutCountMap = new ConcurrentHashMap<>();
+
+
+ /**
+ * add trigger
+ */
+ public void addTrigger(final int jobId, final TriggerTypeEnum triggerType, final int failRetryCount, final String executorShardingParam, final String executorParam) {
+
+ // choose thread pool
+ ThreadPoolExecutor triggerPool_ = fastTriggerPool;
+ AtomicInteger jobTimeoutCount = jobTimeoutCountMap.get(jobId);
+ if (jobTimeoutCount != null && jobTimeoutCount.get() > 10) { // job-timeout 10 times in 1 min
+ triggerPool_ = slowTriggerPool;
+ }
+ // trigger
+ triggerPool_.execute(() -> {
+ long start = System.currentTimeMillis();
+ try {
+ // do trigger
+ JobTrigger.trigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam);
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
+ } finally {
+ // check timeout-count-map
+ long minTim_now = System.currentTimeMillis() / 60000;
+ if (minTim != minTim_now) {
+ minTim = minTim_now;
+ jobTimeoutCountMap.clear();
+ }
+ // incr timeout-count-map
+ long cost = System.currentTimeMillis() - start;
+ if (cost > 500) { // ob-timeout threshold 500ms
+ AtomicInteger timeoutCount = jobTimeoutCountMap.putIfAbsent(jobId, new AtomicInteger(1));
+ if (timeoutCount != null) {
+ timeoutCount.incrementAndGet();
+ }
+ }
+ }
+ });
+ }
+
+
+ // ---------------------- helper ----------------------
+
+ private static JobTriggerPoolHelper helper = new JobTriggerPoolHelper();
+
+ public static void toStart() {
+ helper.start();
+ }
+
+ public static void toStop() {
+ helper.stop();
+ }
+
+ /**
+ * @param jobId
+ * @param triggerType
+ * @param failRetryCount >=0: use this param
+ * <0: use param from job info config
+ * @param executorShardingParam
+ * @param executorParam null: use job param
+ * not null: cover job param
+ */
+ public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam) {
+ helper.addTrigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam);
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/trigger/JobTrigger.java b/czsj-system/src/main/java/com/czsj/bigdata/core/trigger/JobTrigger.java
new file mode 100644
index 0000000..bb6976e
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/trigger/JobTrigger.java
@@ -0,0 +1,263 @@
+package com.czsj.bigdata.core.trigger;
+
+
+import com.czsj.bigdata.core.conf.JobAdminConfig;
+import com.czsj.bigdata.core.route.ExecutorRouteStrategyEnum;
+import com.czsj.bigdata.core.scheduler.JobScheduler;
+import com.czsj.bigdata.core.util.I18nUtil;
+import com.czsj.bigdata.entity.JobDatasource;
+import com.czsj.bigdata.entity.JobGroup;
+import com.czsj.bigdata.entity.JobInfo;
+import com.czsj.bigdata.entity.JobLog;
+import com.czsj.bigdata.tool.query.BaseQueryTool;
+import com.czsj.bigdata.tool.query.QueryToolFactory;
+import com.czsj.bigdata.util.JSONUtils;
+import com.czsj.core.biz.ExecutorBiz;
+import com.czsj.core.biz.model.ReturnT;
+import com.czsj.core.biz.model.TriggerParam;
+import com.czsj.core.enums.ExecutorBlockStrategyEnum;
+import com.czsj.core.enums.IncrementTypeEnum;
+import com.czsj.core.glue.GlueTypeEnum;
+import com.czsj.rpc.util.IpUtil;
+import com.czsj.rpc.util.ThrowableUtil;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * xxl-job trigger
+ * Created by xuxueli on 17/7/13.
+ */
+public class JobTrigger {
+ private static Logger logger = LoggerFactory.getLogger(JobTrigger.class);
+
+ /**
+ * trigger job
+ *
+ * @param jobId
+ * @param triggerType
+ * @param failRetryCount >=0: use this param
+ * <0: use param from job info config
+ * @param executorShardingParam
+ * @param executorParam null: use job param
+ * not null: cover job param
+ */
+ public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam) {
+ JobInfo jobInfo = JobAdminConfig.getAdminConfig().getJobInfoMapper().loadById(jobId);
+ if (jobInfo == null) {
+ logger.warn(">>>>>>>>>>>> trigger fail, jobId invalid,jobId={}", jobId);
+ return;
+ }
+ if (GlueTypeEnum.BEAN.getDesc().equals(jobInfo.getGlueType())) {
+ //解密账密
+ String json = JSONUtils.changeJson(jobInfo.getJobJson(), JSONUtils.decrypt);
+ jobInfo.setJobJson(json);
+ }
+ if (StringUtils.isNotBlank(executorParam)) {
+ jobInfo.setExecutorParam(executorParam);
+ }
+ int finalFailRetryCount = failRetryCount >= 0 ? failRetryCount : jobInfo.getExecutorFailRetryCount();
+ JobGroup group = JobAdminConfig.getAdminConfig().getJobGroupMapper().load(jobInfo.getJobGroup());
+
+ // sharding param
+ int[] shardingParam = null;
+ if (executorShardingParam != null) {
+ String[] shardingArr = executorShardingParam.split("/");
+ if (shardingArr.length == 2 && isNumeric(shardingArr[0]) && isNumeric(shardingArr[1])) {
+ shardingParam = new int[2];
+ shardingParam[0] = Integer.valueOf(shardingArr[0]);
+ shardingParam[1] = Integer.valueOf(shardingArr[1]);
+ }
+ }
+ if (ExecutorRouteStrategyEnum.SHARDING_BROADCAST == ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null)
+ && group.getRegistryList() != null && !group.getRegistryList().isEmpty()
+ && shardingParam == null) {
+ for (int i = 0; i < group.getRegistryList().size(); i++) {
+ processTrigger(group, jobInfo, finalFailRetryCount, triggerType, i, group.getRegistryList().size());
+ }
+ } else {
+ if (shardingParam == null) {
+ shardingParam = new int[]{0, 1};
+ }
+ processTrigger(group, jobInfo, finalFailRetryCount, triggerType, shardingParam[0], shardingParam[1]);
+ }
+
+ }
+
+ private static boolean isNumeric(String str) {
+ try {
+ int result = Integer.valueOf(str);
+ return true;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
+
+ /**
+ * @param group job group, registry list may be empty
+ * @param jobInfo
+ * @param finalFailRetryCount
+ * @param triggerType
+ * @param index sharding index
+ * @param total sharding index
+ */
+ private static void processTrigger(JobGroup group, JobInfo jobInfo, int finalFailRetryCount, TriggerTypeEnum triggerType, int index, int total) {
+
+ TriggerParam triggerParam = new TriggerParam();
+
+ // param
+ ExecutorBlockStrategyEnum blockStrategy = ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), ExecutorBlockStrategyEnum.SERIAL_EXECUTION); // block strategy
+ ExecutorRouteStrategyEnum executorRouteStrategyEnum = ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null); // route strategy
+ String shardingParam = (ExecutorRouteStrategyEnum.SHARDING_BROADCAST == executorRouteStrategyEnum) ? String.valueOf(index).concat("/").concat(String.valueOf(total)) : null;
+
+ // 1、save log-id
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(new Date());
+ calendar.set(Calendar.MILLISECOND, 0);
+ Date triggerTime = calendar.getTime();
+ JobLog jobLog = new JobLog();
+ jobLog.setJobGroup(jobInfo.getJobGroup());
+ jobLog.setJobId(jobInfo.getId());
+ jobLog.setTriggerTime(triggerTime);
+ jobLog.setJobDesc(jobInfo.getJobDesc());
+
+ JobAdminConfig.getAdminConfig().getJobLogMapper().save(jobLog);
+ logger.debug(">>>>>>>>>>> czsj-ground trigger start, jobId:{}", jobLog.getId());
+
+ // 2、init trigger-param
+ triggerParam.setJobId(jobInfo.getId());
+ triggerParam.setExecutorHandler(jobInfo.getExecutorHandler());
+ triggerParam.setExecutorParams(jobInfo.getExecutorParam());
+ triggerParam.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy());
+ triggerParam.setExecutorTimeout(jobInfo.getExecutorTimeout());
+ triggerParam.setLogId(jobLog.getId());
+ triggerParam.setLogDateTime(jobLog.getTriggerTime().getTime());
+ triggerParam.setGlueType(jobInfo.getGlueType());
+ triggerParam.setGlueSource(jobInfo.getGlueSource());
+ triggerParam.setGlueUpdatetime(jobInfo.getGlueUpdatetime().getTime());
+ triggerParam.setBroadcastIndex(index);
+ triggerParam.setBroadcastTotal(total);
+ triggerParam.setJobJson(jobInfo.getJobJson());
+
+ //increment parameter
+ Integer incrementType = jobInfo.getIncrementType();
+ if (incrementType != null) {
+ triggerParam.setIncrementType(incrementType);
+ if (IncrementTypeEnum.ID.getCode() == incrementType) {
+ long maxId = getMaxId(jobInfo);
+ jobLog.setMaxId(maxId);
+ triggerParam.setEndId(maxId);
+ if(maxId != 0){
+ triggerParam.setStartId(maxId);
+ jobInfo.setIncStartId(maxId);
+ }else{
+ triggerParam.setStartId(jobInfo.getIncStartId());
+ }
+ } else if (IncrementTypeEnum.TIME.getCode() == incrementType) {
+ triggerParam.setStartTime(jobInfo.getIncStartTime());
+ triggerParam.setTriggerTime(triggerTime);
+ triggerParam.setReplaceParamType(jobInfo.getReplaceParamType());
+ } else if (IncrementTypeEnum.PARTITION.getCode() == incrementType) {
+ triggerParam.setPartitionInfo(jobInfo.getPartitionInfo());
+ }
+ triggerParam.setReplaceParam(jobInfo.getReplaceParam());
+ }
+ //jvm parameter
+ triggerParam.setJvmParam(jobInfo.getJvmParam());
+
+ // 3、init address
+ String address = null;
+ ReturnT routeAddressResult = null;
+ if (group.getRegistryList() != null && !group.getRegistryList().isEmpty()) {
+ if (ExecutorRouteStrategyEnum.SHARDING_BROADCAST == executorRouteStrategyEnum) {
+ if (index < group.getRegistryList().size()) {
+ address = group.getRegistryList().get(index);
+ } else {
+ address = group.getRegistryList().get(0);
+ }
+ } else {
+ routeAddressResult = executorRouteStrategyEnum.getRouter().route(triggerParam, group.getRegistryList());
+ if (routeAddressResult.getCode() == ReturnT.SUCCESS_CODE) {
+ address = routeAddressResult.getContent();
+ }
+ }
+ } else {
+ routeAddressResult = new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("jobconf_trigger_address_empty"));
+ }
+
+ // 4、trigger remote executor
+ ReturnT triggerResult = null;
+ if (address != null) {
+ triggerResult = runExecutor(triggerParam, address);
+ } else {
+ triggerResult = new ReturnT(ReturnT.FAIL_CODE, null);
+ }
+
+ // 5、collection trigger info
+ StringBuilder triggerMsgSb = new StringBuilder();
+ triggerMsgSb.append(I18nUtil.getString("jobconf_trigger_type")).append(":").append(triggerType.getTitle());
+ triggerMsgSb.append("
").append(I18nUtil.getString("jobconf_trigger_admin_adress")).append(":").append(IpUtil.getIp());
+ triggerMsgSb.append("
").append(I18nUtil.getString("jobconf_trigger_exe_regtype")).append(":")
+ .append((group.getAddressType() == 0) ? I18nUtil.getString("jobgroup_field_addressType_0") : I18nUtil.getString("jobgroup_field_addressType_1"));
+ triggerMsgSb.append("
").append(I18nUtil.getString("jobconf_trigger_exe_regaddress")).append(":").append(group.getRegistryList());
+ triggerMsgSb.append("
").append(I18nUtil.getString("jobinfo_field_executorRouteStrategy")).append(":").append(executorRouteStrategyEnum.getTitle());
+ if (shardingParam != null) {
+ triggerMsgSb.append("(" + shardingParam + ")");
+ }
+ triggerMsgSb.append("
").append(I18nUtil.getString("jobinfo_field_executorBlockStrategy")).append(":").append(blockStrategy.getTitle());
+ triggerMsgSb.append("
").append(I18nUtil.getString("jobinfo_field_timeout")).append(":").append(jobInfo.getExecutorTimeout());
+ triggerMsgSb.append("
").append(I18nUtil.getString("jobinfo_field_executorFailRetryCount")).append(":").append(finalFailRetryCount);
+
+ triggerMsgSb.append("
>>>>>>>>>>>" + I18nUtil.getString("jobconf_trigger_run") + "<<<<<<<<<<<
")
+ .append((routeAddressResult != null && routeAddressResult.getMsg() != null) ? routeAddressResult.getMsg() + "
" : "").append(triggerResult.getMsg() != null ? triggerResult.getMsg() : "");
+
+ // 6、save log trigger-info
+ jobLog.setExecutorAddress(address);
+ jobLog.setExecutorHandler(jobInfo.getExecutorHandler());
+ jobLog.setExecutorParam(jobInfo.getExecutorParam());
+ jobLog.setExecutorShardingParam(shardingParam);
+ jobLog.setExecutorFailRetryCount(finalFailRetryCount);
+ jobLog.setTriggerCode(triggerResult.getCode());
+ jobLog.setTriggerMsg(triggerMsgSb.toString());
+ JobAdminConfig.getAdminConfig().getJobInfoMapper().update(jobInfo);
+ JobAdminConfig.getAdminConfig().getJobLogMapper().updateTriggerInfo(jobLog);
+
+ logger.debug(">>>>>>>>>>> czsj-ground trigger end, jobId:{}", jobLog.getId());
+ }
+
+ private static long getMaxId(JobInfo jobInfo) {
+ JobDatasource datasource = JobAdminConfig.getAdminConfig().getJobDatasourceMapper().selectById(jobInfo.getDatasourceId());
+ BaseQueryTool qTool = QueryToolFactory.getByDbType(datasource);
+ return qTool.getMaxIdVal(jobInfo.getReaderTable(), jobInfo.getPrimaryKey());
+ }
+
+ /**
+ * run executor
+ *
+ * @param triggerParam
+ * @param address
+ * @return
+ */
+ public static ReturnT runExecutor(TriggerParam triggerParam, String address) {
+ ReturnT runResult = null;
+ try {
+ ExecutorBiz executorBiz = JobScheduler.getExecutorBiz(address);
+ runResult = executorBiz.run(triggerParam);
+ } catch (Exception e) {
+ logger.error(">>>>>>>>>>> czsj-ground trigger error, please check if the executor[{}] is running.", address, e);
+ runResult = new ReturnT(ReturnT.FAIL_CODE, ThrowableUtil.toString(e));
+ }
+
+ StringBuilder runResultSB = new StringBuilder(I18nUtil.getString("jobconf_trigger_run") + ":");
+ runResultSB.append("
address:").append(address);
+ runResultSB.append("
code:").append(runResult.getCode());
+ runResultSB.append("
msg:").append(runResult.getMsg());
+
+ runResult.setMsg(runResultSB.toString());
+ return runResult;
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/trigger/TriggerTypeEnum.java b/czsj-system/src/main/java/com/czsj/bigdata/core/trigger/TriggerTypeEnum.java
new file mode 100644
index 0000000..18bbf6a
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/trigger/TriggerTypeEnum.java
@@ -0,0 +1,27 @@
+package com.czsj.bigdata.core.trigger;
+
+
+import com.czsj.bigdata.core.util.I18nUtil;
+
+/**
+ * trigger type enum
+ *
+ * @author xuxueli 2018-09-16 04:56:41
+ */
+public enum TriggerTypeEnum {
+
+ MANUAL(I18nUtil.getString("jobconf_trigger_type_manual")),
+ CRON(I18nUtil.getString("jobconf_trigger_type_cron")),
+ RETRY(I18nUtil.getString("jobconf_trigger_type_retry")),
+ PARENT(I18nUtil.getString("jobconf_trigger_type_parent")),
+ API(I18nUtil.getString("jobconf_trigger_type_api"));
+
+ private TriggerTypeEnum(String title){
+ this.title = title;
+ }
+ private String title;
+ public String getTitle() {
+ return title;
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/util/EmailUtil.java b/czsj-system/src/main/java/com/czsj/bigdata/core/util/EmailUtil.java
new file mode 100644
index 0000000..d9c518c
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/util/EmailUtil.java
@@ -0,0 +1,56 @@
+package com.czsj.bigdata.core.util;
+
+import com.sun.mail.util.MailSSLSocketFactory;
+
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import java.util.Properties;
+
+
+
+public class EmailUtil {
+
+ public static void send(String emailUserName,String emailPassword,String emailAuthorization,String SJemailUserName,String title,String msg) throws Exception{
+ Properties properties = new Properties();
+ //设置QQ邮件服务器
+ properties.setProperty("mail.host","smtp.qq.com");
+ //邮件发送协议
+ properties.setProperty("mail.transport.protocol","smtp");
+ //需要验证用户名密码
+ properties.setProperty("mail.smtp.auth","true");
+ //还要设置SSL加密,加上以下代码即可
+ MailSSLSocketFactory mailSSLSocketFactory = new MailSSLSocketFactory();
+ mailSSLSocketFactory.setTrustAllHosts(true);
+ properties.put("mail.smtp.ssl.enable","true");
+ properties.put("mail.smtp.ssl.socketFactory",mailSSLSocketFactory);
+ //使用JavaMail发送邮件的5个步骤
+ //1、创建定义整个应用程序所需环境信息的 Session 对象
+ Session session = Session.getDefaultInstance(properties, new Authenticator() {
+ @Override
+ public PasswordAuthentication getPasswordAuthentication() {
+ //发件人用户名,授权码
+ return new PasswordAuthentication(emailUserName,emailAuthorization);
+ }
+ });
+ //开启Session的debug模式,这样就可以查看程序发送Email的运行状态
+ session.setDebug(true);
+ //2、通过session得到transport对象
+ Transport transport = session.getTransport();
+ //3、使用用户名和授权码连上邮件服务器
+ transport.connect("smtp.qq.com",emailUserName,emailPassword);
+ //4、创建邮件:写邮件
+ //注意需要传递Session
+ MimeMessage message = new MimeMessage(session);
+ //指明邮件的发件人
+ message.setFrom(new InternetAddress(emailUserName));
+ //指明邮件的收件人,现在发件人和收件人是一样的,就是自己给自己发
+ message.setRecipient(Message.RecipientType.TO , new InternetAddress(SJemailUserName));
+ message.setSubject(title);
+ message.setContent(msg,"text/html;charset=UTF-8");
+ //5、发送邮件
+ transport.sendMessage(message,message.getAllRecipients());
+
+ //6、关闭连接
+ transport.close();
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/util/I18nUtil.java b/czsj-system/src/main/java/com/czsj/bigdata/core/util/I18nUtil.java
new file mode 100644
index 0000000..fd4268c
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/util/I18nUtil.java
@@ -0,0 +1,80 @@
+package com.czsj.bigdata.core.util;
+
+import com.czsj.bigdata.core.conf.JobAdminConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.EncodedResource;
+import org.springframework.core.io.support.PropertiesLoaderUtils;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * i18n util
+ *
+ * @author xuxueli 2018-01-17 20:39:06
+ */
+public class I18nUtil {
+ private static Logger logger = LoggerFactory.getLogger(I18nUtil.class);
+
+ private static Properties prop = null;
+ public static Properties loadI18nProp(){
+ if (prop != null) {
+ return prop;
+ }
+ try {
+ // build i18n prop
+ String i18n = JobAdminConfig.getAdminConfig().getI18n();
+ i18n = (i18n!=null && i18n.trim().length()>0)?("_"+i18n):i18n;
+ String i18nFile = MessageFormat.format("i18n/message{0}.properties", i18n);
+
+ // load prop
+ Resource resource = new ClassPathResource(i18nFile);
+ EncodedResource encodedResource = new EncodedResource(resource,"UTF-8");
+ prop = PropertiesLoaderUtils.loadProperties(encodedResource);
+ } catch (IOException e) {
+ logger.error(e.getMessage(), e);
+ }
+ return prop;
+ }
+
+ /**
+ * get val of i18n key
+ *
+ * @param key
+ * @return
+ */
+ public static String getString(String key) {
+ return loadI18nProp().getProperty(key);
+ }
+
+ /**
+ * get mult val of i18n mult key, as json
+ *
+ * @param keys
+ * @return
+ */
+ public static String getMultString(String... keys) {
+ Map map = new HashMap();
+
+ Properties prop = loadI18nProp();
+ if (keys!=null && keys.length>0) {
+ for (String key: keys) {
+ map.put(key, prop.getProperty(key));
+ }
+ } else {
+ for (String key: prop.stringPropertyNames()) {
+ map.put(key, prop.getProperty(key));
+ }
+ }
+
+ String json = JacksonUtil.writeValueAsString(map);
+ return json;
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/util/JacksonUtil.java b/czsj-system/src/main/java/com/czsj/bigdata/core/util/JacksonUtil.java
new file mode 100644
index 0000000..ab02e53
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/util/JacksonUtil.java
@@ -0,0 +1,92 @@
+package com.czsj.bigdata.core.util;
+
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+/**
+ * Jackson util
+ *
+ * 1、obj need private and set/get;
+ * 2、do not support inner class;
+ *
+ * @author xuxueli 2015-9-25 18:02:56
+ */
+public class JacksonUtil {
+ private static Logger logger = LoggerFactory.getLogger(JacksonUtil.class);
+
+ private final static ObjectMapper objectMapper = new ObjectMapper();
+ public static ObjectMapper getInstance() {
+ return objectMapper;
+ }
+
+ /**
+ * bean、array、List、Map --> json
+ *
+ * @param obj
+ * @return json string
+ * @throws Exception
+ */
+ public static String writeValueAsString(Object obj) {
+ try {
+ return getInstance().writeValueAsString(obj);
+ } catch (JsonGenerationException e) {
+ logger.error(e.getMessage(), e);
+ } catch (JsonMappingException e) {
+ logger.error(e.getMessage(), e);
+ } catch (IOException e) {
+ logger.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * string --> bean、Map、List(array)
+ *
+ * @param jsonStr
+ * @param clazz
+ * @return obj
+ * @throws Exception
+ */
+ public static T readValue(String jsonStr, Class clazz) {
+ try {
+ return getInstance().readValue(jsonStr, clazz);
+ } catch (JsonParseException e) {
+ logger.error(e.getMessage(), e);
+ } catch (JsonMappingException e) {
+ logger.error(e.getMessage(), e);
+ } catch (IOException e) {
+ logger.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * string --> List...
+ *
+ * @param jsonStr
+ * @param parametrized
+ * @param parameterClasses
+ * @param
+ * @return
+ */
+ public static T readValue(String jsonStr, Class> parametrized, Class>... parameterClasses) {
+ try {
+ JavaType javaType = getInstance().getTypeFactory().constructParametricType(parametrized, parameterClasses);
+ return getInstance().readValue(jsonStr, javaType);
+ } catch (JsonParseException e) {
+ logger.error(e.getMessage(), e);
+ } catch (JsonMappingException e) {
+ logger.error(e.getMessage(), e);
+ } catch (IOException e) {
+ logger.error(e.getMessage(), e);
+ }
+ return null;
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/core/util/LocalCacheUtil.java b/czsj-system/src/main/java/com/czsj/bigdata/core/util/LocalCacheUtil.java
new file mode 100644
index 0000000..8711a9f
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/core/util/LocalCacheUtil.java
@@ -0,0 +1,133 @@
+package com.czsj.bigdata.core.util;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * local cache tool
+ *
+ * @author xuxueli 2018-01-22 21:37:34
+ */
+public class LocalCacheUtil {
+
+ private static ConcurrentMap cacheRepository = new ConcurrentHashMap(); // 类型建议用抽象父类,兼容性更好;
+ private static class LocalCacheData{
+ private String key;
+ private Object val;
+ private long timeoutTime;
+
+ public LocalCacheData() {
+ }
+
+ public LocalCacheData(String key, Object val, long timeoutTime) {
+ this.key = key;
+ this.val = val;
+ this.timeoutTime = timeoutTime;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public Object getVal() {
+ return val;
+ }
+
+ public void setVal(Object val) {
+ this.val = val;
+ }
+
+ public long getTimeoutTime() {
+ return timeoutTime;
+ }
+
+ public void setTimeoutTime(long timeoutTime) {
+ this.timeoutTime = timeoutTime;
+ }
+ }
+
+
+ /**
+ * set cache
+ *
+ * @param key
+ * @param val
+ * @param cacheTime
+ * @return
+ */
+ public static boolean set(String key, Object val, long cacheTime){
+
+ // clean timeout cache, before set new cache (avoid cache too much)
+ cleanTimeoutCache();
+
+ // set new cache
+ if (key==null || key.trim().length()==0) {
+ return false;
+ }
+ if (val == null) {
+ remove(key);
+ }
+ if (cacheTime <= 0) {
+ remove(key);
+ }
+ long timeoutTime = System.currentTimeMillis() + cacheTime;
+ LocalCacheData localCacheData = new LocalCacheData(key, val, timeoutTime);
+ cacheRepository.put(localCacheData.getKey(), localCacheData);
+ return true;
+ }
+
+ /**
+ * remove cache
+ *
+ * @param key
+ * @return
+ */
+ public static boolean remove(String key){
+ if (key==null || key.trim().length()==0) {
+ return false;
+ }
+ cacheRepository.remove(key);
+ return true;
+ }
+
+ /**
+ * get cache
+ *
+ * @param key
+ * @return
+ */
+ public static Object get(String key){
+ if (key==null || key.trim().length()==0) {
+ return null;
+ }
+ LocalCacheData localCacheData = cacheRepository.get(key);
+ if (localCacheData!=null && System.currentTimeMillis()=localCacheData.getTimeoutTime()) {
+ cacheRepository.remove(key);
+ }
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/ClickhouseReaderDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/ClickhouseReaderDto.java
new file mode 100644
index 0000000..4da257e
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/ClickhouseReaderDto.java
@@ -0,0 +1,16 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ *
+ * @author gavin
+ * @ClassName clickhouse reader dto
+ * @Version 2.0
+ * @since 2022/9/29
+ */
+@Data
+public class ClickhouseReaderDto implements Serializable {
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/ClickhouseWriterDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/ClickhouseWriterDto.java
new file mode 100644
index 0000000..90e2265
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/ClickhouseWriterDto.java
@@ -0,0 +1,16 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ *
+ * @author gavin
+ * @ClassName clickhouse write dto
+ * @Version 2.0
+ * @since 2022/9/29
+ */
+@Data
+public class ClickhouseWriterDto implements Serializable {
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/DataXBatchJsonBuildDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/DataXBatchJsonBuildDto.java
new file mode 100644
index 0000000..7aaaf50
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/DataXBatchJsonBuildDto.java
@@ -0,0 +1,32 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 构建json dto
+ *
+ * @author jingwk
+ * @ClassName DataXJsonDto
+ * @Version 2.1.2
+ * @since 2022/05/05 17:15
+ */
+@Data
+public class DataXBatchJsonBuildDto implements Serializable {
+
+ private Long readerDatasourceId;
+
+ private List readerTables;
+
+ private Long writerDatasourceId;
+
+ private List writerTables;
+
+ private int templateId;
+
+ private RdbmsReaderDto rdbmsReader;
+
+ private RdbmsWriterDto rdbmsWriter;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/DataXJsonBuildDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/DataXJsonBuildDto.java
new file mode 100644
index 0000000..731156e
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/DataXJsonBuildDto.java
@@ -0,0 +1,46 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 构建json dto
+ *
+ * @author jingwk
+ * @ClassName DataxJsonDto
+ * @Version 2.1.1
+ * @since 2022/03/14 07:15
+ */
+@Data
+public class DataXJsonBuildDto implements Serializable {
+
+ private Long readerDatasourceId;
+
+ private List readerTables;
+
+ private List readerColumns;
+
+ private Long writerDatasourceId;
+
+ private List writerTables;
+
+ private List writerColumns;
+
+ private HiveReaderDto hiveReader;
+
+ private HiveWriterDto hiveWriter;
+
+ private HbaseReaderDto hbaseReader;
+
+ private HbaseWriterDto hbaseWriter;
+
+ private RdbmsReaderDto rdbmsReader;
+
+ private RdbmsWriterDto rdbmsWriter;
+
+ private MongoDBReaderDto mongoDBReader;
+
+ private MongoDBWriterDto mongoDBWriter;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/FlinkSqlDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/FlinkSqlDto.java
new file mode 100644
index 0000000..cca07b4
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/FlinkSqlDto.java
@@ -0,0 +1,21 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ *
+ * @author fei
+ * @date 2022-01-27
+ *
+ **/
+@Data
+public class FlinkSqlDto implements Serializable{
+ private static final long serialVersionUID = 1L;
+
+ @NotBlank(message = "SQL 字符串必传!")
+ private String sqlStr;
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/FlinkXBatchJsonBuildDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/FlinkXBatchJsonBuildDto.java
new file mode 100644
index 0000000..1c3e68d
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/FlinkXBatchJsonBuildDto.java
@@ -0,0 +1,32 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 构建json dto
+ *
+ * @author jingwk
+ * @ClassName FlinkXJsonDto
+ * @Version 2.1.2
+ * @since 2022/05/05 17:15
+ */
+@Data
+public class FlinkXBatchJsonBuildDto implements Serializable {
+
+ private Long readerDatasourceId;
+
+ private List readerTables;
+
+ private Long writerDatasourceId;
+
+ private List writerTables;
+
+ private int templateId;
+
+ private RdbmsReaderDto rdbmsReader;
+
+ private RdbmsWriterDto rdbmsWriter;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/HbaseReaderDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/HbaseReaderDto.java
new file mode 100644
index 0000000..566f3a3
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/HbaseReaderDto.java
@@ -0,0 +1,17 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class HbaseReaderDto implements Serializable {
+
+ private String readerMaxVersion;
+
+ private String readerMode;
+
+ private Range readerRange;
+
+}
+
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/HbaseWriterDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/HbaseWriterDto.java
new file mode 100644
index 0000000..f4b9ac4
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/HbaseWriterDto.java
@@ -0,0 +1,17 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class HbaseWriterDto implements Serializable {
+
+ private String writeNullMode;
+
+ private String writerMode;
+
+ private String writerRowkeyColumn;
+
+ private VersionColumn writerVersionColumn;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/HiveReaderDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/HiveReaderDto.java
new file mode 100644
index 0000000..5548198
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/HiveReaderDto.java
@@ -0,0 +1,28 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 构建hive reader dto
+ *
+ * @author jingwk
+ * @ClassName hive reader
+ * @Version 2.0
+ * @since 2022/01/11 17:15
+ */
+@Data
+public class HiveReaderDto implements Serializable {
+
+ private String readerPath;
+
+ private String readerDefaultFS;
+
+ private String readerFileType;
+
+ private String readerFieldDelimiter;
+
+ private Boolean readerSkipHeader;
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/HiveWriterDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/HiveWriterDto.java
new file mode 100644
index 0000000..19d422a
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/HiveWriterDto.java
@@ -0,0 +1,29 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 构建hive write dto
+ *
+ * @author jingwk
+ * @ClassName hive write dto
+ * @Version 2.0
+ * @since 2022/01/11 17:15
+ */
+@Data
+public class HiveWriterDto implements Serializable {
+
+ private String writerDefaultFS;
+
+ private String writerFileType;
+
+ private String writerPath;
+
+ private String writerFileName;
+
+ private String writeMode;
+
+ private String writeFieldDelimiter;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/JsonBuildDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/JsonBuildDto.java
new file mode 100644
index 0000000..9bbdb1a
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/JsonBuildDto.java
@@ -0,0 +1,52 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 构建json dto
+ *
+ * @author jingwk
+ * @ClassName FlinkxJsonDto
+ * @Version 2.1.1
+ * @since 2022/03/14 07:15
+ */
+@Data
+public class JsonBuildDto implements Serializable {
+
+ private Long readerDatasourceId;
+
+ private List readerTables;
+
+ private List readerColumns;
+
+ private Long writerDatasourceId;
+
+ private List writerTables;
+
+ private List writerColumns;
+
+ private HiveReaderDto hiveReader;
+
+ private HiveWriterDto hiveWriter;
+
+ private HbaseReaderDto hbaseReader;
+
+ private HbaseWriterDto hbaseWriter;
+
+ private RdbmsReaderDto rdbmsReader;
+
+ private RdbmsWriterDto rdbmsWriter;
+
+ private MongoDBReaderDto mongoDBReader;
+
+ private MongoDBWriterDto mongoDBWriter;
+
+ private ClickhouseReaderDto clickhouseReader;
+
+ private ClickhouseWriterDto clickhouseWriter;
+
+ private String type;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/MongoDBReaderDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/MongoDBReaderDto.java
new file mode 100644
index 0000000..b62b063
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/MongoDBReaderDto.java
@@ -0,0 +1,19 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 构建mongodb reader dto
+ *
+ * @author jingwk
+ * @ClassName mongodb reader
+ * @Version 2.1.1
+ * @since 2022/03/14 07:15
+ */
+@Data
+public class MongoDBReaderDto implements Serializable {
+
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/MongoDBWriterDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/MongoDBWriterDto.java
new file mode 100644
index 0000000..23b5b29
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/MongoDBWriterDto.java
@@ -0,0 +1,20 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 构建mongodb write dto
+ *
+ * @author jingwk
+ * @ClassName mongodb write dto
+ * @Version 2.1.1
+ * @since 2022/03/14 07:15
+ */
+@Data
+public class MongoDBWriterDto implements Serializable {
+
+ private UpsertInfo upsertInfo;
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/Range.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/Range.java
new file mode 100644
index 0000000..d3ed9cd
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/Range.java
@@ -0,0 +1,15 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class Range implements Serializable {
+
+ private String startRowkey;
+
+ private String endRowkey;
+
+ private Boolean isBinaryRowkey;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/RdbmsReaderDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/RdbmsReaderDto.java
new file mode 100644
index 0000000..8fa96ca
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/RdbmsReaderDto.java
@@ -0,0 +1,23 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 构建json dto
+ *
+ * @author jingwk
+ * @ClassName RdbmsReaderDto
+ * @Version 2.0
+ * @since 2022/01/11 17:15
+ */
+@Data
+public class RdbmsReaderDto implements Serializable {
+
+ private String readerSplitPk;
+
+ private String whereParams;
+
+ private String querySql;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/RdbmsWriterDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/RdbmsWriterDto.java
new file mode 100644
index 0000000..54d7537
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/RdbmsWriterDto.java
@@ -0,0 +1,21 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 构建json dto
+ *
+ * @author jingwk
+ * @ClassName RdbmsWriteDto
+ * @Version 2.0
+ * @since 2022/01/11 17:15
+ */
+@Data
+public class RdbmsWriterDto implements Serializable {
+
+ private String preSql;
+
+ private String postSql;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/TaskScheduleDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/TaskScheduleDto.java
new file mode 100644
index 0000000..18b6db8
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/TaskScheduleDto.java
@@ -0,0 +1,86 @@
+package com.czsj.bigdata.dto;
+
+public class TaskScheduleDto {
+
+
+ /**
+ * 所选作业类型:
+ * 1 -> 每天
+ * 2 -> 每月
+ * 3 -> 每周
+ */
+ Integer jobType;
+
+ /**
+ * 一周的哪几天
+ */
+ Integer[] dayOfWeeks;
+
+ /**
+ * 一个月的哪几天
+ */
+ Integer[] dayOfMonths;
+
+ /**
+ * 秒
+ */
+ Integer second;
+
+ /**
+ * 分
+ */
+ Integer minute;
+
+ /**
+ * 时
+ */
+ Integer hour;
+
+ public Integer getJobType() {
+ return jobType;
+ }
+
+ public void setJobType(Integer jobType) {
+ this.jobType = jobType;
+ }
+
+ public Integer[] getDayOfWeeks() {
+ return dayOfWeeks;
+ }
+
+ public void setDayOfWeeks(Integer[] dayOfWeeks) {
+ this.dayOfWeeks = dayOfWeeks;
+ }
+
+ public Integer[] getDayOfMonths() {
+ return dayOfMonths;
+ }
+
+ public void setDayOfMonths(Integer[] dayOfMonths) {
+ this.dayOfMonths = dayOfMonths;
+ }
+
+ public Integer getSecond() {
+ return second;
+ }
+
+ public void setSecond(Integer second) {
+ this.second = second;
+ }
+
+ public Integer getMinute() {
+ return minute;
+ }
+
+ public void setMinute(Integer minute) {
+ this.minute = minute;
+ }
+
+ public Integer getHour() {
+ return hour;
+ }
+
+ public void setHour(Integer hour) {
+ this.hour = hour;
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/TriggerJobDto.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/TriggerJobDto.java
new file mode 100644
index 0000000..a0474e2
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/TriggerJobDto.java
@@ -0,0 +1,21 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 用于启动任务接收的实体
+ *
+ * @author jingwk
+ * @ClassName TriggerJobDto
+ * @Version 1.0
+ * @since 2019/12/01 16:12
+ */
+@Data
+public class TriggerJobDto implements Serializable {
+
+ private String executorParam;
+
+ private int jobId;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/UpsertInfo.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/UpsertInfo.java
new file mode 100644
index 0000000..146c916
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/UpsertInfo.java
@@ -0,0 +1,18 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+/**
+ * Created by mac on 2022/3/16.
+ */
+@Data
+public class UpsertInfo {
+ /**
+ * 当设置为true时,表示针对相同的upsertKey做更新操作
+ */
+ private Boolean isUpsert;
+ /**
+ * upsertKey指定了没行记录的业务主键。用来做更新时使用。
+ */
+ private String upsertKey;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/dto/VersionColumn.java b/czsj-system/src/main/java/com/czsj/bigdata/dto/VersionColumn.java
new file mode 100644
index 0000000..3a160a5
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/dto/VersionColumn.java
@@ -0,0 +1,11 @@
+package com.czsj.bigdata.dto;
+
+import lombok.Data;
+
+@Data
+public class VersionColumn {
+
+ private Integer index;
+
+ private String value;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/APIAuth.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/APIAuth.java
new file mode 100644
index 0000000..fd47e3a
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/APIAuth.java
@@ -0,0 +1,24 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ *
+ */
+@Data
+public class APIAuth {
+
+ @ApiModelProperty("属性Id")
+ private int id;
+
+ @ApiModelProperty("请求token的ID")
+ private String token_id;
+
+ @ApiModelProperty("请求分组的ID")
+ private String group_id;
+
+ @ApiModelProperty("更新时间")
+ private String update_time;
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/APIAuthConfig.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/APIAuthConfig.java
new file mode 100644
index 0000000..136e267
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/APIAuthConfig.java
@@ -0,0 +1,20 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ *
+ */
+@Data
+public class APIAuthConfig {
+
+ @ApiModelProperty("属性Id")
+ private int id;
+
+ @ApiModelProperty("权限的id")
+ private String auth_id;
+
+ @ApiModelProperty("配置的id")
+ private String config_id;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/APIConfig.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/APIConfig.java
new file mode 100644
index 0000000..c62ce22
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/APIConfig.java
@@ -0,0 +1,41 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ *
+ */
+@Data
+public class APIConfig {
+
+ @ApiModelProperty("属性Id")
+ private int id;
+
+ @ApiModelProperty("请求路径")
+ private String path;
+
+ @ApiModelProperty("名称")
+ private String name;
+
+ @ApiModelProperty("API分组")
+ private String group_id;
+
+ @ApiModelProperty("描述")
+ private String describe;
+
+ @ApiModelProperty("数据源ID")
+ private Long datasource_id;
+
+ @ApiModelProperty("请求参数")
+ private String params;
+
+ @ApiModelProperty("创建时间")
+ private String create_time;
+
+ @ApiModelProperty("更新时间")
+ private String update_time;
+
+ @ApiModelProperty("执行的SQL语句")
+ private String sql_text;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/APIGroup.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/APIGroup.java
new file mode 100644
index 0000000..784f5a6
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/APIGroup.java
@@ -0,0 +1,17 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ *
+ */
+@Data
+public class APIGroup {
+
+ @ApiModelProperty("属性Id")
+ private int id;
+
+ @ApiModelProperty("分组名称")
+ private String name;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/APISQL.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/APISQL.java
new file mode 100644
index 0000000..8e570ec
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/APISQL.java
@@ -0,0 +1,20 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ *
+ */
+@Data
+public class APISQL {
+
+ @ApiModelProperty("属性Id")
+ private int id;
+
+ @ApiModelProperty("api的Id")
+ private String api_id;
+
+ @ApiModelProperty("api的执行SQL")
+ private String sql_text;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/APIToken.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/APIToken.java
new file mode 100644
index 0000000..fd6d9dd
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/APIToken.java
@@ -0,0 +1,27 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ *
+ */
+@Data
+public class APIToken {
+
+ @ApiModelProperty("属性Id")
+ private int id;
+
+ @ApiModelProperty("请求Token")
+ private String token;
+
+ @ApiModelProperty("描述")
+ private String describe;
+
+ @ApiModelProperty("过期时间")
+ private String expire;
+
+ @ApiModelProperty("创建时间")
+ private String create_time;
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/BaseForm.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/BaseForm.java
new file mode 100644
index 0000000..30b0740
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/BaseForm.java
@@ -0,0 +1,252 @@
+package com.czsj.bigdata.entity;
+
+import cn.hutool.core.util.BooleanUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.czsj.bigdata.util.PageUtils;
+import com.czsj.bigdata.util.ServletUtils;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.URLDecoder;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ *
+ * @Author: czsj
+ * @Date: 2022/9/16 11:14
+ * @Description: 基础参数辅助类
+ **/
+@Slf4j
+public class BaseForm {
+ /**
+ * 查询参数对象
+ */
+ protected Map values = new LinkedHashMap<>();
+
+ /**
+ * 当前页码
+ */
+ private Long current = 1L;
+
+ /**
+ * 页大小
+ */
+ private Long size = 10L;
+
+ /**
+ * 构造方法
+ */
+ public BaseForm() {
+ try {
+ HttpServletRequest request = ServletUtils.getRequest();
+ Enumeration params = request.getParameterNames();
+ while (params.hasMoreElements()) {
+ String name = params.nextElement();
+ String value = StrUtil.trim(request.getParameter(name));
+ this.set(name, URLDecoder.decode(value, "UTF-8"));
+ }
+ this.parsePagingQueryParams();
+ } catch (Exception e) {
+ e.printStackTrace();
+ log.error("BaseControlForm initialize parameters setting error:" + e);
+ }
+ }
+
+ /**
+ * 获取页码
+ *
+ * @return
+ */
+ public Long getPageNo() {
+ String pageNum = StrUtil.toString(this.get("current"));
+ if (!StrUtil.isEmpty(pageNum) && NumberUtil.isNumber(pageNum)) {
+ this.current = Long.parseLong(pageNum);
+ }
+ return this.current;
+ }
+
+ /**
+ * 获取页大小
+ *
+ * @return
+ */
+ public Long getPageSize() {
+ String pageSize = StrUtil.toString(this.get("size"));
+
+ if (StrUtil.isNotEmpty(pageSize) && NumberUtil.isNumber(pageSize) && !"null".equalsIgnoreCase(pageSize)) {
+ this.size = Long.parseLong(pageSize);
+ }
+ return this.size;
+ }
+
+ /**
+ * 获得参数信息对象
+ *
+ * @return
+ */
+ public Map getParameters() {
+ return values;
+ }
+
+ /**
+ * 根据key获取values中的值
+ *
+ * @param name
+ * @return
+ */
+ public Object get(String name) {
+ if (values == null) {
+ values = new LinkedHashMap<>();
+ return null;
+ }
+ return this.values.get(name);
+ }
+
+ /**
+ * 根据key获取values中String类型值
+ *
+ * @param key
+ * @return String
+ */
+ public String getString(String key) {
+ return StrUtil.toString(get(key));
+ }
+
+ /**
+ * 获取排序字段
+ *
+ * @return
+ */
+ public String getSort() {
+ return StrUtil.toString(this.values.get("sort"));
+ }
+
+ /**
+ * 获取排序
+ *
+ * @return
+ */
+ public String getOrder() {
+ return StrUtil.toString(this.values.get("order"));
+ }
+
+ /**
+ * 获取排序
+ *
+ * @return
+ */
+ public String getOrderby() {
+ return StrUtil.toString(this.values.get("orderby"));
+ }
+
+ /**
+ * 解析出mybatis plus分页查询参数
+ */
+ public Page getPlusPagingQueryEntity() {
+ Page page = new Page();
+ //如果无current,默认返回1000条数据
+ page.setCurrent(this.getPageNo());
+ page.setSize(this.getPageSize());
+ if (ObjectUtil.isNotNull(this.get("ifCount"))) {
+ page.setSearchCount(BooleanUtil.toBoolean(this.getString("ifCount")));
+ } else {
+ //默认给true
+ page.setSearchCount(true);
+ }
+ return page;
+ }
+
+ /**
+ * 解析分页排序参数(pageHelper)
+ */
+ public void parsePagingQueryParams() {
+ // 排序字段解析
+ String orderBy = StrUtil.toString(this.get("orderby")).trim();
+ String sortName = StrUtil.toString(this.get("sort")).trim();
+ String sortOrder = StrUtil.toString(this.get("order")).trim().toLowerCase();
+
+ if (StrUtil.isEmpty(orderBy) && !StrUtil.isEmpty(sortName)) {
+ if (!sortOrder.equals("asc") && !sortOrder.equals("desc")) {
+ sortOrder = "asc";
+ }
+ this.set("orderby", sortName + " " + sortOrder);
+ }
+ }
+
+
+ /**
+ * 设置参数
+ *
+ * @param name 参数名称
+ * @param value 参数值
+ */
+ public void set(String name, Object value) {
+ if (ObjectUtil.isNotNull(value)) {
+ this.values.put(name, value);
+ }
+ }
+
+ /**
+ * 移除参数
+ *
+ * @param name
+ */
+ public void remove(String name) {
+ this.values.remove(name);
+ }
+
+ /**
+ * 清除所有参数
+ */
+ public void clear() {
+ if (values != null) {
+ values.clear();
+ }
+ }
+
+
+ /**
+ * 自定义查询组装
+ *
+ * @param map
+ * @return
+ */
+ public QueryWrapper> pageQueryWrapperCustom(Map map, QueryWrapper> queryWrapper) {
+ // mybatis plus 分页相关的参数
+ Map pageParams = PageUtils.filterPageParams(map);
+ //过滤空值,分页查询相关的参数
+ Map colQueryMap = PageUtils.filterColumnQueryParams(map);
+ //排序 操作
+ pageParams.forEach((k, v) -> {
+ switch (k) {
+ case "ascs":
+ queryWrapper.orderByAsc(StrUtil.toUnderlineCase(StrUtil.toString(v)));
+ break;
+ case "descs":
+ queryWrapper.orderByDesc(StrUtil.toUnderlineCase(StrUtil.toString(v)));
+ break;
+ }
+ });
+
+ //遍历进行字段查询条件组装
+ colQueryMap.forEach((k, v) -> {
+ switch (k) {
+ case "pluginName":
+ case "datasourceName":
+ queryWrapper.like(StrUtil.toUnderlineCase(k), v);
+ break;
+ default:
+ queryWrapper.eq(StrUtil.toUnderlineCase(k), v);
+ }
+ });
+
+ return queryWrapper;
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/BaseResource.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/BaseResource.java
new file mode 100644
index 0000000..1eda8e4
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/BaseResource.java
@@ -0,0 +1,37 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ *
+ */
+@Data
+public class BaseResource {
+
+ @ApiModelProperty("属性Id")
+ private int id;
+
+ @ApiModelProperty("资源名称")
+ private String name;
+
+ @ApiModelProperty("资源地址")
+ private String resource_address;
+
+ @ApiModelProperty("更新时间")
+ private String update_time;
+
+ @ApiModelProperty("服务器IP")
+ private String serverIp;
+
+ @ApiModelProperty("服务器用户名")
+ private String serverUser;
+
+ @ApiModelProperty("服务器密码")
+ private String serverPassword;
+
+ @ApiModelProperty("资源类型")
+ private String type;
+
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/ColumnClass.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/ColumnClass.java
new file mode 100644
index 0000000..0770b13
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/ColumnClass.java
@@ -0,0 +1,14 @@
+package com.czsj.bigdata.entity;
+
+/**
+ *
+ *
+ * @Date: 2022/4/4 9:09
+ * @Description:
+ **/
+public class ColumnClass {
+ private String columnType;
+ private String columnName;
+ private String tableName;
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/Common.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/Common.java
new file mode 100644
index 0000000..69bbd9a
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/Common.java
@@ -0,0 +1,14 @@
+package com.czsj.bigdata.entity;
+
+/**
+ *
+ * @Author: czsj
+ * @Date: 2022/10/7 11:21
+ * @Description: 常量描述类
+ **/
+public class Common {
+ public static final String DOCPAGE = "/doc.html";
+ public static String PORT ="8080";
+ public static String SERVERPORT ="server.port";
+ public static String SERVERCONTEXTPATH ="server.contextPath";
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/DeployTask.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/DeployTask.java
new file mode 100644
index 0000000..de2e8ff
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/DeployTask.java
@@ -0,0 +1,32 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ *
+ */
+@Data
+public class DeployTask {
+
+ @ApiModelProperty("作业ID")
+ private String jid;
+
+ @ApiModelProperty("作业名称")
+ private String name;
+
+ @ApiModelProperty("开始时间")
+ private String begintime;
+
+ @ApiModelProperty("持续时间")
+ private String duration;
+
+ @ApiModelProperty("结束时间")
+ private String endtime;
+
+ @ApiModelProperty("任务数")
+ private String tasknumber;
+
+ @ApiModelProperty("状态")
+ private String status;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/DevEnvSetting.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/DevEnvSetting.java
new file mode 100644
index 0000000..2eb3c24
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/DevEnvSetting.java
@@ -0,0 +1,55 @@
+package com.czsj.bigdata.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ *
+ */
+@Data
+public class DevEnvSetting {
+
+ @ApiModelProperty("属性Id")
+ private int id;
+
+ @ApiModelProperty("属性名称")
+ private String name;
+
+ @ApiModelProperty("属性值")
+ private String propValue;
+
+ @ApiModelProperty("属性描述")
+ private String description;
+
+ @ApiModelProperty("用户Id")
+ private Long userId;
+
+ @ApiModelProperty("标记")
+ private Boolean flag;
+
+ @ApiModelProperty("上传的URL")
+ private Boolean uploadurl;
+
+ @ApiModelProperty("部署的URL")
+ private Boolean deployurl;
+
+ @ApiModelProperty("展示的URL")
+ private Boolean showurl;
+
+ @ApiModelProperty("下线的URL")
+ private Boolean offlineurl;
+
+ @ApiModelProperty("创建时间")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTime;
+
+ @ApiModelProperty("更新时间")
+ private Date updateTime;
+
+ @TableField(exist=false)
+ private String userName;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/DevTask.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/DevTask.java
new file mode 100644
index 0000000..8322e27
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/DevTask.java
@@ -0,0 +1,44 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ *
+ */
+@Data
+public class DevTask {
+
+ @ApiModelProperty("属性Id")
+ private int id;
+
+ @ApiModelProperty("任务名称")
+ private String name;
+
+ @ApiModelProperty("任务类型")
+ private String tasktype;
+
+ @ApiModelProperty("运行类型")
+ private String runtype;
+
+ @ApiModelProperty("运行参数")
+ private String run_param;
+
+ @ApiModelProperty("JAR包路径")
+ private String jarpath;
+
+ @ApiModelProperty("任务的SQL")
+ private String sql_text;
+
+ @ApiModelProperty("任务描述")
+ private String task_describe;
+
+ @ApiModelProperty("创建时间")
+ private String create_time;
+
+ @ApiModelProperty("更新时间")
+ private String update_time;
+
+ @ApiModelProperty("类型")
+ private String type;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/InfoReport.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/InfoReport.java
new file mode 100644
index 0000000..1fd971a
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/InfoReport.java
@@ -0,0 +1,9 @@
+package com.czsj.bigdata.entity;
+
+import lombok.Data;
+
+@Data
+public class InfoReport {
+ private int resultCount;
+ private String countType;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobDatasource.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobDatasource.java
new file mode 100644
index 0000000..b586b9f
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobDatasource.java
@@ -0,0 +1,149 @@
+package com.czsj.bigdata.entity;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.czsj.bigdata.core.handler.AESEncryptHandler;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * jdbc数据源配置实体类(job_jdbc_datasource)
+ *
+ * @author zhouhongfa@gz-yibo.com
+ * @version v1.0
+ * @since 2019-07-30
+ */
+
+@Data
+@ApiModel
+@TableName("job_jdbc_datasource")
+public class JobDatasource extends Model {
+
+ /**
+ * 自增主键
+ */
+ @TableId
+ @ApiModelProperty(value = "自增主键")
+ private Long id;
+
+ /**
+ * 数据源名称
+ */
+ @ApiModelProperty(value = "数据源名称")
+ private String datasourceName;
+
+ /**
+ * 数据源
+ */
+ @ApiModelProperty(value = "数据源")
+ private String datasource;
+
+ /**
+ * 数据源分组
+ */
+ @ApiModelProperty(value = "数据源分组")
+ private String datasourceGroup;
+
+ /**
+ * 用户名
+ * AESEncryptHandler 加密类
+ * MyBatis Plus 3.0.7.1之前版本没有typeHandler属性,需要升级到最低3.1.2
+ */
+ @ApiModelProperty(value = "用户名")
+ @TableField(typeHandler = AESEncryptHandler.class)
+ private String jdbcUsername;
+
+ /**
+ * 密码
+ */
+ @TableField(typeHandler = AESEncryptHandler.class)
+ @ApiModelProperty(value = "密码")
+ private String jdbcPassword;
+
+ /**
+ * jdbc url
+ */
+ @ApiModelProperty(value = "jdbc url")
+ private String jdbcUrl;
+
+ /**
+ * jdbc驱动类
+ */
+ @ApiModelProperty(value = "jdbc驱动类")
+ private String jdbcDriverClass;
+
+ /**
+ * 状态:0删除 1启用 2禁用
+ */
+ @TableLogic
+ @ApiModelProperty(value = "状态:0删除 1启用 2禁用")
+ private Integer status;
+
+ /**
+ * 创建人
+ */
+ @TableField(fill = FieldFill.INSERT)
+ @ApiModelProperty(value = "创建人", hidden = true)
+ private String createBy;
+
+ /**
+ * 创建时间
+ */
+ @TableField(fill = FieldFill.INSERT)
+ @JSONField(format = "yyyy/MM/dd")
+ @ApiModelProperty(value = "创建时间", hidden = true)
+ private Date createDate;
+
+ /**
+ * 更新人
+ */
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ @ApiModelProperty(value = "更新人", hidden = true)
+ private String updateBy;
+
+ /**
+ * 更新时间
+ */
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ @JSONField(format = "yyyy/MM/dd")
+ @ApiModelProperty(value = "更新时间", hidden = true)
+ private Date updateDate;
+
+ /**
+ * 备注
+ */
+ @ApiModelProperty(value = "备注", hidden = true)
+ private String comments;
+
+ /**
+ * zookeeper地址
+ */
+ @ApiModelProperty(value = "zookeeper地址", hidden = true)
+ private String zkAdress;
+
+ /**
+ * 数据库名
+ */
+ @ApiModelProperty(value = "数据库名", hidden = true)
+ private String databaseName;
+
+ /**
+ * 数据库名
+ */
+ @ApiModelProperty(value = "orc库名", hidden = true)
+ private String orcschema;
+ /**
+ * 获取主键值
+ *
+ * @return 主键值
+ */
+ @Override
+ protected Serializable pkVal() {
+ return this.id;
+ }
+}
\ No newline at end of file
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobGroup.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobGroup.java
new file mode 100644
index 0000000..454355a
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobGroup.java
@@ -0,0 +1,84 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by jingwk on 2019/11/17
+ */
+public class JobGroup {
+
+ @ApiModelProperty("执行器Id")
+ private int id;
+ @ApiModelProperty("执行器AppName")
+ private String appName;
+ @ApiModelProperty("执行器名称")
+ private String title;
+ @ApiModelProperty("排序")
+ private int order;
+ @ApiModelProperty("执行器地址类型:0=自动注册、1=手动录入")
+ private int addressType;
+ @ApiModelProperty("执行器地址列表,多地址逗号分隔(手动录入)")
+ private String addressList;
+
+ // registry list
+ private List registryList; // 执行器地址列表(系统注册)
+ public List getRegistryList() {
+ if (addressList!=null && addressList.trim().length()>0) {
+ registryList = new ArrayList<>(Arrays.asList(addressList.split(",")));
+ }
+ return registryList;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getAppName() {
+ return appName;
+ }
+
+ public void setAppName(String appName) {
+ this.appName = appName;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int order) {
+ this.order = order;
+ }
+
+ public int getAddressType() {
+ return addressType;
+ }
+
+ public void setAddressType(int addressType) {
+ this.addressType = addressType;
+ }
+
+ public String getAddressList() {
+ return addressList;
+ }
+
+ public void setAddressList(String addressList) {
+ this.addressList = addressList;
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobInfo.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobInfo.java
new file mode 100644
index 0000000..3613402
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobInfo.java
@@ -0,0 +1,125 @@
+package com.czsj.bigdata.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * xxl-job info
+ *
+ * @author jingwk 2019-11-17 14:25:49
+ */
+@Data
+public class JobInfo {
+
+ @ApiModelProperty("主键ID")
+ private int id;
+
+ @ApiModelProperty("执行器主键ID")
+ private int jobGroup;
+
+ @ApiModelProperty("任务执行CRON表达式")
+ private String jobCron;
+
+ @ApiModelProperty("排序")
+ private String jobDesc;
+
+ private Date addTime;
+
+ private Date updateTime;
+
+ @ApiModelProperty("修改用户")
+ private Long userId;
+
+ @ApiModelProperty("报警邮件")
+ private String alarmEmail;
+
+ @ApiModelProperty("执行器路由策略")
+ private String executorRouteStrategy;
+
+ @ApiModelProperty("执行器,任务Handler名称")
+ private String executorHandler;
+
+ @ApiModelProperty("执行器,任务参数")
+ private String executorParam;
+
+ @ApiModelProperty("阻塞处理策略")
+ private String executorBlockStrategy;
+
+ @ApiModelProperty("任务执行超时时间,单位秒")
+ private int executorTimeout;
+
+ @ApiModelProperty("失败重试次数")
+ private int executorFailRetryCount;
+
+ @ApiModelProperty("GLUE类型\t#com.wugui.datatx.core.glue.GlueTypeEnum")
+ private String glueType;
+
+ @ApiModelProperty("GLUE源代码")
+ private String glueSource;
+
+ @ApiModelProperty("GLUE备注")
+ private String glueRemark;
+
+ @ApiModelProperty("GLUE更新时间")
+ private Date glueUpdatetime;
+
+ @ApiModelProperty("子任务ID")
+ private String childJobId;
+
+ @ApiModelProperty("调度状态:0-停止,1-运行")
+ private int triggerStatus;
+
+ @ApiModelProperty("上次调度时间")
+ private long triggerLastTime;
+
+ @ApiModelProperty("下次调度时间")
+ private long triggerNextTime;
+
+ @ApiModelProperty("datax运行json")
+ private String jobJson;
+
+ @ApiModelProperty("脚本动态参数")
+ private String replaceParam;
+
+ @ApiModelProperty("增量日期格式")
+ private String replaceParamType;
+
+ @ApiModelProperty("jvm参数")
+ private String jvmParam;
+
+ @ApiModelProperty("增量初始时间")
+ private Date incStartTime;
+
+ @ApiModelProperty("分区信息")
+ private String partitionInfo;
+
+ @ApiModelProperty("最近一次执行状态")
+ private int lastHandleCode;
+
+ @ApiModelProperty("所属项目Id")
+ private int projectId;
+
+ @ApiModelProperty("主键字段")
+ private String primaryKey;
+
+ @ApiModelProperty("增量初始id")
+ private Long incStartId;
+
+ @ApiModelProperty("增量方式")
+ private int incrementType;
+
+ @ApiModelProperty("datax的读表")
+ private String readerTable;
+
+ @ApiModelProperty("数据源id")
+ private int datasourceId;
+
+ @TableField(exist=false)
+ private String projectName;
+
+ @TableField(exist=false)
+ private String userName;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobLog.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobLog.java
new file mode 100644
index 0000000..d7cef1d
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobLog.java
@@ -0,0 +1,66 @@
+package com.czsj.bigdata.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * czsj-ground log, used to track trigger process
+ *
+ * @author jingwk 2019-11-17 22:08:11
+ */
+@Data
+public class JobLog {
+
+ private long id;
+
+ // job info
+ @ApiModelProperty("执行器主键ID")
+ private int jobGroup;
+ @ApiModelProperty("任务,主键ID")
+ private int jobId;
+ @ApiModelProperty("任务描述")
+ private String jobDesc;
+
+ // execute info
+ @ApiModelProperty("执行器地址,本次执行的地址")
+ private String executorAddress;
+ @ApiModelProperty("执行器任务handler")
+ private String executorHandler;
+ @ApiModelProperty("执行器任务参数")
+ private String executorParam;
+ @ApiModelProperty("执行器任务分片参数,格式如 1/2")
+ private String executorShardingParam;
+ @ApiModelProperty("失败重试次数")
+ private int executorFailRetryCount;
+
+ // trigger info
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ @ApiModelProperty("调度-时间")
+ private Date triggerTime;
+ @ApiModelProperty("调度-结果")
+ private int triggerCode;
+ @ApiModelProperty("调度-日志")
+ private String triggerMsg;
+
+ // handle info
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ @ApiModelProperty("执行-时间")
+ private Date handleTime;
+ @ApiModelProperty("执行-状态")
+ private int handleCode;
+ @ApiModelProperty("执行-日志")
+ private String handleMsg;
+
+ // alarm info
+ @ApiModelProperty("告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败")
+ private int alarmStatus;
+
+ @ApiModelProperty("DataX进程Id")
+ private String processId;
+
+ @ApiModelProperty("增量最大id")
+ private Long maxId;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobLogGlue.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobLogGlue.java
new file mode 100644
index 0000000..24f94b8
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobLogGlue.java
@@ -0,0 +1,34 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * xxl-job log for glue, used to track job code process
+ *
+ * @author xuxueli 2016-5-19 17:57:46
+ */
+@Data
+public class JobLogGlue {
+
+ private int id;
+
+ @ApiModelProperty("任务主键ID")
+ private int jobId;
+
+ @ApiModelProperty("GLUE类型\t#com.xxl.job.core.glue.GlueTypeEnum")
+ private String glueType;
+
+ @ApiModelProperty("GLUE源代码")
+ private String glueSource;
+
+ @ApiModelProperty("GLUE备注")
+ private String glueRemark;
+
+ private Date addTime;
+
+ private Date updateTime;
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobLogReport.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobLogReport.java
new file mode 100644
index 0000000..ca44167
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobLogReport.java
@@ -0,0 +1,17 @@
+package com.czsj.bigdata.entity;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class JobLogReport {
+
+ private int id;
+
+ private Date triggerDay;
+
+ private int runningCount;
+ private int sucCount;
+ private int failCount;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobPermission.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobPermission.java
new file mode 100644
index 0000000..965af4b
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobPermission.java
@@ -0,0 +1,57 @@
+package com.czsj.bigdata.entity;
+
+public class JobPermission {
+
+ private int id;
+ //权限名称
+ private String name;
+
+ //权限描述
+ private String descritpion;
+
+ //授权链接
+ private String url;
+
+ //父节点id
+ private int pid;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescritpion() {
+ return descritpion;
+ }
+
+ public void setDescritpion(String descritpion) {
+ this.descritpion = descritpion;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public int getPid() {
+ return pid;
+ }
+
+ public void setPid(int pid) {
+ this.pid = pid;
+ }
+}
\ No newline at end of file
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobProject.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobProject.java
new file mode 100644
index 0000000..88ab912
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobProject.java
@@ -0,0 +1,41 @@
+package com.czsj.bigdata.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Created by jingwk on 2022/05/24
+ */
+@Data
+public class JobProject {
+
+ @ApiModelProperty("项目Id")
+ private int id;
+
+ @ApiModelProperty("项目名称")
+ private String name;
+
+ @ApiModelProperty("项目描述")
+ private String description;
+
+ @ApiModelProperty("用户Id")
+ private Long userId;
+
+ @ApiModelProperty("标记")
+ private Boolean flag;
+
+ @ApiModelProperty("创建时间")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTime;
+
+ @ApiModelProperty("更新时间")
+ private Date updateTime;
+
+ @TableField(exist=false)
+ private String userName;
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobRegistry.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobRegistry.java
new file mode 100644
index 0000000..62f9c73
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobRegistry.java
@@ -0,0 +1,23 @@
+package com.czsj.bigdata.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Created by xuxueli on 16/9/30.
+ */
+@Data
+public class JobRegistry {
+
+ private int id;
+ private String registryGroup;
+ private String registryKey;
+ private String registryValue;
+ private double cpuUsage;
+ private double memoryUsage;
+ private double loadAverage;
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTime;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobRole.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobRole.java
new file mode 100644
index 0000000..cbde977
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobRole.java
@@ -0,0 +1,30 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author xuxueli 2019-05-04 16:43:12
+ */
+public class JobRole {
+
+ private int id;
+ @ApiModelProperty("账号")
+ private String name;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobTemplate.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobTemplate.java
new file mode 100644
index 0000000..eab5d25
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobTemplate.java
@@ -0,0 +1,92 @@
+package com.czsj.bigdata.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * xxl-job info
+ *
+ * @author jingwk 2019-11-17 14:25:49
+ */
+@Data
+public class JobTemplate {
+
+ @ApiModelProperty("主键ID")
+ private int id;
+
+ @ApiModelProperty("执行器主键ID")
+ private int jobGroup;
+
+ @ApiModelProperty("任务执行CRON表达式")
+ private String jobCron;
+
+ @ApiModelProperty("排序")
+ private String jobDesc;
+
+ private Date addTime;
+
+ private Date updateTime;
+
+ @ApiModelProperty("修改用户")
+ private Long userId;
+
+ @ApiModelProperty("报警邮件")
+ private String alarmEmail;
+
+ @ApiModelProperty("执行器路由策略")
+ private String executorRouteStrategy;
+
+ @ApiModelProperty("执行器,任务Handler名称")
+ private String executorHandler;
+
+ @ApiModelProperty("执行器,任务参数")
+ private String executorParam;
+
+ @ApiModelProperty("阻塞处理策略")
+ private String executorBlockStrategy;
+
+ @ApiModelProperty("任务执行超时时间,单位秒")
+ private int executorTimeout;
+
+ @ApiModelProperty("失败重试次数")
+ private int executorFailRetryCount;
+
+ @ApiModelProperty("GLUE类型\t#com.wugui.datatx.core.glue.GlueTypeEnum")
+ private String glueType;
+
+ @ApiModelProperty("GLUE源代码")
+ private String glueSource;
+
+ @ApiModelProperty("GLUE备注")
+ private String glueRemark;
+
+ @ApiModelProperty("GLUE更新时间")
+ private Date glueUpdatetime;
+
+ @ApiModelProperty("子任务ID")
+ private String childJobId;
+
+ @ApiModelProperty("上次调度时间")
+ private long triggerLastTime;
+
+ @ApiModelProperty("下次调度时间")
+ private long triggerNextTime;
+
+ @ApiModelProperty("datax运行json")
+ private String jobJson;
+
+ @ApiModelProperty("jvm参数")
+ private String jvmParam;
+
+ @ApiModelProperty("所属项目")
+ private int projectId;
+
+ @TableField(exist=false)
+ private String projectName;
+
+ @TableField(exist=false)
+ private String userName;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JobUser.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobUser.java
new file mode 100644
index 0000000..4d25317
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JobUser.java
@@ -0,0 +1,78 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.springframework.util.StringUtils;
+
+/**
+ * @author xuxueli 2019-05-04 16:43:12
+ */
+public class JobUser {
+
+ private int id;
+ @ApiModelProperty("账号")
+ private String username;
+ @ApiModelProperty("密码")
+ private String password;
+ @ApiModelProperty("角色:0-普通用户、1-管理员")
+ private String role;
+ @ApiModelProperty("权限:执行器ID列表,多个逗号分割")
+ private String permission;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ public String getPermission() {
+ return permission;
+ }
+
+ public void setPermission(String permission) {
+ this.permission = permission;
+ }
+
+ // plugin
+ public boolean validPermission(int jobGroup){
+ if ("1".equals(this.role)) {
+ return true;
+ } else {
+ if (StringUtils.hasText(this.permission)) {
+ for (String permissionItem : this.permission.split(",")) {
+ if (String.valueOf(jobGroup).equals(permissionItem)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/JwtUser.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/JwtUser.java
new file mode 100644
index 0000000..0e8a6b3
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/JwtUser.java
@@ -0,0 +1,84 @@
+package com.czsj.bigdata.entity;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Created by jingwk on 2019/11/17
+ */
+public class JwtUser implements UserDetails {
+
+ private Integer id;
+ private String username;
+ private String password;
+ private Collection extends GrantedAuthority> authorities;
+
+ public JwtUser() {
+ }
+
+ // 写一个能直接使用user创建jwtUser的构造器
+ public JwtUser(JobUser user) {
+ id = user.getId();
+ username = user.getUsername();
+ password = user.getPassword();
+ authorities = Collections.singleton(new SimpleGrantedAuthority(user.getRole()));
+ }
+
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ return authorities;
+ }
+
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public String getUsername() {
+ return username;
+ }
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return "JwtUser{" +
+ "id=" + id +
+ ", username='" + username + '\'' +
+ ", password='" + password + '\'' +
+ ", authorities=" + authorities +
+ '}';
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/LoginUser.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/LoginUser.java
new file mode 100644
index 0000000..7f375ef
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/LoginUser.java
@@ -0,0 +1,15 @@
+package com.czsj.bigdata.entity;
+
+import lombok.Data;
+
+/**
+ * Created by jingwk on 2019/11/17
+ */
+@Data
+public class LoginUser {
+
+ private String username;
+ private String password;
+ private Integer rememberMe;
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/OperLog.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/OperLog.java
new file mode 100644
index 0000000..980e6bb
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/OperLog.java
@@ -0,0 +1,18 @@
+package com.czsj.bigdata.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class OperLog {
+ private long id;
+
+ @ApiModelProperty("操作")
+ private String operate;
+ @ApiModelProperty("用户名")
+ private String user;
+ @ApiModelProperty("地址")
+ private String address;
+ @ApiModelProperty("创建时间")
+ private String createtime;
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/ResponseData.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/ResponseData.java
new file mode 100644
index 0000000..7435cab
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/ResponseData.java
@@ -0,0 +1,73 @@
+package com.czsj.bigdata.entity;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+
+/**
+ *
+ *
+ * @Date: 2022/2/1 12:34
+ * @Description:
+ **/
+public class ResponseData {
+ String msg;
+ boolean success;
+
+ @JSONField(serialzeFeatures = {SerializerFeature.WriteMapNullValue})
+ Object data;
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public void setData(Object data) {
+ this.data = data;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static ResponseData apiSuccess(Object data) {
+ ResponseData dto = new ResponseData();
+ dto.setData(data);
+ dto.setSuccess(true);
+ // dto.setMsg("Api access succeeded");
+ return dto;
+
+ }
+
+ public static ResponseData successWithMsg(String msg) {
+ ResponseData dto = new ResponseData();
+ dto.setData(null);
+ dto.setSuccess(true);
+ dto.setMsg(msg);
+ return dto;
+ }
+
+ public static ResponseData successWithData(Object data) {
+ ResponseData dto = new ResponseData();
+ dto.setData(data);
+ dto.setSuccess(true);
+ return dto;
+ }
+
+ public static ResponseData fail(String msg) {
+ ResponseData dto = new ResponseData();
+ dto.setSuccess(false);
+ dto.setMsg(msg);
+ return dto;
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/SysJob.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/SysJob.java
new file mode 100644
index 0000000..c0b7444
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/SysJob.java
@@ -0,0 +1,172 @@
+package com.czsj.bigdata.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.czsj.bigdata.util.CronUtils;
+import com.czsj.common.annotation.Excel;
+import com.czsj.common.annotation.Excel.ColumnType;
+import com.czsj.common.constant.ScheduleConstants;
+import com.czsj.common.core.domain.BaseEntity;
+import com.czsj.common.utils.StringUtils;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+import java.util.Date;
+
+/**
+ * 定时任务调度表 sys_job
+ *
+ * @author czsj
+ */
+public class SysJob extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 任务ID */
+ @Excel(name = "任务序号", cellType = ColumnType.NUMERIC)
+ private Long jobId;
+
+ /** 任务名称 */
+ @Excel(name = "任务名称")
+ private String jobName;
+
+ /** 任务组名 */
+ @Excel(name = "任务组名")
+ private String jobGroup;
+
+ /** 调用目标字符串 */
+ @Excel(name = "调用目标字符串")
+ private String invokeTarget;
+
+ /** cron执行表达式 */
+ @Excel(name = "执行表达式 ")
+ private String cronExpression;
+
+ /** cron计划策略 */
+ @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行")
+ private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT;
+
+ /** 是否并发执行(0允许 1禁止) */
+ @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止")
+ private String concurrent;
+
+ /** 任务状态(0正常 1暂停) */
+ @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停")
+ private String status;
+
+ public Long getJobId()
+ {
+ return jobId;
+ }
+
+ public void setJobId(Long jobId)
+ {
+ this.jobId = jobId;
+ }
+
+ @NotBlank(message = "任务名称不能为空")
+ @Size(min = 0, max = 64, message = "任务名称不能超过64个字符")
+ public String getJobName()
+ {
+ return jobName;
+ }
+
+ public void setJobName(String jobName)
+ {
+ this.jobName = jobName;
+ }
+
+ public String getJobGroup()
+ {
+ return jobGroup;
+ }
+
+ public void setJobGroup(String jobGroup)
+ {
+ this.jobGroup = jobGroup;
+ }
+
+ @NotBlank(message = "调用目标字符串不能为空")
+ @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符")
+ public String getInvokeTarget()
+ {
+ return invokeTarget;
+ }
+
+ public void setInvokeTarget(String invokeTarget)
+ {
+ this.invokeTarget = invokeTarget;
+ }
+
+ @NotBlank(message = "Cron执行表达式不能为空")
+ @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符")
+ public String getCronExpression()
+ {
+ return cronExpression;
+ }
+
+ public void setCronExpression(String cronExpression)
+ {
+ this.cronExpression = cronExpression;
+ }
+
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ public Date getNextValidTime()
+ {
+ if (StringUtils.isNotEmpty(cronExpression))
+ {
+ return CronUtils.getNextExecution(cronExpression);
+ }
+ return null;
+ }
+
+ public String getMisfirePolicy()
+ {
+ return misfirePolicy;
+ }
+
+ public void setMisfirePolicy(String misfirePolicy)
+ {
+ this.misfirePolicy = misfirePolicy;
+ }
+
+ public String getConcurrent()
+ {
+ return concurrent;
+ }
+
+ public void setConcurrent(String concurrent)
+ {
+ this.concurrent = concurrent;
+ }
+
+ public String getStatus()
+ {
+ return status;
+ }
+
+ public void setStatus(String status)
+ {
+ this.status = status;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("jobId", getJobId())
+ .append("jobName", getJobName())
+ .append("jobGroup", getJobGroup())
+ .append("cronExpression", getCronExpression())
+ .append("nextValidTime", getNextValidTime())
+ .append("misfirePolicy", getMisfirePolicy())
+ .append("concurrent", getConcurrent())
+ .append("status", getStatus())
+ .append("createBy", getCreateBy())
+ .append("createTime", getCreateTime())
+ .append("updateBy", getUpdateBy())
+ .append("updateTime", getUpdateTime())
+ .append("remark", getRemark())
+ .toString();
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/SysJobLog.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/SysJobLog.java
new file mode 100644
index 0000000..65ff280
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/SysJobLog.java
@@ -0,0 +1,156 @@
+package com.czsj.bigdata.entity;
+
+import com.czsj.common.annotation.Excel;
+import com.czsj.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.util.Date;
+
+/**
+ * 定时任务调度日志表 sys_job_log
+ *
+ * @author czsj
+ */
+public class SysJobLog extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** ID */
+ @Excel(name = "日志序号")
+ private Long jobLogId;
+
+ /** 任务名称 */
+ @Excel(name = "任务名称")
+ private String jobName;
+
+ /** 任务组名 */
+ @Excel(name = "任务组名")
+ private String jobGroup;
+
+ /** 调用目标字符串 */
+ @Excel(name = "调用目标字符串")
+ private String invokeTarget;
+
+ /** 日志信息 */
+ @Excel(name = "日志信息")
+ private String jobMessage;
+
+ /** 执行状态(0正常 1失败) */
+ @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败")
+ private String status;
+
+ /** 异常信息 */
+ @Excel(name = "异常信息")
+ private String exceptionInfo;
+
+ /** 开始时间 */
+ private Date startTime;
+
+ /** 停止时间 */
+ private Date stopTime;
+
+ public Long getJobLogId()
+ {
+ return jobLogId;
+ }
+
+ public void setJobLogId(Long jobLogId)
+ {
+ this.jobLogId = jobLogId;
+ }
+
+ public String getJobName()
+ {
+ return jobName;
+ }
+
+ public void setJobName(String jobName)
+ {
+ this.jobName = jobName;
+ }
+
+ public String getJobGroup()
+ {
+ return jobGroup;
+ }
+
+ public void setJobGroup(String jobGroup)
+ {
+ this.jobGroup = jobGroup;
+ }
+
+ public String getInvokeTarget()
+ {
+ return invokeTarget;
+ }
+
+ public void setInvokeTarget(String invokeTarget)
+ {
+ this.invokeTarget = invokeTarget;
+ }
+
+ public String getJobMessage()
+ {
+ return jobMessage;
+ }
+
+ public void setJobMessage(String jobMessage)
+ {
+ this.jobMessage = jobMessage;
+ }
+
+ public String getStatus()
+ {
+ return status;
+ }
+
+ public void setStatus(String status)
+ {
+ this.status = status;
+ }
+
+ public String getExceptionInfo()
+ {
+ return exceptionInfo;
+ }
+
+ public void setExceptionInfo(String exceptionInfo)
+ {
+ this.exceptionInfo = exceptionInfo;
+ }
+
+ public Date getStartTime()
+ {
+ return startTime;
+ }
+
+ public void setStartTime(Date startTime)
+ {
+ this.startTime = startTime;
+ }
+
+ public Date getStopTime()
+ {
+ return stopTime;
+ }
+
+ public void setStopTime(Date stopTime)
+ {
+ this.stopTime = stopTime;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("jobLogId", getJobLogId())
+ .append("jobName", getJobName())
+ .append("jobGroup", getJobGroup())
+ .append("jobMessage", getJobMessage())
+ .append("status", getStatus())
+ .append("exceptionInfo", getExceptionInfo())
+ .append("startTime", getStartTime())
+ .append("stopTime", getStopTime())
+ .toString();
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/SysServers.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/SysServers.java
new file mode 100644
index 0000000..f8faa49
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/SysServers.java
@@ -0,0 +1,264 @@
+package com.czsj.bigdata.entity;
+
+import java.math.BigDecimal;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.czsj.common.annotation.Excel;
+import com.czsj.common.core.domain.BaseEntity;
+
+/**
+ * 执行器管理对象 sys_servers
+ *
+ * @author czsj
+ * @date 2022-04-28
+ */
+public class SysServers extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** $column.columnComment */
+ private Long id;
+
+ /** 分组名 */
+ @Excel(name = "分组名")
+ private String groupname;
+
+ /** 分组编码 */
+ @Excel(name = "分组编码")
+ private String groupcode;
+
+ /** 服务器地址 */
+ @Excel(name = "服务器地址")
+ private String serveraddress;
+
+ /** 系统名 */
+ @Excel(name = "系统名")
+ private String osname;
+
+ /** 程序启动时间 */
+ @Excel(name = "程序启动时间")
+ private String starttime;
+
+ /** pid */
+ @Excel(name = "pid")
+ private String pid;
+
+ /** cpu核心数 */
+ @Excel(name = "cpu核心数")
+ private Long cpucores;
+
+ /** cpu使用率 */
+ @Excel(name = "cpu使用率")
+ private BigDecimal cpuutilization;
+
+ /** cpu空闲率 */
+ @Excel(name = "cpu空闲率")
+ private BigDecimal cpurate;
+
+ /** JVM初始内存 */
+ @Excel(name = "JVM初始内存")
+ private BigDecimal jvminitialmemory;
+
+ /** JVM最大内存 */
+ @Excel(name = "JVM最大内存")
+ private BigDecimal jvmmaxmemory;
+
+ /** JVM已用内存 */
+ @Excel(name = "JVM已用内存")
+ private BigDecimal jvmusedmemory;
+
+ /** 总物理内存 */
+ @Excel(name = "总物理内存")
+ private BigDecimal physicalmemory;
+
+ /** 剩余物理内存 */
+ @Excel(name = "剩余物理内存")
+ private BigDecimal surplusmemory;
+
+ /** 已用物理内存 */
+ @Excel(name = "已用物理内存")
+ private BigDecimal usedmemory;
+
+ /** 磁盘状态 */
+ @Excel(name = "磁盘状态")
+ private String diskstatus;
+
+ public void setId(Long id)
+ {
+ this.id = id;
+ }
+
+ public Long getId()
+ {
+ return id;
+ }
+ public void setGroupname(String groupname)
+ {
+ this.groupname = groupname;
+ }
+
+ public String getGroupname()
+ {
+ return groupname;
+ }
+ public void setGroupcode(String groupcode)
+ {
+ this.groupcode = groupcode;
+ }
+
+ public String getGroupcode()
+ {
+ return groupcode;
+ }
+ public void setServeraddress(String serveraddress)
+ {
+ this.serveraddress = serveraddress;
+ }
+
+ public String getServeraddress()
+ {
+ return serveraddress;
+ }
+ public void setOsname(String osname)
+ {
+ this.osname = osname;
+ }
+
+ public String getOsname()
+ {
+ return osname;
+ }
+ public void setStarttime(String starttime)
+ {
+ this.starttime = starttime;
+ }
+
+ public String getStarttime()
+ {
+ return starttime;
+ }
+ public void setPid(String pid)
+ {
+ this.pid = pid;
+ }
+
+ public String getPid()
+ {
+ return pid;
+ }
+ public void setCpucores(Long cpucores)
+ {
+ this.cpucores = cpucores;
+ }
+
+ public Long getCpucores()
+ {
+ return cpucores;
+ }
+ public void setCpuutilization(BigDecimal cpuutilization)
+ {
+ this.cpuutilization = cpuutilization;
+ }
+
+ public BigDecimal getCpuutilization()
+ {
+ return cpuutilization;
+ }
+ public void setCpurate(BigDecimal cpurate)
+ {
+ this.cpurate = cpurate;
+ }
+
+ public BigDecimal getCpurate()
+ {
+ return cpurate;
+ }
+ public void setJvminitialmemory(BigDecimal jvminitialmemory)
+ {
+ this.jvminitialmemory = jvminitialmemory;
+ }
+
+ public BigDecimal getJvminitialmemory()
+ {
+ return jvminitialmemory;
+ }
+ public void setJvmmaxmemory(BigDecimal jvmmaxmemory)
+ {
+ this.jvmmaxmemory = jvmmaxmemory;
+ }
+
+ public BigDecimal getJvmmaxmemory()
+ {
+ return jvmmaxmemory;
+ }
+ public void setJvmusedmemory(BigDecimal jvmusedmemory)
+ {
+ this.jvmusedmemory = jvmusedmemory;
+ }
+
+ public BigDecimal getJvmusedmemory()
+ {
+ return jvmusedmemory;
+ }
+ public void setPhysicalmemory(BigDecimal physicalmemory)
+ {
+ this.physicalmemory = physicalmemory;
+ }
+
+ public BigDecimal getPhysicalmemory()
+ {
+ return physicalmemory;
+ }
+ public void setSurplusmemory(BigDecimal surplusmemory)
+ {
+ this.surplusmemory = surplusmemory;
+ }
+
+ public BigDecimal getSurplusmemory()
+ {
+ return surplusmemory;
+ }
+ public void setUsedmemory(BigDecimal usedmemory)
+ {
+ this.usedmemory = usedmemory;
+ }
+
+ public BigDecimal getUsedmemory()
+ {
+ return usedmemory;
+ }
+ public void setDiskstatus(String diskstatus)
+ {
+ this.diskstatus = diskstatus;
+ }
+
+ public String getDiskstatus()
+ {
+ return diskstatus;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("id", getId())
+ .append("groupname", getGroupname())
+ .append("groupcode", getGroupcode())
+ .append("serveraddress", getServeraddress())
+ .append("osname", getOsname())
+ .append("starttime", getStarttime())
+ .append("pid", getPid())
+ .append("cpucores", getCpucores())
+ .append("cpuutilization", getCpuutilization())
+ .append("cpurate", getCpurate())
+ .append("jvminitialmemory", getJvminitialmemory())
+ .append("jvmmaxmemory", getJvmmaxmemory())
+ .append("jvmusedmemory", getJvmusedmemory())
+ .append("physicalmemory", getPhysicalmemory())
+ .append("surplusmemory", getSurplusmemory())
+ .append("usedmemory", getUsedmemory())
+ .append("diskstatus", getDiskstatus())
+ .append("createTime", getCreateTime())
+ .append("createBy", getCreateBy())
+ .toString();
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/entity/SystemMonitor.java b/czsj-system/src/main/java/com/czsj/bigdata/entity/SystemMonitor.java
new file mode 100644
index 0000000..4cf7457
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/entity/SystemMonitor.java
@@ -0,0 +1,47 @@
+package com.czsj.bigdata.entity;
+
+import lombok.Data;
+
+@Data
+public class SystemMonitor {
+
+ //系统名称
+ private String osName;
+
+ //程序启动时间
+ private String startTime;
+
+ //pid
+ private String pid;
+
+ //cpu核数
+ private Integer cpuCores;
+
+ //cpu使用率
+ private Double cpuUtilization;
+
+ //cpu空闲率
+ private Double cpuRate;
+
+ //JVM初始内存
+ private Double jvmInitialMemory;
+
+ //JVM最大内存
+ private Double jvmMaxMemory;
+
+ //JVM已用内存
+ private Double jvmUsedMemory;
+
+ //总物理内存
+ private Double physicalMemory;
+
+ //剩余物理内存
+ private Double surplusMemory;
+
+ //以用物理内存
+ private Double usedMemory;
+
+ //磁盘状态
+ private String diskStatus;
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/exception/TokenIsExpiredException.java b/czsj-system/src/main/java/com/czsj/bigdata/exception/TokenIsExpiredException.java
new file mode 100644
index 0000000..3dd1120
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/exception/TokenIsExpiredException.java
@@ -0,0 +1,27 @@
+package com.czsj.bigdata.exception;
+
+/**
+ * @description: 自定义异常
+ * @author: jingwk
+ * @date: 2019/11/17 17:21
+ */
+public class TokenIsExpiredException extends Exception{
+ public TokenIsExpiredException() {
+ }
+
+ public TokenIsExpiredException(String message) {
+ super(message);
+ }
+
+ public TokenIsExpiredException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public TokenIsExpiredException(Throwable cause) {
+ super(cause);
+ }
+
+ public TokenIsExpiredException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/filter/JWTAuthenticationFilter.java b/czsj-system/src/main/java/com/czsj/bigdata/filter/JWTAuthenticationFilter.java
new file mode 100644
index 0000000..a023a3c
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/filter/JWTAuthenticationFilter.java
@@ -0,0 +1,92 @@
+package com.czsj.bigdata.filter;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.czsj.bigdata.core.util.I18nUtil;
+import com.czsj.bigdata.entity.JwtUser;
+import com.czsj.bigdata.entity.LoginUser;
+import com.czsj.bigdata.util.JwtTokenUtils;
+import com.czsj.core.biz.model.ReturnT;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.czsj.core.util.Constants.SPLIT_COMMA;
+
+/**
+ * Created by jingwk on 2019/11/17
+ */
+@Slf4j
+public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
+
+ private ThreadLocal rememberMe = new ThreadLocal<>();
+ private AuthenticationManager authenticationManager;
+
+ public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
+ this.authenticationManager = authenticationManager;
+ super.setFilterProcessesUrl("/api/auth/login");
+ }
+
+ @Override
+ public Authentication attemptAuthentication(HttpServletRequest request,
+ HttpServletResponse response) throws AuthenticationException {
+
+ // 从输入流中获取到登录的信息
+ try {
+ LoginUser loginUser = new ObjectMapper().readValue(request.getInputStream(), LoginUser.class);
+ rememberMe.set(loginUser.getRememberMe());
+ return authenticationManager.authenticate(
+ new UsernamePasswordAuthenticationToken(loginUser.getUsername(), loginUser.getPassword(), new ArrayList<>())
+ );
+ } catch (IOException e) {
+ logger.error("attemptAuthentication error :{}",e);
+ return null;
+ }
+ }
+
+ // 成功验证后调用的方法
+ // 如果验证成功,就生成token并返回
+ @Override
+ protected void successfulAuthentication(HttpServletRequest request,
+ HttpServletResponse response,
+ FilterChain chain,
+ Authentication authResult) throws IOException {
+
+ JwtUser jwtUser = (JwtUser) authResult.getPrincipal();
+ boolean isRemember = rememberMe.get() == 1;
+
+ String role = "";
+ Collection extends GrantedAuthority> authorities = jwtUser.getAuthorities();
+ for (GrantedAuthority authority : authorities){
+ role = authority.getAuthority();
+ }
+
+ String token = JwtTokenUtils.createToken(jwtUser.getId(),jwtUser.getUsername(), role, isRemember);
+ response.setHeader("token", JwtTokenUtils.TOKEN_PREFIX + token);
+ response.setCharacterEncoding("UTF-8");
+ Map maps = new HashMap<>();
+ maps.put("data", JwtTokenUtils.TOKEN_PREFIX + token);
+ maps.put("roles", role.split(SPLIT_COMMA));
+ response.getWriter().write(JSON.toJSONString(new ReturnT<>(maps)));
+ }
+
+ @Override
+ protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
+ response.setCharacterEncoding("UTF-8");
+ response.getWriter().write(JSON.toJSON(new ReturnT<>(ReturnT.FAIL_CODE, I18nUtil.getString("login_param_invalid"))).toString());
+ }
+}
\ No newline at end of file
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/filter/JWTAuthorizationFilter.java b/czsj-system/src/main/java/com/czsj/bigdata/filter/JWTAuthorizationFilter.java
new file mode 100644
index 0000000..d89a896
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/filter/JWTAuthorizationFilter.java
@@ -0,0 +1,73 @@
+package com.czsj.bigdata.filter;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.extension.api.R;
+import com.czsj.bigdata.exception.TokenIsExpiredException;
+import com.czsj.bigdata.util.JwtTokenUtils;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Collections;
+
+/**
+ * Created by jingwk on 2019/11/17
+ */
+public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
+
+ public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {
+ super(authenticationManager);
+ }
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request,
+ HttpServletResponse response,
+ FilterChain chain) throws IOException, ServletException {
+
+ String tokenHeader = request.getHeader(JwtTokenUtils.TOKEN_HEADER);
+ // 如果请求头中没有Authorization信息则直接放行
+ if (tokenHeader == null || !tokenHeader.startsWith(JwtTokenUtils.TOKEN_PREFIX)) {
+ chain.doFilter(request, response);
+ return;
+ }
+ // 如果请求头中有token,则进行解析,并且设置认证信息
+ try {
+ SecurityContextHolder.getContext().setAuthentication(getAuthentication(tokenHeader));
+ } catch (TokenIsExpiredException e) {
+ //返回json形式的错误信息
+ response.setCharacterEncoding("UTF-8");
+ response.setContentType("application/json; charset=utf-8");
+ response.getWriter().write(JSON.toJSONString(R.failed(e.getMessage())));
+ response.getWriter().flush();
+ return;
+ }
+ super.doFilterInternal(request, response, chain);
+ }
+
+ // 这里从token中获取用户信息并新建一个token
+ private UsernamePasswordAuthenticationToken getAuthentication(String tokenHeader) throws TokenIsExpiredException {
+ String token = tokenHeader.replace(JwtTokenUtils.TOKEN_PREFIX, "");
+ boolean expiration = JwtTokenUtils.isExpiration(token);
+ if (expiration) {
+ throw new TokenIsExpiredException("登录时间过长,请退出重新登录");
+ }
+ else {
+ String username = JwtTokenUtils.getUsername(token);
+ String role = JwtTokenUtils.getUserRole(token);
+ if (username != null) {
+ return new UsernamePasswordAuthenticationToken(username, null,
+ Collections.singleton(new SimpleGrantedAuthority(role))
+ );
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/APIAuthMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/APIAuthMapper.java
new file mode 100644
index 0000000..6e6c184
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/APIAuthMapper.java
@@ -0,0 +1,24 @@
+package com.czsj.bigdata.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.czsj.bigdata.entity.APIAuth;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface APIAuthMapper extends BaseMapper{
+
+ int delete(@Param("id") int id);
+
+ List findAll();
+
+ int save(APIAuth apiAuth);
+
+ int update(APIAuth entity);
+
+ APIAuth getById(int id);
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/BaseResourceMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/BaseResourceMapper.java
new file mode 100644
index 0000000..817af5b
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/BaseResourceMapper.java
@@ -0,0 +1,30 @@
+package com.czsj.bigdata.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.czsj.bigdata.entity.BaseResource;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface BaseResourceMapper extends BaseMapper{
+
+ int delete(@Param("id") int id);
+
+ List findList(@Param("offset") int offset,
+ @Param("pagesize") int pagesize,
+ @Param("name") String name);
+
+ int save(BaseResource apiAuth);
+
+ int update(BaseResource entity);
+
+ BaseResource getById(int id);
+
+ List getResource();
+
+
+ List getFileResource();
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevEnvSettingMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevEnvSettingMapper.java
new file mode 100644
index 0000000..9697974
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevEnvSettingMapper.java
@@ -0,0 +1,13 @@
+package com.czsj.bigdata.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.czsj.bigdata.entity.DevEnvSetting;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+@Mapper
+public interface DevEnvSettingMapper extends BaseMapper{
+ IPage getDevEnvSettingListPaging(IPage page,
+ @Param("searchName") String searchName);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevJarMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevJarMapper.java
new file mode 100644
index 0000000..d36b904
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevJarMapper.java
@@ -0,0 +1,17 @@
+package com.czsj.bigdata.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.czsj.bigdata.entity.DevTask;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface DevJarMapper extends BaseMapper{
+
+
+ int save(DevTask devJar);
+
+ int update(DevTask entity);
+
+ DevTask getById(int id);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevSQLMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevSQLMapper.java
new file mode 100644
index 0000000..8c268b1
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevSQLMapper.java
@@ -0,0 +1,17 @@
+package com.czsj.bigdata.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.czsj.bigdata.entity.DevTask;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface DevSQLMapper extends BaseMapper{
+
+
+ int save(DevTask devJar);
+
+ int update(DevTask entity);
+
+ DevTask getById(int id);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevTaskMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevTaskMapper.java
new file mode 100644
index 0000000..11ab3f1
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/DevTaskMapper.java
@@ -0,0 +1,28 @@
+package com.czsj.bigdata.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.czsj.bigdata.entity.DevEnvSetting;
+import com.czsj.bigdata.entity.DevTask;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface DevTaskMapper extends BaseMapper{
+
+ int delete(@Param("id") int id);
+
+ int save(DevTask devJar);
+
+ int update(DevTask entity);
+
+ DevTask getById(int id);
+
+ List findList(@Param("offset") int offset,
+ @Param("pagesize") int pagesize,
+ @Param("type") String type);
+
+ String findPath(@Param("tasktype") String tasktype);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobDatasourceMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobDatasourceMapper.java
new file mode 100644
index 0000000..8ca0460
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobDatasourceMapper.java
@@ -0,0 +1,25 @@
+package com.czsj.bigdata.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.czsj.bigdata.entity.JobDatasource;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * jdbc数据源配置表数据库访问层
+ *
+ * @author zhouhongfa@gz-yibo.com
+ * @version v1.0
+ * @since 2019-07-30
+ */
+@Mapper
+public interface JobDatasourceMapper extends BaseMapper {
+ int update(JobDatasource datasource);
+
+ JobDatasource getDataSourceById(Long id);
+
+ List findDataSourceName();
+
+ List getdataSourceAll();
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobGroupMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobGroupMapper.java
new file mode 100644
index 0000000..2952f7b
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobGroupMapper.java
@@ -0,0 +1,29 @@
+package com.czsj.bigdata.mapper;
+
+import com.czsj.bigdata.entity.JobGroup;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * Created by xuxueli on 16/9/30.
+ */
+@Mapper
+public interface JobGroupMapper {
+
+ List findAll();
+
+ List find(@Param("appName") String appName,
+ @Param("title") String title,
+ @Param("addressList") String addressList);
+
+ int save(JobGroup jobGroup);
+ List findByAddressType(@Param("addressType") int addressType);
+
+ int update(JobGroup jobGroup);
+
+ int remove(@Param("id") int id);
+
+ JobGroup load(@Param("id") int id);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobInfoMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobInfoMapper.java
new file mode 100644
index 0000000..a9d808c
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobInfoMapper.java
@@ -0,0 +1,60 @@
+package com.czsj.bigdata.mapper;
+
+import com.czsj.bigdata.entity.JobInfo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * job info
+ *
+ * @author xuxueli 2016-1-12 18:03:45
+ */
+@Mapper
+public interface JobInfoMapper {
+
+ List pageList(@Param("offset") int offset,
+ @Param("pagesize") int pagesize,
+ @Param("jobGroup") int jobGroup,
+ @Param("triggerStatus") int triggerStatus,
+ @Param("jobDesc") String jobDesc,
+ @Param("glueType") String glueType,
+ @Param("userId") int userId,
+ @Param("projectIds") Integer[] projectIds);
+
+ int pageListCount(@Param("offset") int offset,
+ @Param("pagesize") int pagesize,
+ @Param("jobGroup") int jobGroup,
+ @Param("triggerStatus") int triggerStatus,
+ @Param("jobDesc") String jobDesc,
+ @Param("glueType") String glueType,
+ @Param("userId") int userId,
+ @Param("projectIds") Integer[] projectIds);
+
+ List findAll();
+
+ int save(JobInfo info);
+
+ JobInfo loadById(@Param("id") int id);
+
+ int update(JobInfo jobInfo);
+
+ int delete(@Param("id") long id);
+
+ List getJobsByGroup(@Param("jobGroup") int jobGroup);
+
+ int findAllCount();
+
+ List scheduleJobQuery(@Param("maxNextTime") long maxNextTime, @Param("pagesize") int pagesize);
+
+ int scheduleUpdate(JobInfo xxlJobInfo);
+
+ int incrementTimeUpdate(@Param("id") int id, @Param("incStartTime") Date incStartTime);
+
+ public int updateLastHandleCode(@Param("id") int id,@Param("lastHandleCode")int lastHandleCode);
+
+ void incrementIdUpdate(@Param("id") int id, @Param("incStartId")Long incStartId);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogGlueMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogGlueMapper.java
new file mode 100644
index 0000000..36f78b2
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogGlueMapper.java
@@ -0,0 +1,25 @@
+package com.czsj.bigdata.mapper;
+
+import com.czsj.bigdata.entity.JobLogGlue;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * job log for glue
+ *
+ * @author xuxueli 2016-5-19 18:04:56
+ */
+@Mapper
+public interface JobLogGlueMapper {
+
+ int save(JobLogGlue jobLogGlue);
+
+ List findByJobId(@Param("jobId") int jobId);
+
+ int removeOld(@Param("jobId") int jobId, @Param("limit") int limit);
+
+ int deleteByJobId(@Param("jobId") int jobId);
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogMapper.java
new file mode 100644
index 0000000..6994d8a
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogMapper.java
@@ -0,0 +1,67 @@
+package com.czsj.bigdata.mapper;
+
+import com.czsj.bigdata.entity.JobLog;
+import com.czsj.bigdata.entity.OperLog;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * job log
+ *
+ * @author xuxueli 2016-1-12 18:03:06
+ */
+@Mapper
+public interface JobLogMapper {
+
+ // exist jobId not use jobGroup, not exist use jobGroup
+ List pageList(@Param("offset") int offset,
+ @Param("pagesize") int pagesize,
+ @Param("jobGroup") int jobGroup,
+ @Param("jobId") int jobId,
+ @Param("triggerTimeStart") Date triggerTimeStart,
+ @Param("triggerTimeEnd") Date triggerTimeEnd,
+ @Param("logStatus") int logStatus);
+
+ int pageListCount(@Param("offset") int offset,
+ @Param("pagesize") int pagesize,
+ @Param("jobGroup") int jobGroup,
+ @Param("jobId") int jobId,
+ @Param("triggerTimeStart") Date triggerTimeStart,
+ @Param("triggerTimeEnd") Date triggerTimeEnd,
+ @Param("logStatus") int logStatus);
+
+ JobLog load(@Param("id") long id);
+
+ long save(JobLog jobLog);
+
+ int updateTriggerInfo(JobLog jobLog);
+
+ int updateHandleInfo(JobLog jobLog);
+
+ int updateProcessId(@Param("id") long id,
+ @Param("processId") String processId);
+
+ int delete(@Param("jobId") int jobId);
+
+ Map findLogReport(@Param("from") Date from,
+ @Param("to") Date to);
+
+ List findClearLogIds(@Param("jobGroup") int jobGroup,
+ @Param("jobId") int jobId,
+ @Param("clearBeforeTime") Date clearBeforeTime,
+ @Param("clearBeforeNum") int clearBeforeNum,
+ @Param("pagesize") int pagesize);
+
+ int clearLog(@Param("logIds") List logIds);
+
+ List findFailJobLogIds(@Param("pagesize") int pagesize);
+
+ int updateAlarmStatus(@Param("logId") long logId,
+ @Param("oldAlarmStatus") int oldAlarmStatus,
+ @Param("newAlarmStatus") int newAlarmStatus);
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogReportMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogReportMapper.java
new file mode 100644
index 0000000..7cc0afd
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogReportMapper.java
@@ -0,0 +1,30 @@
+package com.czsj.bigdata.mapper;
+
+import com.czsj.bigdata.entity.InfoReport;
+import com.czsj.bigdata.entity.JobLogReport;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * job log
+ *
+ * @author xuxueli 2019-11-22
+ */
+@Mapper
+public interface JobLogReportMapper {
+
+ int save(JobLogReport xxlJobLogReport);
+
+ int update(JobLogReport xxlJobLogReport);
+
+ List queryLogReport(@Param("triggerDayFrom") Date triggerDayFrom,
+ @Param("triggerDayTo") Date triggerDayTo);
+
+
+ List getInfoReportCount();
+
+ JobLogReport queryLogReportTotal();
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogSysMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogSysMapper.java
new file mode 100644
index 0000000..bce5511
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobLogSysMapper.java
@@ -0,0 +1,66 @@
+package com.czsj.bigdata.mapper;
+
+
+import com.czsj.bigdata.entity.SysJobLog;
+
+import java.util.List;
+
+/**
+ * 调度任务日志信息 数据层
+ *
+ * @author czsj
+ */
+public interface JobLogSysMapper
+{
+ /**
+ * 获取quartz调度器日志的计划任务
+ *
+ * @param jobLog 调度日志信息
+ * @return 调度任务日志集合
+ */
+ public List selectJobLogList(SysJobLog jobLog);
+
+ /**
+ * 查询所有调度任务日志
+ *
+ * @return 调度任务日志列表
+ */
+ public List selectJobLogAll();
+
+ /**
+ * 通过调度任务日志ID查询调度信息
+ *
+ * @param jobLogId 调度任务日志ID
+ * @return 调度任务日志对象信息
+ */
+ public SysJobLog selectJobLogById(Long jobLogId);
+
+ /**
+ * 新增任务日志
+ *
+ * @param jobLog 调度日志信息
+ * @return 结果
+ */
+ public int insertJobLog(SysJobLog jobLog);
+
+ /**
+ * 批量删除调度日志信息
+ *
+ * @param logIds 需要删除的数据ID
+ * @return 结果
+ */
+ public int deleteJobLogByIds(Long[] logIds);
+
+ /**
+ * 删除任务日志
+ *
+ * @param jobId 调度日志ID
+ * @return 结果
+ */
+ public int deleteJobLogById(Long jobId);
+
+ /**
+ * 清空任务日志
+ */
+ public void cleanJobLog();
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobProjectMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobProjectMapper.java
new file mode 100644
index 0000000..dece20e
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobProjectMapper.java
@@ -0,0 +1,26 @@
+package com.czsj.bigdata.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.czsj.bigdata.entity.JobProject;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * Project
+ *
+ * @author jingwk
+ * @version v2.1.12
+ * @since 2022-05-24
+ */
+@Mapper
+public interface JobProjectMapper extends BaseMapper {
+ /**
+ * project page
+ * @param page
+ * @param searchName
+ * @return
+ */
+ IPage getProjectListPaging(IPage page,
+ @Param("searchName") String searchName);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobRegistryMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobRegistryMapper.java
new file mode 100644
index 0000000..e06d534
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobRegistryMapper.java
@@ -0,0 +1,50 @@
+package com.czsj.bigdata.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.czsj.bigdata.entity.JobProject;
+import com.czsj.bigdata.entity.JobRegistry;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by jingwk on 2019/11/17
+ */
+@Mapper
+public interface JobRegistryMapper extends BaseMapper {
+
+ public List findDead(@Param("timeout") int timeout,
+ @Param("nowTime") Date nowTime);
+
+ public int removeDead(@Param("ids") List ids);
+
+ public List findAll(@Param("timeout") int timeout,
+ @Param("nowTime") Date nowTime);
+
+ public int registryUpdate(@Param("registryGroup") String registryGroup,
+ @Param("registryKey") String registryKey,
+ @Param("registryValue") String registryValue,
+ @Param("cpuUsage") double cpuUsage,
+ @Param("memoryUsage") double memoryUsage,
+ @Param("loadAverage") double loadAverage,
+ @Param("updateTime") Date updateTime);
+
+ public int registrySave(@Param("registryGroup") String registryGroup,
+ @Param("registryKey") String registryKey,
+ @Param("registryValue") String registryValue,
+ @Param("cpuUsage") double cpuUsage,
+ @Param("memoryUsage") double memoryUsage,
+ @Param("loadAverage") double loadAverage,
+ @Param("updateTime") Date updateTime);
+
+ public int registryDelete(@Param("registryGroup") String registryGroup,
+ @Param("registryKey") String registryKey,
+ @Param("registryValue") String registryValue);
+
+ IPage selectAll(Page page);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobSysMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobSysMapper.java
new file mode 100644
index 0000000..d64d997
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobSysMapper.java
@@ -0,0 +1,77 @@
+package com.czsj.bigdata.mapper;
+
+
+import com.czsj.bigdata.entity.SysJob;
+
+import java.util.List;
+
+/**
+ * 调度任务信息 数据层
+ *
+ * @author czsj
+ */
+public interface JobSysMapper
+{
+ /**
+ * 查询调度任务日志集合
+ *
+ * @param job 调度信息
+ * @return 操作日志集合
+ */
+ public List selectJobList(SysJob job);
+
+ /**
+ * 查询所有调度任务
+ *
+ * @return 调度任务列表
+ */
+ public List selectJobAll();
+
+ /**
+ * 通过调度ID查询调度任务信息
+ *
+ * @param jobId 调度ID
+ * @return 角色对象信息
+ */
+ public SysJob selectJobById(Long jobId);
+
+ /**
+ * 通过调度ID删除调度任务信息
+ *
+ * @param jobId 调度ID
+ * @return 结果
+ */
+ public int deleteJobById(Long jobId);
+
+ /**
+ * 批量删除调度任务信息
+ *
+ * @param ids 需要删除的数据ID
+ * @return 结果
+ */
+ public int deleteJobByIds(Long[] ids);
+
+ /**
+ * 修改调度任务信息
+ *
+ * @param job 调度任务信息
+ * @return 结果
+ */
+ public int updateJob(SysJob job);
+
+ /**
+ * 新增调度任务信息
+ *
+ * @param job 调度任务信息
+ * @return 结果
+ */
+ public int insertJob(SysJob job);
+
+ /**
+ * 通过任务字符串查jobid
+ *
+ * @param target 调度任务信息
+ * @return 结果
+ */
+ public Integer selectJobBytarget(String target);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobTemplateMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobTemplateMapper.java
new file mode 100644
index 0000000..2793720
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobTemplateMapper.java
@@ -0,0 +1,41 @@
+package com.czsj.bigdata.mapper;
+
+import com.czsj.bigdata.entity.JobTemplate;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+
+/**
+ * job info
+ * @author xuxueli 2016-1-12 18:03:45
+ */
+@Mapper
+public interface JobTemplateMapper {
+
+ public List pageList(@Param("offset") int offset,
+ @Param("pagesize") int pagesize,
+ @Param("jobGroup") int jobGroup,
+ @Param("jobDesc") String jobDesc,
+ @Param("executorHandler") String executorHandler,
+ @Param("userId") int userId,
+ @Param("projectIds") Integer[] projectIds);
+
+ public int pageListCount(@Param("offset") int offset,
+ @Param("pagesize") int pagesize,
+ @Param("jobGroup") int jobGroup,
+ @Param("jobDesc") String jobDesc,
+ @Param("executorHandler") String executorHandler,
+ @Param("userId") int userId,
+ @Param("projectIds") Integer[] projectIds);
+
+ public int save(JobTemplate info);
+
+ public JobTemplate loadById(@Param("id") int id);
+
+ public int update(JobTemplate jobTemplate);
+
+ public int delete(@Param("id") long id);
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobUserMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobUserMapper.java
new file mode 100644
index 0000000..402aa7e
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/JobUserMapper.java
@@ -0,0 +1,41 @@
+package com.czsj.bigdata.mapper;
+
+import com.czsj.bigdata.entity.JobUser;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author xuxueli 2019-05-04 16:44:59
+ */
+@Mapper
+@Repository
+public interface JobUserMapper {
+
+ List pageList(@Param("offset") int offset,
+ @Param("pagesize") int pagesize,
+ @Param("username") String username);
+
+ List findAll(@Param("username") String username);
+
+ int pageListCount(@Param("offset") int offset,
+ @Param("pagesize") int pagesize,
+ @Param("username") String username);
+
+ JobUser loadByUserName(@Param("username") String username);
+
+ JobUser getUserById(@Param("id") int id);
+
+ List getUsersByIds(@Param("ids") String[] ids);
+
+ int save(JobUser jobUser);
+
+ int update(JobUser jobUser);
+
+ int delete(@Param("id") int id);
+
+
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/PermissionMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/PermissionMapper.java
new file mode 100644
index 0000000..38585b8
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/PermissionMapper.java
@@ -0,0 +1,16 @@
+package com.czsj.bigdata.mapper;
+
+import com.czsj.bigdata.entity.JobPermission;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Mapper
+@Repository
+public interface PermissionMapper {
+
+ List findAll();
+
+ List findByAdminUserId(int userId);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/mapper/SysServersMapper.java b/czsj-system/src/main/java/com/czsj/bigdata/mapper/SysServersMapper.java
new file mode 100644
index 0000000..76aaa99
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/mapper/SysServersMapper.java
@@ -0,0 +1,65 @@
+package com.czsj.bigdata.mapper;
+
+import com.czsj.bigdata.entity.SysServers;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+
+/**
+ * 执行器管理Mapper接口
+ *
+ * @author czsj
+ * @date 2022-04-28
+ */
+@Mapper
+public interface SysServersMapper
+{
+ /**
+ * 查询执行器管理
+ *
+ * @param id 执行器管理主键
+ * @return 执行器管理
+ */
+ public SysServers selectSysServersById(Long id);
+
+ /**
+ * 查询执行器管理列表
+ *
+ * @param sysServers 执行器管理
+ * @return 执行器管理集合
+ */
+ public List selectSysServersList(SysServers sysServers);
+
+ /**
+ * 新增执行器管理
+ *
+ * @param sysServers 执行器管理
+ * @return 结果
+ */
+ public int insertSysServers(SysServers sysServers);
+
+ /**
+ * 修改执行器管理
+ *
+ * @param sysServers 执行器管理
+ * @return 结果
+ */
+ public int updateSysServers(SysServers sysServers);
+
+ /**
+ * 删除执行器管理
+ *
+ * @param id 执行器管理主键
+ * @return 结果
+ */
+ public int deleteSysServersById(Long id);
+
+ /**
+ * 批量删除执行器管理
+ *
+ * @param ids 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteSysServersByIds(Long[] ids);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/service/APIAuthService.java b/czsj-system/src/main/java/com/czsj/bigdata/service/APIAuthService.java
new file mode 100644
index 0000000..3108926
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/service/APIAuthService.java
@@ -0,0 +1,7 @@
+package com.czsj.bigdata.service;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.czsj.bigdata.entity.APIAuth;
+import com.czsj.bigdata.entity.APIConfig;
+
+public interface APIAuthService extends IService{
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/service/APIConfigService.java b/czsj-system/src/main/java/com/czsj/bigdata/service/APIConfigService.java
new file mode 100644
index 0000000..f0eb312
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/service/APIConfigService.java
@@ -0,0 +1,7 @@
+package com.czsj.bigdata.service;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.czsj.bigdata.entity.APIConfig;
+import com.czsj.bigdata.entity.APIConfig;
+
+public interface APIConfigService extends IService{
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/service/DatasourceQueryService.java b/czsj-system/src/main/java/com/czsj/bigdata/service/DatasourceQueryService.java
new file mode 100644
index 0000000..0bbed24
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/service/DatasourceQueryService.java
@@ -0,0 +1,62 @@
+package com.czsj.bigdata.service;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * 数据库查询服务
+ *
+ * @author zhouhongfa@gz-yibo.com
+ * @ClassName JdbcDatasourceQueryService
+ * @Version 1.0
+ * @since 2019/7/31 20:50
+ */
+public interface DatasourceQueryService {
+
+ /**
+ * 获取db列表
+ * @param id
+ * @return
+ */
+ List getDBs(Long id) throws IOException;
+
+ /**
+ * 根据数据源表id查询出可用的表
+ *
+ * @param id
+ * @return
+ */
+ List getTables(Long id,String tableSchema) throws IOException;
+
+ /**
+ * 获取CollectionNames
+ * @param dbName
+ * @return
+ */
+ List getCollectionNames(long id,String dbName) throws IOException;
+
+ /**
+ * 根据数据源id,表名查询出该表所有字段
+ *
+ * @param id
+ * @return
+ */
+ List getColumns(Long id, String tableName) throws IOException;
+
+ /**
+ * 根据 sql 语句获取字段
+ *
+ * @param datasourceId
+ * @param querySql
+ * @return
+ */
+ List getColumnsByQuerySql(Long datasourceId, String querySql) throws SQLException;
+
+ /**
+ * 获取PG table schema
+ * @param id
+ * @return
+ */
+ List getTableSchema(Long id);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/service/DataxJsonService.java b/czsj-system/src/main/java/com/czsj/bigdata/service/DataxJsonService.java
new file mode 100644
index 0000000..c94520d
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/service/DataxJsonService.java
@@ -0,0 +1,21 @@
+package com.czsj.bigdata.service;
+
+import com.czsj.bigdata.dto.DataXJsonBuildDto;
+
+/**
+ * com.wugui.datax json构建服务层接口
+ *
+ * @author zhouhongfa@gz-yibo.com
+ * @version 1.0
+ * @since 2019/8/1
+ */
+public interface DataxJsonService {
+
+ /**
+ * build datax json
+ *
+ * @param dto
+ * @return
+ */
+ String buildJobJson(DataXJsonBuildDto dto);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/service/DevEnvSettingService.java b/czsj-system/src/main/java/com/czsj/bigdata/service/DevEnvSettingService.java
new file mode 100644
index 0000000..218d9bb
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/service/DevEnvSettingService.java
@@ -0,0 +1,8 @@
+package com.czsj.bigdata.service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.czsj.bigdata.entity.DevEnvSetting;
+public interface DevEnvSettingService extends IService{
+ IPage getDevEnvSettingListPaging(Integer pageSize, Integer pageNo, String searchName);
+
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/service/DevJarService.java b/czsj-system/src/main/java/com/czsj/bigdata/service/DevJarService.java
new file mode 100644
index 0000000..6fcf272
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/service/DevJarService.java
@@ -0,0 +1,6 @@
+package com.czsj.bigdata.service;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.czsj.bigdata.entity.DevTask;
+
+public interface DevJarService extends IService{
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/service/ISysServersService.java b/czsj-system/src/main/java/com/czsj/bigdata/service/ISysServersService.java
new file mode 100644
index 0000000..9242457
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/service/ISysServersService.java
@@ -0,0 +1,62 @@
+package com.czsj.bigdata.service;
+
+import java.util.List;
+
+import com.czsj.bigdata.entity.SysServers;
+
+/**
+ * 执行器管理Service接口
+ *
+ * @author czsj
+ * @date 2022-04-28
+ */
+public interface ISysServersService
+{
+ /**
+ * 查询执行器管理
+ *
+ * @param id 执行器管理主键
+ * @return 执行器管理
+ */
+ public SysServers selectSysServersById(Long id);
+
+ /**
+ * 查询执行器管理列表
+ *
+ * @param sysServers 执行器管理
+ * @return 执行器管理集合
+ */
+ public List selectSysServersList(SysServers sysServers);
+
+ /**
+ * 新增执行器管理
+ *
+ * @param sysServers 执行器管理
+ * @return 结果
+ */
+ public int insertSysServers(SysServers sysServers);
+
+ /**
+ * 修改执行器管理
+ *
+ * @param sysServers 执行器管理
+ * @return 结果
+ */
+ public int updateSysServers(SysServers sysServers);
+
+ /**
+ * 批量删除执行器管理
+ *
+ * @param ids 需要删除的执行器管理主键集合
+ * @return 结果
+ */
+ public int deleteSysServersByIds(Long[] ids);
+
+ /**
+ * 删除执行器管理信息
+ *
+ * @param id 执行器管理主键
+ * @return 结果
+ */
+ public int deleteSysServersById(Long id);
+}
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/service/JobDatasourceService.java b/czsj-system/src/main/java/com/czsj/bigdata/service/JobDatasourceService.java
new file mode 100644
index 0000000..9b19632
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/service/JobDatasourceService.java
@@ -0,0 +1,41 @@
+package com.czsj.bigdata.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.czsj.bigdata.entity.JobDatasource;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * jdbc数据源配置表服务接口
+ *
+ * @author jingwk
+ * @version v2.0
+ * @since 2022-01-10
+ */
+public interface JobDatasourceService extends IService {
+ /**
+ * 测试数据源
+ * @param jdbcDatasource
+ * @return
+ */
+ Boolean dataSourceTest(JobDatasource jdbcDatasource) throws IOException;
+
+ /**
+ *更新数据源信息
+ * @param datasource
+ * @return
+ */
+ int update(JobDatasource datasource);
+
+ /**
+ * 获取所有数据源
+ * @return
+ */
+ List selectAllDatasource();
+
+
+ List findDataSourceName();
+
+ JobDatasource getDataSourceById(Long datasourceId);
+}
\ No newline at end of file
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/service/JobProjectService.java b/czsj-system/src/main/java/com/czsj/bigdata/service/JobProjectService.java
new file mode 100644
index 0000000..54ce4ee
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/service/JobProjectService.java
@@ -0,0 +1,26 @@
+package com.czsj.bigdata.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.czsj.bigdata.entity.JobDatasource;
+import com.czsj.bigdata.entity.JobProject;
+
+/**
+ * Job project
+ *
+ * @author jingwk
+ * @version v2.1.2
+ * @since 2022-05-24
+ */
+public interface JobProjectService extends IService {
+
+ /**
+ * project page
+ * @param pageSize
+ * @param pageNo
+ * @param searchName
+ * @return
+ */
+
+ IPage getProjectListPaging(Integer pageSize, Integer pageNo, String searchName);
+}
\ No newline at end of file
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/service/JobRegistryService.java b/czsj-system/src/main/java/com/czsj/bigdata/service/JobRegistryService.java
new file mode 100644
index 0000000..2f1736b
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/service/JobRegistryService.java
@@ -0,0 +1,14 @@
+package com.czsj.bigdata.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.czsj.bigdata.entity.JobRegistry;
+
+/**
+ * jdbc数据源配置表服务接口
+ *
+ * @author jingwk
+ * @version v2.1.1
+ * @since 2022-03-15
+ */
+public interface JobRegistryService extends IService {
+}
\ No newline at end of file
diff --git a/czsj-system/src/main/java/com/czsj/bigdata/service/JobService.java b/czsj-system/src/main/java/com/czsj/bigdata/service/JobService.java
new file mode 100644
index 0000000..8ed9ba3
--- /dev/null
+++ b/czsj-system/src/main/java/com/czsj/bigdata/service/JobService.java
@@ -0,0 +1,96 @@
+package com.czsj.bigdata.service;
+
+
+import com.czsj.bigdata.dto.DataXBatchJsonBuildDto;
+import com.czsj.bigdata.dto.TaskScheduleDto;
+import com.czsj.bigdata.entity.JobInfo;
+import com.czsj.core.biz.model.ReturnT;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * core job action for czsj-ground
+ *
+ * @author xuxueli 2016-5-28 15:30:33
+ */
+public interface JobService {
+
+ /**
+ * page list
+ *
+ * @param start
+ * @param length
+ * @param jobGroup
+ * @param jobDesc
+ * @param glueType
+ * @param userId
+ * @return
+ */
+ Map pageList(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String glueType, int userId,Integer[] projectIds);
+
+ List list();
+
+ /**
+ * add job
+ *
+ * @param jobInfo
+ * @return
+ */
+ ReturnT add(JobInfo jobInfo);
+
+ /**
+ * update job
+ *
+ * @param jobInfo
+ * @return
+ */
+ ReturnT update(JobInfo jobInfo);
+
+ /**
+ * remove job
+ * *
+ *
+ * @param id
+ * @return
+ */
+ ReturnT remove(int id);
+
+ /**
+ * start job
+ *
+ * @param id
+ * @return
+ */
+ ReturnT start(int id);
+
+ /**
+ * stop job
+ *
+ * @param id
+ * @return
+ */
+ ReturnT stop(int id);
+
+ /**
+ * dashboard info
+ *
+ * @return
+ */
+ Map dashboardInfo();
+
+ /**
+ * chart info
+ *
+ * @return
+ */
+ ReturnT