1 、任务管理
2、设计器功能,一个页面编辑多个任务包含转换和工作,支持框选,组件复制粘贴,在线运行等功能。
3、组件的邮件功能,连线右键功能,设计区域右键功能,基本上涵盖kettle常用右键相关功能。
点击跳转使用手册->查看演示探讨
共同探讨合作 QQ:598762549
1. 本系统基于kettle 9 引擎改造为web-kettle 目前的最新版本在之前的基础上基于用户的需求做了很多功能优化,生产环境比较稳定。
2. 已经做了输入、输出、转换、应用、流程、脚本、查询等150多个转换组件以及工作50多个组件,可按需根据业务定制组件
3. 集成调度平台 和 web-kettle流程设计器直接在浏览器中拖拉拽节点配置属性,然后通过调度模块实现完美调度,支持分布式、集群、前置机部署 ;
4. 由于资源库形式维护起来方便,但是执行效率极其低下,尤其多人操作ETL任务的时候会锁库,脚本模式完美规避这个问题,而且解决了数据库每个脚本单独配置,采用目录形式管理多人协作很方便。时长较长任务支持后台执行,刷新的时候会重现当前任务状态,无需客户端一直等待。
5. 深入研究过kettle 源码,优化部分bug。但是无法做出客户端全部交互效果,不过基本上很接近,简单易用代码简洁,很容易进行二次开发扩展。
6. 技术框架 spring boot 、mybatis 、vue、element-ui
7. 本项目开发持续接近3年,生产环境也部署过上百个节点,再配合自带的调度平台,开源作为完整的一套ETL解决方案。
8、后台代码如何实现一个组件。(比如要实现一个 调用一个存储过程的组件)
package org.flhy.ext.trans.steps;
import com.mxgraph.model.mxCell;
import com.mxgraph.util.mxUtils;
import org.flhy.ext.core.PropsUI;
import org.flhy.ext.trans.step.AbstractStep;
import org.flhy.ext.utils.JSONArray;
import org.flhy.ext.utils.JSONObject;
import org.flhy.ext.utils.StringEscapeHelper;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.row.ValueMeta;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.row.value.ValueMetaFactory;
import org.pentaho.di.trans.step.StepMetaInterface;
import org.pentaho.di.trans.steps.dbproc.DBProcMeta;
import org.pentaho.di.trans.steps.selectvalues.SelectMetadataChange;
import org.pentaho.di.trans.steps.selectvalues.SelectValuesMeta;
import org.pentaho.di.trans.steps.sql.ExecSQLMeta;
import org.pentaho.metastore.api.IMetaStore;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.util.List;
// author sf 2019-08-06
@Component("DBProc")
@Scope("prototype")
public class DBProc extends AbstractStep {
@Override
public void decode(StepMetaInterface stepMetaInterface, mxCell cell, List<DatabaseMeta> databases, IMetaStore metaStore) throws Exception {
DBProcMeta DBProcsMeta = (DBProcMeta) stepMetaInterface;
String con = cell.getAttribute("connection");
DBProcsMeta.setDatabase(DatabaseMeta.findDatabase(databases, con));
DBProcsMeta.setProcedure(cell.getAttribute("procedure"));
DBProcsMeta.setResultName(cell.getAttribute("resultName"));
DBProcsMeta.setAutoCommit("Y".equalsIgnoreCase(cell.getAttribute("autoCommit")));
DBProcsMeta.setResultType(ValueMetaFactory.getIdForValueMeta(cell.getAttribute("resultType")));
// JSONArray jsonArray = JSONArray.fromObject(cell.getAttribute( "argument" ));
// DBProcsMeta.allocate( jsonArray.size() );
// for(int i=0; i<jsonArray.size(); i++) {
// JSONObject jsonObject = jsonArray.getJSONObject(i);
// DBProcsMeta.getArgument()[i] = jsonObject.optString("name");
// }
//
// JSONArray jsonDirectionArray = JSONArray.fromObject(cell.getAttribute( "argumentDirection" ));
// DBProcsMeta.allocate( jsonDirectionArray.size() );
// for(int i=0; i<jsonDirectionArray.size(); i++) {
// JSONObject jsonObject = jsonDirectionArray.getJSONObject(i);
// DBProcsMeta.getArgumentDirection()[i] = jsonObject.optString("directionname");
// }
//
// JSONArray jsonTypeArray = JSONArray.fromObject(cell.getAttribute( "argumentType" ));
// DBProcsMeta.allocate( jsonTypeArray.size() );
// for(int i=0; i<jsonTypeArray.size(); i++) {
// JSONObject jsonObject = jsonTypeArray.getJSONObject(i);
// DBProcsMeta.getArgumentType()[i] = jsonObject.optInt("typeName");
// }
JSONArray jsonArray = JSONArray.fromObject(cell.getAttribute("parameterFields"));
String[] argument = new String[jsonArray.size()];
String[] argumentDirection = new String[jsonArray.size()];
int[] argumentType = new int[jsonArray.size()];
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
argument[i] = jsonObject.optString("name");
argumentDirection[i] = jsonObject.optString("direction");
argumentType[i] = ValueMetaFactory.getIdForValueMeta(jsonObject.optString("type"));
}
DBProcsMeta.setArgument(argument);
DBProcsMeta.setArgumentDirection(argumentDirection);
DBProcsMeta.setArgumentType(argumentType);
}
@Override
public Element encode(StepMetaInterface stepMetaInterface) throws Exception {
DBProcMeta DBPMeta = (DBProcMeta) stepMetaInterface;
Document doc = mxUtils.createDocument();
Element e = doc.createElement(PropsUI.TRANS_STEP_NAME);
e.setAttribute("connection", DBPMeta.getDatabase() == null ? "" : DBPMeta.getDatabase().getName());
e.setAttribute("procedure", DBPMeta.getProcedure());
e.setAttribute("resultName", DBPMeta.getResultName());
// jsonObject.put("type",ValueMetaFactory.getValueMetaName(DBPMeta.getArgumentType()[j]) );
e.setAttribute("resultType",ValueMetaFactory.getValueMetaName(Integer.valueOf(DBPMeta.getResultType())));
e.setAttribute("autoCommit",DBPMeta.isAutoCommit() ? "Y" : "N");
// JSONArray arguments = new JSONArray();
// for ( int i = 0; i < DBPMeta.getArgument().length; i++ ) {
// String name = DBPMeta.getArgument()[i];
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("name", name);
// arguments.add(jsonObject);
// }
// e.setAttribute("arguments", arguments.toString());
//
// JSONArray directions = new JSONArray();
// for ( int i = 0; i < DBPMeta.getArgumentDirection().length; i++ ) {
// String directionname = DBPMeta.getArgumentDirection()[i];
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("directionname", directionname);
// arguments.add(jsonObject);
// }
// e.setAttribute("argumentDirection", directions.toString());
//
// JSONArray argumentTypes = new JSONArray();
// for ( int i = 0; i < DBPMeta.getArgumentType().length; i++ ) {
// String typeName = String.valueOf(DBPMeta.getArgumentType()[i]);
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("typeName", typeName);
// arguments.add(jsonObject);
// }
// e.setAttribute("argumentType", argumentTypes.toString());
JSONArray jsonArray = new JSONArray();
String[] parameters = DBPMeta.getArgument();
for(int j=0; j<parameters.length; j++) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", parameters[j]);
jsonObject.put("direction", DBPMeta.getArgumentDirection()[j]);
jsonObject.put("type",ValueMetaFactory.getValueMetaName(DBPMeta.getArgumentType()[j]) );
jsonArray.add(jsonObject);
}
e.setAttribute("parameterFields", jsonArray.toString());
return e;
}
}
剩下的就是vue做一个ui