mirror of
				https://github.com/dromara/RuoYi-Vue-Plus.git
				synced 2025-11-04 16:23:42 +08:00 
			
		
		
		
	Merge branch '5.X' of gitee.com:dromara/RuoYi-Vue-Plus into JustAuth
Signed-off-by: 三个三 <2029364173@qq.com>
This commit is contained in:
		@@ -1,10 +1,10 @@
 | 
			
		||||
<component name="ProjectRunConfigurationManager">
 | 
			
		||||
  <configuration default="false" name="ruoyi-xxl-job-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
 | 
			
		||||
  <configuration default="false" name="ruoyi-powerjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
 | 
			
		||||
    <deployment type="dockerfile">
 | 
			
		||||
      <settings>
 | 
			
		||||
        <option name="imageTag" value="ruoyi/ruoyi-xxl-job-admin:5.0.0" />
 | 
			
		||||
        <option name="imageTag" value="ruoyi/ruoyi-powerjob-server:5.0.0" />
 | 
			
		||||
        <option name="buildOnly" value="true" />
 | 
			
		||||
        <option name="sourceFilePath" value="ruoyi-extend/ruoyi-xxl-job-admin/Dockerfile" />
 | 
			
		||||
        <option name="sourceFilePath" value="ruoyi-extend/ruoyi-powerjob-server/Dockerfile" />
 | 
			
		||||
      </settings>
 | 
			
		||||
    </deployment>
 | 
			
		||||
    <method v="2" />
 | 
			
		||||
@@ -54,7 +54,7 @@
 | 
			
		||||
| 序列化         | 采用 Jackson Spring官方内置序列化 靠谱!!!                                                                                    | 采用 fastjson bugjson 远近闻名                                                           | 
 | 
			
		||||
| 分布式幂等       | 参考美团GTIS防重系统简化实现(细节可看文档)                                                                                          | 手动编写注解基于aop实现                                                                      |
 | 
			
		||||
| 分布式锁        | 采用 Lock4j 底层基于 Redisson                                                                                           | 无                                                                                  |
 | 
			
		||||
| 分布式任务调度     | 采用 Xxl-Job 天生支持分布式 统一的管理中心                                                                                        | 采用 Quartz 基于数据库锁性能差 集群需要做很多配置与改造                                                   | 
 | 
			
		||||
| 分布式任务调度     | 采用 PowerJob 天生支持分布式 统一的管理中心                                                                                       | 采用 Quartz 基于数据库锁性能差 集群需要做很多配置与改造                                                   | 
 | 
			
		||||
| 文件存储        | 采用 Minio 分布式文件存储 天生支持多机、多硬盘、多分片、多副本存储<br/>支持权限管理 安全可靠 文件可加密存储                                                     | 采用 本机文件存储 文件裸漏 易丢失泄漏 不支持集群有单点效应                                                    |
 | 
			
		||||
| 云存储         | 采用 AWS S3 协议客户端 支持 七牛、阿里、腾讯 等一切支持S3协议的厂家                                                                          | 不支持                                                                                |
 | 
			
		||||
| 短信          | 采用 sms4j 短信融合包 支持数十种短信厂家 只需在yml配置好厂家密钥即可使用 可多厂家共用                                                                 | 不支持                                                                                |
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								pom.xml
									
									
									
									
									
								
							@@ -34,7 +34,7 @@
 | 
			
		||||
        <lock4j.version>2.2.4</lock4j.version>
 | 
			
		||||
        <dynamic-ds.version>3.6.1</dynamic-ds.version>
 | 
			
		||||
        <alibaba-ttl.version>2.14.2</alibaba-ttl.version>
 | 
			
		||||
        <xxl-job.version>2.4.0</xxl-job.version>
 | 
			
		||||
        <powerjob.version>4.3.3</powerjob.version>
 | 
			
		||||
        <mapstruct-plus.version>1.2.3</mapstruct-plus.version>
 | 
			
		||||
        <mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
 | 
			
		||||
        <lombok.version>1.18.26</lombok.version>
 | 
			
		||||
@@ -272,12 +272,6 @@
 | 
			
		||||
                <version>${lock4j.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
            <!-- xxl-job-core -->
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>com.xuxueli</groupId>
 | 
			
		||||
                <artifactId>xxl-job-core</artifactId>
 | 
			
		||||
                <version>${xxl-job.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>com.alibaba</groupId>
 | 
			
		||||
@@ -336,6 +330,18 @@
 | 
			
		||||
                <version>${revision}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
            <!-- PowerJob -->
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>tech.powerjob</groupId>
 | 
			
		||||
                <artifactId>powerjob-worker-spring-boot-starter</artifactId>
 | 
			
		||||
                <version>${powerjob.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>tech.powerjob</groupId>
 | 
			
		||||
                <artifactId>powerjob-official-processors</artifactId>
 | 
			
		||||
                <version>${powerjob.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
        </dependencies>
 | 
			
		||||
    </dependencyManagement>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,27 +8,20 @@ spring.boot.admin.client:
 | 
			
		||||
  username: ruoyi
 | 
			
		||||
  password: 123456
 | 
			
		||||
 | 
			
		||||
--- # xxl-job 配置
 | 
			
		||||
xxl.job:
 | 
			
		||||
  # 执行器开关
 | 
			
		||||
  enabled: true
 | 
			
		||||
  # 调度中心地址:如调度中心集群部署存在多个地址则用逗号分隔。
 | 
			
		||||
  admin-addresses: http://localhost:9100/xxl-job-admin
 | 
			
		||||
  # 执行器通讯TOKEN:非空时启用
 | 
			
		||||
  access-token: xxl-job
 | 
			
		||||
  executor:
 | 
			
		||||
    # 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册
 | 
			
		||||
    appname: xxl-job-executor
 | 
			
		||||
    # 执行器端口号 执行器从9101开始往后写
 | 
			
		||||
    port: 9101
 | 
			
		||||
    # 执行器注册:默认IP:PORT
 | 
			
		||||
    address:
 | 
			
		||||
    # 执行器IP:默认自动获取IP
 | 
			
		||||
    ip:
 | 
			
		||||
    # 执行器运行日志文件存储磁盘路径
 | 
			
		||||
    logpath: ./logs/xxl-job
 | 
			
		||||
    # 执行器日志文件保存天数:大于3生效
 | 
			
		||||
    logretentiondays: 30
 | 
			
		||||
--- # powerjob 配置
 | 
			
		||||
powerjob:
 | 
			
		||||
  worker:
 | 
			
		||||
    # 如何开启调度中心请查看文档教程
 | 
			
		||||
    enabled: false
 | 
			
		||||
    # 需要先在 powerjob 登录页执行应用注册后才能使用
 | 
			
		||||
    app-name: ruoyi-worker
 | 
			
		||||
    enable-test-mode: false
 | 
			
		||||
    max-appended-wf-context-length: 4096
 | 
			
		||||
    max-result-length: 4096
 | 
			
		||||
    port: 27777
 | 
			
		||||
    protocol: http
 | 
			
		||||
    server-address: 127.0.0.1:7700
 | 
			
		||||
    store-strategy: disk
 | 
			
		||||
 | 
			
		||||
--- # 数据源配置
 | 
			
		||||
spring:
 | 
			
		||||
 
 | 
			
		||||
@@ -11,27 +11,20 @@ spring.boot.admin.client:
 | 
			
		||||
  username: ruoyi
 | 
			
		||||
  password: 123456
 | 
			
		||||
 | 
			
		||||
--- # xxl-job 配置
 | 
			
		||||
xxl.job:
 | 
			
		||||
  # 执行器开关
 | 
			
		||||
  enabled: true
 | 
			
		||||
  # 调度中心地址:如调度中心集群部署存在多个地址则用逗号分隔。
 | 
			
		||||
  admin-addresses: http://localhost:9100/xxl-job-admin
 | 
			
		||||
  # 执行器通讯TOKEN:非空时启用
 | 
			
		||||
  access-token: xxl-job
 | 
			
		||||
  executor:
 | 
			
		||||
    # 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册
 | 
			
		||||
    appname: xxl-job-executor
 | 
			
		||||
    # 执行器端口号 执行器从9101开始往后写
 | 
			
		||||
    port: 9101
 | 
			
		||||
    # 执行器注册:默认IP:PORT
 | 
			
		||||
    address:
 | 
			
		||||
    # 执行器IP:默认自动获取IP
 | 
			
		||||
    ip:
 | 
			
		||||
    # 执行器运行日志文件存储磁盘路径
 | 
			
		||||
    logpath: ./logs/xxl-job
 | 
			
		||||
    # 执行器日志文件保存天数:大于3生效
 | 
			
		||||
    logretentiondays: 30
 | 
			
		||||
--- # powerjob 配置
 | 
			
		||||
powerjob:
 | 
			
		||||
  worker:
 | 
			
		||||
    # 如何开启调度中心请查看文档教程
 | 
			
		||||
    enabled: false
 | 
			
		||||
    # 需要先在 powerjob 登录页执行应用注册后才能使用
 | 
			
		||||
    app-name: ruoyi-worker
 | 
			
		||||
    enable-test-mode: false
 | 
			
		||||
    max-appended-wf-context-length: 4096
 | 
			
		||||
    max-result-length: 4096
 | 
			
		||||
    port: 27777
 | 
			
		||||
    protocol: http
 | 
			
		||||
    server-address: 127.0.0.1:7700
 | 
			
		||||
    store-strategy: disk
 | 
			
		||||
 | 
			
		||||
--- # 数据源配置
 | 
			
		||||
spring:
 | 
			
		||||
 
 | 
			
		||||
@@ -15,17 +15,21 @@
 | 
			
		||||
        ruoyi-common-job 定时任务
 | 
			
		||||
    </description>
 | 
			
		||||
 | 
			
		||||
	<dependencies>
 | 
			
		||||
    <dependencies>
 | 
			
		||||
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.springframework.boot</groupId>
 | 
			
		||||
            <artifactId>spring-boot-autoconfigure</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <!-- xxl-job-core -->
 | 
			
		||||
        <!--PowerJob-->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>com.xuxueli</groupId>
 | 
			
		||||
            <artifactId>xxl-job-core</artifactId>
 | 
			
		||||
            <groupId>tech.powerjob</groupId>
 | 
			
		||||
            <artifactId>powerjob-worker-spring-boot-starter</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>tech.powerjob</groupId>
 | 
			
		||||
            <artifactId>powerjob-official-processors</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <dependency>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,80 +0,0 @@
 | 
			
		||||
package com.xxl.job.core.glue.impl;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
 | 
			
		||||
import com.xxl.job.core.glue.GlueFactory;
 | 
			
		||||
import jakarta.annotation.Resource;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Qualifier;
 | 
			
		||||
import org.springframework.core.annotation.AnnotationUtils;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Modifier;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2018-11-01
 | 
			
		||||
 */
 | 
			
		||||
public class SpringGlueFactory extends GlueFactory {
 | 
			
		||||
    private static Logger logger = LoggerFactory.getLogger(SpringGlueFactory.class);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * inject action of spring
 | 
			
		||||
     * @param instance
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void injectService(Object instance){
 | 
			
		||||
        if (instance==null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (XxlJobSpringExecutor.getApplicationContext() == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Field[] fields = instance.getClass().getDeclaredFields();
 | 
			
		||||
        for (Field field : fields) {
 | 
			
		||||
            if (Modifier.isStatic(field.getModifiers())) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Object fieldBean = null;
 | 
			
		||||
            // with bean-id, bean could be found by both @Resource and @Autowired, or bean could only be found by @Autowired
 | 
			
		||||
 | 
			
		||||
            if (AnnotationUtils.getAnnotation(field, Resource.class) != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    Resource resource = AnnotationUtils.getAnnotation(field, Resource.class);
 | 
			
		||||
                    if (resource.name()!=null && resource.name().length()>0){
 | 
			
		||||
                        fieldBean = XxlJobSpringExecutor.getApplicationContext().getBean(resource.name());
 | 
			
		||||
                    } else {
 | 
			
		||||
                        fieldBean = XxlJobSpringExecutor.getApplicationContext().getBean(field.getName());
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                }
 | 
			
		||||
                if (fieldBean==null ) {
 | 
			
		||||
                    fieldBean = XxlJobSpringExecutor.getApplicationContext().getBean(field.getType());
 | 
			
		||||
                }
 | 
			
		||||
            } else if (AnnotationUtils.getAnnotation(field, Autowired.class) != null) {
 | 
			
		||||
                Qualifier qualifier = AnnotationUtils.getAnnotation(field, Qualifier.class);
 | 
			
		||||
                if (qualifier!=null && qualifier.value()!=null && qualifier.value().length()>0) {
 | 
			
		||||
                    fieldBean = XxlJobSpringExecutor.getApplicationContext().getBean(qualifier.value());
 | 
			
		||||
                } else {
 | 
			
		||||
                    fieldBean = XxlJobSpringExecutor.getApplicationContext().getBean(field.getType());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (fieldBean!=null) {
 | 
			
		||||
                field.setAccessible(true);
 | 
			
		||||
                try {
 | 
			
		||||
                    field.set(instance, fieldBean);
 | 
			
		||||
                } catch (IllegalArgumentException e) {
 | 
			
		||||
                    logger.error(e.getMessage(), e);
 | 
			
		||||
                } catch (IllegalAccessException e) {
 | 
			
		||||
                    logger.error(e.getMessage(), e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
package org.dromara.common.job.config;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.scheduling.annotation.EnableScheduling;
 | 
			
		||||
import tech.powerjob.worker.PowerJobWorker;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 启动定时任务
 | 
			
		||||
 * @author yhan219
 | 
			
		||||
 * @since 2023/6/2
 | 
			
		||||
 */
 | 
			
		||||
@Configuration
 | 
			
		||||
@ConditionalOnBean(PowerJobWorker.class)
 | 
			
		||||
@ConditionalOnProperty(prefix = "powerjob.worker", name = "enabled", havingValue = "true")
 | 
			
		||||
@EnableScheduling
 | 
			
		||||
public class PowerJobConfig {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
package org.dromara.common.job.config;
 | 
			
		||||
 | 
			
		||||
import org.dromara.common.job.config.properties.XxlJobProperties;
 | 
			
		||||
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 | 
			
		||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
 | 
			
		||||
import org.springframework.context.annotation.Bean;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xxl-job config
 | 
			
		||||
 *
 | 
			
		||||
 * @author Lion Li
 | 
			
		||||
 */
 | 
			
		||||
@Slf4j
 | 
			
		||||
@AutoConfiguration
 | 
			
		||||
@EnableConfigurationProperties(XxlJobProperties.class)
 | 
			
		||||
@ConditionalOnProperty(prefix = "xxl.job", name = "enabled", havingValue = "true")
 | 
			
		||||
public class XxlJobConfig {
 | 
			
		||||
 | 
			
		||||
    @Bean
 | 
			
		||||
    public XxlJobSpringExecutor xxlJobExecutor(XxlJobProperties xxlJobProperties) {
 | 
			
		||||
        log.info(">>>>>>>>>>> xxl-job config init.");
 | 
			
		||||
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
 | 
			
		||||
        xxlJobSpringExecutor.setAdminAddresses(xxlJobProperties.getAdminAddresses());
 | 
			
		||||
        xxlJobSpringExecutor.setAccessToken(xxlJobProperties.getAccessToken());
 | 
			
		||||
        XxlJobProperties.Executor executor = xxlJobProperties.getExecutor();
 | 
			
		||||
        xxlJobSpringExecutor.setAppname(executor.getAppname());
 | 
			
		||||
        xxlJobSpringExecutor.setAddress(executor.getAddress());
 | 
			
		||||
        xxlJobSpringExecutor.setIp(executor.getIp());
 | 
			
		||||
        xxlJobSpringExecutor.setPort(executor.getPort());
 | 
			
		||||
        xxlJobSpringExecutor.setLogPath(executor.getLogPath());
 | 
			
		||||
        xxlJobSpringExecutor.setLogRetentionDays(executor.getLogRetentionDays());
 | 
			
		||||
        return xxlJobSpringExecutor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,40 +0,0 @@
 | 
			
		||||
package org.dromara.common.job.config.properties;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
import org.springframework.boot.context.properties.ConfigurationProperties;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xxljob配置类
 | 
			
		||||
 *
 | 
			
		||||
 * @author Lion Li
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@ConfigurationProperties(prefix = "xxl.job")
 | 
			
		||||
public class XxlJobProperties {
 | 
			
		||||
 | 
			
		||||
    private Boolean enabled;
 | 
			
		||||
 | 
			
		||||
    private String adminAddresses;
 | 
			
		||||
 | 
			
		||||
    private String accessToken;
 | 
			
		||||
 | 
			
		||||
    private Executor executor;
 | 
			
		||||
 | 
			
		||||
    @Data
 | 
			
		||||
    @NoArgsConstructor
 | 
			
		||||
    public static class Executor {
 | 
			
		||||
 | 
			
		||||
        private String appname;
 | 
			
		||||
 | 
			
		||||
        private String address;
 | 
			
		||||
 | 
			
		||||
        private String ip;
 | 
			
		||||
 | 
			
		||||
        private int port;
 | 
			
		||||
 | 
			
		||||
        private String logPath;
 | 
			
		||||
 | 
			
		||||
        private int logRetentionDays;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
org.dromara.common.job.config.XxlJobConfig
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 | 
			
		||||
    <modules>
 | 
			
		||||
        <module>ruoyi-monitor-admin</module>
 | 
			
		||||
        <module>ruoyi-xxl-job-admin</module>
 | 
			
		||||
        <module>ruoyi-powerjob-server</module>
 | 
			
		||||
    </modules>
 | 
			
		||||
 | 
			
		||||
</project>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								ruoyi-extend/ruoyi-powerjob-server/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								ruoyi-extend/ruoyi-powerjob-server/Dockerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
FROM findepi/graalvm:java17-native
 | 
			
		||||
 | 
			
		||||
MAINTAINER Lion Li
 | 
			
		||||
 | 
			
		||||
RUN mkdir -p /ruoyi/powerjob/logs
 | 
			
		||||
 | 
			
		||||
WORKDIR /ruoyi/powerjob
 | 
			
		||||
 | 
			
		||||
EXPOSE 7700
 | 
			
		||||
 | 
			
		||||
ADD ./target/ruoyi-powerjob-server.jar ./app.jar
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
 | 
			
		||||
							
								
								
									
										68
									
								
								ruoyi-extend/ruoyi-powerjob-server/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								ruoyi-extend/ruoyi-powerjob-server/pom.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 | 
			
		||||
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.dromara</groupId>
 | 
			
		||||
        <artifactId>ruoyi-extend</artifactId>
 | 
			
		||||
        <version>${revision}</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <packaging>jar</packaging>
 | 
			
		||||
    <artifactId>ruoyi-powerjob-server</artifactId>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <spring-boot.version>2.7.12</spring-boot.version>
 | 
			
		||||
        <spring-boot-admin.version>2.7.10</spring-boot-admin.version>
 | 
			
		||||
    </properties>
 | 
			
		||||
    <dependencyManagement>
 | 
			
		||||
        <dependencies>
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>org.springframework.boot</groupId>
 | 
			
		||||
                <artifactId>spring-boot-starter-parent</artifactId>
 | 
			
		||||
                <version>${spring-boot.version}</version>
 | 
			
		||||
                <type>pom</type>
 | 
			
		||||
                <scope>import</scope>
 | 
			
		||||
            </dependency>
 | 
			
		||||
        </dependencies>
 | 
			
		||||
    </dependencyManagement>
 | 
			
		||||
 | 
			
		||||
    <dependencies>
 | 
			
		||||
 | 
			
		||||
        <!-- PowerJob server-->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>tech.powerjob</groupId>
 | 
			
		||||
            <artifactId>powerjob-server-starter</artifactId>
 | 
			
		||||
            <version>${powerjob.version}</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>de.codecentric</groupId>
 | 
			
		||||
            <artifactId>spring-boot-admin-starter-client</artifactId>
 | 
			
		||||
            <version>${spring-boot-admin.version}</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.projectlombok</groupId>
 | 
			
		||||
            <artifactId>lombok</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
    </dependencies>
 | 
			
		||||
 | 
			
		||||
    <build>
 | 
			
		||||
        <finalName>${project.artifactId}</finalName>
 | 
			
		||||
        <plugins>
 | 
			
		||||
            <plugin>
 | 
			
		||||
                <groupId>org.springframework.boot</groupId>
 | 
			
		||||
                <artifactId>spring-boot-maven-plugin</artifactId>
 | 
			
		||||
                <version>${spring-boot.version}</version>
 | 
			
		||||
                <executions>
 | 
			
		||||
                    <execution>
 | 
			
		||||
                        <goals>
 | 
			
		||||
                            <goal>repackage</goal>
 | 
			
		||||
                        </goals>
 | 
			
		||||
                    </execution>
 | 
			
		||||
                </executions>
 | 
			
		||||
            </plugin>
 | 
			
		||||
        </plugins>
 | 
			
		||||
    </build>
 | 
			
		||||
 | 
			
		||||
</project>
 | 
			
		||||
@@ -0,0 +1,25 @@
 | 
			
		||||
package org.dromara.powerjob;
 | 
			
		||||
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.boot.SpringApplication;
 | 
			
		||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
 | 
			
		||||
import org.springframework.scheduling.annotation.EnableScheduling;
 | 
			
		||||
import tech.powerjob.server.common.utils.PropertyUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * powerjob 启动程序
 | 
			
		||||
 *
 | 
			
		||||
 * @author yhan219
 | 
			
		||||
 */
 | 
			
		||||
@Slf4j
 | 
			
		||||
@EnableScheduling
 | 
			
		||||
@SpringBootApplication(scanBasePackages = "tech.powerjob.server")
 | 
			
		||||
public class PowerJobServerApplication {
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        PropertyUtils.init();
 | 
			
		||||
        SpringApplication.run(tech.powerjob.server.PowerJobServerApplication.class, args);
 | 
			
		||||
        log.info("文档地址: https://www.yuque.com/powerjob/guidence/problem");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,50 @@
 | 
			
		||||
oms.env=dev
 | 
			
		||||
 | 
			
		||||
####### Database properties(Configure according to the the environment) #######
 | 
			
		||||
spring.datasource.core.driver-class-name=com.mysql.cj.jdbc.Driver
 | 
			
		||||
spring.datasource.core.jdbc-url=jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
 | 
			
		||||
spring.datasource.core.username=root
 | 
			
		||||
spring.datasource.core.password=root
 | 
			
		||||
spring.datasource.core.maximum-pool-size=20
 | 
			
		||||
spring.datasource.core.minimum-idle=5
 | 
			
		||||
 | 
			
		||||
# 监控配置
 | 
			
		||||
# 客户端开关
 | 
			
		||||
spring.boot.admin.client.enabled=true
 | 
			
		||||
# 设置 Spring Boot Admin Server 地址
 | 
			
		||||
spring.boot.admin.client.url: http://localhost:9090/admin
 | 
			
		||||
spring.boot.admin.client.instance.service-host-type=IP
 | 
			
		||||
spring.boot.admin.client.username=ruoyi
 | 
			
		||||
spring.boot.admin.client.password=123456
 | 
			
		||||
 | 
			
		||||
####### MongoDB properties(Non-core configuration properties)  #######
 | 
			
		||||
####### delete mongodb config to disable mongodb #######
 | 
			
		||||
oms.mongodb.enable=false
 | 
			
		||||
#spring.data.mongodb.uri=mongodb+srv://zqq:No1Bug2Please3!@cluster0.wie54.gcp.mongodb.net/powerjob_daily?retryWrites=true&w=majority
 | 
			
		||||
 | 
			
		||||
####### Email properties(Non-core configuration properties) #######
 | 
			
		||||
####### Delete the following code to disable the mail #######
 | 
			
		||||
#spring.mail.host=smtp.163.com
 | 
			
		||||
#spring.mail.username=zqq@163.com
 | 
			
		||||
#spring.mail.password=GOFZPNARMVKCGONV
 | 
			
		||||
#spring.mail.properties.mail.smtp.auth=true
 | 
			
		||||
#spring.mail.properties.mail.smtp.starttls.enable=true
 | 
			
		||||
#spring.mail.properties.mail.smtp.starttls.required=true
 | 
			
		||||
 | 
			
		||||
####### DingTalk properties(Non-core configuration properties) #######
 | 
			
		||||
####### Delete the following code to disable the DingTalk #######
 | 
			
		||||
#oms.alarm.ding.app-key=dingauqwkvxxnqskknfv
 | 
			
		||||
#oms.alarm.ding.app-secret=XWrEPdAZMPgJeFtHuL0LH73LRj-74umF2_0BFcoXMfvnX0pCQvt0rpb1JOJU_HLl
 | 
			
		||||
#oms.alarm.ding.agent-id=847044348
 | 
			
		||||
 | 
			
		||||
####### Resource cleaning properties #######
 | 
			
		||||
oms.instanceinfo.retention=1
 | 
			
		||||
oms.container.retention.local=1
 | 
			
		||||
oms.container.retention.remote=-1
 | 
			
		||||
 | 
			
		||||
####### Cache properties #######
 | 
			
		||||
oms.instance.metadata.cache.size=1024
 | 
			
		||||
 | 
			
		||||
####### Threshold in precise fetching server(0~100). 100 means full detection of server, in which #######
 | 
			
		||||
####### split-brain could be avoided while performance overhead would increase. #######
 | 
			
		||||
oms.accurate.select.server.percentage = 50
 | 
			
		||||
@@ -0,0 +1,50 @@
 | 
			
		||||
oms.env=prod
 | 
			
		||||
 | 
			
		||||
####### Database properties(Configure according to the the environment) #######
 | 
			
		||||
spring.datasource.core.driver-class-name=com.mysql.cj.jdbc.Driver
 | 
			
		||||
spring.datasource.core.jdbc-url=jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
 | 
			
		||||
spring.datasource.core.username=root
 | 
			
		||||
spring.datasource.core.password=root
 | 
			
		||||
spring.datasource.core.maximum-pool-size=20
 | 
			
		||||
spring.datasource.core.minimum-idle=5
 | 
			
		||||
 | 
			
		||||
# 监控配置
 | 
			
		||||
# 客户端开关
 | 
			
		||||
spring.boot.admin.client.enabled=true
 | 
			
		||||
# 设置 Spring Boot Admin Server 地址
 | 
			
		||||
spring.boot.admin.client.url: http://localhost:9090/admin
 | 
			
		||||
spring.boot.admin.client.instance.service-host-type=IP
 | 
			
		||||
spring.boot.admin.client.username=ruoyi
 | 
			
		||||
spring.boot.admin.client.password=123456
 | 
			
		||||
 | 
			
		||||
####### MongoDB properties(Non-core configuration properties)  #######
 | 
			
		||||
####### delete mongodb config to disable mongodb #######
 | 
			
		||||
oms.mongodb.enable=false
 | 
			
		||||
#spring.data.mongodb.uri=mongodb+srv://zqq:No1Bug2Please3!@cluster0.wie54.gcp.mongodb.net/powerjob_daily?retryWrites=true&w=majority
 | 
			
		||||
 | 
			
		||||
####### Email properties(Non-core configuration properties) #######
 | 
			
		||||
####### Delete the following code to disable the mail #######
 | 
			
		||||
#spring.mail.host=smtp.163.com
 | 
			
		||||
#spring.mail.username=zqq@163.com
 | 
			
		||||
#spring.mail.password=GOFZPNARMVKCGONV
 | 
			
		||||
#spring.mail.properties.mail.smtp.auth=true
 | 
			
		||||
#spring.mail.properties.mail.smtp.starttls.enable=true
 | 
			
		||||
#spring.mail.properties.mail.smtp.starttls.required=true
 | 
			
		||||
 | 
			
		||||
####### DingTalk properties(Non-core configuration properties) #######
 | 
			
		||||
####### Delete the following code to disable the DingTalk #######
 | 
			
		||||
#oms.alarm.ding.app-key=dingauqwkvxxnqskknfv
 | 
			
		||||
#oms.alarm.ding.app-secret=XWrEPdAZMPgJeFtHuL0LH73LRj-74umF2_0BFcoXMfvnX0pCQvt0rpb1JOJU_HLl
 | 
			
		||||
#oms.alarm.ding.agent-id=847044348
 | 
			
		||||
 | 
			
		||||
####### Resource cleaning properties #######
 | 
			
		||||
oms.instanceinfo.retention=7
 | 
			
		||||
oms.container.retention.local=7
 | 
			
		||||
oms.container.retention.remote=-1
 | 
			
		||||
 | 
			
		||||
####### Cache properties #######
 | 
			
		||||
oms.instance.metadata.cache.size=2048
 | 
			
		||||
 | 
			
		||||
####### Threshold in precise fetching server(0~100). 100 means full detection of server, in which #######
 | 
			
		||||
####### split-brain could be avoided while performance overhead would increase. #######
 | 
			
		||||
oms.accurate.select.server.percentage = 50
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
# Http server port
 | 
			
		||||
server.port=7700
 | 
			
		||||
 | 
			
		||||
spring.profiles.active=@profiles.active@
 | 
			
		||||
spring.main.banner-mode=log
 | 
			
		||||
spring.jpa.open-in-view=false
 | 
			
		||||
spring.data.mongodb.repositories.type=none
 | 
			
		||||
logging.level.org.mongodb=warn
 | 
			
		||||
logging.config: classpath:logback-plus.xml
 | 
			
		||||
 | 
			
		||||
# Configuration for uploading files.
 | 
			
		||||
spring.servlet.multipart.enabled=true
 | 
			
		||||
spring.servlet.multipart.file-size-threshold=0
 | 
			
		||||
spring.servlet.multipart.max-file-size=209715200
 | 
			
		||||
spring.servlet.multipart.max-request-size=209715200
 | 
			
		||||
 | 
			
		||||
###### PowerJob transporter configuration  ######
 | 
			
		||||
oms.transporter.active.protocols=AKKA,HTTP
 | 
			
		||||
oms.transporter.main.protocol=HTTP
 | 
			
		||||
oms.akka.port=10086
 | 
			
		||||
oms.http.port=10010
 | 
			
		||||
# Prefix for all tables. Default empty string. Config if you have needs, i.e. pj_
 | 
			
		||||
oms.table-prefix=pj_
 | 
			
		||||
 | 
			
		||||
# Actuator 监控端点的配置项
 | 
			
		||||
spring.application.name: ruoyi-powerjob-server
 | 
			
		||||
management.endpoints.web.exposure.include=*
 | 
			
		||||
management.endpoint.health.show-details=ALWAYS
 | 
			
		||||
management.endpoint.logfile.external-file=./logs/ruoyi-powerjob-server.log
 | 
			
		||||
management.health.mongo.enabled=${oms.mongodb.enable}
 | 
			
		||||
@@ -0,0 +1,11 @@
 | 
			
		||||
Application Version: ${revision}
 | 
			
		||||
Spring Boot Version: ${spring-boot.version}
 | 
			
		||||
                              _       _
 | 
			
		||||
                             (_)     | |
 | 
			
		||||
 _ __   _____      _____ _ __ _  ___ | |__ ______ ___  ___ _ ____   _____ _ __
 | 
			
		||||
| '_ \ / _ \ \ /\ / / _ \ '__| |/ _ \| '_ \______/ __|/ _ \ '__\ \ / / _ \ '__|
 | 
			
		||||
| |_) | (_) \ V  V /  __/ |  | | (_) | |_) |     \__ \  __/ |   \ V /  __/ |
 | 
			
		||||
| .__/ \___/ \_/\_/ \___|_|  | |\___/|_.__/      |___/\___|_|    \_/ \___|_|
 | 
			
		||||
| |                         _/ |
 | 
			
		||||
|_|                        |__/
 | 
			
		||||
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
<configuration debug="false" scan="true" scanPeriod="1 seconds">
 | 
			
		||||
 | 
			
		||||
    <contextName>logback</contextName>
 | 
			
		||||
    <property name="log.path" value="./logs/ruoyi-xxl-job-admin"/>
 | 
			
		||||
    <property name="log.path" value="./logs/ruoyi-powerjob-server"/>
 | 
			
		||||
    <property name="console.log.pattern"
 | 
			
		||||
              value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
 | 
			
		||||
    <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/>
 | 
			
		||||
@@ -31,4 +31,4 @@
 | 
			
		||||
        <appender-ref ref="file"/>
 | 
			
		||||
    </root>
 | 
			
		||||
 | 
			
		||||
</configuration>
 | 
			
		||||
</configuration>
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
FROM findepi/graalvm:java17-native
 | 
			
		||||
 | 
			
		||||
MAINTAINER Lion Li
 | 
			
		||||
 | 
			
		||||
RUN mkdir -p /ruoyi/xxljob/logs
 | 
			
		||||
 | 
			
		||||
WORKDIR /ruoyi/xxljob
 | 
			
		||||
 | 
			
		||||
ENV TZ=PRC
 | 
			
		||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
 | 
			
		||||
 | 
			
		||||
EXPOSE 9100
 | 
			
		||||
 | 
			
		||||
ADD ./target/ruoyi-xxl-job-admin.jar ./app.jar
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
 | 
			
		||||
@@ -1,111 +0,0 @@
 | 
			
		||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 | 
			
		||||
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <artifactId>ruoyi-extend</artifactId>
 | 
			
		||||
        <groupId>org.dromara</groupId>
 | 
			
		||||
        <version>${revision}</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
    <artifactId>ruoyi-xxl-job-admin</artifactId>
 | 
			
		||||
    <packaging>jar</packaging>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <spring-boot.version>2.7.12</spring-boot.version>
 | 
			
		||||
        <spring-boot-admin.version>2.7.10</spring-boot-admin.version>
 | 
			
		||||
        <mybatis-spring-boot.version>2.2.2</mybatis-spring-boot.version>
 | 
			
		||||
    </properties>
 | 
			
		||||
 | 
			
		||||
    <dependencyManagement>
 | 
			
		||||
        <dependencies>
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>org.springframework.boot</groupId>
 | 
			
		||||
                <artifactId>spring-boot-starter-parent</artifactId>
 | 
			
		||||
                <version>${spring-boot.version}</version>
 | 
			
		||||
                <type>pom</type>
 | 
			
		||||
                <scope>import</scope>
 | 
			
		||||
            </dependency>
 | 
			
		||||
        </dependencies>
 | 
			
		||||
    </dependencyManagement>
 | 
			
		||||
 | 
			
		||||
    <dependencies>
 | 
			
		||||
 | 
			
		||||
        <!-- starter-web:spring-webmvc + autoconfigure + logback + yaml + tomcat -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.springframework.boot</groupId>
 | 
			
		||||
            <artifactId>spring-boot-starter-web</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <!-- starter-test:junit + spring-test + mockito -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.springframework.boot</groupId>
 | 
			
		||||
            <artifactId>spring-boot-starter-test</artifactId>
 | 
			
		||||
            <scope>test</scope>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <!-- freemarker-starter -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.springframework.boot</groupId>
 | 
			
		||||
            <artifactId>spring-boot-starter-freemarker</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <!-- mail-starter -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.springframework.boot</groupId>
 | 
			
		||||
            <artifactId>spring-boot-starter-mail</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <!-- starter-actuator -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.springframework.boot</groupId>
 | 
			
		||||
            <artifactId>spring-boot-starter-actuator</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.springframework.boot</groupId>
 | 
			
		||||
            <artifactId>spring-boot-starter-aop</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <!-- mybatis-starter:mybatis + mybatis-spring + hikari(default) -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.mybatis.spring.boot</groupId>
 | 
			
		||||
            <artifactId>mybatis-spring-boot-starter</artifactId>
 | 
			
		||||
            <version>${mybatis-spring-boot.version}</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <!-- mysql -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>com.mysql</groupId>
 | 
			
		||||
            <artifactId>mysql-connector-j</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>de.codecentric</groupId>
 | 
			
		||||
            <artifactId>spring-boot-admin-starter-client</artifactId>
 | 
			
		||||
            <version>${spring-boot-admin.version}</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <!-- xxl-job-core -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>com.xuxueli</groupId>
 | 
			
		||||
            <artifactId>xxl-job-core</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
    </dependencies>
 | 
			
		||||
 | 
			
		||||
    <build>
 | 
			
		||||
        <finalName>${project.artifactId}</finalName>
 | 
			
		||||
        <plugins>
 | 
			
		||||
            <plugin>
 | 
			
		||||
                <groupId>org.springframework.boot</groupId>
 | 
			
		||||
                <artifactId>spring-boot-maven-plugin</artifactId>
 | 
			
		||||
                <version>${spring-boot.version}</version>
 | 
			
		||||
                <executions>
 | 
			
		||||
                    <execution>
 | 
			
		||||
                        <goals>
 | 
			
		||||
                            <goal>repackage</goal>
 | 
			
		||||
                        </goals>
 | 
			
		||||
                    </execution>
 | 
			
		||||
                </executions>
 | 
			
		||||
            </plugin>
 | 
			
		||||
        </plugins>
 | 
			
		||||
    </build>
 | 
			
		||||
 | 
			
		||||
</project>
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.SpringApplication;
 | 
			
		||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2018-10-28 00:38:13
 | 
			
		||||
 */
 | 
			
		||||
@SpringBootApplication
 | 
			
		||||
public class XxlJobAdminApplication {
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        SpringApplication.run(XxlJobAdminApplication.class, args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,97 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.controller.annotation.PermissionLimit;
 | 
			
		||||
import com.xxl.job.admin.service.LoginService;
 | 
			
		||||
import com.xxl.job.admin.service.XxlJobService;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import org.springframework.beans.propertyeditors.CustomDateEditor;
 | 
			
		||||
import org.springframework.stereotype.Controller;
 | 
			
		||||
import org.springframework.ui.Model;
 | 
			
		||||
import org.springframework.web.bind.WebDataBinder;
 | 
			
		||||
import org.springframework.web.bind.annotation.InitBinder;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMethod;
 | 
			
		||||
import org.springframework.web.bind.annotation.ResponseBody;
 | 
			
		||||
import org.springframework.web.servlet.ModelAndView;
 | 
			
		||||
import org.springframework.web.servlet.view.RedirectView;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * index controller
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2015-12-19 16:13:16
 | 
			
		||||
 */
 | 
			
		||||
@Controller
 | 
			
		||||
public class IndexController {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobService xxlJobService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private LoginService loginService;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/")
 | 
			
		||||
    public String index(Model model) {
 | 
			
		||||
 | 
			
		||||
        Map<String, Object> dashboardMap = xxlJobService.dashboardInfo();
 | 
			
		||||
        model.addAllAttributes(dashboardMap);
 | 
			
		||||
 | 
			
		||||
        return "index";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/chartInfo")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<Map<String, Object>> chartInfo(Date startDate, Date endDate) {
 | 
			
		||||
        ReturnT<Map<String, Object>> chartInfo = xxlJobService.chartInfo(startDate, endDate);
 | 
			
		||||
        return chartInfo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/toLogin")
 | 
			
		||||
    @PermissionLimit(limit = false)
 | 
			
		||||
    public ModelAndView toLogin(HttpServletRequest request, HttpServletResponse response, ModelAndView modelAndView) {
 | 
			
		||||
        if (loginService.ifLogin(request, response) != null) {
 | 
			
		||||
            modelAndView.setView(new RedirectView("/", true, false));
 | 
			
		||||
            return modelAndView;
 | 
			
		||||
        }
 | 
			
		||||
        return new ModelAndView("login");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping(value = "login", method = RequestMethod.POST)
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(limit = false)
 | 
			
		||||
    public ReturnT<String> loginDo(HttpServletRequest request, HttpServletResponse response, String userName, String password, String ifRemember) {
 | 
			
		||||
        boolean ifRem = (ifRemember != null && ifRemember.trim().length() > 0 && "on".equals(ifRemember)) ? true : false;
 | 
			
		||||
        return loginService.login(request, response, userName, password, ifRem);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping(value = "logout", method = RequestMethod.POST)
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(limit = false)
 | 
			
		||||
    public ReturnT<String> logout(HttpServletRequest request, HttpServletResponse response) {
 | 
			
		||||
        return loginService.logout(request, response);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/help")
 | 
			
		||||
    public String help() {
 | 
			
		||||
 | 
			
		||||
        /*if (!PermissionInterceptor.ifLogin(request)) {
 | 
			
		||||
            return "redirect:/toLogin";
 | 
			
		||||
        }*/
 | 
			
		||||
 | 
			
		||||
        return "help";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @InitBinder
 | 
			
		||||
    public void initBinder(WebDataBinder binder) {
 | 
			
		||||
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 | 
			
		||||
        dateFormat.setLenient(false);
 | 
			
		||||
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,72 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.controller.annotation.PermissionLimit;
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
import com.xxl.job.core.biz.AdminBiz;
 | 
			
		||||
import com.xxl.job.core.biz.model.HandleCallbackParam;
 | 
			
		||||
import com.xxl.job.core.biz.model.RegistryParam;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.util.GsonTool;
 | 
			
		||||
import com.xxl.job.core.util.XxlJobRemotingUtil;
 | 
			
		||||
import org.springframework.stereotype.Controller;
 | 
			
		||||
import org.springframework.web.bind.annotation.PathVariable;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestBody;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.ResponseBody;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by xuxueli on 17/5/10.
 | 
			
		||||
 */
 | 
			
		||||
@Controller
 | 
			
		||||
@RequestMapping("/api")
 | 
			
		||||
public class JobApiController {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private AdminBiz adminBiz;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * api
 | 
			
		||||
     *
 | 
			
		||||
     * @param uri
 | 
			
		||||
     * @param data
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    @RequestMapping("/{uri}")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(limit = false)
 | 
			
		||||
    public ReturnT<String> api(HttpServletRequest request, @PathVariable("uri") String uri, @RequestBody(required = false) String data) {
 | 
			
		||||
 | 
			
		||||
        // valid
 | 
			
		||||
        if (!"POST".equalsIgnoreCase(request.getMethod())) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, "invalid request, HttpMethod not support.");
 | 
			
		||||
        }
 | 
			
		||||
        if (uri == null || uri.trim().length() == 0) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, "invalid request, uri-mapping empty.");
 | 
			
		||||
        }
 | 
			
		||||
        if (XxlJobAdminConfig.getAdminConfig().getAccessToken() != null
 | 
			
		||||
            && XxlJobAdminConfig.getAdminConfig().getAccessToken().trim().length() > 0
 | 
			
		||||
            && !XxlJobAdminConfig.getAdminConfig().getAccessToken().equals(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, "The access token is wrong.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // services mapping
 | 
			
		||||
        if ("callback".equals(uri)) {
 | 
			
		||||
            List<HandleCallbackParam> callbackParamList = GsonTool.fromJson(data, List.class, HandleCallbackParam.class);
 | 
			
		||||
            return adminBiz.callback(callbackParamList);
 | 
			
		||||
        } else if ("registry".equals(uri)) {
 | 
			
		||||
            RegistryParam registryParam = GsonTool.fromJson(data, RegistryParam.class);
 | 
			
		||||
            return adminBiz.registry(registryParam);
 | 
			
		||||
        } else if ("registryRemove".equals(uri)) {
 | 
			
		||||
            RegistryParam registryParam = GsonTool.fromJson(data, RegistryParam.class);
 | 
			
		||||
            return adminBiz.registryRemove(registryParam);
 | 
			
		||||
        } else {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, "invalid request, uri-mapping(" + uri + ") not found.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,97 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLogGlue;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobInfoDao;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobLogGlueDao;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.glue.GlueTypeEnum;
 | 
			
		||||
import org.springframework.stereotype.Controller;
 | 
			
		||||
import org.springframework.ui.Model;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.ResponseBody;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * job code controller
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2015-12-19 16:13:16
 | 
			
		||||
 */
 | 
			
		||||
@Controller
 | 
			
		||||
@RequestMapping("/jobcode")
 | 
			
		||||
public class JobCodeController {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobInfoDao xxlJobInfoDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobLogGlueDao xxlJobLogGlueDao;
 | 
			
		||||
 | 
			
		||||
    @RequestMapping
 | 
			
		||||
    public String index(HttpServletRequest request, Model model, int jobId) {
 | 
			
		||||
        XxlJobInfo jobInfo = xxlJobInfoDao.loadById(jobId);
 | 
			
		||||
        List<XxlJobLogGlue> jobLogGlues = xxlJobLogGlueDao.findByJobId(jobId);
 | 
			
		||||
 | 
			
		||||
        if (jobInfo == null) {
 | 
			
		||||
            throw new RuntimeException(I18nUtil.getString("jobinfo_glue_jobid_unvalid"));
 | 
			
		||||
        }
 | 
			
		||||
        if (GlueTypeEnum.BEAN == GlueTypeEnum.match(jobInfo.getGlueType())) {
 | 
			
		||||
            throw new RuntimeException(I18nUtil.getString("jobinfo_glue_gluetype_unvalid"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // valid permission
 | 
			
		||||
        JobInfoController.validPermission(request, jobInfo.getJobGroup());
 | 
			
		||||
 | 
			
		||||
        // Glue类型-字典
 | 
			
		||||
        model.addAttribute("GlueTypeEnum", GlueTypeEnum.values());
 | 
			
		||||
 | 
			
		||||
        model.addAttribute("jobInfo", jobInfo);
 | 
			
		||||
        model.addAttribute("jobLogGlues", jobLogGlues);
 | 
			
		||||
        return "jobcode/jobcode.index";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/save")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<String> save(Model model, int id, String glueSource, String glueRemark) {
 | 
			
		||||
        // valid
 | 
			
		||||
        if (glueRemark == null) {
 | 
			
		||||
            return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_glue_remark")));
 | 
			
		||||
        }
 | 
			
		||||
        if (glueRemark.length() < 4 || glueRemark.length() > 100) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("jobinfo_glue_remark_limit"));
 | 
			
		||||
        }
 | 
			
		||||
        XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(id);
 | 
			
		||||
        if (exists_jobInfo == null) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("jobinfo_glue_jobid_unvalid"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // update new code
 | 
			
		||||
        exists_jobInfo.setGlueSource(glueSource);
 | 
			
		||||
        exists_jobInfo.setGlueRemark(glueRemark);
 | 
			
		||||
        exists_jobInfo.setGlueUpdatetime(new Date());
 | 
			
		||||
 | 
			
		||||
        exists_jobInfo.setUpdateTime(new Date());
 | 
			
		||||
        xxlJobInfoDao.update(exists_jobInfo);
 | 
			
		||||
 | 
			
		||||
        // log old code
 | 
			
		||||
        XxlJobLogGlue xxlJobLogGlue = new XxlJobLogGlue();
 | 
			
		||||
        xxlJobLogGlue.setJobId(exists_jobInfo.getId());
 | 
			
		||||
        xxlJobLogGlue.setGlueType(exists_jobInfo.getGlueType());
 | 
			
		||||
        xxlJobLogGlue.setGlueSource(glueSource);
 | 
			
		||||
        xxlJobLogGlue.setGlueRemark(glueRemark);
 | 
			
		||||
 | 
			
		||||
        xxlJobLogGlue.setAddTime(new Date());
 | 
			
		||||
        xxlJobLogGlue.setUpdateTime(new Date());
 | 
			
		||||
        xxlJobLogGlueDao.save(xxlJobLogGlue);
 | 
			
		||||
 | 
			
		||||
        // remove code backup more than 30
 | 
			
		||||
        xxlJobLogGlueDao.removeOld(exists_jobInfo.getId(), 30);
 | 
			
		||||
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,205 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.controller.annotation.PermissionLimit;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobGroup;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobRegistry;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobGroupDao;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobInfoDao;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobRegistryDao;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.enums.RegistryConfig;
 | 
			
		||||
import org.springframework.stereotype.Controller;
 | 
			
		||||
import org.springframework.ui.Model;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestParam;
 | 
			
		||||
import org.springframework.web.bind.annotation.ResponseBody;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * job group controller
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2016-10-02 20:52:56
 | 
			
		||||
 */
 | 
			
		||||
@Controller
 | 
			
		||||
@RequestMapping("/jobgroup")
 | 
			
		||||
public class JobGroupController {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    public XxlJobInfoDao xxlJobInfoDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    public XxlJobGroupDao xxlJobGroupDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobRegistryDao xxlJobRegistryDao;
 | 
			
		||||
 | 
			
		||||
    @RequestMapping
 | 
			
		||||
    @PermissionLimit(adminuser = true)
 | 
			
		||||
    public String index(Model model) {
 | 
			
		||||
        return "jobgroup/jobgroup.index";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/pageList")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(adminuser = true)
 | 
			
		||||
    public Map<String, Object> pageList(HttpServletRequest request,
 | 
			
		||||
                                        @RequestParam(required = false, defaultValue = "0") int start,
 | 
			
		||||
                                        @RequestParam(required = false, defaultValue = "10") int length,
 | 
			
		||||
                                        String appname, String title) {
 | 
			
		||||
 | 
			
		||||
        // page query
 | 
			
		||||
        List<XxlJobGroup> list = xxlJobGroupDao.pageList(start, length, appname, title);
 | 
			
		||||
        int list_count = xxlJobGroupDao.pageListCount(start, length, appname, title);
 | 
			
		||||
 | 
			
		||||
        // package result
 | 
			
		||||
        Map<String, Object> maps = new HashMap<String, Object>();
 | 
			
		||||
        maps.put("recordsTotal", list_count);        // 总记录数
 | 
			
		||||
        maps.put("recordsFiltered", list_count);    // 过滤后的总记录数
 | 
			
		||||
        maps.put("data", list);                    // 分页列表
 | 
			
		||||
        return maps;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/save")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(adminuser = true)
 | 
			
		||||
    public ReturnT<String> save(XxlJobGroup xxlJobGroup) {
 | 
			
		||||
 | 
			
		||||
        // valid
 | 
			
		||||
        if (xxlJobGroup.getAppname() == null || xxlJobGroup.getAppname().trim().length() == 0) {
 | 
			
		||||
            return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + "AppName"));
 | 
			
		||||
        }
 | 
			
		||||
        if (xxlJobGroup.getAppname().length() < 4 || xxlJobGroup.getAppname().length() > 64) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_appname_length"));
 | 
			
		||||
        }
 | 
			
		||||
        if (xxlJobGroup.getAppname().contains(">") || xxlJobGroup.getAppname().contains("<")) {
 | 
			
		||||
            return new ReturnT<String>(500, "AppName" + I18nUtil.getString("system_unvalid"));
 | 
			
		||||
        }
 | 
			
		||||
        if (xxlJobGroup.getTitle() == null || xxlJobGroup.getTitle().trim().length() == 0) {
 | 
			
		||||
            return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")));
 | 
			
		||||
        }
 | 
			
		||||
        if (xxlJobGroup.getTitle().contains(">") || xxlJobGroup.getTitle().contains("<")) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_title") + I18nUtil.getString("system_unvalid"));
 | 
			
		||||
        }
 | 
			
		||||
        if (xxlJobGroup.getAddressType() != 0) {
 | 
			
		||||
            if (xxlJobGroup.getAddressList() == null || xxlJobGroup.getAddressList().trim().length() == 0) {
 | 
			
		||||
                return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_addressType_limit"));
 | 
			
		||||
            }
 | 
			
		||||
            if (xxlJobGroup.getAddressList().contains(">") || xxlJobGroup.getAddressList().contains("<")) {
 | 
			
		||||
                return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_registryList") + I18nUtil.getString("system_unvalid"));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            String[] addresss = xxlJobGroup.getAddressList().split(",");
 | 
			
		||||
            for (String item : addresss) {
 | 
			
		||||
                if (item == null || item.trim().length() == 0) {
 | 
			
		||||
                    return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_registryList_unvalid"));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // process
 | 
			
		||||
        xxlJobGroup.setUpdateTime(new Date());
 | 
			
		||||
 | 
			
		||||
        int ret = xxlJobGroupDao.save(xxlJobGroup);
 | 
			
		||||
        return (ret > 0) ? ReturnT.SUCCESS : ReturnT.FAIL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/update")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(adminuser = true)
 | 
			
		||||
    public ReturnT<String> update(XxlJobGroup xxlJobGroup) {
 | 
			
		||||
        // valid
 | 
			
		||||
        if (xxlJobGroup.getAppname() == null || xxlJobGroup.getAppname().trim().length() == 0) {
 | 
			
		||||
            return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + "AppName"));
 | 
			
		||||
        }
 | 
			
		||||
        if (xxlJobGroup.getAppname().length() < 4 || xxlJobGroup.getAppname().length() > 64) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_appname_length"));
 | 
			
		||||
        }
 | 
			
		||||
        if (xxlJobGroup.getTitle() == null || xxlJobGroup.getTitle().trim().length() == 0) {
 | 
			
		||||
            return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")));
 | 
			
		||||
        }
 | 
			
		||||
        if (xxlJobGroup.getAddressType() == 0) {
 | 
			
		||||
            // 0=自动注册
 | 
			
		||||
            List<String> registryList = findRegistryByAppName(xxlJobGroup.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);
 | 
			
		||||
            }
 | 
			
		||||
            xxlJobGroup.setAddressList(addressListStr);
 | 
			
		||||
        } else {
 | 
			
		||||
            // 1=手动录入
 | 
			
		||||
            if (xxlJobGroup.getAddressList() == null || xxlJobGroup.getAddressList().trim().length() == 0) {
 | 
			
		||||
                return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_addressType_limit"));
 | 
			
		||||
            }
 | 
			
		||||
            String[] addresss = xxlJobGroup.getAddressList().split(",");
 | 
			
		||||
            for (String item : addresss) {
 | 
			
		||||
                if (item == null || item.trim().length() == 0) {
 | 
			
		||||
                    return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_registryList_unvalid"));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // process
 | 
			
		||||
        xxlJobGroup.setUpdateTime(new Date());
 | 
			
		||||
 | 
			
		||||
        int ret = xxlJobGroupDao.update(xxlJobGroup);
 | 
			
		||||
        return (ret > 0) ? ReturnT.SUCCESS : ReturnT.FAIL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private List<String> findRegistryByAppName(String appnameParam) {
 | 
			
		||||
        HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
 | 
			
		||||
        List<XxlJobRegistry> list = xxlJobRegistryDao.findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
 | 
			
		||||
        if (list != null) {
 | 
			
		||||
            for (XxlJobRegistry item : list) {
 | 
			
		||||
                if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
 | 
			
		||||
                    String appname = item.getRegistryKey();
 | 
			
		||||
                    List<String> registryList = appAddressMap.get(appname);
 | 
			
		||||
                    if (registryList == null) {
 | 
			
		||||
                        registryList = new ArrayList<String>();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (!registryList.contains(item.getRegistryValue())) {
 | 
			
		||||
                        registryList.add(item.getRegistryValue());
 | 
			
		||||
                    }
 | 
			
		||||
                    appAddressMap.put(appname, registryList);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return appAddressMap.get(appnameParam);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/remove")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(adminuser = true)
 | 
			
		||||
    public ReturnT<String> remove(int id) {
 | 
			
		||||
 | 
			
		||||
        // valid
 | 
			
		||||
        int count = xxlJobInfoDao.pageListCount(0, 10, id, -1, null, null, null);
 | 
			
		||||
        if (count > 0) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("jobgroup_del_limit_0"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<XxlJobGroup> allList = xxlJobGroupDao.findAll();
 | 
			
		||||
        if (allList.size() == 1) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("jobgroup_del_limit_1"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int ret = xxlJobGroupDao.remove(id);
 | 
			
		||||
        return (ret > 0) ? ReturnT.SUCCESS : ReturnT.FAIL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/loadById")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(adminuser = true)
 | 
			
		||||
    public ReturnT<XxlJobGroup> loadById(int id) {
 | 
			
		||||
        XxlJobGroup jobGroup = xxlJobGroupDao.load(id);
 | 
			
		||||
        return jobGroup != null ? new ReturnT<XxlJobGroup>(jobGroup) : new ReturnT<XxlJobGroup>(ReturnT.FAIL_CODE, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,180 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.exception.XxlJobException;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobGroup;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobUser;
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
 | 
			
		||||
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
 | 
			
		||||
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
 | 
			
		||||
import com.xxl.job.admin.core.thread.JobScheduleHelper;
 | 
			
		||||
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
 | 
			
		||||
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobGroupDao;
 | 
			
		||||
import com.xxl.job.admin.service.LoginService;
 | 
			
		||||
import com.xxl.job.admin.service.XxlJobService;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
 | 
			
		||||
import com.xxl.job.core.glue.GlueTypeEnum;
 | 
			
		||||
import com.xxl.job.core.util.DateUtil;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.stereotype.Controller;
 | 
			
		||||
import org.springframework.ui.Model;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestParam;
 | 
			
		||||
import org.springframework.web.bind.annotation.ResponseBody;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * index controller
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2015-12-19 16:13:16
 | 
			
		||||
 */
 | 
			
		||||
@Controller
 | 
			
		||||
@RequestMapping("/jobinfo")
 | 
			
		||||
public class JobInfoController {
 | 
			
		||||
    private static Logger logger = LoggerFactory.getLogger(JobInfoController.class);
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobGroupDao xxlJobGroupDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobService xxlJobService;
 | 
			
		||||
 | 
			
		||||
    @RequestMapping
 | 
			
		||||
    public String index(HttpServletRequest request, Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) {
 | 
			
		||||
 | 
			
		||||
        // 枚举-字典
 | 
			
		||||
        model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values());        // 路由策略-列表
 | 
			
		||||
        model.addAttribute("GlueTypeEnum", GlueTypeEnum.values());                                // Glue类型-字典
 | 
			
		||||
        model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values());        // 阻塞处理策略-字典
 | 
			
		||||
        model.addAttribute("ScheduleTypeEnum", ScheduleTypeEnum.values());                        // 调度类型
 | 
			
		||||
        model.addAttribute("MisfireStrategyEnum", MisfireStrategyEnum.values());                    // 调度过期策略
 | 
			
		||||
 | 
			
		||||
        // 执行器列表
 | 
			
		||||
        List<XxlJobGroup> jobGroupList_all = xxlJobGroupDao.findAll();
 | 
			
		||||
 | 
			
		||||
        // filter group
 | 
			
		||||
        List<XxlJobGroup> jobGroupList = filterJobGroupByRole(request, jobGroupList_all);
 | 
			
		||||
        if (jobGroupList == null || jobGroupList.size() == 0) {
 | 
			
		||||
            throw new XxlJobException(I18nUtil.getString("jobgroup_empty"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        model.addAttribute("JobGroupList", jobGroupList);
 | 
			
		||||
        model.addAttribute("jobGroup", jobGroup);
 | 
			
		||||
 | 
			
		||||
        return "jobinfo/jobinfo.index";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static List<XxlJobGroup> filterJobGroupByRole(HttpServletRequest request, List<XxlJobGroup> jobGroupList_all) {
 | 
			
		||||
        List<XxlJobGroup> jobGroupList = new ArrayList<>();
 | 
			
		||||
        if (jobGroupList_all != null && jobGroupList_all.size() > 0) {
 | 
			
		||||
            XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
 | 
			
		||||
            if (loginUser.getRole() == 1) {
 | 
			
		||||
                jobGroupList = jobGroupList_all;
 | 
			
		||||
            } else {
 | 
			
		||||
                List<String> groupIdStrs = new ArrayList<>();
 | 
			
		||||
                if (loginUser.getPermission() != null && loginUser.getPermission().trim().length() > 0) {
 | 
			
		||||
                    groupIdStrs = Arrays.asList(loginUser.getPermission().trim().split(","));
 | 
			
		||||
                }
 | 
			
		||||
                for (XxlJobGroup groupItem : jobGroupList_all) {
 | 
			
		||||
                    if (groupIdStrs.contains(String.valueOf(groupItem.getId()))) {
 | 
			
		||||
                        jobGroupList.add(groupItem);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return jobGroupList;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void validPermission(HttpServletRequest request, int jobGroup) {
 | 
			
		||||
        XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
 | 
			
		||||
        if (!loginUser.validPermission(jobGroup)) {
 | 
			
		||||
            throw new RuntimeException(I18nUtil.getString("system_permission_limit") + "[username=" + loginUser.getUsername() + "]");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/pageList")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,
 | 
			
		||||
                                        @RequestParam(required = false, defaultValue = "10") int length,
 | 
			
		||||
                                        int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author) {
 | 
			
		||||
 | 
			
		||||
        return xxlJobService.pageList(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/add")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<String> add(XxlJobInfo jobInfo) {
 | 
			
		||||
        return xxlJobService.add(jobInfo);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/update")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<String> update(XxlJobInfo jobInfo) {
 | 
			
		||||
        return xxlJobService.update(jobInfo);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/remove")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<String> remove(int id) {
 | 
			
		||||
        return xxlJobService.remove(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/stop")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<String> pause(int id) {
 | 
			
		||||
        return xxlJobService.stop(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/start")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<String> start(int id) {
 | 
			
		||||
        return xxlJobService.start(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/trigger")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    //@PermissionLimit(limit = false)
 | 
			
		||||
    public ReturnT<String> triggerJob(int id, String executorParam, String addressList) {
 | 
			
		||||
        // force cover job param
 | 
			
		||||
        if (executorParam == null) {
 | 
			
		||||
            executorParam = "";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null, executorParam, addressList);
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/nextTriggerTime")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<List<String>> nextTriggerTime(String scheduleType, String scheduleConf) {
 | 
			
		||||
 | 
			
		||||
        XxlJobInfo paramXxlJobInfo = new XxlJobInfo();
 | 
			
		||||
        paramXxlJobInfo.setScheduleType(scheduleType);
 | 
			
		||||
        paramXxlJobInfo.setScheduleConf(scheduleConf);
 | 
			
		||||
 | 
			
		||||
        List<String> result = new ArrayList<>();
 | 
			
		||||
        try {
 | 
			
		||||
            Date lastTime = new Date();
 | 
			
		||||
            for (int i = 0; i < 5; i++) {
 | 
			
		||||
                lastTime = JobScheduleHelper.generateNextValidTime(paramXxlJobInfo, lastTime);
 | 
			
		||||
                if (lastTime != null) {
 | 
			
		||||
                    result.add(DateUtil.formatDateTime(lastTime));
 | 
			
		||||
                } else {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error(e.getMessage(), e);
 | 
			
		||||
            return new ReturnT<List<String>>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")) + e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
        return new ReturnT<List<String>>(result);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,238 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.exception.XxlJobException;
 | 
			
		||||
import com.xxl.job.admin.core.complete.XxlJobCompleter;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobGroup;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLog;
 | 
			
		||||
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobGroupDao;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobInfoDao;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobLogDao;
 | 
			
		||||
import com.xxl.job.core.biz.ExecutorBiz;
 | 
			
		||||
import com.xxl.job.core.biz.model.KillParam;
 | 
			
		||||
import com.xxl.job.core.biz.model.LogParam;
 | 
			
		||||
import com.xxl.job.core.biz.model.LogResult;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.util.DateUtil;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.stereotype.Controller;
 | 
			
		||||
import org.springframework.ui.Model;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestParam;
 | 
			
		||||
import org.springframework.web.bind.annotation.ResponseBody;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * index controller
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2015-12-19 16:13:16
 | 
			
		||||
 */
 | 
			
		||||
@Controller
 | 
			
		||||
@RequestMapping("/joblog")
 | 
			
		||||
public class JobLogController {
 | 
			
		||||
    private static Logger logger = LoggerFactory.getLogger(JobLogController.class);
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobGroupDao xxlJobGroupDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    public XxlJobInfoDao xxlJobInfoDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    public XxlJobLogDao xxlJobLogDao;
 | 
			
		||||
 | 
			
		||||
    @RequestMapping
 | 
			
		||||
    public String index(HttpServletRequest request, Model model, @RequestParam(required = false, defaultValue = "0") Integer jobId) {
 | 
			
		||||
 | 
			
		||||
        // 执行器列表
 | 
			
		||||
        List<XxlJobGroup> jobGroupList_all = xxlJobGroupDao.findAll();
 | 
			
		||||
 | 
			
		||||
        // filter group
 | 
			
		||||
        List<XxlJobGroup> jobGroupList = JobInfoController.filterJobGroupByRole(request, jobGroupList_all);
 | 
			
		||||
        if (jobGroupList == null || jobGroupList.size() == 0) {
 | 
			
		||||
            throw new XxlJobException(I18nUtil.getString("jobgroup_empty"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        model.addAttribute("JobGroupList", jobGroupList);
 | 
			
		||||
 | 
			
		||||
        // 任务
 | 
			
		||||
        if (jobId > 0) {
 | 
			
		||||
            XxlJobInfo jobInfo = xxlJobInfoDao.loadById(jobId);
 | 
			
		||||
            if (jobInfo == null) {
 | 
			
		||||
                throw new RuntimeException(I18nUtil.getString("jobinfo_field_id") + I18nUtil.getString("system_unvalid"));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            model.addAttribute("jobInfo", jobInfo);
 | 
			
		||||
 | 
			
		||||
            // valid permission
 | 
			
		||||
            JobInfoController.validPermission(request, jobInfo.getJobGroup());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return "joblog/joblog.index";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/getJobsByGroup")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<List<XxlJobInfo>> getJobsByGroup(int jobGroup) {
 | 
			
		||||
        List<XxlJobInfo> list = xxlJobInfoDao.getJobsByGroup(jobGroup);
 | 
			
		||||
        return new ReturnT<List<XxlJobInfo>>(list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/pageList")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public Map<String, Object> pageList(HttpServletRequest request,
 | 
			
		||||
                                        @RequestParam(required = false, defaultValue = "0") int start,
 | 
			
		||||
                                        @RequestParam(required = false, defaultValue = "10") int length,
 | 
			
		||||
                                        int jobGroup, int jobId, int logStatus, String filterTime) {
 | 
			
		||||
 | 
			
		||||
        // valid permission
 | 
			
		||||
        JobInfoController.validPermission(request, jobGroup);    // 仅管理员支持查询全部;普通用户仅支持查询有权限的 jobGroup
 | 
			
		||||
 | 
			
		||||
        // parse param
 | 
			
		||||
        Date triggerTimeStart = null;
 | 
			
		||||
        Date triggerTimeEnd = null;
 | 
			
		||||
        if (filterTime != null && filterTime.trim().length() > 0) {
 | 
			
		||||
            String[] temp = filterTime.split(" - ");
 | 
			
		||||
            if (temp.length == 2) {
 | 
			
		||||
                triggerTimeStart = DateUtil.parseDateTime(temp[0]);
 | 
			
		||||
                triggerTimeEnd = DateUtil.parseDateTime(temp[1]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // page query
 | 
			
		||||
        List<XxlJobLog> list = xxlJobLogDao.pageList(start, length, jobGroup, jobId, triggerTimeStart, triggerTimeEnd, logStatus);
 | 
			
		||||
        int list_count = xxlJobLogDao.pageListCount(start, length, jobGroup, jobId, triggerTimeStart, triggerTimeEnd, logStatus);
 | 
			
		||||
 | 
			
		||||
        // package result
 | 
			
		||||
        Map<String, Object> maps = new HashMap<String, Object>();
 | 
			
		||||
        maps.put("recordsTotal", list_count);        // 总记录数
 | 
			
		||||
        maps.put("recordsFiltered", list_count);    // 过滤后的总记录数
 | 
			
		||||
        maps.put("data", list);                    // 分页列表
 | 
			
		||||
        return maps;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/logDetailPage")
 | 
			
		||||
    public String logDetailPage(int id, Model model) {
 | 
			
		||||
 | 
			
		||||
        // base check
 | 
			
		||||
        ReturnT<String> logStatue = ReturnT.SUCCESS;
 | 
			
		||||
        XxlJobLog jobLog = xxlJobLogDao.load(id);
 | 
			
		||||
        if (jobLog == null) {
 | 
			
		||||
            throw new RuntimeException(I18nUtil.getString("joblog_logid_unvalid"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        model.addAttribute("triggerCode", jobLog.getTriggerCode());
 | 
			
		||||
        model.addAttribute("handleCode", jobLog.getHandleCode());
 | 
			
		||||
        model.addAttribute("logId", jobLog.getId());
 | 
			
		||||
        return "joblog/joblog.detail";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/logDetailCat")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<LogResult> logDetailCat(long logId, int fromLineNum) {
 | 
			
		||||
        try {
 | 
			
		||||
            // valid
 | 
			
		||||
            XxlJobLog jobLog = xxlJobLogDao.load(logId);	// todo, need to improve performance
 | 
			
		||||
            if (jobLog == null) {
 | 
			
		||||
                return new ReturnT<LogResult>(ReturnT.FAIL_CODE, I18nUtil.getString("joblog_logid_unvalid"));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // log cat
 | 
			
		||||
            ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(jobLog.getExecutorAddress());
 | 
			
		||||
            ReturnT<LogResult> logResult = executorBiz.log(new LogParam(jobLog.getTriggerTime().getTime(), logId, fromLineNum));
 | 
			
		||||
 | 
			
		||||
            // is end
 | 
			
		||||
            if (logResult.getContent() != null && logResult.getContent().getFromLineNum() > logResult.getContent().getToLineNum()) {
 | 
			
		||||
                if (jobLog.getHandleCode() > 0) {
 | 
			
		||||
                    logResult.getContent().setEnd(true);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return logResult;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error(e.getMessage(), e);
 | 
			
		||||
            return new ReturnT<LogResult>(ReturnT.FAIL_CODE, e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/logKill")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<String> logKill(int id) {
 | 
			
		||||
        // base check
 | 
			
		||||
        XxlJobLog log = xxlJobLogDao.load(id);
 | 
			
		||||
        XxlJobInfo jobInfo = xxlJobInfoDao.loadById(log.getJobId());
 | 
			
		||||
        if (jobInfo == null) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("jobinfo_glue_jobid_unvalid"));
 | 
			
		||||
        }
 | 
			
		||||
        if (ReturnT.SUCCESS_CODE != log.getTriggerCode()) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("joblog_kill_log_limit"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // request of kill
 | 
			
		||||
        ReturnT<String> runResult = null;
 | 
			
		||||
        try {
 | 
			
		||||
            ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(log.getExecutorAddress());
 | 
			
		||||
            runResult = executorBiz.kill(new KillParam(jobInfo.getId()));
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error(e.getMessage(), e);
 | 
			
		||||
            runResult = new ReturnT<String>(500, e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (ReturnT.SUCCESS_CODE == runResult.getCode()) {
 | 
			
		||||
            log.setHandleCode(ReturnT.FAIL_CODE);
 | 
			
		||||
            log.setHandleMsg(I18nUtil.getString("joblog_kill_log_byman") + ":" + (runResult.getMsg() != null ? runResult.getMsg() : ""));
 | 
			
		||||
            log.setHandleTime(new Date());
 | 
			
		||||
            XxlJobCompleter.updateHandleInfoAndFinish(log);
 | 
			
		||||
            return new ReturnT<String>(runResult.getMsg());
 | 
			
		||||
        } else {
 | 
			
		||||
            return new ReturnT<String>(500, runResult.getMsg());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/clearLog")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<String> clearLog(int jobGroup, int jobId, int type) {
 | 
			
		||||
 | 
			
		||||
        Date clearBeforeTime = null;
 | 
			
		||||
        int clearBeforeNum = 0;
 | 
			
		||||
        if (type == 1) {
 | 
			
		||||
            clearBeforeTime = DateUtil.addMonths(new Date(), -1);    // 清理一个月之前日志数据
 | 
			
		||||
        } else if (type == 2) {
 | 
			
		||||
            clearBeforeTime = DateUtil.addMonths(new Date(), -3);    // 清理三个月之前日志数据
 | 
			
		||||
        } else if (type == 3) {
 | 
			
		||||
            clearBeforeTime = DateUtil.addMonths(new Date(), -6);    // 清理六个月之前日志数据
 | 
			
		||||
        } else if (type == 4) {
 | 
			
		||||
            clearBeforeTime = DateUtil.addYears(new Date(), -1);    // 清理一年之前日志数据
 | 
			
		||||
        } else if (type == 5) {
 | 
			
		||||
            clearBeforeNum = 1000;        // 清理一千条以前日志数据
 | 
			
		||||
        } else if (type == 6) {
 | 
			
		||||
            clearBeforeNum = 10000;        // 清理一万条以前日志数据
 | 
			
		||||
        } else if (type == 7) {
 | 
			
		||||
            clearBeforeNum = 30000;        // 清理三万条以前日志数据
 | 
			
		||||
        } else if (type == 8) {
 | 
			
		||||
            clearBeforeNum = 100000;    // 清理十万条以前日志数据
 | 
			
		||||
        } else if (type == 9) {
 | 
			
		||||
            clearBeforeNum = 0;            // 清理所有日志数据
 | 
			
		||||
        } else {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("joblog_clean_type_unvalid"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Long> logIds = null;
 | 
			
		||||
        do {
 | 
			
		||||
            logIds = xxlJobLogDao.findClearLogIds(jobGroup, jobId, clearBeforeTime, clearBeforeNum, 1000);
 | 
			
		||||
            if (logIds != null && logIds.size() > 0) {
 | 
			
		||||
                xxlJobLogDao.clearLog(logIds);
 | 
			
		||||
            }
 | 
			
		||||
        } while (logIds != null && logIds.size() > 0);
 | 
			
		||||
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,179 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.controller.annotation.PermissionLimit;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobGroup;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobUser;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobGroupDao;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobUserDao;
 | 
			
		||||
import com.xxl.job.admin.service.LoginService;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import org.springframework.stereotype.Controller;
 | 
			
		||||
import org.springframework.ui.Model;
 | 
			
		||||
import org.springframework.util.DigestUtils;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestParam;
 | 
			
		||||
import org.springframework.web.bind.annotation.ResponseBody;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2019-05-04 16:39:50
 | 
			
		||||
 */
 | 
			
		||||
@Controller
 | 
			
		||||
@RequestMapping("/user")
 | 
			
		||||
public class UserController {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobUserDao xxlJobUserDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobGroupDao xxlJobGroupDao;
 | 
			
		||||
 | 
			
		||||
    @RequestMapping
 | 
			
		||||
    @PermissionLimit(adminuser = true)
 | 
			
		||||
    public String index(Model model) {
 | 
			
		||||
 | 
			
		||||
        // 执行器列表
 | 
			
		||||
        List<XxlJobGroup> groupList = xxlJobGroupDao.findAll();
 | 
			
		||||
        model.addAttribute("groupList", groupList);
 | 
			
		||||
 | 
			
		||||
        return "user/user.index";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/pageList")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(adminuser = true)
 | 
			
		||||
    public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,
 | 
			
		||||
                                        @RequestParam(required = false, defaultValue = "10") int length,
 | 
			
		||||
                                        String username, int role) {
 | 
			
		||||
 | 
			
		||||
        // page list
 | 
			
		||||
        List<XxlJobUser> list = xxlJobUserDao.pageList(start, length, username, role);
 | 
			
		||||
        int list_count = xxlJobUserDao.pageListCount(start, length, username, role);
 | 
			
		||||
 | 
			
		||||
        // filter
 | 
			
		||||
        if (list != null && list.size() > 0) {
 | 
			
		||||
            for (XxlJobUser item : list) {
 | 
			
		||||
                item.setPassword(null);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // package result
 | 
			
		||||
        Map<String, Object> maps = new HashMap<String, Object>();
 | 
			
		||||
        maps.put("recordsTotal", list_count);        // 总记录数
 | 
			
		||||
        maps.put("recordsFiltered", list_count);    // 过滤后的总记录数
 | 
			
		||||
        maps.put("data", list);                    // 分页列表
 | 
			
		||||
        return maps;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/add")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(adminuser = true)
 | 
			
		||||
    public ReturnT<String> add(XxlJobUser xxlJobUser) {
 | 
			
		||||
 | 
			
		||||
        // valid username
 | 
			
		||||
        if (!StringUtils.hasText(xxlJobUser.getUsername())) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_please_input") + I18nUtil.getString("user_username"));
 | 
			
		||||
        }
 | 
			
		||||
        xxlJobUser.setUsername(xxlJobUser.getUsername().trim());
 | 
			
		||||
        if (!(xxlJobUser.getUsername().length() >= 4 && xxlJobUser.getUsername().length() <= 20)) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit") + "[4-20]");
 | 
			
		||||
        }
 | 
			
		||||
        // valid password
 | 
			
		||||
        if (!StringUtils.hasText(xxlJobUser.getPassword())) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_please_input") + I18nUtil.getString("user_password"));
 | 
			
		||||
        }
 | 
			
		||||
        xxlJobUser.setPassword(xxlJobUser.getPassword().trim());
 | 
			
		||||
        if (!(xxlJobUser.getPassword().length() >= 4 && xxlJobUser.getPassword().length() <= 20)) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit") + "[4-20]");
 | 
			
		||||
        }
 | 
			
		||||
        // md5 password
 | 
			
		||||
        xxlJobUser.setPassword(DigestUtils.md5DigestAsHex(xxlJobUser.getPassword().getBytes()));
 | 
			
		||||
 | 
			
		||||
        // check repeat
 | 
			
		||||
        XxlJobUser existUser = xxlJobUserDao.loadByUserName(xxlJobUser.getUsername());
 | 
			
		||||
        if (existUser != null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("user_username_repeat"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // write
 | 
			
		||||
        xxlJobUserDao.save(xxlJobUser);
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/update")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(adminuser = true)
 | 
			
		||||
    public ReturnT<String> update(HttpServletRequest request, XxlJobUser xxlJobUser) {
 | 
			
		||||
 | 
			
		||||
        // avoid opt login seft
 | 
			
		||||
        XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
 | 
			
		||||
        if (loginUser.getUsername().equals(xxlJobUser.getUsername())) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("user_update_loginuser_limit"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // valid password
 | 
			
		||||
        if (StringUtils.hasText(xxlJobUser.getPassword())) {
 | 
			
		||||
            xxlJobUser.setPassword(xxlJobUser.getPassword().trim());
 | 
			
		||||
            if (!(xxlJobUser.getPassword().length() >= 4 && xxlJobUser.getPassword().length() <= 20)) {
 | 
			
		||||
                return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit") + "[4-20]");
 | 
			
		||||
            }
 | 
			
		||||
            // md5 password
 | 
			
		||||
            xxlJobUser.setPassword(DigestUtils.md5DigestAsHex(xxlJobUser.getPassword().getBytes()));
 | 
			
		||||
        } else {
 | 
			
		||||
            xxlJobUser.setPassword(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // write
 | 
			
		||||
        xxlJobUserDao.update(xxlJobUser);
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/remove")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @PermissionLimit(adminuser = true)
 | 
			
		||||
    public ReturnT<String> remove(HttpServletRequest request, int id) {
 | 
			
		||||
 | 
			
		||||
        // avoid opt login seft
 | 
			
		||||
        XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
 | 
			
		||||
        if (loginUser.getId() == id) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("user_update_loginuser_limit"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        xxlJobUserDao.delete(id);
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/updatePwd")
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public ReturnT<String> updatePwd(HttpServletRequest request, String password) {
 | 
			
		||||
 | 
			
		||||
        // valid password
 | 
			
		||||
        if (password == null || password.trim().length() == 0) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL.getCode(), "密码不可为空");
 | 
			
		||||
        }
 | 
			
		||||
        password = password.trim();
 | 
			
		||||
        if (!(password.length() >= 4 && password.length() <= 20)) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit") + "[4-20]");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // md5 password
 | 
			
		||||
        String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
 | 
			
		||||
 | 
			
		||||
        // update pwd
 | 
			
		||||
        XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
 | 
			
		||||
 | 
			
		||||
        // do write
 | 
			
		||||
        XxlJobUser existUser = xxlJobUserDao.loadByUserName(loginUser.getUsername());
 | 
			
		||||
        existUser.setPassword(md5Password);
 | 
			
		||||
        xxlJobUserDao.update(existUser);
 | 
			
		||||
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller.annotation;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 权限限制
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2015-12-12 18:29:02
 | 
			
		||||
 */
 | 
			
		||||
@Target(ElementType.METHOD)
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
public @interface PermissionLimit {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 登录拦截 (默认拦截)
 | 
			
		||||
     */
 | 
			
		||||
    boolean limit() default true;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 要求管理员权限
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    boolean adminuser() default false;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller.interceptor;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.util.FtlUtil;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.springframework.web.servlet.AsyncHandlerInterceptor;
 | 
			
		||||
import org.springframework.web.servlet.ModelAndView;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.http.Cookie;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * push cookies to model as cookieMap
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2015-12-12 18:09:04
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
public class CookieInterceptor implements AsyncHandlerInterceptor {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
 | 
			
		||||
                           ModelAndView modelAndView) throws Exception {
 | 
			
		||||
 | 
			
		||||
        // cookie
 | 
			
		||||
        if (modelAndView != null && request.getCookies() != null && request.getCookies().length > 0) {
 | 
			
		||||
            HashMap<String, Cookie> cookieMap = new HashMap<String, Cookie>();
 | 
			
		||||
            for (Cookie ck : request.getCookies()) {
 | 
			
		||||
                cookieMap.put(ck.getName(), ck);
 | 
			
		||||
            }
 | 
			
		||||
            modelAndView.addObject("cookieMap", cookieMap);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // static method
 | 
			
		||||
        if (modelAndView != null) {
 | 
			
		||||
            modelAndView.addObject("I18nUtil", FtlUtil.generateStaticModel(I18nUtil.class.getName()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,59 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller.interceptor;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.controller.annotation.PermissionLimit;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobUser;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.admin.service.LoginService;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.springframework.web.method.HandlerMethod;
 | 
			
		||||
import org.springframework.web.servlet.AsyncHandlerInterceptor;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 权限拦截
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2015-12-12 18:09:04
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
public class PermissionInterceptor implements AsyncHandlerInterceptor {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private LoginService loginService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 | 
			
		||||
 | 
			
		||||
        if (!(handler instanceof HandlerMethod)) {
 | 
			
		||||
            return true;    // proceed with the next interceptor
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // if need login
 | 
			
		||||
        boolean needLogin = true;
 | 
			
		||||
        boolean needAdminuser = false;
 | 
			
		||||
        HandlerMethod method = (HandlerMethod) handler;
 | 
			
		||||
        PermissionLimit permission = method.getMethodAnnotation(PermissionLimit.class);
 | 
			
		||||
        if (permission != null) {
 | 
			
		||||
            needLogin = permission.limit();
 | 
			
		||||
            needAdminuser = permission.adminuser();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (needLogin) {
 | 
			
		||||
            XxlJobUser loginUser = loginService.ifLogin(request, response);
 | 
			
		||||
            if (loginUser == null) {
 | 
			
		||||
                response.setStatus(302);
 | 
			
		||||
                response.setHeader("location", request.getContextPath() + "/toLogin");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            if (needAdminuser && loginUser.getRole() != 1) {
 | 
			
		||||
                throw new RuntimeException(I18nUtil.getString("system_permission_limit"));
 | 
			
		||||
            }
 | 
			
		||||
            request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;    // proceed with the next interceptor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller.interceptor;
 | 
			
		||||
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 | 
			
		||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * web mvc config
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2018-04-02 20:48:20
 | 
			
		||||
 */
 | 
			
		||||
@Configuration
 | 
			
		||||
public class WebMvcConfig implements WebMvcConfigurer {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private PermissionInterceptor permissionInterceptor;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private CookieInterceptor cookieInterceptor;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addInterceptors(InterceptorRegistry registry) {
 | 
			
		||||
        registry.addInterceptor(permissionInterceptor).addPathPatterns("/**");
 | 
			
		||||
        registry.addInterceptor(cookieInterceptor).addPathPatterns("/**");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,66 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.controller.resolver;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.exception.XxlJobException;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.admin.core.util.JacksonUtil;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.springframework.web.bind.annotation.ResponseBody;
 | 
			
		||||
import org.springframework.web.method.HandlerMethod;
 | 
			
		||||
import org.springframework.web.servlet.HandlerExceptionResolver;
 | 
			
		||||
import org.springframework.web.servlet.ModelAndView;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * common exception resolver
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2016-1-6 19:22:18
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
public class WebExceptionResolver implements HandlerExceptionResolver {
 | 
			
		||||
    private static transient Logger logger = LoggerFactory.getLogger(WebExceptionResolver.class);
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ModelAndView resolveException(HttpServletRequest request,
 | 
			
		||||
                                         HttpServletResponse response, Object handler, Exception ex) {
 | 
			
		||||
 | 
			
		||||
        if (!(ex instanceof XxlJobException)) {
 | 
			
		||||
            logger.error("WebExceptionResolver:{}", ex);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // if json
 | 
			
		||||
        boolean isJson = false;
 | 
			
		||||
        if (handler instanceof HandlerMethod) {
 | 
			
		||||
            HandlerMethod method = (HandlerMethod) handler;
 | 
			
		||||
            ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class);
 | 
			
		||||
            if (responseBody != null) {
 | 
			
		||||
                isJson = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // error result
 | 
			
		||||
        ReturnT<String> errorResult = new ReturnT<String>(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n", "<br/>"));
 | 
			
		||||
 | 
			
		||||
        // response
 | 
			
		||||
        ModelAndView mv = new ModelAndView();
 | 
			
		||||
        if (isJson) {
 | 
			
		||||
            try {
 | 
			
		||||
                response.setContentType("application/json;charset=utf-8");
 | 
			
		||||
                response.getWriter().print(JacksonUtil.writeValueAsString(errorResult));
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                logger.error(e.getMessage(), e);
 | 
			
		||||
            }
 | 
			
		||||
            return mv;
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            mv.addObject("exceptionMsg", errorResult.getMsg());
 | 
			
		||||
            mv.setViewName("/common/common.exception");
 | 
			
		||||
            return mv;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.alarm;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLog;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2020-01-19
 | 
			
		||||
 */
 | 
			
		||||
public interface JobAlarm {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * job alarm
 | 
			
		||||
     *
 | 
			
		||||
     * @param info
 | 
			
		||||
     * @param jobLog
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,65 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.alarm;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLog;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.beans.BeansException;
 | 
			
		||||
import org.springframework.beans.factory.InitializingBean;
 | 
			
		||||
import org.springframework.context.ApplicationContext;
 | 
			
		||||
import org.springframework.context.ApplicationContextAware;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
@Component
 | 
			
		||||
public class JobAlarmer implements ApplicationContextAware, InitializingBean {
 | 
			
		||||
    private static Logger logger = LoggerFactory.getLogger(JobAlarmer.class);
 | 
			
		||||
 | 
			
		||||
    private ApplicationContext applicationContext;
 | 
			
		||||
    private List<JobAlarm> jobAlarmList;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
 | 
			
		||||
        this.applicationContext = applicationContext;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void afterPropertiesSet() throws Exception {
 | 
			
		||||
        Map<String, JobAlarm> serviceBeanMap = applicationContext.getBeansOfType(JobAlarm.class);
 | 
			
		||||
        if (serviceBeanMap != null && serviceBeanMap.size() > 0) {
 | 
			
		||||
            jobAlarmList = new ArrayList<JobAlarm>(serviceBeanMap.values());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * job alarm
 | 
			
		||||
     *
 | 
			
		||||
     * @param info
 | 
			
		||||
     * @param jobLog
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public boolean alarm(XxlJobInfo info, XxlJobLog jobLog) {
 | 
			
		||||
 | 
			
		||||
        boolean result = false;
 | 
			
		||||
        if (jobAlarmList != null && jobAlarmList.size() > 0) {
 | 
			
		||||
            result = true;  // success means all-success
 | 
			
		||||
            for (JobAlarm alarm : jobAlarmList) {
 | 
			
		||||
                boolean resultItem = false;
 | 
			
		||||
                try {
 | 
			
		||||
                    resultItem = alarm.doAlarm(info, jobLog);
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    logger.error(e.getMessage(), e);
 | 
			
		||||
                }
 | 
			
		||||
                if (!resultItem) {
 | 
			
		||||
                    result = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,118 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.alarm.impl;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.alarm.JobAlarm;
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobGroup;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLog;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.mail.javamail.MimeMessageHelper;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
 | 
			
		||||
import javax.mail.internet.MimeMessage;
 | 
			
		||||
import java.text.MessageFormat;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * job alarm by email
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2020-01-19
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
public class EmailJobAlarm implements JobAlarm {
 | 
			
		||||
    private static Logger logger = LoggerFactory.getLogger(EmailJobAlarm.class);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * fail alarm
 | 
			
		||||
     *
 | 
			
		||||
     * @param jobLog
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean doAlarm(XxlJobInfo info, XxlJobLog 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 += "<br>TriggerMsg=<br>" + jobLog.getTriggerMsg();
 | 
			
		||||
            }
 | 
			
		||||
            if (jobLog.getHandleCode() > 0 && jobLog.getHandleCode() != ReturnT.SUCCESS_CODE) {
 | 
			
		||||
                alarmContent += "<br>HandleCode=" + jobLog.getHandleMsg();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // email info
 | 
			
		||||
            XxlJobGroup group = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().load(Integer.valueOf(info.getJobGroup()));
 | 
			
		||||
            String personal = I18nUtil.getString("admin_name_full");
 | 
			
		||||
            String title = I18nUtil.getString("jobconf_monitor");
 | 
			
		||||
            String content = MessageFormat.format(loadEmailJobAlarmTemplate(),
 | 
			
		||||
                group != null ? group.getTitle() : "null",
 | 
			
		||||
                info.getId(),
 | 
			
		||||
                info.getJobDesc(),
 | 
			
		||||
                alarmContent);
 | 
			
		||||
 | 
			
		||||
            Set<String> emailSet = new HashSet<String>(Arrays.asList(info.getAlarmEmail().split(",")));
 | 
			
		||||
            for (String email : emailSet) {
 | 
			
		||||
 | 
			
		||||
                // make mail
 | 
			
		||||
                try {
 | 
			
		||||
                    MimeMessage mimeMessage = XxlJobAdminConfig.getAdminConfig().getMailSender().createMimeMessage();
 | 
			
		||||
 | 
			
		||||
                    MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
 | 
			
		||||
                    helper.setFrom(XxlJobAdminConfig.getAdminConfig().getEmailFrom(), personal);
 | 
			
		||||
                    helper.setTo(email);
 | 
			
		||||
                    helper.setSubject(title);
 | 
			
		||||
                    helper.setText(content, true);
 | 
			
		||||
 | 
			
		||||
                    XxlJobAdminConfig.getAdminConfig().getMailSender().send(mimeMessage);
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    logger.error(">>>>>>>>>>> xxl-job, job fail alarm email send error, JobLogId:{}", jobLog.getId(), e);
 | 
			
		||||
 | 
			
		||||
                    alarmResult = false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return alarmResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * load email job alarm template
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    private static final String loadEmailJobAlarmTemplate() {
 | 
			
		||||
        String mailBodyTemplate = "<h5>" + I18nUtil.getString("jobconf_monitor_detail") + ":</span>" +
 | 
			
		||||
            "<table border=\"1\" cellpadding=\"3\" style=\"border-collapse:collapse; width:80%;\" >\n" +
 | 
			
		||||
            "   <thead style=\"font-weight: bold;color: #ffffff;background-color: #ff8c00;\" >" +
 | 
			
		||||
            "      <tr>\n" +
 | 
			
		||||
            "         <td width=\"20%\" >" + I18nUtil.getString("jobinfo_field_jobgroup") + "</td>\n" +
 | 
			
		||||
            "         <td width=\"10%\" >" + I18nUtil.getString("jobinfo_field_id") + "</td>\n" +
 | 
			
		||||
            "         <td width=\"20%\" >" + I18nUtil.getString("jobinfo_field_jobdesc") + "</td>\n" +
 | 
			
		||||
            "         <td width=\"10%\" >" + I18nUtil.getString("jobconf_monitor_alarm_title") + "</td>\n" +
 | 
			
		||||
            "         <td width=\"40%\" >" + I18nUtil.getString("jobconf_monitor_alarm_content") + "</td>\n" +
 | 
			
		||||
            "      </tr>\n" +
 | 
			
		||||
            "   </thead>\n" +
 | 
			
		||||
            "   <tbody>\n" +
 | 
			
		||||
            "      <tr>\n" +
 | 
			
		||||
            "         <td>{0}</td>\n" +
 | 
			
		||||
            "         <td>{1}</td>\n" +
 | 
			
		||||
            "         <td>{2}</td>\n" +
 | 
			
		||||
            "         <td>" + I18nUtil.getString("jobconf_monitor_alarm_type") + "</td>\n" +
 | 
			
		||||
            "         <td>{3}</td>\n" +
 | 
			
		||||
            "      </tr>\n" +
 | 
			
		||||
            "   </tbody>\n" +
 | 
			
		||||
            "</table>";
 | 
			
		||||
 | 
			
		||||
        return mailBodyTemplate;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,99 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.complete;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLog;
 | 
			
		||||
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
 | 
			
		||||
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.context.XxlJobContext;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.text.MessageFormat;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2020-10-30 20:43:10
 | 
			
		||||
 */
 | 
			
		||||
public class XxlJobCompleter {
 | 
			
		||||
    private static Logger logger = LoggerFactory.getLogger(XxlJobCompleter.class);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * common fresh handle entrance (limit only once)
 | 
			
		||||
     *
 | 
			
		||||
     * @param xxlJobLog
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static int updateHandleInfoAndFinish(XxlJobLog xxlJobLog) {
 | 
			
		||||
 | 
			
		||||
        // finish
 | 
			
		||||
        finishJob(xxlJobLog);
 | 
			
		||||
 | 
			
		||||
        // text最大64kb 避免长度过长
 | 
			
		||||
        if (xxlJobLog.getHandleMsg().length() > 15000) {
 | 
			
		||||
            xxlJobLog.setHandleMsg(xxlJobLog.getHandleMsg().substring(0, 15000));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // fresh handle
 | 
			
		||||
        return XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateHandleInfo(xxlJobLog);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * do somethind to finish job
 | 
			
		||||
     */
 | 
			
		||||
    private static void finishJob(XxlJobLog xxlJobLog) {
 | 
			
		||||
 | 
			
		||||
        // 1、handle success, to trigger child job
 | 
			
		||||
        String triggerChildMsg = null;
 | 
			
		||||
        if (XxlJobContext.HANDLE_CODE_SUCCESS == xxlJobLog.getHandleCode()) {
 | 
			
		||||
            XxlJobInfo xxlJobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(xxlJobLog.getJobId());
 | 
			
		||||
            if (xxlJobInfo != null && xxlJobInfo.getChildJobId() != null && xxlJobInfo.getChildJobId().trim().length() > 0) {
 | 
			
		||||
                triggerChildMsg = "<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>" + I18nUtil.getString("jobconf_trigger_child_run") + "<<<<<<<<<<< </span><br>";
 | 
			
		||||
 | 
			
		||||
                String[] childJobIds = xxlJobInfo.getChildJobId().split(",");
 | 
			
		||||
                for (int i = 0; i < childJobIds.length; i++) {
 | 
			
		||||
                    int childJobId = (childJobIds[i] != null && childJobIds[i].trim().length() > 0 && isNumeric(childJobIds[i])) ? Integer.valueOf(childJobIds[i]) : -1;
 | 
			
		||||
                    if (childJobId > 0) {
 | 
			
		||||
 | 
			
		||||
                        JobTriggerPoolHelper.trigger(childJobId, TriggerTypeEnum.PARENT, -1, null, null, null);
 | 
			
		||||
                        ReturnT<String> triggerChildResult = ReturnT.SUCCESS;
 | 
			
		||||
 | 
			
		||||
                        // add msg
 | 
			
		||||
                        triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg1"),
 | 
			
		||||
                            (i + 1),
 | 
			
		||||
                            childJobIds.length,
 | 
			
		||||
                            childJobIds[i],
 | 
			
		||||
                            (triggerChildResult.getCode() == ReturnT.SUCCESS_CODE ? I18nUtil.getString("system_success") : I18nUtil.getString("system_fail")),
 | 
			
		||||
                            triggerChildResult.getMsg());
 | 
			
		||||
                    } else {
 | 
			
		||||
                        triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg2"),
 | 
			
		||||
                            (i + 1),
 | 
			
		||||
                            childJobIds.length,
 | 
			
		||||
                            childJobIds[i]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (triggerChildMsg != null) {
 | 
			
		||||
            xxlJobLog.setHandleMsg(xxlJobLog.getHandleMsg() + triggerChildMsg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 2、fix_delay trigger next
 | 
			
		||||
        // on the way
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static boolean isNumeric(String str) {
 | 
			
		||||
        try {
 | 
			
		||||
            int result = Integer.valueOf(str);
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (NumberFormatException e) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,159 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.conf;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.alarm.JobAlarmer;
 | 
			
		||||
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
 | 
			
		||||
import com.xxl.job.admin.dao.*;
 | 
			
		||||
import org.springframework.beans.factory.DisposableBean;
 | 
			
		||||
import org.springframework.beans.factory.InitializingBean;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Value;
 | 
			
		||||
import org.springframework.mail.javamail.JavaMailSender;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xxl-job config
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2017-04-28
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@Component
 | 
			
		||||
public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
 | 
			
		||||
 | 
			
		||||
    private static XxlJobAdminConfig adminConfig = null;
 | 
			
		||||
 | 
			
		||||
    public static XxlJobAdminConfig getAdminConfig() {
 | 
			
		||||
        return adminConfig;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // ---------------------- XxlJobScheduler ----------------------
 | 
			
		||||
 | 
			
		||||
    private XxlJobScheduler xxlJobScheduler;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void afterPropertiesSet() throws Exception {
 | 
			
		||||
        adminConfig = this;
 | 
			
		||||
 | 
			
		||||
        xxlJobScheduler = new XxlJobScheduler();
 | 
			
		||||
        xxlJobScheduler.init();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void destroy() throws Exception {
 | 
			
		||||
        xxlJobScheduler.destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // ---------------------- XxlJobScheduler ----------------------
 | 
			
		||||
 | 
			
		||||
    // conf
 | 
			
		||||
    @Value("${xxl.job.i18n}")
 | 
			
		||||
    private String i18n;
 | 
			
		||||
 | 
			
		||||
    @Value("${xxl.job.accessToken}")
 | 
			
		||||
    private String accessToken;
 | 
			
		||||
 | 
			
		||||
    @Value("${spring.mail.from}")
 | 
			
		||||
    private String emailFrom;
 | 
			
		||||
 | 
			
		||||
    @Value("${xxl.job.triggerpool.fast.max}")
 | 
			
		||||
    private int triggerPoolFastMax;
 | 
			
		||||
 | 
			
		||||
    @Value("${xxl.job.triggerpool.slow.max}")
 | 
			
		||||
    private int triggerPoolSlowMax;
 | 
			
		||||
 | 
			
		||||
    @Value("${xxl.job.logretentiondays}")
 | 
			
		||||
    private int logretentiondays;
 | 
			
		||||
 | 
			
		||||
    // dao, service
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobLogDao xxlJobLogDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobInfoDao xxlJobInfoDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobRegistryDao xxlJobRegistryDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobGroupDao xxlJobGroupDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobLogReportDao xxlJobLogReportDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private JavaMailSender mailSender;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private DataSource dataSource;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private JobAlarmer jobAlarmer;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public String getI18n() {
 | 
			
		||||
        if (!Arrays.asList("zh_CN", "zh_TC", "en").contains(i18n)) {
 | 
			
		||||
            return "zh_CN";
 | 
			
		||||
        }
 | 
			
		||||
        return i18n;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getAccessToken() {
 | 
			
		||||
        return accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getEmailFrom() {
 | 
			
		||||
        return emailFrom;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getTriggerPoolFastMax() {
 | 
			
		||||
        if (triggerPoolFastMax < 200) {
 | 
			
		||||
            return 200;
 | 
			
		||||
        }
 | 
			
		||||
        return triggerPoolFastMax;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getTriggerPoolSlowMax() {
 | 
			
		||||
        if (triggerPoolSlowMax < 100) {
 | 
			
		||||
            return 100;
 | 
			
		||||
        }
 | 
			
		||||
        return triggerPoolSlowMax;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getLogretentiondays() {
 | 
			
		||||
        if (logretentiondays < 7) {
 | 
			
		||||
            return -1;  // Limit greater than or equal to 7, otherwise close
 | 
			
		||||
        }
 | 
			
		||||
        return logretentiondays;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public XxlJobLogDao getXxlJobLogDao() {
 | 
			
		||||
        return xxlJobLogDao;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public XxlJobInfoDao getXxlJobInfoDao() {
 | 
			
		||||
        return xxlJobInfoDao;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public XxlJobRegistryDao getXxlJobRegistryDao() {
 | 
			
		||||
        return xxlJobRegistryDao;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public XxlJobGroupDao getXxlJobGroupDao() {
 | 
			
		||||
        return xxlJobGroupDao;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public XxlJobLogReportDao getXxlJobLogReportDao() {
 | 
			
		||||
        return xxlJobLogReportDao;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public JavaMailSender getMailSender() {
 | 
			
		||||
        return mailSender;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DataSource getDataSource() {
 | 
			
		||||
        return dataSource;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public JobAlarmer getJobAlarmer() {
 | 
			
		||||
        return jobAlarmer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,15 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.exception;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2019-05-04 23:19:29
 | 
			
		||||
 */
 | 
			
		||||
public class XxlJobException extends RuntimeException {
 | 
			
		||||
 | 
			
		||||
    public XxlJobException() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public XxlJobException(String message) {
 | 
			
		||||
        super(message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,78 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.model;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by xuxueli on 16/9/30.
 | 
			
		||||
 */
 | 
			
		||||
public class XxlJobGroup {
 | 
			
		||||
 | 
			
		||||
    private int id;
 | 
			
		||||
    private String appname;
 | 
			
		||||
    private String title;
 | 
			
		||||
    private int addressType;        // 执行器地址类型:0=自动注册、1=手动录入
 | 
			
		||||
    private String addressList;     // 执行器地址列表,多地址逗号分隔(手动录入)
 | 
			
		||||
    private Date updateTime;
 | 
			
		||||
 | 
			
		||||
    // registry list
 | 
			
		||||
    private List<String> registryList;  // 执行器地址列表(系统注册)
 | 
			
		||||
 | 
			
		||||
    public List<String> getRegistryList() {
 | 
			
		||||
        if (addressList != null && addressList.trim().length() > 0) {
 | 
			
		||||
            registryList = new ArrayList<String>(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 getAddressType() {
 | 
			
		||||
        return addressType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAddressType(int addressType) {
 | 
			
		||||
        this.addressType = addressType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getAddressList() {
 | 
			
		||||
        return addressList;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getUpdateTime() {
 | 
			
		||||
        return updateTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setUpdateTime(Date updateTime) {
 | 
			
		||||
        this.updateTime = updateTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAddressList(String addressList) {
 | 
			
		||||
        this.addressList = addressList;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,237 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.model;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xxl-job info
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli  2016-1-12 18:25:49
 | 
			
		||||
 */
 | 
			
		||||
public class XxlJobInfo {
 | 
			
		||||
 | 
			
		||||
    private int id;                // 主键ID
 | 
			
		||||
 | 
			
		||||
    private int jobGroup;        // 执行器主键ID
 | 
			
		||||
    private String jobDesc;
 | 
			
		||||
 | 
			
		||||
    private Date addTime;
 | 
			
		||||
    private Date updateTime;
 | 
			
		||||
 | 
			
		||||
    private String author;        // 负责人
 | 
			
		||||
    private String alarmEmail;    // 报警邮件
 | 
			
		||||
 | 
			
		||||
    private String scheduleType;            // 调度类型
 | 
			
		||||
    private String scheduleConf;            // 调度配置,值含义取决于调度类型
 | 
			
		||||
    private String misfireStrategy;            // 调度过期策略
 | 
			
		||||
 | 
			
		||||
    private String executorRouteStrategy;    // 执行器路由策略
 | 
			
		||||
    private String executorHandler;            // 执行器,任务Handler名称
 | 
			
		||||
    private String executorParam;            // 执行器,任务参数
 | 
			
		||||
    private String executorBlockStrategy;    // 阻塞处理策略
 | 
			
		||||
    private int executorTimeout;            // 任务执行超时时间,单位秒
 | 
			
		||||
    private int executorFailRetryCount;        // 失败重试次数
 | 
			
		||||
 | 
			
		||||
    private String glueType;        // GLUE类型	#com.xxl.job.core.glue.GlueTypeEnum
 | 
			
		||||
    private String glueSource;        // GLUE源代码
 | 
			
		||||
    private String glueRemark;        // GLUE备注
 | 
			
		||||
    private Date glueUpdatetime;    // GLUE更新时间
 | 
			
		||||
 | 
			
		||||
    private String childJobId;        // 子任务ID,多个逗号分隔
 | 
			
		||||
 | 
			
		||||
    private int triggerStatus;        // 调度状态:0-停止,1-运行
 | 
			
		||||
    private long triggerLastTime;    // 上次调度时间
 | 
			
		||||
    private long triggerNextTime;    // 下次调度时间
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public int getId() {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setId(int id) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getJobGroup() {
 | 
			
		||||
        return jobGroup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setJobGroup(int jobGroup) {
 | 
			
		||||
        this.jobGroup = jobGroup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getJobDesc() {
 | 
			
		||||
        return jobDesc;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setJobDesc(String jobDesc) {
 | 
			
		||||
        this.jobDesc = jobDesc;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getAddTime() {
 | 
			
		||||
        return addTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAddTime(Date addTime) {
 | 
			
		||||
        this.addTime = addTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getUpdateTime() {
 | 
			
		||||
        return updateTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setUpdateTime(Date updateTime) {
 | 
			
		||||
        this.updateTime = updateTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getAuthor() {
 | 
			
		||||
        return author;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAuthor(String author) {
 | 
			
		||||
        this.author = author;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getAlarmEmail() {
 | 
			
		||||
        return alarmEmail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAlarmEmail(String alarmEmail) {
 | 
			
		||||
        this.alarmEmail = alarmEmail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getScheduleType() {
 | 
			
		||||
        return scheduleType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setScheduleType(String scheduleType) {
 | 
			
		||||
        this.scheduleType = scheduleType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getScheduleConf() {
 | 
			
		||||
        return scheduleConf;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setScheduleConf(String scheduleConf) {
 | 
			
		||||
        this.scheduleConf = scheduleConf;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getMisfireStrategy() {
 | 
			
		||||
        return misfireStrategy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMisfireStrategy(String misfireStrategy) {
 | 
			
		||||
        this.misfireStrategy = misfireStrategy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getExecutorRouteStrategy() {
 | 
			
		||||
        return executorRouteStrategy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setExecutorRouteStrategy(String executorRouteStrategy) {
 | 
			
		||||
        this.executorRouteStrategy = executorRouteStrategy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getExecutorHandler() {
 | 
			
		||||
        return executorHandler;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setExecutorHandler(String executorHandler) {
 | 
			
		||||
        this.executorHandler = executorHandler;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getExecutorParam() {
 | 
			
		||||
        return executorParam;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setExecutorParam(String executorParam) {
 | 
			
		||||
        this.executorParam = executorParam;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getExecutorBlockStrategy() {
 | 
			
		||||
        return executorBlockStrategy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setExecutorBlockStrategy(String executorBlockStrategy) {
 | 
			
		||||
        this.executorBlockStrategy = executorBlockStrategy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getExecutorTimeout() {
 | 
			
		||||
        return executorTimeout;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setExecutorTimeout(int executorTimeout) {
 | 
			
		||||
        this.executorTimeout = executorTimeout;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getExecutorFailRetryCount() {
 | 
			
		||||
        return executorFailRetryCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setExecutorFailRetryCount(int executorFailRetryCount) {
 | 
			
		||||
        this.executorFailRetryCount = executorFailRetryCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getGlueType() {
 | 
			
		||||
        return glueType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setGlueType(String glueType) {
 | 
			
		||||
        this.glueType = glueType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getGlueSource() {
 | 
			
		||||
        return glueSource;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setGlueSource(String glueSource) {
 | 
			
		||||
        this.glueSource = glueSource;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getGlueRemark() {
 | 
			
		||||
        return glueRemark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setGlueRemark(String glueRemark) {
 | 
			
		||||
        this.glueRemark = glueRemark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getGlueUpdatetime() {
 | 
			
		||||
        return glueUpdatetime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setGlueUpdatetime(Date glueUpdatetime) {
 | 
			
		||||
        this.glueUpdatetime = glueUpdatetime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getChildJobId() {
 | 
			
		||||
        return childJobId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setChildJobId(String childJobId) {
 | 
			
		||||
        this.childJobId = childJobId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getTriggerStatus() {
 | 
			
		||||
        return triggerStatus;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setTriggerStatus(int triggerStatus) {
 | 
			
		||||
        this.triggerStatus = triggerStatus;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long getTriggerLastTime() {
 | 
			
		||||
        return triggerLastTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setTriggerLastTime(long triggerLastTime) {
 | 
			
		||||
        this.triggerLastTime = triggerLastTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long getTriggerNextTime() {
 | 
			
		||||
        return triggerNextTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setTriggerNextTime(long triggerNextTime) {
 | 
			
		||||
        this.triggerNextTime = triggerNextTime;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,158 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.model;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xxl-job log, used to track trigger process
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli  2015-12-19 23:19:09
 | 
			
		||||
 */
 | 
			
		||||
public class XxlJobLog {
 | 
			
		||||
 | 
			
		||||
    private long id;
 | 
			
		||||
 | 
			
		||||
    // job info
 | 
			
		||||
    private int jobGroup;
 | 
			
		||||
    private int jobId;
 | 
			
		||||
 | 
			
		||||
    // execute info
 | 
			
		||||
    private String executorAddress;
 | 
			
		||||
    private String executorHandler;
 | 
			
		||||
    private String executorParam;
 | 
			
		||||
    private String executorShardingParam;
 | 
			
		||||
    private int executorFailRetryCount;
 | 
			
		||||
 | 
			
		||||
    // trigger info
 | 
			
		||||
    private Date triggerTime;
 | 
			
		||||
    private int triggerCode;
 | 
			
		||||
    private String triggerMsg;
 | 
			
		||||
 | 
			
		||||
    // handle info
 | 
			
		||||
    private Date handleTime;
 | 
			
		||||
    private int handleCode;
 | 
			
		||||
    private String handleMsg;
 | 
			
		||||
 | 
			
		||||
    // alarm info
 | 
			
		||||
    private int alarmStatus;
 | 
			
		||||
 | 
			
		||||
    public long getId() {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setId(long id) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getJobGroup() {
 | 
			
		||||
        return jobGroup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setJobGroup(int jobGroup) {
 | 
			
		||||
        this.jobGroup = jobGroup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getJobId() {
 | 
			
		||||
        return jobId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setJobId(int jobId) {
 | 
			
		||||
        this.jobId = jobId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getExecutorAddress() {
 | 
			
		||||
        return executorAddress;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setExecutorAddress(String executorAddress) {
 | 
			
		||||
        this.executorAddress = executorAddress;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getExecutorHandler() {
 | 
			
		||||
        return executorHandler;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setExecutorHandler(String executorHandler) {
 | 
			
		||||
        this.executorHandler = executorHandler;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getExecutorParam() {
 | 
			
		||||
        return executorParam;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setExecutorParam(String executorParam) {
 | 
			
		||||
        this.executorParam = executorParam;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getExecutorShardingParam() {
 | 
			
		||||
        return executorShardingParam;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setExecutorShardingParam(String executorShardingParam) {
 | 
			
		||||
        this.executorShardingParam = executorShardingParam;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getExecutorFailRetryCount() {
 | 
			
		||||
        return executorFailRetryCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setExecutorFailRetryCount(int executorFailRetryCount) {
 | 
			
		||||
        this.executorFailRetryCount = executorFailRetryCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getTriggerTime() {
 | 
			
		||||
        return triggerTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setTriggerTime(Date triggerTime) {
 | 
			
		||||
        this.triggerTime = triggerTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getTriggerCode() {
 | 
			
		||||
        return triggerCode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setTriggerCode(int triggerCode) {
 | 
			
		||||
        this.triggerCode = triggerCode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getTriggerMsg() {
 | 
			
		||||
        return triggerMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setTriggerMsg(String triggerMsg) {
 | 
			
		||||
        this.triggerMsg = triggerMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getHandleTime() {
 | 
			
		||||
        return handleTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setHandleTime(Date handleTime) {
 | 
			
		||||
        this.handleTime = handleTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getHandleCode() {
 | 
			
		||||
        return handleCode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setHandleCode(int handleCode) {
 | 
			
		||||
        this.handleCode = handleCode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getHandleMsg() {
 | 
			
		||||
        return handleMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setHandleMsg(String handleMsg) {
 | 
			
		||||
        this.handleMsg = handleMsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getAlarmStatus() {
 | 
			
		||||
        return alarmStatus;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAlarmStatus(int alarmStatus) {
 | 
			
		||||
        this.alarmStatus = alarmStatus;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,76 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.model;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xxl-job log for glue, used to track job code process
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2016-5-19 17:57:46
 | 
			
		||||
 */
 | 
			
		||||
public class XxlJobLogGlue {
 | 
			
		||||
 | 
			
		||||
    private int id;
 | 
			
		||||
    private int jobId;                // 任务主键ID
 | 
			
		||||
    private String glueType;        // GLUE类型	#com.xxl.job.core.glue.GlueTypeEnum
 | 
			
		||||
    private String glueSource;
 | 
			
		||||
    private String glueRemark;
 | 
			
		||||
    private Date addTime;
 | 
			
		||||
    private Date updateTime;
 | 
			
		||||
 | 
			
		||||
    public int getId() {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setId(int id) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getJobId() {
 | 
			
		||||
        return jobId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setJobId(int jobId) {
 | 
			
		||||
        this.jobId = jobId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getGlueType() {
 | 
			
		||||
        return glueType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setGlueType(String glueType) {
 | 
			
		||||
        this.glueType = glueType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getGlueSource() {
 | 
			
		||||
        return glueSource;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setGlueSource(String glueSource) {
 | 
			
		||||
        this.glueSource = glueSource;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getGlueRemark() {
 | 
			
		||||
        return glueRemark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setGlueRemark(String glueRemark) {
 | 
			
		||||
        this.glueRemark = glueRemark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getAddTime() {
 | 
			
		||||
        return addTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAddTime(Date addTime) {
 | 
			
		||||
        this.addTime = addTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getUpdateTime() {
 | 
			
		||||
        return updateTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setUpdateTime(Date updateTime) {
 | 
			
		||||
        this.updateTime = updateTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,54 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.model;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
public class XxlJobLogReport {
 | 
			
		||||
 | 
			
		||||
    private int id;
 | 
			
		||||
 | 
			
		||||
    private Date triggerDay;
 | 
			
		||||
 | 
			
		||||
    private int runningCount;
 | 
			
		||||
    private int sucCount;
 | 
			
		||||
    private int failCount;
 | 
			
		||||
 | 
			
		||||
    public int getId() {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setId(int id) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getTriggerDay() {
 | 
			
		||||
        return triggerDay;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setTriggerDay(Date triggerDay) {
 | 
			
		||||
        this.triggerDay = triggerDay;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getRunningCount() {
 | 
			
		||||
        return runningCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setRunningCount(int runningCount) {
 | 
			
		||||
        this.runningCount = runningCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getSucCount() {
 | 
			
		||||
        return sucCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setSucCount(int sucCount) {
 | 
			
		||||
        this.sucCount = sucCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getFailCount() {
 | 
			
		||||
        return failCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setFailCount(int failCount) {
 | 
			
		||||
        this.failCount = failCount;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,55 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.model;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by xuxueli on 16/9/30.
 | 
			
		||||
 */
 | 
			
		||||
public class XxlJobRegistry {
 | 
			
		||||
 | 
			
		||||
    private int id;
 | 
			
		||||
    private String registryGroup;
 | 
			
		||||
    private String registryKey;
 | 
			
		||||
    private String registryValue;
 | 
			
		||||
    private Date updateTime;
 | 
			
		||||
 | 
			
		||||
    public int getId() {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setId(int id) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getRegistryGroup() {
 | 
			
		||||
        return registryGroup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setRegistryGroup(String registryGroup) {
 | 
			
		||||
        this.registryGroup = registryGroup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getRegistryKey() {
 | 
			
		||||
        return registryKey;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setRegistryKey(String registryKey) {
 | 
			
		||||
        this.registryKey = registryKey;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getRegistryValue() {
 | 
			
		||||
        return registryValue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setRegistryValue(String registryValue) {
 | 
			
		||||
        this.registryValue = registryValue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getUpdateTime() {
 | 
			
		||||
        return updateTime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setUpdateTime(Date updateTime) {
 | 
			
		||||
        this.updateTime = updateTime;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,73 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.model;
 | 
			
		||||
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2019-05-04 16:43:12
 | 
			
		||||
 */
 | 
			
		||||
public class XxlJobUser {
 | 
			
		||||
 | 
			
		||||
    private int id;
 | 
			
		||||
    private String username;        // 账号
 | 
			
		||||
    private String password;        // 密码
 | 
			
		||||
    private int role;                // 角色:0-普通用户、1-管理员
 | 
			
		||||
    private String permission;    // 权限:执行器ID列表,多个逗号分割
 | 
			
		||||
 | 
			
		||||
    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 int getRole() {
 | 
			
		||||
        return role;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setRole(int role) {
 | 
			
		||||
        this.role = role;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getPermission() {
 | 
			
		||||
        return permission;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setPermission(String permission) {
 | 
			
		||||
        this.permission = permission;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // plugin
 | 
			
		||||
    public boolean validPermission(int jobGroup) {
 | 
			
		||||
        if (this.role == 1) {
 | 
			
		||||
            return true;
 | 
			
		||||
        } else {
 | 
			
		||||
            if (StringUtils.hasText(this.permission)) {
 | 
			
		||||
                for (String permissionItem : this.permission.split(",")) {
 | 
			
		||||
                    if (String.valueOf(jobGroup).equals(permissionItem)) {
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,32 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.old;//package com.xxl.job.admin.core.jobbean;
 | 
			
		||||
//
 | 
			
		||||
//import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
 | 
			
		||||
//import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
 | 
			
		||||
//import org.quartz.JobExecutionContext;
 | 
			
		||||
//import org.quartz.JobExecutionException;
 | 
			
		||||
//import org.quartz.JobKey;
 | 
			
		||||
//import org.slf4j.Logger;
 | 
			
		||||
//import org.slf4j.LoggerFactory;
 | 
			
		||||
//import org.springframework.scheduling.quartz.QuartzJobBean;
 | 
			
		||||
//
 | 
			
		||||
///**
 | 
			
		||||
// * http job bean
 | 
			
		||||
// * “@DisallowConcurrentExecution” disable concurrent, thread size can not be only one, better given more
 | 
			
		||||
// * @author xuxueli 2015-12-17 18:20:34
 | 
			
		||||
// */
 | 
			
		||||
////@DisallowConcurrentExecution
 | 
			
		||||
//public class RemoteHttpJobBean extends QuartzJobBean {
 | 
			
		||||
//	private static Logger logger = LoggerFactory.getLogger(RemoteHttpJobBean.class);
 | 
			
		||||
//
 | 
			
		||||
//	@Override
 | 
			
		||||
//	protected void executeInternal(JobExecutionContext context)
 | 
			
		||||
//			throws JobExecutionException {
 | 
			
		||||
//
 | 
			
		||||
//		// load jobId
 | 
			
		||||
//		JobKey jobKey = context.getTrigger().getJobKey();
 | 
			
		||||
//		Integer jobId = Integer.valueOf(jobKey.getName());
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//	}
 | 
			
		||||
//
 | 
			
		||||
//}
 | 
			
		||||
@@ -1,413 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.old;//package com.xxl.job.admin.core.schedule;
 | 
			
		||||
//
 | 
			
		||||
//import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
//import com.xxl.job.admin.core.jobbean.RemoteHttpJobBean;
 | 
			
		||||
//import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
//import com.xxl.job.admin.core.thread.JobFailMonitorHelper;
 | 
			
		||||
//import com.xxl.job.admin.core.thread.JobRegistryMonitorHelper;
 | 
			
		||||
//import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
 | 
			
		||||
//import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
//import com.xxl.job.core.biz.AdminBiz;
 | 
			
		||||
//import com.xxl.job.core.biz.ExecutorBiz;
 | 
			
		||||
//import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
 | 
			
		||||
//import com.xxl.rpc.remoting.invoker.XxlRpcInvokerFactory;
 | 
			
		||||
//import com.xxl.rpc.remoting.invoker.call.CallType;
 | 
			
		||||
//import com.xxl.rpc.remoting.invoker.reference.XxlRpcReferenceBean;
 | 
			
		||||
//import com.xxl.rpc.remoting.invoker.route.LoadBalance;
 | 
			
		||||
//import com.xxl.rpc.remoting.net.NetEnum;
 | 
			
		||||
//import com.xxl.rpc.remoting.net.impl.servlet.server.ServletServerHandler;
 | 
			
		||||
//import com.xxl.rpc.remoting.provider.XxlRpcProviderFactory;
 | 
			
		||||
//import com.xxl.rpc.serialize.Serializer;
 | 
			
		||||
//import org.quartz.*;
 | 
			
		||||
//import org.quartz.Trigger.TriggerState;
 | 
			
		||||
//import org.quartz.impl.triggers.CronTriggerImpl;
 | 
			
		||||
//import org.slf4j.Logger;
 | 
			
		||||
//import org.slf4j.LoggerFactory;
 | 
			
		||||
//import org.springframework.util.Assert;
 | 
			
		||||
//
 | 
			
		||||
//import javax.servlet.ServletException;
 | 
			
		||||
//import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
//import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
//import java.io.IOException;
 | 
			
		||||
//import java.util.Date;
 | 
			
		||||
//import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
//
 | 
			
		||||
///**
 | 
			
		||||
// * base quartz scheduler util
 | 
			
		||||
// * @author xuxueli 2015-12-19 16:13:53
 | 
			
		||||
// */
 | 
			
		||||
//public final class XxlJobDynamicScheduler {
 | 
			
		||||
//    private static final Logger logger = LoggerFactory.getLogger(XxlJobDynamicScheduler_old.class);
 | 
			
		||||
//
 | 
			
		||||
//    // ---------------------- param ----------------------
 | 
			
		||||
//
 | 
			
		||||
//    // scheduler
 | 
			
		||||
//    private static Scheduler scheduler;
 | 
			
		||||
//    public void setScheduler(Scheduler scheduler) {
 | 
			
		||||
//		XxlJobDynamicScheduler_old.scheduler = scheduler;
 | 
			
		||||
//	}
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    // ---------------------- init + destroy ----------------------
 | 
			
		||||
//    public void start() throws Exception {
 | 
			
		||||
//        // valid
 | 
			
		||||
//        Assert.notNull(scheduler, "quartz scheduler is null");
 | 
			
		||||
//
 | 
			
		||||
//        // init i18n
 | 
			
		||||
//        initI18n();
 | 
			
		||||
//
 | 
			
		||||
//        // admin registry monitor run
 | 
			
		||||
//        JobRegistryMonitorHelper.getInstance().start();
 | 
			
		||||
//
 | 
			
		||||
//        // admin monitor run
 | 
			
		||||
//        JobFailMonitorHelper.getInstance().start();
 | 
			
		||||
//
 | 
			
		||||
//        // admin-server
 | 
			
		||||
//        initRpcProvider();
 | 
			
		||||
//
 | 
			
		||||
//        logger.info(">>>>>>>>> init xxl-job admin success.");
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    public void destroy() throws Exception {
 | 
			
		||||
//        // admin trigger pool stop
 | 
			
		||||
//        JobTriggerPoolHelper.toStop();
 | 
			
		||||
//
 | 
			
		||||
//        // admin registry stop
 | 
			
		||||
//        JobRegistryMonitorHelper.getInstance().toStop();
 | 
			
		||||
//
 | 
			
		||||
//        // admin monitor stop
 | 
			
		||||
//        JobFailMonitorHelper.getInstance().toStop();
 | 
			
		||||
//
 | 
			
		||||
//        // admin-server
 | 
			
		||||
//        stopRpcProvider();
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    // ---------------------- I18n ----------------------
 | 
			
		||||
//
 | 
			
		||||
//    private void initI18n(){
 | 
			
		||||
//        for (ExecutorBlockStrategyEnum item:ExecutorBlockStrategyEnum.values()) {
 | 
			
		||||
//            item.setTitle(I18nUtil.getString("jobconf_block_".concat(item.name())));
 | 
			
		||||
//        }
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    // ---------------------- admin rpc provider (no server version) ----------------------
 | 
			
		||||
//    private static ServletServerHandler servletServerHandler;
 | 
			
		||||
//    private void initRpcProvider(){
 | 
			
		||||
//        // init
 | 
			
		||||
//        XxlRpcProviderFactory xxlRpcProviderFactory = new XxlRpcProviderFactory();
 | 
			
		||||
//        xxlRpcProviderFactory.initConfig(
 | 
			
		||||
//                NetEnum.NETTY_HTTP,
 | 
			
		||||
//                Serializer.SerializeEnum.HESSIAN.getSerializer(),
 | 
			
		||||
//                null,
 | 
			
		||||
//                0,
 | 
			
		||||
//                XxlJobAdminConfig.getAdminConfig().getAccessToken(),
 | 
			
		||||
//                null,
 | 
			
		||||
//                null);
 | 
			
		||||
//
 | 
			
		||||
//        // add services
 | 
			
		||||
//        xxlRpcProviderFactory.addService(AdminBiz.class.getName(), null, XxlJobAdminConfig.getAdminConfig().getAdminBiz());
 | 
			
		||||
//
 | 
			
		||||
//        // servlet handler
 | 
			
		||||
//        servletServerHandler = new ServletServerHandler(xxlRpcProviderFactory);
 | 
			
		||||
//    }
 | 
			
		||||
//    private void stopRpcProvider() throws Exception {
 | 
			
		||||
//        XxlRpcInvokerFactory.getInstance().stop();
 | 
			
		||||
//    }
 | 
			
		||||
//    public static void invokeAdminService(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
 | 
			
		||||
//        servletServerHandler.handle(null, request, response);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    // ---------------------- executor-client ----------------------
 | 
			
		||||
//    private static ConcurrentHashMap<String, ExecutorBiz> executorBizRepository = new ConcurrentHashMap<String, ExecutorBiz>();
 | 
			
		||||
//    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
 | 
			
		||||
//        executorBiz = (ExecutorBiz) new XxlRpcReferenceBean(
 | 
			
		||||
//                NetEnum.NETTY_HTTP,
 | 
			
		||||
//                Serializer.SerializeEnum.HESSIAN.getSerializer(),
 | 
			
		||||
//                CallType.SYNC,
 | 
			
		||||
//                LoadBalance.ROUND,
 | 
			
		||||
//                ExecutorBiz.class,
 | 
			
		||||
//                null,
 | 
			
		||||
//                5000,
 | 
			
		||||
//                address,
 | 
			
		||||
//                XxlJobAdminConfig.getAdminConfig().getAccessToken(),
 | 
			
		||||
//                null,
 | 
			
		||||
//                null).getObject();
 | 
			
		||||
//
 | 
			
		||||
//        executorBizRepository.put(address, executorBiz);
 | 
			
		||||
//        return executorBiz;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    // ---------------------- schedule util ----------------------
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * fill job info
 | 
			
		||||
//     *
 | 
			
		||||
//     * @param jobInfo
 | 
			
		||||
//     */
 | 
			
		||||
//	public static void fillJobInfo(XxlJobInfo jobInfo) {
 | 
			
		||||
//
 | 
			
		||||
//        String name = String.valueOf(jobInfo.getId());
 | 
			
		||||
//
 | 
			
		||||
//        // trigger key
 | 
			
		||||
//        TriggerKey triggerKey = TriggerKey.triggerKey(name);
 | 
			
		||||
//        try {
 | 
			
		||||
//
 | 
			
		||||
//            // trigger cron
 | 
			
		||||
//			Trigger trigger = scheduler.getTrigger(triggerKey);
 | 
			
		||||
//			if (trigger!=null && trigger instanceof CronTriggerImpl) {
 | 
			
		||||
//				String cronExpression = ((CronTriggerImpl) trigger).getCronExpression();
 | 
			
		||||
//				jobInfo.setJobCron(cronExpression);
 | 
			
		||||
//			}
 | 
			
		||||
//
 | 
			
		||||
//            // trigger state
 | 
			
		||||
//            TriggerState triggerState = scheduler.getTriggerState(triggerKey);
 | 
			
		||||
//			if (triggerState!=null) {
 | 
			
		||||
//				jobInfo.setJobStatus(triggerState.name());
 | 
			
		||||
//			}
 | 
			
		||||
//
 | 
			
		||||
//            //JobKey jobKey = new JobKey(jobInfo.getJobName(), String.valueOf(jobInfo.getJobGroup()));
 | 
			
		||||
//            //JobDetail jobDetail = scheduler.getJobDetail(jobKey);
 | 
			
		||||
//            //String jobClass = jobDetail.getJobClass().getName();
 | 
			
		||||
//
 | 
			
		||||
//		} catch (SchedulerException e) {
 | 
			
		||||
//			logger.error(e.getMessage(), e);
 | 
			
		||||
//		}
 | 
			
		||||
//	}
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * add trigger + job
 | 
			
		||||
//     *
 | 
			
		||||
//     * @param jobName
 | 
			
		||||
//     * @param cronExpression
 | 
			
		||||
//     * @return
 | 
			
		||||
//     * @throws SchedulerException
 | 
			
		||||
//     */
 | 
			
		||||
//	public static boolean addJob(String jobName, String cronExpression) throws SchedulerException {
 | 
			
		||||
//    	// 1、job key
 | 
			
		||||
//        TriggerKey triggerKey = TriggerKey.triggerKey(jobName);
 | 
			
		||||
//        JobKey jobKey = new JobKey(jobName);
 | 
			
		||||
//
 | 
			
		||||
//        // 2、valid
 | 
			
		||||
//        if (scheduler.checkExists(triggerKey)) {
 | 
			
		||||
//            return true;    // PASS
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        // 3、corn trigger
 | 
			
		||||
//        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();   // withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度
 | 
			
		||||
//        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
 | 
			
		||||
//
 | 
			
		||||
//        // 4、job detail
 | 
			
		||||
//		Class<? extends Job> jobClass_ = RemoteHttpJobBean.class;   // Class.forName(jobInfo.getJobClass());
 | 
			
		||||
//		JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build();
 | 
			
		||||
//
 | 
			
		||||
//        /*if (jobInfo.getJobData()!=null) {
 | 
			
		||||
//        	JobDataMap jobDataMap = jobDetail.getJobDataMap();
 | 
			
		||||
//        	jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));
 | 
			
		||||
//        	// JobExecutionContext context.getMergedJobDataMap().get("mailGuid");
 | 
			
		||||
//		}*/
 | 
			
		||||
//
 | 
			
		||||
//        // 5、schedule job
 | 
			
		||||
//        Date date = scheduler.scheduleJob(jobDetail, cronTrigger);
 | 
			
		||||
//
 | 
			
		||||
//        logger.info(">>>>>>>>>>> addJob success(quartz), jobDetail:{}, cronTrigger:{}, date:{}", jobDetail, cronTrigger, date);
 | 
			
		||||
//        return true;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * remove trigger + job
 | 
			
		||||
//     *
 | 
			
		||||
//     * @param jobName
 | 
			
		||||
//     * @return
 | 
			
		||||
//     * @throws SchedulerException
 | 
			
		||||
//     */
 | 
			
		||||
//    public static boolean removeJob(String jobName) throws SchedulerException {
 | 
			
		||||
//
 | 
			
		||||
//        JobKey jobKey = new JobKey(jobName);
 | 
			
		||||
//        scheduler.deleteJob(jobKey);
 | 
			
		||||
//
 | 
			
		||||
//        /*TriggerKey triggerKey = TriggerKey.triggerKey(jobName);
 | 
			
		||||
//        if (scheduler.checkExists(triggerKey)) {
 | 
			
		||||
//            scheduler.unscheduleJob(triggerKey);    // trigger + job
 | 
			
		||||
//        }*/
 | 
			
		||||
//
 | 
			
		||||
//        logger.info(">>>>>>>>>>> removeJob success(quartz), jobKey:{}", jobKey);
 | 
			
		||||
//        return true;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * updateJobCron
 | 
			
		||||
//     *
 | 
			
		||||
//     * @param jobName
 | 
			
		||||
//     * @param cronExpression
 | 
			
		||||
//     * @return
 | 
			
		||||
//     * @throws SchedulerException
 | 
			
		||||
//     */
 | 
			
		||||
//	public static boolean updateJobCron(String jobName, String cronExpression) throws SchedulerException {
 | 
			
		||||
//
 | 
			
		||||
//        // 1、job key
 | 
			
		||||
//        TriggerKey triggerKey = TriggerKey.triggerKey(jobName);
 | 
			
		||||
//
 | 
			
		||||
//        // 2、valid
 | 
			
		||||
//        if (!scheduler.checkExists(triggerKey)) {
 | 
			
		||||
//            return true;    // PASS
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
 | 
			
		||||
//
 | 
			
		||||
//        // 3、avoid repeat cron
 | 
			
		||||
//        String oldCron = oldTrigger.getCronExpression();
 | 
			
		||||
//        if (oldCron.equals(cronExpression)){
 | 
			
		||||
//            return true;    // PASS
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        // 4、new cron trigger
 | 
			
		||||
//        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
 | 
			
		||||
//        oldTrigger = oldTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
 | 
			
		||||
//
 | 
			
		||||
//        // 5、rescheduleJob
 | 
			
		||||
//        scheduler.rescheduleJob(triggerKey, oldTrigger);
 | 
			
		||||
//
 | 
			
		||||
//        /*
 | 
			
		||||
//        JobKey jobKey = new JobKey(jobName);
 | 
			
		||||
//
 | 
			
		||||
//        // old job detail
 | 
			
		||||
//        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
 | 
			
		||||
//
 | 
			
		||||
//        // new trigger
 | 
			
		||||
//        HashSet<Trigger> triggerSet = new HashSet<Trigger>();
 | 
			
		||||
//        triggerSet.add(cronTrigger);
 | 
			
		||||
//        // cover trigger of job detail
 | 
			
		||||
//        scheduler.scheduleJob(jobDetail, triggerSet, true);*/
 | 
			
		||||
//
 | 
			
		||||
//        logger.info(">>>>>>>>>>> resumeJob success, JobName:{}", jobName);
 | 
			
		||||
//        return true;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * pause
 | 
			
		||||
//     *
 | 
			
		||||
//     * @param jobName
 | 
			
		||||
//     * @return
 | 
			
		||||
//     * @throws SchedulerException
 | 
			
		||||
//     */
 | 
			
		||||
//    /*public static boolean pauseJob(String jobName) throws SchedulerException {
 | 
			
		||||
//
 | 
			
		||||
//    	TriggerKey triggerKey = TriggerKey.triggerKey(jobName);
 | 
			
		||||
//
 | 
			
		||||
//        boolean result = false;
 | 
			
		||||
//        if (scheduler.checkExists(triggerKey)) {
 | 
			
		||||
//            scheduler.pauseTrigger(triggerKey);
 | 
			
		||||
//            result =  true;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        logger.info(">>>>>>>>>>> pauseJob {}, triggerKey:{}", (result?"success":"fail"),triggerKey);
 | 
			
		||||
//        return result;
 | 
			
		||||
//    }*/
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * resume
 | 
			
		||||
//     *
 | 
			
		||||
//     * @param jobName
 | 
			
		||||
//     * @return
 | 
			
		||||
//     * @throws SchedulerException
 | 
			
		||||
//     */
 | 
			
		||||
//    /*public static boolean resumeJob(String jobName) throws SchedulerException {
 | 
			
		||||
//
 | 
			
		||||
//        TriggerKey triggerKey = TriggerKey.triggerKey(jobName);
 | 
			
		||||
//
 | 
			
		||||
//        boolean result = false;
 | 
			
		||||
//        if (scheduler.checkExists(triggerKey)) {
 | 
			
		||||
//            scheduler.resumeTrigger(triggerKey);
 | 
			
		||||
//            result = true;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        logger.info(">>>>>>>>>>> resumeJob {}, triggerKey:{}", (result?"success":"fail"), triggerKey);
 | 
			
		||||
//        return result;
 | 
			
		||||
//    }*/
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * run
 | 
			
		||||
//     *
 | 
			
		||||
//     * @param jobName
 | 
			
		||||
//     * @return
 | 
			
		||||
//     * @throws SchedulerException
 | 
			
		||||
//     */
 | 
			
		||||
//    /*public static boolean triggerJob(String jobName) throws SchedulerException {
 | 
			
		||||
//    	// TriggerKey : name + group
 | 
			
		||||
//    	JobKey jobKey = new JobKey(jobName);
 | 
			
		||||
//        TriggerKey triggerKey = TriggerKey.triggerKey(jobName);
 | 
			
		||||
//
 | 
			
		||||
//        boolean result = false;
 | 
			
		||||
//        if (scheduler.checkExists(triggerKey)) {
 | 
			
		||||
//            scheduler.triggerJob(jobKey);
 | 
			
		||||
//            result = true;
 | 
			
		||||
//            logger.info(">>>>>>>>>>> runJob success, jobKey:{}", jobKey);
 | 
			
		||||
//        } else {
 | 
			
		||||
//        	logger.info(">>>>>>>>>>> runJob fail, jobKey:{}", jobKey);
 | 
			
		||||
//        }
 | 
			
		||||
//        return result;
 | 
			
		||||
//    }*/
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * finaAllJobList
 | 
			
		||||
//     *
 | 
			
		||||
//     * @return
 | 
			
		||||
//     *//*
 | 
			
		||||
//    @Deprecated
 | 
			
		||||
//    public static List<Map<String, Object>> finaAllJobList(){
 | 
			
		||||
//        List<Map<String, Object>> jobList = new ArrayList<Map<String,Object>>();
 | 
			
		||||
//
 | 
			
		||||
//        try {
 | 
			
		||||
//            if (scheduler.getJobGroupNames()==null || scheduler.getJobGroupNames().size()==0) {
 | 
			
		||||
//                return null;
 | 
			
		||||
//            }
 | 
			
		||||
//            String groupName = scheduler.getJobGroupNames().get(0);
 | 
			
		||||
//            Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName));
 | 
			
		||||
//            if (jobKeys!=null && jobKeys.size()>0) {
 | 
			
		||||
//                for (JobKey jobKey : jobKeys) {
 | 
			
		||||
//                    TriggerKey triggerKey = TriggerKey.triggerKey(jobKey.getName(), Scheduler.DEFAULT_GROUP);
 | 
			
		||||
//                    Trigger trigger = scheduler.getTrigger(triggerKey);
 | 
			
		||||
//                    JobDetail jobDetail = scheduler.getJobDetail(jobKey);
 | 
			
		||||
//                    TriggerState triggerState = scheduler.getTriggerState(triggerKey);
 | 
			
		||||
//                    Map<String, Object> jobMap = new HashMap<String, Object>();
 | 
			
		||||
//                    jobMap.put("TriggerKey", triggerKey);
 | 
			
		||||
//                    jobMap.put("Trigger", trigger);
 | 
			
		||||
//                    jobMap.put("JobDetail", jobDetail);
 | 
			
		||||
//                    jobMap.put("TriggerState", triggerState);
 | 
			
		||||
//                    jobList.add(jobMap);
 | 
			
		||||
//                }
 | 
			
		||||
//            }
 | 
			
		||||
//
 | 
			
		||||
//        } catch (SchedulerException e) {
 | 
			
		||||
//            logger.error(e.getMessage(), e);
 | 
			
		||||
//            return null;
 | 
			
		||||
//        }
 | 
			
		||||
//        return jobList;
 | 
			
		||||
//    }*/
 | 
			
		||||
//
 | 
			
		||||
//}
 | 
			
		||||
@@ -1,58 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.old;//package com.xxl.job.admin.core.quartz;
 | 
			
		||||
//
 | 
			
		||||
//import org.quartz.SchedulerConfigException;
 | 
			
		||||
//import org.quartz.spi.ThreadPool;
 | 
			
		||||
//
 | 
			
		||||
///**
 | 
			
		||||
// * single thread pool, for async trigger
 | 
			
		||||
// *
 | 
			
		||||
// * @author xuxueli 2019-03-06
 | 
			
		||||
// */
 | 
			
		||||
//public class XxlJobThreadPool implements ThreadPool {
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public boolean runInThread(Runnable runnable) {
 | 
			
		||||
//
 | 
			
		||||
//        // async run
 | 
			
		||||
//        runnable.run();
 | 
			
		||||
//        return true;
 | 
			
		||||
//
 | 
			
		||||
//        //return false;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public int blockForAvailableThreads() {
 | 
			
		||||
//        return 1;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public void initialize() throws SchedulerConfigException {
 | 
			
		||||
//
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public void shutdown(boolean waitForJobsToComplete) {
 | 
			
		||||
//
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public int getPoolSize() {
 | 
			
		||||
//        return 1;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public void setInstanceId(String schedInstId) {
 | 
			
		||||
//
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public void setInstanceName(String schedName) {
 | 
			
		||||
//
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    // support
 | 
			
		||||
//    public void setThreadCount(int count) {
 | 
			
		||||
//        //
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//}
 | 
			
		||||
@@ -1,49 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.route;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.route.strategy.*;
 | 
			
		||||
import com.xxl.job.admin.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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.route;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.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<String> route(TriggerParam triggerParam, List<String> addressList);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,48 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.route.strategy;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouter;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.core.biz.ExecutorBiz;
 | 
			
		||||
import com.xxl.job.core.biz.model.IdleBeatParam;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.biz.model.TriggerParam;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by xuxueli on 17/3/10.
 | 
			
		||||
 */
 | 
			
		||||
public class ExecutorRouteBusyover extends ExecutorRouter {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) {
 | 
			
		||||
        StringBuffer idleBeatResultSB = new StringBuffer();
 | 
			
		||||
        for (String address : addressList) {
 | 
			
		||||
            // beat
 | 
			
		||||
            ReturnT<String> idleBeatResult = null;
 | 
			
		||||
            try {
 | 
			
		||||
                ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address);
 | 
			
		||||
                idleBeatResult = executorBiz.idleBeat(new IdleBeatParam(triggerParam.getJobId()));
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                logger.error(e.getMessage(), e);
 | 
			
		||||
                idleBeatResult = new ReturnT<String>(ReturnT.FAIL_CODE, "" + e);
 | 
			
		||||
            }
 | 
			
		||||
            idleBeatResultSB.append((idleBeatResultSB.length() > 0) ? "<br><br>" : "")
 | 
			
		||||
                .append(I18nUtil.getString("jobconf_idleBeat") + ":")
 | 
			
		||||
                .append("<br>address:").append(address)
 | 
			
		||||
                .append("<br>code:").append(idleBeatResult.getCode())
 | 
			
		||||
                .append("<br>msg:").append(idleBeatResult.getMsg());
 | 
			
		||||
 | 
			
		||||
            // beat success
 | 
			
		||||
            if (idleBeatResult.getCode() == ReturnT.SUCCESS_CODE) {
 | 
			
		||||
                idleBeatResult.setMsg(idleBeatResultSB.toString());
 | 
			
		||||
                idleBeatResult.setContent(address);
 | 
			
		||||
                return idleBeatResult;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new ReturnT<String>(ReturnT.FAIL_CODE, idleBeatResultSB.toString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,86 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.route.strategy;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouter;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.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<String> addressList) {
 | 
			
		||||
 | 
			
		||||
        // ------A1------A2-------A3------
 | 
			
		||||
        // -----------J1------------------
 | 
			
		||||
        TreeMap<Long, String> addressRing = new TreeMap<Long, String>();
 | 
			
		||||
        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<Long, String> lastRing = addressRing.tailMap(jobHash);
 | 
			
		||||
        if (!lastRing.isEmpty()) {
 | 
			
		||||
            return lastRing.get(lastRing.firstKey());
 | 
			
		||||
        }
 | 
			
		||||
        return addressRing.firstEntry().getValue();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) {
 | 
			
		||||
        String address = hashJob(triggerParam.getJobId(), addressList);
 | 
			
		||||
        return new ReturnT<String>(address);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,48 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.route.strategy;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouter;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.core.biz.ExecutorBiz;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.biz.model.TriggerParam;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by xuxueli on 17/3/10.
 | 
			
		||||
 */
 | 
			
		||||
public class ExecutorRouteFailover extends ExecutorRouter {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) {
 | 
			
		||||
 | 
			
		||||
        StringBuffer beatResultSB = new StringBuffer();
 | 
			
		||||
        for (String address : addressList) {
 | 
			
		||||
            // beat
 | 
			
		||||
            ReturnT<String> beatResult = null;
 | 
			
		||||
            try {
 | 
			
		||||
                ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address);
 | 
			
		||||
                beatResult = executorBiz.beat();
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                logger.error(e.getMessage(), e);
 | 
			
		||||
                beatResult = new ReturnT<String>(ReturnT.FAIL_CODE, "" + e);
 | 
			
		||||
            }
 | 
			
		||||
            beatResultSB.append((beatResultSB.length() > 0) ? "<br><br>" : "")
 | 
			
		||||
                .append(I18nUtil.getString("jobconf_beat") + ":")
 | 
			
		||||
                .append("<br>address:").append(address)
 | 
			
		||||
                .append("<br>code:").append(beatResult.getCode())
 | 
			
		||||
                .append("<br>msg:").append(beatResult.getMsg());
 | 
			
		||||
 | 
			
		||||
            // beat success
 | 
			
		||||
            if (beatResult.getCode() == ReturnT.SUCCESS_CODE) {
 | 
			
		||||
 | 
			
		||||
                beatResult.setMsg(beatResultSB.toString());
 | 
			
		||||
                beatResult.setContent(address);
 | 
			
		||||
                return beatResult;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return new ReturnT<String>(ReturnT.FAIL_CODE, beatResultSB.toString());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.route.strategy;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouter;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.biz.model.TriggerParam;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by xuxueli on 17/3/10.
 | 
			
		||||
 */
 | 
			
		||||
public class ExecutorRouteFirst extends ExecutorRouter {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) {
 | 
			
		||||
        return new ReturnT<String>(addressList.get(0));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.route.strategy;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouter;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.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):最近最久未使用,时间
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Created by xuxueli on 17/3/10.
 | 
			
		||||
 */
 | 
			
		||||
public class ExecutorRouteLFU extends ExecutorRouter {
 | 
			
		||||
 | 
			
		||||
    private static ConcurrentMap<Integer, HashMap<String, Integer>> jobLfuMap = new ConcurrentHashMap<Integer, HashMap<String, Integer>>();
 | 
			
		||||
    private static long CACHE_VALID_TIME = 0;
 | 
			
		||||
 | 
			
		||||
    public String route(int jobId, List<String> addressList) {
 | 
			
		||||
 | 
			
		||||
        // cache clear
 | 
			
		||||
        if (System.currentTimeMillis() > CACHE_VALID_TIME) {
 | 
			
		||||
            jobLfuMap.clear();
 | 
			
		||||
            CACHE_VALID_TIME = System.currentTimeMillis() + 1000 * 60 * 60 * 24;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // lfu item init
 | 
			
		||||
        HashMap<String, Integer> lfuItemMap = jobLfuMap.get(jobId);     // Key排序可以用TreeMap+构造入参Compare;Value排序暂时只能通过ArrayList;
 | 
			
		||||
        if (lfuItemMap == null) {
 | 
			
		||||
            lfuItemMap = new HashMap<String, Integer>();
 | 
			
		||||
            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<String> 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<Map.Entry<String, Integer>> lfuItemList = new ArrayList<Map.Entry<String, Integer>>(lfuItemMap.entrySet());
 | 
			
		||||
        Collections.sort(lfuItemList, new Comparator<Map.Entry<String, Integer>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
 | 
			
		||||
                return o1.getValue().compareTo(o2.getValue());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Map.Entry<String, Integer> addressItem = lfuItemList.get(0);
 | 
			
		||||
        String minAddress = addressItem.getKey();
 | 
			
		||||
        addressItem.setValue(addressItem.getValue() + 1);
 | 
			
		||||
 | 
			
		||||
        return addressItem.getKey();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) {
 | 
			
		||||
        String address = route(triggerParam.getJobId(), addressList);
 | 
			
		||||
        return new ReturnT<String>(address);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,76 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.route.strategy;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouter;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.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):最近最久未使用,时间
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Created by xuxueli on 17/3/10.
 | 
			
		||||
 */
 | 
			
		||||
public class ExecutorRouteLRU extends ExecutorRouter {
 | 
			
		||||
 | 
			
		||||
    private static ConcurrentMap<Integer, LinkedHashMap<String, String>> jobLRUMap = new ConcurrentHashMap<Integer, LinkedHashMap<String, String>>();
 | 
			
		||||
    private static long CACHE_VALID_TIME = 0;
 | 
			
		||||
 | 
			
		||||
    public String route(int jobId, List<String> addressList) {
 | 
			
		||||
 | 
			
		||||
        // cache clear
 | 
			
		||||
        if (System.currentTimeMillis() > CACHE_VALID_TIME) {
 | 
			
		||||
            jobLRUMap.clear();
 | 
			
		||||
            CACHE_VALID_TIME = System.currentTimeMillis() + 1000 * 60 * 60 * 24;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // init lru
 | 
			
		||||
        LinkedHashMap<String, String> lruItem = jobLRUMap.get(jobId);
 | 
			
		||||
        if (lruItem == null) {
 | 
			
		||||
            /**
 | 
			
		||||
             * LinkedHashMap
 | 
			
		||||
             *      a、accessOrder:true=访问顺序排序(get/put时排序);false=插入顺序排期;
 | 
			
		||||
             *      b、removeEldestEntry:新增元素时将会调用,返回true时会删除最老元素;可封装LinkedHashMap并重写该方法,比如定义最大容量,超出是返回true即可实现固定长度的LRU算法;
 | 
			
		||||
             */
 | 
			
		||||
            lruItem = new LinkedHashMap<String, String>(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<String> 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<String> route(TriggerParam triggerParam, List<String> addressList) {
 | 
			
		||||
        String address = route(triggerParam.getJobId(), addressList);
 | 
			
		||||
        return new ReturnT<String>(address);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.route.strategy;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouter;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.biz.model.TriggerParam;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by xuxueli on 17/3/10.
 | 
			
		||||
 */
 | 
			
		||||
public class ExecutorRouteLast extends ExecutorRouter {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) {
 | 
			
		||||
        return new ReturnT<String>(addressList.get(addressList.size() - 1));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.route.strategy;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouter;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.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<String> route(TriggerParam triggerParam, List<String> addressList) {
 | 
			
		||||
        String address = addressList.get(localRandom.nextInt(addressList.size()));
 | 
			
		||||
        return new ReturnT<String>(address);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.route.strategy;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouter;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.biz.model.TriggerParam;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
import java.util.concurrent.ConcurrentMap;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicInteger;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by xuxueli on 17/3/10.
 | 
			
		||||
 */
 | 
			
		||||
public class ExecutorRouteRound extends ExecutorRouter {
 | 
			
		||||
 | 
			
		||||
    private static ConcurrentMap<Integer, AtomicInteger> 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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AtomicInteger count = routeCountEachJob.get(jobId);
 | 
			
		||||
        if (count == null || count.get() > 1000000) {
 | 
			
		||||
            // 初始化时主动Random一次,缓解首次压力
 | 
			
		||||
            count = new AtomicInteger(new Random().nextInt(100));
 | 
			
		||||
        } else {
 | 
			
		||||
            // count++
 | 
			
		||||
            count.addAndGet(1);
 | 
			
		||||
        }
 | 
			
		||||
        routeCountEachJob.put(jobId, count);
 | 
			
		||||
        return count.get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) {
 | 
			
		||||
        String address = addressList.get(count(triggerParam.getJobId()) % addressList.size());
 | 
			
		||||
        return new ReturnT<String>(address);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,39 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.scheduler;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2020-10-29 21:11:23
 | 
			
		||||
 */
 | 
			
		||||
public enum MisfireStrategyEnum {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * do nothing
 | 
			
		||||
     */
 | 
			
		||||
    DO_NOTHING(I18nUtil.getString("misfire_strategy_do_nothing")),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * fire once now
 | 
			
		||||
     */
 | 
			
		||||
    FIRE_ONCE_NOW(I18nUtil.getString("misfire_strategy_fire_once_now"));
 | 
			
		||||
 | 
			
		||||
    private String title;
 | 
			
		||||
 | 
			
		||||
    MisfireStrategyEnum(String title) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getTitle() {
 | 
			
		||||
        return title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MisfireStrategyEnum match(String name, MisfireStrategyEnum defaultItem) {
 | 
			
		||||
        for (MisfireStrategyEnum item : MisfireStrategyEnum.values()) {
 | 
			
		||||
            if (item.name().equals(name)) {
 | 
			
		||||
                return item;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return defaultItem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.scheduler;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2020-10-29 21:11:23
 | 
			
		||||
 */
 | 
			
		||||
public enum ScheduleTypeEnum {
 | 
			
		||||
 | 
			
		||||
    NONE(I18nUtil.getString("schedule_type_none")),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * schedule by cron
 | 
			
		||||
     */
 | 
			
		||||
    CRON(I18nUtil.getString("schedule_type_cron")),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * schedule by fixed rate (in seconds)
 | 
			
		||||
     */
 | 
			
		||||
    FIX_RATE(I18nUtil.getString("schedule_type_fix_rate")),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * schedule by fix delay (in seconds), after the last time
 | 
			
		||||
     */
 | 
			
		||||
    /*FIX_DELAY(I18nUtil.getString("schedule_type_fix_delay"))*/;
 | 
			
		||||
 | 
			
		||||
    private String title;
 | 
			
		||||
 | 
			
		||||
    ScheduleTypeEnum(String title) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getTitle() {
 | 
			
		||||
        return title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ScheduleTypeEnum match(String name, ScheduleTypeEnum defaultItem) {
 | 
			
		||||
        for (ScheduleTypeEnum item : ScheduleTypeEnum.values()) {
 | 
			
		||||
            if (item.name().equals(name)) {
 | 
			
		||||
                return item;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return defaultItem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,102 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.scheduler;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
import com.xxl.job.admin.core.thread.*;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.core.biz.ExecutorBiz;
 | 
			
		||||
import com.xxl.job.core.biz.client.ExecutorBizClient;
 | 
			
		||||
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
 | 
			
		||||
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 XxlJobScheduler {
 | 
			
		||||
    private static final Logger logger = LoggerFactory.getLogger(XxlJobScheduler.class);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public void init() throws Exception {
 | 
			
		||||
        // init i18n
 | 
			
		||||
        initI18n();
 | 
			
		||||
 | 
			
		||||
        // admin trigger pool start
 | 
			
		||||
        JobTriggerPoolHelper.toStart();
 | 
			
		||||
 | 
			
		||||
        // admin registry monitor run
 | 
			
		||||
        JobRegistryHelper.getInstance().start();
 | 
			
		||||
 | 
			
		||||
        // admin fail-monitor run
 | 
			
		||||
        JobFailMonitorHelper.getInstance().start();
 | 
			
		||||
 | 
			
		||||
        // admin lose-monitor run ( depend on JobTriggerPoolHelper )
 | 
			
		||||
        JobCompleteHelper.getInstance().start();
 | 
			
		||||
 | 
			
		||||
        // admin log report start
 | 
			
		||||
        JobLogReportHelper.getInstance().start();
 | 
			
		||||
 | 
			
		||||
        // start-schedule  ( depend on JobTriggerPoolHelper )
 | 
			
		||||
        JobScheduleHelper.getInstance().start();
 | 
			
		||||
 | 
			
		||||
        logger.info(">>>>>>>>> init xxl-job admin success.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public void destroy() throws Exception {
 | 
			
		||||
 | 
			
		||||
        // stop-schedule
 | 
			
		||||
        JobScheduleHelper.getInstance().toStop();
 | 
			
		||||
 | 
			
		||||
        // admin log report stop
 | 
			
		||||
        JobLogReportHelper.getInstance().toStop();
 | 
			
		||||
 | 
			
		||||
        // admin lose-monitor stop
 | 
			
		||||
        JobCompleteHelper.getInstance().toStop();
 | 
			
		||||
 | 
			
		||||
        // admin fail-monitor stop
 | 
			
		||||
        JobFailMonitorHelper.getInstance().toStop();
 | 
			
		||||
 | 
			
		||||
        // admin registry stop
 | 
			
		||||
        JobRegistryHelper.getInstance().toStop();
 | 
			
		||||
 | 
			
		||||
        // admin trigger pool stop
 | 
			
		||||
        JobTriggerPoolHelper.toStop();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ---------------------- I18n ----------------------
 | 
			
		||||
 | 
			
		||||
    private void initI18n() {
 | 
			
		||||
        for (ExecutorBlockStrategyEnum item : ExecutorBlockStrategyEnum.values()) {
 | 
			
		||||
            item.setTitle(I18nUtil.getString("jobconf_block_".concat(item.name())));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ---------------------- executor-client ----------------------
 | 
			
		||||
    private static ConcurrentMap<String, ExecutorBiz> executorBizRepository = new ConcurrentHashMap<String, ExecutorBiz>();
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
        executorBiz = new ExecutorBizClient(address, XxlJobAdminConfig.getAdminConfig().getAccessToken());
 | 
			
		||||
 | 
			
		||||
        executorBizRepository.put(address, executorBiz);
 | 
			
		||||
        return executorBiz;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,185 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.thread;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.complete.XxlJobCompleter;
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLog;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.core.biz.model.HandleCallbackParam;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.util.DateUtil;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * job lose-monitor instance
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2015-9-1 18:05:56
 | 
			
		||||
 */
 | 
			
		||||
public class JobCompleteHelper {
 | 
			
		||||
    private static Logger logger = LoggerFactory.getLogger(JobCompleteHelper.class);
 | 
			
		||||
 | 
			
		||||
    private static JobCompleteHelper instance = new JobCompleteHelper();
 | 
			
		||||
 | 
			
		||||
    public static JobCompleteHelper getInstance() {
 | 
			
		||||
        return instance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ---------------------- monitor ----------------------
 | 
			
		||||
 | 
			
		||||
    private ThreadPoolExecutor callbackThreadPool = null;
 | 
			
		||||
    private Thread monitorThread;
 | 
			
		||||
    private volatile boolean toStop = false;
 | 
			
		||||
 | 
			
		||||
    public void start() {
 | 
			
		||||
 | 
			
		||||
        // for callback
 | 
			
		||||
        callbackThreadPool = new ThreadPoolExecutor(
 | 
			
		||||
            2,
 | 
			
		||||
            20,
 | 
			
		||||
            30L,
 | 
			
		||||
            TimeUnit.SECONDS,
 | 
			
		||||
            new LinkedBlockingQueue<Runnable>(3000),
 | 
			
		||||
            new ThreadFactory() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public Thread newThread(Runnable r) {
 | 
			
		||||
                    return new Thread(r, "xxl-job, admin JobLosedMonitorHelper-callbackThreadPool-" + r.hashCode());
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            new RejectedExecutionHandler() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
 | 
			
		||||
                    r.run();
 | 
			
		||||
                    logger.warn(">>>>>>>>>>> xxl-job, callback too fast, match threadpool rejected handler(run now).");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // for monitor
 | 
			
		||||
        monitorThread = new Thread(new Runnable() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
 | 
			
		||||
                // wait for JobTriggerPoolHelper-init
 | 
			
		||||
                try {
 | 
			
		||||
                    TimeUnit.MILLISECONDS.sleep(50);
 | 
			
		||||
                } catch (InterruptedException e) {
 | 
			
		||||
                    if (!toStop) {
 | 
			
		||||
                        logger.error(e.getMessage(), e);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // monitor
 | 
			
		||||
                while (!toStop) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        // 任务结果丢失处理:调度记录停留在 "运行中" 状态超过10min,且对应执行器心跳注册失败不在线,则将本地调度主动标记失败;
 | 
			
		||||
                        Date losedTime = DateUtil.addMinutes(new Date(), -10);
 | 
			
		||||
                        List<Long> losedJobIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLostJobIds(losedTime);
 | 
			
		||||
 | 
			
		||||
                        if (losedJobIds != null && losedJobIds.size() > 0) {
 | 
			
		||||
                            for (Long logId : losedJobIds) {
 | 
			
		||||
 | 
			
		||||
                                XxlJobLog jobLog = new XxlJobLog();
 | 
			
		||||
                                jobLog.setId(logId);
 | 
			
		||||
 | 
			
		||||
                                jobLog.setHandleTime(new Date());
 | 
			
		||||
                                jobLog.setHandleCode(ReturnT.FAIL_CODE);
 | 
			
		||||
                                jobLog.setHandleMsg(I18nUtil.getString("joblog_lost_fail"));
 | 
			
		||||
 | 
			
		||||
                                XxlJobCompleter.updateHandleInfoAndFinish(jobLog);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        if (!toStop) {
 | 
			
		||||
                            logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    try {
 | 
			
		||||
                        TimeUnit.SECONDS.sleep(60);
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        if (!toStop) {
 | 
			
		||||
                            logger.error(e.getMessage(), e);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                logger.info(">>>>>>>>>>> xxl-job, JobLosedMonitorHelper stop");
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        monitorThread.setDaemon(true);
 | 
			
		||||
        monitorThread.setName("xxl-job, admin JobLosedMonitorHelper");
 | 
			
		||||
        monitorThread.start();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void toStop() {
 | 
			
		||||
        toStop = true;
 | 
			
		||||
 | 
			
		||||
        // stop registryOrRemoveThreadPool
 | 
			
		||||
        callbackThreadPool.shutdownNow();
 | 
			
		||||
 | 
			
		||||
        // stop monitorThread (interrupt and wait)
 | 
			
		||||
        monitorThread.interrupt();
 | 
			
		||||
        try {
 | 
			
		||||
            monitorThread.join();
 | 
			
		||||
        } catch (InterruptedException e) {
 | 
			
		||||
            logger.error(e.getMessage(), e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // ---------------------- helper ----------------------
 | 
			
		||||
 | 
			
		||||
    public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList) {
 | 
			
		||||
 | 
			
		||||
        callbackThreadPool.execute(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                for (HandleCallbackParam handleCallbackParam : callbackParamList) {
 | 
			
		||||
                    ReturnT<String> callbackResult = callback(handleCallbackParam);
 | 
			
		||||
                    logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}",
 | 
			
		||||
                        (callbackResult.getCode() == ReturnT.SUCCESS_CODE ? "success" : "fail"), handleCallbackParam, callbackResult);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ReturnT<String> callback(HandleCallbackParam handleCallbackParam) {
 | 
			
		||||
        // valid log item
 | 
			
		||||
        XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(handleCallbackParam.getLogId());
 | 
			
		||||
        if (log == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, "log item not found.");
 | 
			
		||||
        }
 | 
			
		||||
        if (log.getHandleCode() > 0) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, "log repeate callback.");     // avoid repeat callback, trigger child job etc
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // handle msg
 | 
			
		||||
        StringBuffer handleMsg = new StringBuffer();
 | 
			
		||||
        if (log.getHandleMsg() != null) {
 | 
			
		||||
            handleMsg.append(log.getHandleMsg()).append("<br>");
 | 
			
		||||
        }
 | 
			
		||||
        if (handleCallbackParam.getHandleMsg() != null) {
 | 
			
		||||
            handleMsg.append(handleCallbackParam.getHandleMsg());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // success, save log
 | 
			
		||||
        log.setHandleTime(new Date());
 | 
			
		||||
        log.setHandleCode(handleCallbackParam.getHandleCode());
 | 
			
		||||
        log.setHandleMsg(handleMsg.toString());
 | 
			
		||||
        XxlJobCompleter.updateHandleInfoAndFinish(log);
 | 
			
		||||
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,112 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.thread;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLog;
 | 
			
		||||
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
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<Long> failLogIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findFailJobLogIds(1000);
 | 
			
		||||
                        if (failLogIds != null && !failLogIds.isEmpty()) {
 | 
			
		||||
                            for (long failLogId : failLogIds) {
 | 
			
		||||
 | 
			
		||||
                                // lock log
 | 
			
		||||
                                int lockRet = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, 0, -1);
 | 
			
		||||
                                if (lockRet < 1) {
 | 
			
		||||
                                    continue;
 | 
			
		||||
                                }
 | 
			
		||||
                                XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(failLogId);
 | 
			
		||||
                                XxlJobInfo info = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(log.getJobId());
 | 
			
		||||
 | 
			
		||||
                                // 1、fail retry monitor
 | 
			
		||||
                                if (log.getExecutorFailRetryCount() > 0) {
 | 
			
		||||
                                    JobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount() - 1), log.getExecutorShardingParam(), log.getExecutorParam(), null);
 | 
			
		||||
                                    String retryMsg = "<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>" + I18nUtil.getString("jobconf_trigger_type_retry") + "<<<<<<<<<<< </span><br>";
 | 
			
		||||
                                    log.setTriggerMsg(log.getTriggerMsg() + retryMsg);
 | 
			
		||||
                                    XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateTriggerInfo(log);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                // 2、fail alarm monitor
 | 
			
		||||
                                int newAlarmStatus = 0;        // 告警状态:0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败
 | 
			
		||||
                                if (info != null) {
 | 
			
		||||
                                    boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log);
 | 
			
		||||
                                    newAlarmStatus = alarmResult ? 2 : 3;
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    newAlarmStatus = 1;
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, -1, newAlarmStatus);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        if (!toStop) {
 | 
			
		||||
                            logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    try {
 | 
			
		||||
                        TimeUnit.SECONDS.sleep(10);
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        if (!toStop) {
 | 
			
		||||
                            logger.error(e.getMessage(), e);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                logger.info(">>>>>>>>>>> xxl-job, job fail monitor thread stop");
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        monitorThread.setDaemon(true);
 | 
			
		||||
        monitorThread.setName("xxl-job, 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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,154 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.thread;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLogReport;
 | 
			
		||||
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
 | 
			
		||||
                            XxlJobLogReport xxlJobLogReport = new XxlJobLogReport();
 | 
			
		||||
                            xxlJobLogReport.setTriggerDay(todayFrom);
 | 
			
		||||
                            xxlJobLogReport.setRunningCount(0);
 | 
			
		||||
                            xxlJobLogReport.setSucCount(0);
 | 
			
		||||
                            xxlJobLogReport.setFailCount(0);
 | 
			
		||||
 | 
			
		||||
                            Map<String, Object> triggerCountMap = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().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 = XxlJobAdminConfig.getAdminConfig().getXxlJobLogReportDao().update(xxlJobLogReport);
 | 
			
		||||
                            if (ret < 1) {
 | 
			
		||||
                                XxlJobAdminConfig.getAdminConfig().getXxlJobLogReportDao().save(xxlJobLogReport);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        if (!toStop) {
 | 
			
		||||
                            logger.error(">>>>>>>>>>> xxl-job, job log report thread error:{}", e);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // 2、log-clean: switch open & once each day
 | 
			
		||||
                    if (XxlJobAdminConfig.getAdminConfig().getLogretentiondays() > 0
 | 
			
		||||
                        && System.currentTimeMillis() - lastCleanLogTime > 24 * 60 * 60 * 1000) {
 | 
			
		||||
 | 
			
		||||
                        // expire-time
 | 
			
		||||
                        Calendar expiredDay = Calendar.getInstance();
 | 
			
		||||
                        expiredDay.add(Calendar.DAY_OF_MONTH, -1 * XxlJobAdminConfig.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<Long> logIds = null;
 | 
			
		||||
                        do {
 | 
			
		||||
                            logIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findClearLogIds(0, 0, clearBeforeTime, 0, 1000);
 | 
			
		||||
                            if (logIds != null && logIds.size() > 0) {
 | 
			
		||||
                                XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().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(">>>>>>>>>>> xxl-job, job log report thread stop");
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        logrThread.setDaemon(true);
 | 
			
		||||
        logrThread.setName("xxl-job, 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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,206 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.thread;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobGroup;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobRegistry;
 | 
			
		||||
import com.xxl.job.core.biz.model.RegistryParam;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.enums.RegistryConfig;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.concurrent.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * job registry instance
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2016-10-02 19:10:24
 | 
			
		||||
 */
 | 
			
		||||
public class JobRegistryHelper {
 | 
			
		||||
    private static Logger logger = LoggerFactory.getLogger(JobRegistryHelper.class);
 | 
			
		||||
 | 
			
		||||
    private static JobRegistryHelper instance = new JobRegistryHelper();
 | 
			
		||||
 | 
			
		||||
    public static JobRegistryHelper getInstance() {
 | 
			
		||||
        return instance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ThreadPoolExecutor registryOrRemoveThreadPool = null;
 | 
			
		||||
    private Thread registryMonitorThread;
 | 
			
		||||
    private volatile boolean toStop = false;
 | 
			
		||||
 | 
			
		||||
    public void start() {
 | 
			
		||||
 | 
			
		||||
        // for registry or remove
 | 
			
		||||
        registryOrRemoveThreadPool = new ThreadPoolExecutor(
 | 
			
		||||
            2,
 | 
			
		||||
            10,
 | 
			
		||||
            30L,
 | 
			
		||||
            TimeUnit.SECONDS,
 | 
			
		||||
            new LinkedBlockingQueue<Runnable>(2000),
 | 
			
		||||
            new ThreadFactory() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public Thread newThread(Runnable r) {
 | 
			
		||||
                    return new Thread(r, "xxl-job, admin JobRegistryMonitorHelper-registryOrRemoveThreadPool-" + r.hashCode());
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            new RejectedExecutionHandler() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
 | 
			
		||||
                    r.run();
 | 
			
		||||
                    logger.warn(">>>>>>>>>>> xxl-job, registry or remove too fast, match threadpool rejected handler(run now).");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        // for monitor
 | 
			
		||||
        registryMonitorThread = new Thread(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                while (!toStop) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        // auto registry group
 | 
			
		||||
                        List<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0);
 | 
			
		||||
                        if (groupList != null && !groupList.isEmpty()) {
 | 
			
		||||
 | 
			
		||||
                            // remove dead address (admin/executor)
 | 
			
		||||
                            List<Integer> ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
 | 
			
		||||
                            if (ids != null && ids.size() > 0) {
 | 
			
		||||
                                XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // fresh online address (admin/executor)
 | 
			
		||||
                            HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
 | 
			
		||||
                            List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
 | 
			
		||||
                            if (list != null) {
 | 
			
		||||
                                for (XxlJobRegistry item : list) {
 | 
			
		||||
                                    if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
 | 
			
		||||
                                        String appname = item.getRegistryKey();
 | 
			
		||||
                                        List<String> registryList = appAddressMap.get(appname);
 | 
			
		||||
                                        if (registryList == null) {
 | 
			
		||||
                                            registryList = new ArrayList<String>();
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        if (!registryList.contains(item.getRegistryValue())) {
 | 
			
		||||
                                            registryList.add(item.getRegistryValue());
 | 
			
		||||
                                        }
 | 
			
		||||
                                        appAddressMap.put(appname, registryList);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // fresh group address
 | 
			
		||||
                            for (XxlJobGroup group : groupList) {
 | 
			
		||||
                                List<String> registryList = appAddressMap.get(group.getAppname());
 | 
			
		||||
                                String addressListStr = null;
 | 
			
		||||
                                if (registryList != null && !registryList.isEmpty()) {
 | 
			
		||||
                                    Collections.sort(registryList);
 | 
			
		||||
                                    StringBuilder addressListSB = new StringBuilder();
 | 
			
		||||
                                    for (String item : registryList) {
 | 
			
		||||
                                        addressListSB.append(item).append(",");
 | 
			
		||||
                                    }
 | 
			
		||||
                                    addressListStr = addressListSB.toString();
 | 
			
		||||
                                    addressListStr = addressListStr.substring(0, addressListStr.length() - 1);
 | 
			
		||||
                                }
 | 
			
		||||
                                group.setAddressList(addressListStr);
 | 
			
		||||
                                group.setUpdateTime(new Date());
 | 
			
		||||
 | 
			
		||||
                                XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().update(group);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        if (!toStop) {
 | 
			
		||||
                            logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    try {
 | 
			
		||||
                        TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
 | 
			
		||||
                    } catch (InterruptedException e) {
 | 
			
		||||
                        if (!toStop) {
 | 
			
		||||
                            logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop");
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        registryMonitorThread.setDaemon(true);
 | 
			
		||||
        registryMonitorThread.setName("xxl-job, admin JobRegistryMonitorHelper-registryMonitorThread");
 | 
			
		||||
        registryMonitorThread.start();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void toStop() {
 | 
			
		||||
        toStop = true;
 | 
			
		||||
 | 
			
		||||
        // stop registryOrRemoveThreadPool
 | 
			
		||||
        registryOrRemoveThreadPool.shutdownNow();
 | 
			
		||||
 | 
			
		||||
        // stop monitir (interrupt and wait)
 | 
			
		||||
        registryMonitorThread.interrupt();
 | 
			
		||||
        try {
 | 
			
		||||
            registryMonitorThread.join();
 | 
			
		||||
        } catch (InterruptedException e) {
 | 
			
		||||
            logger.error(e.getMessage(), e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // ---------------------- helper ----------------------
 | 
			
		||||
 | 
			
		||||
    public ReturnT<String> registry(RegistryParam registryParam) {
 | 
			
		||||
 | 
			
		||||
        // valid
 | 
			
		||||
        if (!StringUtils.hasText(registryParam.getRegistryGroup())
 | 
			
		||||
            || !StringUtils.hasText(registryParam.getRegistryKey())
 | 
			
		||||
            || !StringUtils.hasText(registryParam.getRegistryValue())) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // async execute
 | 
			
		||||
        registryOrRemoveThreadPool.execute(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
 | 
			
		||||
                if (ret < 1) {
 | 
			
		||||
                    XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registrySave(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
 | 
			
		||||
 | 
			
		||||
                    // fresh
 | 
			
		||||
                    freshGroupRegistryInfo(registryParam);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ReturnT<String> registryRemove(RegistryParam registryParam) {
 | 
			
		||||
 | 
			
		||||
        // valid
 | 
			
		||||
        if (!StringUtils.hasText(registryParam.getRegistryGroup())
 | 
			
		||||
            || !StringUtils.hasText(registryParam.getRegistryKey())
 | 
			
		||||
            || !StringUtils.hasText(registryParam.getRegistryValue())) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // async execute
 | 
			
		||||
        registryOrRemoveThreadPool.execute(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryDelete(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue());
 | 
			
		||||
                if (ret > 0) {
 | 
			
		||||
                    // fresh
 | 
			
		||||
                    freshGroupRegistryInfo(registryParam);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void freshGroupRegistryInfo(RegistryParam registryParam) {
 | 
			
		||||
        // Under consideration, prevent affecting core tables
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,370 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.thread;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
import com.xxl.job.admin.core.cron.CronExpression;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
 | 
			
		||||
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
 | 
			
		||||
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
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<Integer, List<Integer>> 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 xxl-job admin scheduler success.");
 | 
			
		||||
 | 
			
		||||
                // pre-read count: treadpool-size * trigger-qps (each trigger cost 50ms, qps = 1000/50 = 20)
 | 
			
		||||
                int preReadCount = (XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax() + XxlJobAdminConfig.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 = XxlJobAdminConfig.getAdminConfig().getDataSource().getConnection();
 | 
			
		||||
                        connAutoCommit = conn.getAutoCommit();
 | 
			
		||||
                        conn.setAutoCommit(false);
 | 
			
		||||
 | 
			
		||||
                        preparedStatement = conn.prepareStatement("select * from xxl_job_lock where lock_name = 'schedule_lock' for update");
 | 
			
		||||
                        preparedStatement.execute();
 | 
			
		||||
 | 
			
		||||
                        // tx start
 | 
			
		||||
 | 
			
		||||
                        // 1、pre read
 | 
			
		||||
                        long nowTime = System.currentTimeMillis();
 | 
			
		||||
                        List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount);
 | 
			
		||||
                        if (scheduleList != null && scheduleList.size() > 0) {
 | 
			
		||||
                            // 2、push time-ring
 | 
			
		||||
                            for (XxlJobInfo jobInfo : scheduleList) {
 | 
			
		||||
 | 
			
		||||
                                // time-ring jump
 | 
			
		||||
                                if (nowTime > jobInfo.getTriggerNextTime() + PRE_READ_MS) {
 | 
			
		||||
                                    // 2.1、trigger-expire > 5s:pass && make next-trigger-time
 | 
			
		||||
                                    logger.warn(">>>>>>>>>>> xxl-job, schedule misfire, jobId = " + jobInfo.getId());
 | 
			
		||||
 | 
			
		||||
                                    // 1、misfire match
 | 
			
		||||
                                    MisfireStrategyEnum misfireStrategyEnum = MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), MisfireStrategyEnum.DO_NOTHING);
 | 
			
		||||
                                    if (MisfireStrategyEnum.FIRE_ONCE_NOW == misfireStrategyEnum) {
 | 
			
		||||
                                        // FIRE_ONCE_NOW 》 trigger
 | 
			
		||||
                                        JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.MISFIRE, -1, null, null, null);
 | 
			
		||||
                                        logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId());
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    // 2、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, null);
 | 
			
		||||
                                    logger.debug(">>>>>>>>>>> xxl-job, 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 (XxlJobInfo jobInfo : scheduleList) {
 | 
			
		||||
                                XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleUpdate(jobInfo);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        } else {
 | 
			
		||||
                            preReadSuc = false;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // tx stop
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        if (!scheduleThreadToStop) {
 | 
			
		||||
                            logger.error(">>>>>>>>>>> xxl-job, 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(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread stop");
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        scheduleThread.setDaemon(true);
 | 
			
		||||
        scheduleThread.setName("xxl-job, admin JobScheduleHelper#scheduleThread");
 | 
			
		||||
        scheduleThread.start();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // ring thread
 | 
			
		||||
        ringThread = new Thread(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
 | 
			
		||||
                while (!ringThreadToStop) {
 | 
			
		||||
 | 
			
		||||
                    // align second
 | 
			
		||||
                    try {
 | 
			
		||||
                        TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
 | 
			
		||||
                    } catch (InterruptedException e) {
 | 
			
		||||
                        if (!ringThreadToStop) {
 | 
			
		||||
                            logger.error(e.getMessage(), e);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    try {
 | 
			
		||||
                        // second data
 | 
			
		||||
                        List<Integer> ringItemData = new ArrayList<>();
 | 
			
		||||
                        int nowSecond = Calendar.getInstance().get(Calendar.SECOND);   // 避免处理耗时太长,跨过刻度,向前校验一个刻度;
 | 
			
		||||
                        for (int i = 0; i < 2; i++) {
 | 
			
		||||
                            List<Integer> tmpData = ringData.remove((nowSecond + 60 - i) % 60);
 | 
			
		||||
                            if (tmpData != null) {
 | 
			
		||||
                                ringItemData.addAll(tmpData);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // ring trigger
 | 
			
		||||
                        logger.debug(">>>>>>>>>>> xxl-job, 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, null);
 | 
			
		||||
                            }
 | 
			
		||||
                            // clear
 | 
			
		||||
                            ringItemData.clear();
 | 
			
		||||
                        }
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        if (!ringThreadToStop) {
 | 
			
		||||
                            logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread error:{}", e);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread stop");
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        ringThread.setDaemon(true);
 | 
			
		||||
        ringThread.setName("xxl-job, admin JobScheduleHelper#ringThread");
 | 
			
		||||
        ringThread.start();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void refreshNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception {
 | 
			
		||||
        Date nextValidTime = generateNextValidTime(jobInfo, fromTime);
 | 
			
		||||
        if (nextValidTime != null) {
 | 
			
		||||
            jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
 | 
			
		||||
            jobInfo.setTriggerNextTime(nextValidTime.getTime());
 | 
			
		||||
        } else {
 | 
			
		||||
            jobInfo.setTriggerStatus(0);
 | 
			
		||||
            jobInfo.setTriggerLastTime(0);
 | 
			
		||||
            jobInfo.setTriggerNextTime(0);
 | 
			
		||||
            logger.warn(">>>>>>>>>>> xxl-job, refreshNextValidTime fail for job: jobId={}, scheduleType={}, scheduleConf={}",
 | 
			
		||||
                jobInfo.getId(), jobInfo.getScheduleType(), jobInfo.getScheduleConf());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void pushTimeRing(int ringSecond, int jobId) {
 | 
			
		||||
        // push async ring
 | 
			
		||||
        List<Integer> ringItemData = ringData.get(ringSecond);
 | 
			
		||||
        if (ringItemData == null) {
 | 
			
		||||
            ringItemData = new ArrayList<Integer>();
 | 
			
		||||
            ringData.put(ringSecond, ringItemData);
 | 
			
		||||
        }
 | 
			
		||||
        ringItemData.add(jobId);
 | 
			
		||||
 | 
			
		||||
        logger.debug(">>>>>>>>>>> xxl-job, 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<Integer> 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(">>>>>>>>>>> xxl-job, JobScheduleHelper stop");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // ---------------------- tools ----------------------
 | 
			
		||||
    public static Date generateNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception {
 | 
			
		||||
        ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null);
 | 
			
		||||
        if (ScheduleTypeEnum.CRON == scheduleTypeEnum) {
 | 
			
		||||
            Date nextValidTime = new CronExpression(jobInfo.getScheduleConf()).getNextValidTimeAfter(fromTime);
 | 
			
		||||
            return nextValidTime;
 | 
			
		||||
        } else if (ScheduleTypeEnum.FIX_RATE == scheduleTypeEnum /*|| ScheduleTypeEnum.FIX_DELAY == scheduleTypeEnum*/) {
 | 
			
		||||
            return new Date(fromTime.getTime() + Integer.valueOf(jobInfo.getScheduleConf()) * 1000);
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,148 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.thread;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
 | 
			
		||||
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
 | 
			
		||||
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,
 | 
			
		||||
            XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax(),
 | 
			
		||||
            60L,
 | 
			
		||||
            TimeUnit.SECONDS,
 | 
			
		||||
            new LinkedBlockingQueue<Runnable>(1000),
 | 
			
		||||
            new ThreadFactory() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public Thread newThread(Runnable r) {
 | 
			
		||||
                    return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-fastTriggerPool-" + r.hashCode());
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        slowTriggerPool = new ThreadPoolExecutor(
 | 
			
		||||
            10,
 | 
			
		||||
            XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax(),
 | 
			
		||||
            60L,
 | 
			
		||||
            TimeUnit.SECONDS,
 | 
			
		||||
            new LinkedBlockingQueue<Runnable>(2000),
 | 
			
		||||
            new ThreadFactory() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public Thread newThread(Runnable r) {
 | 
			
		||||
                    return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-" + r.hashCode());
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public void stop() {
 | 
			
		||||
        //triggerPool.shutdown();
 | 
			
		||||
        fastTriggerPool.shutdownNow();
 | 
			
		||||
        slowTriggerPool.shutdownNow();
 | 
			
		||||
        logger.info(">>>>>>>>> xxl-job trigger thread pool shutdown success.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // job timeout count
 | 
			
		||||
    private volatile long minTim = System.currentTimeMillis() / 60000;     // ms > min
 | 
			
		||||
    private volatile ConcurrentMap<Integer, AtomicInteger> jobTimeoutCountMap = new ConcurrentHashMap<>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * add trigger
 | 
			
		||||
     */
 | 
			
		||||
    public void addTrigger(final int jobId,
 | 
			
		||||
                           final TriggerTypeEnum triggerType,
 | 
			
		||||
                           final int failRetryCount,
 | 
			
		||||
                           final String executorShardingParam,
 | 
			
		||||
                           final String executorParam,
 | 
			
		||||
                           final String addressList) {
 | 
			
		||||
 | 
			
		||||
        // 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(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
 | 
			
		||||
                long start = System.currentTimeMillis();
 | 
			
		||||
 | 
			
		||||
                try {
 | 
			
		||||
                    // do trigger
 | 
			
		||||
                    XxlJobTrigger.trigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam, addressList);
 | 
			
		||||
                } 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, String addressList) {
 | 
			
		||||
        helper.addTrigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam, addressList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,29 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.trigger;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.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")),
 | 
			
		||||
    MISFIRE(I18nUtil.getString("jobconf_trigger_type_misfire"));
 | 
			
		||||
 | 
			
		||||
    private TriggerTypeEnum(String title) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String title;
 | 
			
		||||
 | 
			
		||||
    public String getTitle() {
 | 
			
		||||
        return title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,224 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.trigger;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobGroup;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLog;
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
 | 
			
		||||
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.core.biz.ExecutorBiz;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.biz.model.TriggerParam;
 | 
			
		||||
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
 | 
			
		||||
import com.xxl.job.core.util.IpUtil;
 | 
			
		||||
import com.xxl.job.core.util.ThrowableUtil;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * xxl-job trigger
 | 
			
		||||
 * Created by xuxueli on 17/7/13.
 | 
			
		||||
 */
 | 
			
		||||
public class XxlJobTrigger {
 | 
			
		||||
    private static Logger logger = LoggerFactory.getLogger(XxlJobTrigger.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
 | 
			
		||||
     * @param addressList           null: use executor addressList
 | 
			
		||||
     *                              not null: cover
 | 
			
		||||
     */
 | 
			
		||||
    public static void trigger(int jobId,
 | 
			
		||||
                               TriggerTypeEnum triggerType,
 | 
			
		||||
                               int failRetryCount,
 | 
			
		||||
                               String executorShardingParam,
 | 
			
		||||
                               String executorParam,
 | 
			
		||||
                               String addressList) {
 | 
			
		||||
 | 
			
		||||
        // load data
 | 
			
		||||
        XxlJobInfo jobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(jobId);
 | 
			
		||||
        if (jobInfo == null) {
 | 
			
		||||
            logger.warn(">>>>>>>>>>>> trigger fail, jobId invalid,jobId={}", jobId);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (executorParam != null) {
 | 
			
		||||
            jobInfo.setExecutorParam(executorParam);
 | 
			
		||||
        }
 | 
			
		||||
        int finalFailRetryCount = failRetryCount >= 0 ? failRetryCount : jobInfo.getExecutorFailRetryCount();
 | 
			
		||||
        XxlJobGroup group = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().load(jobInfo.getJobGroup());
 | 
			
		||||
 | 
			
		||||
        // cover addressList
 | 
			
		||||
        if (addressList != null && addressList.trim().length() > 0) {
 | 
			
		||||
            group.setAddressType(1);
 | 
			
		||||
            group.setAddressList(addressList.trim());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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(XxlJobGroup group, XxlJobInfo jobInfo, int finalFailRetryCount, TriggerTypeEnum triggerType, int index, int total) {
 | 
			
		||||
 | 
			
		||||
        // 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
 | 
			
		||||
        XxlJobLog jobLog = new XxlJobLog();
 | 
			
		||||
        jobLog.setJobGroup(jobInfo.getJobGroup());
 | 
			
		||||
        jobLog.setJobId(jobInfo.getId());
 | 
			
		||||
        jobLog.setTriggerTime(new Date());
 | 
			
		||||
        XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().save(jobLog);
 | 
			
		||||
        logger.debug(">>>>>>>>>>> xxl-job trigger start, jobId:{}", jobLog.getId());
 | 
			
		||||
 | 
			
		||||
        // 2、init trigger-param
 | 
			
		||||
        TriggerParam triggerParam = new TriggerParam();
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        // 3、init address
 | 
			
		||||
        String address = null;
 | 
			
		||||
        ReturnT<String> 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<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobconf_trigger_address_empty"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 4、trigger remote executor
 | 
			
		||||
        ReturnT<String> triggerResult = null;
 | 
			
		||||
        if (address != null) {
 | 
			
		||||
            triggerResult = runExecutor(triggerParam, address);
 | 
			
		||||
        } else {
 | 
			
		||||
            triggerResult = new ReturnT<String>(ReturnT.FAIL_CODE, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 5、collection trigger info
 | 
			
		||||
        StringBuffer triggerMsgSb = new StringBuffer();
 | 
			
		||||
        triggerMsgSb.append(I18nUtil.getString("jobconf_trigger_type")).append(":").append(triggerType.getTitle());
 | 
			
		||||
        triggerMsgSb.append("<br>").append(I18nUtil.getString("jobconf_trigger_admin_adress")).append(":").append(IpUtil.getIp());
 | 
			
		||||
        triggerMsgSb.append("<br>").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("<br>").append(I18nUtil.getString("jobconf_trigger_exe_regaddress")).append(":").append(group.getRegistryList());
 | 
			
		||||
        triggerMsgSb.append("<br>").append(I18nUtil.getString("jobinfo_field_executorRouteStrategy")).append(":").append(executorRouteStrategyEnum.getTitle());
 | 
			
		||||
        if (shardingParam != null) {
 | 
			
		||||
            triggerMsgSb.append("(" + shardingParam + ")");
 | 
			
		||||
        }
 | 
			
		||||
        triggerMsgSb.append("<br>").append(I18nUtil.getString("jobinfo_field_executorBlockStrategy")).append(":").append(blockStrategy.getTitle());
 | 
			
		||||
        triggerMsgSb.append("<br>").append(I18nUtil.getString("jobinfo_field_timeout")).append(":").append(jobInfo.getExecutorTimeout());
 | 
			
		||||
        triggerMsgSb.append("<br>").append(I18nUtil.getString("jobinfo_field_executorFailRetryCount")).append(":").append(finalFailRetryCount);
 | 
			
		||||
 | 
			
		||||
        triggerMsgSb.append("<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>" + I18nUtil.getString("jobconf_trigger_run") + "<<<<<<<<<<< </span><br>")
 | 
			
		||||
            .append((routeAddressResult != null && routeAddressResult.getMsg() != null) ? routeAddressResult.getMsg() + "<br><br>" : "").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.setTriggerTime();
 | 
			
		||||
        jobLog.setTriggerCode(triggerResult.getCode());
 | 
			
		||||
        jobLog.setTriggerMsg(triggerMsgSb.toString());
 | 
			
		||||
        XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateTriggerInfo(jobLog);
 | 
			
		||||
 | 
			
		||||
        logger.debug(">>>>>>>>>>> xxl-job trigger end, jobId:{}", jobLog.getId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * run executor
 | 
			
		||||
     *
 | 
			
		||||
     * @param triggerParam
 | 
			
		||||
     * @param address
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static ReturnT<String> runExecutor(TriggerParam triggerParam, String address) {
 | 
			
		||||
        ReturnT<String> runResult = null;
 | 
			
		||||
        try {
 | 
			
		||||
            ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address);
 | 
			
		||||
            runResult = executorBiz.run(triggerParam);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error(">>>>>>>>>>> xxl-job trigger error, please check if the executor[{}] is running.", address, e);
 | 
			
		||||
            runResult = new ReturnT<String>(ReturnT.FAIL_CODE, ThrowableUtil.toString(e));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        StringBuffer runResultSB = new StringBuffer(I18nUtil.getString("jobconf_trigger_run") + ":");
 | 
			
		||||
        runResultSB.append("<br>address:").append(address);
 | 
			
		||||
        runResultSB.append("<br>code:").append(runResult.getCode());
 | 
			
		||||
        runResultSB.append("<br>msg:").append(runResult.getMsg());
 | 
			
		||||
 | 
			
		||||
        runResult.setMsg(runResultSB.toString());
 | 
			
		||||
        return runResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,98 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.util;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.http.Cookie;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cookie.Util
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2015-12-12 18:01:06
 | 
			
		||||
 */
 | 
			
		||||
public class CookieUtil {
 | 
			
		||||
 | 
			
		||||
    // 默认缓存时间,单位/秒, 2H
 | 
			
		||||
    private static final int COOKIE_MAX_AGE = Integer.MAX_VALUE;
 | 
			
		||||
    // 保存路径,根路径
 | 
			
		||||
    private static final String COOKIE_PATH = "/";
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 保存
 | 
			
		||||
     *
 | 
			
		||||
     * @param response
 | 
			
		||||
     * @param key
 | 
			
		||||
     * @param value
 | 
			
		||||
     * @param ifRemember
 | 
			
		||||
     */
 | 
			
		||||
    public static void set(HttpServletResponse response, String key, String value, boolean ifRemember) {
 | 
			
		||||
        int age = ifRemember ? COOKIE_MAX_AGE : -1;
 | 
			
		||||
        set(response, key, value, null, COOKIE_PATH, age, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 保存
 | 
			
		||||
     *
 | 
			
		||||
     * @param response
 | 
			
		||||
     * @param key
 | 
			
		||||
     * @param value
 | 
			
		||||
     * @param maxAge
 | 
			
		||||
     */
 | 
			
		||||
    private static void set(HttpServletResponse response, String key, String value, String domain, String path, int maxAge, boolean isHttpOnly) {
 | 
			
		||||
        Cookie cookie = new Cookie(key, value);
 | 
			
		||||
        if (domain != null) {
 | 
			
		||||
            cookie.setDomain(domain);
 | 
			
		||||
        }
 | 
			
		||||
        cookie.setPath(path);
 | 
			
		||||
        cookie.setMaxAge(maxAge);
 | 
			
		||||
        cookie.setHttpOnly(isHttpOnly);
 | 
			
		||||
        response.addCookie(cookie);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 查询value
 | 
			
		||||
     *
 | 
			
		||||
     * @param request
 | 
			
		||||
     * @param key
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static String getValue(HttpServletRequest request, String key) {
 | 
			
		||||
        Cookie cookie = get(request, key);
 | 
			
		||||
        if (cookie != null) {
 | 
			
		||||
            return cookie.getValue();
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 查询Cookie
 | 
			
		||||
     *
 | 
			
		||||
     * @param request
 | 
			
		||||
     * @param key
 | 
			
		||||
     */
 | 
			
		||||
    private static Cookie get(HttpServletRequest request, String key) {
 | 
			
		||||
        Cookie[] arr_cookie = request.getCookies();
 | 
			
		||||
        if (arr_cookie != null && arr_cookie.length > 0) {
 | 
			
		||||
            for (Cookie cookie : arr_cookie) {
 | 
			
		||||
                if (cookie.getName().equals(key)) {
 | 
			
		||||
                    return cookie;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 删除Cookie
 | 
			
		||||
     *
 | 
			
		||||
     * @param request
 | 
			
		||||
     * @param response
 | 
			
		||||
     * @param key
 | 
			
		||||
     */
 | 
			
		||||
    public static void remove(HttpServletRequest request, HttpServletResponse response, String key) {
 | 
			
		||||
        Cookie cookie = get(request, key);
 | 
			
		||||
        if (cookie != null) {
 | 
			
		||||
            set(response, key, "", null, COOKIE_PATH, 0, true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.util;
 | 
			
		||||
 | 
			
		||||
import freemarker.ext.beans.BeansWrapper;
 | 
			
		||||
import freemarker.ext.beans.BeansWrapperBuilder;
 | 
			
		||||
import freemarker.template.Configuration;
 | 
			
		||||
import freemarker.template.TemplateHashModel;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ftl util
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2018-01-17 20:37:48
 | 
			
		||||
 */
 | 
			
		||||
public class FtlUtil {
 | 
			
		||||
    private static Logger logger = LoggerFactory.getLogger(FtlUtil.class);
 | 
			
		||||
 | 
			
		||||
    private static BeansWrapper wrapper = new BeansWrapperBuilder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS).build();     //BeansWrapper.getDefaultInstance();
 | 
			
		||||
 | 
			
		||||
    public static TemplateHashModel generateStaticModel(String packageName) {
 | 
			
		||||
        try {
 | 
			
		||||
            TemplateHashModel staticModels = wrapper.getStaticModels();
 | 
			
		||||
            TemplateHashModel fileStatics = (TemplateHashModel) staticModels.get(packageName);
 | 
			
		||||
            return fileStatics;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error(e.getMessage(), e);
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,80 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.core.util;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
 | 
			
		||||
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 = XxlJobAdminConfig.getAdminConfig().getI18n();
 | 
			
		||||
            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<String, String> map = new HashMap<String, String>();
 | 
			
		||||
 | 
			
		||||
        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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,93 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.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
 | 
			
		||||
 * <p>
 | 
			
		||||
 * 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 OBJECT_MAPPER = new ObjectMapper();
 | 
			
		||||
 | 
			
		||||
    public static ObjectMapper getInstance() {
 | 
			
		||||
        return OBJECT_MAPPER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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> T readValue(String jsonStr, Class<T> 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<Bean>...
 | 
			
		||||
     *
 | 
			
		||||
     * @param jsonStr
 | 
			
		||||
     * @param parametrized
 | 
			
		||||
     * @param parameterClasses
 | 
			
		||||
     * @param <T>
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static <T> 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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,134 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.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<String, LocalCacheData> cacheRepository = new ConcurrentHashMap<String, LocalCacheData>();   // 类型建议用抽象父类,兼容性更好;
 | 
			
		||||
 | 
			
		||||
    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()) {
 | 
			
		||||
            return localCacheData.getVal();
 | 
			
		||||
        } else {
 | 
			
		||||
            remove(key);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * clean timeout cache
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean cleanTimeoutCache() {
 | 
			
		||||
        if (!cacheRepository.keySet().isEmpty()) {
 | 
			
		||||
            for (String key : cacheRepository.keySet()) {
 | 
			
		||||
                LocalCacheData localCacheData = cacheRepository.get(key);
 | 
			
		||||
                if (localCacheData != null && System.currentTimeMillis() >= localCacheData.getTimeoutTime()) {
 | 
			
		||||
                    cacheRepository.remove(key);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,37 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.dao;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobGroup;
 | 
			
		||||
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 XxlJobGroupDao {
 | 
			
		||||
 | 
			
		||||
    public List<XxlJobGroup> findAll();
 | 
			
		||||
 | 
			
		||||
    public List<XxlJobGroup> findByAddressType(@Param("addressType") int addressType);
 | 
			
		||||
 | 
			
		||||
    public int save(XxlJobGroup xxlJobGroup);
 | 
			
		||||
 | 
			
		||||
    public int update(XxlJobGroup xxlJobGroup);
 | 
			
		||||
 | 
			
		||||
    public int remove(@Param("id") int id);
 | 
			
		||||
 | 
			
		||||
    public XxlJobGroup load(@Param("id") int id);
 | 
			
		||||
 | 
			
		||||
    public List<XxlJobGroup> pageList(@Param("offset") int offset,
 | 
			
		||||
                                      @Param("pagesize") int pagesize,
 | 
			
		||||
                                      @Param("appname") String appname,
 | 
			
		||||
                                      @Param("title") String title);
 | 
			
		||||
 | 
			
		||||
    public int pageListCount(@Param("offset") int offset,
 | 
			
		||||
                             @Param("pagesize") int pagesize,
 | 
			
		||||
                             @Param("appname") String appname,
 | 
			
		||||
                             @Param("title") String title);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,51 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.dao;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
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 XxlJobInfoDao {
 | 
			
		||||
 | 
			
		||||
    public List<XxlJobInfo> pageList(@Param("offset") int offset,
 | 
			
		||||
                                     @Param("pagesize") int pagesize,
 | 
			
		||||
                                     @Param("jobGroup") int jobGroup,
 | 
			
		||||
                                     @Param("triggerStatus") int triggerStatus,
 | 
			
		||||
                                     @Param("jobDesc") String jobDesc,
 | 
			
		||||
                                     @Param("executorHandler") String executorHandler,
 | 
			
		||||
                                     @Param("author") String author);
 | 
			
		||||
 | 
			
		||||
    public int pageListCount(@Param("offset") int offset,
 | 
			
		||||
                             @Param("pagesize") int pagesize,
 | 
			
		||||
                             @Param("jobGroup") int jobGroup,
 | 
			
		||||
                             @Param("triggerStatus") int triggerStatus,
 | 
			
		||||
                             @Param("jobDesc") String jobDesc,
 | 
			
		||||
                             @Param("executorHandler") String executorHandler,
 | 
			
		||||
                             @Param("author") String author);
 | 
			
		||||
 | 
			
		||||
    public int save(XxlJobInfo info);
 | 
			
		||||
 | 
			
		||||
    public XxlJobInfo loadById(@Param("id") int id);
 | 
			
		||||
 | 
			
		||||
    public int update(XxlJobInfo xxlJobInfo);
 | 
			
		||||
 | 
			
		||||
    public int delete(@Param("id") long id);
 | 
			
		||||
 | 
			
		||||
    public List<XxlJobInfo> getJobsByGroup(@Param("jobGroup") int jobGroup);
 | 
			
		||||
 | 
			
		||||
    public int findAllCount();
 | 
			
		||||
 | 
			
		||||
    public List<XxlJobInfo> scheduleJobQuery(@Param("maxNextTime") long maxNextTime, @Param("pagesize") int pagesize);
 | 
			
		||||
 | 
			
		||||
    public int scheduleUpdate(XxlJobInfo xxlJobInfo);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,65 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.dao;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLog;
 | 
			
		||||
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 XxlJobLogDao {
 | 
			
		||||
 | 
			
		||||
    // exist jobId not use jobGroup, not exist use jobGroup
 | 
			
		||||
    public List<XxlJobLog> 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);
 | 
			
		||||
 | 
			
		||||
    public 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);
 | 
			
		||||
 | 
			
		||||
    public XxlJobLog load(@Param("id") long id);
 | 
			
		||||
 | 
			
		||||
    public long save(XxlJobLog xxlJobLog);
 | 
			
		||||
 | 
			
		||||
    public int updateTriggerInfo(XxlJobLog xxlJobLog);
 | 
			
		||||
 | 
			
		||||
    public int updateHandleInfo(XxlJobLog xxlJobLog);
 | 
			
		||||
 | 
			
		||||
    public int delete(@Param("jobId") int jobId);
 | 
			
		||||
 | 
			
		||||
    public Map<String, Object> findLogReport(@Param("from") Date from,
 | 
			
		||||
                                             @Param("to") Date to);
 | 
			
		||||
 | 
			
		||||
    public List<Long> findClearLogIds(@Param("jobGroup") int jobGroup,
 | 
			
		||||
                                      @Param("jobId") int jobId,
 | 
			
		||||
                                      @Param("clearBeforeTime") Date clearBeforeTime,
 | 
			
		||||
                                      @Param("clearBeforeNum") int clearBeforeNum,
 | 
			
		||||
                                      @Param("pagesize") int pagesize);
 | 
			
		||||
 | 
			
		||||
    public int clearLog(@Param("logIds") List<Long> logIds);
 | 
			
		||||
 | 
			
		||||
    public List<Long> findFailJobLogIds(@Param("pagesize") int pagesize);
 | 
			
		||||
 | 
			
		||||
    public int updateAlarmStatus(@Param("logId") long logId,
 | 
			
		||||
                                 @Param("oldAlarmStatus") int oldAlarmStatus,
 | 
			
		||||
                                 @Param("newAlarmStatus") int newAlarmStatus);
 | 
			
		||||
 | 
			
		||||
    public List<Long> findLostJobIds(@Param("losedTime") Date losedTime);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.dao;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLogGlue;
 | 
			
		||||
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 XxlJobLogGlueDao {
 | 
			
		||||
 | 
			
		||||
    public int save(XxlJobLogGlue xxlJobLogGlue);
 | 
			
		||||
 | 
			
		||||
    public List<XxlJobLogGlue> findByJobId(@Param("jobId") int jobId);
 | 
			
		||||
 | 
			
		||||
    public int removeOld(@Param("jobId") int jobId, @Param("limit") int limit);
 | 
			
		||||
 | 
			
		||||
    public int deleteByJobId(@Param("jobId") int jobId);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.dao;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLogReport;
 | 
			
		||||
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 XxlJobLogReportDao {
 | 
			
		||||
 | 
			
		||||
    public int save(XxlJobLogReport xxlJobLogReport);
 | 
			
		||||
 | 
			
		||||
    public int update(XxlJobLogReport xxlJobLogReport);
 | 
			
		||||
 | 
			
		||||
    public List<XxlJobLogReport> queryLogReport(@Param("triggerDayFrom") Date triggerDayFrom,
 | 
			
		||||
                                                @Param("triggerDayTo") Date triggerDayTo);
 | 
			
		||||
 | 
			
		||||
    public XxlJobLogReport queryLogReportTotal();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.dao;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobRegistry;
 | 
			
		||||
import org.apache.ibatis.annotations.Mapper;
 | 
			
		||||
import org.apache.ibatis.annotations.Param;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by xuxueli on 16/9/30.
 | 
			
		||||
 */
 | 
			
		||||
@Mapper
 | 
			
		||||
public interface XxlJobRegistryDao {
 | 
			
		||||
 | 
			
		||||
    public List<Integer> findDead(@Param("timeout") int timeout,
 | 
			
		||||
                                  @Param("nowTime") Date nowTime);
 | 
			
		||||
 | 
			
		||||
    public int removeDead(@Param("ids") List<Integer> ids);
 | 
			
		||||
 | 
			
		||||
    public List<XxlJobRegistry> 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("updateTime") Date updateTime);
 | 
			
		||||
 | 
			
		||||
    public int registrySave(@Param("registryGroup") String registryGroup,
 | 
			
		||||
                            @Param("registryKey") String registryKey,
 | 
			
		||||
                            @Param("registryValue") String registryValue,
 | 
			
		||||
                            @Param("updateTime") Date updateTime);
 | 
			
		||||
 | 
			
		||||
    public int registryDelete(@Param("registryGroup") String registryGroup,
 | 
			
		||||
                              @Param("registryKey") String registryKey,
 | 
			
		||||
                              @Param("registryValue") String registryValue);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,33 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.dao;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobUser;
 | 
			
		||||
import org.apache.ibatis.annotations.Mapper;
 | 
			
		||||
import org.apache.ibatis.annotations.Param;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2019-05-04 16:44:59
 | 
			
		||||
 */
 | 
			
		||||
@Mapper
 | 
			
		||||
public interface XxlJobUserDao {
 | 
			
		||||
 | 
			
		||||
    public List<XxlJobUser> pageList(@Param("offset") int offset,
 | 
			
		||||
                                     @Param("pagesize") int pagesize,
 | 
			
		||||
                                     @Param("username") String username,
 | 
			
		||||
                                     @Param("role") int role);
 | 
			
		||||
 | 
			
		||||
    public int pageListCount(@Param("offset") int offset,
 | 
			
		||||
                             @Param("pagesize") int pagesize,
 | 
			
		||||
                             @Param("username") String username,
 | 
			
		||||
                             @Param("role") int role);
 | 
			
		||||
 | 
			
		||||
    public XxlJobUser loadByUserName(@Param("username") String username);
 | 
			
		||||
 | 
			
		||||
    public int save(XxlJobUser xxlJobUser);
 | 
			
		||||
 | 
			
		||||
    public int update(XxlJobUser xxlJobUser);
 | 
			
		||||
 | 
			
		||||
    public int delete(@Param("id") int id);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,108 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.service;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobUser;
 | 
			
		||||
import com.xxl.job.admin.core.util.CookieUtil;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.admin.core.util.JacksonUtil;
 | 
			
		||||
import com.xxl.job.admin.dao.XxlJobUserDao;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.util.DigestUtils;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.math.BigInteger;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2019-05-04 22:13:264
 | 
			
		||||
 */
 | 
			
		||||
@Configuration
 | 
			
		||||
public class LoginService {
 | 
			
		||||
 | 
			
		||||
    public static final String LOGIN_IDENTITY_KEY = "XXL_JOB_LOGIN_IDENTITY";
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobUserDao xxlJobUserDao;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private String makeToken(XxlJobUser xxlJobUser) {
 | 
			
		||||
        String tokenJson = JacksonUtil.writeValueAsString(xxlJobUser);
 | 
			
		||||
        String tokenHex = new BigInteger(tokenJson.getBytes()).toString(16);
 | 
			
		||||
        return tokenHex;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private XxlJobUser parseToken(String tokenHex) {
 | 
			
		||||
        XxlJobUser xxlJobUser = null;
 | 
			
		||||
        if (tokenHex != null) {
 | 
			
		||||
            String tokenJson = new String(new BigInteger(tokenHex, 16).toByteArray());      // username_password(md5)
 | 
			
		||||
            xxlJobUser = JacksonUtil.readValue(tokenJson, XxlJobUser.class);
 | 
			
		||||
        }
 | 
			
		||||
        return xxlJobUser;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public ReturnT<String> login(HttpServletRequest request, HttpServletResponse response, String username, String password, boolean ifRemember) {
 | 
			
		||||
 | 
			
		||||
        // param
 | 
			
		||||
        if (username == null || username.trim().length() == 0 || password == null || password.trim().length() == 0) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("login_param_empty"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // valid passowrd
 | 
			
		||||
        XxlJobUser xxlJobUser = xxlJobUserDao.loadByUserName(username);
 | 
			
		||||
        if (xxlJobUser == null) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("login_param_unvalid"));
 | 
			
		||||
        }
 | 
			
		||||
        String passwordMd5 = DigestUtils.md5DigestAsHex(password.getBytes());
 | 
			
		||||
        if (!passwordMd5.equals(xxlJobUser.getPassword())) {
 | 
			
		||||
            return new ReturnT<String>(500, I18nUtil.getString("login_param_unvalid"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String loginToken = makeToken(xxlJobUser);
 | 
			
		||||
 | 
			
		||||
        // do login
 | 
			
		||||
        CookieUtil.set(response, LOGIN_IDENTITY_KEY, loginToken, ifRemember);
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * logout
 | 
			
		||||
     *
 | 
			
		||||
     * @param request
 | 
			
		||||
     * @param response
 | 
			
		||||
     */
 | 
			
		||||
    public ReturnT<String> logout(HttpServletRequest request, HttpServletResponse response) {
 | 
			
		||||
        CookieUtil.remove(request, response, LOGIN_IDENTITY_KEY);
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * logout
 | 
			
		||||
     *
 | 
			
		||||
     * @param request
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public XxlJobUser ifLogin(HttpServletRequest request, HttpServletResponse response) {
 | 
			
		||||
        String cookieToken = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY);
 | 
			
		||||
        if (cookieToken != null) {
 | 
			
		||||
            XxlJobUser cookieUser = null;
 | 
			
		||||
            try {
 | 
			
		||||
                cookieUser = parseToken(cookieToken);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                logout(request, response);
 | 
			
		||||
            }
 | 
			
		||||
            if (cookieUser != null) {
 | 
			
		||||
                XxlJobUser dbUser = xxlJobUserDao.loadByUserName(cookieUser.getUsername());
 | 
			
		||||
                if (dbUser != null) {
 | 
			
		||||
                    if (cookieUser.getPassword().equals(dbUser.getPassword())) {
 | 
			
		||||
                        return dbUser;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,87 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.service;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * core job action for xxl-job
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2016-5-28 15:30:33
 | 
			
		||||
 */
 | 
			
		||||
public interface XxlJobService {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * page list
 | 
			
		||||
     *
 | 
			
		||||
     * @param start
 | 
			
		||||
     * @param length
 | 
			
		||||
     * @param jobGroup
 | 
			
		||||
     * @param jobDesc
 | 
			
		||||
     * @param executorHandler
 | 
			
		||||
     * @param author
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public Map<String, Object> pageList(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * add job
 | 
			
		||||
     *
 | 
			
		||||
     * @param jobInfo
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public ReturnT<String> add(XxlJobInfo jobInfo);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * update job
 | 
			
		||||
     *
 | 
			
		||||
     * @param jobInfo
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public ReturnT<String> update(XxlJobInfo jobInfo);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * remove job
 | 
			
		||||
     * *
 | 
			
		||||
     *
 | 
			
		||||
     * @param id
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public ReturnT<String> remove(int id);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * start job
 | 
			
		||||
     *
 | 
			
		||||
     * @param id
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public ReturnT<String> start(int id);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * stop job
 | 
			
		||||
     *
 | 
			
		||||
     * @param id
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public ReturnT<String> stop(int id);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * dashboard info
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public Map<String, Object> dashboardInfo();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * chart info
 | 
			
		||||
     *
 | 
			
		||||
     * @param startDate
 | 
			
		||||
     * @param endDate
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public ReturnT<Map<String, Object>> chartInfo(Date startDate, Date endDate);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.service.impl;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.thread.JobCompleteHelper;
 | 
			
		||||
import com.xxl.job.admin.core.thread.JobRegistryHelper;
 | 
			
		||||
import com.xxl.job.core.biz.AdminBiz;
 | 
			
		||||
import com.xxl.job.core.biz.model.HandleCallbackParam;
 | 
			
		||||
import com.xxl.job.core.biz.model.RegistryParam;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author xuxueli 2017-07-27 21:54:20
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
public class AdminBizImpl implements AdminBiz {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList) {
 | 
			
		||||
        return JobCompleteHelper.getInstance().callback(callbackParamList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> registry(RegistryParam registryParam) {
 | 
			
		||||
        return JobRegistryHelper.getInstance().registry(registryParam);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> registryRemove(RegistryParam registryParam) {
 | 
			
		||||
        return JobRegistryHelper.getInstance().registryRemove(registryParam);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,435 +0,0 @@
 | 
			
		||||
package com.xxl.job.admin.service.impl;
 | 
			
		||||
 | 
			
		||||
import com.xxl.job.admin.core.cron.CronExpression;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobGroup;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobInfo;
 | 
			
		||||
import com.xxl.job.admin.core.model.XxlJobLogReport;
 | 
			
		||||
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
 | 
			
		||||
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
 | 
			
		||||
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
 | 
			
		||||
import com.xxl.job.admin.core.thread.JobScheduleHelper;
 | 
			
		||||
import com.xxl.job.admin.core.util.I18nUtil;
 | 
			
		||||
import com.xxl.job.admin.dao.*;
 | 
			
		||||
import com.xxl.job.admin.service.XxlJobService;
 | 
			
		||||
import com.xxl.job.core.biz.model.ReturnT;
 | 
			
		||||
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
 | 
			
		||||
import com.xxl.job.core.glue.GlueTypeEnum;
 | 
			
		||||
import com.xxl.job.core.util.DateUtil;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import java.text.MessageFormat;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * core job action for xxl-job
 | 
			
		||||
 *
 | 
			
		||||
 * @author xuxueli 2016-5-28 15:30:33
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
public class XxlJobServiceImpl implements XxlJobService {
 | 
			
		||||
    private static Logger logger = LoggerFactory.getLogger(XxlJobServiceImpl.class);
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobGroupDao xxlJobGroupDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobInfoDao xxlJobInfoDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    public XxlJobLogDao xxlJobLogDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobLogGlueDao xxlJobLogGlueDao;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private XxlJobLogReportDao xxlJobLogReportDao;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<String, Object> pageList(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author) {
 | 
			
		||||
 | 
			
		||||
        // page list
 | 
			
		||||
        List<XxlJobInfo> list = xxlJobInfoDao.pageList(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author);
 | 
			
		||||
        int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author);
 | 
			
		||||
 | 
			
		||||
        // package result
 | 
			
		||||
        Map<String, Object> maps = new HashMap<String, Object>();
 | 
			
		||||
        maps.put("recordsTotal", list_count);        // 总记录数
 | 
			
		||||
        maps.put("recordsFiltered", list_count);    // 过滤后的总记录数
 | 
			
		||||
        maps.put("data", list);                    // 分页列表
 | 
			
		||||
        return maps;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> add(XxlJobInfo jobInfo) {
 | 
			
		||||
 | 
			
		||||
        // valid base
 | 
			
		||||
        XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup());
 | 
			
		||||
        if (group == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_choose") + I18nUtil.getString("jobinfo_field_jobgroup")));
 | 
			
		||||
        }
 | 
			
		||||
        if (jobInfo.getJobDesc() == null || jobInfo.getJobDesc().trim().length() == 0) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_jobdesc")));
 | 
			
		||||
        }
 | 
			
		||||
        if (jobInfo.getAuthor() == null || jobInfo.getAuthor().trim().length() == 0) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_author")));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // valid trigger
 | 
			
		||||
        ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null);
 | 
			
		||||
        if (scheduleTypeEnum == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
        }
 | 
			
		||||
        if (scheduleTypeEnum == ScheduleTypeEnum.CRON) {
 | 
			
		||||
            if (jobInfo.getScheduleConf() == null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
 | 
			
		||||
                return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron" + I18nUtil.getString("system_unvalid"));
 | 
			
		||||
            }
 | 
			
		||||
        } else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE/* || scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
 | 
			
		||||
            if (jobInfo.getScheduleConf() == null) {
 | 
			
		||||
                return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")));
 | 
			
		||||
            }
 | 
			
		||||
            try {
 | 
			
		||||
                int fixSecond = Integer.valueOf(jobInfo.getScheduleConf());
 | 
			
		||||
                if (fixSecond < 1) {
 | 
			
		||||
                    return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
                }
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // valid job
 | 
			
		||||
        if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_gluetype") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
        }
 | 
			
		||||
        if (GlueTypeEnum.BEAN == GlueTypeEnum.match(jobInfo.getGlueType()) && (jobInfo.getExecutorHandler() == null || jobInfo.getExecutorHandler().trim().length() == 0)) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + "JobHandler"));
 | 
			
		||||
        }
 | 
			
		||||
        // 》fix "\r" in shell
 | 
			
		||||
        if (GlueTypeEnum.GLUE_SHELL == GlueTypeEnum.match(jobInfo.getGlueType()) && jobInfo.getGlueSource() != null) {
 | 
			
		||||
            jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", ""));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // valid advanced
 | 
			
		||||
        if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
        }
 | 
			
		||||
        if (MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), null) == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("misfire_strategy") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
        }
 | 
			
		||||
        if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 》ChildJobId valid
 | 
			
		||||
        if (jobInfo.getChildJobId() != null && jobInfo.getChildJobId().trim().length() > 0) {
 | 
			
		||||
            String[] childJobIds = jobInfo.getChildJobId().split(",");
 | 
			
		||||
            for (String childJobIdItem : childJobIds) {
 | 
			
		||||
                if (childJobIdItem != null && childJobIdItem.trim().length() > 0 && isNumeric(childJobIdItem)) {
 | 
			
		||||
                    XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.parseInt(childJobIdItem));
 | 
			
		||||
                    if (childJobInfo == null) {
 | 
			
		||||
                        return new ReturnT<String>(ReturnT.FAIL_CODE,
 | 
			
		||||
                            MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_not_found")), childJobIdItem));
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    return new ReturnT<String>(ReturnT.FAIL_CODE,
 | 
			
		||||
                        MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_unvalid")), childJobIdItem));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // join , avoid "xxx,,"
 | 
			
		||||
            String temp = "";
 | 
			
		||||
            for (String item : childJobIds) {
 | 
			
		||||
                temp += item + ",";
 | 
			
		||||
            }
 | 
			
		||||
            temp = temp.substring(0, temp.length() - 1);
 | 
			
		||||
 | 
			
		||||
            jobInfo.setChildJobId(temp);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // add in db
 | 
			
		||||
        jobInfo.setAddTime(new Date());
 | 
			
		||||
        jobInfo.setUpdateTime(new Date());
 | 
			
		||||
        jobInfo.setGlueUpdatetime(new Date());
 | 
			
		||||
        xxlJobInfoDao.save(jobInfo);
 | 
			
		||||
        if (jobInfo.getId() < 1) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add") + I18nUtil.getString("system_fail")));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new ReturnT<String>(String.valueOf(jobInfo.getId()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isNumeric(String str) {
 | 
			
		||||
        try {
 | 
			
		||||
            int result = Integer.valueOf(str);
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (NumberFormatException e) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> update(XxlJobInfo jobInfo) {
 | 
			
		||||
 | 
			
		||||
        // valid base
 | 
			
		||||
        if (jobInfo.getJobDesc() == null || jobInfo.getJobDesc().trim().length() == 0) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_jobdesc")));
 | 
			
		||||
        }
 | 
			
		||||
        if (jobInfo.getAuthor() == null || jobInfo.getAuthor().trim().length() == 0) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_author")));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // valid trigger
 | 
			
		||||
        ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null);
 | 
			
		||||
        if (scheduleTypeEnum == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
        }
 | 
			
		||||
        if (scheduleTypeEnum == ScheduleTypeEnum.CRON) {
 | 
			
		||||
            if (jobInfo.getScheduleConf() == null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
 | 
			
		||||
                return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron" + I18nUtil.getString("system_unvalid"));
 | 
			
		||||
            }
 | 
			
		||||
        } else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE /*|| scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
 | 
			
		||||
            if (jobInfo.getScheduleConf() == null) {
 | 
			
		||||
                return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
            }
 | 
			
		||||
            try {
 | 
			
		||||
                int fixSecond = Integer.valueOf(jobInfo.getScheduleConf());
 | 
			
		||||
                if (fixSecond < 1) {
 | 
			
		||||
                    return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
                }
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // valid advanced
 | 
			
		||||
        if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
        }
 | 
			
		||||
        if (MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), null) == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("misfire_strategy") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
        }
 | 
			
		||||
        if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 》ChildJobId valid
 | 
			
		||||
        if (jobInfo.getChildJobId() != null && jobInfo.getChildJobId().trim().length() > 0) {
 | 
			
		||||
            String[] childJobIds = jobInfo.getChildJobId().split(",");
 | 
			
		||||
            for (String childJobIdItem : childJobIds) {
 | 
			
		||||
                if (childJobIdItem != null && childJobIdItem.trim().length() > 0 && isNumeric(childJobIdItem)) {
 | 
			
		||||
                    XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.parseInt(childJobIdItem));
 | 
			
		||||
                    if (childJobInfo == null) {
 | 
			
		||||
                        return new ReturnT<String>(ReturnT.FAIL_CODE,
 | 
			
		||||
                            MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_not_found")), childJobIdItem));
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    return new ReturnT<String>(ReturnT.FAIL_CODE,
 | 
			
		||||
                        MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_unvalid")), childJobIdItem));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // join , avoid "xxx,,"
 | 
			
		||||
            String temp = "";
 | 
			
		||||
            for (String item : childJobIds) {
 | 
			
		||||
                temp += item + ",";
 | 
			
		||||
            }
 | 
			
		||||
            temp = temp.substring(0, temp.length() - 1);
 | 
			
		||||
 | 
			
		||||
            jobInfo.setChildJobId(temp);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // group valid
 | 
			
		||||
        XxlJobGroup jobGroup = xxlJobGroupDao.load(jobInfo.getJobGroup());
 | 
			
		||||
        if (jobGroup == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_jobgroup") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // stage job info
 | 
			
		||||
        XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(jobInfo.getId());
 | 
			
		||||
        if (exists_jobInfo == null) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id") + I18nUtil.getString("system_not_found")));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // next trigger time (5s后生效,避开预读周期)
 | 
			
		||||
        long nextTriggerTime = exists_jobInfo.getTriggerNextTime();
 | 
			
		||||
        boolean scheduleDataNotChanged = jobInfo.getScheduleType().equals(exists_jobInfo.getScheduleType()) && jobInfo.getScheduleConf().equals(exists_jobInfo.getScheduleConf());
 | 
			
		||||
        if (exists_jobInfo.getTriggerStatus() == 1 && !scheduleDataNotChanged) {
 | 
			
		||||
            try {
 | 
			
		||||
                Date nextValidTime = JobScheduleHelper.generateNextValidTime(jobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS));
 | 
			
		||||
                if (nextValidTime == null) {
 | 
			
		||||
                    return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
                }
 | 
			
		||||
                nextTriggerTime = nextValidTime.getTime();
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                logger.error(e.getMessage(), e);
 | 
			
		||||
                return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        exists_jobInfo.setJobGroup(jobInfo.getJobGroup());
 | 
			
		||||
        exists_jobInfo.setJobDesc(jobInfo.getJobDesc());
 | 
			
		||||
        exists_jobInfo.setAuthor(jobInfo.getAuthor());
 | 
			
		||||
        exists_jobInfo.setAlarmEmail(jobInfo.getAlarmEmail());
 | 
			
		||||
        exists_jobInfo.setScheduleType(jobInfo.getScheduleType());
 | 
			
		||||
        exists_jobInfo.setScheduleConf(jobInfo.getScheduleConf());
 | 
			
		||||
        exists_jobInfo.setMisfireStrategy(jobInfo.getMisfireStrategy());
 | 
			
		||||
        exists_jobInfo.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy());
 | 
			
		||||
        exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler());
 | 
			
		||||
        exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam());
 | 
			
		||||
        exists_jobInfo.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy());
 | 
			
		||||
        exists_jobInfo.setExecutorTimeout(jobInfo.getExecutorTimeout());
 | 
			
		||||
        exists_jobInfo.setExecutorFailRetryCount(jobInfo.getExecutorFailRetryCount());
 | 
			
		||||
        exists_jobInfo.setChildJobId(jobInfo.getChildJobId());
 | 
			
		||||
        exists_jobInfo.setTriggerNextTime(nextTriggerTime);
 | 
			
		||||
 | 
			
		||||
        exists_jobInfo.setUpdateTime(new Date());
 | 
			
		||||
        xxlJobInfoDao.update(exists_jobInfo);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> remove(int id) {
 | 
			
		||||
        XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
 | 
			
		||||
        if (xxlJobInfo == null) {
 | 
			
		||||
            return ReturnT.SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        xxlJobInfoDao.delete(id);
 | 
			
		||||
        xxlJobLogDao.delete(id);
 | 
			
		||||
        xxlJobLogGlueDao.deleteByJobId(id);
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> start(int id) {
 | 
			
		||||
        XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
 | 
			
		||||
 | 
			
		||||
        // valid
 | 
			
		||||
        ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(xxlJobInfo.getScheduleType(), ScheduleTypeEnum.NONE);
 | 
			
		||||
        if (ScheduleTypeEnum.NONE == scheduleTypeEnum) {
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type_none_limit_start")));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // next trigger time (5s后生效,避开预读周期)
 | 
			
		||||
        long nextTriggerTime = 0;
 | 
			
		||||
        try {
 | 
			
		||||
            Date nextValidTime = JobScheduleHelper.generateNextValidTime(xxlJobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS));
 | 
			
		||||
            if (nextValidTime == null) {
 | 
			
		||||
                return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
            }
 | 
			
		||||
            nextTriggerTime = nextValidTime.getTime();
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logger.error(e.getMessage(), e);
 | 
			
		||||
            return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        xxlJobInfo.setTriggerStatus(1);
 | 
			
		||||
        xxlJobInfo.setTriggerLastTime(0);
 | 
			
		||||
        xxlJobInfo.setTriggerNextTime(nextTriggerTime);
 | 
			
		||||
 | 
			
		||||
        xxlJobInfo.setUpdateTime(new Date());
 | 
			
		||||
        xxlJobInfoDao.update(xxlJobInfo);
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<String> stop(int id) {
 | 
			
		||||
        XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
 | 
			
		||||
 | 
			
		||||
        xxlJobInfo.setTriggerStatus(0);
 | 
			
		||||
        xxlJobInfo.setTriggerLastTime(0);
 | 
			
		||||
        xxlJobInfo.setTriggerNextTime(0);
 | 
			
		||||
 | 
			
		||||
        xxlJobInfo.setUpdateTime(new Date());
 | 
			
		||||
        xxlJobInfoDao.update(xxlJobInfo);
 | 
			
		||||
        return ReturnT.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<String, Object> dashboardInfo() {
 | 
			
		||||
 | 
			
		||||
        int jobInfoCount = xxlJobInfoDao.findAllCount();
 | 
			
		||||
        int jobLogCount = 0;
 | 
			
		||||
        int jobLogSuccessCount = 0;
 | 
			
		||||
        XxlJobLogReport xxlJobLogReport = xxlJobLogReportDao.queryLogReportTotal();
 | 
			
		||||
        if (xxlJobLogReport != null) {
 | 
			
		||||
            jobLogCount = xxlJobLogReport.getRunningCount() + xxlJobLogReport.getSucCount() + xxlJobLogReport.getFailCount();
 | 
			
		||||
            jobLogSuccessCount = xxlJobLogReport.getSucCount();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // executor count
 | 
			
		||||
        Set<String> executorAddressSet = new HashSet<String>();
 | 
			
		||||
        List<XxlJobGroup> groupList = xxlJobGroupDao.findAll();
 | 
			
		||||
 | 
			
		||||
        if (groupList != null && !groupList.isEmpty()) {
 | 
			
		||||
            for (XxlJobGroup group : groupList) {
 | 
			
		||||
                if (group.getRegistryList() != null && !group.getRegistryList().isEmpty()) {
 | 
			
		||||
                    executorAddressSet.addAll(group.getRegistryList());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int executorCount = executorAddressSet.size();
 | 
			
		||||
 | 
			
		||||
        Map<String, Object> dashboardMap = new HashMap<String, Object>();
 | 
			
		||||
        dashboardMap.put("jobInfoCount", jobInfoCount);
 | 
			
		||||
        dashboardMap.put("jobLogCount", jobLogCount);
 | 
			
		||||
        dashboardMap.put("jobLogSuccessCount", jobLogSuccessCount);
 | 
			
		||||
        dashboardMap.put("executorCount", executorCount);
 | 
			
		||||
        return dashboardMap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReturnT<Map<String, Object>> chartInfo(Date startDate, Date endDate) {
 | 
			
		||||
 | 
			
		||||
        // process
 | 
			
		||||
        List<String> triggerDayList = new ArrayList<String>();
 | 
			
		||||
        List<Integer> triggerDayCountRunningList = new ArrayList<Integer>();
 | 
			
		||||
        List<Integer> triggerDayCountSucList = new ArrayList<Integer>();
 | 
			
		||||
        List<Integer> triggerDayCountFailList = new ArrayList<Integer>();
 | 
			
		||||
        int triggerCountRunningTotal = 0;
 | 
			
		||||
        int triggerCountSucTotal = 0;
 | 
			
		||||
        int triggerCountFailTotal = 0;
 | 
			
		||||
 | 
			
		||||
        List<XxlJobLogReport> logReportList = xxlJobLogReportDao.queryLogReport(startDate, endDate);
 | 
			
		||||
 | 
			
		||||
        if (logReportList != null && logReportList.size() > 0) {
 | 
			
		||||
            for (XxlJobLogReport item : logReportList) {
 | 
			
		||||
                String day = DateUtil.formatDate(item.getTriggerDay());
 | 
			
		||||
                int triggerDayCountRunning = item.getRunningCount();
 | 
			
		||||
                int triggerDayCountSuc = item.getSucCount();
 | 
			
		||||
                int triggerDayCountFail = item.getFailCount();
 | 
			
		||||
 | 
			
		||||
                triggerDayList.add(day);
 | 
			
		||||
                triggerDayCountRunningList.add(triggerDayCountRunning);
 | 
			
		||||
                triggerDayCountSucList.add(triggerDayCountSuc);
 | 
			
		||||
                triggerDayCountFailList.add(triggerDayCountFail);
 | 
			
		||||
 | 
			
		||||
                triggerCountRunningTotal += triggerDayCountRunning;
 | 
			
		||||
                triggerCountSucTotal += triggerDayCountSuc;
 | 
			
		||||
                triggerCountFailTotal += triggerDayCountFail;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            for (int i = -6; i <= 0; i++) {
 | 
			
		||||
                triggerDayList.add(DateUtil.formatDate(DateUtil.addDays(new Date(), i)));
 | 
			
		||||
                triggerDayCountRunningList.add(0);
 | 
			
		||||
                triggerDayCountSucList.add(0);
 | 
			
		||||
                triggerDayCountFailList.add(0);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Map<String, Object> result = new HashMap<String, Object>();
 | 
			
		||||
        result.put("triggerDayList", triggerDayList);
 | 
			
		||||
        result.put("triggerDayCountRunningList", triggerDayCountRunningList);
 | 
			
		||||
        result.put("triggerDayCountSucList", triggerDayCountSucList);
 | 
			
		||||
        result.put("triggerDayCountFailList", triggerDayCountFailList);
 | 
			
		||||
 | 
			
		||||
        result.put("triggerCountRunningTotal", triggerCountRunningTotal);
 | 
			
		||||
        result.put("triggerCountSucTotal", triggerCountSucTotal);
 | 
			
		||||
        result.put("triggerCountFailTotal", triggerCountFailTotal);
 | 
			
		||||
 | 
			
		||||
        return new ReturnT<Map<String, Object>>(result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,47 +0,0 @@
 | 
			
		||||
--- # 监控配置
 | 
			
		||||
spring.boot.admin.client:
 | 
			
		||||
  # 增加客户端开关
 | 
			
		||||
  enabled: true
 | 
			
		||||
  # 设置 Spring Boot Admin Server 地址
 | 
			
		||||
  url: http://localhost:9090/admin
 | 
			
		||||
  instance:
 | 
			
		||||
    service-host-type: IP
 | 
			
		||||
  username: ruoyi
 | 
			
		||||
  password: 123456
 | 
			
		||||
 | 
			
		||||
--- # 数据库配置
 | 
			
		||||
spring:
 | 
			
		||||
  datasource:
 | 
			
		||||
    type: com.zaxxer.hikari.HikariDataSource
 | 
			
		||||
    driver-class-name: com.mysql.cj.jdbc.Driver
 | 
			
		||||
    url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
 | 
			
		||||
    username: root
 | 
			
		||||
    password: root
 | 
			
		||||
    hikari:
 | 
			
		||||
      auto-commit: true
 | 
			
		||||
      connection-test-query: SELECT 1
 | 
			
		||||
      connection-timeout: 10000
 | 
			
		||||
      idle-timeout: 30000
 | 
			
		||||
      max-lifetime: 900000
 | 
			
		||||
      maximum-pool-size: 30
 | 
			
		||||
      minimum-idle: 10
 | 
			
		||||
      pool-name: HikariCP
 | 
			
		||||
      validation-timeout: 1000
 | 
			
		||||
 | 
			
		||||
--- # 邮件配置
 | 
			
		||||
spring:
 | 
			
		||||
  mail:
 | 
			
		||||
    from: xxx@qq.com
 | 
			
		||||
    host: smtp.qq.com
 | 
			
		||||
    username: xxx@qq.com
 | 
			
		||||
    password: xxx
 | 
			
		||||
    port: 25
 | 
			
		||||
    properties:
 | 
			
		||||
      mail:
 | 
			
		||||
        smtp:
 | 
			
		||||
          auth: true
 | 
			
		||||
          socketFactory:
 | 
			
		||||
            class: javax.net.ssl.SSLSocketFactory
 | 
			
		||||
          starttls:
 | 
			
		||||
            enable: true
 | 
			
		||||
            required: true
 | 
			
		||||
@@ -1,47 +0,0 @@
 | 
			
		||||
--- # 监控配置
 | 
			
		||||
spring.boot.admin.client:
 | 
			
		||||
  # 增加客户端开关
 | 
			
		||||
  enabled: true
 | 
			
		||||
  # 设置 Spring Boot Admin Server 地址
 | 
			
		||||
  url: http://localhost:9090/admin
 | 
			
		||||
  instance:
 | 
			
		||||
    service-host-type: IP
 | 
			
		||||
  username: ruoyi
 | 
			
		||||
  password: 123456
 | 
			
		||||
 | 
			
		||||
--- # 数据库配置
 | 
			
		||||
spring:
 | 
			
		||||
  datasource:
 | 
			
		||||
    type: com.zaxxer.hikari.HikariDataSource
 | 
			
		||||
    driver-class-name: com.mysql.cj.jdbc.Driver
 | 
			
		||||
    url: jdbc:mysql://127.0.0.1:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
 | 
			
		||||
    username: root
 | 
			
		||||
    password: root
 | 
			
		||||
    hikari:
 | 
			
		||||
      auto-commit: true
 | 
			
		||||
      connection-test-query: SELECT 1
 | 
			
		||||
      connection-timeout: 10000
 | 
			
		||||
      idle-timeout: 30000
 | 
			
		||||
      max-lifetime: 900000
 | 
			
		||||
      maximum-pool-size: 30
 | 
			
		||||
      minimum-idle: 10
 | 
			
		||||
      pool-name: HikariCP
 | 
			
		||||
      validation-timeout: 1000
 | 
			
		||||
 | 
			
		||||
--- # 邮件配置
 | 
			
		||||
spring:
 | 
			
		||||
  mail:
 | 
			
		||||
    from: xxx@qq.com
 | 
			
		||||
    host: smtp.qq.com
 | 
			
		||||
    username: xxx@qq.com
 | 
			
		||||
    password: xxx
 | 
			
		||||
    port: 25
 | 
			
		||||
    properties:
 | 
			
		||||
      mail:
 | 
			
		||||
        smtp:
 | 
			
		||||
          auth: true
 | 
			
		||||
          socketFactory:
 | 
			
		||||
            class: javax.net.ssl.SSLSocketFactory
 | 
			
		||||
          starttls:
 | 
			
		||||
            enable: true
 | 
			
		||||
            required: true
 | 
			
		||||
@@ -1,64 +0,0 @@
 | 
			
		||||
--- # server 配置
 | 
			
		||||
server:
 | 
			
		||||
  port: 9100
 | 
			
		||||
  servlet:
 | 
			
		||||
    context-path: /xxl-job-admin
 | 
			
		||||
spring:
 | 
			
		||||
  application:
 | 
			
		||||
    name: ruoyi-xxl-job-admin
 | 
			
		||||
  profiles:
 | 
			
		||||
    active: @profiles.active@
 | 
			
		||||
  mvc:
 | 
			
		||||
    servlet:
 | 
			
		||||
      load-on-startup: 0
 | 
			
		||||
    static-path-pattern: /static/**
 | 
			
		||||
  web:
 | 
			
		||||
    resources:
 | 
			
		||||
      static-locations: classpath:/static/
 | 
			
		||||
 | 
			
		||||
logging:
 | 
			
		||||
  config: classpath:logback-plus.xml
 | 
			
		||||
 | 
			
		||||
--- # mybatis 配置
 | 
			
		||||
mybatis:
 | 
			
		||||
  mapper-locations: classpath:/mybatis-mapper/*Mapper.xml
 | 
			
		||||
 | 
			
		||||
--- # 页面配置
 | 
			
		||||
spring:
 | 
			
		||||
  freemarker:
 | 
			
		||||
    charset: UTF-8
 | 
			
		||||
    request-context-attribute: request
 | 
			
		||||
    settings:
 | 
			
		||||
      number_format: 0.##########
 | 
			
		||||
    suffix: .ftl
 | 
			
		||||
    templateLoaderPath: classpath:/templates/
 | 
			
		||||
 | 
			
		||||
--- # Actuator 监控端点的配置项
 | 
			
		||||
management:
 | 
			
		||||
  health:
 | 
			
		||||
    mail:
 | 
			
		||||
      enabled: false
 | 
			
		||||
  endpoints:
 | 
			
		||||
    web:
 | 
			
		||||
      exposure:
 | 
			
		||||
        include: '*'
 | 
			
		||||
  endpoint:
 | 
			
		||||
    health:
 | 
			
		||||
      show-details: ALWAYS
 | 
			
		||||
    logfile:
 | 
			
		||||
      external-file: ./logs/ruoyi-xxl-job-admin.log
 | 
			
		||||
 | 
			
		||||
--- # xxljob系统配置
 | 
			
		||||
xxl:
 | 
			
		||||
  job:
 | 
			
		||||
    # 鉴权token
 | 
			
		||||
    accessToken: xxl-job
 | 
			
		||||
    # 国际化
 | 
			
		||||
    i18n: zh_CN
 | 
			
		||||
    # 日志清理
 | 
			
		||||
    logretentiondays: 30
 | 
			
		||||
    triggerpool:
 | 
			
		||||
      fast:
 | 
			
		||||
        max: 200
 | 
			
		||||
      slow:
 | 
			
		||||
        max: 100
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
Application Version: ${revision}
 | 
			
		||||
Spring Boot Version: ${spring-boot.version}
 | 
			
		||||
__   __      _            _       _                     _           _
 | 
			
		||||
\ \ / /     | |          | |     | |           /\      | |         (_)
 | 
			
		||||
 \ V / __  _| |______    | | ___ | |__ ______ /  \   __| |_ __ ___  _ _ __
 | 
			
		||||
  > <  \ \/ / |______|   | |/ _ \| '_ \______/ /\ \ / _` | '_ ` _ \| | '_ \
 | 
			
		||||
 / . \  >  <| |     | |__| | (_) | |_) |    / ____ \ (_| | | | | | | | | | |
 | 
			
		||||
/_/ \_\/_/\_\_|      \____/ \___/|_.__/    /_/    \_\__,_|_| |_| |_|_|_| |_|
 | 
			
		||||
@@ -1,276 +0,0 @@
 | 
			
		||||
admin_name=Scheduling Center
 | 
			
		||||
admin_name_full=Distributed Task Scheduling Platform XXL-JOB
 | 
			
		||||
admin_version=2.4.0
 | 
			
		||||
admin_i18n=en
 | 
			
		||||
 | 
			
		||||
## system
 | 
			
		||||
system_tips=System message
 | 
			
		||||
system_ok=Confirm
 | 
			
		||||
system_close=Close
 | 
			
		||||
system_save=Save
 | 
			
		||||
system_cancel=Cancel
 | 
			
		||||
system_search=Search
 | 
			
		||||
system_status=Status
 | 
			
		||||
system_opt=Operate
 | 
			
		||||
system_please_input=please input
 | 
			
		||||
system_please_choose=please choose
 | 
			
		||||
system_success=success
 | 
			
		||||
system_fail=fail
 | 
			
		||||
system_add_suc=add success
 | 
			
		||||
system_add_fail=add fail
 | 
			
		||||
system_update_suc=update success
 | 
			
		||||
system_update_fail=update fail
 | 
			
		||||
system_all=All
 | 
			
		||||
system_api_error=net error
 | 
			
		||||
system_show=Show
 | 
			
		||||
system_empty=Empty
 | 
			
		||||
system_opt_suc=operate success
 | 
			
		||||
system_opt_fail=operate fail
 | 
			
		||||
system_opt_edit=Edit
 | 
			
		||||
system_opt_del=Delete
 | 
			
		||||
system_opt_copy=Copy
 | 
			
		||||
system_unvalid=illegal
 | 
			
		||||
system_not_found=not exist
 | 
			
		||||
system_nav=Navigation
 | 
			
		||||
system_digits=digits
 | 
			
		||||
system_lengh_limit=Length limit
 | 
			
		||||
system_permission_limit=Permission limit
 | 
			
		||||
system_welcome=Welcome
 | 
			
		||||
 | 
			
		||||
## daterangepicker
 | 
			
		||||
daterangepicker_ranges_recent_hour=recent one hour
 | 
			
		||||
daterangepicker_ranges_today=today
 | 
			
		||||
daterangepicker_ranges_yesterday=yesterday
 | 
			
		||||
daterangepicker_ranges_this_month=this month
 | 
			
		||||
daterangepicker_ranges_last_month=last month
 | 
			
		||||
daterangepicker_ranges_recent_week=recent one week
 | 
			
		||||
daterangepicker_ranges_recent_month=recent one month
 | 
			
		||||
daterangepicker_custom_name=custom
 | 
			
		||||
daterangepicker_custom_starttime=start time
 | 
			
		||||
daterangepicker_custom_endtime=end time
 | 
			
		||||
daterangepicker_custom_daysofweek=Sun,Mon,Tue,Wed,Thu,Fri,Sat
 | 
			
		||||
daterangepicker_custom_monthnames=Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
 | 
			
		||||
 | 
			
		||||
## dataTable
 | 
			
		||||
dataTable_sProcessing=processing...
 | 
			
		||||
dataTable_sLengthMenu= _MENU_ records per page
 | 
			
		||||
dataTable_sZeroRecords=No matching results
 | 
			
		||||
dataTable_sInfo=page _PAGE_  ( Total _PAGES_ pages,_TOTAL_ records )
 | 
			
		||||
dataTable_sInfoEmpty=No Record
 | 
			
		||||
dataTable_sInfoFiltered=(Filtered by _MAX_ results)
 | 
			
		||||
dataTable_sSearch=Search
 | 
			
		||||
dataTable_sEmptyTable=Table data is empty
 | 
			
		||||
dataTable_sLoadingRecords=Loading...
 | 
			
		||||
dataTable_sFirst=FIRST PAGE
 | 
			
		||||
dataTable_sPrevious=Previous Page
 | 
			
		||||
dataTable_sNext=Next Page
 | 
			
		||||
dataTable_sLast=LAST PAGE
 | 
			
		||||
dataTable_sSortAscending=: Rank this column in ascending order
 | 
			
		||||
dataTable_sSortDescending=: Rank this column in descending order
 | 
			
		||||
 | 
			
		||||
## login
 | 
			
		||||
login_btn=Login
 | 
			
		||||
login_remember_me=Remember Me
 | 
			
		||||
login_username_placeholder=Please enter username
 | 
			
		||||
login_password_placeholder=Please enter password
 | 
			
		||||
login_username_empty=Please enter username
 | 
			
		||||
login_username_lt_4=Username length should not be less than 4
 | 
			
		||||
login_password_empty=Please enter password
 | 
			
		||||
login_password_lt_4=Password length should not be less than 4
 | 
			
		||||
login_success=Login success
 | 
			
		||||
login_fail=Login fail
 | 
			
		||||
login_param_empty=Username or password is empty
 | 
			
		||||
login_param_unvalid=Username or password error
 | 
			
		||||
 | 
			
		||||
## logout
 | 
			
		||||
logout_btn=Logout
 | 
			
		||||
logout_confirm=Confirm logout?
 | 
			
		||||
logout_success=Logout success
 | 
			
		||||
logout_fail=Logout fail
 | 
			
		||||
 | 
			
		||||
## change pwd
 | 
			
		||||
change_pwd=Change password
 | 
			
		||||
change_pwd_suc_to_logout=Change password successful, about to log out login
 | 
			
		||||
change_pwd_field_newpwd=new password
 | 
			
		||||
 | 
			
		||||
## dashboard
 | 
			
		||||
job_dashboard_name=Run report
 | 
			
		||||
job_dashboard_job_num=Job number
 | 
			
		||||
job_dashboard_job_num_tip=The number of tasks running in the scheduling center
 | 
			
		||||
job_dashboard_trigger_num=trigger number
 | 
			
		||||
job_dashboard_trigger_num_tip=The number of trigger record scheduled by the scheduling center
 | 
			
		||||
job_dashboard_jobgroup_num=Executor number
 | 
			
		||||
job_dashboard_jobgroup_num_tip=The number of online executor machines perceived by the scheduling center
 | 
			
		||||
job_dashboard_report=Scheduling report
 | 
			
		||||
job_dashboard_report_loaddata_fail=Scheduling report load data error
 | 
			
		||||
job_dashboard_date_report=Date distribution
 | 
			
		||||
job_dashboard_rate_report=Percentage distribution
 | 
			
		||||
 | 
			
		||||
## job info
 | 
			
		||||
jobinfo_name=Job Manage
 | 
			
		||||
jobinfo_job=Job
 | 
			
		||||
jobinfo_field_add=Add Job
 | 
			
		||||
jobinfo_field_update=Edit Job
 | 
			
		||||
jobinfo_field_id=Job ID
 | 
			
		||||
jobinfo_field_jobgroup=Executor
 | 
			
		||||
jobinfo_field_jobdesc=Job description
 | 
			
		||||
jobinfo_field_timeout=Job timeout period
 | 
			
		||||
jobinfo_field_gluetype=GLUE Type
 | 
			
		||||
jobinfo_field_executorparam=Param
 | 
			
		||||
jobinfo_field_author=Author
 | 
			
		||||
jobinfo_field_alarmemail=Alarm email
 | 
			
		||||
jobinfo_field_alarmemail_placeholder=Please enter alarm mail, if there are more than one comma separated
 | 
			
		||||
jobinfo_field_executorRouteStrategy=Route Strategy
 | 
			
		||||
jobinfo_field_childJobId=Child Job ID
 | 
			
		||||
jobinfo_field_childJobId_placeholder=Please enter the Child job ID, if there are more than one comma separated
 | 
			
		||||
jobinfo_field_executorBlockStrategy=Block Strategy
 | 
			
		||||
jobinfo_field_executorFailRetryCount=Fail Retry Count
 | 
			
		||||
jobinfo_field_executorFailRetryCount_placeholder=Fail Retry Count. effect if greater than zero
 | 
			
		||||
jobinfo_script_location=Script location
 | 
			
		||||
jobinfo_shard_index=Shard index
 | 
			
		||||
jobinfo_shard_total=Shard total
 | 
			
		||||
jobinfo_opt_stop=Stop
 | 
			
		||||
jobinfo_opt_start=Start
 | 
			
		||||
jobinfo_opt_log=Query Log
 | 
			
		||||
jobinfo_opt_run=Run Once
 | 
			
		||||
jobinfo_opt_run_tips=Please input the address for this trigger. Null will be obtained from the executor
 | 
			
		||||
jobinfo_opt_registryinfo=Registry Info
 | 
			
		||||
jobinfo_opt_next_time=Next trigger time
 | 
			
		||||
jobinfo_glue_remark=Resource Remark
 | 
			
		||||
jobinfo_glue_remark_limit=Resource Remark length is limited to 4~100
 | 
			
		||||
jobinfo_glue_rollback=Version Backtrack
 | 
			
		||||
jobinfo_glue_jobid_unvalid=Job ID is illegal
 | 
			
		||||
jobinfo_glue_gluetype_unvalid=The job is not GLUE Type
 | 
			
		||||
jobinfo_field_executorTimeout_placeholder=Job Timeout period,in seconds. effect if greater than zero
 | 
			
		||||
schedule_type=Schedule Type
 | 
			
		||||
schedule_type_none=None
 | 
			
		||||
schedule_type_cron=Cron
 | 
			
		||||
schedule_type_fix_rate=Fix rate
 | 
			
		||||
schedule_type_fix_delay=Fix delay
 | 
			
		||||
schedule_type_none_limit_start=The current schedule type disables startup
 | 
			
		||||
misfire_strategy=Misfire strategy
 | 
			
		||||
misfire_strategy_do_nothing=Do nothing
 | 
			
		||||
misfire_strategy_fire_once_now=Fire once now
 | 
			
		||||
jobinfo_conf_base=Base configuration
 | 
			
		||||
jobinfo_conf_schedule=Schedule configuration
 | 
			
		||||
jobinfo_conf_job=Job configuration
 | 
			
		||||
jobinfo_conf_advanced=Advanced configuration
 | 
			
		||||
 | 
			
		||||
## job log
 | 
			
		||||
joblog_name=Trigger Log
 | 
			
		||||
joblog_status=Status
 | 
			
		||||
joblog_status_all=All
 | 
			
		||||
joblog_status_suc=Success
 | 
			
		||||
joblog_status_fail=Fail
 | 
			
		||||
joblog_status_running=Running
 | 
			
		||||
joblog_field_triggerTime=Trigger Time
 | 
			
		||||
joblog_field_triggerCode=Trigger Result
 | 
			
		||||
joblog_field_triggerMsg=Trigger Msg
 | 
			
		||||
joblog_field_handleTime=Handle Time
 | 
			
		||||
joblog_field_handleCode=Handle Result
 | 
			
		||||
joblog_field_handleMsg=Trigger Msg
 | 
			
		||||
joblog_field_executorAddress=Executor Address
 | 
			
		||||
joblog_clean=Clean
 | 
			
		||||
joblog_clean_log=Clean Log
 | 
			
		||||
joblog_clean_type=Clean Type
 | 
			
		||||
joblog_clean_type_1=Clean up log data a month ago
 | 
			
		||||
joblog_clean_type_2=Clean up log data three month ago
 | 
			
		||||
joblog_clean_type_3=Clean up log data six month ago
 | 
			
		||||
joblog_clean_type_4=Clean up log data a year ago
 | 
			
		||||
joblog_clean_type_5=Clean up log data a thousand record ago
 | 
			
		||||
joblog_clean_type_6=Clean up log data ten thousand record ago
 | 
			
		||||
joblog_clean_type_7=Clean up log data thirty thousand record ago
 | 
			
		||||
joblog_clean_type_8=Clean up log data hundred thousand record ago
 | 
			
		||||
joblog_clean_type_9=Clean up all log data
 | 
			
		||||
joblog_clean_type_unvalid=Clean type is illegal
 | 
			
		||||
joblog_handleCode_200=Success
 | 
			
		||||
joblog_handleCode_500=Fail
 | 
			
		||||
joblog_handleCode_502=Timeout
 | 
			
		||||
joblog_kill_log=Kill Job
 | 
			
		||||
joblog_kill_log_limit=Trigger Fail, can not kill job
 | 
			
		||||
joblog_kill_log_byman=Manual operation, kill job
 | 
			
		||||
joblog_lost_fail=Job result lost, marked as failure
 | 
			
		||||
joblog_rolling_log=Rolling log
 | 
			
		||||
joblog_rolling_log_refresh=Refresh
 | 
			
		||||
joblog_rolling_log_triggerfail=The job trigger fail, can not view the rolling log
 | 
			
		||||
joblog_rolling_log_failoften=The request for the Rolling log is terminated, the number of failed requests exceeds the limit, Reload the log on the refresh page
 | 
			
		||||
joblog_logid_unvalid=Log ID is illegal
 | 
			
		||||
 | 
			
		||||
## job group
 | 
			
		||||
jobgroup_name=Executor Manage
 | 
			
		||||
jobgroup_list=Executor List
 | 
			
		||||
jobgroup_add=Add Executor
 | 
			
		||||
jobgroup_edit=Edit Executor
 | 
			
		||||
jobgroup_del=Delete Executor
 | 
			
		||||
jobgroup_field_title=Title
 | 
			
		||||
jobgroup_field_addressType=Registry Type
 | 
			
		||||
jobgroup_field_addressType_0=Automatic registration
 | 
			
		||||
jobgroup_field_addressType_1=Manual registration
 | 
			
		||||
jobgroup_field_addressType_limit=Manually registration type, the machine address must not be empty
 | 
			
		||||
jobgroup_field_registryList=machine address
 | 
			
		||||
jobgroup_field_registryList_unvalid=registry machine address is illegal
 | 
			
		||||
jobgroup_field_registryList_placeholder=Please enter the machine address, if there are more than one comma separated
 | 
			
		||||
jobgroup_field_appname_limit=Limit the beginning of a lowercase letter, consists of lowercase letters、number and hyphen.
 | 
			
		||||
jobgroup_field_appname_length=AppName length is limited to 4~64
 | 
			
		||||
jobgroup_field_title_length=Title length is limited to 4~12
 | 
			
		||||
jobgroup_field_order_digits=Please enter a positive integer
 | 
			
		||||
jobgroup_field_orderrange=Order is limited to 1~1000
 | 
			
		||||
jobgroup_del_limit_0=Refuse to delete, the executor is being used
 | 
			
		||||
jobgroup_del_limit_1=Refuses to delete, the system retains at least one executor
 | 
			
		||||
jobgroup_empty=There is no valid executor. Please contact the administrator
 | 
			
		||||
 | 
			
		||||
## job conf
 | 
			
		||||
jobconf_block_SERIAL_EXECUTION=Serial execution
 | 
			
		||||
jobconf_block_DISCARD_LATER=Discard Later
 | 
			
		||||
jobconf_block_COVER_EARLY=Cover Early
 | 
			
		||||
jobconf_route_first=First
 | 
			
		||||
jobconf_route_last=Last
 | 
			
		||||
jobconf_route_round=Round
 | 
			
		||||
jobconf_route_random=Random
 | 
			
		||||
jobconf_route_consistenthash=Consistent Hash
 | 
			
		||||
jobconf_route_lfu=Least Frequently Used
 | 
			
		||||
jobconf_route_lru=Least Recently Used
 | 
			
		||||
jobconf_route_failover=Failover
 | 
			
		||||
jobconf_route_busyover=Busyover
 | 
			
		||||
jobconf_route_shard=Sharding Broadcast
 | 
			
		||||
jobconf_idleBeat=Idle check
 | 
			
		||||
jobconf_beat=Heartbeats
 | 
			
		||||
jobconf_monitor=Task Scheduling Center monitor alarm
 | 
			
		||||
jobconf_monitor_detail=monitor alarm details
 | 
			
		||||
jobconf_monitor_alarm_title=Alarm Type
 | 
			
		||||
jobconf_monitor_alarm_type=Trigger Fail
 | 
			
		||||
jobconf_monitor_alarm_content=Alarm Content
 | 
			
		||||
jobconf_trigger_admin_adress=Trigger machine address
 | 
			
		||||
jobconf_trigger_exe_regtype=Execotor-Registry Type
 | 
			
		||||
jobconf_trigger_exe_regaddress=Execotor-Registry Address
 | 
			
		||||
jobconf_trigger_address_empty=Trigger Fail:registry address is empty
 | 
			
		||||
jobconf_trigger_run=Trigger Job
 | 
			
		||||
jobconf_trigger_child_run=Trigger child job
 | 
			
		||||
jobconf_callback_child_msg1={0}/{1} [Job ID={2}], Trigger {3}, Trigger msg: {4} <br>
 | 
			
		||||
jobconf_callback_child_msg2={0}/{1} [Job ID={2}], Trigger Fail, Trigger msg: Job ID is illegal <br>
 | 
			
		||||
jobconf_trigger_type=Job trigger type
 | 
			
		||||
jobconf_trigger_type_cron=Cron trigger
 | 
			
		||||
jobconf_trigger_type_manual=Manual trigger
 | 
			
		||||
jobconf_trigger_type_parent=Parent job trigger
 | 
			
		||||
jobconf_trigger_type_api=Api trigger
 | 
			
		||||
jobconf_trigger_type_retry=Fail retry trigger
 | 
			
		||||
jobconf_trigger_type_misfire=Misfire compensation trigger
 | 
			
		||||
 | 
			
		||||
## user
 | 
			
		||||
user_manage=User Manage
 | 
			
		||||
user_username=Username
 | 
			
		||||
user_password=Password
 | 
			
		||||
user_role=Role
 | 
			
		||||
user_role_admin=Admin User
 | 
			
		||||
user_role_normal=Normal User
 | 
			
		||||
user_permission=Permission
 | 
			
		||||
user_add=Add User
 | 
			
		||||
user_update=Edit User
 | 
			
		||||
user_username_repeat=Username Repeat
 | 
			
		||||
user_username_valid=Restrictions start with a lowercase letter and consist of lowercase letters and Numbers
 | 
			
		||||
user_password_update_placeholder=Please input password, empty means not update
 | 
			
		||||
user_update_loginuser_limit=Operation of current login account is not allowed
 | 
			
		||||
 | 
			
		||||
## help
 | 
			
		||||
job_help=Tutorial
 | 
			
		||||
job_help_document=Official Document
 | 
			
		||||
@@ -1,276 +0,0 @@
 | 
			
		||||
admin_name=任务调度中心
 | 
			
		||||
admin_name_full=分布式任务调度平台XXL-JOB
 | 
			
		||||
admin_version=2.4.0
 | 
			
		||||
admin_i18n=
 | 
			
		||||
 | 
			
		||||
## system
 | 
			
		||||
system_tips=系统提示
 | 
			
		||||
system_ok=确定
 | 
			
		||||
system_close=关闭
 | 
			
		||||
system_save=保存
 | 
			
		||||
system_cancel=取消
 | 
			
		||||
system_search=搜索
 | 
			
		||||
system_status=状态
 | 
			
		||||
system_opt=操作
 | 
			
		||||
system_please_input=请输入
 | 
			
		||||
system_please_choose=请选择
 | 
			
		||||
system_success=成功
 | 
			
		||||
system_fail=失败
 | 
			
		||||
system_add_suc=新增成功
 | 
			
		||||
system_add_fail=新增失败
 | 
			
		||||
system_update_suc=更新成功
 | 
			
		||||
system_update_fail=更新失败
 | 
			
		||||
system_all=全部
 | 
			
		||||
system_api_error=接口异常
 | 
			
		||||
system_show=查看
 | 
			
		||||
system_empty=无
 | 
			
		||||
system_opt_suc=操作成功
 | 
			
		||||
system_opt_fail=操作失败
 | 
			
		||||
system_opt_edit=编辑
 | 
			
		||||
system_opt_del=删除
 | 
			
		||||
system_opt_copy=复制
 | 
			
		||||
system_unvalid=非法
 | 
			
		||||
system_not_found=不存在
 | 
			
		||||
system_nav=导航
 | 
			
		||||
system_digits=整数
 | 
			
		||||
system_lengh_limit=长度限制
 | 
			
		||||
system_permission_limit=权限拦截
 | 
			
		||||
system_welcome=欢迎
 | 
			
		||||
 | 
			
		||||
## daterangepicker
 | 
			
		||||
daterangepicker_ranges_recent_hour=最近一小时
 | 
			
		||||
daterangepicker_ranges_today=今日
 | 
			
		||||
daterangepicker_ranges_yesterday=昨日
 | 
			
		||||
daterangepicker_ranges_this_month=本月
 | 
			
		||||
daterangepicker_ranges_last_month=上个月
 | 
			
		||||
daterangepicker_ranges_recent_week=最近一周
 | 
			
		||||
daterangepicker_ranges_recent_month=最近一月
 | 
			
		||||
daterangepicker_custom_name=自定义
 | 
			
		||||
daterangepicker_custom_starttime=起始时间
 | 
			
		||||
daterangepicker_custom_endtime=结束时间
 | 
			
		||||
daterangepicker_custom_daysofweek=日,一,二,三,四,五,六
 | 
			
		||||
daterangepicker_custom_monthnames=一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月
 | 
			
		||||
 | 
			
		||||
## dataTable
 | 
			
		||||
dataTable_sProcessing=处理中...
 | 
			
		||||
dataTable_sLengthMenu=每页 _MENU_ 条记录
 | 
			
		||||
dataTable_sZeroRecords=没有匹配结果
 | 
			
		||||
dataTable_sInfo=第 _PAGE_ 页 ( 总共 _PAGES_ 页,_TOTAL_ 条记录 )
 | 
			
		||||
dataTable_sInfoEmpty=无记录
 | 
			
		||||
dataTable_sInfoFiltered=(由 _MAX_ 项结果过滤)
 | 
			
		||||
dataTable_sSearch=搜索
 | 
			
		||||
dataTable_sEmptyTable=表中数据为空
 | 
			
		||||
dataTable_sLoadingRecords=载入中...
 | 
			
		||||
dataTable_sFirst=首页
 | 
			
		||||
dataTable_sPrevious=上页
 | 
			
		||||
dataTable_sNext=下页
 | 
			
		||||
dataTable_sLast=末页
 | 
			
		||||
dataTable_sSortAscending=: 以升序排列此列
 | 
			
		||||
dataTable_sSortDescending=: 以降序排列此列
 | 
			
		||||
 | 
			
		||||
## login
 | 
			
		||||
login_btn=登录
 | 
			
		||||
login_remember_me=记住密码
 | 
			
		||||
login_username_placeholder=请输入登录账号
 | 
			
		||||
login_password_placeholder=请输入登录密码
 | 
			
		||||
login_username_empty=请输入登录账号
 | 
			
		||||
login_username_lt_4=登录账号不应低于4位
 | 
			
		||||
login_password_empty=请输入登录密码
 | 
			
		||||
login_password_lt_4=登录密码不应低于4位
 | 
			
		||||
login_success=登录成功
 | 
			
		||||
login_fail=登录失败
 | 
			
		||||
login_param_empty=账号或密码为空
 | 
			
		||||
login_param_unvalid=账号或密码错误
 | 
			
		||||
 | 
			
		||||
## logout
 | 
			
		||||
logout_btn=注销
 | 
			
		||||
logout_confirm=确认注销登录?
 | 
			
		||||
logout_success=注销成功
 | 
			
		||||
logout_fail=注销失败
 | 
			
		||||
 | 
			
		||||
## change pwd
 | 
			
		||||
change_pwd=修改密码
 | 
			
		||||
change_pwd_suc_to_logout=修改密码成功,即将注销登陆
 | 
			
		||||
change_pwd_field_newpwd=新密码
 | 
			
		||||
 | 
			
		||||
## dashboard
 | 
			
		||||
job_dashboard_name=运行报表
 | 
			
		||||
job_dashboard_job_num=任务数量
 | 
			
		||||
job_dashboard_job_num_tip=调度中心运行的任务数量
 | 
			
		||||
job_dashboard_trigger_num=调度次数
 | 
			
		||||
job_dashboard_trigger_num_tip=调度中心触发的调度次数
 | 
			
		||||
job_dashboard_jobgroup_num=执行器数量
 | 
			
		||||
job_dashboard_jobgroup_num_tip=调度中心在线的执行器机器数量
 | 
			
		||||
job_dashboard_report=调度报表
 | 
			
		||||
job_dashboard_report_loaddata_fail=调度报表数据加载异常
 | 
			
		||||
job_dashboard_date_report=日期分布图
 | 
			
		||||
job_dashboard_rate_report=成功比例图
 | 
			
		||||
 | 
			
		||||
## job info
 | 
			
		||||
jobinfo_name=任务管理
 | 
			
		||||
jobinfo_job=任务
 | 
			
		||||
jobinfo_field_add=新增
 | 
			
		||||
jobinfo_field_update=更新任务
 | 
			
		||||
jobinfo_field_id=任务ID
 | 
			
		||||
jobinfo_field_jobgroup=执行器
 | 
			
		||||
jobinfo_field_jobdesc=任务描述
 | 
			
		||||
jobinfo_field_gluetype=运行模式
 | 
			
		||||
jobinfo_field_executorparam=任务参数
 | 
			
		||||
jobinfo_field_author=负责人
 | 
			
		||||
jobinfo_field_timeout=任务超时时间
 | 
			
		||||
jobinfo_field_alarmemail=报警邮件
 | 
			
		||||
jobinfo_field_alarmemail_placeholder=请输入报警邮件,多个邮件地址则逗号分隔
 | 
			
		||||
jobinfo_field_executorRouteStrategy=路由策略
 | 
			
		||||
jobinfo_field_childJobId=子任务ID
 | 
			
		||||
jobinfo_field_childJobId_placeholder=请输入子任务的任务ID,如存在多个则逗号分隔
 | 
			
		||||
jobinfo_field_executorBlockStrategy=阻塞处理策略
 | 
			
		||||
jobinfo_field_executorFailRetryCount=失败重试次数
 | 
			
		||||
jobinfo_field_executorFailRetryCount_placeholder=失败重试次数,大于零时生效
 | 
			
		||||
jobinfo_script_location=脚本位置
 | 
			
		||||
jobinfo_shard_index=分片序号
 | 
			
		||||
jobinfo_shard_total=分片总数
 | 
			
		||||
jobinfo_opt_stop=停止
 | 
			
		||||
jobinfo_opt_start=启动
 | 
			
		||||
jobinfo_opt_log=查询日志
 | 
			
		||||
jobinfo_opt_run=执行一次
 | 
			
		||||
jobinfo_opt_run_tips=请输入本次执行的机器地址,为空则从执行器获取
 | 
			
		||||
jobinfo_opt_registryinfo=注册节点
 | 
			
		||||
jobinfo_opt_next_time=下次执行时间
 | 
			
		||||
jobinfo_glue_remark=源码备注
 | 
			
		||||
jobinfo_glue_remark_limit=源码备注长度限制为4~100
 | 
			
		||||
jobinfo_glue_rollback=版本回溯
 | 
			
		||||
jobinfo_glue_jobid_unvalid=任务ID非法
 | 
			
		||||
jobinfo_glue_gluetype_unvalid=该任务非GLUE模式
 | 
			
		||||
jobinfo_field_executorTimeout_placeholder=任务超时时间,单位秒,大于零时生效
 | 
			
		||||
schedule_type=调度类型
 | 
			
		||||
schedule_type_none=无
 | 
			
		||||
schedule_type_cron=CRON
 | 
			
		||||
schedule_type_fix_rate=固定速度
 | 
			
		||||
schedule_type_fix_delay=固定延迟
 | 
			
		||||
schedule_type_none_limit_start=当前调度类型禁止启动
 | 
			
		||||
misfire_strategy=调度过期策略
 | 
			
		||||
misfire_strategy_do_nothing=忽略
 | 
			
		||||
misfire_strategy_fire_once_now=立即执行一次
 | 
			
		||||
jobinfo_conf_base=基础配置
 | 
			
		||||
jobinfo_conf_schedule=调度配置
 | 
			
		||||
jobinfo_conf_job=任务配置
 | 
			
		||||
jobinfo_conf_advanced=高级配置
 | 
			
		||||
 | 
			
		||||
## job log
 | 
			
		||||
joblog_name=调度日志
 | 
			
		||||
joblog_status=状态
 | 
			
		||||
joblog_status_all=全部
 | 
			
		||||
joblog_status_suc=成功
 | 
			
		||||
joblog_status_fail=失败
 | 
			
		||||
joblog_status_running=进行中
 | 
			
		||||
joblog_field_triggerTime=调度时间
 | 
			
		||||
joblog_field_triggerCode=调度结果
 | 
			
		||||
joblog_field_triggerMsg=调度备注
 | 
			
		||||
joblog_field_handleTime=执行时间
 | 
			
		||||
joblog_field_handleCode=执行结果
 | 
			
		||||
joblog_field_handleMsg=执行备注
 | 
			
		||||
joblog_field_executorAddress=执行器地址
 | 
			
		||||
joblog_clean=清理
 | 
			
		||||
joblog_clean_log=日志清理
 | 
			
		||||
joblog_clean_type=清理方式
 | 
			
		||||
joblog_clean_type_1=清理一个月之前日志数据
 | 
			
		||||
joblog_clean_type_2=清理三个月之前日志数据
 | 
			
		||||
joblog_clean_type_3=清理六个月之前日志数据
 | 
			
		||||
joblog_clean_type_4=清理一年之前日志数据
 | 
			
		||||
joblog_clean_type_5=清理一千条以前日志数据
 | 
			
		||||
joblog_clean_type_6=清理一万条以前日志数据
 | 
			
		||||
joblog_clean_type_7=清理三万条以前日志数据
 | 
			
		||||
joblog_clean_type_8=清理十万条以前日志数据
 | 
			
		||||
joblog_clean_type_9=清理所有日志数据
 | 
			
		||||
joblog_clean_type_unvalid=清理类型参数异常
 | 
			
		||||
joblog_handleCode_200=成功
 | 
			
		||||
joblog_handleCode_500=失败
 | 
			
		||||
joblog_handleCode_502=失败(超时)
 | 
			
		||||
joblog_kill_log=终止任务
 | 
			
		||||
joblog_kill_log_limit=调度失败,无法终止日志
 | 
			
		||||
joblog_kill_log_byman=人为操作,主动终止
 | 
			
		||||
joblog_lost_fail=任务结果丢失,标记失败
 | 
			
		||||
joblog_rolling_log=执行日志
 | 
			
		||||
joblog_rolling_log_refresh=刷新
 | 
			
		||||
joblog_rolling_log_triggerfail=任务发起调度失败,无法查看执行日志
 | 
			
		||||
joblog_rolling_log_failoften=终止请求Rolling日志,请求失败次数超上限,可刷新页面重新加载日志
 | 
			
		||||
joblog_logid_unvalid=日志ID非法
 | 
			
		||||
 | 
			
		||||
## job group
 | 
			
		||||
jobgroup_name=执行器管理
 | 
			
		||||
jobgroup_list=执行器列表
 | 
			
		||||
jobgroup_add=新增执行器
 | 
			
		||||
jobgroup_edit=编辑执行器
 | 
			
		||||
jobgroup_del=删除执行器
 | 
			
		||||
jobgroup_field_title=名称
 | 
			
		||||
jobgroup_field_addressType=注册方式
 | 
			
		||||
jobgroup_field_addressType_0=自动注册
 | 
			
		||||
jobgroup_field_addressType_1=手动录入
 | 
			
		||||
jobgroup_field_addressType_limit=手动录入注册方式,机器地址不可为空
 | 
			
		||||
jobgroup_field_registryList=机器地址
 | 
			
		||||
jobgroup_field_registryList_unvalid=机器地址格式非法
 | 
			
		||||
jobgroup_field_registryList_placeholder=请输入执行器地址列表,多地址逗号分隔
 | 
			
		||||
jobgroup_field_appname_limit=限制以小写字母开头,由小写字母、数字和中划线组成
 | 
			
		||||
jobgroup_field_appname_length=AppName长度限制为4~64
 | 
			
		||||
jobgroup_field_title_length=名称长度限制为4~12
 | 
			
		||||
jobgroup_field_order_digits=请输入整数
 | 
			
		||||
jobgroup_field_orderrange=取值范围为1~1000
 | 
			
		||||
jobgroup_del_limit_0=拒绝删除,该执行器使用中
 | 
			
		||||
jobgroup_del_limit_1=拒绝删除, 系统至少保留一个执行器
 | 
			
		||||
jobgroup_empty=不存在有效执行器,请联系管理员
 | 
			
		||||
 | 
			
		||||
## job conf
 | 
			
		||||
jobconf_block_SERIAL_EXECUTION=单机串行
 | 
			
		||||
jobconf_block_DISCARD_LATER=丢弃后续调度
 | 
			
		||||
jobconf_block_COVER_EARLY=覆盖之前调度
 | 
			
		||||
jobconf_route_first=第一个
 | 
			
		||||
jobconf_route_last=最后一个
 | 
			
		||||
jobconf_route_round=轮询
 | 
			
		||||
jobconf_route_random=随机
 | 
			
		||||
jobconf_route_consistenthash=一致性HASH
 | 
			
		||||
jobconf_route_lfu=最不经常使用
 | 
			
		||||
jobconf_route_lru=最近最久未使用
 | 
			
		||||
jobconf_route_failover=故障转移
 | 
			
		||||
jobconf_route_busyover=忙碌转移
 | 
			
		||||
jobconf_route_shard=分片广播
 | 
			
		||||
jobconf_idleBeat=空闲检测
 | 
			
		||||
jobconf_beat=心跳检测
 | 
			
		||||
jobconf_monitor=任务调度中心监控报警
 | 
			
		||||
jobconf_monitor_detail=监控告警明细
 | 
			
		||||
jobconf_monitor_alarm_title=告警类型
 | 
			
		||||
jobconf_monitor_alarm_type=调度失败
 | 
			
		||||
jobconf_monitor_alarm_content=告警内容
 | 
			
		||||
jobconf_trigger_admin_adress=调度机器
 | 
			
		||||
jobconf_trigger_exe_regtype=执行器-注册方式
 | 
			
		||||
jobconf_trigger_exe_regaddress=执行器-地址列表
 | 
			
		||||
jobconf_trigger_address_empty=调度失败:执行器地址为空
 | 
			
		||||
jobconf_trigger_run=触发调度
 | 
			
		||||
jobconf_trigger_child_run=触发子任务
 | 
			
		||||
jobconf_callback_child_msg1={0}/{1} [任务ID={2}], 触发{3}, 触发备注: {4} <br>
 | 
			
		||||
jobconf_callback_child_msg2={0}/{1} [任务ID={2}], 触发失败, 触发备注: 任务ID格式错误 <br>
 | 
			
		||||
jobconf_trigger_type=任务触发类型
 | 
			
		||||
jobconf_trigger_type_cron=Cron触发
 | 
			
		||||
jobconf_trigger_type_manual=手动触发
 | 
			
		||||
jobconf_trigger_type_parent=父任务触发
 | 
			
		||||
jobconf_trigger_type_api=API触发
 | 
			
		||||
jobconf_trigger_type_retry=失败重试触发
 | 
			
		||||
jobconf_trigger_type_misfire=调度过期补偿
 | 
			
		||||
 | 
			
		||||
## user
 | 
			
		||||
user_manage=用户管理
 | 
			
		||||
user_username=账号
 | 
			
		||||
user_password=密码
 | 
			
		||||
user_role=角色
 | 
			
		||||
user_role_admin=管理员
 | 
			
		||||
user_role_normal=普通用户
 | 
			
		||||
user_permission=权限
 | 
			
		||||
user_add=新增用户
 | 
			
		||||
user_update=更新用户
 | 
			
		||||
user_username_repeat=账号重复
 | 
			
		||||
user_username_valid=限制以小写字母开头,由小写字母、数字组成
 | 
			
		||||
user_password_update_placeholder=请输入新密码,为空则不更新密码
 | 
			
		||||
user_update_loginuser_limit=禁止操作当前登录账号
 | 
			
		||||
 | 
			
		||||
## help
 | 
			
		||||
job_help=使用教程
 | 
			
		||||
job_help_document=官方文档
 | 
			
		||||
@@ -1,276 +0,0 @@
 | 
			
		||||
admin_name=任務調度中心
 | 
			
		||||
admin_name_full=分布式任務調度平臺XXL-JOB
 | 
			
		||||
admin_version=2.4.0
 | 
			
		||||
admin_i18n=
 | 
			
		||||
 | 
			
		||||
## system
 | 
			
		||||
system_tips=系統提示
 | 
			
		||||
system_ok=確定
 | 
			
		||||
system_close=關閉
 | 
			
		||||
system_save=儲存
 | 
			
		||||
system_cancel=取消
 | 
			
		||||
system_search=搜尋
 | 
			
		||||
system_status=狀態
 | 
			
		||||
system_opt=操作
 | 
			
		||||
system_please_input=請輸入
 | 
			
		||||
system_please_choose=请選擇
 | 
			
		||||
system_success=成功
 | 
			
		||||
system_fail=失敗
 | 
			
		||||
system_add_suc=新增成功
 | 
			
		||||
system_add_fail=新增失敗
 | 
			
		||||
system_update_suc=更新成功
 | 
			
		||||
system_update_fail=更新失敗
 | 
			
		||||
system_all=全部
 | 
			
		||||
system_api_error=API錯誤
 | 
			
		||||
system_show=查看
 | 
			
		||||
system_empty=無
 | 
			
		||||
system_opt_suc=操作成功
 | 
			
		||||
system_opt_fail=操作失敗
 | 
			
		||||
system_opt_edit=編輯
 | 
			
		||||
system_opt_del=刪除
 | 
			
		||||
system_opt_copy=復制
 | 
			
		||||
system_unvalid=非法
 | 
			
		||||
system_not_found=不存在
 | 
			
		||||
system_nav=導航
 | 
			
		||||
system_digits=整數
 | 
			
		||||
system_lengh_limit=長度限制
 | 
			
		||||
system_permission_limit=權限控管
 | 
			
		||||
system_welcome=歡迎
 | 
			
		||||
 | 
			
		||||
## daterangepicker
 | 
			
		||||
daterangepicker_ranges_recent_hour=最近一小時
 | 
			
		||||
daterangepicker_ranges_today=今日
 | 
			
		||||
daterangepicker_ranges_yesterday=昨日
 | 
			
		||||
daterangepicker_ranges_this_month=本月
 | 
			
		||||
daterangepicker_ranges_last_month=上個月
 | 
			
		||||
daterangepicker_ranges_recent_week=最近一周
 | 
			
		||||
daterangepicker_ranges_recent_month=最近一月
 | 
			
		||||
daterangepicker_custom_name=自定義
 | 
			
		||||
daterangepicker_custom_starttime=起始時間
 | 
			
		||||
daterangepicker_custom_endtime=結束時間
 | 
			
		||||
daterangepicker_custom_daysofweek=日,一,二,三,四,五,六
 | 
			
		||||
daterangepicker_custom_monthnames=一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月
 | 
			
		||||
 | 
			
		||||
## dataTable
 | 
			
		||||
dataTable_sProcessing=處理中...
 | 
			
		||||
dataTable_sLengthMenu=每頁 _MENU_ 條記錄
 | 
			
		||||
dataTable_sZeroRecords=沒有相符合記錄
 | 
			
		||||
dataTable_sInfo=第 _PAGE_ 頁 ( 總共 _PAGES_ 頁,_TOTAL_ 條記錄 )
 | 
			
		||||
dataTable_sInfoEmpty=無記錄
 | 
			
		||||
dataTable_sInfoFiltered=(由 _MAX_ 項結果過濾)
 | 
			
		||||
dataTable_sSearch=搜尋
 | 
			
		||||
dataTable_sEmptyTable=表中資料為空
 | 
			
		||||
dataTable_sLoadingRecords=載入中...
 | 
			
		||||
dataTable_sFirst=首頁
 | 
			
		||||
dataTable_sPrevious=上頁
 | 
			
		||||
dataTable_sNext=下頁
 | 
			
		||||
dataTable_sLast=末頁
 | 
			
		||||
dataTable_sSortAscending=: 以升幂排序此列
 | 
			
		||||
dataTable_sSortDescending=: 以降幂排序此列
 | 
			
		||||
 | 
			
		||||
## login
 | 
			
		||||
login_btn=登入
 | 
			
		||||
login_remember_me=記住密碼
 | 
			
		||||
login_username_placeholder=請輸入登入帳號
 | 
			
		||||
login_password_placeholder=請輸入登入密碼
 | 
			
		||||
login_username_empty=請輸入登入帳號
 | 
			
		||||
login_username_lt_4=登入帳號不應低於4位數
 | 
			
		||||
login_password_empty=請輸入登入密碼
 | 
			
		||||
login_password_lt_4=登入密碼不應低於4位數
 | 
			
		||||
login_success=登入成功
 | 
			
		||||
login_fail=登入失敗
 | 
			
		||||
login_param_empty=帳號或密碼為空值
 | 
			
		||||
login_param_unvalid=帳號或密碼錯誤
 | 
			
		||||
 | 
			
		||||
## logout
 | 
			
		||||
logout_btn=登出
 | 
			
		||||
logout_confirm=確認登出?
 | 
			
		||||
logout_success=登出成功
 | 
			
		||||
logout_fail=登出失敗
 | 
			
		||||
 | 
			
		||||
## change pwd
 | 
			
		||||
change_pwd=修改密碼
 | 
			
		||||
change_pwd_suc_to_logout=修改密碼成功,即將登出
 | 
			
		||||
change_pwd_field_newpwd=新密碼
 | 
			
		||||
 | 
			
		||||
## dashboard
 | 
			
		||||
job_dashboard_name=運行報表
 | 
			
		||||
job_dashboard_job_num=任務數量
 | 
			
		||||
job_dashboard_job_num_tip=調度中心運行的任務數量
 | 
			
		||||
job_dashboard_trigger_num=調度次數
 | 
			
		||||
job_dashboard_trigger_num_tip=調度中心觸發的調度次數
 | 
			
		||||
job_dashboard_jobgroup_num=執行器數量
 | 
			
		||||
job_dashboard_jobgroup_num_tip=調度中心在線的執行器機器數量
 | 
			
		||||
job_dashboard_report=調度報表
 | 
			
		||||
job_dashboard_report_loaddata_fail=調度報表資料加載異常
 | 
			
		||||
job_dashboard_date_report=日期分布圖
 | 
			
		||||
job_dashboard_rate_report=成功比例圖
 | 
			
		||||
 | 
			
		||||
## job info
 | 
			
		||||
jobinfo_name=任務管理
 | 
			
		||||
jobinfo_job=任務
 | 
			
		||||
jobinfo_field_add=新增
 | 
			
		||||
jobinfo_field_update=更新任務
 | 
			
		||||
jobinfo_field_id=任務ID
 | 
			
		||||
jobinfo_field_jobgroup=執行器
 | 
			
		||||
jobinfo_field_jobdesc=任務描述
 | 
			
		||||
jobinfo_field_gluetype=運行模式
 | 
			
		||||
jobinfo_field_executorparam=任務參數
 | 
			
		||||
jobinfo_field_author=負責人
 | 
			
		||||
jobinfo_field_timeout=任務超時秒數
 | 
			
		||||
jobinfo_field_alarmemail=告警郵件
 | 
			
		||||
jobinfo_field_alarmemail_placeholder=輸入多個告警郵件地址,請以逗號分隔
 | 
			
		||||
jobinfo_field_executorRouteStrategy=路由策略
 | 
			
		||||
jobinfo_field_childJobId=子任務ID
 | 
			
		||||
jobinfo_field_childJobId_placeholder=輸入子任務ID,如有多個請以逗號分隔
 | 
			
		||||
jobinfo_field_executorBlockStrategy=阻塞處理策略
 | 
			
		||||
jobinfo_field_executorFailRetryCount=失敗重試次數
 | 
			
		||||
jobinfo_field_executorFailRetryCount_placeholder=失敗重試次數,大於零時生效
 | 
			
		||||
jobinfo_script_location=腳本位置
 | 
			
		||||
jobinfo_shard_index=分片序號
 | 
			
		||||
jobinfo_shard_total=分片總數
 | 
			
		||||
jobinfo_opt_stop=停止
 | 
			
		||||
jobinfo_opt_start=啟動
 | 
			
		||||
jobinfo_opt_log=查詢日誌
 | 
			
		||||
jobinfo_opt_run=執行一次
 | 
			
		||||
jobinfo_opt_run_tips=請輸入本次執行的機器地址,為空則從執行器獲取
 | 
			
		||||
jobinfo_opt_registryinfo=注冊節點
 | 
			
		||||
jobinfo_opt_next_time=下次執行時間
 | 
			
		||||
jobinfo_glue_remark=源碼備註
 | 
			
		||||
jobinfo_glue_remark_limit=源碼備註長度限制為4~100
 | 
			
		||||
jobinfo_glue_rollback=版本回復
 | 
			
		||||
jobinfo_glue_jobid_unvalid=任務ID非法
 | 
			
		||||
jobinfo_glue_gluetype_unvalid=該任務非GLUE模式
 | 
			
		||||
jobinfo_field_executorTimeout_placeholder=任務超時時間,單位秒,大於零時生效
 | 
			
		||||
schedule_type=調度類型
 | 
			
		||||
schedule_type_none=無
 | 
			
		||||
schedule_type_cron=CRON
 | 
			
		||||
schedule_type_fix_rate=固定速度
 | 
			
		||||
schedule_type_fix_delay=固定延遲
 | 
			
		||||
schedule_type_none_limit_start=當前調度類型禁止啟動
 | 
			
		||||
misfire_strategy=調度過期策略
 | 
			
		||||
misfire_strategy_do_nothing=忽略
 | 
			
		||||
misfire_strategy_fire_once_now=立即執行壹次
 | 
			
		||||
jobinfo_conf_base=基礎配置
 | 
			
		||||
jobinfo_conf_schedule=調度配置
 | 
			
		||||
jobinfo_conf_job=任務配置
 | 
			
		||||
jobinfo_conf_advanced=高級配置
 | 
			
		||||
 | 
			
		||||
## job log
 | 
			
		||||
joblog_name=調度日誌
 | 
			
		||||
joblog_status=狀態
 | 
			
		||||
joblog_status_all=全部
 | 
			
		||||
joblog_status_suc=成功
 | 
			
		||||
joblog_status_fail=失敗
 | 
			
		||||
joblog_status_running=進行中
 | 
			
		||||
joblog_field_triggerTime=調度時間
 | 
			
		||||
joblog_field_triggerCode=調度結果
 | 
			
		||||
joblog_field_triggerMsg=調度備註
 | 
			
		||||
joblog_field_handleTime=執行時間
 | 
			
		||||
joblog_field_handleCode=執行结果
 | 
			
		||||
joblog_field_handleMsg=執行備註
 | 
			
		||||
joblog_field_executorAddress=執行器地址
 | 
			
		||||
joblog_clean=清理
 | 
			
		||||
joblog_clean_log=日誌清理
 | 
			
		||||
joblog_clean_type=清理方式
 | 
			
		||||
joblog_clean_type_1=清理一個月之前日誌資料
 | 
			
		||||
joblog_clean_type_2=清理三個月之前日誌資料
 | 
			
		||||
joblog_clean_type_3=清理六個月之前日誌資料
 | 
			
		||||
joblog_clean_type_4=清理一年之前日誌資料
 | 
			
		||||
joblog_clean_type_5=清理一千條以前日誌資料
 | 
			
		||||
joblog_clean_type_6=清理一萬條以前日誌資料
 | 
			
		||||
joblog_clean_type_7=清理三萬條以前日誌資料
 | 
			
		||||
joblog_clean_type_8=清理十萬條以前日誌資料
 | 
			
		||||
joblog_clean_type_9=清理所有日誌資料
 | 
			
		||||
joblog_clean_type_unvalid=清理類型參数異常
 | 
			
		||||
joblog_handleCode_200=成功
 | 
			
		||||
joblog_handleCode_500=失敗
 | 
			
		||||
joblog_handleCode_502=失敗(超時)
 | 
			
		||||
joblog_kill_log=终止任務
 | 
			
		||||
joblog_kill_log_limit=調度失敗,無法终止日誌
 | 
			
		||||
joblog_kill_log_byman=人為操作,主動終止
 | 
			
		||||
joblog_lost_fail=任務結果丟失,標記失敗
 | 
			
		||||
joblog_rolling_log=執行日誌
 | 
			
		||||
joblog_rolling_log_refresh=更新
 | 
			
		||||
joblog_rolling_log_triggerfail=任務發起調度失敗,無法查看執行日誌
 | 
			
		||||
joblog_rolling_log_failoften=終止請求Rolling日誌,請求失敗次數超上限,可刷新頁面重新加載日誌
 | 
			
		||||
joblog_logid_unvalid=日誌ID非法
 | 
			
		||||
 | 
			
		||||
## job group
 | 
			
		||||
jobgroup_name=執行器管理
 | 
			
		||||
jobgroup_list=執行器列表
 | 
			
		||||
jobgroup_add=新增執行器
 | 
			
		||||
jobgroup_edit=編輯執行器
 | 
			
		||||
jobgroup_del=刪除執行器
 | 
			
		||||
jobgroup_field_title=名稱
 | 
			
		||||
jobgroup_field_addressType=注冊方式
 | 
			
		||||
jobgroup_field_addressType_0=自動注冊
 | 
			
		||||
jobgroup_field_addressType_1=手動登錄
 | 
			
		||||
jobgroup_field_addressType_limit=手動登錄注冊方式,機器地址不可為空
 | 
			
		||||
jobgroup_field_registryList=機器地址
 | 
			
		||||
jobgroup_field_registryList_unvalid=機器地址格式非法
 | 
			
		||||
jobgroup_field_registryList_placeholder=請輸入執行器地址列表,多個地址請以逗號分隔
 | 
			
		||||
jobgroup_field_appname_limit=限制以小寫字母開頭,由小寫字母、數字和中划線組成
 | 
			
		||||
jobgroup_field_appname_length=AppName長度限制為4~64
 | 
			
		||||
jobgroup_field_title_length=名稱長度限制為4~12
 | 
			
		||||
jobgroup_field_order_digits=請輸入整數
 | 
			
		||||
jobgroup_field_orderrange=取值範圍為1~1000
 | 
			
		||||
jobgroup_del_limit_0=拒絕刪除,該執行器使用中
 | 
			
		||||
jobgroup_del_limit_1=拒絕删除,系统至少保留一個執行器
 | 
			
		||||
jobgroup_empty=不存在有效執行器,請聯絡系統管理員
 | 
			
		||||
 | 
			
		||||
## job conf
 | 
			
		||||
jobconf_block_SERIAL_EXECUTION=單機串行
 | 
			
		||||
jobconf_block_DISCARD_LATER=丢棄后續調度
 | 
			
		||||
jobconf_block_COVER_EARLY=覆蓋之前調度
 | 
			
		||||
jobconf_route_first=第一個
 | 
			
		||||
jobconf_route_last=最後一個
 | 
			
		||||
jobconf_route_round=輪詢
 | 
			
		||||
jobconf_route_random=隨機
 | 
			
		||||
jobconf_route_consistenthash=一致性HASH
 | 
			
		||||
jobconf_route_lfu=最不經常使用
 | 
			
		||||
jobconf_route_lru=最近最久未使用
 | 
			
		||||
jobconf_route_failover=故障轉移
 | 
			
		||||
jobconf_route_busyover=忙碌轉移
 | 
			
		||||
jobconf_route_shard=分片廣播
 | 
			
		||||
jobconf_idleBeat=空閒檢測
 | 
			
		||||
jobconf_beat=心跳檢測
 | 
			
		||||
jobconf_monitor=任務調度中心監控告警
 | 
			
		||||
jobconf_monitor_detail=監控告警明细
 | 
			
		||||
jobconf_monitor_alarm_title=告警類型
 | 
			
		||||
jobconf_monitor_alarm_type=調度失敗
 | 
			
		||||
jobconf_monitor_alarm_content=告警内容
 | 
			
		||||
jobconf_trigger_admin_adress=調度機器
 | 
			
		||||
jobconf_trigger_exe_regtype=執行器-注冊方式
 | 
			
		||||
jobconf_trigger_exe_regaddress=執行器-地址列表
 | 
			
		||||
jobconf_trigger_address_empty=調度失敗:執行器地址為空
 | 
			
		||||
jobconf_trigger_run=觸發調度
 | 
			
		||||
jobconf_trigger_child_run=觸發子任務
 | 
			
		||||
jobconf_callback_child_msg1={0}/{1} [任務ID={2}], 觸發{3}, 觸發備註: {4} <br>
 | 
			
		||||
jobconf_callback_child_msg2={0}/{1} [任務ID={2}], 觸發失败, 觸發備註: 任務ID格式錯誤 <br>
 | 
			
		||||
jobconf_trigger_type=任務觸發類型
 | 
			
		||||
jobconf_trigger_type_cron=Cron觸發
 | 
			
		||||
jobconf_trigger_type_manual=手動觸發
 | 
			
		||||
jobconf_trigger_type_parent=父任務觸發
 | 
			
		||||
jobconf_trigger_type_api=API觸發
 | 
			
		||||
jobconf_trigger_type_retry=失敗重試觸發
 | 
			
		||||
jobconf_trigger_type_misfire=調度過期補償
 | 
			
		||||
 | 
			
		||||
## user
 | 
			
		||||
user_manage=用户管理
 | 
			
		||||
user_username=帳號
 | 
			
		||||
user_password=密碼
 | 
			
		||||
user_role=角色
 | 
			
		||||
user_role_admin=管理員
 | 
			
		||||
user_role_normal=普通用戶
 | 
			
		||||
user_permission=權限
 | 
			
		||||
user_add=新增用戶
 | 
			
		||||
user_update=更新用戶
 | 
			
		||||
user_username_repeat=帳號重複
 | 
			
		||||
user_username_valid=限制以小寫字母開頭,由小寫字母、數字組成
 | 
			
		||||
user_password_update_placeholder=請輸入新密碼,為空則不更新密碼
 | 
			
		||||
user_update_loginuser_limit=禁止操作當前登入帳號
 | 
			
		||||
 | 
			
		||||
## help
 | 
			
		||||
job_help=使用教程
 | 
			
		||||
job_help_document=官方文件
 | 
			
		||||
@@ -1,91 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 | 
			
		||||
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
			
		||||
<mapper namespace="com.xxl.job.admin.dao.XxlJobGroupDao">
 | 
			
		||||
 | 
			
		||||
    <resultMap id="XxlJobGroup" type="com.xxl.job.admin.core.model.XxlJobGroup" >
 | 
			
		||||
        <result column="id" property="id" />
 | 
			
		||||
        <result column="app_name" property="appname" />
 | 
			
		||||
        <result column="title" property="title" />
 | 
			
		||||
        <result column="address_type" property="addressType" />
 | 
			
		||||
        <result column="address_list" property="addressList" />
 | 
			
		||||
        <result column="update_time" property="updateTime" />
 | 
			
		||||
    </resultMap>
 | 
			
		||||
 | 
			
		||||
    <sql id="Base_Column_List">
 | 
			
		||||
        t.id,
 | 
			
		||||
        t.app_name,
 | 
			
		||||
        t.title,
 | 
			
		||||
        t.address_type,
 | 
			
		||||
        t.address_list,
 | 
			
		||||
        t.update_time
 | 
			
		||||
    </sql>
 | 
			
		||||
 | 
			
		||||
    <select id="findAll" resultMap="XxlJobGroup">
 | 
			
		||||
        SELECT <include refid="Base_Column_List" />
 | 
			
		||||
        FROM xxl_job_group AS t
 | 
			
		||||
        ORDER BY t.app_name, t.title, t.id ASC
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <select id="findByAddressType" parameterType="java.lang.Integer" resultMap="XxlJobGroup">
 | 
			
		||||
        SELECT <include refid="Base_Column_List" />
 | 
			
		||||
        FROM xxl_job_group AS t
 | 
			
		||||
        WHERE t.address_type = #{addressType}
 | 
			
		||||
        ORDER BY t.app_name, t.title, t.id ASC
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobGroup" useGeneratedKeys="true" keyProperty="id" >
 | 
			
		||||
        INSERT INTO xxl_job_group ( `app_name`, `title`, `address_type`, `address_list`, `update_time`)
 | 
			
		||||
        values ( #{appname}, #{title}, #{addressType}, #{addressList}, #{updateTime} );
 | 
			
		||||
    </insert>
 | 
			
		||||
 | 
			
		||||
    <update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobGroup" >
 | 
			
		||||
        UPDATE xxl_job_group
 | 
			
		||||
        SET `app_name` = #{appname},
 | 
			
		||||
            `title` = #{title},
 | 
			
		||||
            `address_type` = #{addressType},
 | 
			
		||||
            `address_list` = #{addressList},
 | 
			
		||||
            `update_time` = #{updateTime}
 | 
			
		||||
        WHERE id = #{id}
 | 
			
		||||
    </update>
 | 
			
		||||
 | 
			
		||||
    <delete id="remove" parameterType="java.lang.Integer" >
 | 
			
		||||
        DELETE FROM xxl_job_group
 | 
			
		||||
        WHERE id = #{id}
 | 
			
		||||
    </delete>
 | 
			
		||||
 | 
			
		||||
    <select id="load" parameterType="java.lang.Integer" resultMap="XxlJobGroup">
 | 
			
		||||
        SELECT <include refid="Base_Column_List" />
 | 
			
		||||
        FROM xxl_job_group AS t
 | 
			
		||||
        WHERE t.id = #{id}
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobGroup">
 | 
			
		||||
        SELECT <include refid="Base_Column_List" />
 | 
			
		||||
        FROM xxl_job_group AS t
 | 
			
		||||
        <trim prefix="WHERE" prefixOverrides="AND | OR" >
 | 
			
		||||
            <if test="appname != null and appname != ''">
 | 
			
		||||
                AND t.app_name like CONCAT(CONCAT('%', #{appname}), '%')
 | 
			
		||||
            </if>
 | 
			
		||||
            <if test="title != null and title != ''">
 | 
			
		||||
                AND t.title like CONCAT(CONCAT('%', #{title}), '%')
 | 
			
		||||
            </if>
 | 
			
		||||
        </trim>
 | 
			
		||||
        ORDER BY t.app_name, t.title, t.id ASC
 | 
			
		||||
        LIMIT #{offset}, #{pagesize}
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <select id="pageListCount" parameterType="java.util.HashMap" resultType="int">
 | 
			
		||||
        SELECT count(1)
 | 
			
		||||
        FROM xxl_job_group AS t
 | 
			
		||||
        <trim prefix="WHERE" prefixOverrides="AND | OR" >
 | 
			
		||||
            <if test="appname != null and appname != ''">
 | 
			
		||||
                AND t.app_name like CONCAT(CONCAT('%', #{appname}), '%')
 | 
			
		||||
            </if>
 | 
			
		||||
            <if test="title != null and title != ''">
 | 
			
		||||
                AND t.title like CONCAT(CONCAT('%', #{title}), '%')
 | 
			
		||||
            </if>
 | 
			
		||||
        </trim>
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
@@ -1,240 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 | 
			
		||||
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
			
		||||
<mapper namespace="com.xxl.job.admin.dao.XxlJobInfoDao">
 | 
			
		||||
 | 
			
		||||
    <resultMap id="XxlJobInfo" type="com.xxl.job.admin.core.model.XxlJobInfo" >
 | 
			
		||||
        <result column="id" property="id" />
 | 
			
		||||
 | 
			
		||||
        <result column="job_group" property="jobGroup" />
 | 
			
		||||
        <result column="job_desc" property="jobDesc" />
 | 
			
		||||
 | 
			
		||||
        <result column="add_time" property="addTime" />
 | 
			
		||||
        <result column="update_time" property="updateTime" />
 | 
			
		||||
 | 
			
		||||
        <result column="author" property="author" />
 | 
			
		||||
        <result column="alarm_email" property="alarmEmail" />
 | 
			
		||||
 | 
			
		||||
        <result column="schedule_type" property="scheduleType" />
 | 
			
		||||
        <result column="schedule_conf" property="scheduleConf" />
 | 
			
		||||
        <result column="misfire_strategy" property="misfireStrategy" />
 | 
			
		||||
 | 
			
		||||
        <result column="executor_route_strategy" property="executorRouteStrategy" />
 | 
			
		||||
        <result column="executor_handler" property="executorHandler" />
 | 
			
		||||
        <result column="executor_param" property="executorParam" />
 | 
			
		||||
        <result column="executor_block_strategy" property="executorBlockStrategy" />
 | 
			
		||||
        <result column="executor_timeout" property="executorTimeout" />
 | 
			
		||||
        <result column="executor_fail_retry_count" property="executorFailRetryCount" />
 | 
			
		||||
 | 
			
		||||
        <result column="glue_type" property="glueType" />
 | 
			
		||||
        <result column="glue_source" property="glueSource" />
 | 
			
		||||
        <result column="glue_remark" property="glueRemark" />
 | 
			
		||||
        <result column="glue_updatetime" property="glueUpdatetime" />
 | 
			
		||||
 | 
			
		||||
        <result column="child_jobid" property="childJobId" />
 | 
			
		||||
 | 
			
		||||
        <result column="trigger_status" property="triggerStatus" />
 | 
			
		||||
        <result column="trigger_last_time" property="triggerLastTime" />
 | 
			
		||||
        <result column="trigger_next_time" property="triggerNextTime" />
 | 
			
		||||
    </resultMap>
 | 
			
		||||
 | 
			
		||||
    <sql id="Base_Column_List">
 | 
			
		||||
        t.id,
 | 
			
		||||
        t.job_group,
 | 
			
		||||
        t.job_desc,
 | 
			
		||||
        t.add_time,
 | 
			
		||||
        t.update_time,
 | 
			
		||||
        t.author,
 | 
			
		||||
        t.alarm_email,
 | 
			
		||||
        t.schedule_type,
 | 
			
		||||
        t.schedule_conf,
 | 
			
		||||
        t.misfire_strategy,
 | 
			
		||||
        t.executor_route_strategy,
 | 
			
		||||
        t.executor_handler,
 | 
			
		||||
        t.executor_param,
 | 
			
		||||
        t.executor_block_strategy,
 | 
			
		||||
        t.executor_timeout,
 | 
			
		||||
        t.executor_fail_retry_count,
 | 
			
		||||
        t.glue_type,
 | 
			
		||||
        t.glue_source,
 | 
			
		||||
        t.glue_remark,
 | 
			
		||||
        t.glue_updatetime,
 | 
			
		||||
        t.child_jobid,
 | 
			
		||||
        t.trigger_status,
 | 
			
		||||
        t.trigger_last_time,
 | 
			
		||||
        t.trigger_next_time
 | 
			
		||||
    </sql>
 | 
			
		||||
 | 
			
		||||
    <select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
 | 
			
		||||
        SELECT <include refid="Base_Column_List" />
 | 
			
		||||
        FROM xxl_job_info AS t
 | 
			
		||||
        <trim prefix="WHERE" prefixOverrides="AND | OR" >
 | 
			
		||||
            <if test="jobGroup gt 0">
 | 
			
		||||
                AND t.job_group = #{jobGroup}
 | 
			
		||||
            </if>
 | 
			
		||||
            <if test="triggerStatus gte 0">
 | 
			
		||||
                AND t.trigger_status = #{triggerStatus}
 | 
			
		||||
            </if>
 | 
			
		||||
            <if test="jobDesc != null and jobDesc != ''">
 | 
			
		||||
                AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%')
 | 
			
		||||
            </if>
 | 
			
		||||
            <if test="executorHandler != null and executorHandler != ''">
 | 
			
		||||
                AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
 | 
			
		||||
            </if>
 | 
			
		||||
            <if test="author != null and author != ''">
 | 
			
		||||
                AND t.author like CONCAT(CONCAT('%', #{author}), '%')
 | 
			
		||||
            </if>
 | 
			
		||||
        </trim>
 | 
			
		||||
        ORDER BY id DESC
 | 
			
		||||
        LIMIT #{offset}, #{pagesize}
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <select id="pageListCount" parameterType="java.util.HashMap" resultType="int">
 | 
			
		||||
        SELECT count(1)
 | 
			
		||||
        FROM xxl_job_info AS t
 | 
			
		||||
        <trim prefix="WHERE" prefixOverrides="AND | OR" >
 | 
			
		||||
            <if test="jobGroup gt 0">
 | 
			
		||||
                AND t.job_group = #{jobGroup}
 | 
			
		||||
            </if>
 | 
			
		||||
            <if test="triggerStatus gte 0">
 | 
			
		||||
                AND t.trigger_status = #{triggerStatus}
 | 
			
		||||
            </if>
 | 
			
		||||
            <if test="jobDesc != null and jobDesc != ''">
 | 
			
		||||
                AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%')
 | 
			
		||||
            </if>
 | 
			
		||||
            <if test="executorHandler != null and executorHandler != ''">
 | 
			
		||||
                AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
 | 
			
		||||
            </if>
 | 
			
		||||
            <if test="author != null and author != ''">
 | 
			
		||||
                AND t.author like CONCAT(CONCAT('%', #{author}), '%')
 | 
			
		||||
            </if>
 | 
			
		||||
        </trim>
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" useGeneratedKeys="true" keyProperty="id" >
 | 
			
		||||
        INSERT INTO xxl_job_info (
 | 
			
		||||
            job_group,
 | 
			
		||||
            job_desc,
 | 
			
		||||
            add_time,
 | 
			
		||||
            update_time,
 | 
			
		||||
            author,
 | 
			
		||||
            alarm_email,
 | 
			
		||||
            schedule_type,
 | 
			
		||||
            schedule_conf,
 | 
			
		||||
            misfire_strategy,
 | 
			
		||||
            executor_route_strategy,
 | 
			
		||||
            executor_handler,
 | 
			
		||||
            executor_param,
 | 
			
		||||
            executor_block_strategy,
 | 
			
		||||
            executor_timeout,
 | 
			
		||||
            executor_fail_retry_count,
 | 
			
		||||
            glue_type,
 | 
			
		||||
            glue_source,
 | 
			
		||||
            glue_remark,
 | 
			
		||||
            glue_updatetime,
 | 
			
		||||
            child_jobid,
 | 
			
		||||
            trigger_status,
 | 
			
		||||
            trigger_last_time,
 | 
			
		||||
            trigger_next_time
 | 
			
		||||
        ) VALUES (
 | 
			
		||||
            #{jobGroup},
 | 
			
		||||
            #{jobDesc},
 | 
			
		||||
            #{addTime},
 | 
			
		||||
            #{updateTime},
 | 
			
		||||
            #{author},
 | 
			
		||||
            #{alarmEmail},
 | 
			
		||||
            #{scheduleType},
 | 
			
		||||
            #{scheduleConf},
 | 
			
		||||
            #{misfireStrategy},
 | 
			
		||||
            #{executorRouteStrategy},
 | 
			
		||||
            #{executorHandler},
 | 
			
		||||
            #{executorParam},
 | 
			
		||||
            #{executorBlockStrategy},
 | 
			
		||||
            #{executorTimeout},
 | 
			
		||||
            #{executorFailRetryCount},
 | 
			
		||||
            #{glueType},
 | 
			
		||||
            #{glueSource},
 | 
			
		||||
            #{glueRemark},
 | 
			
		||||
            #{glueUpdatetime},
 | 
			
		||||
            #{childJobId},
 | 
			
		||||
            #{triggerStatus},
 | 
			
		||||
            #{triggerLastTime},
 | 
			
		||||
            #{triggerNextTime}
 | 
			
		||||
        );
 | 
			
		||||
        <!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
 | 
			
		||||
            SELECT LAST_INSERT_ID()
 | 
			
		||||
            /*SELECT @@IDENTITY AS id*/
 | 
			
		||||
        </selectKey>-->
 | 
			
		||||
    </insert>
 | 
			
		||||
 | 
			
		||||
    <select id="loadById" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
 | 
			
		||||
        SELECT <include refid="Base_Column_List" />
 | 
			
		||||
        FROM xxl_job_info AS t
 | 
			
		||||
        WHERE t.id = #{id}
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" >
 | 
			
		||||
        UPDATE xxl_job_info
 | 
			
		||||
        SET
 | 
			
		||||
            job_group = #{jobGroup},
 | 
			
		||||
            job_desc = #{jobDesc},
 | 
			
		||||
            update_time = #{updateTime},
 | 
			
		||||
            author = #{author},
 | 
			
		||||
            alarm_email = #{alarmEmail},
 | 
			
		||||
            schedule_type = #{scheduleType},
 | 
			
		||||
            schedule_conf = #{scheduleConf},
 | 
			
		||||
            misfire_strategy = #{misfireStrategy},
 | 
			
		||||
            executor_route_strategy = #{executorRouteStrategy},
 | 
			
		||||
            executor_handler = #{executorHandler},
 | 
			
		||||
            executor_param = #{executorParam},
 | 
			
		||||
            executor_block_strategy = #{executorBlockStrategy},
 | 
			
		||||
            executor_timeout = ${executorTimeout},
 | 
			
		||||
            executor_fail_retry_count = ${executorFailRetryCount},
 | 
			
		||||
            glue_type = #{glueType},
 | 
			
		||||
            glue_source = #{glueSource},
 | 
			
		||||
            glue_remark = #{glueRemark},
 | 
			
		||||
            glue_updatetime = #{glueUpdatetime},
 | 
			
		||||
            child_jobid = #{childJobId},
 | 
			
		||||
            trigger_status = #{triggerStatus},
 | 
			
		||||
            trigger_last_time = #{triggerLastTime},
 | 
			
		||||
            trigger_next_time = #{triggerNextTime}
 | 
			
		||||
        WHERE id = #{id}
 | 
			
		||||
    </update>
 | 
			
		||||
 | 
			
		||||
    <delete id="delete" parameterType="java.util.HashMap">
 | 
			
		||||
        DELETE
 | 
			
		||||
        FROM xxl_job_info
 | 
			
		||||
        WHERE id = #{id}
 | 
			
		||||
    </delete>
 | 
			
		||||
 | 
			
		||||
    <select id="getJobsByGroup" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
 | 
			
		||||
        SELECT <include refid="Base_Column_List" />
 | 
			
		||||
        FROM xxl_job_info AS t
 | 
			
		||||
        WHERE t.job_group = #{jobGroup}
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <select id="findAllCount" resultType="int">
 | 
			
		||||
        SELECT count(1)
 | 
			
		||||
        FROM xxl_job_info
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <select id="scheduleJobQuery" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
 | 
			
		||||
        SELECT <include refid="Base_Column_List" />
 | 
			
		||||
        FROM xxl_job_info AS t
 | 
			
		||||
        WHERE t.trigger_status = 1
 | 
			
		||||
            and t.trigger_next_time <![CDATA[ <= ]]> #{maxNextTime}
 | 
			
		||||
        ORDER BY id ASC
 | 
			
		||||
        LIMIT #{pagesize}
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <update id="scheduleUpdate" parameterType="com.xxl.job.admin.core.model.XxlJobInfo"  >
 | 
			
		||||
        UPDATE xxl_job_info
 | 
			
		||||
        SET
 | 
			
		||||
            trigger_last_time = #{triggerLastTime},
 | 
			
		||||
            trigger_next_time = #{triggerNextTime},
 | 
			
		||||
            trigger_status = #{triggerStatus}
 | 
			
		||||
        WHERE id = #{id}
 | 
			
		||||
    </update>
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
@@ -1,71 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 | 
			
		||||
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
			
		||||
<mapper namespace="com.xxl.job.admin.dao.XxlJobLogGlueDao">
 | 
			
		||||
 | 
			
		||||
    <resultMap id="XxlJobLogGlue" type="com.xxl.job.admin.core.model.XxlJobLogGlue" >
 | 
			
		||||
        <result column="id" property="id" />
 | 
			
		||||
        <result column="job_id" property="jobId" />
 | 
			
		||||
        <result column="glue_type" property="glueType" />
 | 
			
		||||
        <result column="glue_source" property="glueSource" />
 | 
			
		||||
        <result column="glue_remark" property="glueRemark" />
 | 
			
		||||
        <result column="add_time" property="addTime" />
 | 
			
		||||
        <result column="update_time" property="updateTime" />
 | 
			
		||||
    </resultMap>
 | 
			
		||||
 | 
			
		||||
    <sql id="Base_Column_List">
 | 
			
		||||
        t.id,
 | 
			
		||||
        t.job_id,
 | 
			
		||||
        t.glue_type,
 | 
			
		||||
        t.glue_source,
 | 
			
		||||
        t.glue_remark,
 | 
			
		||||
        t.add_time,
 | 
			
		||||
        t.update_time
 | 
			
		||||
    </sql>
 | 
			
		||||
 | 
			
		||||
    <insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobLogGlue" useGeneratedKeys="true" keyProperty="id" >
 | 
			
		||||
        INSERT INTO xxl_job_logglue (
 | 
			
		||||
            `job_id`,
 | 
			
		||||
            `glue_type`,
 | 
			
		||||
            `glue_source`,
 | 
			
		||||
            `glue_remark`,
 | 
			
		||||
            `add_time`,
 | 
			
		||||
            `update_time`
 | 
			
		||||
        ) VALUES (
 | 
			
		||||
            #{jobId},
 | 
			
		||||
            #{glueType},
 | 
			
		||||
            #{glueSource},
 | 
			
		||||
            #{glueRemark},
 | 
			
		||||
            #{addTime},
 | 
			
		||||
            #{updateTime}
 | 
			
		||||
        );
 | 
			
		||||
        <!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
 | 
			
		||||
            SELECT LAST_INSERT_ID()
 | 
			
		||||
        </selectKey>-->
 | 
			
		||||
    </insert>
 | 
			
		||||
 | 
			
		||||
    <select id="findByJobId" parameterType="java.lang.Integer" resultMap="XxlJobLogGlue">
 | 
			
		||||
        SELECT <include refid="Base_Column_List" />
 | 
			
		||||
        FROM xxl_job_logglue AS t
 | 
			
		||||
        WHERE t.job_id = #{jobId}
 | 
			
		||||
        ORDER BY id DESC
 | 
			
		||||
    </select>
 | 
			
		||||
 | 
			
		||||
    <delete id="removeOld" >
 | 
			
		||||
        DELETE FROM xxl_job_logglue
 | 
			
		||||
        WHERE id NOT in(
 | 
			
		||||
            SELECT id FROM(
 | 
			
		||||
                SELECT id FROM xxl_job_logglue
 | 
			
		||||
                WHERE `job_id` = #{jobId}
 | 
			
		||||
                ORDER BY update_time desc
 | 
			
		||||
                LIMIT 0, #{limit}
 | 
			
		||||
            ) t1
 | 
			
		||||
        ) AND `job_id` = #{jobId}
 | 
			
		||||
    </delete>
 | 
			
		||||
 | 
			
		||||
    <delete id="deleteByJobId" parameterType="java.lang.Integer" >
 | 
			
		||||
        DELETE FROM xxl_job_logglue
 | 
			
		||||
        WHERE `job_id` = #{jobId}
 | 
			
		||||
    </delete>
 | 
			
		||||
 | 
			
		||||
</mapper>
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user