From 36d60a564adef2bfec49705f82422f38591bee9f Mon Sep 17 00:00:00 2001
From: Kerwin <37063904+zhuangchong@users.noreply.github.com>
Date: Tue, 7 Sep 2021 15:04:18 +0800
Subject: [PATCH] [Feature][Task]Task plugin spi (#6116)
---
.../common/utils/DateUtils.java | 32 +
.../worker/runner/TaskExecuteThread.java | 5 +-
dolphinscheduler-spi/pom.xml | 226 ++++++-
.../spi/enums/CommandType.java | 84 +++
.../dolphinscheduler/spi/enums/DataType.java | 37 ++
.../spi/enums/DbConnectType.java | 42 ++
.../dolphinscheduler/spi/enums/DbType.java | 59 ++
.../dolphinscheduler/spi/enums/Flag.java | 51 ++
.../spi/enums/ResUploadType.java | 30 +
.../spi/enums/TaskTimeoutStrategy.java | 58 ++
.../spi/task/AbstractTask.java | 2 +
.../dolphinscheduler/spi/task/Property.java | 2 +-
.../spi/task/TaskChannel.java | 2 +
.../spi/task/TaskConstants.java | 241 +++++++
.../spi/task/UdfFuncBean.java | 188 ++++++
.../AbstractDatasourceProcessor.java | 79 +++
.../task/datasource/BaseConnectionParam.java | 108 +++
.../datasource/BaseDataSourceParamDTO.java | 161 +++++
.../datasource/BaseHdfsConnectionParam.java | 57 ++
.../BaseHdfsDatasourceParamDTO.java | 61 ++
.../spi/task/datasource/ConnectionParam.java | 26 +
.../task/datasource/DatasourceProcessor.java | 81 +++
.../spi/task/datasource/DatasourceUtil.java | 121 ++++
.../spi/task/datasource/HiveConfUtils.java | 87 +++
.../spi/task/datasource/PasswordUtils.java | 88 +++
.../ClickHouseDatasourceParamDTO.java | 41 ++
.../ClickHouseDatasourceProcessor.java | 131 ++++
.../clickhouse/ClickhouseConnectionParam.java | 34 +
.../datasource/db2/Db2ConnectionParam.java | 34 +
.../datasource/db2/Db2DatasourceParamDTO.java | 43 ++
.../db2/Db2DatasourceProcessor.java | 132 ++++
.../datasource/hive/HiveConnectionParam.java | 38 ++
.../hive/HiveDataSourceParamDTO.java | 45 ++
.../hive/HiveDatasourceProcessor.java | 192 ++++++
.../mysql/MysqlConnectionParam.java | 35 +
.../mysql/MysqlDatasourceParamDTO.java | 43 ++
.../mysql/MysqlDatasourceProcessor.java | 176 +++++
.../oracle/OracleConnectionParam.java | 47 ++
.../oracle/OracleDatasourceParamDTO.java | 55 ++
.../oracle/OracleDatasourceProcessor.java | 149 +++++
.../postgresql/PostgreSqlConnectionParam.java | 34 +
.../PostgreSqlDatasourceParamDTO.java | 41 ++
.../PostgreSqlDatasourceProcessor.java | 132 ++++
.../presto/PrestoConnectionParam.java | 34 +
.../presto/PrestoDatasourceParamDTO.java | 43 ++
.../presto/PrestoDatasourceProcessor.java | 134 ++++
.../spark/SparkConnectionParam.java | 38 ++
.../spark/SparkDatasourceParamDTO.java | 45 ++
.../spark/SparkDatasourceProcessor.java | 161 +++++
.../sqlserver/SqlServerConnectionParam.java | 34 +
.../SqlServerDatasourceParamDTO.java | 43 ++
.../SqlServerDatasourceProcessor.java | 129 ++++
.../task/paramparser/BusinessTimeUtils.java | 78 +++
.../spi/task/paramparser/ParamUtils.java | 158 +++++
.../spi/task/paramparser/ParameterUtils.java | 269 ++++++++
.../task/paramparser/PlaceholderUtils.java | 103 +++
.../PropertyPlaceholderHelper.java | 255 +++++++
.../paramparser/TimePlaceholderUtils.java | 570 ++++++++++++++++
.../spi/task/request/DataxTaskRequest.java | 115 ++++
.../task/request/ProcedureTaskRequest.java | 45 ++
.../spi/task/request/SQLTaskRequest.java | 80 +++
.../spi/task/request/SqoopTaskRequest.java | 115 ++++
.../spi/task/{ => request}/TaskRequest.java | 16 +-
.../spi/utils/CommonUtils.java | 104 +++
.../dolphinscheduler/spi/utils/Constants.java | 20 +
.../dolphinscheduler/spi/utils/DateUtils.java | 622 ++++++++++++++++++
.../spi/utils/PropertyUtils.java | 260 ++++++++
.../spi/utils/StringUtils.java | 195 +++++-
.../task/api/AbstractCommandExecutor.java | 2 +-
.../plugin/task/api/AbstractTaskExecutor.java | 2 +-
.../plugin/task/api/AbstractYarnTask.java | 9 +-
.../plugin/task/api/ProcessUtils.java | 2 +-
.../plugin/task/api/ShellCommandExecutor.java | 2 +-
.../api/TaskExecutionContextCacheManager.java | 2 +-
.../dolphinscheduler-task-datax/pom.xml | 12 +-
.../plugin/task/datax/DataxParameters.java | 251 +++++++
.../plugin/task/datax/DataxTask.java | 570 ++++++++++++++++
.../plugin/task/datax/DataxTaskChannel.java | 36 +
.../task/datax/DataxTaskChannelFactory.java | 42 ++
.../plugin/task/datax/DataxTaskPlugin.java | 31 +
.../plugin/task/datax/DataxUtils.java | 136 ++++
.../dolphinscheduler-task-flink/pom.xml | 22 +-
.../plugin/task/flink/FlinkTask.java | 87 +--
.../plugin/task/flink/FlinkTaskChannel.java | 2 +-
.../dolphinscheduler-task-http/pom.xml | 12 +-
.../plugin/task/http/HttpMethod.java | 18 +-
.../plugin/task/http/HttpParameters.java | 5 +-
.../plugin/task/http/HttpParametersType.java | 1 +
.../plugin/task/http/HttpProperty.java | 192 +++---
.../plugin/task/http/HttpTask.java | 269 +++++++-
.../plugin/task/http/HttpTaskChannel.java | 4 +-
.../task/http/HttpTaskChannelFactory.java | 5 +-
.../plugin/task/http/HttpTaskConstants.java} | 8 +-
.../plugin/task/http/HttpTaskPlugin.java | 3 +-
.../dolphinscheduler-task-mr/pom.xml | 5 +
.../plugin/task/mr/MapReduceArgsUtils.java | 88 +++
.../plugin/task/mr/MapReduceParameters.java | 159 +++++
.../plugin/task/mr/MapReduceTask.java | 134 ++++
.../plugin/task/mr/MapReduceTaskChannel.java | 34 +
.../task/mr/MapReduceTaskChannelFactory.java | 42 ++
.../task/mr/MapReduceTaskConstants.java | 36 +
.../plugin/task/mr/MapReduceTaskPlugin.java | 31 +
.../plugin/task/mr/ProgramType.java | 30 +
.../dolphinscheduler-task-procedure/pom.xml | 7 +-
.../task/procedure/ProcedureParameters.java | 89 +++
.../plugin/task/procedure/ProcedureTask.java | 330 ++++++++++
.../task/procedure/ProcedureTaskChannel.java | 36 +
.../ProcedureTaskChannelFactory.java | 42 ++
.../task/procedure/ProcedureTaskPlugin.java | 31 +
.../dolphinscheduler-task-python/pom.xml | 22 +-
.../task/python/PythonCommandExecutor.java | 2 +-
.../plugin/task/python/PythonTask.java | 5 +-
.../plugin/task/python/PythonTaskChannel.java | 2 +-
.../plugin/task/shell/ShellTask.java | 4 +-
.../plugin/task/shell/ShellTaskChannel.java | 6 +-
.../dolphinscheduler-task-spark/pom.xml | 24 +-
.../plugin/task/spark/SparkTask.java | 53 +-
.../plugin/task/spark/SparkTaskChannel.java | 5 +-
.../task/spark/SparkTaskChannelFactory.java | 2 +-
.../plugin/task/spark/SparkTaskPlugin.java | 1 +
.../dolphinscheduler-task-sqoop/pom.xml | 4 +
.../plugin/task/sqoop/SqoopConstants.java | 75 +++
.../plugin/task/sqoop/SqoopJobType.java | 40 ++
.../plugin/task/sqoop/SqoopQueryType.java | 41 ++
.../plugin/task/sqoop/SqoopTask.java | 93 +++
.../plugin/task/sqoop/SqoopTaskChannel.java | 36 +
.../task/sqoop/SqoopTaskChannelFactory.java | 42 ++
.../plugin/task/sqoop/SqoopTaskPlugin.java | 31 +
.../task/sqoop/generator/CommonGenerator.java | 88 +++
.../sqoop/generator/ISourceGenerator.java | 36 +
.../sqoop/generator/ITargetGenerator.java | 36 +
.../sqoop/generator/SqoopJobGenerator.java | 124 ++++
.../sources/HdfsSourceGenerator.java | 64 ++
.../sources/HiveSourceGenerator.java | 77 +++
.../sources/MysqlSourceGenerator.java | 147 +++++
.../targets/HdfsTargetGenerator.java | 93 +++
.../targets/HiveTargetGenerator.java | 101 +++
.../targets/MysqlTargetGenerator.java | 123 ++++
.../task/sqoop/parameter/SqoopParameters.java | 204 ++++++
.../sources/SourceHdfsParameter.java | 37 ++
.../sources/SourceHiveParameter.java | 73 ++
.../sources/SourceMysqlParameter.java | 137 ++++
.../targets/TargetHdfsParameter.java | 98 +++
.../targets/TargetHiveParameter.java | 121 ++++
.../targets/TargetMysqlParameter.java | 133 ++++
.../plugin/task/tis/TISTask.java | 6 +-
.../plugin/task/tis/TISTaskChannel.java | 2 +-
.../plugin/task/tis/TISTaskTest.java | 2 +-
dolphinscheduler-task-plugin/pom.xml | 10 +-
pom.xml | 2 +-
150 files changed, 11732 insertions(+), 285 deletions(-)
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/CommandType.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DataType.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbConnectType.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbType.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/Flag.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/ResUploadType.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/TaskTimeoutStrategy.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/UdfFuncBean.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/AbstractDatasourceProcessor.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseDataSourceParamDTO.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseHdfsConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseHdfsDatasourceParamDTO.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/ConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/DatasourceProcessor.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/DatasourceUtil.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/HiveConfUtils.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/PasswordUtils.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickHouseDatasourceParamDTO.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickHouseDatasourceProcessor.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickhouseConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2ConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2DatasourceParamDTO.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2DatasourceProcessor.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveDataSourceParamDTO.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveDatasourceProcessor.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlDatasourceParamDTO.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlDatasourceProcessor.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleDatasourceParamDTO.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleDatasourceProcessor.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlDatasourceParamDTO.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlDatasourceProcessor.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoDatasourceParamDTO.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoDatasourceProcessor.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkDatasourceParamDTO.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkDatasourceProcessor.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerConnectionParam.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerDatasourceParamDTO.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerDatasourceProcessor.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/BusinessTimeUtils.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/ParamUtils.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/ParameterUtils.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/PlaceholderUtils.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/PropertyPlaceholderHelper.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/TimePlaceholderUtils.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/DataxTaskRequest.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/ProcedureTaskRequest.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/SQLTaskRequest.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/SqoopTaskRequest.java
rename dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/{ => request}/TaskRequest.java (95%)
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/CommonUtils.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/DateUtils.java
create mode 100644 dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/PropertyUtils.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-datax/src/main/java/org/apache/dolphinscheduler/plugin/task/datax/DataxParameters.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-datax/src/main/java/org/apache/dolphinscheduler/plugin/task/datax/DataxTask.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-datax/src/main/java/org/apache/dolphinscheduler/plugin/task/datax/DataxTaskChannel.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-datax/src/main/java/org/apache/dolphinscheduler/plugin/task/datax/DataxTaskChannelFactory.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-datax/src/main/java/org/apache/dolphinscheduler/plugin/task/datax/DataxTaskPlugin.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-datax/src/main/java/org/apache/dolphinscheduler/plugin/task/datax/DataxUtils.java
rename dolphinscheduler-task-plugin/{dolphinscheduler-task-shell/src/main/java/org/apache/dolphinscheduler/plugin/task/shell/ShellTaskConstants.java => dolphinscheduler-task-http/src/main/java/org/apache/dolphinscheduler/plugin/task/http/HttpTaskConstants.java} (83%)
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-mr/src/main/java/org/apache/dolphinscheduler/plugin/task/mr/MapReduceArgsUtils.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-mr/src/main/java/org/apache/dolphinscheduler/plugin/task/mr/MapReduceParameters.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-mr/src/main/java/org/apache/dolphinscheduler/plugin/task/mr/MapReduceTask.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-mr/src/main/java/org/apache/dolphinscheduler/plugin/task/mr/MapReduceTaskChannel.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-mr/src/main/java/org/apache/dolphinscheduler/plugin/task/mr/MapReduceTaskChannelFactory.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-mr/src/main/java/org/apache/dolphinscheduler/plugin/task/mr/MapReduceTaskConstants.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-mr/src/main/java/org/apache/dolphinscheduler/plugin/task/mr/MapReduceTaskPlugin.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-mr/src/main/java/org/apache/dolphinscheduler/plugin/task/mr/ProgramType.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-procedure/src/main/java/org/apache/dolphinscheduler/plugin/task/procedure/ProcedureParameters.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-procedure/src/main/java/org/apache/dolphinscheduler/plugin/task/procedure/ProcedureTask.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-procedure/src/main/java/org/apache/dolphinscheduler/plugin/task/procedure/ProcedureTaskChannel.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-procedure/src/main/java/org/apache/dolphinscheduler/plugin/task/procedure/ProcedureTaskChannelFactory.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-procedure/src/main/java/org/apache/dolphinscheduler/plugin/task/procedure/ProcedureTaskPlugin.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/SqoopConstants.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/SqoopJobType.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/SqoopQueryType.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/SqoopTask.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/SqoopTaskChannel.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/SqoopTaskChannelFactory.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/SqoopTaskPlugin.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/CommonGenerator.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/ISourceGenerator.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/ITargetGenerator.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/SqoopJobGenerator.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/sources/HdfsSourceGenerator.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/sources/HiveSourceGenerator.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/sources/MysqlSourceGenerator.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/targets/HdfsTargetGenerator.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/targets/HiveTargetGenerator.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/targets/MysqlTargetGenerator.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/parameter/SqoopParameters.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/parameter/sources/SourceHdfsParameter.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/parameter/sources/SourceHiveParameter.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/parameter/sources/SourceMysqlParameter.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/parameter/targets/TargetHdfsParameter.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/parameter/targets/TargetHiveParameter.java
create mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/parameter/targets/TargetMysqlParameter.java
diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java
index ec929112a7..5a6a704e02 100644
--- a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java
+++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java
@@ -483,6 +483,38 @@ public class DateUtils {
Constants.YYYY_MM_DD_HH_MM_SS);
}
+ public static Date addYears(Date date, int amount) {
+ return add(date, 1, amount);
+ }
+
+ public static Date addMonths(Date date, int amount) {
+ return add(date, 2, amount);
+ }
+
+ public static Date addWeeks(Date date, int amount) {
+ return add(date, 3, amount);
+ }
+
+ public static Date addDays(Date date, int amount) {
+ return add(date, 5, amount);
+ }
+
+ public static Date addHours(Date date, int amount) {
+ return add(date, 11, amount);
+ }
+
+ public static Date addMinutes(Date date, int amount) {
+ return add(date, 12, amount);
+ }
+
+ public static Date addSeconds(Date date, int amount) {
+ return add(date, 13, amount);
+ }
+
+ public static Date addMilliseconds(Date date, int amount) {
+ return add(date, 14, amount);
+ }
+
/**
* get date
*
diff --git a/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/runner/TaskExecuteThread.java b/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/runner/TaskExecuteThread.java
index 6376f3a4cc..56744738df 100644
--- a/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/runner/TaskExecuteThread.java
+++ b/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/runner/TaskExecuteThread.java
@@ -41,7 +41,7 @@ import org.apache.dolphinscheduler.service.alert.AlertClientService;
import org.apache.dolphinscheduler.service.bean.SpringApplicationContext;
import org.apache.dolphinscheduler.spi.task.AbstractTask;
import org.apache.dolphinscheduler.spi.task.TaskChannel;
-import org.apache.dolphinscheduler.spi.task.TaskRequest;
+import org.apache.dolphinscheduler.spi.task.request.TaskRequest;
import org.apache.commons.collections.MapUtils;
@@ -57,9 +57,6 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
-import org.apache.dolphinscheduler.spi.task.AbstractTask;
-import org.apache.dolphinscheduler.spi.task.TaskChannel;
-import org.apache.dolphinscheduler.spi.task.TaskRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/dolphinscheduler-spi/pom.xml b/dolphinscheduler-spi/pom.xml
index 79b7a583b9..b96161e1b9 100644
--- a/dolphinscheduler-spi/pom.xml
+++ b/dolphinscheduler-spi/pom.xml
@@ -56,7 +56,11 @@
commons-beanutilsprovided
-
+
+ commons-codec
+ commons-codec
+ provided
+ org.slf4jslf4j-api
@@ -94,6 +98,226 @@
resolverprovided
+
+
+ org.apache.hive
+ hive-jdbc
+ provided
+
+
+ slf4j-log4j12
+ org.slf4j
+
+
+ org.eclipse.jetty.aggregate
+ jetty-all
+
+
+
+ org.apache.ant
+ ant
+
+
+ io.dropwizard.metrics
+ metrics-json
+
+
+ io.dropwizard.metrics
+ metrics-jvm
+
+
+ com.github.joshelser
+ dropwizard-metrics-hadoop-metrics2-reporter
+
+
+
+ io.netty
+ netty-all
+
+
+ com.google.code.gson
+ gson
+
+
+ com.google.code.findbugs
+ jsr305
+
+
+ io.dropwizard.metrics
+ metrics-core
+
+
+ javax.servlet
+ servlet-api
+
+
+ org.apache.avro
+ avro
+
+
+ org.apache.commons
+ commons-compress
+
+
+ org.apache.curator
+ curator-client
+
+
+ org.apache.hadoop
+ hadoop-auth
+
+
+ org.apache.hadoop
+ hadoop-mapreduce-client-core
+
+
+ org.apache.hadoop
+ hadoop-yarn-api
+
+
+
+ org.apache.zookeeper
+ zookeeper
+
+
+ org.codehaus.jackson
+ jackson-jaxrs
+
+
+ org.codehaus.jackson
+ jackson-xc
+
+
+ com.google.protobuf
+ protobuf-java
+
+
+
+ org.json
+ json
+
+
+ log4j-slf4j-impl
+ org.apache.logging.log4j
+
+
+ javax.servlet
+ org.eclipse.jetty.orbit
+
+
+ servlet-api-2.5
+ org.mortbay.jetty
+
+
+ jasper-runtime
+ tomcat
+
+
+ slider-core
+ org.apache.slider
+
+
+ hbase-server
+ org.apache.hbase
+
+
+ jersey-client
+ com.sun.jersey
+
+
+ jersey-core
+ com.sun.jersey
+
+
+ jersey-json
+ com.sun.jersey
+
+
+ jersey-server
+ com.sun.jersey
+
+
+ jersey-guice
+ com.sun.jersey.contribs
+
+
+ hbase-common
+ org.apache.hbase
+
+
+ hbase-hadoop2-compat
+ org.apache.hbase
+
+
+ hbase-client
+ org.apache.hbase
+
+
+ hbase-hadoop-compat
+ org.apache.hbase
+
+
+ tephra-hbase-compat-1.0
+ co.cask.tephra
+
+
+ jaxb-api
+ javax.xml.bind
+
+
+ hive-llap-client
+ org.apache.hive
+
+
+ hive-llap-common
+ org.apache.hive
+
+
+ hive-llap-server
+ org.apache.hive
+
+
+ tephra-core
+ co.cask.tephra
+
+
+ ant
+ ant
+
+
+ stringtemplate
+ org.antlr
+
+
+ antlr-runtime
+ org.antlr
+
+
+ hive-shims
+ org.apache.hive
+
+
+ jsp-api
+ javax.servlet
+
+
+ log4j-api
+ org.apache.logging.log4j
+
+
+ log4j-core
+ org.apache.logging.log4j
+
+
+ log4j-web
+ org.apache.logging.log4j
+
+
+ jasper-compiler
+ tomcat
+
+
+
\ No newline at end of file
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/CommandType.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/CommandType.java
new file mode 100644
index 0000000000..f3aa8ff6d2
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/CommandType.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * command types
+ */
+public enum CommandType {
+
+ /**
+ * command types
+ * 0 start a new process
+ * 1 start a new process from current nodes
+ * 2 recover tolerance fault process
+ * 3 recover suspended process
+ * 4 start process from failure task nodes
+ * 5 complement data
+ * 6 start a new process from scheduler
+ * 7 repeat running a process
+ * 8 pause a process
+ * 9 stop a process
+ * 10 recover waiting thread
+ */
+ START_PROCESS(0, "start a new process"),
+ START_CURRENT_TASK_PROCESS(1, "start a new process from current nodes"),
+ RECOVER_TOLERANCE_FAULT_PROCESS(2, "recover tolerance fault process"),
+ RECOVER_SUSPENDED_PROCESS(3, "recover suspended process"),
+ START_FAILURE_TASK_PROCESS(4, "start process from failure task nodes"),
+ COMPLEMENT_DATA(5, "complement data"),
+ SCHEDULER(6, "start a new process from scheduler"),
+ REPEAT_RUNNING(7, "repeat running a process"),
+ PAUSE(8, "pause a process"),
+ STOP(9, "stop a process"),
+ RECOVER_WAITING_THREAD(10, "recover waiting thread");
+
+ CommandType(int code, String descp) {
+ this.code = code;
+ this.descp = descp;
+ }
+
+ private final int code;
+ private final String descp;
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescp() {
+ return descp;
+ }
+
+ private static final Map COMMAND_TYPE_MAP = new HashMap<>();
+
+ static {
+ for (CommandType commandType : CommandType.values()) {
+ COMMAND_TYPE_MAP.put(commandType.code,commandType);
+ }
+ }
+
+ public static CommandType of(Integer status) {
+ if (COMMAND_TYPE_MAP.containsKey(status)) {
+ return COMMAND_TYPE_MAP.get(status);
+ }
+ throw new IllegalArgumentException("invalid status : " + status);
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DataType.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DataType.java
new file mode 100644
index 0000000000..f4787e5fec
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DataType.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.enums;
+
+/**
+ * data types in user define parameter
+ */
+public enum DataType {
+ /**
+ * 0 string
+ * 1 integer
+ * 2 long
+ * 3 float
+ * 4 double
+ * 5 date, "YYYY-MM-DD"
+ * 6 time, "HH:MM:SS"
+ * 7 time stamp
+ * 8 Boolean
+ * 9 list
+ */
+ VARCHAR,INTEGER,LONG,FLOAT,DOUBLE,DATE,TIME,TIMESTAMP,BOOLEAN,LIST
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbConnectType.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbConnectType.java
new file mode 100644
index 0000000000..72b0322da7
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbConnectType.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.enums;
+
+public enum DbConnectType {
+
+ ORACLE_SERVICE_NAME(0, "Oracle Service Name"),
+ ORACLE_SID(1, "Oracle SID");
+
+ DbConnectType(int code, String descp) {
+ this.code = code;
+ this.descp = descp;
+ }
+
+ private final int code;
+
+ private final String descp;
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescp() {
+ return descp;
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbType.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbType.java
new file mode 100644
index 0000000000..0c88407a02
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbType.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.enums;
+
+import static java.util.stream.Collectors.toMap;
+
+import java.util.Arrays;
+import java.util.Map;
+
+import com.google.common.base.Functions;
+
+public enum DbType {
+
+ MYSQL(0),
+ POSTGRESQL(1),
+ HIVE(2),
+ SPARK(3),
+ CLICKHOUSE(4),
+ ORACLE(5),
+ SQLSERVER(6),
+ DB2(7),
+ PRESTO(8),
+ H2(9);
+
+ DbType(int code) {
+ this.code = code;
+ }
+
+ private final int code;
+
+ public int getCode() {
+ return code;
+ }
+
+ private static final Map DB_TYPE_MAP =
+ Arrays.stream(DbType.values()).collect(toMap(DbType::getCode, Functions.identity()));
+
+ public static DbType of(int type) {
+ if (DB_TYPE_MAP.containsKey(type)) {
+ return DB_TYPE_MAP.get(type);
+ }
+ return null;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/Flag.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/Flag.java
new file mode 100644
index 0000000000..0640259e0d
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/Flag.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.enums;
+
+/**
+ * have_script
+ * have_file
+ * can_retry
+ * have_arr_variables
+ * have_map_variables
+ * have_alert
+ */
+public enum Flag {
+ /**
+ * 0 no
+ * 1 yes
+ */
+ NO(0, "no"),
+ YES(1, "yes");
+
+ Flag(int code, String descp) {
+ this.code = code;
+ this.descp = descp;
+ }
+
+ private final int code;
+ private final String descp;
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescp() {
+ return descp;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/ResUploadType.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/ResUploadType.java
new file mode 100644
index 0000000000..78bbbed9a8
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/ResUploadType.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.enums;
+
+/**
+ * data base types
+ */
+public enum ResUploadType {
+ /**
+ * 0 hdfs
+ * 1 s3
+ * 2 none
+ */
+ HDFS,S3,NONE
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/TaskTimeoutStrategy.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/TaskTimeoutStrategy.java
new file mode 100644
index 0000000000..9df8d55abe
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/TaskTimeoutStrategy.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.enums;
+
+/**
+ * task timeout strategy
+ */
+public enum TaskTimeoutStrategy {
+ /**
+ * 0 warn
+ * 1 failed
+ * 2 warn+failed
+ */
+ WARN(0, "warn"),
+ FAILED(1,"failed"),
+ WARNFAILED(2,"warnfailed");
+
+ TaskTimeoutStrategy(int code, String descp) {
+ this.code = code;
+ this.descp = descp;
+ }
+
+ private final int code;
+ private final String descp;
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescp() {
+ return descp;
+ }
+
+ public static TaskTimeoutStrategy of(int status) {
+ for (TaskTimeoutStrategy es : values()) {
+ if (es.getCode() == status) {
+ return es;
+ }
+ }
+ throw new IllegalArgumentException("invalid status : " + status);
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/AbstractTask.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/AbstractTask.java
index 4c354ef1aa..b0ab09aeb2 100644
--- a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/AbstractTask.java
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/AbstractTask.java
@@ -17,6 +17,8 @@
package org.apache.dolphinscheduler.spi.task;
+import org.apache.dolphinscheduler.spi.task.request.TaskRequest;
+
/**
* executive task
*/
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/Property.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/Property.java
index edd27589cf..cd6e3c1615 100644
--- a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/Property.java
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/Property.java
@@ -17,7 +17,7 @@
package org.apache.dolphinscheduler.spi.task;
-import org.apache.dolphinscheduler.spi.params.base.DataType;
+import org.apache.dolphinscheduler.spi.enums.DataType;
import java.io.Serializable;
import java.util.Objects;
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/TaskChannel.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/TaskChannel.java
index 9ffd545291..7ab3b17aeb 100644
--- a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/TaskChannel.java
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/TaskChannel.java
@@ -15,6 +15,8 @@ package org.apache.dolphinscheduler.spi.task;/*
* limitations under the License.
*/
+import org.apache.dolphinscheduler.spi.task.request.TaskRequest;
+
public interface TaskChannel {
void cancelApplication(boolean status);
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/TaskConstants.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/TaskConstants.java
index 6c34302e44..b7d5cbb01e 100644
--- a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/TaskConstants.java
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/TaskConstants.java
@@ -41,6 +41,54 @@ public class TaskConstants {
*/
public static final String COMMA = ",";
+ /**
+ * slash /
+ */
+ public static final String SLASH = "/";
+
+ /**
+ * COLON :
+ */
+ public static final String COLON = ":";
+
+ /**
+ * SPACE " "
+ */
+ public static final String SPACE = " ";
+
+ /**
+ * SINGLE_SLASH /
+ */
+ public static final String SINGLE_SLASH = "/";
+
+ /**
+ * DOUBLE_SLASH //
+ */
+ public static final String DOUBLE_SLASH = "//";
+
+ /**
+ * SINGLE_QUOTES "'"
+ */
+ public static final String SINGLE_QUOTES = "'";
+ /**
+ * DOUBLE_QUOTES "\""
+ */
+ public static final String DOUBLE_QUOTES = "\"";
+
+ /**
+ * SEMICOLON ;
+ */
+ public static final String SEMICOLON = ";";
+
+ /**
+ * EQUAL SIGN
+ */
+ public static final String EQUAL_SIGN = "=";
+ /**
+ * AT SIGN
+ */
+ public static final String AT_SIGN = "@";
+
/**
* sleep time
*/
@@ -75,4 +123,197 @@ public class TaskConstants {
public static final String RWXR_XR_X = "rwxr-xr-x";
+ /**
+ * task log info format
+ */
+ public static final String TASK_LOG_INFO_FORMAT = "TaskLogInfo-%s";
+
+ /**
+ * date format of yyyyMMdd
+ */
+ public static final String PARAMETER_FORMAT_DATE = "yyyyMMdd";
+
+ /**
+ * date format of yyyyMMddHHmmss
+ */
+ public static final String PARAMETER_FORMAT_TIME = "yyyyMMddHHmmss";
+
+ /**
+ * new
+ * schedule time
+ */
+ public static final String PARAMETER_SHECDULE_TIME = "schedule.time";
+
+ /**
+ * system date(yyyyMMddHHmmss)
+ */
+ public static final String PARAMETER_DATETIME = "system.datetime";
+
+ /**
+ * system date(yyyymmdd) today
+ */
+ public static final String PARAMETER_CURRENT_DATE = "system.biz.curdate";
+
+ /**
+ * system date(yyyymmdd) yesterday
+ */
+ public static final String PARAMETER_BUSINESS_DATE = "system.biz.date";
+
+ /**
+ * the absolute path of current executing task
+ */
+ public static final String PARAMETER_TASK_EXECUTE_PATH = "system.task.execute.path";
+
+ /**
+ * the instance id of current task
+ */
+ public static final String PARAMETER_TASK_INSTANCE_ID = "system.task.instance.id";
+
+ /**
+ * month_begin
+ */
+ public static final String MONTH_BEGIN = "month_begin";
+ /**
+ * add_months
+ */
+ public static final String ADD_MONTHS = "add_months";
+ /**
+ * month_end
+ */
+ public static final String MONTH_END = "month_end";
+ /**
+ * week_begin
+ */
+ public static final String WEEK_BEGIN = "week_begin";
+ /**
+ * week_end
+ */
+ public static final String WEEK_END = "week_end";
+ /**
+ * timestamp
+ */
+ public static final String TIMESTAMP = "timestamp";
+ public static final char SUBTRACT_CHAR = '-';
+ public static final char ADD_CHAR = '+';
+ public static final char MULTIPLY_CHAR = '*';
+ public static final char DIVISION_CHAR = '/';
+ public static final char LEFT_BRACE_CHAR = '(';
+ public static final char RIGHT_BRACE_CHAR = ')';
+ public static final String ADD_STRING = "+";
+ public static final String MULTIPLY_STRING = "*";
+ public static final String DIVISION_STRING = "/";
+ public static final String LEFT_BRACE_STRING = "(";
+ public static final char P = 'P';
+ public static final char N = 'N';
+ public static final String SUBTRACT_STRING = "-";
+ public static final String GLOBAL_PARAMS = "globalParams";
+ public static final String LOCAL_PARAMS = "localParams";
+ public static final String LOCAL_PARAMS_LIST = "localParamsList";
+ public static final String SUBPROCESS_INSTANCE_ID = "subProcessInstanceId";
+ public static final String PROCESS_INSTANCE_STATE = "processInstanceState";
+ public static final String PARENT_WORKFLOW_INSTANCE = "parentWorkflowInstance";
+ public static final String CONDITION_RESULT = "conditionResult";
+ public static final String SWITCH_RESULT = "switchResult";
+ public static final String DEPENDENCE = "dependence";
+ public static final String TASK_TYPE = "taskType";
+ public static final String TASK_LIST = "taskList";
+ public static final String QUEUE = "queue";
+ public static final String QUEUE_NAME = "queueName";
+ public static final int LOG_QUERY_SKIP_LINE_NUMBER = 0;
+ public static final int LOG_QUERY_LIMIT = 4096;
+
+ /**
+ * jar
+ */
+ public static final String JAR = "jar";
+
+ /**
+ * hadoop
+ */
+ public static final String HADOOP = "hadoop";
+
+ /**
+ * -D =
+ */
+ public static final String D = "-D";
+
+ /**
+ * jdbc url
+ */
+ public static final String JDBC_MYSQL = "jdbc:mysql://";
+ public static final String JDBC_POSTGRESQL = "jdbc:postgresql://";
+ public static final String JDBC_HIVE_2 = "jdbc:hive2://";
+ public static final String JDBC_CLICKHOUSE = "jdbc:clickhouse://";
+ public static final String JDBC_ORACLE_SID = "jdbc:oracle:thin:@";
+ public static final String JDBC_ORACLE_SERVICE_NAME = "jdbc:oracle:thin:@//";
+ public static final String JDBC_SQLSERVER = "jdbc:sqlserver://";
+ public static final String JDBC_DB2 = "jdbc:db2://";
+ public static final String JDBC_PRESTO = "jdbc:presto://";
+
+ /**
+ * driver
+ */
+ public static final String ORG_POSTGRESQL_DRIVER = "org.postgresql.Driver";
+ public static final String COM_MYSQL_JDBC_DRIVER = "com.mysql.jdbc.Driver";
+ public static final String ORG_APACHE_HIVE_JDBC_HIVE_DRIVER = "org.apache.hive.jdbc.HiveDriver";
+ public static final String COM_CLICKHOUSE_JDBC_DRIVER = "ru.yandex.clickhouse.ClickHouseDriver";
+ public static final String COM_ORACLE_JDBC_DRIVER = "oracle.jdbc.driver.OracleDriver";
+ public static final String COM_SQLSERVER_JDBC_DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
+ public static final String COM_DB2_JDBC_DRIVER = "com.ibm.db2.jcc.DB2Driver";
+ public static final String COM_PRESTO_JDBC_DRIVER = "com.facebook.presto.jdbc.PrestoDriver";
+
+ /**
+ * datasource encryption salt
+ */
+ public static final String DATASOURCE_ENCRYPTION_SALT_DEFAULT = "!@#$%^&*";
+ public static final String DATASOURCE_ENCRYPTION_ENABLE = "datasource.encryption.enable";
+ public static final String DATASOURCE_ENCRYPTION_SALT = "datasource.encryption.salt";
+
+ /**
+ * resource storage type
+ */
+ public static final String RESOURCE_STORAGE_TYPE = "resource.storage.type";
+
+ /**
+ * kerberos
+ */
+ public static final String KERBEROS = "kerberos";
+
+ /**
+ * kerberos expire time
+ */
+ public static final String KERBEROS_EXPIRE_TIME = "kerberos.expire.time";
+
+ /**
+ * java.security.krb5.conf
+ */
+ public static final String JAVA_SECURITY_KRB5_CONF = "java.security.krb5.conf";
+
+ /**
+ * java.security.krb5.conf.path
+ */
+ public static final String JAVA_SECURITY_KRB5_CONF_PATH = "java.security.krb5.conf.path";
+
+ /**
+ * loginUserFromKeytab user
+ */
+ public static final String LOGIN_USER_KEY_TAB_USERNAME = "login.user.keytab.username";
+
+ /**
+ * loginUserFromKeytab path
+ */
+ public static final String LOGIN_USER_KEY_TAB_PATH = "login.user.keytab.path";
+
+
+ /**
+ * hadoop.security.authentication
+ */
+ public static final String HADOOP_SECURITY_AUTHENTICATION = "hadoop.security.authentication";
+
+ /**
+ * hadoop.security.authentication
+ */
+ public static final String HADOOP_SECURITY_AUTHENTICATION_STARTUP_STATE = "hadoop.security.authentication.startup.state";
+
+
}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/UdfFuncBean.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/UdfFuncBean.java
new file mode 100644
index 0000000000..52e77d60c8
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/UdfFuncBean.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task;
+
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.KeyDeserializer;
+
+/**
+ * udf function
+ */
+public class UdfFuncBean {
+ /**
+ * id
+ */
+ private int id;
+ /**
+ * user id
+ */
+ private int userId;
+
+ /**
+ * udf function name
+ */
+ private String funcName;
+
+ /**
+ * udf class name
+ */
+ private String className;
+
+ /**
+ * udf argument types
+ */
+ private String argTypes;
+
+ /**
+ * udf data base
+ */
+ private String database;
+
+ /**
+ * udf description
+ */
+ private String description;
+
+ /**
+ * resource id
+ */
+ private int resourceId;
+
+ /**
+ * resource name
+ */
+ private String resourceName;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getUserId() {
+ return userId;
+ }
+
+ public void setUserId(int userId) {
+ this.userId = userId;
+ }
+
+ public String getFuncName() {
+ return funcName;
+ }
+
+ public void setFuncName(String funcName) {
+ this.funcName = funcName;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ public String getArgTypes() {
+ return argTypes;
+ }
+
+ public void setArgTypes(String argTypes) {
+ this.argTypes = argTypes;
+ }
+
+ public String getDatabase() {
+ return database;
+ }
+
+ public void setDatabase(String database) {
+ this.database = database;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ public void setResourceName(String resourceName) {
+ this.resourceName = resourceName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ UdfFuncBean udfFunc = (UdfFuncBean) o;
+
+ if (id != udfFunc.id) {
+ return false;
+ }
+ return !(funcName != null ? !funcName.equals(udfFunc.funcName) : udfFunc.funcName != null);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id;
+ result = 31 * result + (funcName != null ? funcName.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return JSONUtils.toJsonString(this);
+ }
+
+ public static class UdfFuncDeserializer extends KeyDeserializer {
+
+ @Override
+ public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException {
+ if (StringUtils.isBlank(key)) {
+ return null;
+ }
+ return JSONUtils.parseObject(key, UdfFuncBean.class);
+ }
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/AbstractDatasourceProcessor.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/AbstractDatasourceProcessor.java
new file mode 100644
index 0000000000..2e5fa2efd3
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/AbstractDatasourceProcessor.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource;
+
+import org.apache.commons.collections4.MapUtils;
+
+import java.util.Map;
+import java.util.regex.Pattern;
+
+public abstract class AbstractDatasourceProcessor implements DatasourceProcessor {
+
+ private static final Pattern IPV4_PATTERN = Pattern.compile("^[a-zA-Z0-9\\_\\-\\.]+$");
+
+ private static final Pattern IPV6_PATTERN = Pattern.compile("^[a-zA-Z0-9\\_\\-\\.\\:\\[\\]]+$");
+
+ private static final Pattern DATABASE_PATTER = Pattern.compile("^[a-zA-Z0-9\\_\\-\\.]+$");
+
+ private static final Pattern PARAMS_PATTER = Pattern.compile("^[a-zA-Z0-9\\-\\_\\/]+$");
+
+ @Override
+ public void checkDatasourceParam(BaseDataSourceParamDTO baseDataSourceParamDTO) {
+ checkHost(baseDataSourceParamDTO.getHost());
+ checkDatasourcePatter(baseDataSourceParamDTO.getDatabase());
+ checkOther(baseDataSourceParamDTO.getOther());
+ }
+
+ /**
+ * Check the host is valid
+ *
+ * @param host datasource host
+ */
+ protected void checkHost(String host) {
+ if (!IPV4_PATTERN.matcher(host).matches() || !IPV6_PATTERN.matcher(host).matches()) {
+ throw new IllegalArgumentException("datasource host illegal");
+ }
+ }
+
+ /**
+ * check database name is valid
+ *
+ * @param database database name
+ */
+ protected void checkDatasourcePatter(String database) {
+ if (!DATABASE_PATTER.matcher(database).matches()) {
+ throw new IllegalArgumentException("datasource name illegal");
+ }
+ }
+
+ /**
+ * check other is valid
+ *
+ * @param other other
+ */
+ protected void checkOther(Map other) {
+ if (MapUtils.isEmpty(other)) {
+ return;
+ }
+ boolean paramsCheck = other.entrySet().stream().allMatch(p -> PARAMS_PATTER.matcher(p.getValue()).matches());
+ if (!paramsCheck) {
+ throw new IllegalArgumentException("datasource other params illegal");
+ }
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseConnectionParam.java
new file mode 100644
index 0000000000..087c2000c8
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseConnectionParam.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource;
+
+import org.apache.dolphinscheduler.spi.task.datasource.clickhouse.ClickhouseConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.db2.Db2ConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.hive.HiveConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.mysql.MysqlConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.oracle.OracleConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.postgresql.PostgreSqlConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.presto.PrestoConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.spark.SparkConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.sqlserver.SqlServerConnectionParam;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+
+/**
+ * The base model of connection param
+ *
+ * {@link ClickhouseConnectionParam}
+ * {@link Db2ConnectionParam}
+ * {@link HiveConnectionParam}
+ * {@link MysqlConnectionParam}
+ * {@link OracleConnectionParam}
+ * {@link PostgreSqlConnectionParam}
+ * {@link PrestoConnectionParam}
+ * {@link SparkConnectionParam}
+ * {@link SqlServerConnectionParam}
+ */
+@JsonInclude(Include.NON_NULL)
+public abstract class BaseConnectionParam implements ConnectionParam {
+
+ protected String user;
+
+ protected String password;
+
+ protected String address;
+
+ protected String database;
+
+ protected String jdbcUrl;
+
+ protected String other;
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getDatabase() {
+ return database;
+ }
+
+ public void setDatabase(String database) {
+ this.database = database;
+ }
+
+ public String getJdbcUrl() {
+ return jdbcUrl;
+ }
+
+ public void setJdbcUrl(String jdbcUrl) {
+ this.jdbcUrl = jdbcUrl;
+ }
+
+ public String getOther() {
+ return other;
+ }
+
+ public void setOther(String other) {
+ this.other = other;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseDataSourceParamDTO.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseDataSourceParamDTO.java
new file mode 100644
index 0000000000..c9ced44ecd
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseDataSourceParamDTO.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.clickhouse.ClickHouseDatasourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.db2.Db2DatasourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.hive.HiveDataSourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.mysql.MysqlDatasourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.oracle.OracleDatasourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.postgresql.PostgreSqlDatasourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.presto.PrestoDatasourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.spark.SparkDatasourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.sqlserver.SqlServerDatasourceParamDTO;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+/**
+ * Basic datasource params submitted to api.
+ *
+ * see {@link MysqlDatasourceParamDTO}
+ * see {@link PostgreSqlDatasourceParamDTO}
+ * see {@link HiveDataSourceParamDTO}
+ * see {@link SparkDatasourceParamDTO}
+ * see {@link ClickHouseDatasourceParamDTO}
+ * see {@link OracleDatasourceParamDTO}
+ * see {@link SqlServerDatasourceParamDTO}
+ * see {@link Db2DatasourceParamDTO}
+ * see {@link PrestoDatasourceParamDTO}
+ */
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
+@JsonSubTypes(value = {
+ @JsonSubTypes.Type(value = MysqlDatasourceParamDTO.class, name = "MYSQL"),
+ @JsonSubTypes.Type(value = PostgreSqlDatasourceParamDTO.class, name = "POSTGRESQL"),
+ @JsonSubTypes.Type(value = HiveDataSourceParamDTO.class, name = "HIVE"),
+ @JsonSubTypes.Type(value = SparkDatasourceParamDTO.class, name = "SPARK"),
+ @JsonSubTypes.Type(value = ClickHouseDatasourceParamDTO.class, name = "CLICKHOUSE"),
+ @JsonSubTypes.Type(value = OracleDatasourceParamDTO.class, name = "ORACLE"),
+ @JsonSubTypes.Type(value = SqlServerDatasourceParamDTO.class, name = "SQLSERVER"),
+ @JsonSubTypes.Type(value = Db2DatasourceParamDTO.class, name = "DB2"),
+ @JsonSubTypes.Type(value = PrestoDatasourceParamDTO.class, name = "PRESTO"),
+})
+public abstract class BaseDataSourceParamDTO implements Serializable {
+
+ protected Integer id;
+
+ protected String name;
+
+ protected String note;
+
+ protected String host;
+
+ protected Integer port;
+
+ protected String database;
+
+ protected String userName;
+
+ protected String password;
+
+ protected Map other;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getNote() {
+ return note;
+ }
+
+ public void setNote(String note) {
+ this.note = note;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public Integer getPort() {
+ return port;
+ }
+
+ public void setPort(Integer port) {
+ this.port = port;
+ }
+
+ public String getDatabase() {
+ return database;
+ }
+
+ public void setDatabase(String database) {
+ this.database = database;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public Map getOther() {
+ return other;
+ }
+
+ public void setOther(Map other) {
+ this.other = other;
+ }
+
+ /**
+ * Get the datasource type
+ * see{@link DbType}
+ *
+ * @return datasource type code
+ */
+ public abstract DbType getType();
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseHdfsConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseHdfsConnectionParam.java
new file mode 100644
index 0000000000..e3f8eb9a74
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseHdfsConnectionParam.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource;
+
+public class BaseHdfsConnectionParam extends BaseConnectionParam {
+ protected String principal;
+ protected String javaSecurityKrb5Conf;
+ protected String loginUserKeytabUsername;
+ protected String loginUserKeytabPath;
+
+ public String getPrincipal() {
+ return principal;
+ }
+
+ public void setPrincipal(String principal) {
+ this.principal = principal;
+ }
+
+ public String getJavaSecurityKrb5Conf() {
+ return javaSecurityKrb5Conf;
+ }
+
+ public void setJavaSecurityKrb5Conf(String javaSecurityKrb5Conf) {
+ this.javaSecurityKrb5Conf = javaSecurityKrb5Conf;
+ }
+
+ public String getLoginUserKeytabUsername() {
+ return loginUserKeytabUsername;
+ }
+
+ public void setLoginUserKeytabUsername(String loginUserKeytabUsername) {
+ this.loginUserKeytabUsername = loginUserKeytabUsername;
+ }
+
+ public String getLoginUserKeytabPath() {
+ return loginUserKeytabPath;
+ }
+
+ public void setLoginUserKeytabPath(String loginUserKeytabPath) {
+ this.loginUserKeytabPath = loginUserKeytabPath;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseHdfsDatasourceParamDTO.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseHdfsDatasourceParamDTO.java
new file mode 100644
index 0000000000..5e03ceb394
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/BaseHdfsDatasourceParamDTO.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource;
+
+public abstract class BaseHdfsDatasourceParamDTO extends BaseDataSourceParamDTO {
+
+ protected String principal;
+
+ protected String javaSecurityKrb5Conf;
+
+ protected String loginUserKeytabUsername;
+
+ protected String loginUserKeytabPath;
+
+ public String getPrincipal() {
+ return principal;
+ }
+
+ public void setPrincipal(String principal) {
+ this.principal = principal;
+ }
+
+ public String getLoginUserKeytabUsername() {
+ return loginUserKeytabUsername;
+ }
+
+ public void setLoginUserKeytabUsername(String loginUserKeytabUsername) {
+ this.loginUserKeytabUsername = loginUserKeytabUsername;
+ }
+
+ public String getLoginUserKeytabPath() {
+ return loginUserKeytabPath;
+ }
+
+ public void setLoginUserKeytabPath(String loginUserKeytabPath) {
+ this.loginUserKeytabPath = loginUserKeytabPath;
+ }
+
+ public String getJavaSecurityKrb5Conf() {
+ return javaSecurityKrb5Conf;
+ }
+
+ public void setJavaSecurityKrb5Conf(String javaSecurityKrb5Conf) {
+ this.javaSecurityKrb5Conf = javaSecurityKrb5Conf;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/ConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/ConnectionParam.java
new file mode 100644
index 0000000000..403ebe2841
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/ConnectionParam.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource;
+
+import java.io.Serializable;
+
+/**
+ * The model of Datasource Connection param
+ */
+public interface ConnectionParam extends Serializable {
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/DatasourceProcessor.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/DatasourceProcessor.java
new file mode 100644
index 0000000000..fe888185d6
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/DatasourceProcessor.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public interface DatasourceProcessor {
+
+ /**
+ * check datasource param is valid
+ */
+ void checkDatasourceParam(BaseDataSourceParamDTO datasourceParam);
+
+ /**
+ * create BaseDataSourceParamDTO by connectionJson
+ *
+ * @param connectionJson see{@link org.apache.dolphinscheduler.dao.entity.Datasource}
+ * @return {@link BaseDataSourceParamDTO}
+ */
+ BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson);
+
+ /**
+ * create datasource connection parameter which will be stored at DataSource
+ *
+ * see {@code org.apache.dolphinscheduler.dao.entity.DataSource.connectionParams}
+ */
+ ConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam);
+
+ /**
+ * deserialize json to datasource connection param
+ *
+ * @param connectionJson {@code org.apache.dolphinscheduler.dao.entity.DataSource.connectionParams}
+ * @return {@link BaseConnectionParam}
+ */
+ ConnectionParam createConnectionParams(String connectionJson);
+
+ /**
+ * get datasource Driver
+ */
+ String getDatasourceDriver();
+
+ /**
+ * get jdbcUrl by connection param, the jdbcUrl is different with ConnectionParam.jdbcUrl, this method will inject
+ * other to jdbcUrl
+ *
+ * @param connectionParam connection param
+ */
+ String getJdbcUrl(ConnectionParam connectionParam);
+
+ /**
+ * get connection by connectionParam
+ *
+ * @param connectionParam connectionParam
+ * @return {@link Connection}
+ */
+ Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException, IOException;
+
+ /**
+ * @return {@link DbType}
+ */
+ DbType getDbType();
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/DatasourceUtil.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/DatasourceUtil.java
new file mode 100644
index 0000000000..c5c4754916
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/DatasourceUtil.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.clickhouse.ClickHouseDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.db2.Db2DatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.hive.HiveDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.mysql.MysqlDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.oracle.OracleDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.postgresql.PostgreSqlDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.presto.PrestoDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.spark.SparkDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.sqlserver.SqlServerDatasourceProcessor;
+
+import java.sql.Connection;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DatasourceUtil {
+
+ private DatasourceUtil() {
+ }
+
+ private static final Logger logger = LoggerFactory.getLogger(DatasourceUtil.class);
+
+ private static final DatasourceProcessor mysqlProcessor = new MysqlDatasourceProcessor();
+ private static final DatasourceProcessor postgreSqlProcessor = new PostgreSqlDatasourceProcessor();
+ private static final DatasourceProcessor hiveProcessor = new HiveDatasourceProcessor();
+ private static final DatasourceProcessor sparkProcessor = new SparkDatasourceProcessor();
+ private static final DatasourceProcessor clickhouseProcessor = new ClickHouseDatasourceProcessor();
+ private static final DatasourceProcessor oracleProcessor = new OracleDatasourceProcessor();
+ private static final DatasourceProcessor sqlServerProcessor = new SqlServerDatasourceProcessor();
+ private static final DatasourceProcessor db2PROCESSOR = new Db2DatasourceProcessor();
+ private static final DatasourceProcessor prestoPROCESSOR = new PrestoDatasourceProcessor();
+
+ /**
+ * check datasource param
+ *
+ * @param baseDataSourceParamDTO datasource param
+ */
+ public static void checkDatasourceParam(BaseDataSourceParamDTO baseDataSourceParamDTO) {
+ getDatasourceProcessor(baseDataSourceParamDTO.getType()).checkDatasourceParam(baseDataSourceParamDTO);
+ }
+
+ /**
+ * build connection url
+ *
+ * @param baseDataSourceParamDTO datasourceParam
+ */
+ public static ConnectionParam buildConnectionParams(BaseDataSourceParamDTO baseDataSourceParamDTO) {
+ ConnectionParam connectionParams = getDatasourceProcessor(baseDataSourceParamDTO.getType())
+ .createConnectionParams(baseDataSourceParamDTO);
+ if (logger.isDebugEnabled()) {
+ logger.info("parameters map:{}", connectionParams);
+ }
+ return connectionParams;
+ }
+
+ public static ConnectionParam buildConnectionParams(DbType dbType, String connectionJson) {
+ return getDatasourceProcessor(dbType).createConnectionParams(connectionJson);
+ }
+
+ public static Connection getConnection(DbType dbType, ConnectionParam connectionParam) {
+ try {
+ return getDatasourceProcessor(dbType).getConnection(connectionParam);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String getJdbcUrl(DbType dbType, ConnectionParam baseConnectionParam) {
+ return getDatasourceProcessor(dbType).getJdbcUrl(baseConnectionParam);
+ }
+
+ public static BaseDataSourceParamDTO buildDatasourceParamDTO(DbType dbType, String connectionParams) {
+ return getDatasourceProcessor(dbType).createDatasourceParamDTO(connectionParams);
+ }
+
+ public static DatasourceProcessor getDatasourceProcessor(DbType dbType) {
+ switch (dbType) {
+ case MYSQL:
+ return mysqlProcessor;
+ case POSTGRESQL:
+ return postgreSqlProcessor;
+ case HIVE:
+ return hiveProcessor;
+ case SPARK:
+ return sparkProcessor;
+ case CLICKHOUSE:
+ return clickhouseProcessor;
+ case ORACLE:
+ return oracleProcessor;
+ case SQLSERVER:
+ return sqlServerProcessor;
+ case DB2:
+ return db2PROCESSOR;
+ case PRESTO:
+ return prestoPROCESSOR;
+ default:
+ throw new IllegalArgumentException("datasource type illegal:" + dbType);
+ }
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/HiveConfUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/HiveConfUtils.java
new file mode 100644
index 0000000000..96485b27cb
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/HiveConfUtils.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * hive conf utils
+ */
+public class HiveConfUtils {
+
+ private HiveConfUtils() {
+ throw new UnsupportedOperationException("Construct HiveConfUtils");
+ }
+
+ private static class HiveConfHandler {
+ private static HiveConf singleton;
+
+ private static Map hiveConfVars;
+
+ static {
+ singleton = new HiveConf();
+ hiveConfVars = new HashMap<>();
+ Arrays.stream(ConfVars.values()).forEach(confVar -> hiveConfVars.put(confVar.varname,confVar));
+ }
+ }
+
+ /**
+ * get HiveConf instance
+ * @return HiveConf hiveConf
+ */
+ public static HiveConf getInstance() {
+ return HiveConfHandler.singleton;
+ }
+
+ /**
+ * get hive conf vars
+ * @return
+ */
+ public static Map getHiveConfVars() {
+ return HiveConfHandler.hiveConfVars;
+ }
+
+ /**
+ * Determine if it belongs to a hive conf property
+ * @param conf config
+ * @return boolean result
+ */
+ public static boolean isHiveConfVar(String conf) {
+ // the default hive conf var name
+ String confKey = conf.split("=")[0];
+ Map hiveConfVars = HiveConfUtils.getHiveConfVars();
+ if (hiveConfVars.get(confKey) != null) {
+ return true;
+ }
+
+ // the security authorization hive conf var name
+ HiveConf hiveConf = HiveConfUtils.getInstance();
+ String hiveAuthorizationSqlStdAuthConfigWhitelist = hiveConf.getVar(HiveConf.ConfVars.HIVE_AUTHORIZATION_SQL_STD_AUTH_CONFIG_WHITELIST);
+ Pattern modWhiteListPattern = Pattern.compile(hiveAuthorizationSqlStdAuthConfigWhitelist);
+ Matcher matcher = modWhiteListPattern.matcher(confKey);
+ return matcher.matches();
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/PasswordUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/PasswordUtils.java
new file mode 100644
index 0000000000..a20cd332bd
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/PasswordUtils.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DATASOURCE_ENCRYPTION_ENABLE;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DATASOURCE_ENCRYPTION_SALT;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DATASOURCE_ENCRYPTION_SALT_DEFAULT;
+
+import org.apache.dolphinscheduler.spi.utils.PropertyUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import org.apache.commons.codec.binary.Base64;
+
+import java.nio.charset.StandardCharsets;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PasswordUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(PasswordUtils.class);
+
+ private static final Base64 BASE64 = new Base64();
+
+ private PasswordUtils() {
+ throw new UnsupportedOperationException("Construct PasswordUtils");
+ }
+
+ /**
+ * encode password
+ */
+ public static String encodePassword(String password) {
+ if (StringUtils.isEmpty(password)) {
+ return StringUtils.EMPTY;
+ }
+ //if encryption is not turned on, return directly
+ boolean encryptionEnable = PropertyUtils.getBoolean(DATASOURCE_ENCRYPTION_ENABLE, false);
+ if (!encryptionEnable) {
+ return password;
+ }
+
+ // Using Base64 + salt to process password
+ String salt = PropertyUtils.getString(DATASOURCE_ENCRYPTION_SALT, DATASOURCE_ENCRYPTION_SALT_DEFAULT);
+ String passwordWithSalt = salt + new String(BASE64.encode(password.getBytes(
+ StandardCharsets.UTF_8)));
+ return new String(BASE64.encode(passwordWithSalt.getBytes(StandardCharsets.UTF_8)));
+ }
+
+ /**
+ * decode password
+ */
+ public static String decodePassword(String password) {
+ if (StringUtils.isEmpty(password)) {
+ return StringUtils.EMPTY;
+ }
+
+ //if encryption is not turned on, return directly
+ boolean encryptionEnable = PropertyUtils.getBoolean(DATASOURCE_ENCRYPTION_ENABLE, false);
+ if (!encryptionEnable) {
+ return password;
+ }
+
+ // Using Base64 + salt to process password
+ String salt = PropertyUtils.getString(DATASOURCE_ENCRYPTION_SALT, DATASOURCE_ENCRYPTION_SALT_DEFAULT);
+ String passwordWithSalt = new String(BASE64.decode(password), StandardCharsets.UTF_8);
+ if (!passwordWithSalt.startsWith(salt)) {
+ logger.warn("There is a password and salt mismatch: {} ", password);
+ return password;
+ }
+ return new String(BASE64.decode(passwordWithSalt.substring(salt.length())), StandardCharsets.UTF_8);
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickHouseDatasourceParamDTO.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickHouseDatasourceParamDTO.java
new file mode 100644
index 0000000000..750552b196
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickHouseDatasourceParamDTO.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.clickhouse;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+
+public class ClickHouseDatasourceParamDTO extends BaseDataSourceParamDTO {
+
+ @Override
+ public String toString() {
+ return "ClickHouseDatasourceParamDTO{"
+ + "host='" + host + '\''
+ + ", port=" + port
+ + ", database='" + database + '\''
+ + ", userName='" + userName + '\''
+ + ", password='" + password + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+
+ @Override
+ public DbType getType() {
+ return DbType.CLICKHOUSE;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickHouseDatasourceProcessor.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickHouseDatasourceProcessor.java
new file mode 100644
index 0000000000..fcc3bc7f56
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickHouseDatasourceProcessor.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.clickhouse;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_CLICKHOUSE_JDBC_DRIVER;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_CLICKHOUSE;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam;
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import org.apache.commons.collections4.MapUtils;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class ClickHouseDatasourceProcessor extends AbstractDatasourceProcessor {
+
+ @Override
+ public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) {
+ ClickhouseConnectionParam connectionParams = (ClickhouseConnectionParam) createConnectionParams(connectionJson);
+
+ ClickHouseDatasourceParamDTO clickHouseDatasourceParamDTO = new ClickHouseDatasourceParamDTO();
+ clickHouseDatasourceParamDTO.setDatabase(connectionParams.getDatabase());
+ clickHouseDatasourceParamDTO.setUserName(connectionParams.getUser());
+ clickHouseDatasourceParamDTO.setOther(parseOther(connectionParams.getOther()));
+
+ String[] hostSeperator = connectionParams.getAddress().split(DOUBLE_SLASH);
+ String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA);
+ clickHouseDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1]));
+ clickHouseDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]);
+
+ return clickHouseDatasourceParamDTO;
+ }
+
+ @Override
+ public ConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) {
+ ClickHouseDatasourceParamDTO clickHouseParam = (ClickHouseDatasourceParamDTO) datasourceParam;
+ String address = String.format("%s%s:%s", JDBC_CLICKHOUSE, clickHouseParam.getHost(), clickHouseParam.getPort());
+ String jdbcUrl = address + "/" + clickHouseParam.getDatabase();
+
+ ClickhouseConnectionParam clickhouseConnectionParam = new ClickhouseConnectionParam();
+ clickhouseConnectionParam.setDatabase(clickHouseParam.getDatabase());
+ clickhouseConnectionParam.setAddress(address);
+ clickhouseConnectionParam.setJdbcUrl(jdbcUrl);
+ clickhouseConnectionParam.setUser(clickHouseParam.getUserName());
+ clickhouseConnectionParam.setPassword(encodePassword(clickHouseParam.getPassword()));
+ clickhouseConnectionParam.setOther(transformOther(clickHouseParam.getOther()));
+ return clickhouseConnectionParam;
+ }
+
+ @Override
+ public ConnectionParam createConnectionParams(String connectionJson) {
+ return JSONUtils.parseObject(connectionJson, ClickhouseConnectionParam.class);
+ }
+
+ @Override
+ public String getDatasourceDriver() {
+ return COM_CLICKHOUSE_JDBC_DRIVER;
+ }
+
+ @Override
+ public String getJdbcUrl(ConnectionParam connectionParam) {
+ ClickhouseConnectionParam clickhouseConnectionParam = (ClickhouseConnectionParam) connectionParam;
+ String jdbcUrl = clickhouseConnectionParam.getJdbcUrl();
+ if (StringUtils.isNotEmpty(clickhouseConnectionParam.getOther())) {
+ jdbcUrl = String.format("%s?%s", jdbcUrl, clickhouseConnectionParam.getOther());
+ }
+ return jdbcUrl;
+ }
+
+ @Override
+ public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException {
+ ClickhouseConnectionParam clickhouseConnectionParam = (ClickhouseConnectionParam) connectionParam;
+ Class.forName(getDatasourceDriver());
+ return DriverManager.getConnection(getJdbcUrl(clickhouseConnectionParam),
+ clickhouseConnectionParam.getUser(), decodePassword(clickhouseConnectionParam.getPassword()));
+ }
+
+ @Override
+ public DbType getDbType() {
+ return DbType.CLICKHOUSE;
+ }
+
+ private String transformOther(Map otherMap) {
+ if (MapUtils.isEmpty(otherMap)) {
+ return null;
+ }
+ StringBuilder stringBuilder = new StringBuilder();
+ otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s%s", key, value, "&")));
+ return stringBuilder.toString();
+ }
+
+ private Map parseOther(String other) {
+ if (other == null) {
+ return null;
+ }
+ Map otherMap = new LinkedHashMap<>();
+ String[] configs = other.split("&");
+ for (String config : configs) {
+ otherMap.put(config.split("=")[0], config.split("=")[1]);
+ }
+ return otherMap;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickhouseConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickhouseConnectionParam.java
new file mode 100644
index 0000000000..38f51f4efb
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/clickhouse/ClickhouseConnectionParam.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.clickhouse;
+
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+
+public class ClickhouseConnectionParam extends BaseConnectionParam {
+ @Override
+ public String toString() {
+ return "ClickhouseConnectionParam{"
+ + "user='" + user + '\''
+ + ", password='" + password + '\''
+ + ", address='" + address + '\''
+ + ", database='" + database + '\''
+ + ", jdbcUrl='" + jdbcUrl + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2ConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2ConnectionParam.java
new file mode 100644
index 0000000000..1460ed7326
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2ConnectionParam.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.db2;
+
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+
+public class Db2ConnectionParam extends BaseConnectionParam {
+ @Override
+ public String toString() {
+ return "Db2ConnectionParam{"
+ + "user='" + user + '\''
+ + ", password='" + password + '\''
+ + ", address='" + address + '\''
+ + ", database='" + database + '\''
+ + ", jdbcUrl='" + jdbcUrl + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2DatasourceParamDTO.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2DatasourceParamDTO.java
new file mode 100644
index 0000000000..d186e75820
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2DatasourceParamDTO.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.db2;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+
+public class Db2DatasourceParamDTO extends BaseDataSourceParamDTO {
+
+ @Override
+ public String toString() {
+ return "Db2DatasourceParamDTO{"
+ + "name='" + name + '\''
+ + ", note='" + note + '\''
+ + ", host='" + host + '\''
+ + ", port=" + port
+ + ", database='" + database + '\''
+ + ", userName='" + userName + '\''
+ + ", password='" + password + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+
+ @Override
+ public DbType getType() {
+ return DbType.DB2;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2DatasourceProcessor.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2DatasourceProcessor.java
new file mode 100644
index 0000000000..2452870f26
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/db2/Db2DatasourceProcessor.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.db2;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_DB2_JDBC_DRIVER;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_DB2;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam;
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import org.apache.commons.collections4.MapUtils;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class Db2DatasourceProcessor extends AbstractDatasourceProcessor {
+
+ @Override
+ public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) {
+ Db2ConnectionParam connectionParams = (Db2ConnectionParam) createConnectionParams(connectionJson);
+
+ Db2DatasourceParamDTO db2DatasourceParamDTO = new Db2DatasourceParamDTO();
+ db2DatasourceParamDTO.setDatabase(connectionParams.getDatabase());
+ db2DatasourceParamDTO.setOther(parseOther(connectionParams.getOther()));
+ db2DatasourceParamDTO.setUserName(db2DatasourceParamDTO.getUserName());
+
+ String[] hostSeperator = connectionParams.getAddress().split(DOUBLE_SLASH);
+ String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA);
+ db2DatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]);
+ db2DatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1]));
+
+ return db2DatasourceParamDTO;
+ }
+
+ @Override
+ public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) {
+ Db2DatasourceParamDTO db2Param = (Db2DatasourceParamDTO) datasourceParam;
+ String address = String.format("%s%s:%s", JDBC_DB2, db2Param.getHost(), db2Param.getPort());
+ String jdbcUrl = String.format("%s/%s", address, db2Param.getDatabase());
+
+ Db2ConnectionParam db2ConnectionParam = new Db2ConnectionParam();
+ db2ConnectionParam.setAddress(address);
+ db2ConnectionParam.setDatabase(db2Param.getDatabase());
+ db2ConnectionParam.setJdbcUrl(jdbcUrl);
+ db2ConnectionParam.setUser(db2Param.getUserName());
+ db2ConnectionParam.setPassword(encodePassword(db2Param.getPassword()));
+ db2ConnectionParam.setOther(transformOther(db2Param.getOther()));
+
+ return db2ConnectionParam;
+ }
+
+ @Override
+ public ConnectionParam createConnectionParams(String connectionJson) {
+ return JSONUtils.parseObject(connectionJson, Db2ConnectionParam.class);
+ }
+
+ @Override
+ public String getDatasourceDriver() {
+ return COM_DB2_JDBC_DRIVER;
+ }
+
+ @Override
+ public String getJdbcUrl(ConnectionParam connectionParam) {
+ Db2ConnectionParam db2ConnectionParam = (Db2ConnectionParam) connectionParam;
+ if (StringUtils.isNotEmpty(db2ConnectionParam.getOther())) {
+ return String.format("%s;%s", db2ConnectionParam.getJdbcUrl(), db2ConnectionParam.getOther());
+ }
+ return db2ConnectionParam.getJdbcUrl();
+ }
+
+ @Override
+ public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException {
+ Db2ConnectionParam db2ConnectionParam = (Db2ConnectionParam) connectionParam;
+ Class.forName(getDatasourceDriver());
+ return DriverManager.getConnection(getJdbcUrl(db2ConnectionParam),
+ db2ConnectionParam.getUser(), decodePassword(db2ConnectionParam.getPassword()));
+ }
+
+ @Override
+ public DbType getDbType() {
+ return DbType.DB2;
+ }
+
+ private String transformOther(Map otherMap) {
+ if (MapUtils.isEmpty(otherMap)) {
+ return null;
+ }
+ StringBuilder stringBuilder = new StringBuilder();
+ otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s%s", key, value, ";")));
+ stringBuilder.deleteCharAt(stringBuilder.length() - 1);
+ return stringBuilder.toString();
+ }
+
+ private Map parseOther(String other) {
+ if (other == null) {
+ return null;
+ }
+ Map otherMap = new LinkedHashMap<>();
+ for (String config : other.split("&")) {
+ otherMap.put(config.split("=")[0], config.split("=")[1]);
+ }
+ return otherMap;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveConnectionParam.java
new file mode 100644
index 0000000000..e77d362822
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveConnectionParam.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.hive;
+
+import org.apache.dolphinscheduler.spi.task.datasource.BaseHdfsConnectionParam;
+
+public class HiveConnectionParam extends BaseHdfsConnectionParam {
+ @Override
+ public String toString() {
+ return "HiveConnectionParam{"
+ + "user='" + user + '\''
+ + ", password='" + password + '\''
+ + ", address='" + address + '\''
+ + ", database='" + database + '\''
+ + ", jdbcUrl='" + jdbcUrl + '\''
+ + ", other='" + other + '\''
+ + ", principal='" + principal + '\''
+ + ", javaSecurityKrb5Conf='" + javaSecurityKrb5Conf + '\''
+ + ", loginUserKeytabUsername='" + loginUserKeytabUsername + '\''
+ + ", loginUserKeytabPath='" + loginUserKeytabPath + '\''
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveDataSourceParamDTO.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveDataSourceParamDTO.java
new file mode 100644
index 0000000000..db967888b7
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveDataSourceParamDTO.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.hive;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseHdfsDatasourceParamDTO;
+
+public class HiveDataSourceParamDTO extends BaseHdfsDatasourceParamDTO {
+
+ @Override
+ public String toString() {
+ return "HiveDataSourceParamDTO{"
+ + "host='" + host + '\''
+ + ", port=" + port
+ + ", database='" + database + '\''
+ + ", principal='" + principal + '\''
+ + ", userName='" + userName + '\''
+ + ", password='" + password + '\''
+ + ", other='" + other + '\''
+ + ", javaSecurityKrb5Conf='" + javaSecurityKrb5Conf + '\''
+ + ", loginUserKeytabUsername='" + loginUserKeytabUsername + '\''
+ + ", loginUserKeytabPath='" + loginUserKeytabPath + '\''
+ + '}';
+ }
+
+ @Override
+ public DbType getType() {
+ return DbType.HIVE;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveDatasourceProcessor.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveDatasourceProcessor.java
new file mode 100644
index 0000000000..e4360e496d
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/hive/HiveDatasourceProcessor.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.hive;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_HIVE_2;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.ORG_APACHE_HIVE_JDBC_HIVE_DRIVER;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.HiveConfUtils;
+import org.apache.dolphinscheduler.spi.utils.CommonUtils;
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import org.apache.commons.collections4.MapUtils;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class HiveDatasourceProcessor extends AbstractDatasourceProcessor {
+
+ @Override
+ public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) {
+ HiveDataSourceParamDTO hiveDataSourceParamDTO = new HiveDataSourceParamDTO();
+ HiveConnectionParam hiveConnectionParam = (HiveConnectionParam) createConnectionParams(connectionJson);
+
+ hiveDataSourceParamDTO.setDatabase(hiveConnectionParam.getDatabase());
+ hiveDataSourceParamDTO.setUserName(hiveConnectionParam.getUser());
+ hiveDataSourceParamDTO.setOther(parseOther(hiveConnectionParam.getOther()));
+ hiveDataSourceParamDTO.setLoginUserKeytabUsername(hiveConnectionParam.getLoginUserKeytabUsername());
+ hiveDataSourceParamDTO.setLoginUserKeytabPath(hiveConnectionParam.getLoginUserKeytabPath());
+ hiveDataSourceParamDTO.setJavaSecurityKrb5Conf(hiveConnectionParam.getJavaSecurityKrb5Conf());
+
+ String[] tmpArray = hiveConnectionParam.getAddress().split(DOUBLE_SLASH);
+ StringBuilder hosts = new StringBuilder();
+ String[] hostPortArray = tmpArray[tmpArray.length - 1].split(COMMA);
+ for (String hostPort : hostPortArray) {
+ hosts.append(hostPort.split(COLON)[0]).append(COMMA);
+ }
+ hosts.deleteCharAt(hosts.length() - 1);
+ hiveDataSourceParamDTO.setHost(hosts.toString());
+ hiveDataSourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1]));
+
+ return hiveDataSourceParamDTO;
+ }
+
+ @Override
+ public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) {
+ HiveDataSourceParamDTO hiveParam = (HiveDataSourceParamDTO) datasourceParam;
+ StringBuilder address = new StringBuilder();
+ address.append(JDBC_HIVE_2);
+ for (String zkHost : hiveParam.getHost().split(",")) {
+ address.append(String.format("%s:%s,", zkHost, hiveParam.getPort()));
+ }
+ address.deleteCharAt(address.length() - 1);
+ String jdbcUrl = address.toString() + "/" + hiveParam.getDatabase();
+ if (CommonUtils.getKerberosStartupState()) {
+ jdbcUrl += ";principal=" + hiveParam.getPrincipal();
+ }
+
+ HiveConnectionParam hiveConnectionParam = new HiveConnectionParam();
+ hiveConnectionParam.setDatabase(hiveParam.getDatabase());
+ hiveConnectionParam.setAddress(address.toString());
+ hiveConnectionParam.setJdbcUrl(jdbcUrl);
+ hiveConnectionParam.setUser(hiveParam.getUserName());
+ hiveConnectionParam.setPassword(encodePassword(hiveParam.getPassword()));
+
+ if (CommonUtils.getKerberosStartupState()) {
+ hiveConnectionParam.setPrincipal(hiveParam.getPrincipal());
+ hiveConnectionParam.setJavaSecurityKrb5Conf(hiveParam.getJavaSecurityKrb5Conf());
+ hiveConnectionParam.setLoginUserKeytabPath(hiveParam.getLoginUserKeytabPath());
+ hiveConnectionParam.setLoginUserKeytabUsername(hiveParam.getLoginUserKeytabUsername());
+ }
+ hiveConnectionParam.setOther(transformOther(hiveParam.getOther()));
+ return hiveConnectionParam;
+ }
+
+ @Override
+ public ConnectionParam createConnectionParams(String connectionJson) {
+ return JSONUtils.parseObject(connectionJson, HiveConnectionParam.class);
+ }
+
+ @Override
+ public String getDatasourceDriver() {
+ return ORG_APACHE_HIVE_JDBC_HIVE_DRIVER;
+ }
+
+ @Override
+ public String getJdbcUrl(ConnectionParam connectionParam) {
+ HiveConnectionParam hiveConnectionParam = (HiveConnectionParam) connectionParam;
+ String jdbcUrl = hiveConnectionParam.getJdbcUrl();
+ String otherParams = filterOther(hiveConnectionParam.getOther());
+ if (StringUtils.isNotEmpty(otherParams) && !"?".equals(otherParams.substring(0, 1))) {
+ jdbcUrl += ";";
+ }
+ return jdbcUrl + otherParams;
+ }
+
+ @Override
+ public Connection getConnection(ConnectionParam connectionParam) throws IOException, ClassNotFoundException, SQLException {
+ HiveConnectionParam hiveConnectionParam = (HiveConnectionParam) connectionParam;
+ CommonUtils.loadKerberosConf(hiveConnectionParam.getJavaSecurityKrb5Conf(),
+ hiveConnectionParam.getLoginUserKeytabUsername(), hiveConnectionParam.getLoginUserKeytabPath());
+ Class.forName(getDatasourceDriver());
+ return DriverManager.getConnection(getJdbcUrl(connectionParam),
+ hiveConnectionParam.getUser(), decodePassword(hiveConnectionParam.getPassword()));
+ }
+
+ @Override
+ public DbType getDbType() {
+ return DbType.HIVE;
+ }
+
+ private String transformOther(Map otherMap) {
+ if (MapUtils.isEmpty(otherMap)) {
+ return null;
+ }
+ StringBuilder stringBuilder = new StringBuilder();
+ otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s;", key, value)));
+ return stringBuilder.toString();
+ }
+
+ private String filterOther(String otherParams) {
+ if (StringUtils.isBlank(otherParams)) {
+ return "";
+ }
+
+ StringBuilder hiveConfListSb = new StringBuilder();
+ hiveConfListSb.append("?");
+ StringBuilder sessionVarListSb = new StringBuilder();
+
+ String[] otherArray = otherParams.split(";", -1);
+
+ for (String conf : otherArray) {
+ if (HiveConfUtils.isHiveConfVar(conf)) {
+ hiveConfListSb.append(conf).append(";");
+ } else {
+ sessionVarListSb.append(conf).append(";");
+ }
+ }
+
+ // remove the last ";"
+ if (sessionVarListSb.length() > 0) {
+ sessionVarListSb.deleteCharAt(sessionVarListSb.length() - 1);
+ }
+
+ if (hiveConfListSb.length() > 0) {
+ hiveConfListSb.deleteCharAt(hiveConfListSb.length() - 1);
+ }
+
+ return sessionVarListSb.toString() + hiveConfListSb.toString();
+ }
+
+ private Map parseOther(String other) {
+ if (other == null) {
+ return null;
+ }
+ Map otherMap = new LinkedHashMap<>();
+ String[] configs = other.split(";");
+ for (String config : configs) {
+ otherMap.put(config.split("=")[0], config.split("=")[1]);
+ }
+ return otherMap;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlConnectionParam.java
new file mode 100644
index 0000000000..8f3e65bc9f
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlConnectionParam.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.mysql;
+
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+
+public class MysqlConnectionParam extends BaseConnectionParam {
+
+ @Override
+ public String toString() {
+ return "MysqlConnectionParam{"
+ + "user='" + user + '\''
+ + ", password='" + password + '\''
+ + ", address='" + address + '\''
+ + ", database='" + database + '\''
+ + ", jdbcUrl='" + jdbcUrl + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlDatasourceParamDTO.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlDatasourceParamDTO.java
new file mode 100644
index 0000000000..48d7aa98d5
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlDatasourceParamDTO.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.mysql;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+
+public class MysqlDatasourceParamDTO extends BaseDataSourceParamDTO {
+
+ @Override
+ public String toString() {
+ return "MysqlDatasourceParamDTO{"
+ + "name='" + name + '\''
+ + ", note='" + note + '\''
+ + ", host='" + host + '\''
+ + ", port=" + port
+ + ", database='" + database + '\''
+ + ", userName='" + userName + '\''
+ + ", password='" + password + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+
+ @Override
+ public DbType getType() {
+ return DbType.MYSQL;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlDatasourceProcessor.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlDatasourceProcessor.java
new file mode 100644
index 0000000000..0ba9671451
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/mysql/MysqlDatasourceProcessor.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.mysql;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_MYSQL_JDBC_DRIVER;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_MYSQL;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam;
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import org.apache.commons.collections4.MapUtils;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MysqlDatasourceProcessor extends AbstractDatasourceProcessor {
+
+ private final Logger logger = LoggerFactory.getLogger(MysqlDatasourceProcessor.class);
+
+ private static final String ALLOW_LOAD_LOCAL_IN_FILE_NAME = "allowLoadLocalInfile";
+
+ private static final String AUTO_DESERIALIZE = "autoDeserialize";
+
+ private static final String ALLOW_LOCAL_IN_FILE_NAME = "allowLocalInfile";
+
+ private static final String ALLOW_URL_IN_LOCAL_IN_FILE_NAME = "allowUrlInLocalInfile";
+
+ private static final String APPEND_PARAMS = "allowLoadLocalInfile=false&autoDeserialize=false&allowLocalInfile=false&allowUrlInLocalInfile=false";
+
+ @Override
+ public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) {
+ MysqlConnectionParam connectionParams = (MysqlConnectionParam) createConnectionParams(connectionJson);
+ MysqlDatasourceParamDTO mysqlDatasourceParamDTO = new MysqlDatasourceParamDTO();
+
+ mysqlDatasourceParamDTO.setUserName(connectionParams.getUser());
+ mysqlDatasourceParamDTO.setDatabase(connectionParams.getDatabase());
+ mysqlDatasourceParamDTO.setOther(parseOther(connectionParams.getOther()));
+
+ String address = connectionParams.getAddress();
+ String[] hostSeperator = address.split(DOUBLE_SLASH);
+ String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA);
+ mysqlDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1]));
+ mysqlDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]);
+
+ return mysqlDatasourceParamDTO;
+ }
+
+ @Override
+ public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO dataSourceParam) {
+ MysqlDatasourceParamDTO mysqlDatasourceParam = (MysqlDatasourceParamDTO) dataSourceParam;
+ String address = String.format("%s%s:%s", JDBC_MYSQL, mysqlDatasourceParam.getHost(), mysqlDatasourceParam.getPort());
+ String jdbcUrl = String.format("%s/%s", address, mysqlDatasourceParam.getDatabase());
+
+ MysqlConnectionParam mysqlConnectionParam = new MysqlConnectionParam();
+ mysqlConnectionParam.setJdbcUrl(jdbcUrl);
+ mysqlConnectionParam.setDatabase(mysqlDatasourceParam.getDatabase());
+ mysqlConnectionParam.setAddress(address);
+ mysqlConnectionParam.setUser(mysqlDatasourceParam.getUserName());
+ mysqlConnectionParam.setPassword(encodePassword(mysqlDatasourceParam.getPassword()));
+ mysqlConnectionParam.setOther(transformOther(mysqlDatasourceParam.getOther()));
+
+ return mysqlConnectionParam;
+ }
+
+ @Override
+ public ConnectionParam createConnectionParams(String connectionJson) {
+ return JSONUtils.parseObject(connectionJson, MysqlConnectionParam.class);
+ }
+
+ @Override
+ public String getDatasourceDriver() {
+ return COM_MYSQL_JDBC_DRIVER;
+ }
+
+ @Override
+ public String getJdbcUrl(ConnectionParam connectionParam) {
+ MysqlConnectionParam mysqlConnectionParam = (MysqlConnectionParam) connectionParam;
+ String jdbcUrl = mysqlConnectionParam.getJdbcUrl();
+ if (StringUtils.isNotEmpty(mysqlConnectionParam.getOther())) {
+ return String.format("%s?%s&%s", jdbcUrl, mysqlConnectionParam.getOther(), APPEND_PARAMS);
+ }
+ return String.format("%s?%s", jdbcUrl, APPEND_PARAMS);
+ }
+
+ @Override
+ public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException {
+ MysqlConnectionParam mysqlConnectionParam = (MysqlConnectionParam) connectionParam;
+ Class.forName(getDatasourceDriver());
+ String user = mysqlConnectionParam.getUser();
+ if (user.contains(AUTO_DESERIALIZE)) {
+ logger.warn("sensitive param : {} in username field is filtered", AUTO_DESERIALIZE);
+ user = user.replace(AUTO_DESERIALIZE, "");
+ }
+ String password = decodePassword(mysqlConnectionParam.getPassword());
+ if (password.contains(AUTO_DESERIALIZE)) {
+ logger.warn("sensitive param : {} in password field is filtered", AUTO_DESERIALIZE);
+ password = password.replace(AUTO_DESERIALIZE, "");
+ }
+ return DriverManager.getConnection(getJdbcUrl(connectionParam), user, password);
+ }
+
+ @Override
+ public DbType getDbType() {
+ return DbType.MYSQL;
+ }
+
+ private String transformOther(Map paramMap) {
+ if (MapUtils.isEmpty(paramMap)) {
+ return null;
+ }
+ Map otherMap = new HashMap<>();
+ paramMap.forEach((k, v) -> {
+ if (!checkKeyIsLegitimate(k)) {
+ return;
+ }
+ otherMap.put(k, v);
+ });
+ if (MapUtils.isEmpty(otherMap)) {
+ return null;
+ }
+ StringBuilder stringBuilder = new StringBuilder();
+ otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s&", key, value)));
+ return stringBuilder.toString();
+ }
+
+ private static boolean checkKeyIsLegitimate(String key) {
+ return !key.contains(ALLOW_LOAD_LOCAL_IN_FILE_NAME)
+ && !key.contains(AUTO_DESERIALIZE)
+ && !key.contains(ALLOW_LOCAL_IN_FILE_NAME)
+ && !key.contains(ALLOW_URL_IN_LOCAL_IN_FILE_NAME);
+ }
+
+ private Map parseOther(String other) {
+ if (StringUtils.isEmpty(other)) {
+ return null;
+ }
+ Map otherMap = new LinkedHashMap<>();
+ for (String config : other.split("&")) {
+ otherMap.put(config.split("=")[0], config.split("=")[1]);
+ }
+ return otherMap;
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleConnectionParam.java
new file mode 100644
index 0000000000..03bf74ddf0
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleConnectionParam.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.oracle;
+
+import org.apache.dolphinscheduler.spi.enums.DbConnectType;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+
+public class OracleConnectionParam extends BaseConnectionParam {
+
+ protected DbConnectType connectType;
+
+ public DbConnectType getConnectType() {
+ return connectType;
+ }
+
+ public void setConnectType(DbConnectType connectType) {
+ this.connectType = connectType;
+ }
+
+ @Override
+ public String toString() {
+ return "OracleConnectionParam{"
+ + "user='" + user + '\''
+ + ", password='" + password + '\''
+ + ", address='" + address + '\''
+ + ", database='" + database + '\''
+ + ", jdbcUrl='" + jdbcUrl + '\''
+ + ", other='" + other + '\''
+ + ", connectType=" + connectType
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleDatasourceParamDTO.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleDatasourceParamDTO.java
new file mode 100644
index 0000000000..07cb8da7d7
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleDatasourceParamDTO.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.oracle;
+
+import org.apache.dolphinscheduler.spi.enums.DbConnectType;
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+
+public class OracleDatasourceParamDTO extends BaseDataSourceParamDTO {
+
+ private DbConnectType connectType;
+
+ public DbConnectType getConnectType() {
+ return connectType;
+ }
+
+ public void setConnectType(DbConnectType connectType) {
+ this.connectType = connectType;
+ }
+
+ @Override
+ public String toString() {
+ return "OracleDatasourceParamDTO{"
+ + "name='" + name + '\''
+ + ", note='" + note + '\''
+ + ", host='" + host + '\''
+ + ", port=" + port
+ + ", database='" + database + '\''
+ + ", userName='" + userName + '\''
+ + ", password='" + password + '\''
+ + ", connectType=" + connectType
+ + ", other='" + other + '\''
+ + '}';
+ }
+
+ @Override
+ public DbType getType() {
+ return DbType.ORACLE;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleDatasourceProcessor.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleDatasourceProcessor.java
new file mode 100644
index 0000000000..7c456a8f16
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/oracle/OracleDatasourceProcessor.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.oracle;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.AT_SIGN;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_ORACLE_JDBC_DRIVER;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_ORACLE_SERVICE_NAME;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_ORACLE_SID;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword;
+
+import org.apache.dolphinscheduler.spi.enums.DbConnectType;
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam;
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import org.apache.commons.collections4.MapUtils;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class OracleDatasourceProcessor extends AbstractDatasourceProcessor {
+
+ @Override
+ public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) {
+ OracleConnectionParam connectionParams = (OracleConnectionParam) createConnectionParams(connectionJson);
+ OracleDatasourceParamDTO oracleDatasourceParamDTO = new OracleDatasourceParamDTO();
+
+ oracleDatasourceParamDTO.setDatabase(connectionParams.getDatabase());
+ oracleDatasourceParamDTO.setUserName(connectionParams.getUser());
+ oracleDatasourceParamDTO.setOther(parseOther(connectionParams.getOther()));
+
+ String hostSeperator = DOUBLE_SLASH;
+ if (DbConnectType.ORACLE_SID.equals(connectionParams.connectType)) {
+ hostSeperator = AT_SIGN;
+ }
+ String[] hostPort = connectionParams.getAddress().split(hostSeperator);
+ String[] hostPortArray = hostPort[hostPort.length - 1].split(COMMA);
+ oracleDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1]));
+ oracleDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]);
+
+ return oracleDatasourceParamDTO;
+ }
+
+ @Override
+ public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) {
+ OracleDatasourceParamDTO oracleParam = (OracleDatasourceParamDTO) datasourceParam;
+ String address;
+ if (DbConnectType.ORACLE_SID.equals(oracleParam.getConnectType())) {
+ address = String.format("%s%s:%s",
+ JDBC_ORACLE_SID, oracleParam.getHost(), oracleParam.getPort());
+ } else {
+ address = String.format("%s%s:%s",
+ JDBC_ORACLE_SERVICE_NAME, oracleParam.getHost(), oracleParam.getPort());
+ }
+ String jdbcUrl = address + "/" + oracleParam.getDatabase();
+
+ OracleConnectionParam oracleConnectionParam = new OracleConnectionParam();
+ oracleConnectionParam.setUser(oracleParam.getUserName());
+ oracleConnectionParam.setPassword(encodePassword(oracleParam.getPassword()));
+ oracleConnectionParam.setAddress(address);
+ oracleConnectionParam.setJdbcUrl(jdbcUrl);
+ oracleConnectionParam.setDatabase(oracleParam.getDatabase());
+ oracleConnectionParam.setConnectType(oracleParam.getConnectType());
+ oracleConnectionParam.setOther(transformOther(oracleParam.getOther()));
+
+ return oracleConnectionParam;
+ }
+
+ @Override
+ public ConnectionParam createConnectionParams(String connectionJson) {
+ return JSONUtils.parseObject(connectionJson, OracleConnectionParam.class);
+ }
+
+ @Override
+ public String getDatasourceDriver() {
+ return COM_ORACLE_JDBC_DRIVER;
+ }
+
+ @Override
+ public String getJdbcUrl(ConnectionParam connectionParam) {
+ OracleConnectionParam oracleConnectionParam = (OracleConnectionParam) connectionParam;
+ if (StringUtils.isNotEmpty(oracleConnectionParam.getOther())) {
+ return String.format("%s?%s", oracleConnectionParam.getJdbcUrl(), oracleConnectionParam.getOther());
+ }
+ return oracleConnectionParam.getJdbcUrl();
+ }
+
+ @Override
+ public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException {
+ OracleConnectionParam oracleConnectionParam = (OracleConnectionParam) connectionParam;
+ Class.forName(getDatasourceDriver());
+ return DriverManager.getConnection(getJdbcUrl(connectionParam),
+ oracleConnectionParam.getUser(), decodePassword(oracleConnectionParam.getPassword()));
+ }
+
+ @Override
+ public DbType getDbType() {
+ return DbType.ORACLE;
+ }
+
+ private String transformOther(Map otherMap) {
+ if (MapUtils.isEmpty(otherMap)) {
+ return null;
+ }
+ List list = new ArrayList<>();
+ otherMap.forEach((key, value) -> list.add(String.format("%s=%s", key, value)));
+ return String.join("&", list);
+ }
+
+ private Map parseOther(String other) {
+ if (StringUtils.isEmpty(other)) {
+ return null;
+ }
+ Map otherMap = new LinkedHashMap<>();
+ String[] configs = other.split("&");
+ for (String config : configs) {
+ otherMap.put(config.split("=")[0], config.split("=")[1]);
+ }
+ return otherMap;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlConnectionParam.java
new file mode 100644
index 0000000000..c63096d333
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlConnectionParam.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.postgresql;
+
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+
+public class PostgreSqlConnectionParam extends BaseConnectionParam {
+ @Override
+ public String toString() {
+ return "PostgreSqlConnectionParam{"
+ + "user='" + user + '\''
+ + ", password='" + password + '\''
+ + ", address='" + address + '\''
+ + ", database='" + database + '\''
+ + ", jdbcUrl='" + jdbcUrl + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlDatasourceParamDTO.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlDatasourceParamDTO.java
new file mode 100644
index 0000000000..14c4aaa636
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlDatasourceParamDTO.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.postgresql;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+
+public class PostgreSqlDatasourceParamDTO extends BaseDataSourceParamDTO {
+
+ @Override
+ public String toString() {
+ return "PostgreSqlDatasourceParamDTO{"
+ + "host='" + host + '\''
+ + ", port=" + port
+ + ", database='" + database + '\''
+ + ", userName='" + userName + '\''
+ + ", password='" + password + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+
+ @Override
+ public DbType getType() {
+ return DbType.POSTGRESQL;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlDatasourceProcessor.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlDatasourceProcessor.java
new file mode 100644
index 0000000000..337809eaaa
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/postgresql/PostgreSqlDatasourceProcessor.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.postgresql;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_POSTGRESQL;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.ORG_POSTGRESQL_DRIVER;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam;
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import org.apache.commons.collections4.MapUtils;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class PostgreSqlDatasourceProcessor extends AbstractDatasourceProcessor {
+
+ @Override
+ public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) {
+ PostgreSqlConnectionParam connectionParams = (PostgreSqlConnectionParam) createConnectionParams(connectionJson);
+ PostgreSqlDatasourceParamDTO postgreSqlDatasourceParamDTO = new PostgreSqlDatasourceParamDTO();
+ postgreSqlDatasourceParamDTO.setDatabase(connectionParams.getDatabase());
+ postgreSqlDatasourceParamDTO.setUserName(connectionParams.getUser());
+ postgreSqlDatasourceParamDTO.setOther(parseOther(connectionParams.getOther()));
+
+ String address = connectionParams.getAddress();
+ String[] hostSeperator = address.split(DOUBLE_SLASH);
+ String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA);
+ postgreSqlDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]);
+ postgreSqlDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1]));
+
+ return postgreSqlDatasourceParamDTO;
+ }
+
+ @Override
+ public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) {
+ PostgreSqlDatasourceParamDTO postgreSqlParam = (PostgreSqlDatasourceParamDTO) datasourceParam;
+ String address = String.format("%s%s:%s", JDBC_POSTGRESQL, postgreSqlParam.getHost(), postgreSqlParam.getPort());
+ String jdbcUrl = String.format("%s/%s", address, postgreSqlParam.getDatabase());
+
+ PostgreSqlConnectionParam postgreSqlConnectionParam = new PostgreSqlConnectionParam();
+ postgreSqlConnectionParam.setJdbcUrl(jdbcUrl);
+ postgreSqlConnectionParam.setAddress(address);
+ postgreSqlConnectionParam.setDatabase(postgreSqlParam.getDatabase());
+ postgreSqlConnectionParam.setUser(postgreSqlParam.getUserName());
+ postgreSqlConnectionParam.setPassword(encodePassword(postgreSqlParam.getPassword()));
+ postgreSqlConnectionParam.setOther(transformOther(postgreSqlParam.getOther()));
+
+ return postgreSqlConnectionParam;
+ }
+
+ @Override
+ public ConnectionParam createConnectionParams(String connectionJson) {
+ return JSONUtils.parseObject(connectionJson, PostgreSqlConnectionParam.class);
+ }
+
+ @Override
+ public String getDatasourceDriver() {
+ return ORG_POSTGRESQL_DRIVER;
+ }
+
+ @Override
+ public String getJdbcUrl(ConnectionParam connectionParam) {
+ PostgreSqlConnectionParam postgreSqlConnectionParam = (PostgreSqlConnectionParam) connectionParam;
+ if (StringUtils.isNotEmpty(postgreSqlConnectionParam.getOther())) {
+ return String.format("%s?%s", postgreSqlConnectionParam.getJdbcUrl(), postgreSqlConnectionParam.getOther());
+ }
+ return postgreSqlConnectionParam.getJdbcUrl();
+ }
+
+ @Override
+ public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException {
+ PostgreSqlConnectionParam postgreSqlConnectionParam = (PostgreSqlConnectionParam) connectionParam;
+ Class.forName(getDatasourceDriver());
+ return DriverManager.getConnection(getJdbcUrl(postgreSqlConnectionParam),
+ postgreSqlConnectionParam.getUser(), decodePassword(postgreSqlConnectionParam.getPassword()));
+ }
+
+ @Override
+ public DbType getDbType() {
+ return DbType.POSTGRESQL;
+ }
+
+ private String transformOther(Map otherMap) {
+ if (MapUtils.isEmpty(otherMap)) {
+ return null;
+ }
+ StringBuilder stringBuilder = new StringBuilder();
+ otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s&", key, value)));
+ return stringBuilder.toString();
+ }
+
+ private Map parseOther(String other) {
+ if (StringUtils.isEmpty(other)) {
+ return null;
+ }
+ Map otherMap = new LinkedHashMap<>();
+ for (String config : other.split("&")) {
+ String[] split = config.split("=");
+ otherMap.put(split[0], split[1]);
+ }
+ return otherMap;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoConnectionParam.java
new file mode 100644
index 0000000000..ac142b6ff0
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoConnectionParam.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.presto;
+
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+
+public class PrestoConnectionParam extends BaseConnectionParam {
+ @Override
+ public String toString() {
+ return "PrestoConnectionParam{"
+ + "user='" + user + '\''
+ + ", password='" + password + '\''
+ + ", address='" + address + '\''
+ + ", database='" + database + '\''
+ + ", jdbcUrl='" + jdbcUrl + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoDatasourceParamDTO.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoDatasourceParamDTO.java
new file mode 100644
index 0000000000..689d6738f8
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoDatasourceParamDTO.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.presto;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+
+public class PrestoDatasourceParamDTO extends BaseDataSourceParamDTO {
+
+ @Override
+ public String toString() {
+ return "PrestoDatasourceParamDTO{"
+ + "name='" + name + '\''
+ + ", note='" + note + '\''
+ + ", host='" + host + '\''
+ + ", port=" + port
+ + ", database='" + database + '\''
+ + ", userName='" + userName + '\''
+ + ", password='" + password + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+
+ @Override
+ public DbType getType() {
+ return DbType.PRESTO;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoDatasourceProcessor.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoDatasourceProcessor.java
new file mode 100644
index 0000000000..55eef138c9
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/presto/PrestoDatasourceProcessor.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.presto;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_PRESTO_JDBC_DRIVER;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_PRESTO;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam;
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import org.apache.commons.collections4.MapUtils;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class PrestoDatasourceProcessor extends AbstractDatasourceProcessor {
+
+ @Override
+ public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) {
+ PrestoConnectionParam connectionParams = (PrestoConnectionParam) createConnectionParams(connectionJson);
+
+ String[] hostSeperator = connectionParams.getAddress().split(DOUBLE_SLASH);
+ String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA);
+
+ PrestoDatasourceParamDTO prestoDatasourceParamDTO = new PrestoDatasourceParamDTO();
+ prestoDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1]));
+ prestoDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]);
+ prestoDatasourceParamDTO.setDatabase(connectionParams.getDatabase());
+ prestoDatasourceParamDTO.setUserName(connectionParams.getUser());
+ prestoDatasourceParamDTO.setOther(parseOther(connectionParams.getOther()));
+
+ return prestoDatasourceParamDTO;
+ }
+
+ @Override
+ public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) {
+ PrestoDatasourceParamDTO prestoParam = (PrestoDatasourceParamDTO) datasourceParam;
+ String address = String.format("%s%s:%s", JDBC_PRESTO, prestoParam.getHost(), prestoParam.getPort());
+ String jdbcUrl = address + "/" + prestoParam.getDatabase();
+
+ PrestoConnectionParam prestoConnectionParam = new PrestoConnectionParam();
+ prestoConnectionParam.setUser(prestoParam.getUserName());
+ prestoConnectionParam.setPassword(encodePassword(prestoParam.getPassword()));
+ prestoConnectionParam.setOther(transformOther(prestoParam.getOther()));
+ prestoConnectionParam.setAddress(address);
+ prestoConnectionParam.setJdbcUrl(jdbcUrl);
+ prestoConnectionParam.setDatabase(prestoParam.getDatabase());
+
+ return prestoConnectionParam;
+ }
+
+ @Override
+ public ConnectionParam createConnectionParams(String connectionJson) {
+ return JSONUtils.parseObject(connectionJson, PrestoConnectionParam.class);
+ }
+
+ @Override
+ public String getDatasourceDriver() {
+ return COM_PRESTO_JDBC_DRIVER;
+ }
+
+ @Override
+ public String getJdbcUrl(ConnectionParam connectionParam) {
+ PrestoConnectionParam prestoConnectionParam = (PrestoConnectionParam) connectionParam;
+ if (StringUtils.isNotEmpty(prestoConnectionParam.getOther())) {
+ return String.format("%s?%s", prestoConnectionParam.getJdbcUrl(), prestoConnectionParam.getOther());
+ }
+ return prestoConnectionParam.getJdbcUrl();
+ }
+
+ @Override
+ public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException {
+ PrestoConnectionParam prestoConnectionParam = (PrestoConnectionParam) connectionParam;
+ Class.forName(getDatasourceDriver());
+ return DriverManager.getConnection(getJdbcUrl(connectionParam),
+ prestoConnectionParam.getUser(), decodePassword(prestoConnectionParam.getPassword()));
+ }
+
+ @Override
+ public DbType getDbType() {
+ return DbType.PRESTO;
+ }
+
+ private String transformOther(Map otherMap) {
+ if (MapUtils.isNotEmpty(otherMap)) {
+ List list = new ArrayList<>();
+ otherMap.forEach((key, value) -> list.add(String.format("%s=%s", key, value)));
+ return String.join("&", list);
+ }
+ return null;
+ }
+
+ private Map parseOther(String other) {
+ if (StringUtils.isEmpty(other)) {
+ return null;
+ }
+ Map otherMap = new LinkedHashMap<>();
+ String[] configs = other.split("&");
+ for (String config : configs) {
+ otherMap.put(config.split("=")[0], config.split("=")[1]);
+ }
+ return otherMap;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkConnectionParam.java
new file mode 100644
index 0000000000..ff226a20e4
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkConnectionParam.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.spark;
+
+import org.apache.dolphinscheduler.spi.task.datasource.BaseHdfsConnectionParam;
+
+public class SparkConnectionParam extends BaseHdfsConnectionParam {
+ @Override
+ public String toString() {
+ return "SparkConnectionParam{"
+ + "user='" + user + '\''
+ + ", password='" + password + '\''
+ + ", address='" + address + '\''
+ + ", database='" + database + '\''
+ + ", jdbcUrl='" + jdbcUrl + '\''
+ + ", other='" + other + '\''
+ + ", principal='" + principal + '\''
+ + ", javaSecurityKrb5Conf='" + javaSecurityKrb5Conf + '\''
+ + ", loginUserKeytabUsername='" + loginUserKeytabUsername + '\''
+ + ", loginUserKeytabPath='" + loginUserKeytabPath + '\''
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkDatasourceParamDTO.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkDatasourceParamDTO.java
new file mode 100644
index 0000000000..afe204751d
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkDatasourceParamDTO.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.spark;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseHdfsDatasourceParamDTO;
+
+public class SparkDatasourceParamDTO extends BaseHdfsDatasourceParamDTO {
+
+ @Override
+ public String toString() {
+ return "SparkDatasourceParamDTO{"
+ + "host='" + host + '\''
+ + ", port=" + port
+ + ", database='" + database + '\''
+ + ", principal='" + principal + '\''
+ + ", userName='" + userName + '\''
+ + ", password='" + password + '\''
+ + ", other='" + other + '\''
+ + ", javaSecurityKrb5Conf='" + javaSecurityKrb5Conf + '\''
+ + ", loginUserKeytabUsername='" + loginUserKeytabUsername + '\''
+ + ", loginUserKeytabPath='" + loginUserKeytabPath + '\''
+ + '}';
+ }
+
+ @Override
+ public DbType getType() {
+ return DbType.SPARK;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkDatasourceProcessor.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkDatasourceProcessor.java
new file mode 100644
index 0000000000..53b4fd9770
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/spark/SparkDatasourceProcessor.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.spark;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_HIVE_2;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.ORG_APACHE_HIVE_JDBC_HIVE_DRIVER;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam;
+import org.apache.dolphinscheduler.spi.utils.CommonUtils;
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import org.apache.commons.collections4.MapUtils;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class SparkDatasourceProcessor extends AbstractDatasourceProcessor {
+
+ @Override
+ public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) {
+ SparkConnectionParam connectionParams = (SparkConnectionParam) createConnectionParams(connectionJson);
+
+ SparkDatasourceParamDTO sparkDatasourceParamDTO = new SparkDatasourceParamDTO();
+ sparkDatasourceParamDTO.setDatabase(connectionParams.getDatabase());
+ sparkDatasourceParamDTO.setUserName(connectionParams.getUser());
+ sparkDatasourceParamDTO.setOther(parseOther(connectionParams.getOther()));
+ sparkDatasourceParamDTO.setJavaSecurityKrb5Conf(connectionParams.getJavaSecurityKrb5Conf());
+ sparkDatasourceParamDTO.setLoginUserKeytabPath(connectionParams.getLoginUserKeytabPath());
+ sparkDatasourceParamDTO.setLoginUserKeytabUsername(connectionParams.getLoginUserKeytabUsername());
+
+ StringBuilder hosts = new StringBuilder();
+ String[] tmpArray = connectionParams.getAddress().split(DOUBLE_SLASH);
+ String[] hostPortArray = tmpArray[tmpArray.length - 1].split(COMMA);
+ Arrays.stream(hostPortArray).forEach(hostPort -> hosts.append(hostPort.split(COLON)[0]).append(COMMA));
+ hosts.deleteCharAt(hosts.length() - 1);
+
+ sparkDatasourceParamDTO.setHost(hosts.toString());
+ sparkDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1]));
+
+ return sparkDatasourceParamDTO;
+ }
+
+ @Override
+ public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO dataSourceParam) {
+ StringBuilder address = new StringBuilder();
+ SparkDatasourceParamDTO sparkDatasourceParam = (SparkDatasourceParamDTO) dataSourceParam;
+ address.append(JDBC_HIVE_2);
+ for (String zkHost : sparkDatasourceParam.getHost().split(",")) {
+ address.append(String.format("%s:%s,", zkHost, sparkDatasourceParam.getPort()));
+ }
+ address.deleteCharAt(address.length() - 1);
+
+ String jdbcUrl = address + "/" + sparkDatasourceParam.getDatabase();
+ if (CommonUtils.getKerberosStartupState()) {
+ jdbcUrl += ";principal=" + sparkDatasourceParam.getPrincipal();
+ }
+
+ SparkConnectionParam sparkConnectionParam = new SparkConnectionParam();
+ sparkConnectionParam.setPassword(encodePassword(sparkDatasourceParam.getPassword()));
+ sparkConnectionParam.setUser(sparkDatasourceParam.getUserName());
+ sparkConnectionParam.setOther(transformOther(sparkDatasourceParam.getOther()));
+ sparkConnectionParam.setDatabase(sparkDatasourceParam.getDatabase());
+ sparkConnectionParam.setAddress(address.toString());
+ sparkConnectionParam.setJdbcUrl(jdbcUrl);
+ if (CommonUtils.getKerberosStartupState()) {
+ sparkConnectionParam.setPrincipal(sparkDatasourceParam.getPrincipal());
+ sparkConnectionParam.setJavaSecurityKrb5Conf(sparkDatasourceParam.getJavaSecurityKrb5Conf());
+ sparkConnectionParam.setLoginUserKeytabPath(sparkDatasourceParam.getLoginUserKeytabPath());
+ sparkConnectionParam.setLoginUserKeytabUsername(sparkDatasourceParam.getLoginUserKeytabUsername());
+ }
+
+ return sparkConnectionParam;
+ }
+
+ @Override
+ public ConnectionParam createConnectionParams(String connectionJson) {
+ return JSONUtils.parseObject(connectionJson, SparkConnectionParam.class);
+ }
+
+ @Override
+ public String getDatasourceDriver() {
+ return ORG_APACHE_HIVE_JDBC_HIVE_DRIVER;
+ }
+
+ @Override
+ public String getJdbcUrl(ConnectionParam connectionParam) {
+ SparkConnectionParam sparkConnectionParam = (SparkConnectionParam) connectionParam;
+ if (StringUtils.isNotEmpty(sparkConnectionParam.getOther())) {
+ return String.format("%s;%s", sparkConnectionParam.getJdbcUrl(), sparkConnectionParam.getOther());
+ }
+ return sparkConnectionParam.getJdbcUrl();
+ }
+
+ @Override
+ public Connection getConnection(ConnectionParam connectionParam) throws IOException, ClassNotFoundException, SQLException {
+ SparkConnectionParam sparkConnectionParam = (SparkConnectionParam) connectionParam;
+ CommonUtils.loadKerberosConf(sparkConnectionParam.getJavaSecurityKrb5Conf(),
+ sparkConnectionParam.getLoginUserKeytabUsername(), sparkConnectionParam.getLoginUserKeytabPath());
+ Class.forName(getDatasourceDriver());
+ return DriverManager.getConnection(getJdbcUrl(sparkConnectionParam),
+ sparkConnectionParam.getUser(), decodePassword(sparkConnectionParam.getPassword()));
+ }
+
+ @Override
+ public DbType getDbType() {
+ return DbType.SPARK;
+ }
+
+ private String transformOther(Map otherMap) {
+ if (MapUtils.isEmpty(otherMap)) {
+ return null;
+ }
+ List stringBuilder = otherMap.entrySet().stream()
+ .map(entry -> String.format("%s=%s", entry.getKey(), entry.getValue())).collect(Collectors.toList());
+ return String.join(";", stringBuilder);
+ }
+
+ private Map parseOther(String other) {
+ if (StringUtils.isEmpty(other)) {
+ return null;
+ }
+ Map otherMap = new LinkedHashMap<>();
+ String[] configs = other.split(";");
+ for (String config : configs) {
+ otherMap.put(config.split("=")[0], config.split("=")[1]);
+ }
+ return otherMap;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerConnectionParam.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerConnectionParam.java
new file mode 100644
index 0000000000..8091cd86b3
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerConnectionParam.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.sqlserver;
+
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+
+public class SqlServerConnectionParam extends BaseConnectionParam {
+ @Override
+ public String toString() {
+ return "SqlServerConnectionParam{"
+ + "user='" + user + '\''
+ + ", password='" + password + '\''
+ + ", address='" + address + '\''
+ + ", database='" + database + '\''
+ + ", jdbcUrl='" + jdbcUrl + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerDatasourceParamDTO.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerDatasourceParamDTO.java
new file mode 100644
index 0000000000..c6024c8a8d
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerDatasourceParamDTO.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.sqlserver;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+
+public class SqlServerDatasourceParamDTO extends BaseDataSourceParamDTO {
+
+ @Override
+ public String toString() {
+ return "SqlServerDatasourceParamDTO{"
+ + "name='" + name + '\''
+ + ", note='" + note + '\''
+ + ", host='" + host + '\''
+ + ", port=" + port
+ + ", database='" + database + '\''
+ + ", userName='" + userName + '\''
+ + ", password='" + password + '\''
+ + ", other='" + other + '\''
+ + '}';
+ }
+
+ @Override
+ public DbType getType() {
+ return DbType.SQLSERVER;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerDatasourceProcessor.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerDatasourceProcessor.java
new file mode 100644
index 0000000000..6b76a6b0a2
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/datasource/sqlserver/SqlServerDatasourceProcessor.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.datasource.sqlserver;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_SQLSERVER_JDBC_DRIVER;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_SQLSERVER;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword;
+import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword;
+
+import org.apache.dolphinscheduler.spi.enums.DbType;
+import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam;
+import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO;
+import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam;
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import org.apache.commons.collections4.MapUtils;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class SqlServerDatasourceProcessor extends AbstractDatasourceProcessor {
+
+ @Override
+ public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) {
+ SqlServerConnectionParam connectionParams = (SqlServerConnectionParam) createConnectionParams(connectionJson);
+ String[] hostSeperator = connectionParams.getAddress().split(DOUBLE_SLASH);
+ String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA);
+
+ SqlServerDatasourceParamDTO sqlServerDatasourceParamDTO = new SqlServerDatasourceParamDTO();
+ sqlServerDatasourceParamDTO.setDatabase(connectionParams.getDatabase());
+ sqlServerDatasourceParamDTO.setUserName(connectionParams.getUser());
+ sqlServerDatasourceParamDTO.setOther(parseOther(connectionParams.getOther()));
+ sqlServerDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1]));
+ sqlServerDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]);
+ return sqlServerDatasourceParamDTO;
+ }
+
+ @Override
+ public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) {
+ SqlServerDatasourceParamDTO sqlServerParam = (SqlServerDatasourceParamDTO) datasourceParam;
+ String address = String.format("%s%s:%s", JDBC_SQLSERVER, sqlServerParam.getHost(), sqlServerParam.getPort());
+ String jdbcUrl = address + ";databaseName=" + sqlServerParam.getDatabase();
+
+ SqlServerConnectionParam sqlServerConnectionParam = new SqlServerConnectionParam();
+ sqlServerConnectionParam.setAddress(address);
+ sqlServerConnectionParam.setDatabase(sqlServerParam.getDatabase());
+ sqlServerConnectionParam.setJdbcUrl(jdbcUrl);
+ sqlServerConnectionParam.setOther(transformOther(sqlServerParam.getOther()));
+ sqlServerConnectionParam.setUser(sqlServerParam.getUserName());
+ sqlServerConnectionParam.setPassword(encodePassword(sqlServerParam.getPassword()));
+ return sqlServerConnectionParam;
+ }
+
+ @Override
+ public BaseConnectionParam createConnectionParams(String connectionJson) {
+ return JSONUtils.parseObject(connectionJson, SqlServerConnectionParam.class);
+ }
+
+ @Override
+ public String getDatasourceDriver() {
+ return COM_SQLSERVER_JDBC_DRIVER;
+ }
+
+ @Override
+ public String getJdbcUrl(ConnectionParam connectionParam) {
+ SqlServerConnectionParam sqlServerConnectionParam = (SqlServerConnectionParam) connectionParam;
+
+ if (StringUtils.isNotEmpty(sqlServerConnectionParam.getOther())) {
+ return String.format("%s;%s", sqlServerConnectionParam.getJdbcUrl(), sqlServerConnectionParam.getOther());
+ }
+ return sqlServerConnectionParam.getJdbcUrl();
+ }
+
+ @Override
+ public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException {
+ SqlServerConnectionParam sqlServerConnectionParam = (SqlServerConnectionParam) connectionParam;
+ Class.forName(getDatasourceDriver());
+ return DriverManager.getConnection(getJdbcUrl(connectionParam), sqlServerConnectionParam.getUser(),
+ decodePassword(sqlServerConnectionParam.getPassword()));
+ }
+
+ @Override
+ public DbType getDbType() {
+ return DbType.SQLSERVER;
+ }
+
+ private String transformOther(Map otherMap) {
+ if (MapUtils.isEmpty(otherMap)) {
+ return null;
+ }
+ StringBuilder stringBuilder = new StringBuilder();
+ otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s;", key, value)));
+ return stringBuilder.toString();
+ }
+
+ private Map parseOther(String other) {
+ if (StringUtils.isEmpty(other)) {
+ return null;
+ }
+ Map otherMap = new LinkedHashMap<>();
+ for (String config : other.split(";")) {
+ otherMap.put(config.split("=")[0], config.split("=")[1]);
+ }
+ return otherMap;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/BusinessTimeUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/BusinessTimeUtils.java
new file mode 100644
index 0000000000..b35598d42e
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/BusinessTimeUtils.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.paramparser;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_BUSINESS_DATE;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_CURRENT_DATE;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_DATETIME;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_FORMAT_DATE;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_FORMAT_TIME;
+import static org.apache.dolphinscheduler.spi.utils.DateUtils.addDays;
+import static org.apache.dolphinscheduler.spi.utils.DateUtils.format;
+
+import org.apache.dolphinscheduler.spi.enums.CommandType;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * business time utils
+ */
+public class BusinessTimeUtils {
+ private BusinessTimeUtils() {
+ throw new IllegalStateException("BusinessTimeUtils class");
+ }
+
+ /**
+ * get business time in parameters by different command types
+ *
+ * @param commandType command type
+ * @param runTime run time or schedule time
+ * @return business time
+ */
+ public static Map getBusinessTime(CommandType commandType, Date runTime) {
+ Date businessDate = runTime;
+ switch (commandType) {
+ case COMPLEMENT_DATA:
+ break;
+ case START_PROCESS:
+ case START_CURRENT_TASK_PROCESS:
+ case RECOVER_TOLERANCE_FAULT_PROCESS:
+ case RECOVER_SUSPENDED_PROCESS:
+ case START_FAILURE_TASK_PROCESS:
+ case REPEAT_RUNNING:
+ case SCHEDULER:
+ default:
+ businessDate = addDays(new Date(), -1);
+ if (runTime != null) {
+ /**
+ * If there is a scheduled time, take the scheduling time. Recovery from failed nodes, suspension of recovery, re-run for scheduling
+ */
+ businessDate = addDays(runTime, -1);
+ }
+ break;
+ }
+ Date businessCurrentDate = addDays(businessDate, 1);
+ Map result = new HashMap<>();
+ result.put(PARAMETER_CURRENT_DATE, format(businessCurrentDate, PARAMETER_FORMAT_DATE));
+ result.put(PARAMETER_BUSINESS_DATE, format(businessDate, PARAMETER_FORMAT_DATE));
+ result.put(PARAMETER_DATETIME, format(businessCurrentDate, PARAMETER_FORMAT_TIME));
+ return result;
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/ParamUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/ParamUtils.java
new file mode 100644
index 0000000000..069f941ff8
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/ParamUtils.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.paramparser;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_TASK_EXECUTE_PATH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_TASK_INSTANCE_ID;
+
+import org.apache.dolphinscheduler.spi.enums.CommandType;
+import org.apache.dolphinscheduler.spi.enums.DataType;
+import org.apache.dolphinscheduler.spi.task.AbstractParameters;
+import org.apache.dolphinscheduler.spi.task.Direct;
+import org.apache.dolphinscheduler.spi.task.Property;
+import org.apache.dolphinscheduler.spi.task.request.TaskRequest;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * param utils
+ */
+public class ParamUtils {
+
+ /**
+ * parameter conversion
+ * Warning:
+ * When you first invoke the function of convert, the variables of localParams and varPool in the ShellParameters will be modified.
+ * But in the whole system the variables of localParams and varPool have been used in other functions. I'm not sure if this current
+ * situation is wrong. So I cannot modify the original logic.
+ *
+ * @param taskExecutionContext the context of this task instance
+ * @param parameters the parameters
+ * @return global params
+ *
+ */
+ public static Map convert(TaskRequest taskExecutionContext, AbstractParameters parameters) {
+ Preconditions.checkNotNull(taskExecutionContext);
+ Preconditions.checkNotNull(parameters);
+ Map globalParams = getUserDefParamsMap(taskExecutionContext.getDefinedParams());
+ Map globalParamsMap = taskExecutionContext.getDefinedParams();
+ CommandType commandType = CommandType.of(taskExecutionContext.getCmdTypeIfComplement());
+ Date scheduleTime = taskExecutionContext.getScheduleTime();
+
+ // combining local and global parameters
+ Map localParams = parameters.getLocalParametersMap();
+
+ Map varParams = parameters.getVarPoolMap();
+
+ if (globalParams == null && localParams == null) {
+ return null;
+ }
+ // if it is a complement,
+ // you need to pass in the task instance id to locate the time
+ // of the process instance complement
+ Map params = BusinessTimeUtils
+ .getBusinessTime(commandType,
+ scheduleTime);
+
+ if (globalParamsMap != null) {
+
+ params.putAll(globalParamsMap);
+ }
+
+ if (StringUtils.isNotBlank(taskExecutionContext.getExecutePath())) {
+ params.put(PARAMETER_TASK_EXECUTE_PATH, taskExecutionContext.getExecutePath());
+ }
+ params.put(PARAMETER_TASK_INSTANCE_ID, Integer.toString(taskExecutionContext.getTaskInstanceId()));
+
+ if (globalParams != null && localParams != null) {
+ globalParams.putAll(localParams);
+ } else if (globalParams == null && localParams != null) {
+ globalParams = localParams;
+ }
+ if (varParams != null) {
+ varParams.putAll(globalParams);
+ globalParams = varParams;
+ }
+ Iterator> iter = globalParams.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry en = iter.next();
+ Property property = en.getValue();
+
+ if (StringUtils.isNotEmpty(property.getValue())
+ && property.getValue().startsWith("$")) {
+ /**
+ * local parameter refers to global parameter with the same name
+ * note: the global parameters of the process instance here are solidified parameters,
+ * and there are no variables in them.
+ */
+ String val = property.getValue();
+
+ val = ParameterUtils.convertParameterPlaceholders(val, params);
+ property.setValue(val);
+ }
+ }
+
+ return globalParams;
+ }
+
+ /**
+ * format convert
+ *
+ * @param paramsMap params map
+ * @return Map of converted
+ */
+ public static Map convert(Map paramsMap) {
+ if (paramsMap == null) {
+ return null;
+ }
+
+ Map map = new HashMap<>();
+ Iterator> iter = paramsMap.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry en = iter.next();
+ map.put(en.getKey(), en.getValue().getValue());
+ }
+ return map;
+ }
+
+ /**
+ * get parameters map
+ *
+ * @param definedParams definedParams
+ * @return parameters map
+ */
+ public static Map getUserDefParamsMap(Map definedParams) {
+ if (definedParams != null) {
+ Map userDefParamsMaps = new HashMap<>();
+ Iterator> iter = definedParams.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry en = iter.next();
+ Property property = new Property(en.getKey(), Direct.IN, DataType.VARCHAR, en.getValue());
+ userDefParamsMaps.put(property.getProp(),property);
+ }
+ return userDefParamsMaps;
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/ParameterUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/ParameterUtils.java
new file mode 100644
index 0000000000..208022f5ca
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/ParameterUtils.java
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.paramparser;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_DATETIME;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_FORMAT_TIME;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_SHECDULE_TIME;
+
+import org.apache.dolphinscheduler.spi.enums.CommandType;
+import org.apache.dolphinscheduler.spi.enums.DataType;
+import org.apache.dolphinscheduler.spi.task.Property;
+import org.apache.dolphinscheduler.spi.utils.DateUtils;
+import org.apache.dolphinscheduler.spi.utils.JSONUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import java.sql.PreparedStatement;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * parameter parse utils
+ */
+public class ParameterUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(ParameterUtils.class);
+
+ private static final String DATE_PARSE_PATTERN = "\\$\\[([^\\$\\]]+)]";
+
+ private static final String DATE_START_PATTERN = "^[0-9]";
+
+ private ParameterUtils() {
+ throw new UnsupportedOperationException("Construct ParameterUtils");
+ }
+
+ /**
+ * convert parameters place holders
+ *
+ * @param parameterString parameter
+ * @param parameterMap parameter map
+ * @return convert parameters place holders
+ */
+ public static String convertParameterPlaceholders(String parameterString, Map parameterMap) {
+ if (StringUtils.isEmpty(parameterString)) {
+ return parameterString;
+ }
+ Date cronTime;
+ if (parameterMap != null && !parameterMap.isEmpty()) {
+ // replace variable ${} form,refers to the replacement of system variables and custom variables
+ parameterString = PlaceholderUtils.replacePlaceholders(parameterString, parameterMap, true);
+ }
+ if (parameterMap != null && null != parameterMap.get(PARAMETER_DATETIME)) {
+ //Get current time, schedule execute time
+ String cronTimeStr = parameterMap.get(PARAMETER_DATETIME);
+ cronTime = DateUtils.parse(cronTimeStr, PARAMETER_FORMAT_TIME);
+ } else {
+ cronTime = new Date();
+ }
+ // replace time $[...] form, eg. $[yyyyMMdd]
+ if (cronTime != null) {
+ return dateTemplateParse(parameterString, cronTime);
+ }
+ return parameterString;
+ }
+
+ /**
+ * new
+ * convert parameters place holders
+ *
+ * @param parameterString parameter
+ * @param parameterMap parameter map
+ * @return convert parameters place holders
+ */
+ public static String convertParameterPlaceholders2(String parameterString, Map parameterMap) {
+ if (StringUtils.isEmpty(parameterString)) {
+ return parameterString;
+ }
+ //Get current time, schedule execute time
+ String cronTimeStr = parameterMap.get(PARAMETER_SHECDULE_TIME);
+ Date cronTime = null;
+
+ if (StringUtils.isNotEmpty(cronTimeStr)) {
+ cronTime = DateUtils.parse(cronTimeStr, PARAMETER_FORMAT_TIME);
+
+ } else {
+ cronTime = new Date();
+ }
+
+ // replace variable ${} form,refers to the replacement of system variables and custom variables
+ if (!parameterMap.isEmpty()) {
+ parameterString = PlaceholderUtils.replacePlaceholders(parameterString, parameterMap, true);
+ }
+
+ // replace time $[...] form, eg. $[yyyyMMdd]
+ if (cronTime != null) {
+ return dateTemplateParse(parameterString, cronTime);
+ }
+ return parameterString;
+ }
+
+ /**
+ * set in parameter
+ *
+ * @param index index
+ * @param stmt preparedstatement
+ * @param dataType data type
+ * @param value value
+ * @throws Exception errors
+ */
+ public static void setInParameter(int index, PreparedStatement stmt, DataType dataType, String value) throws Exception {
+ if (dataType.equals(DataType.VARCHAR)) {
+ stmt.setString(index, value);
+ } else if (dataType.equals(DataType.INTEGER)) {
+ stmt.setInt(index, Integer.parseInt(value));
+ } else if (dataType.equals(DataType.LONG)) {
+ stmt.setLong(index, Long.parseLong(value));
+ } else if (dataType.equals(DataType.FLOAT)) {
+ stmt.setFloat(index, Float.parseFloat(value));
+ } else if (dataType.equals(DataType.DOUBLE)) {
+ stmt.setDouble(index, Double.parseDouble(value));
+ } else if (dataType.equals(DataType.DATE)) {
+ stmt.setDate(index, java.sql.Date.valueOf(value));
+ } else if (dataType.equals(DataType.TIME)) {
+ stmt.setString(index, value);
+ } else if (dataType.equals(DataType.TIMESTAMP)) {
+ stmt.setTimestamp(index, java.sql.Timestamp.valueOf(value));
+ } else if (dataType.equals(DataType.BOOLEAN)) {
+ stmt.setBoolean(index, Boolean.parseBoolean(value));
+ }
+ }
+
+ /**
+ * curing user define parameters
+ *
+ * @param globalParamMap global param map
+ * @param globalParamList global param list
+ * @param commandType command type
+ * @param scheduleTime schedule time
+ * @return curing user define parameters
+ */
+ public static String curingGlobalParams(Map globalParamMap, List globalParamList,
+ CommandType commandType, Date scheduleTime) {
+
+ if (globalParamList == null || globalParamList.isEmpty()) {
+ return null;
+ }
+
+ Map globalMap = new HashMap<>();
+ if (globalParamMap != null) {
+ globalMap.putAll(globalParamMap);
+ }
+ Map allParamMap = new HashMap<>();
+ //If it is a complement, a complement time needs to be passed in, according to the task type
+ Map timeParams = BusinessTimeUtils
+ .getBusinessTime(commandType, scheduleTime);
+
+ if (timeParams != null) {
+ allParamMap.putAll(timeParams);
+ }
+
+ allParamMap.putAll(globalMap);
+
+ Set> entries = allParamMap.entrySet();
+
+ Map resolveMap = new HashMap<>();
+ for (Map.Entry entry : entries) {
+ String val = entry.getValue();
+ if (val.startsWith("$")) {
+ String str = ParameterUtils.convertParameterPlaceholders(val, allParamMap);
+ resolveMap.put(entry.getKey(), str);
+ }
+ }
+ globalMap.putAll(resolveMap);
+
+ for (Property property : globalParamList) {
+ String val = globalMap.get(property.getProp());
+ if (val != null) {
+ property.setValue(val);
+ }
+ }
+ return JSONUtils.toJsonString(globalParamList);
+ }
+
+ /**
+ * $[yyyyMMdd] replace schedule time
+ */
+ public static String replaceScheduleTime(String text, Date scheduleTime) {
+ Map paramsMap = new HashMap<>();
+ //if getScheduleTime null ,is current date
+ if (null == scheduleTime) {
+ scheduleTime = new Date();
+ }
+
+ String dateTime = DateUtils.format(scheduleTime, PARAMETER_FORMAT_TIME);
+ Property p = new Property();
+ p.setValue(dateTime);
+ p.setProp(PARAMETER_SHECDULE_TIME);
+ paramsMap.put(PARAMETER_SHECDULE_TIME, p);
+ text = ParameterUtils.convertParameterPlaceholders2(text, convert(paramsMap));
+
+ return text;
+ }
+
+ /**
+ * format convert
+ *
+ * @param paramsMap params map
+ * @return Map of converted
+ * see org.apache.dolphinscheduler.server.utils.ParamUtils.convert
+ */
+ public static Map convert(Map paramsMap) {
+ Map map = new HashMap<>();
+ Iterator> iter = paramsMap.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry en = iter.next();
+ map.put(en.getKey(), en.getValue().getValue());
+ }
+ return map;
+ }
+
+ private static String dateTemplateParse(String templateStr, Date date) {
+ if (templateStr == null) {
+ return null;
+ }
+ Pattern pattern = Pattern.compile(DATE_PARSE_PATTERN);
+
+ StringBuffer newValue = new StringBuffer(templateStr.length());
+
+ Matcher matcher = pattern.matcher(templateStr);
+
+ while (matcher.find()) {
+ String key = matcher.group(1);
+ if (Pattern.matches(DATE_START_PATTERN, key)) {
+ continue;
+ }
+ String value = TimePlaceholderUtils.getPlaceHolderTime(key, date);
+ assert value != null;
+ matcher.appendReplacement(newValue, value);
+ }
+
+ matcher.appendTail(newValue);
+
+ return newValue.toString();
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/PlaceholderUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/PlaceholderUtils.java
new file mode 100644
index 0000000000..90ee18311a
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/PlaceholderUtils.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.paramparser;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * placeholder utils
+ */
+public class PlaceholderUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(PlaceholderUtils.class);
+
+ /**
+ * Prefix of the position to be replaced
+ */
+ public static final String PLACEHOLDER_PREFIX = "${";
+
+ /**
+ * The suffix of the position to be replaced
+ */
+
+ public static final String PLACEHOLDER_SUFFIX = "}";
+
+ /**
+ * Replaces all placeholders of format {@code ${name}} with the value returned
+ * from the supplied {@link PropertyPlaceholderHelper.PlaceholderResolver}.
+ *
+ * @param value the value containing the placeholders to be replaced
+ * @param paramsMap placeholder data dictionary
+ * @param ignoreUnresolvablePlaceholders ignoreUnresolvablePlaceholders
+ * @return the supplied value with placeholders replaced inline
+ */
+ public static String replacePlaceholders(String value,
+ Map paramsMap,
+ boolean ignoreUnresolvablePlaceholders) {
+ //replacement tool, parameter key will be replaced by value,if can't match , will throw an exception
+ PropertyPlaceholderHelper strictHelper = getPropertyPlaceholderHelper(false);
+
+ //Non-strict replacement tool implementation, when the position to be replaced does not get the corresponding value, the current position is ignored, and the next position is replaced.
+ PropertyPlaceholderHelper nonStrictHelper = getPropertyPlaceholderHelper(true);
+
+ PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper);
+
+ //the PlaceholderResolver to use for replacement
+ return helper.replacePlaceholders(value, new PropertyPlaceholderResolver(value, paramsMap));
+ }
+
+ /**
+ * Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix.
+ * @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should
+ * be ignored ({@code true}) or cause an exception ({@code false})
+ * @return PropertyPlaceholderHelper
+ */
+ public static PropertyPlaceholderHelper getPropertyPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
+
+ return new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, null, ignoreUnresolvablePlaceholders);
+ }
+
+ /**
+ * Placeholder replacement resolver
+ */
+ private static class PropertyPlaceholderResolver implements PropertyPlaceholderHelper.PlaceholderResolver {
+
+ private final String value;
+
+ private final Map paramsMap;
+
+ public PropertyPlaceholderResolver(String value, Map paramsMap) {
+ this.value = value;
+ this.paramsMap = paramsMap;
+ }
+
+ @Override
+ public String resolvePlaceholder(String placeholderName) {
+ try {
+ return paramsMap.get(placeholderName);
+ } catch (Exception ex) {
+ logger.error("resolve placeholder '{}' in [ {} ]", placeholderName, value, ex);
+ return null;
+ }
+ }
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/PropertyPlaceholderHelper.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/PropertyPlaceholderHelper.java
new file mode 100644
index 0000000000..7c571d6c63
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/PropertyPlaceholderHelper.java
@@ -0,0 +1,255 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.paramparser;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class for working with Strings that have placeholder values in them. A placeholder takes the form
+ * {@code ${name}}. Using {@code PropertyPlaceholderHelper} these placeholders can be substituted for
+ * user-supplied values.
Values for substitution can be supplied using a {@link Properties} instance or
+ * using a {@link PlaceholderResolver}.
+ *
+ * @author Juergen Hoeller
+ * @author Rob Harrop
+ * @since 3.0
+ */
+public class PropertyPlaceholderHelper {
+
+ private static final Logger logger = LoggerFactory.getLogger(PropertyPlaceholderHelper.class);
+
+ private static final Map wellKnownSimplePrefixes = new HashMap(4);
+
+ static {
+ wellKnownSimplePrefixes.put("}", "{");
+ wellKnownSimplePrefixes.put("]", "[");
+ wellKnownSimplePrefixes.put(")", "(");
+ }
+
+
+ private final String placeholderPrefix;
+
+ private final String placeholderSuffix;
+
+ private final String simplePrefix;
+
+ private final String valueSeparator;
+
+ private final boolean ignoreUnresolvablePlaceholders;
+
+ /**
+ * Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix.
+ * Unresolvable placeholders are ignored.
+ * @param placeholderPrefix the prefix that denotes the start of a placeholder
+ * @param placeholderSuffix the suffix that denotes the end of a placeholder
+ */
+ public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix) {
+ this(placeholderPrefix, placeholderSuffix, null, true);
+ }
+
+ /**
+ * Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix.
+ * @param placeholderPrefix the prefix that denotes the start of a placeholder
+ * @param placeholderSuffix the suffix that denotes the end of a placeholder
+ * @param valueSeparator the separating character between the placeholder variable
+ * and the associated default value, if any
+ * @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should
+ * be ignored ({@code true}) or cause an exception ({@code false})
+ */
+ public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix,
+ String valueSeparator, boolean ignoreUnresolvablePlaceholders) {
+
+ notNull(placeholderPrefix, "'placeholderPrefix' must not be null");
+ notNull(placeholderSuffix, "'placeholderSuffix' must not be null");
+ this.placeholderPrefix = placeholderPrefix;
+ this.placeholderSuffix = placeholderSuffix;
+ String simplePrefixForSuffix = wellKnownSimplePrefixes.get(this.placeholderSuffix);
+ if (simplePrefixForSuffix != null && this.placeholderPrefix.endsWith(simplePrefixForSuffix)) {
+ this.simplePrefix = simplePrefixForSuffix;
+ }
+ else {
+ this.simplePrefix = this.placeholderPrefix;
+ }
+ this.valueSeparator = valueSeparator;
+ this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
+ }
+
+ /**
+ * Replaces all placeholders of format {@code ${name}} with the corresponding
+ * property from the supplied {@link Properties}.
+ * @param value the value containing the placeholders to be replaced
+ * @param properties the {@code Properties} to use for replacement
+ * @return the supplied value with placeholders replaced inline
+ */
+ public String replacePlaceholders(String value, final Properties properties) {
+ notNull(properties, "'properties' must not be null");
+ return replacePlaceholders(value, new PlaceholderResolver() {
+ @Override
+ public String resolvePlaceholder(String placeholderName) {
+ return properties.getProperty(placeholderName);
+ }
+ });
+ }
+
+ /**
+ * Replaces all placeholders of format {@code ${name}} with the value returned
+ * from the supplied {@link PlaceholderResolver}.
+ * @param value the value containing the placeholders to be replaced
+ * @param placeholderResolver the {@code PlaceholderResolver} to use for replacement
+ * @return the supplied value with placeholders replaced inline
+ */
+ public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
+ notNull(value, "'value' must not be null");
+ return parseStringValue(value, placeholderResolver, new HashSet());
+ }
+
+ protected String parseStringValue(
+ String value, PlaceholderResolver placeholderResolver, Set visitedPlaceholders) {
+
+ StringBuilder result = new StringBuilder(value);
+
+ int startIndex = value.indexOf(this.placeholderPrefix);
+ while (startIndex != -1) {
+ int endIndex = findPlaceholderEndIndex(result, startIndex);
+ if (endIndex != -1) {
+ String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
+ String originalPlaceholder = placeholder;
+ if (!visitedPlaceholders.add(originalPlaceholder)) {
+ throw new IllegalArgumentException(
+ "Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
+ }
+ // Recursive invocation, parsing placeholders contained in the placeholder key.
+ placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
+ // Now obtain the value for the fully resolved key...
+ String propVal = placeholderResolver.resolvePlaceholder(placeholder);
+ if (propVal == null && this.valueSeparator != null) {
+ int separatorIndex = placeholder.indexOf(this.valueSeparator);
+ if (separatorIndex != -1) {
+ String actualPlaceholder = placeholder.substring(0, separatorIndex);
+ String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
+ propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
+ if (propVal == null) {
+ propVal = defaultValue;
+ }
+ }
+ }
+ if (propVal != null) {
+ // Recursive invocation, parsing placeholders contained in the
+ // previously resolved placeholder value.
+ propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
+ result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Resolved placeholder '" + placeholder + "'");
+ }
+ startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
+ }
+ else if (this.ignoreUnresolvablePlaceholders) {
+ // Proceed with unprocessed value.
+ startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
+ }
+ else {
+ throw new IllegalArgumentException("Could not resolve placeholder '"
+ + placeholder + "'" + " in value \"" + value + "\"");
+ }
+ visitedPlaceholders.remove(originalPlaceholder);
+ }
+ else {
+ startIndex = -1;
+ }
+ }
+
+ return result.toString();
+ }
+
+ private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {
+ int index = startIndex + this.placeholderPrefix.length();
+ int withinNestedPlaceholder = 0;
+ while (index < buf.length()) {
+ if (substringMatch(buf, index, this.placeholderSuffix)) {
+ if (withinNestedPlaceholder > 0) {
+ withinNestedPlaceholder--;
+ index = index + this.placeholderSuffix.length();
+ }
+ else {
+ return index;
+ }
+ }
+ else if (substringMatch(buf, index, this.simplePrefix)) {
+ withinNestedPlaceholder++;
+ index = index + this.simplePrefix.length();
+ }
+ else {
+ index++;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Strategy interface used to resolve replacement values for placeholders contained in Strings.
+ */
+ public interface PlaceholderResolver {
+
+ /**
+ * Resolve the supplied placeholder name to the replacement value.
+ * @param placeholderName the name of the placeholder to resolve
+ * @return the replacement value, or {@code null} if no replacement is to be made
+ */
+ String resolvePlaceholder(String placeholderName);
+ }
+
+ /**
+ * Test whether the given string matches the given substring
+ * at the given index.
+ * @param str the original string (or StringBuilder)
+ * @param index the index in the original string to start matching against
+ * @param substring the substring to match at the given index
+ * @return whether the given string matches the given substring
+ */
+ public static boolean substringMatch(CharSequence str, int index, CharSequence substring) {
+ for (int j = 0; j < substring.length(); j++) {
+ int i = index + j;
+ if (i >= str.length() || str.charAt(i) != substring.charAt(j)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Assert that an object is not {@code null}.
+ *
Assert.notNull(clazz, "The class must not be null");
+ * @param object the object to check
+ * @param message the exception message to use if the assertion fails
+ * @throws IllegalArgumentException if the object is {@code null}
+ */
+ public static void notNull(Object object, String message) {
+ if (object == null) {
+ throw new IllegalArgumentException(message);
+ }
+ }
+
+}
+
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/TimePlaceholderUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/TimePlaceholderUtils.java
new file mode 100644
index 0000000000..da72089f92
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/paramparser/TimePlaceholderUtils.java
@@ -0,0 +1,570 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.paramparser;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.ADD_CHAR;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.ADD_MONTHS;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.ADD_STRING;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DIVISION_CHAR;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.DIVISION_STRING;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.LEFT_BRACE_CHAR;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.LEFT_BRACE_STRING;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.MONTH_BEGIN;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.MONTH_END;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.MULTIPLY_CHAR;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.MULTIPLY_STRING;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.N;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.P;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_FORMAT_TIME;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.RIGHT_BRACE_CHAR;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.SUBTRACT_CHAR;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.SUBTRACT_STRING;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.TIMESTAMP;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.WEEK_BEGIN;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.WEEK_END;
+import static org.apache.dolphinscheduler.spi.utils.DateUtils.addDays;
+import static org.apache.dolphinscheduler.spi.utils.DateUtils.addMinutes;
+import static org.apache.dolphinscheduler.spi.utils.DateUtils.addMonths;
+
+import org.apache.dolphinscheduler.spi.utils.DateUtils;
+import org.apache.dolphinscheduler.spi.utils.StringUtils;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * time place holder utils
+ */
+public class TimePlaceholderUtils {
+ private static final Logger logger = LoggerFactory.getLogger(TimePlaceholderUtils.class);
+
+ /**
+ * Prefix of the position to be replaced
+ */
+ public static final String PLACEHOLDER_PREFIX = "$[";
+
+ /**
+ * The suffix of the position to be replaced
+ */
+ public static final String PLACEHOLDER_SUFFIX = "]";
+
+ /**
+ * Replaces all placeholders of format {@code ${name}} with the value returned
+ * from the supplied {@link PropertyPlaceholderHelper.PlaceholderResolver}.
+ *
+ * @param value the value containing the placeholders to be replaced
+ * @param date custom date
+ * @param ignoreUnresolvablePlaceholders ignore unresolvable placeholders
+ * @return the supplied value with placeholders replaced inline
+ */
+ public static String replacePlaceholders(String value, Date date, boolean ignoreUnresolvablePlaceholders) {
+ PropertyPlaceholderHelper strictHelper = getPropertyPlaceholderHelper(false);
+ PropertyPlaceholderHelper nonStrictHelper = getPropertyPlaceholderHelper(true);
+
+ PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper);
+ return helper.replacePlaceholders(value, new TimePlaceholderResolver(value, date));
+ }
+
+ /**
+ * Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix.
+ *
+ * @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should
+ * be ignored ({@code true}) or cause an exception ({@code false})
+ */
+ private static PropertyPlaceholderHelper getPropertyPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
+ return new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, null, ignoreUnresolvablePlaceholders);
+ }
+
+ /**
+ * calculate expression's value
+ *
+ * @param expression expression
+ * @return expression's value
+ */
+ public static Integer calculate(String expression) {
+ expression = StringUtils.trim(expression);
+ expression = convert(expression);
+
+ List result = string2List(expression);
+ result = convert2SuffixList(result);
+
+ return calculate(result);
+ }
+
+ /**
+ * Change the sign in the expression to P (positive) N (negative)
+ *
+ * @param expression
+ * @return eg. "-3+-6*(+8)-(-5) -> S3+S6*(P8)-(S5)"
+ */
+ private static String convert(String expression) {
+ char[] arr = expression.toCharArray();
+
+ for (int i = 0; i < arr.length; i++) {
+ if (arr[i] == SUBTRACT_CHAR) {
+ if (i == 0) {
+ arr[i] = N;
+ } else {
+ char c = arr[i - 1];
+ if (c == ADD_CHAR || c == SUBTRACT_CHAR || c == MULTIPLY_CHAR || c == DIVISION_CHAR || c == LEFT_BRACE_CHAR) {
+ arr[i] = N;
+ }
+ }
+ } else if (arr[i] == ADD_CHAR) {
+ if (i == 0) {
+ arr[i] = P;
+ } else {
+ char c = arr[i - 1];
+ if (c == ADD_CHAR || c == SUBTRACT_CHAR || c == MULTIPLY_CHAR || c == DIVISION_CHAR || c == LEFT_BRACE_CHAR) {
+ arr[i] = P;
+ }
+ }
+ }
+ }
+
+ return new String(arr);
+ }
+
+ /**
+ * to suffix expression
+ *
+ * @param srcList
+ * @return
+ */
+ private static List convert2SuffixList(List srcList) {
+ List result = new ArrayList<>();
+ Stack stack = new Stack<>();
+
+ for (int i = 0; i < srcList.size(); i++) {
+ if (Character.isDigit(srcList.get(i).charAt(0))) {
+ result.add(srcList.get(i));
+ } else {
+ switch (srcList.get(i).charAt(0)) {
+ case LEFT_BRACE_CHAR:
+ stack.push(srcList.get(i));
+ break;
+ case RIGHT_BRACE_CHAR:
+ while (!LEFT_BRACE_STRING.equals(stack.peek())) {
+ result.add(stack.pop());
+ }
+ stack.pop();
+ break;
+ default:
+ while (!stack.isEmpty() && compare(stack.peek(), srcList.get(i))) {
+ result.add(stack.pop());
+ }
+ stack.push(srcList.get(i));
+ break;
+ }
+ }
+ }
+
+ while (!stack.isEmpty()) {
+ result.add(stack.pop());
+ }
+
+ return result;
+ }
+
+ /**
+ * Calculate the suffix expression
+ *
+ * @param result
+ * @return
+ */
+ private static Integer calculate(List result) {
+ Stack stack = new Stack<>();
+ for (int i = 0; i < result.size(); i++) {
+ if (Character.isDigit(result.get(i).charAt(0))) {
+ stack.push(Integer.parseInt(result.get(i)));
+ } else {
+ Integer backInt = stack.pop();
+ Integer frontInt = 0;
+ char op = result.get(i).charAt(0);
+
+ if (!(op == P || op == N)) {
+ frontInt = stack.pop();
+ }
+
+ Integer res = 0;
+ switch (result.get(i).charAt(0)) {
+ case P:
+ res = frontInt + backInt;
+ break;
+ case N:
+ res = frontInt - backInt;
+ break;
+ case ADD_CHAR:
+ res = frontInt + backInt;
+ break;
+ case SUBTRACT_CHAR:
+ res = frontInt - backInt;
+ break;
+ case MULTIPLY_CHAR:
+ res = frontInt * backInt;
+ break;
+ case DIVISION_CHAR:
+ res = frontInt / backInt;
+ break;
+ default:
+ break;
+ }
+ stack.push(res);
+ }
+ }
+
+ return stack.pop();
+ }
+
+ /**
+ * string to list
+ *
+ * @param expression
+ * @return list
+ */
+ private static List string2List(String expression) {
+ List result = new ArrayList<>();
+ String num = "";
+ for (int i = 0; i < expression.length(); i++) {
+ if (Character.isDigit(expression.charAt(i))) {
+ num = num + expression.charAt(i);
+ } else {
+ if (!num.isEmpty()) {
+ result.add(num);
+ }
+ result.add(expression.charAt(i) + "");
+ num = "";
+ }
+ }
+
+ if (!num.isEmpty()) {
+ result.add(num);
+ }
+
+ return result;
+ }
+
+ /**
+ * compare loginUser level
+ *
+ * @param peek
+ * @param cur
+ * @return true or false
+ */
+ private static boolean compare(String peek, String cur) {
+ if (MULTIPLY_STRING.equals(peek) && (DIVISION_STRING.equals(cur) || MULTIPLY_STRING.equals(cur) || ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) {
+ return true;
+ } else if (DIVISION_STRING.equals(peek) && (DIVISION_STRING.equals(cur) || MULTIPLY_STRING.equals(cur) || ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) {
+ return true;
+ } else if (ADD_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) {
+ return true;
+ } else {
+ return SUBTRACT_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur));
+ }
+
+ }
+
+ /**
+ * Placeholder replacement resolver
+ */
+ private static class TimePlaceholderResolver implements
+ PropertyPlaceholderHelper.PlaceholderResolver {
+
+ private final String value;
+
+ private final Date date;
+
+ public TimePlaceholderResolver(String value, Date date) {
+ this.value = value;
+ this.date = date;
+ }
+
+ @Override
+ public String resolvePlaceholder(String placeholderName) {
+ try {
+ return calculateTime(placeholderName, date);
+ } catch (Exception ex) {
+ logger.error("resolve placeholder '{}' in [ {} ]", placeholderName, value, ex);
+ return null;
+ }
+ }
+ }
+
+ /**
+ * return the formatted date according to the corresponding date format
+ *
+ * @param expression date expression
+ * @param date date
+ * @return reformat date
+ */
+ public static String getPlaceHolderTime(String expression, Date date) {
+ if (StringUtils.isBlank(expression)) {
+ return null;
+ }
+ if (null == date) {
+ return null;
+ }
+ return calculateTime(expression, date);
+ }
+
+ /**
+ * calculate time
+ *
+ * @param date date
+ * @return calculate time
+ */
+ private static String calculateTime(String expression, Date date) {
+ // After N years: $[add_months(yyyyMMdd,12*N)], the first N months: $[add_months(yyyyMMdd,-N)], etc
+ String value;
+
+ try {
+ if (expression.startsWith(TIMESTAMP)) {
+ String timeExpression = expression.substring(TIMESTAMP.length() + 1, expression.length() - 1);
+
+ Map.Entry entry = calcTimeExpression(timeExpression, date);
+
+ String dateStr = DateUtils.format(entry.getKey(), entry.getValue());
+
+ Date timestamp = DateUtils.parse(dateStr, PARAMETER_FORMAT_TIME);
+
+ value = String.valueOf(timestamp.getTime() / 1000);
+ } else {
+ Map.Entry entry = calcTimeExpression(expression, date);
+ value = DateUtils.format(entry.getKey(), entry.getValue());
+ }
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
+ throw e;
+ }
+
+ return value;
+ }
+
+ /**
+ * calculate time expresstion
+ *
+ * @param expression expresstion
+ * @param date date
+ * @return map with date, date format
+ */
+ public static Map.Entry calcTimeExpression(String expression, Date date) {
+ Map.Entry resultEntry;
+
+ if (expression.startsWith(ADD_MONTHS)) {
+ resultEntry = calcMonths(expression, date);
+ } else if (expression.startsWith(MONTH_BEGIN)) {
+ resultEntry = calcMonthBegin(expression, date);
+ } else if (expression.startsWith(MONTH_END)) {
+ resultEntry = calcMonthEnd(expression, date);
+ } else if (expression.startsWith(WEEK_BEGIN)) {
+ resultEntry = calcWeekStart(expression, date);
+ } else if (expression.startsWith(WEEK_END)) {
+ resultEntry = calcWeekEnd(expression, date);
+ } else {
+ resultEntry = calcMinutes(expression, date);
+ }
+
+ return resultEntry;
+ }
+
+ /**
+ * get first day of month
+ *
+ * @param expression expresstion
+ * @param date date
+ * @return first day of month
+ */
+ public static Map.Entry calcMonthBegin(String expression, Date date) {
+ String addMonthExpr = expression.substring(MONTH_BEGIN.length() + 1, expression.length() - 1);
+ String[] params = addMonthExpr.split(COMMA);
+
+ if (params.length == 2) {
+ String dateFormat = params[0];
+ String dayExpr = params[1];
+ Integer day = calculate(dayExpr);
+ Date targetDate = DateUtils.getFirstDayOfMonth(date);
+ targetDate = addDays(targetDate, day);
+
+ return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
+ }
+
+ throw new RuntimeException("expression not valid");
+ }
+
+ /**
+ * get last day of month
+ *
+ * @param expression expresstion
+ * @param date date
+ * @return last day of month
+ */
+ public static Map.Entry calcMonthEnd(String expression, Date date) {
+ String addMonthExpr = expression.substring(MONTH_END.length() + 1, expression.length() - 1);
+ String[] params = addMonthExpr.split(COMMA);
+
+ if (params.length == 2) {
+ String dateFormat = params[0];
+ String dayExpr = params[1];
+ Integer day = calculate(dayExpr);
+ Date targetDate = DateUtils.getLastDayOfMonth(date);
+ targetDate = addDays(targetDate, day);
+
+ return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
+ }
+
+ throw new RuntimeException("expression not valid");
+ }
+
+ /**
+ * get first day of week
+ *
+ * @param expression expresstion
+ * @param date date
+ * @return monday
+ */
+ public static Map.Entry calcWeekStart(String expression, Date date) {
+ String addMonthExpr = expression.substring(WEEK_BEGIN.length() + 1, expression.length() - 1);
+ String[] params = addMonthExpr.split(COMMA);
+
+ if (params.length == 2) {
+ String dateFormat = params[0];
+ String dayExpr = params[1];
+ Integer day = calculate(dayExpr);
+ Date targetDate = DateUtils.getMonday(date);
+ targetDate = addDays(targetDate, day);
+ return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
+ }
+
+ throw new RuntimeException("expression not valid");
+ }
+
+ /**
+ * get last day of week
+ *
+ * @param expression expresstion
+ * @param date date
+ * @return last day of week
+ */
+ public static Map.Entry calcWeekEnd(String expression, Date date) {
+ String addMonthExpr = expression.substring(WEEK_END.length() + 1, expression.length() - 1);
+ String[] params = addMonthExpr.split(COMMA);
+
+ if (params.length == 2) {
+ String dateFormat = params[0];
+ String dayExpr = params[1];
+ Integer day = calculate(dayExpr);
+ Date targetDate = DateUtils.getSunday(date);
+ targetDate = addDays(targetDate, day);
+
+ return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
+ }
+
+ throw new RuntimeException("Expression not valid");
+ }
+
+ /**
+ * calc months expression
+ *
+ * @param expression expresstion
+ * @param date date
+ * @return calc months
+ */
+ public static Map.Entry calcMonths(String expression, Date date) {
+ String addMonthExpr = expression.substring(ADD_MONTHS.length() + 1, expression.length() - 1);
+ String[] params = addMonthExpr.split(COMMA);
+
+ if (params.length == 2) {
+ String dateFormat = params[0];
+ String monthExpr = params[1];
+ Integer addMonth = calculate(monthExpr);
+ Date targetDate = addMonths(date, addMonth);
+
+ return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
+ }
+
+ throw new RuntimeException("expression not valid");
+ }
+
+ /**
+ * calculate time expression
+ *
+ * @param expression expresstion
+ * @param date date
+ * @return calculate time expression with date,format
+ */
+ public static Map.Entry calcMinutes(String expression, Date date) {
+ if (expression.contains("+")) {
+ int index = expression.lastIndexOf('+');
+
+ if (Character.isDigit(expression.charAt(index + 1))) {
+ String addMinuteExpr = expression.substring(index + 1);
+ Date targetDate = addMinutes(date, calcMinutes(addMinuteExpr));
+ String dateFormat = expression.substring(0, index);
+
+ return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
+ }
+ } else if (expression.contains("-")) {
+ int index = expression.lastIndexOf('-');
+
+ if (Character.isDigit(expression.charAt(index + 1))) {
+ String addMinuteExpr = expression.substring(index + 1);
+ Date targetDate = addMinutes(date, 0 - calcMinutes(addMinuteExpr));
+ String dateFormat = expression.substring(0, index);
+
+ return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
+ }
+
+ // yyyy-MM-dd/HH:mm:ss
+ return new AbstractMap.SimpleImmutableEntry<>(date, expression);
+ }
+
+ // $[HHmmss]
+ return new AbstractMap.SimpleImmutableEntry<>(date, expression);
+ }
+
+ /**
+ * calculate need minutes
+ *
+ * @param minuteExpression minute expression
+ * @return calculate need minutes
+ */
+ public static Integer calcMinutes(String minuteExpression) {
+ int index = minuteExpression.indexOf('/');
+
+ String calcExpression;
+
+ if (index == -1) {
+ calcExpression = String.format("60*24*(%s)", minuteExpression);
+ } else {
+
+ calcExpression = String.format("60*24*(%s)%s", minuteExpression.substring(0, index),
+ minuteExpression.substring(index));
+ }
+
+ return calculate(calcExpression);
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/DataxTaskRequest.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/DataxTaskRequest.java
new file mode 100644
index 0000000000..8afc397398
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/DataxTaskRequest.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.request;
+
+/**
+ * DataX Task ExecutionContext
+ * to master/worker task transport
+ */
+public class DataxTaskRequest extends TaskRequest {
+
+ /**
+ * dataSourceId
+ */
+ private int dataSourceId;
+
+ /**
+ * sourcetype
+ */
+ private int sourcetype;
+
+ /**
+ * sourceConnectionParams
+ */
+ private String sourceConnectionParams;
+
+ /**
+ * dataTargetId
+ */
+ private int dataTargetId;
+
+ /**
+ * targetType
+ */
+ private int targetType;
+
+ /**
+ * targetConnectionParams
+ */
+ private String targetConnectionParams;
+
+ public int getDataSourceId() {
+ return dataSourceId;
+ }
+
+ public void setDataSourceId(int dataSourceId) {
+ this.dataSourceId = dataSourceId;
+ }
+
+ public int getSourcetype() {
+ return sourcetype;
+ }
+
+ public void setSourcetype(int sourcetype) {
+ this.sourcetype = sourcetype;
+ }
+
+ public String getSourceConnectionParams() {
+ return sourceConnectionParams;
+ }
+
+ public void setSourceConnectionParams(String sourceConnectionParams) {
+ this.sourceConnectionParams = sourceConnectionParams;
+ }
+
+ public int getDataTargetId() {
+ return dataTargetId;
+ }
+
+ public void setDataTargetId(int dataTargetId) {
+ this.dataTargetId = dataTargetId;
+ }
+
+ public int getTargetType() {
+ return targetType;
+ }
+
+ public void setTargetType(int targetType) {
+ this.targetType = targetType;
+ }
+
+ public String getTargetConnectionParams() {
+ return targetConnectionParams;
+ }
+
+ public void setTargetConnectionParams(String targetConnectionParams) {
+ this.targetConnectionParams = targetConnectionParams;
+ }
+
+ @Override
+ public String toString() {
+ return "DataxTaskExecutionContext{"
+ + "dataSourceId=" + dataSourceId
+ + ", sourcetype=" + sourcetype
+ + ", sourceConnectionParams='" + sourceConnectionParams + '\''
+ + ", dataTargetId=" + dataTargetId
+ + ", targetType=" + targetType
+ + ", targetConnectionParams='" + targetConnectionParams + '\''
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/ProcedureTaskRequest.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/ProcedureTaskRequest.java
new file mode 100644
index 0000000000..b043d7f1d4
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/ProcedureTaskRequest.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.request;
+
+/**
+ * Procedure Task ExecutionContext
+ * to master/worker task transport
+ */
+public class ProcedureTaskRequest extends TaskRequest {
+
+ /**
+ * connectionParams
+ */
+ private String connectionParams;
+
+ public String getConnectionParams() {
+ return connectionParams;
+ }
+
+ public void setConnectionParams(String connectionParams) {
+ this.connectionParams = connectionParams;
+ }
+
+ @Override
+ public String toString() {
+ return "ProcedureTaskExecutionContext{"
+ + "connectionParams='" + connectionParams + '\''
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/SQLTaskRequest.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/SQLTaskRequest.java
new file mode 100644
index 0000000000..0608af2fee
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/SQLTaskRequest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.request;
+
+import org.apache.dolphinscheduler.spi.task.UdfFuncBean;
+import org.apache.dolphinscheduler.spi.task.UdfFuncBean.UdfFuncDeserializer;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+
+/**
+ * SQL Task ExecutionContext
+ * to master/worker task transport
+ */
+public class SQLTaskRequest extends TaskRequest {
+
+ /**
+ * warningGroupId
+ */
+ private int warningGroupId;
+
+ /**
+ * connectionParams
+ */
+ private String connectionParams;
+ /**
+ * udf function tenant code map
+ */
+ @JsonDeserialize(keyUsing = UdfFuncDeserializer.class)
+ private Map udfFuncTenantCodeMap;
+
+ public int getWarningGroupId() {
+ return warningGroupId;
+ }
+
+ public void setWarningGroupId(int warningGroupId) {
+ this.warningGroupId = warningGroupId;
+ }
+
+ public Map getUdfFuncTenantCodeMap() {
+ return udfFuncTenantCodeMap;
+ }
+
+ public void setUdfFuncTenantCodeMap(Map udfFuncTenantCodeMap) {
+ this.udfFuncTenantCodeMap = udfFuncTenantCodeMap;
+ }
+
+ public String getConnectionParams() {
+ return connectionParams;
+ }
+
+ public void setConnectionParams(String connectionParams) {
+ this.connectionParams = connectionParams;
+ }
+
+ @Override
+ public String toString() {
+ return "SQLTaskExecutionContext{"
+ + "warningGroupId=" + warningGroupId
+ + ", connectionParams='" + connectionParams + '\''
+ + ", udfFuncTenantCodeMap=" + udfFuncTenantCodeMap
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/SqoopTaskRequest.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/SqoopTaskRequest.java
new file mode 100644
index 0000000000..69f8cf8d66
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/SqoopTaskRequest.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.task.request;
+
+/**
+ * Sqoop Task ExecutionContext
+ * to master/worker task transport
+ */
+public class SqoopTaskRequest extends TaskRequest {
+
+ /**
+ * dataSourceId
+ */
+ private int dataSourceId;
+
+ /**
+ * sourcetype
+ */
+ private int sourcetype;
+
+ /**
+ * sourceConnectionParams
+ */
+ private String sourceConnectionParams;
+
+ /**
+ * dataTargetId
+ */
+ private int dataTargetId;
+
+ /**
+ * targetType
+ */
+ private int targetType;
+
+ /**
+ * targetConnectionParams
+ */
+ private String targetConnectionParams;
+
+ public int getDataSourceId() {
+ return dataSourceId;
+ }
+
+ public void setDataSourceId(int dataSourceId) {
+ this.dataSourceId = dataSourceId;
+ }
+
+ public int getSourcetype() {
+ return sourcetype;
+ }
+
+ public void setSourcetype(int sourcetype) {
+ this.sourcetype = sourcetype;
+ }
+
+ public String getSourceConnectionParams() {
+ return sourceConnectionParams;
+ }
+
+ public void setSourceConnectionParams(String sourceConnectionParams) {
+ this.sourceConnectionParams = sourceConnectionParams;
+ }
+
+ public int getDataTargetId() {
+ return dataTargetId;
+ }
+
+ public void setDataTargetId(int dataTargetId) {
+ this.dataTargetId = dataTargetId;
+ }
+
+ public int getTargetType() {
+ return targetType;
+ }
+
+ public void setTargetType(int targetType) {
+ this.targetType = targetType;
+ }
+
+ public String getTargetConnectionParams() {
+ return targetConnectionParams;
+ }
+
+ public void setTargetConnectionParams(String targetConnectionParams) {
+ this.targetConnectionParams = targetConnectionParams;
+ }
+
+ @Override
+ public String toString() {
+ return "SqoopTaskExecutionContext{"
+ + "dataSourceId=" + dataSourceId
+ + ", sourcetype=" + sourcetype
+ + ", sourceConnectionParams='" + sourceConnectionParams + '\''
+ + ", dataTargetId=" + dataTargetId
+ + ", targetType=" + targetType
+ + ", targetConnectionParams='" + targetConnectionParams + '\''
+ + '}';
+ }
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/TaskRequest.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/TaskRequest.java
similarity index 95%
rename from dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/TaskRequest.java
rename to dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/TaskRequest.java
index 1394c27625..0de96e1734 100644
--- a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/TaskRequest.java
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/task/request/TaskRequest.java
@@ -15,17 +15,21 @@
* limitations under the License.
*/
-package org.apache.dolphinscheduler.spi.task;
+package org.apache.dolphinscheduler.spi.task.request;
+
+import org.apache.dolphinscheduler.spi.enums.TaskTimeoutStrategy;
+import org.apache.dolphinscheduler.spi.task.Property;
import java.util.Date;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat;
+/**
+ * to master/worker task transport
+ */
public class TaskRequest {
-
-
/**
* task id
*/
@@ -157,7 +161,7 @@ public class TaskRequest {
/**
* task timeout strategy
*/
- private int taskTimeoutStrategy;
+ private TaskTimeoutStrategy taskTimeoutStrategy;
/**
* task timeout
@@ -392,11 +396,11 @@ public class TaskRequest {
this.taskAppId = taskAppId;
}
- public int getTaskTimeoutStrategy() {
+ public TaskTimeoutStrategy getTaskTimeoutStrategy() {
return taskTimeoutStrategy;
}
- public void setTaskTimeoutStrategy(int taskTimeoutStrategy) {
+ public void setTaskTimeoutStrategy(TaskTimeoutStrategy taskTimeoutStrategy) {
this.taskTimeoutStrategy = taskTimeoutStrategy;
}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/CommonUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/CommonUtils.java
new file mode 100644
index 0000000000..9017655d1c
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/CommonUtils.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.utils;
+
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.HADOOP_SECURITY_AUTHENTICATION;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.HADOOP_SECURITY_AUTHENTICATION_STARTUP_STATE;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JAVA_SECURITY_KRB5_CONF;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.JAVA_SECURITY_KRB5_CONF_PATH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.KERBEROS;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.LOGIN_USER_KEY_TAB_PATH;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.LOGIN_USER_KEY_TAB_USERNAME;
+import static org.apache.dolphinscheduler.spi.task.TaskConstants.RESOURCE_STORAGE_TYPE;
+
+import org.apache.dolphinscheduler.spi.enums.ResUploadType;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+
+import java.io.IOException;
+
+/**
+ * common utils
+ */
+public class CommonUtils {
+
+ private CommonUtils() {
+ throw new UnsupportedOperationException("Construct CommonUtils");
+ }
+
+ /**
+ * if upload resource is HDFS and kerberos startup is true , else false
+ *
+ * @return true if upload resource is HDFS and kerberos startup
+ */
+ public static boolean getKerberosStartupState() {
+ String resUploadStartupType = PropertyUtils.getUpperCaseString(RESOURCE_STORAGE_TYPE);
+ ResUploadType resUploadType = ResUploadType.valueOf(resUploadStartupType);
+ Boolean kerberosStartupState = PropertyUtils.getBoolean(HADOOP_SECURITY_AUTHENTICATION_STARTUP_STATE, false);
+ return resUploadType == ResUploadType.HDFS && kerberosStartupState;
+ }
+
+ /**
+ * load kerberos configuration
+ *
+ * @param configuration
+ * @return load kerberos config return true
+ * @throws IOException errors
+ */
+ public static boolean loadKerberosConf(Configuration configuration) throws IOException {
+ return loadKerberosConf(PropertyUtils.getString(JAVA_SECURITY_KRB5_CONF_PATH),
+ PropertyUtils.getString(LOGIN_USER_KEY_TAB_USERNAME),
+ PropertyUtils.getString(LOGIN_USER_KEY_TAB_PATH), configuration);
+ }
+
+ /**
+ * load kerberos configuration
+ *
+ * @param javaSecurityKrb5Conf javaSecurityKrb5Conf
+ * @param loginUserKeytabUsername loginUserKeytabUsername
+ * @param loginUserKeytabPath loginUserKeytabPath
+ * @throws IOException errors
+ */
+ public static void loadKerberosConf(String javaSecurityKrb5Conf, String loginUserKeytabUsername, String loginUserKeytabPath) throws IOException {
+ loadKerberosConf(javaSecurityKrb5Conf, loginUserKeytabUsername, loginUserKeytabPath, new Configuration());
+ }
+
+ /**
+ * load kerberos configuration
+ *
+ * @param javaSecurityKrb5Conf javaSecurityKrb5Conf
+ * @param loginUserKeytabUsername loginUserKeytabUsername
+ * @param loginUserKeytabPath loginUserKeytabPath
+ * @param configuration configuration
+ * @return load kerberos config return true
+ * @throws IOException errors
+ */
+ public static boolean loadKerberosConf(String javaSecurityKrb5Conf, String loginUserKeytabUsername, String loginUserKeytabPath, Configuration configuration) throws IOException {
+ if (CommonUtils.getKerberosStartupState()) {
+ System.setProperty(JAVA_SECURITY_KRB5_CONF, StringUtils.defaultIfBlank(javaSecurityKrb5Conf, PropertyUtils.getString(JAVA_SECURITY_KRB5_CONF_PATH)));
+ configuration.set(HADOOP_SECURITY_AUTHENTICATION, KERBEROS);
+ UserGroupInformation.setConfiguration(configuration);
+ UserGroupInformation.loginUserFromKeytab(StringUtils.defaultIfBlank(loginUserKeytabUsername, PropertyUtils.getString(LOGIN_USER_KEY_TAB_USERNAME)),
+ StringUtils.defaultIfBlank(loginUserKeytabPath, PropertyUtils.getString(LOGIN_USER_KEY_TAB_PATH)));
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/Constants.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/Constants.java
index d653d4e435..a3a8b77564 100644
--- a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/Constants.java
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/Constants.java
@@ -52,4 +52,24 @@ public class Constants {
/** string no */
public static final String STRING_NO = "NO";
+ /**
+ * common properties path
+ */
+ public static final String COMMON_PROPERTIES_PATH = "/common.properties";
+
+ /**
+ * date format of yyyy-MM-dd HH:mm:ss
+ */
+ public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
+
+ /**
+ * date format of yyyyMMddHHmmss
+ */
+ public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
+
+ /**
+ * date format of yyyyMMddHHmmssSSS
+ */
+ public static final String YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";
+
}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/DateUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/DateUtils.java
new file mode 100644
index 0000000000..9e63498645
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/DateUtils.java
@@ -0,0 +1,622 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.utils;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Objects;
+import java.util.TimeZone;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * date utils
+ */
+public class DateUtils {
+
+ static final long C0 = 1L;
+ static final long C1 = C0 * 1000L;
+ static final long C2 = C1 * 1000L;
+ static final long C3 = C2 * 1000L;
+ static final long C4 = C3 * 60L;
+ static final long C5 = C4 * 60L;
+ static final long C6 = C5 * 24L;
+
+ /**
+ * a default datetime formatter for the timestamp
+ */
+ private static final DateTimeFormatter DEFAULT_DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+ private static final Logger logger = LoggerFactory.getLogger(DateUtils.class);
+
+ private DateUtils() {
+ throw new UnsupportedOperationException("Construct DateUtils");
+ }
+
+ /**
+ * @param timeMillis timeMillis like System.currentTimeMillis()
+ * @return string formatted as yyyy-MM-dd HH:mm:ss
+ */
+ public static String formatTimeStamp(long timeMillis) {
+ return formatTimeStamp(timeMillis, DEFAULT_DATETIME_FORMATTER);
+ }
+
+ /**
+ * @param timeMillis timeMillis like System.currentTimeMillis()
+ * @param dateTimeFormatter expect formatter, like yyyy-MM-dd HH:mm:ss
+ * @return formatted string
+ */
+ public static String formatTimeStamp(long timeMillis, DateTimeFormatter dateTimeFormatter) {
+ Objects.requireNonNull(dateTimeFormatter);
+ return dateTimeFormatter.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(timeMillis),
+ ZoneId.systemDefault()));
+ }
+
+ /**
+ * date to local datetime
+ *
+ * @param date date
+ * @return local datetime
+ */
+ private static LocalDateTime date2LocalDateTime(Date date) {
+ return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
+ }
+
+ /**
+ * local datetime to date
+ *
+ * @param localDateTime local datetime
+ * @return date
+ */
+ private static Date localDateTime2Date(LocalDateTime localDateTime) {
+ Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
+ return Date.from(instant);
+ }
+
+ /**
+ * get current date str
+ *
+ * @return date string
+ */
+ public static String getCurrentTime() {
+ return getCurrentTime(Constants.YYYY_MM_DD_HH_MM_SS);
+ }
+
+ /**
+ * get the date string in the specified format of the current time
+ *
+ * @param format date format
+ * @return date string
+ */
+ public static String getCurrentTime(String format) {
+ return LocalDateTime.now().format(DateTimeFormatter.ofPattern(format));
+ }
+
+ /**
+ * get the formatted date string
+ *
+ * @param date date
+ * @param format e.g. yyyy-MM-dd HH:mm:ss
+ * @return date string
+ */
+ public static String format(Date date, String format) {
+ return format(date2LocalDateTime(date), format);
+ }
+
+ /**
+ * get the formatted date string
+ *
+ * @param localDateTime local data time
+ * @param format yyyy-MM-dd HH:mm:ss
+ * @return date string
+ */
+ public static String format(LocalDateTime localDateTime, String format) {
+ return localDateTime.format(DateTimeFormatter.ofPattern(format));
+ }
+
+ /**
+ * convert time to yyyy-MM-dd HH:mm:ss format
+ *
+ * @param date date
+ * @return date string
+ */
+ public static String dateToString(Date date) {
+ return format(date, Constants.YYYY_MM_DD_HH_MM_SS);
+ }
+
+ /**
+ * convert string to date and time
+ *
+ * @param date date
+ * @param format format
+ * @return date
+ */
+ public static Date parse(String date, String format) {
+ try {
+ LocalDateTime ldt = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(format));
+ return localDateTime2Date(ldt);
+ } catch (Exception e) {
+ logger.error("error while parse date:" + date, e);
+ }
+ return null;
+ }
+
+ /**
+ * convert date str to yyyy-MM-dd HH:mm:ss format
+ *
+ * @param str date string
+ * @return yyyy-MM-dd HH:mm:ss format
+ */
+ public static Date stringToDate(String str) {
+ return parse(str, Constants.YYYY_MM_DD_HH_MM_SS);
+ }
+
+ /**
+ * get seconds between two dates
+ *
+ * @param d1 date1
+ * @param d2 date2
+ * @return differ seconds
+ */
+ public static long differSec(Date d1, Date d2) {
+ if (d1 == null || d2 == null) {
+ return 0;
+ }
+ return (long) Math.ceil(differMs(d1, d2) / 1000.0);
+ }
+
+ /**
+ * get ms between two dates
+ *
+ * @param d1 date1
+ * @param d2 date2
+ * @return differ ms
+ */
+ public static long differMs(Date d1, Date d2) {
+ return Math.abs(d1.getTime() - d2.getTime());
+ }
+
+ /**
+ * get hours between two dates
+ *
+ * @param d1 date1
+ * @param d2 date2
+ * @return differ hours
+ */
+ public static long diffHours(Date d1, Date d2) {
+ return (long) Math.ceil(diffMin(d1, d2) / 60.0);
+ }
+
+ /**
+ * get minutes between two dates
+ *
+ * @param d1 date1
+ * @param d2 date2
+ * @return differ minutes
+ */
+ public static long diffMin(Date d1, Date d2) {
+ return (long) Math.ceil(differSec(d1, d2) / 60.0);
+ }
+
+ /**
+ * get the date of the specified date in the days before and after
+ *
+ * @param date date
+ * @param day day
+ * @return the date of the specified date in the days before and after
+ */
+ public static Date getSomeDay(Date date, int day) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ calendar.add(Calendar.DATE, day);
+ return calendar.getTime();
+ }
+
+ /**
+ * get the hour of day.
+ *
+ * @param date date
+ * @return hour of day
+ */
+ public static int getHourIndex(Date date) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ return calendar.get(Calendar.HOUR_OF_DAY);
+ }
+
+ /**
+ * compare two dates
+ *
+ * @param future future date
+ * @param old old date
+ * @return true if future time greater than old time
+ */
+ public static boolean compare(Date future, Date old) {
+ return future.getTime() > old.getTime();
+ }
+
+ /**
+ * convert schedule string to date
+ *
+ * @param schedule schedule
+ * @return convert schedule string to date
+ */
+ public static Date getScheduleDate(String schedule) {
+ return stringToDate(schedule);
+ }
+
+ /**
+ * format time to readable
+ *
+ * @param ms ms
+ * @return format time
+ */
+ public static String format2Readable(long ms) {
+
+ long days = MILLISECONDS.toDays(ms);
+ long hours = MILLISECONDS.toDurationHours(ms);
+ long minutes = MILLISECONDS.toDurationMinutes(ms);
+ long seconds = MILLISECONDS.toDurationSeconds(ms);
+
+ return String.format("%02d %02d:%02d:%02d", days, hours, minutes, seconds);
+
+ }
+
+ /**
+ * format time to duration
+ *
+ * @param d1 d1
+ * @param d2 d2
+ * @return format time
+ */
+ public static String format2Duration(Date d1, Date d2) {
+ if (d1 == null || d2 == null) {
+ return null;
+ }
+ return format2Duration(differMs(d1, d2));
+ }
+
+ /**
+ * format time to duration
+ *
+ * @param ms ms
+ * @return format time
+ */
+ public static String format2Duration(long ms) {
+
+ long days = MILLISECONDS.toDays(ms);
+ long hours = MILLISECONDS.toDurationHours(ms);
+ long minutes = MILLISECONDS.toDurationMinutes(ms);
+ long seconds = MILLISECONDS.toDurationSeconds(ms);
+
+ StringBuilder strBuilder = new StringBuilder();
+ strBuilder = days > 0 ? strBuilder.append(days).append("d").append(" ") : strBuilder;
+ strBuilder = hours > 0 ? strBuilder.append(hours).append("h").append(" ") : strBuilder;
+ strBuilder = minutes > 0 ? strBuilder.append(minutes).append("m").append(" ") : strBuilder;
+ strBuilder = seconds > 0 ? strBuilder.append(seconds).append("s") : strBuilder;
+
+ return strBuilder.toString();
+
+ }
+
+ /**
+ * get monday
+ *
+ * note: Set the first day of the week to Monday, the default is Sunday
+ *
+ * @param date date
+ * @return get monday
+ */
+ public static Date getMonday(Date date) {
+ Calendar cal = Calendar.getInstance();
+
+ cal.setTime(date);
+
+ cal.setFirstDayOfWeek(Calendar.MONDAY);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+
+ return cal.getTime();
+ }
+
+ /**
+ * get sunday
+ *
+ * note: Set the first day of the week to Monday, the default is Sunday
+ *
+ * @param date date
+ * @return get sunday
+ */
+ public static Date getSunday(Date date) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+
+ cal.setFirstDayOfWeek(Calendar.MONDAY);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
+
+ return cal.getTime();
+ }
+
+ /**
+ * get first day of month
+ *
+ * @param date date
+ * @return first day of month
+ */
+ public static Date getFirstDayOfMonth(Date date) {
+ Calendar cal = Calendar.getInstance();
+
+ cal.setTime(date);
+ cal.set(Calendar.DAY_OF_MONTH, 1);
+
+ return cal.getTime();
+ }
+
+ /**
+ * get some hour of day
+ *
+ * @param date date
+ * @param offsetHour hours
+ * @return some hour of day
+ */
+ public static Date getSomeHourOfDay(Date date, int offsetHour) {
+ Calendar cal = Calendar.getInstance();
+
+ cal.setTime(date);
+ cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) + offsetHour);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+
+ return cal.getTime();
+ }
+
+ /**
+ * get last day of month
+ *
+ * @param date date
+ * @return get last day of month
+ */
+ public static Date getLastDayOfMonth(Date date) {
+ Calendar cal = Calendar.getInstance();
+
+ cal.setTime(date);
+
+ cal.add(Calendar.MONTH, 1);
+ cal.set(Calendar.DAY_OF_MONTH, 1);
+ cal.add(Calendar.DAY_OF_MONTH, -1);
+
+ return cal.getTime();
+ }
+
+ /**
+ * return YYYY-MM-DD 00:00:00
+ *
+ * @param inputDay date
+ * @return start day
+ */
+ public static Date getStartOfDay(Date inputDay) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(inputDay);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ return cal.getTime();
+ }
+
+ /**
+ * return YYYY-MM-DD 23:59:59
+ *
+ * @param inputDay day
+ * @return end of day
+ */
+ public static Date getEndOfDay(Date inputDay) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(inputDay);
+ cal.set(Calendar.HOUR_OF_DAY, 23);
+ cal.set(Calendar.MINUTE, 59);
+ cal.set(Calendar.SECOND, 59);
+ cal.set(Calendar.MILLISECOND, 999);
+ return cal.getTime();
+ }
+
+ /**
+ * return YYYY-MM-DD 00:00:00
+ *
+ * @param inputDay day
+ * @return start of hour
+ */
+ public static Date getStartOfHour(Date inputDay) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(inputDay);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ return cal.getTime();
+ }
+
+ /**
+ * return YYYY-MM-DD 23:59:59
+ *
+ * @param inputDay day
+ * @return end of hour
+ */
+ public static Date getEndOfHour(Date inputDay) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(inputDay);
+ cal.set(Calendar.MINUTE, 59);
+ cal.set(Calendar.SECOND, 59);
+ cal.set(Calendar.MILLISECOND, 999);
+ return cal.getTime();
+ }
+
+ /**
+ * get current date
+ *
+ * @return current date
+ */
+ public static Date getCurrentDate() {
+ return DateUtils.parse(DateUtils.getCurrentTime(),
+ Constants.YYYY_MM_DD_HH_MM_SS);
+ }
+
+ public static Date addYears(Date date, int amount) {
+ return add(date, 1, amount);
+ }
+
+ public static Date addMonths(Date date, int amount) {
+ return add(date, 2, amount);
+ }
+
+ public static Date addWeeks(Date date, int amount) {
+ return add(date, 3, amount);
+ }
+
+ public static Date addDays(Date date, int amount) {
+ return add(date, 5, amount);
+ }
+
+ public static Date addHours(Date date, int amount) {
+ return add(date, 11, amount);
+ }
+
+ public static Date addMinutes(Date date, int amount) {
+ return add(date, 12, amount);
+ }
+
+ public static Date addSeconds(Date date, int amount) {
+ return add(date, 13, amount);
+ }
+
+ public static Date addMilliseconds(Date date, int amount) {
+ return add(date, 14, amount);
+ }
+
+ /**
+ * get date
+ *
+ * @param date date
+ * @param calendarField calendarField
+ * @param amount amount
+ * @return date
+ */
+ public static Date add(final Date date, final int calendarField, final int amount) {
+ if (date == null) {
+ throw new IllegalArgumentException("The date must not be null");
+ }
+ final Calendar c = Calendar.getInstance();
+ c.setTime(date);
+ c.add(calendarField, amount);
+ return c.getTime();
+ }
+
+ /**
+ * starting from the current time, get how many seconds are left before the target time.
+ * targetTime = baseTime + intervalSeconds
+ *
+ * @param baseTime base time
+ * @param intervalSeconds a period of time
+ * @return the number of seconds
+ */
+ public static long getRemainTime(Date baseTime, long intervalSeconds) {
+ if (baseTime == null) {
+ return 0;
+ }
+ long usedTime = (System.currentTimeMillis() - baseTime.getTime()) / 1000;
+ return intervalSeconds - usedTime;
+ }
+
+ /**
+ * get current time stamp : yyyyMMddHHmmssSSS
+ *
+ * @return date string
+ */
+ public static String getCurrentTimeStamp() {
+ return getCurrentTime(Constants.YYYYMMDDHHMMSSSSS);
+ }
+
+ /**
+ * transform date to target timezone date
+ *
e.g.
+ *
if input date is 2020-01-01 00:00:00 current timezone is CST
+ *
targetTimezoneId is MST
+ *
this method will return 2020-01-01 15:00:00
+ */
+ public static Date getTimezoneDate(Date date, String targetTimezoneId) {
+ if (StringUtils.isEmpty(targetTimezoneId)) {
+ return date;
+ }
+
+ String dateToString = dateToString(date);
+ LocalDateTime localDateTime = LocalDateTime.parse(dateToString, DateTimeFormatter.ofPattern(Constants.YYYY_MM_DD_HH_MM_SS));
+ ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, TimeZone.getTimeZone(targetTimezoneId).toZoneId());
+ return Date.from(zonedDateTime.toInstant());
+ }
+
+ /**
+ * get timezone by timezoneId
+ */
+ public static TimeZone getTimezone(String timezoneId) {
+ if (StringUtils.isEmpty(timezoneId)) {
+ return null;
+ }
+ return TimeZone.getTimeZone(timezoneId);
+ }
+
+ /**
+ * Time unit representing one thousandth of a second
+ */
+ public static class MILLISECONDS {
+
+ public static long toSeconds(long d) {
+ return d / (C3 / C2);
+ }
+
+ public static long toMinutes(long d) {
+ return d / (C4 / C2);
+ }
+
+ public static long toHours(long d) {
+ return d / (C5 / C2);
+ }
+
+ public static long toDays(long d) {
+ return d / (C6 / C2);
+ }
+
+ public static long toDurationSeconds(long d) {
+ return (d % (C4 / C2)) / (C3 / C2);
+ }
+
+ public static long toDurationMinutes(long d) {
+ return (d % (C5 / C2)) / (C4 / C2);
+ }
+
+ public static long toDurationHours(long d) {
+ return (d % (C6 / C2)) / (C5 / C2);
+ }
+
+ }
+
+}
diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/PropertyUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/PropertyUtils.java
new file mode 100644
index 0000000000..491be64d5d
--- /dev/null
+++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/PropertyUtils.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.spi.utils;
+
+import static org.apache.dolphinscheduler.spi.utils.Constants.COMMON_PROPERTIES_PATH;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PropertyUtils {
+ private static final Logger logger = LoggerFactory.getLogger(PropertyUtils.class);
+
+ private static final Properties properties = new Properties();
+
+ private PropertyUtils() {
+ throw new UnsupportedOperationException("Construct PropertyUtils");
+ }
+
+ static {
+ loadPropertyFile(COMMON_PROPERTIES_PATH);
+ }
+
+ public static synchronized void loadPropertyFile(String... propertyFiles) {
+ for (String fileName : propertyFiles) {
+ try (InputStream fis = PropertyUtils.class.getResourceAsStream(fileName);) {
+ properties.load(fis);
+
+ } catch (IOException e) {
+ logger.error(e.getMessage(), e);
+ System.exit(1);
+ }
+ }
+
+ // Override from system properties
+ System.getProperties().forEach((k, v) -> {
+ final String key = String.valueOf(k);
+ logger.info("Overriding property from system property: {}", key);
+ PropertyUtils.setValue(key, String.valueOf(v));
+ });
+ }
+
+ /**
+ * get property value
+ *
+ * @param key property name
+ * @return property value
+ */
+ public static String getString(String key) {
+ return properties.getProperty(key.trim());
+ }
+
+ /**
+ * get property value with upper case
+ *
+ * @param key property name
+ * @return property value with upper case
+ */
+ public static String getUpperCaseString(String key) {
+ return properties.getProperty(key.trim()).toUpperCase();
+ }
+
+ /**
+ * get property value
+ *
+ * @param key property name
+ * @param defaultVal default value
+ * @return property value
+ */
+ public static String getString(String key, String defaultVal) {
+ String val = properties.getProperty(key.trim());
+ return val == null ? defaultVal : val;
+ }
+
+ /**
+ * get property value
+ *
+ * @param key property name
+ * @return get property int value , if key == null, then return -1
+ */
+ public static int getInt(String key) {
+ return getInt(key, -1);
+ }
+
+ /**
+ * @param key key
+ * @param defaultValue default value
+ * @return property value
+ */
+ public static int getInt(String key, int defaultValue) {
+ String value = getString(key);
+ if (value == null) {
+ return defaultValue;
+ }
+
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ logger.info(e.getMessage(), e);
+ }
+ return defaultValue;
+ }
+
+ /**
+ * get property value
+ *
+ * @param key property name
+ * @return property value
+ */
+ public static boolean getBoolean(String key) {
+ String value = properties.getProperty(key.trim());
+ if (null != value) {
+ return Boolean.parseBoolean(value);
+ }
+
+ return false;
+ }
+
+ /**
+ * get property value
+ *
+ * @param key property name
+ * @param defaultValue default value
+ * @return property value
+ */
+ public static Boolean getBoolean(String key, boolean defaultValue) {
+ String value = properties.getProperty(key.trim());
+ if (null != value) {
+ return Boolean.parseBoolean(value);
+ }
+
+ return defaultValue;
+ }
+
+ /**
+ * get property long value
+ *
+ * @param key key
+ * @param defaultVal default value
+ * @return property value
+ */
+ public static long getLong(String key, long defaultVal) {
+ String val = getString(key);
+ return val == null ? defaultVal : Long.parseLong(val);
+ }
+
+ /**
+ * @param key key
+ * @return property value
+ */
+ public static long getLong(String key) {
+ return getLong(key, -1);
+ }
+
+ /**
+ * @param key key
+ * @param defaultVal default value
+ * @return property value
+ */
+ public static double getDouble(String key, double defaultVal) {
+ String val = getString(key);
+ return val == null ? defaultVal : Double.parseDouble(val);
+ }
+
+ /**
+ * get array
+ *
+ * @param key property name
+ * @param splitStr separator
+ * @return property value through array
+ */
+ public static String[] getArray(String key, String splitStr) {
+ String value = getString(key);
+ if (value == null) {
+ return new String[0];
+ }
+ try {
+ String[] propertyArray = value.split(splitStr);
+ return propertyArray;
+ } catch (NumberFormatException e) {
+ logger.info(e.getMessage(), e);
+ }
+ return new String[0];
+ }
+
+ /**
+ * @param key key
+ * @param type type
+ * @param defaultValue default value
+ * @param T
+ * @return get enum value
+ */
+ public static > T getEnum(String key, Class type,
+ T defaultValue) {
+ String val = getString(key);
+ return val == null ? defaultValue : Enum.valueOf(type, val);
+ }
+
+ /**
+ * get all properties with specified prefix, like: fs.
+ *
+ * @param prefix prefix to search
+ * @return all properties with specified prefix
+ */
+ public static Map getPrefixedProperties(String prefix) {
+ Map matchedProperties = new HashMap<>();
+ for (String propName : properties.stringPropertyNames()) {
+ if (propName.startsWith(prefix)) {
+ matchedProperties.put(propName, properties.getProperty(propName));
+ }
+ }
+ return matchedProperties;
+ }
+
+ /**
+ *
+ */
+ public static void setValue(String key, String value) {
+ properties.setProperty(key, value);
+ }
+
+ public static Map getPropertiesByPrefix(String prefix) {
+ if (StringUtils.isEmpty(prefix)) {
+ return null;
+ }
+ Set