This commit is contained in:
bo.yang 2021-07-23 09:42:00 +08:00
commit 671f3d4b73
48 changed files with 6420 additions and 2 deletions

153
bps-kettle/pom.xml Normal file
View File

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.6.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bps-kettle</artifactId>
<properties>
<kettle-version>9.0.0.0-423</kettle-version>
<janino-version>2.5.16</janino-version>
<javascript-version>1.7.2</javascript-version>
<jxl-version>2.6.12</jxl-version>
</properties>
<dependencies>
<!-- 通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-system</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<!--丝袜哥-->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
<scope>compile</scope>
</dependency>
<!-- kettle核心依赖 -->
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-core</artifactId>
<version>${kettle-version}</version>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-engine</artifactId>
<version>${kettle-version}</version>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-dbdialog</artifactId>
<version>${kettle-version}</version>
</dependency>
<dependency>
<groupId>org.pentaho.di.plugins</groupId>
<artifactId>kettle-sap-plugin-core</artifactId>
<version>${kettle-version}</version>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-ui-swt</artifactId>
<version>${kettle-version}</version>
</dependency>
<!--kettle执行复杂脚本需要此包如执行js组件-->
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>${janino-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.birt.runtime.3_7_1</groupId>
<artifactId>org.mozilla.javascript</artifactId>
<version>${javascript-version}</version>
</dependency>
<!-- kettle plugin excel-->
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>${jxl-version}</version>
</dependency>
<!-- 降低MySQL版本kettle中连接mysql资源库使用的是低版本驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- org.gjt.mm.mysql.Driver -->
<dependency>
<groupId>mm.mysql</groupId>
<artifactId>mm.mysql</artifactId>
<version>2.0.7</version>
</dependency>
<!-- sqlserver(native)连接方式驱动-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
</dependency>
<!-- sqlser连接驱动-->
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<repositories>
<repository>
<id>pentaho</id>
<url>https://nexus.pentaho.org/content/groups/omni/</url>
</repository>
</repositories>
<!-- <properties>-->
<!-- <maven.compiler.source>8</maven.compiler.source>-->
<!-- <maven.compiler.target>8</maven.compiler.target>-->
<!-- </properties>-->
</project>

View File

@ -0,0 +1,43 @@
package com.ruoyi.kettle.cons;
public enum XJobStatus {
UNKNOWN("-1", "未知状态"),
PENDING("10", "等待中"),
RUNNING("20", "运行中"),
HALTING("21", "终止中"),
STOPPED("30", "已中断"),
FINISHED("40", "已完成"),
SUCCESS("88", "运行成功"),
FAILED("99", "异常停止");
private String status;
private String description;
private XJobStatus(String status, String description) {
this.status = status;
this.description = description;
}
public String value() {
return this.status;
}
public String description() {
return this.description;
}
public static XJobStatus forName(Integer value) {
XJobStatus[] statuses = values();
XJobStatus[] var2 = statuses;
int var3 = statuses.length;
for(int var4 = 0; var4 < var3; ++var4) {
XJobStatus status = var2[var4];
if (status.value().equals(value)) {
return status;
}
}
return UNKNOWN;
}
}

View File

@ -0,0 +1,46 @@
package com.ruoyi.kettle.cons;
public enum XTransStatus {
UNKNOWN("-1", "未知状态"),
WAITING("10", "等待中"),
INITIALIZING("20", "转换初始化"),
PREPARING("21", "转换准备执行"),
STOPPED("30", "已终止"),
FINISHED("40", "已结束"),
RUNNING("50", "转换运行中"),
PAUSED("60", "转换已被暂停"),
HALTING("70", "转换被挂起"),
SUCCESS("88", "转换运行成功"),
FAILED("99", "异常停止");
private String status;
private String description;
private XTransStatus(String status, String description) {
this.status = status;
this.description = description;
}
public String value() {
return this.status;
}
public String description() {
return this.description;
}
public static XTransStatus forName(Integer value) {
XTransStatus[] statuses = values();
XTransStatus[] var2 = statuses;
int var3 = statuses.length;
for(int var4 = 0; var4 < var3; ++var4) {
XTransStatus status = var2[var4];
if (status.value().equals(value)) {
return status;
}
}
return UNKNOWN;
}
}

View File

@ -0,0 +1,186 @@
package com.ruoyi.kettle.controller;
import java.util.List;
import java.util.stream.Collectors;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.kettle.domain.KettleTrans;
import com.ruoyi.quartz.service.ISysJobService;
import com.ruoyi.system.service.ISysRoleService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.kettle.domain.KettleJob;
import com.ruoyi.kettle.service.IKettleJobService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 作业调度Controller
*
* @author kone
* @date 2021-07-22
*/
@Controller
@RequestMapping("/kettle/job")
public class KettleJobController extends BaseController
{
private String prefix = "kettle/job";
@Autowired
private IKettleJobService kettleJobService;
@Autowired
private ISysRoleService roleService;
@Autowired
private ISysJobService jobService;
@RequiresPermissions("kettle:job:view")
@GetMapping()
public String job()
{
return prefix + "/job";
}
/**
* 查询作业调度列表
*/
@RequiresPermissions("kettle:job:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(KettleJob kettleJob)
{
startPage();
List<KettleJob> list = kettleJobService.selectKettleJobList(kettleJob);
return getDataTable(list);
}
/**
* 导出作业调度列表
*/
@RequiresPermissions("kettle:job:export")
@Log(title = "作业调度", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(KettleJob kettleJob)
{
List<KettleJob> list = kettleJobService.selectKettleJobList(kettleJob);
ExcelUtil<KettleJob> util = new ExcelUtil<KettleJob>(KettleJob.class);
return util.exportExcel(list, "作业调度数据");
}
/**
* 新增作业调度
*/
@GetMapping("/add")
public String add(ModelMap mmap)
{
List<String> roleKeys=roleService.selectRoleAll().stream().map(SysRole::getRoleKey).collect(Collectors.toList());
mmap.put("allRoles",roleKeys);
return prefix + "/add";
}
/**
* 新增保存作业调度
*/
@RequiresPermissions("kettle:job:add")
@Log(title = "作业调度", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(KettleJob kettleJob)
{
return kettleJobService.insertKettleJob(kettleJob);
}
/**
* 修改作业调度
*/
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
KettleJob kettleJob = kettleJobService.selectKettleJobById(id);
List<String> roleKeys=roleService.selectRoleAll().stream().map(SysRole::getRoleKey).collect(Collectors.toList());
String rks="";
if(kettleJob!=null && kettleJob.getRoleKey()!=null){
rks=kettleJob.getRoleKey();
}
String[] rkArray=rks.split(",");
mmap.put("allRoles",roleKeys);
mmap.put("rkArray",rkArray);
mmap.put("kettleJob", kettleJob);
return prefix + "/edit";
}
/**
* 修改保存作业调度
*/
@RequiresPermissions("kettle:job:edit")
@Log(title = "作业调度", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(KettleJob kettleJob)
{
return toAjax(kettleJobService.updateKettleJob(kettleJob));
}
/**
* 删除作业调度
*/
@RequiresPermissions("kettle:job:remove")
@Log(title = "作业调度", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(kettleJobService.deleteKettleJobByIds(ids));
}
@Log(title = "立即执行作业", businessType = BusinessType.UPDATE)
@RequiresPermissions("kettle:job:run")
@PostMapping("/run")
@ResponseBody
public AjaxResult run(KettleJob job)
{
AjaxResult result = kettleJobService.run(job);
return result;
}
@RequiresPermissions("kettle:job:log")
@GetMapping("/detail/{id}")
public String detail(@PathVariable("id") Long id, ModelMap mmap)
{
KettleJob kettleJob = kettleJobService.selectKettleJobById(id);
List<String> jobLog= kettleJobService.queryJobLog(kettleJob);
mmap.put("kettleJob", kettleJob);
mmap.put("jobLog",jobLog);
return prefix + "/detail";
}
/**
* 跳转到新增调度定时任务页面
*/
@RequiresPermissions("kettle:job:setquartz")
@GetMapping("/jobQuartz/{id}")
public String jobQuartz(@PathVariable("id") Long id,ModelMap mmap)
{
KettleJob kettleJob = kettleJobService.selectKettleJobById(id);
//kettleTransServiceImpl.runTransQuartz('12','text')
String checkStr="kettleJobServiceImpl.runJobQuartz('"+kettleJob.getId()+"','"+kettleJob.getJobName()+"')";
Long jobId = kettleJobService.checkQuartzExist(checkStr);
if(jobId != null){
mmap.put("job", jobService.selectJobById(Long.valueOf(jobId)));
return "kettle/quartz/editquartz";
}else{
mmap.put("invokeTarget", checkStr);
//mmap.put("job", kettleJob);
return "kettle/quartz/addquartz";
}
}
}

View File

@ -0,0 +1,196 @@
package com.ruoyi.kettle.controller;
import java.util.List;
import java.util.stream.Collectors;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.quartz.service.ISysJobService;
import com.ruoyi.system.service.ISysRoleService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.kettle.domain.KettleTrans;
import com.ruoyi.kettle.service.IKettleTransService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 转换Controller
*
* @author kone
* @date 2021-07-14
*/
@Controller
@RequestMapping("/kettle/trans")
public class KettleTransController extends BaseController
{
private String prefix = "kettle/trans";
@Autowired
private IKettleTransService kettleTransService;
@Autowired
private ISysRoleService roleService;
@Autowired
private ISysJobService jobService;
@RequiresPermissions("kettle:trans:view")
@GetMapping()
public String trans()
{
return prefix + "/trans";
}
/**
* 查询转换列表
*/
@RequiresPermissions("kettle:trans:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(KettleTrans kettleTrans)
{
startPage();
List<KettleTrans> list = kettleTransService.selectKettleTransList(kettleTrans);
return getDataTable(list);
}
/**
* 导出转换列表
*/
@RequiresPermissions("kettle:trans:export")
@Log(title = "转换", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(KettleTrans kettleTrans)
{
List<KettleTrans> list = kettleTransService.selectKettleTransList(kettleTrans);
ExcelUtil<KettleTrans> util = new ExcelUtil<KettleTrans>(KettleTrans.class);
return util.exportExcel(list, "转换数据");
}
/**
* 新增转换
*/
@GetMapping("/add")
public String add(ModelMap mmap)
{
List<String> roleKeys=roleService.selectRoleAll().stream().map(SysRole::getRoleKey).collect(Collectors.toList());
mmap.put("allRoles",roleKeys);
return prefix + "/add";
}
/**
* 新增保存转换
*/
@RequiresPermissions("kettle:trans:add")
@Log(title = "转换", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(KettleTrans kettleTrans)
{
return kettleTransService.insertKettleTrans(kettleTrans) ;
}
/**
* 修改转换
*/
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
KettleTrans kettleTrans = kettleTransService.selectKettleTransById(id);
List<String> roleKeys=roleService.selectRoleAll().stream().map(SysRole::getRoleKey).collect(Collectors.toList());
String rks="";
if(kettleTrans!=null && kettleTrans.getRoleKey()!=null){
rks=kettleTrans.getRoleKey();
}
String[] rkArray=rks.split(",");
mmap.put("allRoles",roleKeys);
mmap.put("kettleTrans", kettleTrans);
mmap.put("rkArray",rkArray);
return prefix + "/edit";
}
/**
* 修改保存转换
*/
@RequiresPermissions("kettle:trans:edit")
@Log(title = "转换", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(KettleTrans kettleTrans)
{
return toAjax(kettleTransService.updateKettleTrans(kettleTrans));
}
/**
* 删除转换
*/
@RequiresPermissions("kettle:trans:remove")
@Log(title = "转换", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(kettleTransService.deleteKettleTransByIds(ids));
}
/**
* 转换执行得日志
*/
@RequiresPermissions("kettle:trans:log")
@GetMapping("/detail/{id}")
public String detail(@PathVariable("id") Long id, ModelMap mmap)
{
KettleTrans kettleTrans = kettleTransService.selectKettleTransById(id);
List<String> transLog= kettleTransService.queryTransLog(kettleTrans);
mmap.put("kettleTrans", kettleTrans);
mmap.put("transLog",transLog);
return prefix + "/detail";
}
/**
* 转换立即执行一次
*/
@Log(title = "立即执行转换", businessType = BusinessType.UPDATE)
@RequiresPermissions("kettle:trans:run")
@PostMapping("/run")
@ResponseBody
public AjaxResult run(KettleTrans trans)
{
AjaxResult result = kettleTransService.run(trans);
return result;
}
/**
* 跳转到新增调度定时任务页面
*/
@RequiresPermissions("kettle:trans:setquartz")
@GetMapping("/transQuartz/{id}")
public String transQuartz(@PathVariable("id") Long id,ModelMap mmap)
{
KettleTrans trans = kettleTransService.selectKettleTransById(id);
//kettleTransServiceImpl.runTransQuartz('12','text')
String checkStr="kettleTransServiceImpl.runTransQuartz('"+trans.getId()+"','"+trans.getTransName()+"')";
Long jobId = kettleTransService.checkQuartzExist(checkStr);
if(jobId != null){
mmap.put("job", jobService.selectJobById(Long.valueOf(jobId)));
return "kettle/quartz/editquartz";
}else{
mmap.put("invokeTarget", checkStr);
//mmap.put("trans", trans);
return "kettle/quartz/addquartz";
}
}
}

View File

@ -0,0 +1,153 @@
package com.ruoyi.kettle.controller;
import java.util.List;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.kettle.repo.RepoTree;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.kettle.domain.XRepository;
import com.ruoyi.kettle.service.IXRepositoryService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 资源库Controller
*
* @author kone
* @date 2021-07-12
*/
@Controller
@RequestMapping("/kettle/repository")
public class XRepositoryController extends BaseController
{
private String prefix = "kettle/repository";
@Autowired
private IXRepositoryService xRepositoryService;
@RequiresPermissions("kettle:repository:view")
@GetMapping()
public String repository()
{
return prefix + "/repository";
}
/**
* 查询资源库列表
*/
@RequiresPermissions("kettle:repository:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(XRepository xRepository)
{
startPage();
List<XRepository> list = xRepositoryService.selectXRepositoryList(xRepository);
return getDataTable(list);
}
@GetMapping(value = { "/selectRepositoryTree", "/selectRepositoryTree/{excludeId}" })
public String selectRepositoryTree( @PathVariable(value = "excludeId", required = false) String excludeId, ModelMap mmap)
{
XRepository r=new XRepository();
List<XRepository> repoTree = xRepositoryService.selectXRepositoryList(r);
XRepository repository=xRepositoryService.selectXRepositoryById(2L);
mmap.put("repository", repository);
mmap.put("repoTree", repoTree);
mmap.put("excludeId", excludeId);
return "kettle/common/repository_tree";
}
@GetMapping("/repositoryRoot")
@ResponseBody
public List<RepoTree> repositoryRoot()
{
List<RepoTree> ztrees = xRepositoryService.selectRepoRoot(new XRepository());
return ztrees;
}
@PostMapping("/qryRepoSubTree/{id}")
@ResponseBody
public List<RepoTree> qryRepoSubTree(@PathVariable("id") Long id, ModelMap mmapy) {
List<RepoTree> ztrees = xRepositoryService.selectRepoTree(id);
return ztrees;
}
/**
* 导出资源库列表
*/
@RequiresPermissions("kettle:repository:export")
@Log(title = "资源库", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(XRepository xRepository)
{
List<XRepository> list = xRepositoryService.selectXRepositoryList(xRepository);
ExcelUtil<XRepository> util = new ExcelUtil<XRepository>(XRepository.class);
return util.exportExcel(list, "资源库数据");
}
/**
* 新增资源库
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存资源库
*/
@RequiresPermissions("kettle:repository:add")
@Log(title = "资源库", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(XRepository xRepository)
{
return toAjax(xRepositoryService.insertXRepository(xRepository));
}
/**
* 修改资源库
*/
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
XRepository xRepository = xRepositoryService.selectXRepositoryById(id);
mmap.put("xRepository", xRepository);
return prefix + "/edit";
}
/**
* 修改保存资源库
*/
@RequiresPermissions("kettle:repository:edit")
@Log(title = "资源库", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(XRepository xRepository)
{
return toAjax(xRepositoryService.updateXRepository(xRepository));
}
/**
* 删除资源库
*/
@RequiresPermissions("kettle:repository:remove")
@Log(title = "资源库", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(xRepositoryService.deleteXRepositoryByIds(ids));
}
}

View File

@ -0,0 +1,224 @@
package com.ruoyi.kettle.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 作业调度对象 kettle_job
*
* @author kone
* @date 2021-07-22
*/
public class KettleJob extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** */
private Long id;
/** */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** */
@Excel(name = "")
private String createdBy;
/** 作业名称 */
@Excel(name = "作业名称")
private String jobName;
/** 描述 */
@Excel(name = "描述")
private String jobDescription;
/** 作业类型(file,ftp,sf) */
@Excel(name = "作业类型(file,ftp,sf)")
private String jobType;
/** 路径 */
@Excel(name = "路径")
private String jobPath;
/** 资源库id */
@Excel(name = "资源库id")
private Long jobRepositoryId;
/** 日志级别 */
@Excel(name = "日志级别")
private String jobLogLevel;
/** 状态 */
@Excel(name = "状态")
private String jobStatus;
/** 是否删除 */
@Excel(name = "是否删除")
private Integer isDel;
/** 是否监控 */
@Excel(name = "是否监控")
private Integer isMonitorEnabled;
/** 可执行角色key,用+号拼接 */
@Excel(name = "可执行角色key,用+号拼接")
private String roleKey;
/** */
@Excel(name = "")
private String tplKey;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setCreatedTime(Date createdTime)
{
this.createdTime = createdTime;
}
public Date getCreatedTime()
{
return createdTime;
}
public void setCreatedBy(String createdBy)
{
this.createdBy = createdBy;
}
public String getCreatedBy()
{
return createdBy;
}
public void setJobName(String jobName)
{
this.jobName = jobName;
}
public String getJobName()
{
return jobName;
}
public void setJobDescription(String jobDescription)
{
this.jobDescription = jobDescription;
}
public String getJobDescription()
{
return jobDescription;
}
public void setJobType(String jobType)
{
this.jobType = jobType;
}
public String getJobType()
{
return jobType;
}
public void setJobPath(String jobPath)
{
this.jobPath = jobPath;
}
public String getJobPath()
{
return jobPath;
}
public void setJobRepositoryId(Long jobRepositoryId)
{
this.jobRepositoryId = jobRepositoryId;
}
public Long getJobRepositoryId()
{
return jobRepositoryId;
}
public void setJobLogLevel(String jobLogLevel)
{
this.jobLogLevel = jobLogLevel;
}
public String getJobLogLevel()
{
return jobLogLevel;
}
public void setJobStatus(String jobStatus)
{
this.jobStatus = jobStatus;
}
public String getJobStatus()
{
return jobStatus;
}
public void setIsDel(Integer isDel)
{
this.isDel = isDel;
}
public Integer getIsDel()
{
return isDel;
}
public void setIsMonitorEnabled(Integer isMonitorEnabled)
{
this.isMonitorEnabled = isMonitorEnabled;
}
public Integer getIsMonitorEnabled()
{
return isMonitorEnabled;
}
public void setRoleKey(String roleKey)
{
this.roleKey = roleKey;
}
public String getRoleKey()
{
return roleKey;
}
public void setTplKey(String tplKey)
{
this.tplKey = tplKey;
}
public String getTplKey()
{
return tplKey;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("createdTime", getCreatedTime())
.append("updateTime", getUpdateTime())
.append("createdBy", getCreatedBy())
.append("updateBy", getUpdateBy())
.append("jobName", getJobName())
.append("jobDescription", getJobDescription())
.append("jobType", getJobType())
.append("jobPath", getJobPath())
.append("jobRepositoryId", getJobRepositoryId())
.append("jobLogLevel", getJobLogLevel())
.append("jobStatus", getJobStatus())
.append("isDel", getIsDel())
.append("isMonitorEnabled", getIsMonitorEnabled())
.append("roleKey", getRoleKey())
.append("tplKey", getTplKey())
.toString();
}
}

View File

@ -0,0 +1,220 @@
package com.ruoyi.kettle.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 转换对象 kettle_trans
*
* @author kone
* @date 2021-07-14
*/
public class KettleTrans extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** */
private Long id;
/** 转换名称 */
@Excel(name = "转换名称")
private String transName;
/** 转换描述 */
@Excel(name = "转换描述")
private String transDescription;
/** */
private Date createdTime;
/** */
private String createdBy;
/** 转换类型(file,ftp,sf) */
private String transType;
/** 路径 */
@Excel(name = "路径")
private String transPath;
/** 所属资源库id */
@Excel(name = "所属资源库id")
private Long transRepositoryId;
/** 日志级别 */
@Excel(name = "日志级别")
private String transLogLevel;
/** 状态 */
@Excel(name = "状态")
private String transStatus;
/** 是否删除 */
@Excel(name = "是否删除")
private Integer isDel;
/** 是否启用 */
@Excel(name = "是否启用")
private Integer isMonitorEnabled;
/** 保留备用 */
private String tplKey;
/** 可执行角色key,用+号拼接 */
@Excel(name = "可执行角色key")
private String roleKey;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setTransName(String transName)
{
this.transName = transName;
}
public String getTransName()
{
return transName;
}
public void setTransDescription(String transDescription)
{
this.transDescription = transDescription;
}
public String getTransDescription()
{
return transDescription;
}
public void setCreatedTime(Date createdTime)
{
this.createdTime = createdTime;
}
public Date getCreatedTime()
{
return createdTime;
}
public void setCreatedBy(String createdBy)
{
this.createdBy = createdBy;
}
public String getCreatedBy()
{
return createdBy;
}
public void setTransType(String transType)
{
this.transType = transType;
}
public String getTransType()
{
return transType;
}
public void setTransPath(String transPath)
{
this.transPath = transPath;
}
public String getTransPath()
{
return transPath;
}
public void setTransRepositoryId(Long transRepositoryId)
{
this.transRepositoryId = transRepositoryId;
}
public Long getTransRepositoryId()
{
return transRepositoryId;
}
public void setTransLogLevel(String transLogLevel)
{
this.transLogLevel = transLogLevel;
}
public String getTransLogLevel()
{
return transLogLevel;
}
public void setTransStatus(String transStatus)
{
this.transStatus = transStatus;
}
public String getTransStatus()
{
return transStatus;
}
public void setIsDel(Integer isDel)
{
this.isDel = isDel;
}
public Integer getIsDel()
{
return isDel;
}
public void setIsMonitorEnabled(Integer isMonitorEnabled)
{
this.isMonitorEnabled = isMonitorEnabled;
}
public Integer getIsMonitorEnabled()
{
return isMonitorEnabled;
}
public void setTplKey(String tplKey)
{
this.tplKey = tplKey;
}
public String getTplKey()
{
return tplKey;
}
public void setRoleKey(String roleKey)
{
this.roleKey = roleKey;
}
public String getRoleKey()
{
return roleKey;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("transName", getTransName())
.append("transDescription", getTransDescription())
.append("createdTime", getCreatedTime())
.append("updateTime", getUpdateTime())
.append("createdBy", getCreatedBy())
.append("updateBy", getUpdateBy())
.append("transType", getTransType())
.append("transPath", getTransPath())
.append("transRepositoryId", getTransRepositoryId())
.append("transLogLevel", getTransLogLevel())
.append("transStatus", getTransStatus())
.append("isDel", getIsDel())
.append("isMonitorEnabled", getIsMonitorEnabled())
.append("tplKey", getTplKey())
.append("roleKey", getRoleKey())
.append("remark", getRemark())
.toString();
}
}

View File

@ -0,0 +1,256 @@
package com.ruoyi.kettle.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 资源库对象 kettle_repository
*
* @author kone
* @date 2021-07-12
*/
public class XRepository extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** */
private Long id;
/** */
@Excel(name = "")
private String repoId;
/** 资源库名称 */
@Excel(name = "资源库名称")
private String repoName;
/** 当资源库类型是db时候的用户名 */
private String repoUsername;
/** 当资源库类型是db时候的密码 */
private String repoPassword;
/** db类型 */
private String repoType;
/** 当资源库类型是db时候的连接类型 */
private String dbAccess;
/** 当资源库类型是db时候的ip */
private String dbHost;
/** 当资源库类型是db时候的端口 */
private String dbPort;
/** 当资源库类型是db时候的db库名 */
private String dbName;
/** 当资源库类型是db时候的db用户名 */
private String dbUsername;
/** 当资源库类型是db时候的db用户密码 */
private String dbPassword;
/** 软删除 */
private int isDel;
/** */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** */
@Excel(name = "")
private String createdBy;
/** 资源库类型 */
@Excel(name = "资源库类型")
private String type;
/** 基础路径 */
@Excel(name = "基础路径")
private String baseDir;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setRepoId(String repoId)
{
this.repoId = repoId;
}
public String getRepoId()
{
return repoId;
}
public void setRepoName(String repoName)
{
this.repoName = repoName;
}
public String getRepoName()
{
return repoName;
}
public void setRepoUsername(String repoUsername)
{
this.repoUsername = repoUsername;
}
public String getRepoUsername()
{
return repoUsername;
}
public void setRepoPassword(String repoPassword)
{
this.repoPassword = repoPassword;
}
public String getRepoPassword()
{
return repoPassword;
}
public void setRepoType(String repoType)
{
this.repoType = repoType;
}
public String getRepoType()
{
return repoType;
}
public void setDbAccess(String dbAccess)
{
this.dbAccess = dbAccess;
}
public String getDbAccess()
{
return dbAccess;
}
public void setDbHost(String dbHost)
{
this.dbHost = dbHost;
}
public String getDbHost()
{
return dbHost;
}
public void setDbPort(String dbPort)
{
this.dbPort = dbPort;
}
public String getDbPort()
{
return dbPort;
}
public void setDbName(String dbName)
{
this.dbName = dbName;
}
public String getDbName()
{
return dbName;
}
public void setDbUsername(String dbUsername)
{
this.dbUsername = dbUsername;
}
public String getDbUsername()
{
return dbUsername;
}
public void setDbPassword(String dbPassword)
{
this.dbPassword = dbPassword;
}
public String getDbPassword()
{
return dbPassword;
}
public void setIsDel(int isDel)
{
this.isDel = isDel;
}
public int getIsDel()
{
return isDel;
}
public void setCreatedTime(Date createdTime)
{
this.createdTime = createdTime;
}
public Date getCreatedTime()
{
return createdTime;
}
public void setCreatedBy(String createdBy)
{
this.createdBy = createdBy;
}
public String getCreatedBy()
{
return createdBy;
}
public void setType(String type)
{
this.type = type;
}
public String getType()
{
return type;
}
public void setBaseDir(String baseDir)
{
this.baseDir = baseDir;
}
public String getBaseDir()
{
return baseDir;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("repoId", getRepoId())
.append("repoName", getRepoName())
.append("repoUsername", getRepoUsername())
.append("repoPassword", getRepoPassword())
.append("repoType", getRepoType())
.append("dbAccess", getDbAccess())
.append("dbHost", getDbHost())
.append("dbPort", getDbPort())
.append("dbName", getDbName())
.append("dbUsername", getDbUsername())
.append("dbPassword", getDbPassword())
.append("isDel", getIsDel())
.append("createdTime", getCreatedTime())
.append("updateTime", getUpdateTime())
.append("createdBy", getCreatedBy())
.append("updateBy", getUpdateBy())
.append("type", getType())
.append("baseDir", getBaseDir())
.toString();
}
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.kettle.mapper;
import java.util.List;
import com.ruoyi.kettle.domain.KettleJob;
import org.apache.ibatis.annotations.Param;
/**
* 作业调度Mapper接口
*
* @author kone
* @date 2021-07-22
*/
public interface KettleJobMapper
{
/**
* 查询作业调度
*
* @param id 作业调度ID
* @return 作业调度
*/
public KettleJob selectKettleJobById(Long id);
/**
* 查询作业调度列表
*
* @param kettleJob 作业调度
* @param roleKeys
* @return 作业调度集合
*/
public List<KettleJob> selectKettleJobList(@Param("kettleJob") KettleJob kettleJob,@Param("roleKey") List<String> roleKeys);
/**
* 新增作业调度
*
* @param kettleJob 作业调度
* @return 结果
*/
public int insertKettleJob(KettleJob kettleJob);
/**
* 修改作业调度
*
* @param kettleJob 作业调度
* @return 结果
*/
public int updateKettleJob(KettleJob kettleJob);
/**
* 删除作业调度
*
* @param id 作业调度ID
* @return 结果
*/
public int deleteKettleJobById(Long id);
/**
* 批量删除作业调度
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteKettleJobByIds(String[] ids);
int selectJobByNameAndRepoId(@Param("jobName")String jobName, @Param("jobRepositoryId")Long jobRepositoryId);
List<String> queryJobLog(String jobName);
Long checkQuartzExist(String checkStr);
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.kettle.mapper;
import java.util.List;
import com.ruoyi.kettle.domain.KettleTrans;
import org.apache.ibatis.annotations.Param;
/**
* 转换Mapper接口
*
* @author kone
* @date 2021-07-14
*/
public interface KettleTransMapper
{
/**
* 查询转换
*
* @param id 转换ID
* @return 转换
*/
public KettleTrans selectKettleTransById(Long id);
/**
* 查询转换列表
*
* @param kettleTrans 转换
* @param roleKey
* @return 转换集合
*/
public List<KettleTrans> selectKettleTransList(@Param("KettleTrans") KettleTrans kettleTrans,@Param("roleKey") List<String> roleKey);
/**
* 新增转换
*
* @param kettleTrans 转换
* @return 结果
*/
public int insertKettleTrans(KettleTrans kettleTrans);
/**
* 修改转换
*
* @param kettleTrans 转换
* @return 结果
*/
public int updateKettleTrans(KettleTrans kettleTrans);
/**
* 删除转换
*
* @param id 转换ID
* @return 结果
*/
public int deleteKettleTransById(Long id);
/**
* 批量删除转换
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteKettleTransByIds(String[] ids);
int selectKettleTransByTransName(String transName);
List<String> queryTransLog(String transName);
Long checkQuartzExist(String checkStr);
}

View File

@ -0,0 +1,77 @@
package com.ruoyi.kettle.mapper;
import java.util.List;
import com.ruoyi.kettle.domain.XRepository;
/**
* 资源库Mapper接口
*
* @author kone
* @date 2021-07-12
*/
public interface XRepositoryMapper
{
/**
* 查询资源库
*
* @param id 资源库ID
* @return 资源库
*/
public XRepository selectXRepositoryById(Long id);
/**
* 查询资源库列表
*
* @param xRepository 资源库
* @return 资源库集合
*/
public List<XRepository> selectXRepositoryList(XRepository xRepository);
/**
* 新增资源库
*
* @param xRepository 资源库
* @return 结果
*/
public int insertXRepository(XRepository xRepository);
/**
* 修改资源库
*
* @param xRepository 资源库
* @return 结果
*/
public int updateXRepository(XRepository xRepository);
/**
* 删除资源库
*
* @param id 资源库ID
* @return 结果
*/
public int deleteXRepositoryById(Long id);
/**
* 批量删除资源库
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteXRepositoryByIds(String[] ids);
/**
* @Description:软删除
* @Author: Kone.wang
* @Date: 14:07
* @param id:
* @return: int
**/
int updateIsDel(Long id);
/**
* @Description:批量软删除
* @Author: Kone.wang
* @Date: 2021/7/19 14:07
* @param ids:
* @return: int
**/
public int updateIsDelBatch(String[] ids);
}

View File

@ -0,0 +1,96 @@
package com.ruoyi.kettle.repo;
public class RepoTree {
private static final long serialVersionUID = 1L;
/** 节点ID */
private String id;
/** 节点父ID */
private String pId;
/** 节点名称 */
private String name;
/** 节点标题 */
private String title;
/** 是否勾选 */
private boolean checked = false;
/** 是否展开 */
private boolean open = false;
/** 是否能勾选 */
private boolean nocheck = false;
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getpId()
{
return pId;
}
public void setpId(String pId)
{
this.pId = pId;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public boolean isChecked()
{
return checked;
}
public void setChecked(boolean checked)
{
this.checked = checked;
}
public boolean isOpen()
{
return open;
}
public void setOpen(boolean open)
{
this.open = open;
}
public boolean isNocheck()
{
return nocheck;
}
public void setNocheck(boolean nocheck)
{
this.nocheck = nocheck;
}
}

View File

@ -0,0 +1,94 @@
package com.ruoyi.kettle.repo;
public class RepositoryTree {
private String id;
private String parent;
private String text;
private String icon;
private Object state;
private String type;
private boolean isLasted;
private String path;
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public String getPath() {
return this.path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isLasted() {
return this.isLasted;
}
public void setLasted(boolean isLasted) {
this.isLasted = isLasted;
}
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getParent() {
return this.parent;
}
public void setParent(String parent) {
this.parent = parent;
}
public String getText() {
return this.text;
}
public void setText(String text) {
this.text = text;
}
public String getIcon() {
return this.icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public Object getState() {
return this.state;
}
public void setState(Object state) {
this.state = state;
}
public RepositoryTree(String id, String parent, String text, String icon, Object state, String type, boolean isLasted, String path) {
this.id = id;
this.parent = parent;
this.text = text;
this.icon = icon;
this.state = state;
this.type = type;
this.isLasted = isLasted;
this.path = path;
}
public RepositoryTree() {
}
public String toString() {
return "RepositoryTree [id=" + this.id + ", parent=" + this.parent + ", text=" + this.text + ", icon=" + this.icon + ", state=" + this.state + ", type=" + this.type + ", isLasted=" + this.isLasted + ", path=" + this.path + "]";
}
}

View File

@ -0,0 +1,262 @@
package com.ruoyi.kettle.repo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.ProgressMonitorListener;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.repository.*;
import org.pentaho.di.repository.filerep.KettleFileRepository;
import org.pentaho.di.repository.filerep.KettleFileRepositoryMeta;
import org.pentaho.di.repository.kdr.KettleDatabaseRepository;
import org.pentaho.di.repository.kdr.KettleDatabaseRepositoryMeta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class XRepoManager {
private static final Logger log = LoggerFactory.getLogger(XRepoManager.class);
public static Map<String, Repository> repositoryCache = new HashMap();
public static Map<String, DatabaseMeta> databaseMeta = new ConcurrentHashMap();
public XRepoManager() {
}
public static String[] getDataBaseAccess() {
String[] dataBaseAccess = DatabaseMeta.dbAccessTypeCode;
return dataBaseAccess;
}
public static DatabaseMeta createDatabaseMeta(String name, String type, String access, String host, String db, String port, String user, String pass, Map params, boolean replace, Repository repository) {
DatabaseMeta dm = null;
if (repository != null) {
try {
ObjectId dbId = repository.getDatabaseID(name);
if (dbId != null && !replace) {
dm = repository.loadDatabaseMeta(dbId, (String)null);
} else if (dbId != null && replace) {
repository.deleteDatabaseMeta(name);
}
} catch (KettleException var15) {
log.error("创建数据库元数据失败", var15);
}
}
if (dm == null) {
dm = new DatabaseMeta(name, type, access, host, db, port, user, pass);
if (params != null) {
Iterator var13 = params.entrySet().iterator();
while(var13.hasNext()) {
Map.Entry<String, Object> ent = (Map.Entry)var13.next();
dm.addExtraOption(type, (String)ent.getKey(), "" + ent.getValue());
}
}
dm.setForcingIdentifiersToLowerCase(true);
if (repository != null) {
try {
repository.save(dm, (String)null, (ProgressMonitorListener)null, true);
} catch (KettleException var14) {
log.error("保存数据库元数据失败", var14);
}
}
}
if (!StringUtils.isEmpty(dm)) {
databaseMeta.put("databaseMeta", dm);
log.info("第一次连接,获取到资源库数据库信息,{}", JSON.toJSON(dm));
}
return dm;
}
private static Repository get(String repoId) {
return (Repository)repositoryCache.get(repoId);
}
public static Repository createRep(BaseRepositoryMeta baseRepositoryMeta, String id) throws KettleException {
if (get(id) != null) {
return get(id);
} else {
Repository repo = null;
if (baseRepositoryMeta instanceof KettleDatabaseRepositoryMeta) {
repo = new KettleDatabaseRepository();
((Repository)repo).init((KettleDatabaseRepositoryMeta)baseRepositoryMeta);
} else {
repo = new KettleFileRepository();
((Repository)repo).init((KettleFileRepositoryMeta)baseRepositoryMeta);
}
repositoryCache.put(id, repo);
log.info(((Repository)repo).getName() + "资源库初始化成功");
return (Repository)repo;
}
}
public static Repository createFileRep(String repoId, String repName, String description, String baseDirectory) throws KettleException {
if (!KettleEnvironment.isInitialized()) {
KettleEnvironment.init();
}
KettleFileRepositoryMeta fileRepMeta = new KettleFileRepositoryMeta(repoId, repName, description, baseDirectory);
return createRep(fileRepMeta, repoId);
}
public static Repository createDBRepByJndi(String repoId, String name, String type, String db) throws KettleException {
return createBaseMetaRep(repoId, (String)null, (String)null, (JSONObject)null, name, type, DatabaseMeta.dbAccessTypeCode[4], (String)null, db, (String)null, (String)null, (String)null);
}
public static Repository createDBRepByParams(String repoId, String repoName, JSONObject params, String databaseMetaName, String type, String access, String host, String db, String port, String user, String pass) throws KettleException {
return createBaseMetaRep(repoId, repoName, repoName, params, databaseMetaName, type, access, host, db, port, user, pass);
}
public static Repository createDBRepByDesc(String repoId, String repoName, String description, String databaseMetaName, String type, String access, String host, String db, String port, String user, String pass) throws KettleException {
return createBaseMetaRep(repoId, repoName, description, (JSONObject)null, databaseMetaName, type, access, host, db, port, user, pass);
}
public static Repository createBaseMetaRep(String repoId, String repoName, String description, JSONObject params, String databaseMetaName, String type, String access, String host, String db, String port, String user, String pass) throws KettleException {
DatabaseMeta dataMeta = createDatabaseMeta(databaseMetaName, type, access, host, db, port, user, pass, params, false, (Repository)null);
return createBaseRep(dataMeta, repoId, repoName, description);
}
public static Repository createBaseRep(DatabaseMeta dataMeta, String repoId, String repoName, String description) throws KettleException {
KettleDatabaseRepositoryMeta kettleDatabaseMeta = new KettleDatabaseRepositoryMeta(repoId, repoName, description, dataMeta);
return createRep(kettleDatabaseMeta, repoId);
}
public static KettleFileRepository createKFR(String id, String repName, String description, String baseDirectory) throws KettleException {
KettleFileRepositoryMeta kettleFileRepositoryMeta = (KettleFileRepositoryMeta)createFileRep(id, repName, repName + "文件资源库", baseDirectory);
KettleFileRepository kettleFileRepository = new KettleFileRepository();
kettleFileRepository.init(kettleFileRepositoryMeta);
return kettleFileRepository;
}
public static KettleDatabaseRepository createKDR(String name, String repoType, String dbAccess, String dbHost, String dbName, String dbPort, String dbUserName, String dbPass, String repoName, String repoId) throws KettleException {
createDatabaseMeta(name, repoType, dbAccess, dbHost, dbName, dbPort, dbUserName, dbPass, (Map)null, false, (Repository)null);
KettleDatabaseRepositoryMeta kettleDatabaseRepositoryMeta = (KettleDatabaseRepositoryMeta)createDBRepByDesc(repoId, repoName, repoName, name, repoType, dbAccess, dbHost, dbName, dbPort, dbUserName, dbPass);
KettleDatabaseRepository kettleDatabaseRepository = new KettleDatabaseRepository();
kettleDatabaseRepository.init(kettleDatabaseRepositoryMeta);
return kettleDatabaseRepository;
}
public static void disConnectionRepository(String id) {
if (repositoryCache.containsKey(id)) {
Repository repository = (Repository)repositoryCache.get(id);
repository.disconnect();
repository.clearSharedObjectCache();
repositoryCache.remove(id);
}
}
public static void destroyAll() {
repositoryCache.forEach((id, repository) -> {
repository.disconnect();
repository.clearSharedObjectCache();
});
repositoryCache.clear();
}
public static List<RepositoryTree> getAllDirectoryTreeList(String repoId, Repository repository, String path, List<RepositoryTree> allRepositoryTreeList) throws KettleException {
List<RepositoryTree> repositoryTreeList = getJobAndTrans(repoId, repository, path);
if (repositoryTreeList.size() != 0) {
Iterator var5 = repositoryTreeList.iterator();
while(var5.hasNext()) {
RepositoryTree repositoryTree = (RepositoryTree)var5.next();
if (!repositoryTree.isLasted()) {
getAllDirectoryTreeList(repoId, repository, repositoryTree.getPath(), allRepositoryTreeList);
allRepositoryTreeList.add(repositoryTree);
} else {
allRepositoryTreeList.add(repositoryTree);
}
}
}
return allRepositoryTreeList;
}
public static List<RepositoryTree> getJobAndTrans(String repoId, Repository repository, String path) throws KettleException {
RepositoryDirectoryInterface rDirectory = repository.loadRepositoryDirectoryTree().findDirectory(path);
List<RepositoryTree> repositoryTreeList = getDirectory(repoId, repository, rDirectory);
List<RepositoryElementMetaInterface> li = repository.getJobAndTransformationObjects(rDirectory.getObjectId(), false);
if (null != li) {
Iterator var6 = li.iterator();
while(var6.hasNext()) {
RepositoryElementMetaInterface repel = (RepositoryElementMetaInterface)var6.next();
RepositoryTree repositoryTree;
StringBuilder stringBuilder;
if ("job".equals(repel.getObjectType().toString())) {
repositoryTree = new RepositoryTree();
stringBuilder = new StringBuilder();
stringBuilder.append("job").append(rDirectory.getObjectId().toString()).append("@").append(repel.getObjectId().toString());
repositoryTree.setId(stringBuilder.toString());
repositoryTree.setParent(repoId + "@" + rDirectory.getObjectId().toString());
repositoryTree.setText(repel.getName());
if (repository instanceof KettleDatabaseRepository) {
repositoryTree.setType(repoId + "@db@" + "job");
} else if (repository instanceof KettleFileRepository) {
repositoryTree.setType(repoId + "@file@" + "job");
}
repositoryTree.setLasted(true);
repositoryTree.setPath(repel.getRepositoryDirectory().getPath());
repositoryTreeList.add(repositoryTree);
} else if ("transformation".equals(repel.getObjectType().toString())) {
repositoryTree = new RepositoryTree();
stringBuilder = new StringBuilder();
stringBuilder.append("transformation").append(rDirectory.getObjectId().toString()).append("@").append(repel.getObjectId().toString());
repositoryTree.setId(stringBuilder.toString());
repositoryTree.setParent(repoId + "@" + rDirectory.getObjectId().toString());
repositoryTree.setText(repel.getName());
if (repository instanceof KettleDatabaseRepository) {
repositoryTree.setType(repoId + "@db@" + "transformation");
} else if (repository instanceof KettleFileRepository) {
repositoryTree.setType(repoId + "@file@" + "transformation");
}
repositoryTree.setLasted(true);
repositoryTree.setPath(repel.getRepositoryDirectory().getPath());
repositoryTreeList.add(repositoryTree);
}
}
}
return repositoryTreeList;
}
private static List<RepositoryTree> getDirectory(String repoId, Repository repository, RepositoryDirectoryInterface rDirectory) throws KettleException {
List<RepositoryTree> repositoryTreeList = new ArrayList();
if (null != repository && null != rDirectory) {
RepositoryDirectoryInterface tree = repository.loadRepositoryDirectoryTree().findDirectory(rDirectory.getObjectId());
if (rDirectory.getNrSubdirectories() > 0) {
for(int i = 0; i < rDirectory.getNrSubdirectories(); ++i) {
RepositoryDirectory subTree = tree.getSubdirectory(i);
RepositoryTree repositoryTree = new RepositoryTree();
repositoryTree.setId(repoId + "@" + subTree.getObjectId().toString());
repositoryTree.setParent(repoId + "@" + rDirectory.getObjectId().toString());
repositoryTree.setText(subTree.getName());
repositoryTree.setPath(subTree.getPath());
repositoryTree.setType("subTree");
List<RepositoryElementMetaInterface> RepositoryElementMetaInterfaceList = repository.getJobAndTransformationObjects(subTree.getObjectId(), false);
if (subTree.getNrSubdirectories() <= 0 && RepositoryElementMetaInterfaceList.size() <= 0) {
repositoryTree.setLasted(true);
} else {
repositoryTree.setLasted(false);
}
repositoryTreeList.add(repositoryTree);
}
}
}
return repositoryTreeList;
}
}

View File

@ -0,0 +1,71 @@
package com.ruoyi.kettle.service;
import java.util.List;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.kettle.domain.KettleJob;
/**
* 作业调度Service接口
*
* @author kone
* @date 2021-07-22
*/
public interface IKettleJobService
{
/**
* 查询作业调度
*
* @param id 作业调度ID
* @return 作业调度
*/
public KettleJob selectKettleJobById(Long id);
/**
* 查询作业调度列表
*
* @param kettleJob 作业调度
* @return 作业调度集合
*/
public List<KettleJob> selectKettleJobList(KettleJob kettleJob);
/**
* 新增作业调度
*
* @param kettleJob 作业调度
* @return 结果
*/
public AjaxResult insertKettleJob(KettleJob kettleJob);
/**
* 修改作业调度
*
* @param kettleJob 作业调度
* @return 结果
*/
public int updateKettleJob(KettleJob kettleJob);
/**
* 批量删除作业调度
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteKettleJobByIds(String ids);
/**
* 删除作业调度信息
*
* @param id 作业调度ID
* @return 结果
*/
public int deleteKettleJobById(Long id);
AjaxResult run(KettleJob job);
List<String> queryJobLog(KettleJob kettleJob);
Long checkQuartzExist(String checkStr);
public AjaxResult runJobQuartz(String id, String jobName);
}

View File

@ -0,0 +1,84 @@
package com.ruoyi.kettle.service;
import java.util.List;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.kettle.domain.KettleTrans;
/**
* 转换Service接口
*
* @author kone
* @date 2021-07-14
*/
public interface IKettleTransService
{
/**
* 查询转换
*
* @param id 转换ID
* @return 转换
*/
public KettleTrans selectKettleTransById(Long id);
/**
* 查询转换列表
*
* @param kettleTrans 转换
* @return 转换集合
*/
public List<KettleTrans> selectKettleTransList(KettleTrans kettleTrans);
/**
* 新增转换
*
* @param kettleTrans 转换
* @return 结果
*/
public AjaxResult insertKettleTrans(KettleTrans kettleTrans);
/**
* 修改转换
*
* @param kettleTrans 转换
* @return 结果
*/
public int updateKettleTrans(KettleTrans kettleTrans);
/**
* 批量删除转换
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteKettleTransByIds(String ids);
/**
* 删除转换信息
*
* @param id 转换ID
* @return 结果
*/
public int deleteKettleTransById(Long id);
/**
* @Description:立即执行一次转换
* @Author: Kone.wang
* @Date: 2021/7/15 14:31
* @param trans :
* @return: void
**/
AjaxResult run(KettleTrans trans);
List<String> queryTransLog(KettleTrans trans) ;
/**
* @Description:设置定时执行转换
* @Author: Kone.wang
* @Date: 2021/7/21 14:59
* @param id:
* @param transName:
* @return: com.ruoyi.common.core.domain.AjaxResult
**/
public AjaxResult runTransQuartz(String id,String transName);
Long checkQuartzExist(String checkStr);
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.kettle.service;
import java.util.List;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.kettle.domain.XRepository;
import com.ruoyi.kettle.repo.RepoTree;
/**
* 资源库Service接口
*
* @author kone
* @date 2021-07-12
*/
public interface IXRepositoryService
{
/**
* 查询资源库
*
* @param id 资源库ID
* @return 资源库
*/
public XRepository selectXRepositoryById(Long id);
/**
* 查询资源库列表
*
* @param xRepository 资源库
* @return 资源库集合
*/
public List<XRepository> selectXRepositoryList(XRepository xRepository);
/**
* 新增资源库
*
* @param xRepository 资源库
* @return 结果
*/
public int insertXRepository(XRepository xRepository);
/**
* 修改资源库
*
* @param xRepository 资源库
* @return 结果
*/
public int updateXRepository(XRepository xRepository);
/**
* 批量删除资源库
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteXRepositoryByIds(String ids);
/**
* 删除资源库信息
*
* @param id 资源库ID
* @return 结果
*/
public int deleteXRepositoryById(Long id);
List<RepoTree> selectRepoTree(Long id);
List<RepoTree> selectRepoRoot(XRepository repository);
}

View File

@ -0,0 +1,169 @@
package com.ruoyi.kettle.service.impl;
import java.util.List;
import java.util.stream.Collectors;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.security.PermissionUtils;
import com.ruoyi.kettle.domain.KettleTrans;
import com.ruoyi.kettle.domain.XRepository;
import com.ruoyi.kettle.mapper.XRepositoryMapper;
import com.ruoyi.kettle.tools.KettleUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.kettle.mapper.KettleJobMapper;
import com.ruoyi.kettle.domain.KettleJob;
import com.ruoyi.kettle.service.IKettleJobService;
import com.ruoyi.common.core.text.Convert;
/**
* 作业调度Service业务层处理
*
* @author kone
* @date 2021-07-22
*/
@Service("kettleJobServiceImpl")
public class KettleJobServiceImpl implements IKettleJobService
{
@Autowired
private KettleJobMapper kettleJobMapper;
@Autowired
private XRepositoryMapper repositoryMapper;
@Autowired
private KettleUtil kettleUtil;
/**
* 查询作业调度
*
* @param id 作业调度ID
* @return 作业调度
*/
@Override
public KettleJob selectKettleJobById(Long id)
{
return kettleJobMapper.selectKettleJobById(id);
}
/**
* 查询作业调度列表
*
* @param kettleJob 作业调度
* @return 作业调度
*/
@Override
public List<KettleJob> selectKettleJobList(KettleJob kettleJob)
{
List<SysRole> roleList = (List<SysRole>) PermissionUtils.getPrincipalProperty("roles");
//当前用户的roleKey
List<String> roleKeys=roleList.stream().map(SysRole::getRoleKey).collect(Collectors.toList());
return kettleJobMapper.selectKettleJobList(kettleJob,roleKeys);
}
/**
* 新增作业调度
*
* @param kettleJob 作业调度
* @return 结果
*/
@Override
public AjaxResult insertKettleJob(KettleJob kettleJob)
{
String jobName=kettleJob.getJobName();
if(kettleJobMapper.selectJobByNameAndRepoId(jobName,kettleJob.getJobRepositoryId())>0){
return AjaxResult.error("已存在同名作业");
}
String userName = (String) PermissionUtils.getPrincipalProperty("userName");
if(kettleJob.getRoleKey()==null){
kettleJob.setRoleKey("admin");
}else{
if(!kettleJob.getRoleKey().contains("admin")){
kettleJob.setRoleKey(kettleJob.getRoleKey().concat(",admin"));
}
}
kettleJob.setCreatedBy(userName);
kettleJob.setUpdateBy(userName);
kettleJob.setJobType("File");
return AjaxResult.success(kettleJobMapper.insertKettleJob(kettleJob));
}
/**
* 修改作业调度
*
* @param kettleJob 作业调度
* @return 结果
*/
@Override
public int updateKettleJob(KettleJob kettleJob)
{
kettleJob.setUpdateTime(DateUtils.getNowDate());
return kettleJobMapper.updateKettleJob(kettleJob);
}
/**
* 删除作业调度对象
*
* @param ids 需要删除的数据ID
* @return 结果
*/
@Override
public int deleteKettleJobByIds(String ids)
{
return kettleJobMapper.deleteKettleJobByIds(Convert.toStrArray(ids));
}
/**
* 删除作业调度信息
*
* @param id 作业调度ID
* @return 结果
*/
@Override
public int deleteKettleJobById(Long id)
{
return kettleJobMapper.deleteKettleJobById(id);
}
@Override
public AjaxResult run(KettleJob job) {
Long id = job.getId();
KettleJob kettleJob = kettleJobMapper.selectKettleJobById(id);
if(kettleJob ==null){
return AjaxResult.error("作业不存在!");
}
XRepository repository=repositoryMapper.selectXRepositoryById(kettleJob.getJobRepositoryId());
if(repository==null){
return AjaxResult.error("资源库不存在!");
}
String path = kettleJob.getJobPath();
try {
kettleUtil.KETTLE_LOG_LEVEL=kettleJob.getJobLogLevel();
kettleUtil.KETTLE_REPO_ID=String.valueOf(kettleJob.getJobRepositoryId());
kettleUtil.KETTLE_REPO_NAME=repository.getRepoName();
kettleUtil.KETTLE_REPO_PATH=repository.getBaseDir();
kettleUtil.callJob(path,kettleJob.getJobName(),null,null);
} catch (Exception e) {
e.printStackTrace();
}
return AjaxResult.success("执行成功!"); }
@Override
public List<String> queryJobLog(KettleJob kettleJob) {
List<String> logs=kettleJobMapper.queryJobLog(kettleJob.getJobName());
return logs;
}
@Override
public Long checkQuartzExist(String checkStr) {
return kettleJobMapper.checkQuartzExist(checkStr);
}
@Override
public AjaxResult runJobQuartz(String id, String jobName) {
KettleJob kettleJob = kettleJobMapper.selectKettleJobById(Long.valueOf(id));
return run(kettleJob);
}
}

View File

@ -0,0 +1,209 @@
package com.ruoyi.kettle.service.impl;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.security.PermissionUtils;
import com.ruoyi.kettle.domain.XRepository;
import com.ruoyi.kettle.mapper.XRepositoryMapper;
import com.ruoyi.kettle.service.IKettleTransService;
import com.ruoyi.kettle.tools.KettleUtil;
import lombok.extern.slf4j.Slf4j;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.trans.Trans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.kettle.mapper.KettleTransMapper;
import com.ruoyi.kettle.domain.KettleTrans;
import com.ruoyi.common.core.text.Convert;
/**
* 转换Service业务层处理
*
* @author kone
* @date 2021-07-14
*/
@Service("kettleTransServiceImpl")
@Slf4j
public class KettleTransServiceImpl implements IKettleTransService
{
@Autowired
private KettleTransMapper kettleTransMapper;
@Autowired
private XRepositoryMapper repositoryMapper;
@Autowired
private KettleUtil kettleUtil;
/**
* 查询转换
*
* @param id 转换ID
* @return 转换
*/
@Override
public KettleTrans selectKettleTransById(Long id)
{
return kettleTransMapper.selectKettleTransById(id);
}
/**
* 查询转换列表
*
* @param kettleTrans 转换
* @return 转换
*/
@Override
public List<KettleTrans> selectKettleTransList(KettleTrans kettleTrans)
{
List<SysRole> roleList = (List<SysRole>) PermissionUtils.getPrincipalProperty("roles");
//当前用户的roleKey
List<String> roleKeys=roleList.stream().map(SysRole::getRoleKey).collect(Collectors.toList());
return kettleTransMapper.selectKettleTransList(kettleTrans,roleKeys);
}
/**
* 新增转换
*
* @param kettleTrans 转换
* @return 结果
*/
@Override
public AjaxResult insertKettleTrans(KettleTrans kettleTrans)
{
String transName=kettleTrans.getTransName();
if(kettleTransMapper.selectKettleTransByTransName(transName)>0){
return AjaxResult.error("已存在同名转换");
}
String userName = (String) PermissionUtils.getPrincipalProperty("userName");
if(kettleTrans.getRoleKey()==null){
kettleTrans.setRoleKey("admin");
}else{
if(!kettleTrans.getRoleKey().contains("admin")){
kettleTrans.setRoleKey(kettleTrans.getRoleKey().concat(",admin"));
}
}
kettleTrans.setCreatedBy(userName);
kettleTrans.setUpdateBy(userName);
kettleTrans.setTransType("File");
return AjaxResult.success(kettleTransMapper.insertKettleTrans(kettleTrans));
}
/**
* 修改转换
*
* @param kettleTrans 转换
* @return 结果
*/
@Override
public int updateKettleTrans(KettleTrans kettleTrans)
{
String userName = (String) PermissionUtils.getPrincipalProperty("userName");
kettleTrans.setUpdateBy(userName);
kettleTrans.setUpdateTime(DateUtils.getNowDate());
kettleTrans.setTransType("File");
if(kettleTrans.getRoleKey()==null){
kettleTrans.setRoleKey("admin");
}else{
if(!kettleTrans.getRoleKey().contains("admin")){
kettleTrans.setRoleKey(kettleTrans.getRoleKey().concat(",admin"));
}
} return kettleTransMapper.updateKettleTrans(kettleTrans);
}
/**
* 删除转换对象
*
* @param ids 需要删除的数据ID
* @return 结果
*/
@Override
public int deleteKettleTransByIds(String ids)
{
return kettleTransMapper.deleteKettleTransByIds(Convert.toStrArray(ids));
}
/**
* 删除转换信息
*
* @param id 转换ID
* @return 结果
*/
@Override
public int deleteKettleTransById(Long id)
{
return kettleTransMapper.deleteKettleTransById(id);
}
/**
* @Description:立即执行一次转换
* @Author: Kone.wang
* @Date: 2021/7/15 14:31
* @param trans :
* @return: void
**/
@Override
public AjaxResult run(KettleTrans trans) {
Long id = trans.getId();
KettleTrans kettleTrans = kettleTransMapper.selectKettleTransById(id);
if(kettleTrans ==null){
return AjaxResult.error("转换不存在!");
}
XRepository repository=repositoryMapper.selectXRepositoryById(kettleTrans.getTransRepositoryId());
if(repository==null){
return AjaxResult.error("资源库不存在!");
}
String path = kettleTrans.getTransPath();
try {
kettleUtil.KETTLE_LOG_LEVEL=kettleTrans.getTransLogLevel();
kettleUtil.KETTLE_REPO_ID=String.valueOf(kettleTrans.getTransRepositoryId());
kettleUtil.KETTLE_REPO_NAME=repository.getRepoName();
kettleUtil.KETTLE_REPO_PATH=repository.getBaseDir();
kettleUtil.callTrans(path,kettleTrans.getTransName(),null,null);
} catch (Exception e) {
e.printStackTrace();
}
return AjaxResult.success("执行成功!");
}
@Override
public List<String> queryTransLog(KettleTrans kettleTrans) {
List<String> transLogs=kettleTransMapper.queryTransLog(kettleTrans.getTransName());
return transLogs;
}
/**
* @Description:设置定时执行转换
* @Author: Kone.wang
* @Date: 2021/7/21 14:59
* @param id:
* @param transName:
* @return: com.ruoyi.common.core.domain.AjaxResult
**/
@Override
public AjaxResult runTransQuartz(String id, String transName) {
KettleTrans kettleTrans = kettleTransMapper.selectKettleTransById(Long.valueOf(id));
return run(kettleTrans);
}
/**
* @Description:检查该转换是否设置了定时任务
* @Author: Kone.wang
* @Date: 2021/7/21 16:37
* @param checkStr:
* @return: int
**/
@Override
public Long checkQuartzExist(String checkStr) {
return kettleTransMapper.checkQuartzExist(checkStr);
}
}

View File

@ -0,0 +1,250 @@
package com.ruoyi.kettle.service.impl;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.security.PermissionUtils;
import com.ruoyi.kettle.repo.RepoTree;
import com.ruoyi.kettle.repo.RepositoryTree;
import com.ruoyi.kettle.repo.XRepoManager;
import com.ruoyi.kettle.tools.KettleUtil_2;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.repository.RepositoryDirectoryInterface;
import org.pentaho.di.repository.filerep.KettleFileRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.kettle.mapper.XRepositoryMapper;
import com.ruoyi.kettle.domain.XRepository;
import com.ruoyi.kettle.service.IXRepositoryService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.util.CollectionUtils;
/**
* 资源库Service业务层处理
*
* @author kone
* @date 2021-07-12
*/
@Service
public class XRepositoryServiceImpl implements IXRepositoryService
{
@Autowired
private XRepositoryMapper xRepositoryMapper;
/**
* 查询资源库
*
* @param id 资源库ID
* @return 资源库
*/
@Override
public XRepository selectXRepositoryById(Long id)
{
return xRepositoryMapper.selectXRepositoryById(id);
}
/**
* 查询资源库列表
*
* @param xRepository 资源库
* @return 资源库
*/
@Override
public List<XRepository> selectXRepositoryList(XRepository xRepository)
{
return xRepositoryMapper.selectXRepositoryList(xRepository);
}
/**
* 新增资源库
*
* @param xRepository 资源库
* @return 结果
*/
@Override
public int insertXRepository(XRepository xRepository)
{
String userName = (String) PermissionUtils.getPrincipalProperty("userName");
xRepository.setCreatedBy(userName);
xRepository.setUpdateBy(userName);
xRepository.setType("File");
return xRepositoryMapper.insertXRepository(xRepository);
}
/**
* 修改资源库
*
* @param xRepository 资源库
* @return 结果
*/
@Override
public int updateXRepository(XRepository xRepository)
{
String userName = (String) PermissionUtils.getPrincipalProperty("userName");
xRepository.setUpdateTime(DateUtils.getNowDate());
xRepository.setUpdateBy(userName);
return xRepositoryMapper.updateXRepository(xRepository);
}
/**
* 删除资源库对象
*
* @param ids 需要删除的数据ID
* @return 结果
*/
@Override
public int deleteXRepositoryByIds(String ids)
{
return xRepositoryMapper.updateIsDelBatch(Convert.toStrArray(ids));
// return xRepositoryMapper.deleteXRepositoryByIds(Convert.toStrArray(ids));
}
/**
* 删除资源库信息
*
* @param id 资源库ID
* @return 结果
*/
@Override
public int deleteXRepositoryById(Long id)
{
return xRepositoryMapper.updateIsDel(id);
//return xRepositoryMapper.deleteXRepositoryById(id);
}
@Override
public List<RepoTree> selectRepoRoot(XRepository repository) {
List<XRepository> repositoryList = xRepositoryMapper.selectXRepositoryList(repository);
List<RepoTree> ztrees = initZtree2(repositoryList);
return ztrees;
}
@Override
public List<RepoTree> selectRepoTree(Long id) {
XRepository xrs = xRepositoryMapper.selectXRepositoryById(id);
List<RepositoryTree> repositoryTrees = getRepoTress(xrs);
List<RepositoryTree> subTrees = new ArrayList<>();
String type=null;
String pId=String.valueOf(xrs.getId());
// try
// {
// repositoryTrees.forEach(item -> {
// if (item.getParent().equals(pId)) {
// if (item.isLasted()) {
// if (!StringUtils.isEmpty(type)) {
// if (item.getType().indexOf(type) != -1) {
// subTrees.add(item);
// }
// } else {
// subTrees.add(item);
// }
//
// } else {
// subTrees.add(item);
// }
// }});
// }catch (Exception e)
// {
// StringWriter sw = new StringWriter();
// e.printStackTrace(new PrintWriter(sw));
// //throw new UserDefinedException(BaseResultConstant.UNKNOW_EXCEPTION, sw.toString().substring(0, 800));
// }
List<RepoTree> ztrees = initZtree(repositoryTrees,String.valueOf(id));
return ztrees;
}
public List<RepoTree> initZtree(List<RepositoryTree> repositoryList ,String parentId)
{
List<RepoTree> ztrees = new ArrayList<RepoTree>();
for (RepositoryTree rt : repositoryList) {
if(rt.getId().equals(parentId) || rt.getText().equals("/")){
continue;
}
RepoTree ztree = new RepoTree();
ztree.setId(rt.getId());
ztree.setpId(rt.getParent());
ztree.setName(rt.getText());
ztree.setTitle(rt.getPath());
ztrees.add(ztree);
}
return ztrees;
}
public List<RepoTree> initZtree2(List<XRepository> repositoryList )
{
List<RepoTree> ztrees = new ArrayList<RepoTree>();
for (XRepository rt : repositoryList)
{
RepoTree ztree = new RepoTree();
ztree.setId(String.valueOf(rt.getId()));
ztree.setpId(" ");
ztree.setName(rt.getRepoName());
ztree.setTitle(rt.getBaseDir());
ztrees.add(ztree);
}
return ztrees;
}
private List<RepositoryTree> getRepoTress(XRepository xr) {
List<RepositoryTree> repositoryTrees = new ArrayList<>();
List<XRepository> xRepositoryList =xRepositoryMapper.selectXRepositoryList(xr);
if (!CollectionUtils.isEmpty(xRepositoryList)) {
xRepositoryList.forEach(item -> {
List<RepositoryTree> tmpRepositoryList = new ArrayList<>();
String type = item.getType();
if (type.equalsIgnoreCase("File")) {
// 文件库
String baseDir = item.getBaseDir();
try {
KettleFileRepository repository = (KettleFileRepository) KettleUtil_2.
conFileRep(String.valueOf(item.getId()), item.getRepoName(), baseDir);
XRepoManager.getAllDirectoryTreeList(String.valueOf(item.getId()), repository, "/", tmpRepositoryList);
if (tmpRepositoryList.size() > 0) {
RepositoryDirectoryInterface rDirectory = repository.loadRepositoryDirectoryTree().findDirectory("/");
RepositoryTree repositoryTree = new RepositoryTree();
repositoryTree.setParent(String.valueOf(item.getId()));
repositoryTree.setId(item.getRepoId() + "@" + rDirectory.getObjectId().toString());
//repositoryTree.setId(String.valueOf(item.getId()));
repositoryTree.setText(rDirectory.getName().equals("\\/") ? "基础路径" : rDirectory.getName());
repositoryTree.setLasted(false);
repositoryTree.setType("tree");
repositoryTree.setPath("file");
tmpRepositoryList.add(repositoryTree);
}
} catch (KettleException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
// throw new UserDefinedException(BaseResultConstant.UNKNOW_EXCEPTION, sw.toString().substring(0, 800));
}
}
// RepositoryTree repositoryTree;
// repositoryTree = new RepositoryTree();
// repositoryTree.setParent("99");
// repositoryTree.setId(String.valueOf(item.getId()));
// repositoryTree.setText(item.getRepoName());
// repositoryTree.setLasted(false);
// repositoryTree.setType(type);
// repositoryTree.setPath("repo");
// tmpRepositoryList.add(repositoryTree);
repositoryTrees.addAll(tmpRepositoryList);
});
}
return repositoryTrees;
}
}

View File

@ -0,0 +1,151 @@
package com.ruoyi.kettle.tools;
import org.apache.commons.lang.StringUtils;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.logging.LogLevel;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class Constant extends Const {
public static final String VERSION = "7.1.0.0-12";
public static final String DEFAULT_ENCODING = "UTF-8";
public static final String DEFAULT_TIMEZONE = "GMT+8";
public static final String UKETTLE = "resource/xtl.properties";
public static final String VARIABLE_JOB_ID = "GLOBAL_JOB_ID";
public static final String VARIABLE_TRANS_ID = "GLOBAL_TRANS_ID";
public static final String VARIABLE_JOB_MONITOR_ID = "GLOBAL_JOB_MONITOR_ID";
public static final String VARIABLE_TRANS_MONITOR_ID = "GLOBAL_TRANS_MONITOR_ID";
public static final String DEFAULT_REPO_ID = "1326379690046259200";
public static final String TYPE_JOB = "job";
public static final String TYPE_TRANS = "transformation";
public static final String JOB_FILE_TYPE = "file";
public static final String JOB_REPO_TYPE = "db";
public static final String TRANS_FILE_TYPE = "file";
public static final String TRANS_REPO_TYPE = "db";
public static final String TYPE_JOB_SUFFIX = ".kjb";
public static final String TYPE_TRANS_SUFFIX = ".ktr";
public static final String STARTS_WITH_USD = "$";
public static final String STARTS_WITH_PARAM = "-param:";
public static final String SPLIT_PARAM = "-param:";
public static final String SPLIT_EQUAL = "=";
public static final String SPLIT_USD = "$";
public static final String KETTLE_REPO = "repo";
public static final String JOB_PREFIX = "JOB";
public static final String JOB_GROUP_PREFIX = "JOB_GROUP";
public static final String TRIGGER_PREFIX = "TRIGGER";
public static final String TRIGGER_GROUP_PREFIX = "TRIGGER_GROUP";
public static final String QUARTZ_SEPARATE = "@";
public static final String RUNSTATUS_SEPARATE = "-";
public static String KETTLE_HOME;
public static String KETTLE_PLUGIN;
public static String KETTLE_SCRIPT;
public static LogLevel KETTLE_LOGLEVEL;
public static Properties props;
public Constant() {
}
public static String get(String key) {
return props.getProperty(key);
}
public static void set(Properties p) {
props = p;
}
public static Properties readProperties() {
Properties p = new Properties();
try {
p.load(new FileInputStream(Constant.class.getResource("/").getPath().replace("%20", " ") + "resource/xtl.properties"));
} catch (Exception var2) {
var2.printStackTrace();
}
return p;
}
public static LogLevel logger(int level) {
LogLevel logLevel = null;
if ("3".equals(level + "")) {
logLevel = LogLevel.BASIC;
} else if ("4".equals(level + "")) {
logLevel = LogLevel.DETAILED;
} else if ("1".equals(level + "")) {
logLevel = LogLevel.ERROR;
} else if ("5".equals(level + "")) {
logLevel = LogLevel.DEBUG;
} else if ("2".equals(level + "")) {
logLevel = LogLevel.MINIMAL;
} else if ("6".equals(level + "")) {
logLevel = LogLevel.ROWLEVEL;
} else if ("0".endsWith(level + "")) {
logLevel = LogLevel.NOTHING;
} else {
logLevel = KETTLE_LOGLEVEL;
}
return logLevel;
}
public static LogLevel logger(String code) {
LogLevel logLevel = null;
if ("Basic".equalsIgnoreCase(code)) {
logLevel = LogLevel.BASIC;
} else if ("Detail".equalsIgnoreCase(code)) {
logLevel = LogLevel.DETAILED;
} else if ("Error".equalsIgnoreCase(code)) {
logLevel = LogLevel.ERROR;
} else if ("Debug".equalsIgnoreCase(code)) {
logLevel = LogLevel.DEBUG;
} else if ("Minimal".equalsIgnoreCase(code)) {
logLevel = LogLevel.MINIMAL;
} else if ("Rowlevel".equalsIgnoreCase(code)) {
logLevel = LogLevel.ROWLEVEL;
} else if ("Nothing".equalsIgnoreCase(code)) {
logLevel = LogLevel.NOTHING;
}
return logLevel;
}
private static String uKettle() {
String classPath = Constant.class.getResource("/").getPath().replace("%20", " ");
String iQuartz = "";
String index = "WEB-INF";
if (classPath.indexOf("target") > 0) {
index = "target";
}
if ("\\".equals(FILE_SEPARATOR)) {
iQuartz = classPath.substring(1, classPath.indexOf(index));
iQuartz = iQuartz.replace("/", "\\");
}
if ("/".equals(FILE_SEPARATOR)) {
iQuartz = classPath.substring(0, classPath.indexOf(index));
iQuartz = iQuartz.replace("\\", "/");
}
return iQuartz;
}
public static Map<String, String> getQuartzBasic(String name, String path) {
Map<String, String> quartzBasic = new HashMap();
StringBuilder jobName = new StringBuilder();
jobName.append("JOB").append("@").append(name).append("@").append(path);
StringBuilder jobGroupName = new StringBuilder();
jobGroupName.append("JOB_GROUP").append("@").append("@").append(name).append("@").append(path);
String triggerName = StringUtils.replace(jobName.toString(), "JOB", "TRIGGER");
String triggerGroupName = StringUtils.replace(jobGroupName.toString(), "JOB_GROUP", "TRIGGER_GROUP");
quartzBasic.put("jobName", jobName.toString());
quartzBasic.put("jobGroupName", jobGroupName.toString());
quartzBasic.put("triggerName", triggerName);
quartzBasic.put("triggerGroupName", triggerGroupName);
return quartzBasic;
}
}

View File

@ -0,0 +1,16 @@
package com.ruoyi.kettle.tools;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateHelper {
public DateHelper() {
}
public static String format(Date date) {
String strDate = "";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss.s");
strDate = formatter.format(date);
return strDate;
}
}

View File

@ -0,0 +1,108 @@
package com.ruoyi.kettle.tools;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
public class GenCodeUtil {
private static final long TWEPOCH = 1288834974657L;
private static final long WORKER_ID_BITS = 5L;
private static final long DATACENTER_ID_BITS = 5L;
private static final long MAX_WORKER_ID = 31L;
private static final long MAX_DATACENTER_ID = 31L;
private static final long SEQUENCE_BITS = 12L;
private static final long WORKER_ID_SHIFT = 12L;
private static final long DATACENTER_ID_SHIFT = 17L;
private static final long TIMESTAMP_LEFT_SHIFT = 22L;
private static final long SEQUENCE_MASK = 4095L;
private static long lastTimestamp = -1L;
private static long sequence = 0L;
private static long workerId;
private static long datacenterId;
public GenCodeUtil() {
datacenterId = getDatacenterId(31L);
workerId = getMaxWorkerId(datacenterId, 31L);
}
public GenCodeUtil(long workerId, long datacenterId) {
if (workerId <= 31L && workerId >= 0L) {
if (datacenterId <= 31L && datacenterId >= 0L) {
GenCodeUtil.workerId = workerId;
GenCodeUtil.datacenterId = datacenterId;
} else {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", 31L));
}
} else {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", 31L));
}
}
public static synchronized String nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
} else {
if (lastTimestamp == timestamp) {
sequence = sequence + 1L & 4095L;
if (sequence == 0L) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
long nextId = timestamp - 1288834974657L << 22 | datacenterId << 17 | workerId << 12 | sequence;
return String.valueOf(nextId);
}
}
private static long tilNextMillis(long lastTimestamp) {
long timestamp;
for(timestamp = timeGen(); timestamp <= lastTimestamp; timestamp = timeGen()) {
}
return timestamp;
}
private static long timeGen() {
return System.currentTimeMillis();
}
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
StringBuffer mpid = new StringBuffer();
mpid.append(datacenterId);
String name = ManagementFactory.getRuntimeMXBean().getName();
if (!name.isEmpty()) {
mpid.append(name.split("@")[0]);
}
return (long)(mpid.toString().hashCode() & '\uffff') % (maxWorkerId + 1L);
}
protected static long getDatacenterId(long maxDatacenterId) {
long id = 0L;
try {
InetAddress ip = InetAddress.getLocalHost();
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
if (network == null) {
id = 1L;
} else {
byte[] mac = network.getHardwareAddress();
id = (255L & (long)mac[mac.length - 1] | 65280L & (long)mac[mac.length - 2] << 8) >> 6;
id %= maxDatacenterId + 1L;
}
} catch (Exception var7) {
System.out.println(" getDatacenterId: " + var7.getMessage());
}
return id;
}
public static void main(String[] args) {
System.out.println(nextId());
}
}

View File

@ -0,0 +1,332 @@
package com.ruoyi.kettle.tools;
import lombok.extern.slf4j.Slf4j;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.logging.*;
import org.pentaho.di.core.util.EnvUtil;
import org.pentaho.di.core.variables.VariableSpace;
import org.pentaho.di.core.variables.Variables;
import org.pentaho.di.job.Job;
import org.pentaho.di.job.JobMeta;
import org.pentaho.di.repository.RepositoryDirectoryInterface;
import org.pentaho.di.repository.filerep.KettleFileRepository;
import org.pentaho.di.repository.filerep.KettleFileRepositoryMeta;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import java.util.Iterator;
import java.util.Map;
@Slf4j
@Component
public class KettleUtil {
public String KETTLE_LOG_LEVEL = "basic";
public String KETTLE_REPO_ID = "2";
public String KETTLE_REPO_NAME = "koneTest";
public String KETTLE_REPO_DESC = "DESC";
public String KETTLE_REPO_PATH = "D:\\etl";
/**
* 执行文件资源库转换
* @param transPath 转换路径相对于资源库
* @param transName 转换名称不需要后缀
* @param namedParams 命名参数
* @param clParams 命令行参数
*/
public void callTrans(String transPath, String transName, Map<String,String> namedParams, String[] clParams) throws Exception {
KettleEnv.init();
DatabaseMeta databaseMeta=new DatabaseMeta("kettle_trans_log", "mysql", "Native(JDBC)",
"192.168.2.18","bps?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8", "3306", "root", "abc.123");
// DatabaseMeta databaseMeta=new DatabaseMeta("kettle_trans_log", "mysql", "Native(JDBC)",
// "127.0.0.1","etl?useUniCode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=UTC","3306","root","2129");
String msg;
KettleFileRepository repo = this.fileRepositoryCon();
TransMeta transMeta = this.loadTrans(repo, transPath, transName);
transMeta.addDatabase(databaseMeta);
VariableSpace space=new Variables();
TransLogTable jobLogTable= TransLogTable.getDefault(space,transMeta,null);
jobLogTable.setTableName("kettle_trans_log");
jobLogTable.setConnectionName("kettle_trans_log");
transMeta.setTransLogTable(jobLogTable);
//transMeta.getTransLogTable().setTableName(repInitialization.transLog);
//转换
Trans trans = new Trans(transMeta);
//设置命名参数
if(null != namedParams) {
//namedParams.forEach(trans::setParameterValue);
/*for (Map.Entry<String, String> entry : namedParams.entrySet()) {
trans.setParameterValue(entry.getKey(), entry.getValue());
}*/
for(Iterator<Map.Entry<String, String>> it = namedParams.entrySet().iterator(); it.hasNext();){
Map.Entry<String, String> entry = it.next();
trans.setParameterValue(entry.getKey(), entry.getValue());
}
}
trans.setLogLevel(this.getLogerLevel(KETTLE_LOG_LEVEL));
//执行
trans.execute(clParams);
trans.waitUntilFinished();
KettleLogStore.discardLines(trans.getLogChannelId(),true);
//记录日志
String logChannelId = trans.getLogChannelId();
LoggingBuffer appender = KettleLogStore.getAppender();
String logText = appender.getBuffer(logChannelId, true).toString();
log.info("[logTextlogText:"+logText+":logTextlogText]");
//抛出异常
if (trans.getErrors() > 0) {
msg = "There are errors during transformation exception!(转换过程中发生异常)";
log.error(msg);
throw new Exception(msg);
}
}
/**
* 执行文件资源库job
* @param jobName
* @throws Exception
*/
public boolean callJob(String jobPath, String jobName, Map<String,String> variables, String[] clParams) throws Exception {
KettleEnv.init();
String msg;
DatabaseMeta databaseMeta=new DatabaseMeta("kettle_job_log", "mysql", "Native(JDBC)",
"192.168.2.18","bps?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8", "3306", "root", "abc.123");
KettleFileRepository repo = this.fileRepositoryCon();
JobMeta jobMeta = this.loadJob(repo, jobPath, jobName);
jobMeta.addDatabase(databaseMeta);
VariableSpace space=new Variables();
space.setVariable("test","fromDbName");
JobLogTable jobLogTable= JobLogTable.getDefault(space,jobMeta);
jobLogTable.setTableName("kettle_job_log");
jobLogTable.setConnectionName("kettle_job_log");
jobMeta.setJobLogTable(jobLogTable);
Job job = new Job(repo, jobMeta);
//向Job 脚本传递参数脚本中获取参数值${参数名}
if(null != variables) {
for(Iterator<Map.Entry<String, String>> it = variables.entrySet().iterator(); it.hasNext();){
Map.Entry<String, String> entry = it.next();
job.setVariable(entry.getKey(), entry.getValue());
}
}
//设置日志级别
job.setLogLevel(this.getLogerLevel(KETTLE_LOG_LEVEL));
job.setArguments(clParams);
job.start();
job.waitUntilFinished();
//记录日志
String logChannelId = job.getLogChannelId();
LoggingBuffer appender = KettleLogStore.getAppender();
String logText = appender.getBuffer(logChannelId, true).toString();
log.info(logText);
if (job.getErrors() > 0) {
msg = "There are errors during job exception!(执行job发生异常)";
log.error(msg);
throw new Exception(msg);
}
return true;
}
/**
* 加载转换
* @param repo kettle文件资源库
* @param transPath 相对路径
* @param transName 转换名称
*/
public TransMeta loadTrans(KettleFileRepository repo, String transPath, String transName) throws Exception{
String msg;
RepositoryDirectoryInterface dir = repo.findDirectory(transPath);//根据指定的字符串路径找到目录
if(null == dir){
msg = "kettle资源库转换路径不存在【"+repo.getRepositoryMeta().getBaseDirectory()+transPath+"】!";
throw new Exception(msg);
}
TransMeta transMeta = repo.loadTransformation(repo.getTransformationID(transName, dir), null);
if(null == transMeta){
msg = "kettle资源库【"+dir.getPath()+"】不存在该转换【"+transName+"】!";
throw new Exception(msg);
}
return transMeta;
}
/**
* 加载job
* @param repo kettle文件资源库
* @param jobPath 相对路径
* @param jobName job名称
*/
private JobMeta loadJob(KettleFileRepository repo, String jobPath, String jobName) throws Exception{
String msg;
RepositoryDirectoryInterface dir = repo.findDirectory(jobPath);//根据指定的字符串路径找到目录
if(null == dir){
msg = "kettle资源库Job路径不存在【"+repo.getRepositoryMeta().getBaseDirectory()+jobPath+"】!";
throw new Exception(msg);
}
JobMeta jobMeta = repo.loadJob(repo.getJobId(jobName, dir), null);
if(null == jobMeta){
msg = "kettle资源库【"+dir.getPath()+"】不存在该转换【"+jobName+"】!";
throw new Exception(msg);
}
return jobMeta;
}
/**
* 调用trans文件 带参数的
*/
public void callNativeTransWithParams(String[] params, String transName) throws Exception {
// 初始化
KettleEnvironment.init();
EnvUtil.environmentInit();
TransMeta transMeta = new TransMeta(transName);
//转换
Trans trans = new Trans(transMeta);
//执行
trans.execute(params);
//等待结束
trans.waitUntilFinished();
//抛出异常
if (trans.getErrors() > 0) {
throw new Exception("There are errors during transformation exception!(传输过程中发生异常)");
}
}
/**
* 调用job文件
* @param jobName
* @throws Exception
*/
public void callNativeJob(String jobName) throws Exception {
// 初始化
/*KettleEnvironment.init();*/
JobMeta jobMeta = new JobMeta(jobName, null);
Job job = new Job(null, jobMeta);
//向Job 脚本传递参数脚本中获取参数值${参数名}
//job.setVariable(paraname, paravalue);
//设置日志级别
job.setLogLevel(this.getLogerLevel(KETTLE_LOG_LEVEL));
job.start();
job.waitUntilFinished();
if (job.getErrors() > 0) {
throw new Exception("There are errors during job exception!(执行job发生异常)");
}
}
/**
* 取得kettle的日志级别
*/
private LogLevel getLogerLevel(String level) {
LogLevel logLevel;
if ("basic".equals(level)) {
logLevel = LogLevel.BASIC;
} else if ("detail".equals(level)) {
logLevel = LogLevel.DETAILED;
} else if ("error".equals(level)) {
logLevel = LogLevel.ERROR;
} else if ("debug".equals(level)) {
logLevel = LogLevel.DEBUG;
} else if ("minimal".equals(level)) {
logLevel = LogLevel.MINIMAL;
} else if ("rowlevel".equals(level)) {
logLevel = LogLevel.ROWLEVEL;
} else if ("nothing".endsWith(level)){
logLevel = LogLevel.NOTHING;
}else {
logLevel = null;
}
return logLevel;
}
/**
* 配置kettle文件库资源库环境
**/
public KettleFileRepository fileRepositoryCon() throws KettleException {
String msg;
//初始化
/*EnvUtil.environmentInit();
KettleEnvironment.init();*/
//资源库元对象
KettleFileRepositoryMeta fileRepositoryMeta = new KettleFileRepositoryMeta(this.KETTLE_REPO_ID, this.KETTLE_REPO_NAME, this.KETTLE_REPO_DESC, this.KETTLE_REPO_PATH);
// 文件形式的资源库
KettleFileRepository repo = new KettleFileRepository();
repo.init(fileRepositoryMeta);
//连接到资源库
repo.connect("", "");//默认的连接资源库的用户名和密码
if (repo.isConnected()) {
msg = "kettle文件库资源库【" + KETTLE_REPO_PATH + "】连接成功";
log.info(msg);
return repo;
} else {
msg = "kettle文件库资源库【" + KETTLE_REPO_PATH + "】连接失败";
log.error(msg);
throw new KettleException(msg);
}
}
// 调用Transformation示例
public static void runTrans(String filename) {
try {
KettleEnvironment.init();
TransMeta transMeta = new TransMeta(filename);
Trans trans = new Trans(transMeta);
trans.execute(null);// 执行转换
trans.waitUntilFinished(); // 等待转换执行结束
if (trans.getErrors() != 0) {
System.out.println("Error");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Kettle环境初始化.
*/
public static class KettleEnv {
public static void init(){
try {
KettleEnvironment.init();
EnvUtil.environmentInit();
log.info("Kettle环境初始化成功");
}catch (Exception e){
e.printStackTrace();
log.error("Kettle环境初始化失败");
}
}
}
/**
* 初始化环境
*/
public class StartInit implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
KettleEnv.init();
}
}
}

View File

@ -0,0 +1,735 @@
package com.ruoyi.kettle.tools;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.kettle.cons.XJobStatus;
import com.ruoyi.kettle.cons.XTransStatus;
import com.ruoyi.kettle.repo.XRepoManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.vfs2.FileObject;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.ProgressMonitorListener;
import org.pentaho.di.core.database.Database;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleSecurityException;
import org.pentaho.di.core.gui.Point;
import org.pentaho.di.core.gui.Rectangle;
import org.pentaho.di.core.gui.ScrollBarInterface;
import org.pentaho.di.core.gui.SwingGC;
import org.pentaho.di.core.parameters.NamedParams;
import org.pentaho.di.core.variables.VariableSpace;
import org.pentaho.di.core.vfs.KettleVFS;
import org.pentaho.di.job.Job;
import org.pentaho.di.job.JobHopMeta;
import org.pentaho.di.job.JobMeta;
import org.pentaho.di.job.JobPainter;
import org.pentaho.di.job.entries.job.JobEntryJob;
import org.pentaho.di.job.entries.special.JobEntrySpecial;
import org.pentaho.di.job.entries.trans.JobEntryTrans;
import org.pentaho.di.job.entry.JobEntryBase;
import org.pentaho.di.job.entry.JobEntryCopy;
import org.pentaho.di.job.entry.JobEntryInterface;
import org.pentaho.di.repository.*;
import org.pentaho.di.repository.filerep.KettleFileRepositoryMeta;
import org.pentaho.di.repository.kdr.KettleDatabaseRepository;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransHopMeta;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.TransPainter;
import org.pentaho.di.trans.step.StepInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.StepMetaInterface;
import org.pentaho.di.trans.steps.jobexecutor.JobExecutorMeta;
import org.pentaho.di.trans.steps.transexecutor.TransExecutorMeta;
import org.pentaho.metastore.api.IMetaStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class KettleUtil_2 {
private static final Logger log = LoggerFactory.getLogger(KettleUtil_2.class);
public static Map<String, Repository> holder = new ConcurrentHashMap();
public static Map<String, Repository> getHolder() {
return holder;
}
public static void setHolder(Map<String, Repository> holder) {
KettleUtil_2.holder = holder;
}
public KettleUtil_2() {
}
public static Repository conByJndi(String repoId, String name, String db, String type, String kuser, String kpass) throws Exception {
testConnect(repoId);
if (holder.containsKey(repoId)) {
return (Repository)holder.get(repoId);
} else {
XRepoManager.createDBRepByJndi(repoId, name, type, db);
Repository repository = connect(repoId, kuser, kpass);
if (null != repository) {
holder.put(repoId, repository);
return repository;
} else {
return null;
}
}
}
public static Repository conFileRep(String repoId, String repoName, String baseDirectory) throws KettleException {
if (holder.containsKey(repoId)) {
return (Repository)holder.get(repoId);
} else {
XRepoManager.createFileRep(repoId, repoName, "文件资源库", baseDirectory);
Repository repository = connect(repoId);
if (null != repository) {
holder.put(repoId, repository);
return repository;
} else {
return null;
}
}
}
public static Repository conByNative(String repoId, String repoName, String name, String type, String host, String port, String db, String user, String pass, String kuser, String kpass) throws KettleException {
testConnect(repoId);
if (holder.containsKey(repoId)) {
return (Repository)holder.get(repoId);
} else {
XRepoManager.createDBRepByDesc(repoId, repoName, "资源库", name, type, "Native", host, db, port, user, pass);
Repository repository = connect(repoId, kuser, kpass);
if (null != repository) {
holder.put(repoId, repository);
return repository;
} else {
return null;
}
}
}
public static DatabaseMeta createDatabaseMeta(String name, String type, String access, String host, String dbName, String port, String user, String pass, boolean replace, Repository repository) {
return XRepoManager.createDatabaseMeta(name, type, access, host, dbName, port, user, pass, (Map)null, replace, repository);
}
public static DatabaseMeta createDatabaseMeta(String name, String type, String access, String host, String dbName, String port, String user, String pass, Map params, Repository repository) {
return XRepoManager.createDatabaseMeta(name, type, access, host, dbName, port, user, pass, params, false, repository);
}
public static Repository conByParams(String repoId, String repoName, JSONObject params, String name, String type, String access, String host, String db, String port, String user, String pass, String kuser, String kpass) throws Exception {
testConnect(repoId);
if (holder.containsKey(repoId)) {
return (Repository)holder.get(repoId);
} else {
XRepoManager.createDBRepByParams(repoId, repoName, params, name, type, access, host, db, port, user, pass);
Repository repository = connect(repoId, kuser, kpass);
if (null != repository) {
holder.put(repoId, repository);
return repository;
} else {
return null;
}
}
}
public static Repository connect(String repoId) throws KettleSecurityException, KettleException {
return connect(repoId, (String)null, (String)null);
}
public static Repository connect(String repoId, String username, String password) throws KettleSecurityException, KettleException {
Repository repository = (Repository)XRepoManager.repositoryCache.get(repoId);
if (!repository.isConnected()) {
repository.connect(username, password);
log.info(repository.getName() + "资源库已连接!");
}
return repository;
}
public static void setRepository(Repository repository) {
}
public static void destroy(String id) {
XRepoManager.disConnectionRepository(id);
}
public static void delJob(String repoId, long id_job) throws KettleException {
testConnect(repoId);
delJob(id_job, (Repository)holder.get(repoId));
}
private static String calcRelativeElementDirectory(RepositoryDirectoryInterface dir) {
return dir != null ? dir.getPath() : "/";
}
private static String calcDirectoryName(String repoId, RepositoryDirectoryInterface dir) {
testConnect(repoId);
StringBuilder directory = new StringBuilder();
KettleFileRepositoryMeta repositoryMeta = (KettleFileRepositoryMeta)((Repository)holder.get(repoId)).getRepositoryMeta();
String baseDir = repositoryMeta.getBaseDirectory();
baseDir = Const.replace(baseDir, "\\", "/");
directory.append(baseDir);
if (!baseDir.endsWith("/")) {
directory.append("/");
}
if (dir != null) {
String path = calcRelativeElementDirectory(dir);
if (path.startsWith("/")) {
directory.append(path.substring(1));
} else {
directory.append(path);
}
if (!path.endsWith("/")) {
directory.append("/");
}
}
return directory.toString();
}
public static void delFileJob(String repoId, String jobId) throws KettleException {
String path = jobId.substring(0, jobId.lastIndexOf("/"));
String jobName = jobId.substring(jobId.lastIndexOf("/") + 1);
RepositoryDirectoryInterface repositoryDirectoryInterface = ((Repository)holder.get(repoId)).findDirectory(path);
String filename = calcFilename(repoId, repositoryDirectoryInterface, jobName);
deleteFile(filename);
}
private static String calcFilename(String repoId, RepositoryDirectoryInterface repositoryDirectoryInterface, String jobName) {
return calcDirectoryName(repoId, (RepositoryDirectoryInterface)null) + repositoryDirectoryInterface.getPath() + "/" + jobName;
}
private static void deleteFile(String filename) throws KettleException {
try {
FileObject fileObject = KettleVFS.getFileObject(filename);
fileObject.delete();
} catch (Exception var2) {
throw new KettleException("Unable to delete file with name [" + filename + "]", var2);
}
}
public static void delJob(long id_job, Repository repository) throws KettleException {
repository.deleteJob(new LongObjectId(id_job));
}
public static void delTrans(String repoId, long id_job) throws KettleException {
testConnect(repoId);
delTrans(id_job, (Repository)holder.get(repoId));
}
public static void delTrans(long id_job, Repository repository) throws KettleException {
repository.deleteTransformation(new LongObjectId(id_job));
}
public static JobMeta loadJob(String repoId, long jobId) throws KettleException {
testConnect(repoId);
return ((Repository)holder.get(repoId)).loadJob(new LongObjectId(jobId), (String)null);
}
public static JobMeta loadJob(String repoId, String jobId) throws KettleException {
testConnect(repoId);
return ((Repository)holder.get(repoId)).loadJob(new StringObjectId(jobId), (String)null);
}
public static JobMeta loadJob(String repoId, String jobname, String directory) throws KettleException {
testConnect(repoId);
return loadJob(jobname, directory, (Repository)holder.get(repoId));
}
public static JobMeta loadJob(String jobname, String directory, Repository repository) throws KettleException {
RepositoryDirectoryInterface dir = repository.findDirectory(directory);
return repository.loadJob(jobname, dir, (ProgressMonitorListener)null, (String)null);
}
public static JobMeta loadJob(String repoId, String jobname, long directory) throws KettleException {
testConnect(repoId);
return loadJob(jobname, directory, (Repository)holder.get(repoId));
}
public static JobMeta loadJob(String jobname, long directory, Repository repository) throws KettleException {
RepositoryDirectoryInterface dir = repository.findDirectory(new LongObjectId(directory));
return repository.loadJob(jobname, dir, (ProgressMonitorListener)null, (String)null);
}
public static TransMeta loadTrans(String repoId, long id) throws KettleException {
testConnect(repoId);
return ((Repository)holder.get(repoId)).loadTransformation(new LongObjectId(id), (String)null);
}
public static TransMeta loadTrans(String repoId, String transname, String directory) throws KettleException {
testConnect(repoId);
return loadTrans(transname, directory, (Repository)holder.get(repoId));
}
public static TransMeta loadTrans(String transname, String directory, Repository repository) throws KettleException {
RepositoryDirectoryInterface dir = repository.findDirectory(directory);
return repository.loadTransformation(transname, dir, (ProgressMonitorListener)null, true, (String)null);
}
public static TransMeta loadTrans(String repoId, JobMeta jobMeta, String teansName) throws KettleException {
JobEntryTrans trans = (JobEntryTrans)jobMeta.findJobEntry(teansName).getEntry();
TransMeta transMeta = loadTrans(repoId, trans.getTransname(), trans.getDirectory());
return transMeta;
}
public static <T extends JobEntryBase> T loadJobEntry(String repoId, JobMeta jobMeta, String jobEntryName, T jobEntryMeta) throws KettleException {
return loadJobEntry(repoId, jobMeta.findJobEntry(jobEntryName).getEntry().getObjectId(), jobEntryMeta);
}
public static <T extends JobEntryBase> T loadJobEntry(String repoId, ObjectId entryId, T jobEntryMeta) throws KettleException {
testConnect(repoId);
jobEntryMeta.loadRep((Repository)holder.get(repoId), (IMetaStore)null, entryId, (List)null, (List)null);
jobEntryMeta.setObjectId(entryId);
return jobEntryMeta;
}
public static JobEntrySpecial findStart(JobMeta jobMeta) {
for(int i = 0; i < jobMeta.nrJobEntries(); ++i) {
JobEntryCopy jec = jobMeta.getJobEntry(i);
JobEntryInterface je = jec.getEntry();
if (je.getPluginId().equals("SPECIAL")) {
return (JobEntrySpecial)je;
}
}
return null;
}
public static void saveRepositoryElement(String repoId, RepositoryElementInterface repositoryElement) throws KettleException {
testConnect(repoId);
saveRepositoryElement((Repository)holder.get(repoId), repositoryElement);
}
public static void saveRepositoryElement(Repository repository, RepositoryElementInterface repositoryElement) throws KettleException {
repository.save(repositoryElement, (String)null, (ProgressMonitorListener)null, true);
}
public static void saveTrans(String repoId, TransMeta transMeta) throws KettleException {
testConnect(repoId);
saveRepositoryElement((Repository)((Repository)holder.get(repoId)), transMeta);
}
public static void saveTrans(Repository repository, TransMeta transMeta) throws KettleException {
saveRepositoryElement((Repository)repository, transMeta);
}
public static void saveJob(String repoId, JobMeta jobMeta) throws KettleException {
testConnect(repoId);
saveRepositoryElement((Repository)((Repository)holder.get(repoId)), jobMeta);
}
public static void saveJob(Repository repository, JobMeta jobMeta) throws KettleException {
saveRepositoryElement((Repository)repository, jobMeta);
}
public static boolean isDirectoryExist(Repository repository, String directoryName) {
try {
RepositoryDirectoryInterface dir = repository.findDirectory(directoryName);
return dir != null;
} catch (KettleException var3) {
log.error("判断job目录是否存在失败", var3);
return false;
}
}
public static RepositoryDirectoryInterface getOrMakeDirectory(String repoId, String parentDirectory, String directoryName) throws KettleException {
testConnect(repoId);
RepositoryDirectoryInterface parent = ((Repository)holder.get(repoId)).findDirectory(parentDirectory);
if (StringUtils.isBlank(parentDirectory)) {
parent = ((Repository)holder.get(repoId)).findDirectory("/");
}
if (StringUtils.isNotBlank(directoryName)) {
RepositoryDirectoryInterface dir = ((Repository)holder.get(repoId)).findDirectory(parentDirectory + "/" + directoryName);
return dir == null ? ((Repository)holder.get(repoId)).createRepositoryDirectory(parent, directoryName) : dir;
} else {
return parent;
}
}
public static RepositoryDirectoryInterface makeDirs(String repoId, String directoryName) throws KettleException {
if (!StringUtils.isNotBlank(directoryName)) {
return null;
} else {
String parentDirectory = "";
String[] dirArr = directoryName.replace("\\", "/").split("/");
String[] var6 = dirArr;
int var5 = dirArr.length;
for(int var4 = 0; var4 < var5; ++var4) {
String dirStr = var6[var4];
try {
if (StringUtils.isNotBlank(dirStr)) {
RepositoryDirectoryInterface p = getOrMakeDirectory(repoId, parentDirectory, dirStr);
parentDirectory = p.getPath();
}
} catch (Exception var9) {
log.error("创建目录失败:" + directoryName + "," + parentDirectory + "," + dirStr, var9);
}
}
return getOrMakeDirectory(repoId, parentDirectory, (String)null);
}
}
public static String getDirectory(String repoId, long dirId) throws KettleException {
return getDirectory(repoId, new LongObjectId(dirId));
}
public static String getDirectory(String repoId, ObjectId dirId) throws KettleException {
testConnect(repoId);
RepositoryDirectoryInterface dir = ((Repository)holder.get(repoId)).findDirectory(dirId);
return dir == null ? null : dir.getPath();
}
public static void setStepToTrans(TransMeta teans, String stepName, StepMetaInterface smi) {
StepMeta step = teans.findStep(stepName);
step.setStepMetaInterface(smi);
}
public static void setStepToTransAndSave(String repoId, TransMeta teans, String stepName, StepMetaInterface smi) throws KettleException {
setStepToTrans(teans, stepName, smi);
saveTrans(repoId, teans);
}
public static void jobStopAll(Job job) {
job.stopAll();
JobMeta jobMeta = job.getJobMeta();
Iterator var3 = jobMeta.getJobCopies().iterator();
while(var3.hasNext()) {
JobEntryCopy jec = (JobEntryCopy)var3.next();
if (jec.isTransformation()) {
JobEntryTrans jet = (JobEntryTrans)jec.getEntry();
if (jet.getTrans() != null) {
jet.getTrans().stopAll();
}
} else if (jec.isJob()) {
JobEntryJob jej = (JobEntryJob)jec.getEntry();
if (jej.getJob() != null) {
jobStopAll(jej.getJob());
}
}
}
}
public static void jobKillAll(Job job) {
job.stopAll();
JobMeta jobMeta = job.getJobMeta();
Iterator var3 = jobMeta.getJobCopies().iterator();
while(var3.hasNext()) {
JobEntryCopy jec = (JobEntryCopy)var3.next();
if (jec.isTransformation()) {
JobEntryTrans jet = (JobEntryTrans)jec.getEntry();
if (jet.getTrans() != null) {
jet.getTrans().killAll();
}
} else if (jec.isJob()) {
JobEntryJob jej = (JobEntryJob)jec.getEntry();
if (jej.getJob() != null) {
jobKillAll(jej.getJob());
}
}
}
if (!job.getState().equals(Thread.State.BLOCKED) && !job.getState().equals(Thread.State.TIMED_WAITING)) {
job.interrupt();
} else {
job.stop();
}
}
public static void transCopy(Map param, Repository fromRepository, Repository toRepository) throws KettleException {
String jobName = param.get("transName") + "";
String jobPath = param.get("transPath") + "";
String newName = param.get("newName") + "";
String newPath = param.get("newPath") + "";
String des = param.get("transDescription") + "";
TransMeta jobMeta = loadTrans(jobName, jobPath, fromRepository);
new TransMeta();
jobMeta.setName(newName);
jobMeta.setDescription(des);
jobMeta.setRepositoryDirectory(makeDirs(param.get("repoId") + "", newPath));
saveTrans(toRepository, jobMeta);
}
public static void jobCopy(Map param, Repository fromRepository, Repository toRepository) throws KettleException {
String jobName = param.get("jobName") + "";
String jobPath = param.get("jobPath") + "";
String newName = param.get("newName") + "";
String newPath = param.get("newPath") + "";
String des = param.get("jobDescription") + "";
JobMeta jobMeta = loadJob(jobName, jobPath, fromRepository);
jobMeta.setName(newName);
jobMeta.setDescription(des);
jobMeta.setRepositoryDirectory(makeDirs(param.get("repoId") + "", newPath));
saveJob(toRepository, jobMeta);
}
public static void jobCopy(String jobName, String jobPath, Repository fromRepository, Repository toRepository) throws KettleException {
JobMeta jobMeta = loadJob(jobName, jobPath, fromRepository);
Iterator var6 = jobMeta.getJobCopies().iterator();
while(var6.hasNext()) {
JobEntryCopy jec = (JobEntryCopy)var6.next();
if (jec.isTransformation()) {
JobEntryTrans jet = (JobEntryTrans)jec.getEntry();
transCopy(jet.getObjectName(), jet.getDirectory(), fromRepository, toRepository);
} else if (jec.isJob()) {
JobEntryJob jej = (JobEntryJob)jec.getEntry();
jobCopy(jej.getObjectName(), jej.getDirectory(), fromRepository, toRepository);
}
}
jobMeta.setRepository(toRepository);
jobMeta.setMetaStore(toRepository.getMetaStore());
if (!isDirectoryExist(toRepository, jobPath)) {
toRepository.createRepositoryDirectory(toRepository.findDirectory("/"), jobPath);
}
saveJob(toRepository, jobMeta);
}
public static void transCopy(String transName, String transPath, Repository fromRepository, Repository toRepository) throws KettleException {
TransMeta tm = loadTrans(transName, transPath, fromRepository);
Iterator var6 = tm.getSteps().iterator();
while(var6.hasNext()) {
StepMeta sm = (StepMeta)var6.next();
if (sm.isJobExecutor()) {
JobExecutorMeta jem = (JobExecutorMeta)sm.getStepMetaInterface();
jobCopy(jem.getJobName(), jem.getDirectoryPath(), fromRepository, toRepository);
} else if (sm.getStepMetaInterface() instanceof TransExecutorMeta) {
TransExecutorMeta te = (TransExecutorMeta)sm.getStepMetaInterface();
transCopy(te.getTransName(), te.getDirectoryPath(), fromRepository, toRepository);
}
}
if (!isDirectoryExist(toRepository, transPath)) {
toRepository.createRepositoryDirectory(toRepository.findDirectory("/"), transPath);
}
tm.setRepository(toRepository);
tm.setMetaStore(toRepository.getMetaStore());
saveTrans(toRepository, tm);
}
public static ObjectId getJobId(String repoId, JobMeta jm) {
return getJobId(repoId, jm.getName(), jm.getRepositoryDirectory());
}
public static ObjectId getJobId(String repoId, String name, RepositoryDirectoryInterface repositoryDirectory) {
try {
testConnect(repoId);
return ((Repository)holder.get(repoId)).getJobId(name, repositoryDirectory);
} catch (KettleException var4) {
log.info("获取作业id失败", var4);
return null;
}
}
public static ObjectId getTransformationID(String repoId, TransMeta tm) {
return getTransformationID(repoId, tm.getName(), tm.getRepositoryDirectory());
}
public static ObjectId getTransformationID(String repoId, String name, RepositoryDirectoryInterface repositoryDirectory) {
try {
testConnect(repoId);
return ((Repository)holder.get(repoId)).getTransformationID(name, repositoryDirectory);
} catch (KettleException var4) {
log.info("获取转换id失败", var4);
return null;
}
}
public static void repairTransHop(TransMeta tm) {
for(int i = 0; i < tm.nrTransHops(); ++i) {
TransHopMeta hop = tm.getTransHop(i);
hop.setFromStep(tm.findStep(hop.getFromStep().getName()));
hop.setToStep(tm.findStep(hop.getToStep().getName()));
}
}
public static void setParams(NamedParams target, NamedParams source, Map<String, String> params) {
target.eraseParameters();
try {
String[] var6;
int var5 = (var6 = source.listParameters()).length;
for(int var4 = 0; var4 < var5; ++var4) {
String key = var6[var4];
String defaultVal = source.getParameterDefault(key);
if (params.containsKey(key)) {
defaultVal = (String)params.get(key);
}
target.addParameterDefinition(key, defaultVal, source.getParameterDescription(key));
}
} catch (Exception var8) {
log.error("保存JOB失败", var8);
}
}
public static void repairHop(JobMeta jm) {
Iterator var2 = jm.getJobhops().iterator();
while(var2.hasNext()) {
JobHopMeta hop = (JobHopMeta)var2.next();
hop.setFromEntry(jm.findJobEntry(hop.getFromEntry().getName()));
hop.setToEntry(jm.findJobEntry(hop.getToEntry().getName()));
}
}
public static String getProp(VariableSpace vs, String key) {
String value = vs.environmentSubstitute("${" + key + "}");
return value.startsWith("${") ? "" : value;
}
public static JSONObject getPropJSONObject(VariableSpace vs, String key) {
String value = getProp(vs, key);
return StringUtils.isNotBlank(value) ? JSON.parseObject(value) : null;
}
public static Job getRootJob(Job rootjob) {
while(rootjob != null && rootjob.getParentJob() != null) {
rootjob = rootjob.getParentJob();
}
return rootjob;
}
public static Job getRootJob(JobEntryBase jee) {
Job rootjob = jee.getParentJob();
return getRootJob(rootjob);
}
public static Job getRootJob(StepInterface si) {
Job rootjob = si.getTrans().getParentJob();
return getRootJob(rootjob);
}
public static String getRootJobId(JobEntryBase jee) {
return getRootJob(jee).getObjectId().getId();
}
public static String getRootJobId(StepInterface si) {
Job rootjob = getRootJob(si);
return rootjob != null ? rootjob.getObjectId().getId() : null;
}
public static String getRootJobName(StepInterface si) {
Job rootjob = getRootJob(si);
return rootjob != null ? rootjob.getObjectName() : null;
}
public static BufferedImage generateTransformationImage(TransMeta transMeta) throws Exception {
float magnification = 1.0F;
Point maximum = transMeta.getMaximum();
maximum.multiply(magnification);
SwingGC gc = new SwingGC((ImageObserver)null, maximum, 32, 0, 0);
TransPainter transPainter = new TransPainter(gc, transMeta, maximum, (ScrollBarInterface)null, (ScrollBarInterface)null, (TransHopMeta)null, (Point)null, (Rectangle)null, new ArrayList(), new ArrayList(), 32, 1, 0, 0, true, "Arial", 10);
transPainter.setMagnification(magnification);
transPainter.buildTransformationImage();
BufferedImage image = (BufferedImage)gc.getImage();
return image;
}
public static BufferedImage generateJobImage(JobMeta jobMeta) throws Exception {
float magnification = 1.0F;
Point maximum = jobMeta.getMaximum();
maximum.multiply(magnification);
SwingGC gc = new SwingGC((ImageObserver)null, maximum, 32, 0, 0);
JobPainter jobPainter = new JobPainter(gc, jobMeta, maximum, (ScrollBarInterface)null, (ScrollBarInterface)null, (JobHopMeta)null, (Point)null, (Rectangle)null, new ArrayList(), new ArrayList(), 32, 1, 0, 0, true, "Arial", 10);
jobPainter.setMagnification(magnification);
jobPainter.drawJob();
BufferedImage image = (BufferedImage)gc.getImage();
return image;
}
public static XJobStatus getJobStatus(Job job) {
String status = job.getStatus();
if (status.indexOf("errors") > -1) {
return XJobStatus.FAILED;
} else if (status.equals("Waiting")) {
return XJobStatus.PENDING;
} else if (status.equals("Halting")) {
return XJobStatus.HALTING;
} else if (status.equals("Running")) {
return XJobStatus.RUNNING;
} else if (status.equals("Stopped")) {
return XJobStatus.STOPPED;
} else {
return status.equalsIgnoreCase("Finished") ? XJobStatus.FINISHED : XJobStatus.UNKNOWN;
}
}
public static XTransStatus getTransStatus(Trans trans) {
String status = trans.getStatus();
if (status.indexOf("errors") > -1) {
return XTransStatus.FAILED;
} else if (status.equals("Waiting")) {
return XTransStatus.WAITING;
} else if (status.equals("Halting")) {
return XTransStatus.HALTING;
} else if (status.equals("Running")) {
return XTransStatus.RUNNING;
} else if (status.equals("Stopped")) {
return XTransStatus.STOPPED;
} else if (status.equals("Finished")) {
return XTransStatus.FINISHED;
} else if (status.equals("Paused")) {
return XTransStatus.PAUSED;
} else if (status.contains("Preparing")) {
return XTransStatus.PREPARING;
} else {
return status.equals("Initializing") ? XTransStatus.INITIALIZING : XTransStatus.UNKNOWN;
}
}
private static void testConnect(String repoId) {
Repository repository = (Repository)holder.get(repoId);
if (repository instanceof KettleDatabaseRepository) {
KettleDatabaseRepository kettleDatabaseRepository = (KettleDatabaseRepository)repository;
Database database = kettleDatabaseRepository.getDatabase();
Connection connection = database.getConnection();
try {
if (connection.isClosed()) {
holder.remove(repoId);
log.info("当前数据库连接已经关闭,准备重新连接.......");
DatabaseMeta databaseMeta = (DatabaseMeta)XRepoManager.databaseMeta.get("databaseMeta");
XRepoManager.createDBRepByDesc(repoId, repository.getName(), "资源库", databaseMeta.getName(), databaseMeta.getDatabaseTypeDesc(), "Native", databaseMeta.getHostname(), databaseMeta.getDatabaseName(), databaseMeta.getDatabasePortNumberString(), databaseMeta.getUsername(), databaseMeta.getPassword());
kettleDatabaseRepository = (KettleDatabaseRepository)connect(repoId, "admin", "admin");
if (null != repository) {
holder.put(repoId, kettleDatabaseRepository);
}
}
} catch (SQLException var6) {
log.error("数据库重连出现异常,{}", var6);
} catch (KettleException var7) {
log.error("数据库重连出现异常,{}", var7);
}
}
}
}

View File

@ -0,0 +1,85 @@
package com.ruoyi.kettle.tools;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Iterator;
import java.util.Map;
@Component
public class SpringContextUtil implements BeanFactoryPostProcessor, ApplicationContextAware {
private static ConfigurableListableBeanFactory beanFactory;
private static ApplicationContext context = null;
private SpringContextUtil() {
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(String beanName) {
return (T) beanFactory.getBean(beanName);
}
public static <T> T getBean(String beanName, Class<T> clazz) {
return beanFactory.getBean(beanName, clazz);
}
public static <T> T getBean(Class<T> clazz) {
T t = null;
Map<String, T> map = beanFactory.getBeansOfType(clazz);
Map.Entry entry;
for(Iterator var3 = map.entrySet().iterator(); var3.hasNext();
t = (T) entry.getValue()) {
entry = (Map.Entry)var3.next();
}
return t;
}
public static boolean containsBean(String beanName) {
return beanFactory.containsBean(beanName);
}
public static boolean isSingleton(String beanName) {
return beanFactory.isSingleton(beanName);
}
public static Class getType(String beanName) {
return beanFactory.getType(beanName);
}
public static HttpServletResponse getResponse() {
return getServletRequestAttributes().getResponse();
}
public static HttpServletRequest getRequest() {
return getServletRequestAttributes().getRequest();
}
public static ServletRequestAttributes getServletRequestAttributes() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes)requestAttributes;
}
public static HttpSession getSession() {
return getRequest().getSession();
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
beanFactory = configurableListableBeanFactory;
}
}

View File

@ -0,0 +1,141 @@
<?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.ruoyi.kettle.mapper.KettleJobMapper">
<resultMap type="KettleJob" id="KettleJobResult">
<result property="id" column="id" />
<result property="createdTime" column="created_time" />
<result property="updateTime" column="update_time" />
<result property="createdBy" column="created_by" />
<result property="updateBy" column="update_by" />
<result property="jobName" column="job_name" />
<result property="jobDescription" column="job_description" />
<result property="jobType" column="job_type" />
<result property="jobPath" column="job_path" />
<result property="jobRepositoryId" column="job_repository_id" />
<result property="jobLogLevel" column="job_log_level" />
<result property="jobStatus" column="job_status" />
<result property="isDel" column="is_del" />
<result property="isMonitorEnabled" column="is_monitor_enabled" />
<result property="roleKey" column="role_key" />
<result property="tplKey" column="tpl_key" />
</resultMap>
<sql id="selectKettleJobVo">
select id, created_time, update_time, created_by, update_by, job_name, job_description, job_type, job_path, job_repository_id, job_log_level, job_status, is_del, is_monitor_enabled, role_key, tpl_key from kettle_job
</sql>
<select id="selectKettleJobList" parameterType="KettleJob" resultMap="KettleJobResult">
<include refid="selectKettleJobVo"/>
<where>
<if test="kettleJob.createdTime != null "> and created_time = #{kettleJob.createdTime}</if>
<if test="kettleJob.updateTime != null "> and update_time = #{kettleJob.updateTime}</if>
<if test="kettleJob.createdBy != null and kettleJob.createdBy != ''"> and created_by = #{kettleJob.createdBy}</if>
<if test="kettleJob.updateBy != null and kettleJob.updateBy != ''"> and update_by = #{kettleJob.updateBy}</if>
<if test="kettleJob.jobName != null and kettleJob.jobName != ''"> and job_name like concat('%', #{kettleJob.jobName}, '%')</if>
<if test="kettleJob.jobDescription != null and kettleJob.jobDescription != ''"> and job_description = #{kettleJob.jobDescription}</if>
<if test="kettleJob.jobType != null and kettleJob.jobType != ''"> and job_type = #{kettleJob.jobType}</if>
<if test="kettleJob.jobPath != null and kettleJob.jobPath != ''"> and job_path = #{kettleJob.jobPath}</if>
<if test="kettleJob.jobRepositoryId != null "> and job_repository_id = #{kettleJob.jobRepositoryId}</if>
<if test="kettleJob.jobLogLevel != null and kettleJob.jobLogLevel != ''"> and job_log_level = #{kettleJob.jobLogLevel}</if>
<if test="kettleJob.jobStatus != null and kettleJob.jobStatus != ''"> and job_status = #{kettleJob.jobStatus}</if>
<if test="kettleJob.isDel != null "> and is_del = #{isDel}</if>
<if test="kettleJob.isMonitorEnabled != null "> and is_monitor_enabled = #{kettleJob.isMonitorEnabled}</if>
<if test="roleKey != null ">
and
<foreach collection="roleKey" item="item" open="(" close=")" separator=" or " >
role_key like concat('%',#{item}, '%')
</foreach>
</if>
and (is_del != 1 or is_del is null)
</where>
</select>
<select id="checkQuartzExist" parameterType="String" resultType="Long">
select job_id from sys_job where invoke_target = #{checkStr} and job_group='KETTLE'
</select>
<select id="selectKettleJobById" parameterType="Long" resultMap="KettleJobResult">
<include refid="selectKettleJobVo"/>
where id = #{id}
</select>
<select id="selectJobByNameAndRepoId" resultType="int">
select count(*) from kettle_job where job_name = #{jobName} and job_repository_id=#{jobRepositoryId}
</select>
<select id="queryJobLog" parameterType="String" resultType="String">
select log_field from kettle_job_log where jobname=#{jobName} order by id_job asc
</select>
<insert id="insertKettleJob" parameterType="KettleJob" useGeneratedKeys="true" keyProperty="id">
insert into kettle_job
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="createdTime != null">created_time,</if>
<if test="updateTime != null">update_time,</if>
<if test="createdBy != null">created_by,</if>
<if test="updateBy != null">update_by,</if>
<if test="jobName != null and jobName != ''">job_name,</if>
<if test="jobDescription != null">job_description,</if>
<if test="jobType != null">job_type,</if>
<if test="jobPath != null">job_path,</if>
<if test="jobRepositoryId != null">job_repository_id,</if>
<if test="jobLogLevel != null">job_log_level,</if>
<if test="jobStatus != null">job_status,</if>
<if test="isDel != null">is_del,</if>
<if test="isMonitorEnabled != null">is_monitor_enabled,</if>
<if test="roleKey != null">role_key,</if>
<if test="tplKey != null">tpl_key,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="createdTime != null">#{createdTime},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="createdBy != null">#{createdBy},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="jobName != null and jobName != ''">#{jobName},</if>
<if test="jobDescription != null">#{jobDescription},</if>
<if test="jobType != null">#{jobType},</if>
<if test="jobPath != null">#{jobPath},</if>
<if test="jobRepositoryId != null">#{jobRepositoryId},</if>
<if test="jobLogLevel != null">#{jobLogLevel},</if>
<if test="jobStatus != null">#{jobStatus},</if>
<if test="isDel != null">#{isDel},</if>
<if test="isMonitorEnabled != null">#{isMonitorEnabled},</if>
<if test="roleKey != null">#{roleKey},</if>
<if test="tplKey != null">#{tplKey},</if>
</trim>
</insert>
<update id="updateKettleJob" parameterType="KettleJob">
update kettle_job
<trim prefix="SET" suffixOverrides=",">
<if test="createdTime != null">created_time = #{createdTime},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="createdBy != null">created_by = #{createdBy},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="jobName != null and jobName != ''">job_name = #{jobName},</if>
<if test="jobDescription != null">job_description = #{jobDescription},</if>
<if test="jobType != null">job_type = #{jobType},</if>
<if test="jobPath != null">job_path = #{jobPath},</if>
<if test="jobRepositoryId != null">job_repository_id = #{jobRepositoryId},</if>
<if test="jobLogLevel != null">job_log_level = #{jobLogLevel},</if>
<if test="jobStatus != null">job_status = #{jobStatus},</if>
<if test="isDel != null">is_del = #{isDel},</if>
<if test="isMonitorEnabled != null">is_monitor_enabled = #{isMonitorEnabled},</if>
<if test="roleKey != null">role_key = #{roleKey},</if>
<if test="tplKey != null">tpl_key = #{tplKey},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteKettleJobById" parameterType="Long">
delete from kettle_job where id = #{id}
</delete>
<delete id="deleteKettleJobByIds" parameterType="String">
delete from kettle_job where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,144 @@
<?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.ruoyi.kettle.mapper.KettleTransMapper">
<resultMap type="KettleTrans" id="KettleTransResult">
<result property="id" column="id" />
<result property="transName" column="trans_name" />
<result property="transDescription" column="trans_description" />
<result property="createdTime" column="created_time" />
<result property="updateTime" column="update_time" />
<result property="createdBy" column="created_by" />
<result property="updateBy" column="update_by" />
<result property="transType" column="trans_type" />
<result property="transPath" column="trans_path" />
<result property="transRepositoryId" column="trans_repository_id" />
<result property="transLogLevel" column="trans_log_level" />
<result property="transStatus" column="trans_status" />
<result property="isDel" column="is_del" />
<result property="isMonitorEnabled" column="is_monitor_enabled" />
<result property="tplKey" column="tpl_key" />
<result property="roleKey" column="role_key" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectKettleTransVo">
select id, trans_name, trans_description, created_time, update_time, created_by, update_by, trans_type, trans_path, trans_repository_id, trans_log_level, trans_status, is_del, is_monitor_enabled, tpl_key, role_key, remark from kettle_trans
</sql>
<select id="selectKettleTransList" parameterType="KettleTrans" resultMap="KettleTransResult">
<include refid="selectKettleTransVo"/>
<where>
<if test="KettleTrans.transName != null and KettleTrans.transName != ''"> and trans_name like concat('%', #{KettleTrans.transName}, '%')</if>
<if test="KettleTrans.transDescription != null and KettleTrans.transDescription != ''"> and trans_description = #{KettleTrans.transDescription}</if>
<if test="KettleTrans.transPath != null and KettleTrans.transPath != ''"> and trans_path = #{KettleTrans.transPath}</if>
<if test="KettleTrans.transRepositoryId != null "> and trans_repository_id = #{KettleTrans.transRepositoryId}</if>
<if test="KettleTrans.transLogLevel != null and KettleTrans.transLogLevel != ''"> and trans_log_level = #{KettleTrans.transLogLevel}</if>
<if test="KettleTrans.transStatus != null and KettleTrans.transStatus != ''"> and trans_status = #{KettleTrans.transStatus}</if>
<if test="KettleTrans.isMonitorEnabled != null "> and is_monitor_enabled = #{KettleTrans.isMonitorEnabled}</if>
<if test="roleKey != null ">
and
<foreach collection="roleKey" item="item" open="(" close=")" separator=" or " >
role_key like concat('%',#{item}, '%')
</foreach>
</if>
and is_del != 1
</where>
</select>
<select id="selectKettleTransById" parameterType="Long" resultMap="KettleTransResult">
<include refid="selectKettleTransVo"/>
where id = #{id}
</select>
<select id="selectKettleTransByTransName" parameterType="String" resultType="int">
select count(*) from kettle_trans where trans_name = #{transName}
</select>
<select id="checkQuartzExist" parameterType="String" resultType="Long">
select job_id from sys_job where invoke_target = #{checkStr} and job_group='KETTLE'
</select>
<select id="queryTransLog" parameterType="String" resultType="String">
select log_field from kettle_trans_log where transname=#{transName} order by id_batch asc
</select>
<!-- <select id="selectKettleTransByTransName" parameterType="Long" resultMap="KettleTransResult">
<include refid="selectKettleTransVo"/>
where trans_name = #{id}
</select>-->
<insert id="insertKettleTrans" parameterType="KettleTrans" useGeneratedKeys="true" keyProperty="id">
insert into kettle_trans
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="transName != null and transName != ''">trans_name,</if>
<if test="transDescription != null">trans_description,</if>
<if test="createdTime != null">created_time,</if>
<if test="updateTime != null">update_time,</if>
<if test="createdBy != null">created_by,</if>
<if test="updateBy != null">update_by,</if>
<if test="transType != null">trans_type,</if>
<if test="transPath != null">trans_path,</if>
<if test="transRepositoryId != null">trans_repository_id,</if>
<if test="transLogLevel != null">trans_log_level,</if>
<if test="transStatus != null">trans_status,</if>
<if test="isDel != null">is_del,</if>
<if test="isMonitorEnabled != null">is_monitor_enabled,</if>
<if test="tplKey != null">tpl_key,</if>
<if test="roleKey != null">role_key,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="transName != null and transName != ''">#{transName},</if>
<if test="transDescription != null">#{transDescription},</if>
<if test="createdTime != null">#{createdTime},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="createdBy != null">#{createdBy},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="transType != null">#{transType},</if>
<if test="transPath != null">#{transPath},</if>
<if test="transRepositoryId != null">#{transRepositoryId},</if>
<if test="transLogLevel != null">#{transLogLevel},</if>
<if test="transStatus != null">#{transStatus},</if>
<if test="isDel != null">#{isDel},</if>
<if test="isMonitorEnabled != null">#{isMonitorEnabled},</if>
<if test="tplKey != null">#{tplKey},</if>
<if test="roleKey != null">#{roleKey},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateKettleTrans" parameterType="KettleTrans">
update kettle_trans
<trim prefix="SET" suffixOverrides=",">
<if test="transName != null and transName != ''">trans_name = #{transName},</if>
<if test="transDescription != null">trans_description = #{transDescription},</if>
<if test="createdTime != null">created_time = #{createdTime},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="createdBy != null">created_by = #{createdBy},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="transType != null">trans_type = #{transType},</if>
<if test="transPath != null">trans_path = #{transPath},</if>
<if test="transRepositoryId != null">trans_repository_id = #{transRepositoryId},</if>
<if test="transLogLevel != null">trans_log_level = #{transLogLevel},</if>
<if test="transStatus != null">trans_status = #{transStatus},</if>
<if test="isDel != null">is_del = #{isDel},</if>
<if test="isMonitorEnabled != null">is_monitor_enabled = #{isMonitorEnabled},</if>
<if test="tplKey != null">tpl_key = #{tplKey},</if>
<if test="roleKey != null">role_key = #{roleKey},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteKettleTransById" parameterType="Long">
delete from kettle_trans where id = #{id}
</delete>
<delete id="deleteKettleTransByIds" parameterType="String">
delete from kettle_trans where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,148 @@
<?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.ruoyi.kettle.mapper.XRepositoryMapper">
<resultMap type="XRepository" id="XRepositoryResult">
<result property="id" column="id" />
<result property="repoId" column="repo_id" />
<result property="repoName" column="repo_name" />
<result property="repoUsername" column="repo_username" />
<result property="repoPassword" column="repo_password" />
<result property="repoType" column="repo_type" />
<result property="dbAccess" column="db_access" />
<result property="dbHost" column="db_host" />
<result property="dbPort" column="db_port" />
<result property="dbName" column="db_name" />
<result property="dbUsername" column="db_username" />
<result property="dbPassword" column="db_password" />
<result property="isDel" column="is_del" />
<result property="createdTime" column="created_time" />
<result property="updateTime" column="update_time" />
<result property="createdBy" column="created_by" />
<result property="updateBy" column="update_by" />
<result property="type" column="type" />
<result property="baseDir" column="base_dir" />
</resultMap>
<sql id="selectXRepositoryVo">
select id, repo_id, repo_name, repo_username, repo_password, repo_type, db_access, db_host, db_port, db_name, db_username, db_password, is_del, created_time, update_time, created_by, update_by, type, base_dir from kettle_repository
</sql>
<select id="selectXRepositoryList" parameterType="XRepository" resultMap="XRepositoryResult">
<include refid="selectXRepositoryVo"/>
<where>
<if test="repoId != null and repoId != ''"> and repo_id = #{repoId}</if>
<if test="repoName != null and repoName != ''"> and repo_name like concat('%', #{repoName}, '%')</if>
<if test="repoUsername != null and repoUsername != ''"> and repo_username like concat('%', #{repoUsername}, '%')</if>
<if test="repoPassword != null and repoPassword != ''"> and repo_password = #{repoPassword}</if>
<if test="repoType != null and repoType != ''"> and repo_type = #{repoType}</if>
<if test="dbAccess != null and dbAccess != ''"> and db_access = #{dbAccess}</if>
<if test="dbHost != null and dbHost != ''"> and db_host = #{dbHost}</if>
<if test="dbPort != null and dbPort != ''"> and db_port = #{dbPort}</if>
<if test="dbName != null and dbName != ''"> and db_name like concat('%', #{dbName}, '%')</if>
<if test="dbUsername != null and dbUsername != ''"> and db_username like concat('%', #{dbUsername}, '%')</if>
<if test="dbPassword != null and dbPassword != ''"> and db_password = #{dbPassword}</if>
<if test="createdTime != null "> and created_time = #{createdTime}</if>
<if test="createdBy != null and createdBy != ''"> and created_by = #{createdBy}</if>
<if test="type != null and type != ''"> and type = #{type}</if>
<if test="baseDir != null and baseDir != ''"> and base_dir = #{baseDir}</if>
and is_del != 1
</where>
</select>
<select id="selectXRepositoryById" parameterType="Long" resultMap="XRepositoryResult">
<include refid="selectXRepositoryVo"/>
where id = #{id}
</select>
<insert id="insertXRepository" parameterType="XRepository" useGeneratedKeys="true" keyProperty="id">
insert into kettle_repository
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="repoId != null and repoId != ''">repo_id,</if>
<if test="repoName != null">repo_name,</if>
<if test="repoUsername != null">repo_username,</if>
<if test="repoPassword != null">repo_password,</if>
<if test="repoType != null">repo_type,</if>
<if test="dbAccess != null">db_access,</if>
<if test="dbHost != null">db_host,</if>
<if test="dbPort != null">db_port,</if>
<if test="dbName != null">db_name,</if>
<if test="dbUsername != null">db_username,</if>
<if test="dbPassword != null">db_password,</if>
<if test="isDel != null">is_del,</if>
<if test="createdTime != null">created_time,</if>
<if test="updateTime != null">update_time,</if>
<if test="createdBy != null">created_by,</if>
<if test="updateBy != null">update_by,</if>
<if test="type != null">type,</if>
<if test="baseDir != null">base_dir,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="repoId != null and repoId != ''">#{repoId},</if>
<if test="repoName != null">#{repoName},</if>
<if test="repoUsername != null">#{repoUsername},</if>
<if test="repoPassword != null">#{repoPassword},</if>
<if test="repoType != null">#{repoType},</if>
<if test="dbAccess != null">#{dbAccess},</if>
<if test="dbHost != null">#{dbHost},</if>
<if test="dbPort != null">#{dbPort},</if>
<if test="dbName != null">#{dbName},</if>
<if test="dbUsername != null">#{dbUsername},</if>
<if test="dbPassword != null">#{dbPassword},</if>
<if test="isDel != null">#{isDel},</if>
<if test="createdTime != null">#{createdTime},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="createdBy != null">#{createdBy},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="type != null">#{type},</if>
<if test="baseDir != null">#{baseDir},</if>
</trim>
</insert>
<update id="updateXRepository" parameterType="XRepository">
update kettle_repository
<trim prefix="SET" suffixOverrides=",">
<if test="repoId != null and repoId != ''">repo_id = #{repoId},</if>
<if test="repoName != null">repo_name = #{repoName},</if>
<if test="repoUsername != null">repo_username = #{repoUsername},</if>
<if test="repoPassword != null">repo_password = #{repoPassword},</if>
<if test="repoType != null">repo_type = #{repoType},</if>
<if test="dbAccess != null">db_access = #{dbAccess},</if>
<if test="dbHost != null">db_host = #{dbHost},</if>
<if test="dbPort != null">db_port = #{dbPort},</if>
<if test="dbName != null">db_name = #{dbName},</if>
<if test="dbUsername != null">db_username = #{dbUsername},</if>
<if test="dbPassword != null">db_password = #{dbPassword},</if>
<if test="isDel != null">is_del = #{isDel},</if>
<if test="createdTime != null">created_time = #{createdTime},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="createdBy != null">created_by = #{createdBy},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="type != null">type = #{type},</if>
<if test="baseDir != null">base_dir = #{baseDir},</if>
</trim>
where id = #{id}
</update>
<update id="updateIsDel" parameterType="Long" >
update kettle_repository set is_del=1 where id = #{id}
</update>
<update id="updateIsDelBatch" parameterType="String">
update kettle_repository set is_del=1 where id IN
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</update>
<delete id="deleteXRepositoryById" parameterType="Long">
delete from kettle_repository where id = #{id}
</delete>
<delete id="deleteXRepositoryByIds" parameterType="String">
delete from kettle_repository where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('资源库选择')" />
<th:block th:include="include :: ztree-css" />
</head>
<style>
body{height:auto;font-family: "Microsoft YaHei";}
button{font-family: "SimSun","Helvetica Neue",Helvetica,Arial;}
</style>
<body class="hold-transition box box-main">
<input id="treeId" name="treeId" type="hidden" />
<input id="treeName" name="treeName" type="hidden" />
<input id="transPath" name="transPath" type="hidden" />
<input id="transRepositoryId" name="transRepositoryId" type="hidden" />
<div class="wrapper"><div class="treeShowHideButton" onclick="$.tree.toggleSearch();">
<label id="btnShow" title="显示搜索" style="display:none;"></label>
<label id="btnHide" title="隐藏搜索"></label>
</div>
<div class="treeSearchInput" id="search">
<label for="keyword">关键字:</label><input type="text" class="empty" id="keyword" maxlength="50">
<button class="btn" id="btn" onclick="$.tree.searchNode()"> 搜索 </button>
</div>
<div class="treeExpandCollapse">
<a href="#" onclick="$.tree.expand()">展开</a> /
<a href="#" onclick="$.tree.collapse()">折叠</a>
</div>
<div id="tree" class="ztree treeselect"></div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: ztree-js" />
<script th:inline="javascript">
var prefix = ctx + "kettle/repository"
var deptId = [[${deptId}]];
var excludeId = [[${excludeId}]];
$(function() {
var url = $.common.isEmpty(excludeId) ? prefix + "/repositoryRoot": prefix + "/repositoryRoot/" + excludeId;
var options = {
url: url,
expandLevel: 2,
onClick : zOnClick
};
$.tree.init(options);
});
function zOnClick(event, treeId, treeNode) {
var treeId = treeNode.id;
var treeName = treeNode.name;
var path=treeNode.title;
$("#treeId").val(treeId);
$("#treeName").val(treeName);
$("#transPath").val(path);
if(/^[0-9]+.?[0-9]*$/.test(treeId)){
$("#transRepositoryId").val(treeId);
}
console.log("pathpathpathpath::"+path);
var treeObj = $.fn.zTree.getZTreeObj( "tree");
var selectedNode = treeObj .getSelectedNodes();
if(/^[0-9]+.?[0-9]*$/.test(treeId) && !selectedNode[0].isParent){
console.log("进来了");
qryRepoSubTree(treeId);
return true;
}
}
function qryRepoSubTree(treeId){
$.ajax({
type: 'POST',
url: prefix+ "/qryRepoSubTree/"+treeId,
//data: {"id":treeId},
contentType: "application/json",
dataType: "json",
success: function (data) {
var treeObj = $.fn.zTree.getZTreeObj( "tree");
var selectedNode = treeObj .getSelectedNodes();
treeObj.addNodes(selectedNode[ 0], data);
},
error: function (e){
alert("error");
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增作业调度')" />
<th:block th:include="include :: datetimepicker-css" />
<th:block th:include="include :: select2-css" />
<th:block th:include="include :: bootstrap-select-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-job-add">
<input name="jobRepositoryId" class="form-control" type="hidden" id="jobRepositoryId" required>
<div class="form-group">
<label class="col-sm-3 control-label is-required">选择转换:</label>
<div class="col-sm-8">
<input name="jobName" class="form-control" type="text" id="treeName" onclick="chooseJob();" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">描述:</label>
<div class="col-sm-8">
<textarea name="jobDescription" class="form-control"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">作业类型(file,ftp,sf)</label>
<div class="col-sm-8">
<select name="jobType" class="form-control m-b" th:with="type=${@dict.getType('repository_type')}" disabled="disabled">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">路径:</label>
<div class="col-sm-8">
<input name="jobPath" id="jobPath" class="form-control" type="text" required readonly>
</div>
</div>
<!-- <div class="form-group">
<label class="col-sm-3 control-label">资源库id</label>
<div class="col-sm-8">
<input name="jobRepositoryId" class="form-control" type="text">
</div>
</div>-->
<div class="form-group">
<label class="col-sm-3 control-label">日志级别:</label>
<div class="col-sm-8">
<select name="jobLogLevel" class="form-control m-b" th:with="type=${@dict.getType('kettle_log_level')}" >
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">角色key:</label>
<div class="col-sm-8">
<select class="form-control noselect2 selectpicker m-b" name="roleKey" data-none-selected-text="可以执行该转换的角色组合" multiple >
<option th:each="allRoles:${allRoles}" th:value="${allRoles}" th:text="${allRoles}" ></option>
</select>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<th:block th:include="include :: select2-js" />
<th:block th:include="include :: bootstrap-select-js" />
<script th:inline="javascript">
var prefix = ctx + "kettle/job"
$("#form-job-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-job-add').serialize());
}
}
$("input[name='createdTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
function chooseJob(){
var treeId = $("#treeId").val();
//var repoid = $.common.isEmpty(treeId) ? "999999" : $("#treeId").val();
var url = ctx + "kettle/repository/selectRepositoryTree/"
var options = {
title: '选择资源库',
width: "380",
url: url,
callBack: doSubmit
};
$.modal.openOptions(options);
}
function doSubmit(index, layero){
var tree = layero.find("iframe")[0].contentWindow.$._tree;
var body = layer.getChildFrame('body', index);
$("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val());
$("#jobRepositoryId").val(body.find('#transRepositoryId').val());
$("#jobPath").val(body.find('#transPath').val());
layer.close(index);
}
</script>
</body>
</html>

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('转换执行日志')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-expsubspushresp-detail" th:object="${kettleJob}">
<input name="id" th:field="*{id}" type="hidden">
<div class="form-group">
<!-- <label class="col-sm-3 control-label">运行日志:</label>
<div class="col-sm-8">
<span name="transName" id="transName" class="form-control" th:text="*{transName}" ></span>
</div>-->
<textarea name="transLog" class="textarea-inherit" th:text="${jobLog}" type="text" rows="30"></textarea>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "kettle/trans";
$(function (){
});
</script>
</body>
<style>
.textarea-inherit {
width: 100%;
height: auto;
overflow: auto;
word-break: break-all; //解决兼容问题
}
</style>
</html>

View File

@ -0,0 +1,90 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改转换')" />
<th:block th:include="include :: datetimepicker-css" />
<th:block th:include="include :: select2-css" />
<th:block th:include="include :: bootstrap-select-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-job-edit" th:object="${kettleJob}">
<input name="id" th:field="*{id}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label is-required">作业名称:</label>
<div class="col-sm-8">
<input name="jobName" th:field="*{jobName}" class="form-control" type="text" readonly required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">描述:</label>
<div class="col-sm-8">
<textarea name="jobDescription" class="form-control">[[*{jobDescription}]]</textarea>
</div>
</div>
<!--<div class="form-group">
<label class="col-sm-3 control-label">作业类型(file,ftp,sf)</label>
<div class="col-sm-8">
<select name="jobType" class="form-control m-b" th:with="type=${@dict.getType('repository_type')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{jobType}"></option>
</select>
</div>
</div>-->
<div class="form-group">
<label class="col-sm-3 control-label">路径:</label>
<div class="col-sm-8">
<input name="jobPath" th:field="*{jobPath}" class="form-control" type="text" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">日志级别:</label>
<div class="col-sm-8">
<select name="jobLogLevel" class="form-control m-b" th:with="type=${@dict.getType('kettle_log_level')}" th:field="*{jobLogLevel}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" ></option>
</select>
</div>
</div>
<!-- <div class="form-group">
<label class="col-sm-3 control-label">是否监控:</label>
<div class="col-sm-8">
<label class="radio-box">
<input type="radio" checked="" value=1 id="optionsRadios1" name="isMonitorEnabled" th:checked="${kettleJob.isMonitorEnabled == 1 ? true : false}"></label>
<label class="radio-box">
<input type="radio" value=0 id="optionsRadios2" name="isMonitorEnabled" th:checked="${kettleJob.isMonitorEnabled == 0 ? true : false}"></label>
</div>
</div>-->
<div class="form-group">
<label class="col-sm-3 control-label">角色key:</label>
<div class="col-sm-8">
<select class="form-control noselect2 selectpicker m-b " name="roleKey" data-none-selected-text="可以执行该转换的角色组合" multiple >
<option th:each="allRoles:${allRoles}" th:value="${allRoles}" th:text="${allRoles}" ></option>
</select>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<th:block th:include="include :: select2-js" />
<th:block th:include="include :: bootstrap-select-js" /> <script th:inline="javascript">
var prefix = ctx + "kettle/job";
var rkArray = [[${rkArray}]];
$('.selectpicker').selectpicker('val',rkArray);
$("#form-job-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-job-edit').serialize());
}
}
$("input[name='createdTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
</script>
</body>
</html>

View File

@ -0,0 +1,160 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('作业调度列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>作业名称:</label>
<input type="text" name="jobName"/>
</li>
<!-- <li>
<label>作业类型:</label>
<select name="jobType" th:with="type=${@dict.getType('repository_type')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>-->
<li>
<label>状态:</label>
<select name="jobStatus" th:with="type=${@dict.getType('kettle_trans_status')}" >
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" ></option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="kettle:job:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="kettle:job:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="kettle:job:remove">
<i class="fa fa-remove"></i> 删除
</a>
<!-- <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="kettle:job:export">
<i class="fa fa-download"></i> 导出
</a>-->
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('kettle:job:edit')}]];
var removeFlag = [[${@permission.hasPermi('kettle:job:remove')}]];
var jobTypeDatas = [[${@dict.getType('repository_type')}]];
var logFlag=[[${@permission.hasPermi('kettle:job:log')}]];
var runFlag=[[${@permission.hasPermi('kettle:job:run')}]];
var quartzFlag=[[${@permission.hasPermi('kettle:job:setquartz')}]];
var prefix = ctx + "kettle/job";
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
detailUrl: prefix + "/detail/{id}",
modalName: "作业调度",
columns: [{
checkbox: true
},
{
field: 'id',
title: '',
visible: false
},
{
field: 'jobName',
title: '作业名称'
},
{
field: 'jobDescription',
title: '描述'
},
/* {
field: 'jobType',
title: '作业类型(file,ftp,sf)',
formatter: function(value, row, index) {
return $.table.selectDictLabel(jobTypeDatas, value);
}
},*/
{
field: 'jobPath',
title: '路径'
},
/* {
field: 'jobRepositoryId',
title: '资源库id'
},*/
{
field: 'jobLogLevel',
title: '日志级别'
},
{
field: 'jobStatus',
title: '状态'
},
/* {
field: 'isDel',
title: '是否删除'
},
{
field: 'isMonitorEnabled',
title: '是否监控'
},*/
{
field: 'roleKey',
title: '可执行角色'
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
actions.push("<a class='btn btn-default btn-xs " + runFlag + "' href='javascript:void(0)' onclick='runJobNow(" + row.id + ")'><i class='fa fa-play-circle-o'></i>立即运行</a> ");
actions.push("<a class='btn btn-default btn-xs " + quartzFlag + "' href='javascript:void(0)' onclick='setJobQuartz(" + row.id + ")'><i class='glyphicon glyphicon-time'></i>设置定时</a>");
// actions.push("<a class='btn btn-default btn-xs " + logFlag + "' href='javascript:void(0)' onclick='$.operate.detail(" + row.id + ")'><i class='fa fa-search'></i>运行日志</a> ");
actions.push('<a class="btn btn-default btn-xs ' + logFlag + '" href="javascript:void(0)" onclick="$.operate.detail(\'' + row.id + '\')"><i class="fa fa-search"></i>运行日志</a> ');
return actions.join('');
}
}]
};
$.table.init(options);
});
/* 立即执行一次trans */
function runJobNow(id) {
$.modal.confirm("确认要立即执行一次该作业吗?", function() {
$.operate.post(prefix + "/run", { "id": id});
})
}
/*设置定时任务*/
function setJobQuartz(id){
$.modal.open('添加定时任务', prefix + "/jobQuartz/"+id, '900', '500');
}
</script>
</body>
</html>

View File

@ -0,0 +1,107 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增定时任务')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-job-add">
<input type="hidden" name="createBy" th:value="${@permission.getPrincipalProperty('loginName')}">
<div class="form-group">
<label class="col-sm-3 control-label is-required">任务名称:</label>
<div class="col-sm-8">
<input class="form-control" type="text" name="jobName" id="jobName" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">任务分组:</label>
<div class="col-sm-8">
<select name="jobGroup" class="form-control m-b selectpicker" th:with="type=${@dict.getType('sys_job_group')}" >
<option th:each="dict : ${type}" th:selected="${dict.dictValue=='KETTLE'}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">调用目标字符串:</label>
<div class="col-sm-8">
<!-- kettleTransServiceImpl.runTransQuartz() -->
<input class="form-control" type="text" name="invokeTarget" id="invokeTarget" readonly required
th:value="${invokeTarget}" >
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">cron表达式</label>
<div class="col-sm-8">
<input class="form-control" type="text" name="cronExpression" id="cronExpression" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">执行策略:</label>
<div class="col-sm-8">
<label class="radio-box"> <input type="radio" name="misfirePolicy" value="1" th:checked="true"/> 立即执行 </label>
<label class="radio-box"> <input type="radio" name="misfirePolicy" value="2" /> 执行一次 </label>
<label class="radio-box"> <input type="radio" name="misfirePolicy" value="3" /> 放弃执行 </label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">并发执行:</label>
<div class="col-sm-8">
<label class="radio-box"> <input type="radio" name="concurrent" value="0"/> 允许 </label>
<label class="radio-box"> <input type="radio" name="concurrent" value="1" th:checked="true"/> 禁止 </label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_job_status')}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">备注:</label>
<div class="col-sm-8">
<textarea id="remark" name="remark" class="form-control"></textarea>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
var prefix = ctx + "monitor/job";
$("#form-job-add").validate({
onkeyup: false,
rules:{
cronExpression:{
remote: {
url: prefix + "/checkCronExpressionIsValid",
type: "post",
dataType: "json",
data: {
"cronExpression": function() {
return $.common.trim($("#cronExpression").val());
}
},
dataFilter: function(data, type) {
return data;
}
}
},
},
messages: {
"cronExpression": {
remote: "表达式不正确"
}
},
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-job-add').serialize());
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改定时任务')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-job-edit" th:object="${job}">
<input id="jobId" name="jobId" type="hidden" th:field="*{jobId}"/>
<input type="hidden" name="updateBy" th:value="${@permission.getPrincipalProperty('loginName')}">
<div class="form-group">
<label class="col-sm-3 control-label is-required">任务名称:</label>
<div class="col-sm-8">
<input class="form-control" type="text" name="jobName" id="jobName" th:field="*{jobName}" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">任务分组:</label>
<div class="col-sm-8">
<select name="jobGroup" class="form-control m-b" th:with="type=${@dict.getType('sys_job_group')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{jobGroup}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">调用目标字符串:</label>
<div class="col-sm-8">
<input class="form-control" type="text" name="invokeTarget" id="invokeTarget" th:field="*{invokeTarget}" required readonly >
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">cron表达式</label>
<div class="col-sm-8">
<input class="form-control" type="text" name="cronExpression" id="cronExpression" th:field="*{cronExpression}" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">执行策略:</label>
<div class="col-sm-8">
<label class="radio-box"> <input type="radio" th:field="*{misfirePolicy}" name="misfirePolicy" value="1" /> 立即执行 </label>
<label class="radio-box"> <input type="radio" th:field="*{misfirePolicy}" name="misfirePolicy" value="2" /> 执行一次 </label>
<label class="radio-box"> <input type="radio" th:field="*{misfirePolicy}" name="misfirePolicy" value="3" /> 放弃执行 </label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">并发执行:</label>
<div class="col-sm-8">
<label class="radio-box"> <input type="radio" th:field="*{concurrent}" name="concurrent" value="0"/> 允许 </label>
<label class="radio-box"> <input type="radio" th:field="*{concurrent}" name="concurrent" value="1"/> 禁止 </label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_job_status')}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:field="*{status}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">备注:</label>
<div class="col-sm-8">
<textarea id="remark" name="remark" class="form-control">[[*{remark}]]</textarea>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
var prefix = ctx + "monitor/job";
$("#form-job-edit").validate({
onkeyup: false,
rules:{
cronExpression:{
required:true,
remote: {
url: prefix + "/checkCronExpressionIsValid",
type: "post",
dataType: "json",
data: {
"cronExpression": function() {
return $.common.trim($("#cronExpression").val());
}
},
dataFilter: function(data, type) {
return data;
}
}
},
},
messages: {
"cronExpression": {
remote: "表达式不正确"
}
},
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-job-edit').serialize());
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,135 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增资源库')" />
<th:block th:include="include :: datetimepicker-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-repository-add">
<div class="form-group">
<label class="col-sm-3 control-label">资源库名称:</label>
<div class="col-sm-8">
<input name="repoName" class="form-control" type="text">
</div>
</div>
<!--<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的用户名</label>
<div class="col-sm-8">
<input name="repoUsername" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的密码</label>
<div class="col-sm-8">
<input name="repoPassword" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">db类型</label>
<div class="col-sm-8">
<select name="repoType" class="form-control m-b">
<option value="">所有</option>
</select>
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 代码生成请选择字典属性</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的连接类型</label>
<div class="col-sm-8">
<input name="dbAccess" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的ip</label>
<div class="col-sm-8">
<input name="dbHost" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的端口</label>
<div class="col-sm-8">
<input name="dbPort" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的db库名</label>
<div class="col-sm-8">
<input name="dbName" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的db用户名</label>
<div class="col-sm-8">
<input name="dbUsername" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的db用户密码</label>
<div class="col-sm-8">
<input name="dbPassword" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">软删除:</label>
<div class="col-sm-8">
<input name="isDel" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-8">
<div class="input-group date">
<input name="createdTime" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-8">
<input name="createdBy" class="form-control" type="text">
</div>
</div>-->
<div class="form-group">
<label class="col-sm-3 control-label">资源库类型:</label>
<div class="col-sm-8">
<!-- <select name="type" class="form-control m-b">
<option value="">所有</option>
</select>-->
<select class="form-control" name="type" th:with="type=${@dict.getType('repository_type')}" disabled="disabled">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" ></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">基础路径:</label>
<div class="col-sm-8">
<input name="baseDir" class="form-control" type="text">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<script th:inline="javascript">
var prefix = ctx + "kettle/repository"
$("#form-repository-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-repository-add').serialize());
}
}
// $("input[name='createdTime']").datetimepicker({
// format: "yyyy-mm-dd",
// minView: "month",
// autoclose: true
// });
</script>
</body>
</html>

View File

@ -0,0 +1,132 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改资源库')" />
<th:block th:include="include :: datetimepicker-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-repository-edit" th:object="${xRepository}">
<input name="repoName" th:field="*{id}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">资源库名称:</label>
<div class="col-sm-8">
<input name="repoName" th:field="*{repoName}" class="form-control" type="text">
</div>
</div>
<!--<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的用户名</label>
<div class="col-sm-8">
<input name="repoUsername" th:field="*{repoUsername}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的密码</label>
<div class="col-sm-8">
<input name="repoPassword" th:field="*{repoPassword}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">db类型</label>
<div class="col-sm-8">
<select name="repoType" class="form-control m-b">
<option value="">所有</option>
</select>
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 代码生成请选择字典属性</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的连接类型</label>
<div class="col-sm-8">
<input name="dbAccess" th:field="*{dbAccess}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的ip</label>
<div class="col-sm-8">
<input name="dbHost" th:field="*{dbHost}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的端口</label>
<div class="col-sm-8">
<input name="dbPort" th:field="*{dbPort}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的db库名</label>
<div class="col-sm-8">
<input name="dbName" th:field="*{dbName}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的db用户名</label>
<div class="col-sm-8">
<input name="dbUsername" th:field="*{dbUsername}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">当资源库类型是db时候的db用户密码</label>
<div class="col-sm-8">
<input name="dbPassword" th:field="*{dbPassword}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">软删除:</label>
<div class="col-sm-8">
<input name="isDel" th:field="*{isDel}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-8">
<div class="input-group date">
<input name="createdTime" th:value="${#dates.format(xRepository.createdTime, 'yyyy-MM-dd')}" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-8">
<input name="createdBy" th:field="*{createdBy}" class="form-control" type="text">
</div>
</div>-->
<div class="form-group">
<label class="col-sm-3 control-label">资源库类型:</label>
<div class="col-sm-8">
<select class="form-control" name="type" th:with="type=${@dict.getType('repository_type')}" disabled="disabled">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" ></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">基础路径:</label>
<div class="col-sm-8">
<input name="baseDir" th:field="*{baseDir}" class="form-control" type="text">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<script th:inline="javascript">
var prefix = ctx + "kettle/repository";
$("#form-repository-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-repository-edit').serialize());
}
}
$("input[name='createdTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
</script>
</body>
</html>

View File

@ -0,0 +1,122 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('资源库列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>名称:</label>
<input type="text" name="repoName" placeholder="资源库名称" />
</li>
<!-- <li>
<label>资源库类型:</label>
<select name="type">
<option value="">所有</option>
<option value="-1">代码生成请选择字典属性</option>
</select>
</li>-->
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="kettle:repository:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="kettle:repository:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="kettle:repository:remove">
<i class="fa fa-remove"></i> 删除
</a>
<!-- <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="kettle:repository:export">
<i class="fa fa-download"></i> 导出
</a>-->
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('kettle:repository:edit')}]];
var removeFlag = [[${@permission.hasPermi('kettle:repository:remove')}]];
var prefix = ctx + "kettle/repository";
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "资源库",
columns: [{
checkbox: true
},
{
field: 'id',
title: 'id',
visible: false
},
{
field: 'repoName',
title: '资源库名称'
},
// {
// field: 'isDel',
// title: '是否删除'
// },
{
field: 'createdTime',
title: '创建时间'
},
{
field: 'createdBy',
title: '创建人'
},
{
field: 'updateTime',
title: '最后修改时间'
},
{
field: 'updateBy',
title: '修改人'
},
/*{
field: 'type',
title: '资源库类型'
},*/
{
field: 'baseDir',
title: '基础路径'
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>

View File

@ -0,0 +1,143 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增转换')" />
<th:block th:include="include :: datetimepicker-css" />
<th:block th:include="include :: select2-css" />
<th:block th:include="include :: bootstrap-select-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-trans-add">
<!-- <div class="form-group">
<label class="col-sm-3 control-label is-required">选择转换:</label>
<div class="col-sm-8">
<input name="transName" class="form-control" type="text" onclick="chooseTrans();" required>
</div>
</div>-->
<input name="transRepositoryId" class="form-control" type="hidden" id="transRepositoryId" required>
<div class="form-group">
<label class="col-sm-3 control-label is-required">选择转换:</label>
<div class="col-sm-8">
<input name="transName" class="form-control" type="text" id="treeName" onclick="chooseTrans();" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">转换描述:</label>
<div class="col-sm-8">
<textarea name="transDescription" class="form-control"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">转换类型(file,ftp,sftp)</label>
<div class="col-sm-8">
<select name="transType" class="form-control m-b" th:with="type=${@dict.getType('repository_type')}" disabled="disabled">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">路径:</label>
<div class="col-sm-8">
<input name="transPath" id="transPath" class="form-control" type="text" required readonly>
</div>
</div>
<!-- <div class="form-group"> -->
<!-- <label class="col-sm-3 control-label">所属资源库id</label>-->
<!-- <div class="col-sm-8">-->
<!-- <input name="transRepositoryId" class="form-control" type="text">-->
<!-- </div>-->
<!-- </div>-->
<div class="form-group">
<label class="col-sm-3 control-label">日志级别:</label>
<div class="col-sm-8">
<select name="transLogLevel" class="form-control m-b" th:with="type=${@dict.getType('kettle_log_level')}" >
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
<!-- <div class="form-group">
<label class="col-sm-3 control-label">状态:</label>
<div class="col-sm-8">
<div class="radio-box">
<input type="radio" name="transStatus" value="">
<label th:for="transStatus" th:text="未知"></label>
</div>
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 代码生成请选择字典属性</span>
</div>
</div>-->
<!-- <div class="form-group">
<label class="col-sm-3 control-label">是否监控:</label>
<div class="col-sm-8">
<label class="radio-box">
<input type="radio" checked="" value=1 id="optionsRadios1" name="isMonitorEnabled"></label>
<label class="radio-box">
<input type="radio" value=0 id="optionsRadios2" name="isMonitorEnabled"></label>
</div>
</div>-->
<!-- <div class="form-group">-->
<!-- <label class="col-sm-3 control-label">角色key</label>-->
<!-- <div class="col-sm-8">-->
<!-- <textarea name="roleKey" class="form-control" placeholder="可以执行该转换的角色组合,用','连接,如:admin,guest,表示admin角色和guest角色都可以执行该转换"></textarea>-->
<!-- </div>-->
<!-- </div>-->
<div class="form-group">
<label class="col-sm-3 control-label">角色key:</label>
<div class="col-sm-8">
<select class="form-control noselect2 selectpicker m-b" name="roleKey" data-none-selected-text="可以执行该转换的角色组合" multiple >
<option th:each="allRoles:${allRoles}" th:value="${allRoles}" th:text="${allRoles}" ></option>
</select>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<th:block th:include="include :: select2-js" />
<th:block th:include="include :: bootstrap-select-js" />
<script th:inline="javascript">
$.fn.selectpicker.Constructor.DEFAULTS.liveSearch=true
var prefix = ctx + "kettle/trans"
$("#form-trans-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-trans-add').serialize());
}
}
$("input[name='createdTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
function chooseTrans(){
var treeId = $("#treeId").val();
//var repoid = $.common.isEmpty(treeId) ? "999999" : $("#treeId").val();
var url = ctx + "kettle/repository/selectRepositoryTree/"
var options = {
title: '选择资源库',
width: "380",
url: url,
callBack: doSubmit
};
$.modal.openOptions(options);
}
function doSubmit(index, layero){
var tree = layero.find("iframe")[0].contentWindow.$._tree;
var body = layer.getChildFrame('body', index);
$("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val());
$("#transRepositoryId").val(body.find('#transRepositoryId').val());
$("#transPath").val(body.find('#transPath').val());
layer.close(index);
}
</script>
</body>
</html>

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('转换执行日志')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-expsubspushresp-detail" th:object="${kettleTrans}">
<input name="id" th:field="*{id}" type="hidden">
<div class="form-group">
<!-- <label class="col-sm-3 control-label">运行日志:</label>
<div class="col-sm-8">
<span name="transName" id="transName" class="form-control" th:text="*{transName}" ></span>
</div>-->
<textarea name="transLog" class="textarea-inherit" th:text="${transLog}" type="text" rows="30"></textarea>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "kettle/trans";
$(function (){
});
</script>
</body>
<style>
.textarea-inherit {
width: 100%;
height: auto;
overflow: auto;
word-break: break-all; //解决兼容问题
}
</style>
</html>

View File

@ -0,0 +1,105 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改转换')" />
<th:block th:include="include :: datetimepicker-css" />
<th:block th:include="include :: select2-css" />
<th:block th:include="include :: bootstrap-select-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-trans-edit" th:object="${kettleTrans}">
<input name="id" th:field="*{id}" type="hidden">
<input name="transRepositoryId" class="form-control" type="hidden" th:field="*{transRepositoryId}" id="transRepositoryId" >
<div class="form-group">
<label class="col-sm-3 control-label is-required">转换名称:</label>
<div class="col-sm-8">
<input name="transName" th:field="*{transName}" class="form-control" type="text" required readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">转换描述:</label>
<div class="col-sm-8">
<textarea name="transDescription" class="form-control">[[*{transDescription}]]</textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">路径:</label>
<div class="col-sm-8">
<input name="transPath" th:field="*{transPath}" class="form-control" type="text" required readonly>
</div>
</div>
<!-- <div class="form-group">
<label class="col-sm-3 control-label">所属资源库id</label>
<div class="col-sm-8">
<input name="transRepositoryId" th:field="*{transRepositoryId}" class="form-control" type="text">
</div>
</div>-->
<div class="form-group">
<label class="col-sm-3 control-label">日志级别:</label>
<div class="col-sm-8">
<select name="transLogLevel" class="form-control m-b" th:with="type=${@dict.getType('kettle_log_level')}" th:field="*{transLogLevel}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" ></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">是否监控:</label>
<div class="col-sm-8">
<!-- <label class="toggle-switch switch-solid">
<input name="isMonitorEnabled" type="checkbox" id="status" th:checked="${kettleTrans.isMonitorEnabled == 1 ? true : false}">
<span></span>
</label>-->
<label class="radio-box">
<input type="radio" checked="" value=1 id="optionsRadios1" name="isMonitorEnabled" th:checked="${kettleTrans.isMonitorEnabled == 1 ? true : false}"></label>
<label class="radio-box">
<input type="radio" value=0 id="optionsRadios2" name="isMonitorEnabled" th:checked="${kettleTrans.isMonitorEnabled == 0 ? true : false}"></label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">角色key:</label>
<div class="col-sm-8">
<select class="form-control noselect2 selectpicker m-b " name="roleKey" data-none-selected-text="可以执行该转换的角色组合" multiple >
<option th:each="allRoles:${allRoles}" th:value="${allRoles}" th:text="${allRoles}" ></option>
</select>
</div>
</div>
<!-- <div class="form-group">
<label class="col-sm-3 control-label">可执行角色:</label>
<div class="col-sm-8">
<textarea name="roleKey" class="form-control" placeholder="可以执行该转换的角色组合,用','连接,如:admin,guest,表示admin角色和guest角色都可以执行该转换">[[*{roleKey}]]</textarea>
</div>
<div class="col-sm-8">
<select class="form-control noselect2 selectpicker m-b" name="roleKey" data-none-selected-text="可以执行该转换的角色组合" multiple >
<option th:each="allRoles:${allRoles}" th:value="${allRoles}" th:text="${allRoles}" ></option>
</select>
</div>
</div>-->
<!-- <div class="form-group">
<label class="col-sm-3 control-label">备注:</label>
<div class="col-sm-8">
<input name="remark" th:field="*{remark}" class="form-control" type="text">
</div>
</div>-->
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<th:block th:include="include :: select2-js" />
<th:block th:include="include :: bootstrap-select-js" />
<script th:inline="javascript">
var rkArray = [[${rkArray}]];
$('.selectpicker').selectpicker('val',rkArray);
var prefix = ctx + "kettle/trans";
$("#form-trans-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-trans-edit').serialize());
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,165 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('转换列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>转换名称:</label>
<input type="text" name="transName"/>
</li>
<li>
<label>状态:</label>
<select name="transStatus" th:with="type=${@dict.getType('kettle_trans_status')}" >
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" ></option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="kettle:trans:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="kettle:trans:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="kettle:trans:remove">
<i class="fa fa-remove"></i> 删除
</a>
<!-- <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="kettle:trans:export">
<i class="fa fa-download"></i> 导出
</a>-->
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('kettle:trans:edit')}]];
var removeFlag = [[${@permission.hasPermi('kettle:trans:remove')}]];
var detailFlag=[[${@permission.hasPermi('kettle:trans:detail')}]];
var logFlag=[[${@permission.hasPermi('kettle:trans:log')}]];
var runFlag=[[${@permission.hasPermi('kettle:trans:run')}]];
var quartzFlag=[[${@permission.hasPermi('kettle:trans:setquartz')}]];
var prefix = ctx + "kettle/trans";
var logLevel = [[${@dict.getType('kettle_log_level')}]];
var transStatus = [[${@dict.getType('kettle_trans_status')}]];
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
detailUrl: prefix + "/detail/{id}",
modalName: "转换",
columns: [{
checkbox: true
},
{
field: 'id',
title: '',
visible: false
},
{
field: 'transName',
title: '转换名称'
},
{
field: 'transDescription',
title: '转换描述'
},
{
field: 'transPath',
title: '路径'
},
{
field: 'transRepositoryId',
title: '所属资源库id'
},
{
field: 'transLogLevel',
title: '日志级别',
formatter: function(value, row, index) {
return $.table.selectDictLabel(logLevel, value);
}
},
{
field: 'transStatus',
title: '状态',
formatter: function(value, row, index) {
return $.table.selectDictLabel(transStatus, value);
}
},
// {
// field: 'isDel',
// title: '是否删除'
// },
{
field: 'isMonitorEnabled',
title: '是否启用',
formatter: function(value, row, index) {
return value==1?"是":"否";
}
},
// {
// field: 'tplKey',
// title: '保留备用'
// },
{
field: 'roleKey',
title: '可执行角色'
},
// {
// field: 'remark',
// title: '备注'
// },
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
actions.push("<a class='btn btn-default btn-xs " + runFlag + "' href='javascript:void(0)' onclick='runTransNow(" + row.id + ")'><i class='fa fa-play-circle-o'></i>立即运行</a> ");
actions.push("<a class='btn btn-default btn-xs " + quartzFlag + "' href='javascript:void(0)' onclick='setTransQuartz(" + row.id + ")'><i class='glyphicon glyphicon-time'></i>设置定时</a>");
actions.push("<a class='btn btn-default btn-xs " + logFlag + "' href='javascript:void(0)' onclick='$.operate.detail(" + row.id + ")'><i class='fa fa-search'></i>运行日志</a> ");
return actions.join('');
}
}]
};
$.table.init(options);
});
/* 立即执行一次trans */
function runTransNow(id) {
$.modal.confirm("确认要立即执行一次该转换吗?", function() {
$.operate.post(prefix + "/run", { "id": id});
})
}
/*设置定时任务*/
function setTransQuartz(id){
//$.operate.get(prefix + "/transQuartz/"+id);
$.modal.open('添加定时任务', prefix + "/transQuartz/"+id, '900', '500');
}
</script>
</body>
</html>

View File

@ -0,0 +1,15 @@
package com.kone;
import com.ruoyi.kettle.tools.KettleUtil;
import org.junit.Test;
public class Testsetset {
@Test
public void test1() throws Exception {
KettleUtil.KettleEnv.init();
KettleUtil util=new KettleUtil();
util.callTrans("/","text",null,null);
}
}

View File

@ -232,6 +232,11 @@
<version>${ruoyi.version}</version>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>bps-kettle</artifactId>
<version>${ruoyi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -244,6 +249,7 @@
<module>ruoyi-common</module>
<module>box-test</module>
<module>box-bps</module>
<module>bps-kettle</module>
</modules>
<packaging>pom</packaging>

View File

@ -93,7 +93,10 @@
<groupId>com.ruoyi</groupId>
<artifactId>box-bps</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>bps-kettle</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -196,7 +196,7 @@ public class SysJobServiceImpl implements ISysJobService
@Transactional
public int insertJob(SysJob job) throws SchedulerException, TaskException
{
job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
//job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
int rows = jobMapper.insertJob(job);
if (rows > 0)
{