Merge branch 'v2.1.1'

This commit is contained in:
weiye 2020-01-06 13:49:56 +08:00
commit 7d33026762
56 changed files with 930 additions and 61 deletions

View File

@ -85,7 +85,7 @@ http://localhost:8080/index.html#/dashboard
- 覆盖之前调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务;
- 增量增新建议将阻塞策略设置为丢弃后续调度或者单机串行
- 设置单机串行时应该注意合理设置重试次数(失败重试的次数*每次执行时间<任务的调度周期)重试的次数如果设置的过多会导致数据重复例如任务30秒执行一次每次执行时间需要20秒设置重试三次如果任务失败了第一个重试的时间段为1577755680-1577756680重试任务没结束新任务又开启那新任务的时间段会是1577755680-1577758680
[增量参数设置](https://github.com/WeiYe-Jing/datax-web/blob/master/doc/datax-web/%E5%8A%A8%E6%80%81%E5%8F%82%E6%95%B0%E5%AE%8C%E6%88%90%E5%A2%9E%E9%87%8F%E6%8A%BD%E5%8F%96.md
- [增量参数设置](https://github.com/WeiYe-Jing/datax-web/blob/master/doc/datax-web/%E5%8A%A8%E6%80%81%E5%8F%82%E6%95%B0%E5%AE%8C%E6%88%90%E5%A2%9E%E9%87%8F%E6%8A%BD%E5%8F%96.md
)
### 10. 任务列表
![](https://github.com/WeiYe-Jing/datax-web/blob/master/doc/img/job.png)
@ -109,9 +109,13 @@ Quick Start操作完前四步之后
- 修复前端页面自适应问题
- 修复添加任务时json转换失败的问题
- 修复构建json时数据库连接增加问题
- 修复增量更新失败重试成功后增量更新时间跳跃的问题
- 修复失败重试时序列化失败问题
- 1、指定增量字段自动获取每次的数据区间
- 2、页面配置datax启动参数
- 3、数据源连接错误提醒功能
- 4、任务模板创建
- 5、构建JSON之后选择任务模板创建任务
## TODO List
- 1、从源表到目标端表的自动创建
- 2、任务批量导入功能

View File

@ -5,8 +5,8 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.api.R;
import com.wugui.datax.admin.core.util.LocalCacheUtil;
import com.wugui.datax.admin.service.IJobJdbcDatasourceService;
import com.wugui.datax.admin.tool.query.BaseQueryTool;
import com.wugui.datax.admin.util.PageUtils;
import com.wugui.datax.admin.entity.JobJdbcDatasource;
import io.swagger.annotations.Api;
@ -132,7 +132,7 @@ public class JobJdbcDatasourceController extends ApiController {
@PutMapping
@ApiOperation("修改数据")
public R<Boolean> update(@RequestBody JobJdbcDatasource entity) {
BaseQueryTool.CREATED_CONNECTIONS.remove(entity.getDatasourceName());
LocalCacheUtil.remove(entity.getDatasourceName());
return success(this.jobJdbcDatasourceService.updateById(entity));
}

View File

@ -0,0 +1,81 @@
package com.wugui.datax.admin.controller;
import com.wugui.datatx.core.biz.model.ReturnT;
import com.wugui.datatx.core.util.DateUtil;
import com.wugui.datax.admin.core.cron.CronExpression;
import com.wugui.datax.admin.core.util.I18nUtil;
import com.wugui.datax.admin.entity.JobTemplate;
import com.wugui.datax.admin.service.JobTemplateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* index controller
*
* @author xuxueli 2015-12-19 16:13:16
*/
@Api(tags = "任务配置接口")
@RestController
@RequestMapping("/api/jobTemplate")
public class JobTemplateController {
@Resource
private JobTemplateService xxlJobTemplateService;
@GetMapping("/pageList")
@ApiOperation("任务列表")
public ReturnT<Map<String, Object>> pageList(@RequestParam(required = false, defaultValue = "0") int current,
@RequestParam(required = false, defaultValue = "10") int size,
int jobGroup, String jobDesc, String executorHandler, String author) {
return new ReturnT<>(xxlJobTemplateService.pageList((current-1)*size, size, jobGroup, jobDesc, executorHandler, author));
}
@PostMapping("/add")
@ApiOperation("添加任务")
public ReturnT<String> add(@RequestBody JobTemplate jobTemplate) {
return xxlJobTemplateService.add(jobTemplate);
}
@PostMapping("/update")
@ApiOperation("更新任务")
public ReturnT<String> update(@RequestBody JobTemplate jobTemplate) {
return xxlJobTemplateService.update(jobTemplate);
}
@PostMapping(value = "/remove/{id}")
@ApiOperation("移除任务")
public ReturnT<String> remove(@PathVariable(value = "id") int id) {
return xxlJobTemplateService.remove(id);
}
@GetMapping("/nextTriggerTime")
@ApiOperation("获取近5次触发时间")
public ReturnT<List<String>> nextTriggerTime(String cron) {
List<String> result = new ArrayList<>();
try {
CronExpression cronExpression = new CronExpression(cron);
Date lastTime = new Date();
for (int i = 0; i < 5; i++) {
lastTime = cronExpression.getNextValidTimeAfter(lastTime);
if (lastTime != null) {
result.add(DateUtil.formatDateTime(lastTime));
} else {
break;
}
}
} catch (ParseException e) {
return new ReturnT<>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid"));
}
return new ReturnT<>(result);
}
}

View File

@ -0,0 +1,89 @@
package com.wugui.datax.admin.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* xxl-job info
*
* @author jingwk 2019-11-17 14:25:49
*/
@Data
public class JobTemplate {
@ApiModelProperty("主键ID")
private int id;
@ApiModelProperty("执行器主键ID")
private int jobGroup;
@ApiModelProperty("任务执行CRON表达式")
private String jobCron;
@ApiModelProperty("排序")
private String jobDesc;
private Date addTime;
private Date updateTime;
@ApiModelProperty("负责人")
private String author;
@ApiModelProperty("报警邮件")
private String alarmEmail;
@ApiModelProperty("执行器路由策略")
private String executorRouteStrategy;
@ApiModelProperty("执行器任务Handler名称")
private String executorHandler;
@ApiModelProperty("执行器,任务参数")
private String executorParam;
@ApiModelProperty("阻塞处理策略")
private String executorBlockStrategy;
@ApiModelProperty("任务执行超时时间,单位秒")
private int executorTimeout;
@ApiModelProperty("失败重试次数")
private int executorFailRetryCount;
@ApiModelProperty("GLUE类型\t#com.wugui.datatx.core.glue.GlueTypeEnum")
private String glueType;
@ApiModelProperty("GLUE源代码")
private String glueSource;
@ApiModelProperty("GLUE备注")
private String glueRemark;
@ApiModelProperty("GLUE更新时间")
private Date glueUpdatetime;
@ApiModelProperty("子任务ID多个逗号分隔")
private String childJobId;
@ApiModelProperty("上次调度时间")
private long triggerLastTime;
@ApiModelProperty("下次调度时间")
private long triggerNextTime;
@ApiModelProperty("datax运行json")
private String jobJson;
@ApiModelProperty("脚本动态参数")
private String replaceParam;
@ApiModelProperty("jvm参数")
private String jvmParam;
@ApiModelProperty("增量初始时间")
private Date incStartTime;
}

View File

@ -0,0 +1,38 @@
package com.wugui.datax.admin.mapper;
import com.wugui.datax.admin.entity.JobTemplate;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* job info
* @author xuxueli 2016-1-12 18:03:45
*/
@Mapper
public interface JobTemplateMapper {
public List<JobTemplate> pageList(@Param("offset") int offset,
@Param("pagesize") int pagesize,
@Param("jobGroup") int jobGroup,
@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("jobDesc") String jobDesc,
@Param("executorHandler") String executorHandler,
@Param("author") String author);
public int save(JobTemplate info);
public JobTemplate loadById(@Param("id") int id);
public int update(JobTemplate xxlJobTemplate);
public int delete(@Param("id") long id);
}

View File

@ -0,0 +1,52 @@
package com.wugui.datax.admin.service;
import com.wugui.datatx.core.biz.model.ReturnT;
import com.wugui.datax.admin.entity.JobTemplate;
import java.util.Map;
/**
* core job action for datax-web
*
* @author xuxueli 2016-5-28 15:30:33
*/
public interface JobTemplateService {
/**
* 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, String jobDesc, String executorHandler, String author);
/**
* add job
*
* @param jobTemplate
* @return
*/
public ReturnT<String> add(JobTemplate jobTemplate);
/**
* update job
*
* @param jobTemplate
* @return
*/
public ReturnT<String> update(JobTemplate jobTemplate);
/**
* remove job
* *
* @param id
* @return
*/
public ReturnT<String> remove(int id);
}

View File

@ -0,0 +1,242 @@
package com.wugui.datax.admin.service.impl;
import com.google.common.collect.Maps;
import com.wugui.datatx.core.biz.model.ReturnT;
import com.wugui.datatx.core.enums.ExecutorBlockStrategyEnum;
import com.wugui.datatx.core.glue.GlueTypeEnum;
import com.wugui.datatx.core.util.DateUtil;
import com.wugui.datax.admin.core.cron.CronExpression;
import com.wugui.datax.admin.core.route.ExecutorRouteStrategyEnum;
import com.wugui.datax.admin.core.thread.JobScheduleHelper;
import com.wugui.datax.admin.core.util.I18nUtil;
import com.wugui.datax.admin.entity.JobGroup;
import com.wugui.datax.admin.entity.JobLogReport;
import com.wugui.datax.admin.entity.JobTemplate;
import com.wugui.datax.admin.mapper.*;
import com.wugui.datax.admin.service.JobTemplateService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
/**
* core job action for xxl-job
* @author xuxueli 2016-5-28 15:30:33
*/
@Service
public class JobTemplateServiceImpl implements JobTemplateService {
private static Logger logger = LoggerFactory.getLogger(JobTemplateServiceImpl.class);
@Resource
private JobGroupMapper jobGroupMapper;
@Resource
private JobTemplateMapper jobTemplateMapper;
@Resource
private JobLogMapper jobLogMapper;
@Resource
private JobLogGlueMapper jobLogGlueMapper;
@Resource
private JobLogReportMapper jobLogReportMapper;
private final static ConcurrentMap<String, String> jobTmpFiles = Maps.newConcurrentMap();
@Override
public Map<String, Object> pageList(int start, int length, int jobGroup, String jobDesc, String executorHandler, String author) {
// page list
List<JobTemplate> list = jobTemplateMapper.pageList(start, length, jobGroup, jobDesc, executorHandler, author);
int list_count = jobTemplateMapper.pageListCount(start, length, jobGroup, 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(JobTemplate jobTemplate) {
// valid
JobGroup group = jobGroupMapper.load(jobTemplate.getJobGroup());
if (group == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_choose")+I18nUtil.getString("jobinfo_field_jobgroup")) );
}
if (!CronExpression.isValidExpression(jobTemplate.getJobCron())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") );
}
if (jobTemplate.getJobDesc()==null || jobTemplate.getJobDesc().trim().length()==0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) );
}
if (jobTemplate.getAuthor()==null || jobTemplate.getAuthor().trim().length()==0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) );
}
if (ExecutorRouteStrategyEnum.match(jobTemplate.getExecutorRouteStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) );
}
if (ExecutorBlockStrategyEnum.match(jobTemplate.getExecutorBlockStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) );
}
if (GlueTypeEnum.match(jobTemplate.getGlueType()) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_gluetype")+I18nUtil.getString("system_unvalid")) );
}
if (GlueTypeEnum.BEAN==GlueTypeEnum.match(jobTemplate.getGlueType()) && (jobTemplate.getExecutorHandler()==null || jobTemplate.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(jobTemplate.getGlueType()) && jobTemplate.getGlueSource()!=null) {
jobTemplate.setGlueSource(jobTemplate.getGlueSource().replaceAll("\r", ""));
}
// ChildJobId valid
if (jobTemplate.getChildJobId()!=null && jobTemplate.getChildJobId().trim().length()>0) {
String[] childJobIds = jobTemplate.getChildJobId().split(",");
for (String childJobIdItem: childJobIds) {
if (childJobIdItem!=null && childJobIdItem.trim().length()>0 && isNumeric(childJobIdItem)) {
JobTemplate childJobTemplate = jobTemplateMapper.loadById(Integer.parseInt(childJobIdItem));
if (childJobTemplate==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);
jobTemplate.setChildJobId(temp);
}
// add in db
jobTemplate.setAddTime(new Date());
jobTemplate.setUpdateTime(new Date());
jobTemplate.setGlueUpdatetime(new Date());
jobTemplateMapper.save(jobTemplate);
if (jobTemplate.getId() < 1) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail")) );
}
return new ReturnT<String>(String.valueOf(jobTemplate.getId()));
}
private boolean isNumeric(String str){
try {
int result = Integer.valueOf(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public ReturnT<String> update(JobTemplate jobTemplate) {
// valid
if (!CronExpression.isValidExpression(jobTemplate.getJobCron())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") );
}
if (jobTemplate.getJobDesc()==null || jobTemplate.getJobDesc().trim().length()==0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) );
}
if (jobTemplate.getAuthor()==null || jobTemplate.getAuthor().trim().length()==0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) );
}
if (ExecutorRouteStrategyEnum.match(jobTemplate.getExecutorRouteStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) );
}
if (ExecutorBlockStrategyEnum.match(jobTemplate.getExecutorBlockStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) );
}
// ChildJobId valid
if (jobTemplate.getChildJobId()!=null && jobTemplate.getChildJobId().trim().length()>0) {
String[] childJobIds = jobTemplate.getChildJobId().split(",");
for (String childJobIdItem: childJobIds) {
if (childJobIdItem!=null && childJobIdItem.trim().length()>0 && isNumeric(childJobIdItem)) {
JobTemplate childJobTemplate = jobTemplateMapper.loadById(Integer.parseInt(childJobIdItem));
if (childJobTemplate==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);
jobTemplate.setChildJobId(temp);
}
// group valid
JobGroup jobGroup = jobGroupMapper.load(jobTemplate.getJobGroup());
if (jobGroup == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_jobgroup")+I18nUtil.getString("system_unvalid")) );
}
// stage job info
JobTemplate exists_jobTemplate = jobTemplateMapper.loadById(jobTemplate.getId());
if (exists_jobTemplate == 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_jobTemplate.getTriggerNextTime();
exists_jobTemplate.setJobGroup(jobTemplate.getJobGroup());
exists_jobTemplate.setJobCron(jobTemplate.getJobCron());
exists_jobTemplate.setJobDesc(jobTemplate.getJobDesc());
exists_jobTemplate.setAuthor(jobTemplate.getAuthor());
exists_jobTemplate.setAlarmEmail(jobTemplate.getAlarmEmail());
exists_jobTemplate.setExecutorRouteStrategy(jobTemplate.getExecutorRouteStrategy());
exists_jobTemplate.setExecutorHandler(jobTemplate.getExecutorHandler());
exists_jobTemplate.setExecutorParam(jobTemplate.getExecutorParam());
exists_jobTemplate.setExecutorBlockStrategy(jobTemplate.getExecutorBlockStrategy());
exists_jobTemplate.setExecutorTimeout(jobTemplate.getExecutorTimeout());
exists_jobTemplate.setExecutorFailRetryCount(jobTemplate.getExecutorFailRetryCount());
exists_jobTemplate.setChildJobId(jobTemplate.getChildJobId());
exists_jobTemplate.setTriggerNextTime(nextTriggerTime);
exists_jobTemplate.setJobJson(jobTemplate.getJobJson());
exists_jobTemplate.setReplaceParam(jobTemplate.getReplaceParam());
exists_jobTemplate.setJvmParam(jobTemplate.getJvmParam());
exists_jobTemplate.setIncStartTime(jobTemplate.getIncStartTime());
exists_jobTemplate.setUpdateTime(new Date());
jobTemplateMapper.update(exists_jobTemplate);
return ReturnT.SUCCESS;
}
@Override
public ReturnT<String> remove(int id) {
JobTemplate xxlJobTemplate = jobTemplateMapper.loadById(id);
if (xxlJobTemplate == null) {
return ReturnT.SUCCESS;
}
jobTemplateMapper.delete(id);
jobLogMapper.delete(id);
jobLogGlueMapper.deleteByJobId(id);
return ReturnT.SUCCESS;
}
}

View File

@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.util.JdbcUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.wugui.datax.admin.core.util.LocalCacheUtil;
import com.wugui.datax.admin.entity.JobJdbcDatasource;
import com.wugui.datax.admin.tool.database.ColumnInfo;
import com.wugui.datax.admin.tool.database.DasColumn;
@ -32,8 +32,6 @@ import java.util.Map;
public abstract class BaseQueryTool implements QueryToolInterface {
protected static final Logger logger = LoggerFactory.getLogger(BaseQueryTool.class);
public static final Map<String, Connection> CREATED_CONNECTIONS = Maps.newConcurrentMap();
/**
* 用于获取查询语句
*/
@ -53,7 +51,8 @@ public abstract class BaseQueryTool implements QueryToolInterface {
* @param jobJdbcDatasource
*/
BaseQueryTool(JobJdbcDatasource jobJdbcDatasource) throws SQLException {
if(!CREATED_CONNECTIONS.containsKey(jobJdbcDatasource.getDatasourceName())){
String currentDbType = JdbcUtils.getDbType(jobJdbcDatasource.getJdbcUrl(), jobJdbcDatasource.getJdbcDriverClass());
if (LocalCacheUtil.get(jobJdbcDatasource.getDatasourceName()) == null) {
//这里默认使用 hikari 数据源
HikariDataSource dataSource = new HikariDataSource();
dataSource.setUsername(jobJdbcDatasource.getJdbcUsername());
@ -61,22 +60,18 @@ public abstract class BaseQueryTool implements QueryToolInterface {
dataSource.setJdbcUrl(jobJdbcDatasource.getJdbcUrl());
dataSource.setDriverClassName(jobJdbcDatasource.getJdbcDriverClass());
dataSource.setMaximumPoolSize(1);
dataSource.setMaxLifetime(45000);
dataSource.setIdleTimeout(35000);
dataSource.setMinimumIdle(0);
dataSource.setConnectionTimeout(30000);
dataSource.setConnectionTestQuery("SELECT 1");
//设为只读
dataSource.setReadOnly(true);
this.datasource = dataSource;
this.connection = this.datasource.getConnection();
}else{
this.connection =CREATED_CONNECTIONS.get(jobJdbcDatasource.getDatasourceName());
} else {
this.connection = (Connection) LocalCacheUtil.get(jobJdbcDatasource.getDatasourceName());
}
String currentDbType = JdbcUtils.getDbType(jobJdbcDatasource.getJdbcUrl(), jobJdbcDatasource.getJdbcDriverClass());
sqlBuilder = DatabaseMetaFactory.getByDbType(currentDbType);
currentSchema = getSchema(jobJdbcDatasource.getJdbcUsername());
CREATED_CONNECTIONS.put(jobJdbcDatasource.getDatasourceName(),this.connection);
LocalCacheUtil.set(jobJdbcDatasource.getDatasourceName(), this.connection, 4 * 60 * 60 * 1000);
}
//根据connection获取schema

View File

@ -0,0 +1,209 @@
<?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.wugui.datax.admin.mapper.JobTemplateMapper">
<resultMap id="JobTemplate" type="com.wugui.datax.admin.entity.JobTemplate" >
<result column="id" property="id" />
<result column="job_group" property="jobGroup" />
<result column="job_cron" property="jobCron" />
<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="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_last_time" property="triggerLastTime" />
<result column="trigger_next_time" property="triggerNextTime" />
<result column="job_json" property="jobJson" />
<result column="replace_param" property="replaceParam" />
<result column="jvm_param" property="jvmParam" />
<result column="inc_start_time" property="incStartTime" />
</resultMap>
<sql id="Base_Column_List">
t.id,
t.job_group,
t.job_cron,
t.job_desc,
t.add_time,
t.update_time,
t.author,
t.alarm_email,
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_last_time,
t.trigger_next_time,
t.job_json,
t.replace_param,
t.jvm_param,
t.inc_start_time
</sql>
<select id="pageList" parameterType="java.util.HashMap" resultMap="JobTemplate">
SELECT <include refid="Base_Column_List" />
FROM job_template AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="jobGroup gt 0">
AND t.job_group = #{jobGroup}
</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 job_template AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="jobGroup gt 0">
AND t.job_group = #{jobGroup}
</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.wugui.datax.admin.entity.JobTemplate" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO job_template (
job_group,
job_cron,
job_desc,
add_time,
update_time,
author,
alarm_email,
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_last_time,
trigger_next_time,
job_json,
replace_param,
jvm_param,
inc_start_time
) VALUES (
#{jobGroup},
#{jobCron},
#{jobDesc},
#{addTime},
#{updateTime},
#{author},
#{alarmEmail},
#{executorRouteStrategy},
#{executorHandler},
#{executorParam},
#{executorBlockStrategy},
#{executorTimeout},
#{executorFailRetryCount},
#{glueType},
#{glueSource},
#{glueRemark},
#{glueUpdatetime},
#{childJobId},
#{triggerLastTime},
#{triggerNextTime},
#{jobJson},
#{replaceParam},
#{jvmParam},
#{incStartTime}
);
<!--<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="JobTemplate">
SELECT <include refid="Base_Column_List" />
FROM job_template AS t
WHERE t.id = #{id}
</select>
<update id="update" parameterType="com.wugui.datax.admin.entity.JobTemplate" >
UPDATE job_template
SET
job_group = #{jobGroup},
job_cron = #{jobCron},
job_desc = #{jobDesc},
update_time = #{updateTime},
author = #{author},
alarm_email = #{alarmEmail},
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_last_time = #{triggerLastTime},
trigger_next_time = #{triggerNextTime},
job_json=#{jobJson},
replace_param=#{replaceParam},
jvm_param=#{jvmParam},
inc_start_time=#{incStartTime}
WHERE id = #{id}
</update>
<delete id="delete" parameterType="java.util.HashMap">
DELETE
FROM job_template
WHERE id = #{id}
</delete>
</mapper>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.log-container[data-v-1e37135b]{margin-bottom:20px;background:#f5f5f5;width:100%;height:500px;overflow:scroll}.log-container pre[data-v-1e37135b]{display:block;padding:10px;margin:0 0 10.5px;word-break:break-all;word-wrap:break-word;color:#334851;background-color:#f5f5f5;border-radius:1px}

View File

@ -1 +1 @@
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.pagination-container[data-v-f3b72548]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-f3b72548]{display:none}
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}

View File

@ -1 +1 @@
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.pagination-container[data-v-f3b72548]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-f3b72548]{display:none}
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}

View File

@ -1 +1 @@
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.pagination-container[data-v-f3b72548]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-f3b72548]{display:none}
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.el-dropdown+.el-dropdown{margin-left:15px}

View File

@ -1 +0,0 @@
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.pagination-container[data-v-f3b72548]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-f3b72548]{display:none}.log-container[data-v-1e37135b]{margin-bottom:20px;background:#f5f5f5;width:100%;height:500px;overflow:scroll}.log-container pre[data-v-1e37135b]{display:block;padding:10px;margin:0 0 10.5px;word-break:break-all;word-wrap:break-word;color:#334851;background-color:#f5f5f5;border-radius:1px}

View File

@ -1 +1 @@
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.pagination-container[data-v-f3b72548]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-f3b72548]{display:none}
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}

View File

@ -0,0 +1 @@
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.el-dropdown+.el-dropdown{margin-left:15px}

View File

@ -1 +0,0 @@
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.pagination-container[data-v-f3b72548]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-f3b72548]{display:none}.json-editor[data-v-fad11014]{height:100%;position:relative}.json-editor[data-v-fad11014] .CodeMirror{height:auto;min-height:300px}.json-editor[data-v-fad11014] .CodeMirror-scroll{min-height:300px}.json-editor[data-v-fad11014] .cm-s-rubyblue span.cm-string{color:#f08047}.el-dropdown+.el-dropdown{margin-left:15px}

View File

@ -0,0 +1 @@
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}

View File

@ -0,0 +1 @@
.pagination-container[data-v-f3b72548]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-f3b72548]{display:none}.json-editor[data-v-fad11014]{height:100%;position:relative}.json-editor[data-v-fad11014] .CodeMirror{height:auto;min-height:300px}.json-editor[data-v-fad11014] .CodeMirror-scroll{min-height:300px}.json-editor[data-v-fad11014] .cm-s-rubyblue span.cm-string{color:#f08047}

View File

@ -1 +0,0 @@
.json-editor[data-v-fad11014]{height:100%;position:relative}.json-editor[data-v-fad11014] .CodeMirror{height:auto;min-height:300px}.json-editor[data-v-fad11014] .CodeMirror-scroll{min-height:300px}.json-editor[data-v-fad11014] .cm-s-rubyblue span.cm-string{color:#f08047}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-73865ec4"],{"24e2":function(t,a,i){"use strict";i.r(a);var e=function(){var t=this,a=t.$createElement,i=t._self._c||a;return i("div",{staticClass:"errPage-container"},[i("el-button",{staticClass:"pan-back-btn",attrs:{icon:"arrow-left"},on:{click:t.back}},[t._v("\n 返回\n ")]),t._v(" "),i("el-row",[i("el-col",{attrs:{span:12}},[i("h1",{staticClass:"text-jumbo text-ginormous"},[t._v("\n Oops!\n ")]),t._v("\n gif来源"),i("a",{attrs:{href:"https://zh.airbnb.com/",target:"_blank"}},[t._v("airbnb")]),t._v(" 页面\n "),i("h2",[t._v("你没有权限去该页面")]),t._v(" "),i("h6",[t._v("如有不满请联系你领导")]),t._v(" "),i("ul",{staticClass:"list-unstyled"},[i("li",[t._v("或者你可以去:")]),t._v(" "),i("li",{staticClass:"link-type"},[i("router-link",{attrs:{to:"/dashboard"}},[t._v("\n 回首页\n ")])],1),t._v(" "),i("li",{staticClass:"link-type"},[i("a",{attrs:{href:"https://www.taobao.com/"}},[t._v("随便看看")])]),t._v(" "),i("li",[i("a",{attrs:{href:"#"},on:{click:function(a){a.preventDefault(),t.dialogVisible=!0}}},[t._v("点我看图")])])])]),t._v(" "),i("el-col",{attrs:{span:12}},[i("img",{attrs:{src:t.errGif,width:"313",height:"428",alt:"Girl has dropped her ice cream."}})])],1),t._v(" "),i("el-dialog",{attrs:{visible:t.dialogVisible,title:"随便看"},on:{"update:visible":function(a){t.dialogVisible=a}}},[i("img",{staticClass:"pan-img",attrs:{src:t.ewizardClap}})])],1)},s=[],n=i("cc6c"),r=i.n(n),c={name:"Page401",data:function(){return{errGif:r.a+"?"+ +new Date,ewizardClap:"https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646",dialogVisible:!1}},methods:{back:function(){this.$route.query.noGoBack?this.$router.push({path:"/dashboard"}):this.$router.go(-1)}}},l=c,o=(i("efaf"),i("2877")),u=Object(o["a"])(l,e,s,!1,null,"2c77c6fb",null);a["default"]=u.exports},5757:function(t,a,i){},cc6c:function(t,a,i){t.exports=i.p+"static/img/401.089007e7.gif"},efaf:function(t,a,i){"use strict";var e=i("5757"),s=i.n(e);s.a}}]);
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-46fcab30"],{"24e2":function(t,a,i){"use strict";i.r(a);var e=function(){var t=this,a=t.$createElement,i=t._self._c||a;return i("div",{staticClass:"errPage-container"},[i("el-button",{staticClass:"pan-back-btn",attrs:{icon:"arrow-left"},on:{click:t.back}},[t._v("\n 返回\n ")]),t._v(" "),i("el-row",[i("el-col",{attrs:{span:12}},[i("h1",{staticClass:"text-jumbo text-ginormous"},[t._v("\n Oops!\n ")]),t._v("\n gif来源"),i("a",{attrs:{href:"https://zh.airbnb.com/",target:"_blank"}},[t._v("airbnb")]),t._v(" 页面\n "),i("h2",[t._v("你没有权限去该页面")]),t._v(" "),i("h6",[t._v("如有不满请联系你领导")]),t._v(" "),i("ul",{staticClass:"list-unstyled"},[i("li",[t._v("或者你可以去:")]),t._v(" "),i("li",{staticClass:"link-type"},[i("router-link",{attrs:{to:"/dashboard"}},[t._v("\n 回首页\n ")])],1),t._v(" "),i("li",{staticClass:"link-type"},[i("a",{attrs:{href:"https://www.taobao.com/"}},[t._v("随便看看")])]),t._v(" "),i("li",[i("a",{attrs:{href:"#"},on:{click:function(a){a.preventDefault(),t.dialogVisible=!0}}},[t._v("点我看图")])])])]),t._v(" "),i("el-col",{attrs:{span:12}},[i("img",{attrs:{src:t.errGif,width:"313",height:"428",alt:"Girl has dropped her ice cream."}})])],1),t._v(" "),i("el-dialog",{attrs:{visible:t.dialogVisible,title:"随便看"},on:{"update:visible":function(a){t.dialogVisible=a}}},[i("img",{staticClass:"pan-img",attrs:{src:t.ewizardClap}})])],1)},s=[],n=i("cc6c"),r=i.n(n),c={name:"Page401",data:function(){return{errGif:r.a+"?"+ +new Date,ewizardClap:"https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646",dialogVisible:!1}},methods:{back:function(){this.$route.query.noGoBack?this.$router.push({path:"/dashboard"}):this.$router.go(-1)}}},l=c,o=(i("efaf"),i("2877")),u=Object(o["a"])(l,e,s,!1,null,"2c77c6fb",null);a["default"]=u.exports},5757:function(t,a,i){},cc6c:function(t,a,i){t.exports=i.p+"static/img/401.089007e7.gif"},efaf:function(t,a,i){"use strict";var e=i("5757"),s=i.n(e);s.a}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-64238bd4"],{"00e3":function(t,s,a){},"1bc5":function(t,s,a){"use strict";var e=a("00e3"),c=a.n(e);c.a},"1db4":function(t,s,a){"use strict";a.r(s);var e=function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"wscn-http404-container"},[a("div",{staticClass:"wscn-http404"},[t._m(0),t._v(" "),a("div",{staticClass:"bullshit"},[a("div",{staticClass:"bullshit__oops"},[t._v("OOPS!")]),t._v(" "),t._m(1),t._v(" "),a("div",{staticClass:"bullshit__headline"},[t._v(t._s(t.message))]),t._v(" "),a("div",{staticClass:"bullshit__info"},[t._v("Please check that the URL you entered is correct, or click the button below to return to the homepage.")]),t._v(" "),a("a",{staticClass:"bullshit__return-home",attrs:{href:""}},[t._v("Back to home")])])])])},c=[function(){var t=this,s=t.$createElement,e=t._self._c||s;return e("div",{staticClass:"pic-404"},[e("img",{staticClass:"pic-404__parent",attrs:{src:a("a36b"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child left",attrs:{src:a("26fc"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child mid",attrs:{src:a("26fc"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child right",attrs:{src:a("26fc"),alt:"404"}})])},function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"bullshit__info"},[t._v("All rights reserved\n "),a("a",{staticStyle:{color:"#20a0ff"},attrs:{href:"https://wallstreetcn.com",target:"_blank"}},[t._v("wallstreetcn")])])}],i={name:"Page404",computed:{message:function(){return"The webmaster said that you can not enter this page..."}}},l=i,n=(a("1bc5"),a("2877")),r=Object(n["a"])(l,e,c,!1,null,"22c31b5a",null);s["default"]=r.exports},"26fc":function(t,s,a){t.exports=a.p+"static/img/404_cloud.0f4bc32b.png"},a36b:function(t,s,a){t.exports=a.p+"static/img/404.a57b6f31.png"}}]);
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-5bfc3adc"],{"00e3":function(t,s,a){},"1bc5":function(t,s,a){"use strict";var c=a("00e3"),e=a.n(c);e.a},"1db4":function(t,s,a){"use strict";a.r(s);var c=function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"wscn-http404-container"},[a("div",{staticClass:"wscn-http404"},[t._m(0),t._v(" "),a("div",{staticClass:"bullshit"},[a("div",{staticClass:"bullshit__oops"},[t._v("OOPS!")]),t._v(" "),t._m(1),t._v(" "),a("div",{staticClass:"bullshit__headline"},[t._v(t._s(t.message))]),t._v(" "),a("div",{staticClass:"bullshit__info"},[t._v("Please check that the URL you entered is correct, or click the button below to return to the homepage.")]),t._v(" "),a("a",{staticClass:"bullshit__return-home",attrs:{href:""}},[t._v("Back to home")])])])])},e=[function(){var t=this,s=t.$createElement,c=t._self._c||s;return c("div",{staticClass:"pic-404"},[c("img",{staticClass:"pic-404__parent",attrs:{src:a("a36b"),alt:"404"}}),t._v(" "),c("img",{staticClass:"pic-404__child left",attrs:{src:a("26fc"),alt:"404"}}),t._v(" "),c("img",{staticClass:"pic-404__child mid",attrs:{src:a("26fc"),alt:"404"}}),t._v(" "),c("img",{staticClass:"pic-404__child right",attrs:{src:a("26fc"),alt:"404"}})])},function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"bullshit__info"},[t._v("All rights reserved\n "),a("a",{staticStyle:{color:"#20a0ff"},attrs:{href:"https://wallstreetcn.com",target:"_blank"}},[t._v("wallstreetcn")])])}],i={name:"Page404",computed:{message:function(){return"The webmaster said that you can not enter this page..."}}},l=i,n=(a("1bc5"),a("2877")),r=Object(n["a"])(l,c,e,!1,null,"22c31b5a",null);s["default"]=r.exports},"26fc":function(t,s,a){t.exports=a.p+"static/img/404_cloud.0f4bc32b.png"},a36b:function(t,s,a){t.exports=a.p+"static/img/404.a57b6f31.png"}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-commons"],{"1c64":function(e,t,n){},"1cc6":function(e,t,n){"use strict";var a=n("1c64"),i=n.n(a);i.a},"333d":function(e,t,n){"use strict";var a=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"pagination-container",class:{hidden:e.hidden}},[n("el-pagination",e._b({attrs:{background:e.background,"current-page":e.currentPage,"page-size":e.pageSize,layout:e.layout,"page-sizes":e.pageSizes,total:e.total},on:{"update:currentPage":function(t){e.currentPage=t},"update:current-page":function(t){e.currentPage=t},"update:pageSize":function(t){e.pageSize=t},"update:page-size":function(t){e.pageSize=t},"size-change":e.handleSizeChange,"current-change":e.handleCurrentChange}},"el-pagination",e.$attrs,!1))],1)},i=[],r=(n("c5f6"),n("09f4")),u={name:"Pagination",props:{total:{required:!0,type:Number},page:{type:Number,default:1},limit:{type:Number,default:20},pageSizes:{type:Array,default:function(){return[10,20,30,50]}},layout:{type:String,default:"total, sizes, prev, pager, next, jumper"},background:{type:Boolean,default:!0},autoScroll:{type:Boolean,default:!0},hidden:{type:Boolean,default:!1}},computed:{currentPage:{get:function(){return this.page},set:function(e){this.$emit("update:page",e)}},pageSize:{get:function(){return this.limit},set:function(e){this.$emit("update:limit",e)}}},methods:{handleSizeChange:function(e){this.$emit("pagination",{page:this.currentPage,limit:e}),this.autoScroll&&Object(r["a"])(0,800)},handleCurrentChange:function(e){this.$emit("pagination",{page:e,limit:this.pageSize}),this.autoScroll&&Object(r["a"])(0,800)}}},o=u,s=(n("1cc6"),n("2877")),c=Object(s["a"])(o,a,i,!1,null,"f3b72548",null);t["a"]=c.exports},b8b0:function(e,t,n){"use strict";var a=n("f84c"),i=n.n(a);i.a},f84c:function(e,t,n){},fa7e:function(e,t,n){"use strict";var a=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"json-editor"},[n("textarea",{ref:"textarea"})])},i=[],r=n("56b3"),u=n.n(r);n("0dd0"),n("a7be"),n("acdf"),n("f9d4"),n("8822"),n("d2de");n("ae67");var o={name:"JsonEditor",props:["value"],data:function(){return{jsonEditor:!1}},watch:{value:function(e){var t=this.jsonEditor.getValue();e!==t&&this.jsonEditor.setValue(JSON.stringify(this.value,null,2))}},mounted:function(){var e=this;this.jsonEditor=u.a.fromTextArea(this.$refs.textarea,{lineNumbers:!0,mode:"application/json",gutters:["CodeMirror-lint-markers"],theme:"rubyblue",lint:!0}),this.jsonEditor.setValue(JSON.stringify(this.value,null,2)),this.jsonEditor.on("change",(function(t){e.$emit("changed",t.getValue()),e.$emit("input",t.getValue())}))},methods:{getValue:function(){return this.jsonEditor.getValue()}}},s=o,c=(n("b8b0"),n("2877")),l=Object(c["a"])(s,a,i,!1,null,"fad11014",null);t["a"]=l.exports}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -28,14 +28,6 @@
<version>${groovy.version}</version>
</dependency>
<!-- commons-exec -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
<version>${commons-exec.version}</version>
</dependency>
<!-- spring-context -->
<dependency>
<groupId>org.springframework</groupId>

View File

@ -1,12 +1,14 @@
package com.wugui.datatx.core.util;
import com.wugui.datatx.core.log.JobLogger;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
/**
* 1内嵌编译器如"PythonInterpreter"无法引用扩展包因此推荐使用java调用控制台进程方式"Runtime.getRuntime().exec()"来运行脚本(shell或python)
@ -42,12 +44,7 @@ public class ScriptUtil {
}
/**
* 日志文件输出方式
*
* 优点支持将目标数据实时输出到指定日志文件中去
* 缺点
* 标准输出和错误输出优先级固定可能和脚本中顺序不一致
* Java无法实时获取
* 脚本执行日志文件实时输出
*
* @param command
* @param scriptFile
@ -57,6 +54,141 @@ public class ScriptUtil {
* @throws IOException
*/
public static int execToFile(String command, String scriptFile, String logFile, String... params) throws IOException {
FileOutputStream fileOutputStream = null;
Thread inputThread = null;
Thread errThread = null;
try {
// file
fileOutputStream = new FileOutputStream(logFile, true);
// command
List<String> cmdarray = new ArrayList<>();
cmdarray.add(command);
cmdarray.add(scriptFile);
if (params!=null && params.length>0) {
for (String param:params) {
cmdarray.add(param);
}
}
String[] cmdarrayFinal = cmdarray.toArray(new String[cmdarray.size()]);
// process-exec
final Process process = Runtime.getRuntime().exec(cmdarrayFinal);
// log-thread
final FileOutputStream finalFileOutputStream = fileOutputStream;
inputThread = new Thread(new Runnable() {
@Override
public void run() {
try {
copy(process.getInputStream(), finalFileOutputStream, new byte[1024]);
} catch (IOException e) {
JobLogger.log(e);
}
}
});
errThread = new Thread(new Runnable() {
@Override
public void run() {
try {
copy(process.getErrorStream(), finalFileOutputStream, new byte[1024]);
} catch (IOException e) {
JobLogger.log(e);
}
}
});
inputThread.start();
errThread.start();
// process-wait
int exitValue = process.waitFor(); // exit code: 0=success, 1=error
// log-thread join
inputThread.join();
errThread.join();
return exitValue;
} catch (Exception e) {
JobLogger.log(e);
return -1;
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
JobLogger.log(e);
}
}
if (inputThread != null && inputThread.isAlive()) {
inputThread.interrupt();
}
if (errThread != null && errThread.isAlive()) {
errThread.interrupt();
}
}
}
/**
* 数据流CopyInput自动关闭Output不处理
*
* @param inputStream
* @param outputStream
* @param buffer
* @return
* @throws IOException
*/
private static long copy(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws IOException {
try {
long total = 0;
for (;;) {
int res = inputStream.read(buffer);
if (res == -1) {
break;
}
if (res > 0) {
total += res;
if (outputStream != null) {
outputStream.write(buffer, 0, res);
}
}
}
outputStream.flush();
//out = null;
inputStream.close();
inputStream = null;
return total;
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
/**
* 脚本执行日志文件实时输出
*
* 优点支持将目标数据实时输出到指定日志文件中去
* 缺点
* 标准输出和错误输出优先级固定可能和脚本中顺序不一致
* Java无法实时获取
*
* <!-- commons-exec -->
* <dependency>
* <groupId>org.apache.commons</groupId>
* <artifactId>commons-exec</artifactId>
* <version>${commons-exec.version}</version>
* </dependency>
*
* @param command
* @param scriptFile
* @param logFile
* @param params
* @return
* @throws IOException
*/
/*public static int execToFileB(String command, String scriptFile, String logFile, String... params) throws IOException {
// 标准输出print null if watchdog timeout
// 错误输出logging + 异常 still exists if watchdog timeout
// 标准输入
@ -92,6 +224,7 @@ public class ScriptUtil {
}
}
}
}*/
}

View File

@ -252,3 +252,35 @@ ALTER TABLE `datax_web`.`job_info` DROP COLUMN `time_offset`;
ALTER TABLE `datax_web`.`job_info`
ADD COLUMN `inc_start_time` DATETIME NULL DEFAULT NULL COMMENT '增量初始时间' AFTER `jvm_param`;
-- ----------------------------
-- Table structure for job_template
-- ----------------------------
DROP TABLE IF EXISTS `job_template`;
CREATE TABLE `job_template` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_group` int(11) NOT NULL COMMENT '执行器主键ID',
`job_cron` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务执行CRON',
`job_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`add_time` datetime(0) NULL DEFAULT NULL,
`update_time` datetime(0) NULL DEFAULT NULL,
`author` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '作者',
`alarm_email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '报警邮件',
`executor_route_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器路由策略',
`executor_handler` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器任务handler',
`executor_param` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器参数',
`executor_block_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '阻塞处理策略',
`executor_timeout` int(11) NOT NULL DEFAULT 0 COMMENT '任务执行超时时间,单位秒',
`executor_fail_retry_count` int(11) NOT NULL DEFAULT 0 COMMENT '失败重试次数',
`glue_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'GLUE类型',
`glue_source` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT 'GLUE源代码',
`glue_remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'GLUE备注',
`glue_updatetime` datetime(0) NULL DEFAULT NULL COMMENT 'GLUE更新时间',
`child_jobid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '子任务ID多个逗号分隔',
`trigger_last_time` bigint(13) NOT NULL DEFAULT 0 COMMENT '上次调度时间',
`trigger_next_time` bigint(13) NOT NULL DEFAULT 0 COMMENT '下次调度时间',
`job_json` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT 'datax运行脚本',
`replace_param` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '动态参数',
`jvm_param` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'jvm参数',
`inc_start_time` datetime(0) NULL DEFAULT NULL COMMENT '增量初始时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

View File

@ -40,7 +40,6 @@
<druid.version>1.1.14</druid.version>
<mysql-connector.version>5.1.47</mysql-connector.version>
<jna.version>4.1.0</jna.version>
<commons-exec.version>1.3</commons-exec.version>
<groovy.version>2.5.8</groovy.version>
<mybatisplus.version>3.0.7.1</mybatisplus.version>