diff --git a/escheduler-api/src/main/java/cn/escheduler/api/service/DataSourceService.java b/escheduler-api/src/main/java/cn/escheduler/api/service/DataSourceService.java index a717dd1342dc389ab630611474e8a5e4da6c741a..a5c72758fb1af1fb1379c844425a34ff24050105 100644 --- a/escheduler-api/src/main/java/cn/escheduler/api/service/DataSourceService.java +++ b/escheduler-api/src/main/java/cn/escheduler/api/service/DataSourceService.java @@ -210,6 +210,7 @@ public class DataSourceService extends BaseService{ switch (dataSource.getType()) { case HIVE: + case SQLSERVER: separator = ";"; break; case MYSQL: @@ -376,6 +377,10 @@ public class DataSourceService extends BaseService{ datasource = JSONObject.parseObject(parameter, OracleDataSource.class); Class.forName(Constants.COM_ORACLE_JDBC_DRIVER); break; + case SQLSERVER: + datasource = JSONObject.parseObject(parameter, SQLServerDataSource.class); + Class.forName(Constants.COM_SQLSERVER_JDBC_DRIVER); + break; default: break; } @@ -447,7 +452,9 @@ public class DataSourceService extends BaseService{ || Constants.CLICKHOUSE.equals(type.name()) || Constants.ORACLE.equals(type.name())) { separator = "&"; - } else if (Constants.HIVE.equals(type.name()) || Constants.SPARK.equals(type.name())) { + } else if (Constants.HIVE.equals(type.name()) + || Constants.SPARK.equals(type.name()) + || Constants.SQLSERVER.equals(type.name())) { separator = ";"; } @@ -502,6 +509,9 @@ public class DataSourceService extends BaseService{ } else if (Constants.ORACLE.equals(type.name())) { sb.append(Constants.JDBC_ORACLE); sb.append(host).append(":").append(port); + } else if (Constants.SQLSERVER.equals(type.name())) { + sb.append(Constants.JDBC_SQLSERVER); + sb.append(host).append(":").append(port); } return sb.toString(); diff --git a/escheduler-api/src/main/java/cn/escheduler/api/utils/Constants.java b/escheduler-api/src/main/java/cn/escheduler/api/utils/Constants.java index 0335026bb692cb58af1d291a7603870f09765422..79cf3e5b3fa7a5f824b10ed0a1afb09ed6c1649f 100644 --- a/escheduler-api/src/main/java/cn/escheduler/api/utils/Constants.java +++ b/escheduler-api/src/main/java/cn/escheduler/api/utils/Constants.java @@ -84,6 +84,7 @@ public class Constants { 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"; /** * database type @@ -94,6 +95,7 @@ public class Constants { public static final String SPARK = "SPARK"; public static final String CLICKHOUSE = "CLICKHOUSE"; public static final String ORACLE = "ORACLE"; + public static final String SQLSERVER = "SQLSERVER"; /** * jdbc url @@ -103,6 +105,7 @@ public class Constants { public static final String JDBC_HIVE_2 = "jdbc:hive2://"; public static final String JDBC_CLICKHOUSE = "jdbc:clickhouse://"; public static final String JDBC_ORACLE = "jdbc:oracle:thin:@//"; + public static final String JDBC_SQLSERVER = "jdbc:sqlserver://"; public static final String ADDRESS = "address"; diff --git a/escheduler-common/pom.xml b/escheduler-common/pom.xml index 35c83bc2b0aff8751fd8d474e809dde79440f522..c0daa0bce7cc536aaf7a13d5d428ab1435ab8d0a 100644 --- a/escheduler-common/pom.xml +++ b/escheduler-common/pom.xml @@ -386,6 +386,17 @@ + + + com.microsoft.sqlserver + mssql-jdbc + + + com.microsoft.azure + azure-keyvault + + + diff --git a/escheduler-common/src/main/java/cn/escheduler/common/Constants.java b/escheduler-common/src/main/java/cn/escheduler/common/Constants.java index c0cd2290f699a63e35717adea5f03870d6d69fae..98a2535f03e6e3e2b78f866b05ab937658c06c94 100644 --- a/escheduler-common/src/main/java/cn/escheduler/common/Constants.java +++ b/escheduler-common/src/main/java/cn/escheduler/common/Constants.java @@ -621,6 +621,11 @@ public final class Constants { */ public static final String JDBC_ORACLE_CLASS_NAME = "oracle.jdbc.driver.OracleDriver"; + /** + * Oracle + */ + public static final String JDBC_SQLSERVER_CLASS_NAME = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; + /** * spark params constant */ diff --git a/escheduler-common/src/main/java/cn/escheduler/common/enums/DbType.java b/escheduler-common/src/main/java/cn/escheduler/common/enums/DbType.java index df8e86a182014bc62d8ec1f2cd74198a52a7bc65..bf0ebba60c9f25022839747c9ee8ec23588546f1 100644 --- a/escheduler-common/src/main/java/cn/escheduler/common/enums/DbType.java +++ b/escheduler-common/src/main/java/cn/escheduler/common/enums/DbType.java @@ -27,6 +27,7 @@ public enum DbType { * 3 spark * 4 clickhouse * 5 oracle + * 6 sqlserver */ - MYSQL, POSTGRESQL, HIVE, SPARK, CLICKHOUSE, ORACLE + MYSQL, POSTGRESQL, HIVE, SPARK, CLICKHOUSE, ORACLE, SQLSERVER } diff --git a/escheduler-common/src/main/java/cn/escheduler/common/job/db/DataSourceFactory.java b/escheduler-common/src/main/java/cn/escheduler/common/job/db/DataSourceFactory.java index 400864507460eaec815a40a00e6cb4b8f55c108e..316be26d89bcb30f06f433c49b10e9962ff96ae0 100644 --- a/escheduler-common/src/main/java/cn/escheduler/common/job/db/DataSourceFactory.java +++ b/escheduler-common/src/main/java/cn/escheduler/common/job/db/DataSourceFactory.java @@ -43,6 +43,8 @@ public class DataSourceFactory { return JSONUtils.parseObject(parameter, ClickHouseDataSource.class); case ORACLE: return JSONUtils.parseObject(parameter, OracleDataSource.class); + case SQLSERVER: + return JSONUtils.parseObject(parameter, SQLServerDataSource.class); default: return null; } diff --git a/escheduler-common/src/main/java/cn/escheduler/common/job/db/SQLServerDataSource.java b/escheduler-common/src/main/java/cn/escheduler/common/job/db/SQLServerDataSource.java new file mode 100644 index 0000000000000000000000000000000000000000..f4d202a76e8b7800823ddada47d3bb905f5ece34 --- /dev/null +++ b/escheduler-common/src/main/java/cn/escheduler/common/job/db/SQLServerDataSource.java @@ -0,0 +1,71 @@ +/* + * 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 cn.escheduler.common.job.db; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +/** + * data source of SQL Server + */ +public class SQLServerDataSource extends BaseDataSource { + private static final Logger logger = LoggerFactory.getLogger(SQLServerDataSource.class); + + /** + * gets the JDBC url for the data source connection + * @return + */ + @Override + public String getJdbcUrl() { + String jdbcUrl = getAddress(); + jdbcUrl += ";databaseName=" + getDatabase(); + + if (StringUtils.isNotEmpty(getOther())) { + jdbcUrl += ";" + getOther(); + } + + return jdbcUrl; + } + + /** + * test whether the data source can be connected successfully + * @throws Exception + */ + @Override + public void isConnectable() throws Exception { + Connection con = null; + try { + Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); + con = DriverManager.getConnection(getJdbcUrl(), getUser(), getPassword()); + } finally { + if (con != null) { + try { + con.close(); + } catch (SQLException e) { + logger.error("SQL Server datasource try conn close conn error", e); + throw e; + } + } + } + + } +} diff --git a/escheduler-server/src/main/java/cn/escheduler/server/worker/task/processdure/ProcedureTask.java b/escheduler-server/src/main/java/cn/escheduler/server/worker/task/processdure/ProcedureTask.java index ee592b89e717d17708c62c88b4a592167ae22a2b..98428c5389260869fa0a48187d6363fda832f820 100644 --- a/escheduler-server/src/main/java/cn/escheduler/server/worker/task/processdure/ProcedureTask.java +++ b/escheduler-server/src/main/java/cn/escheduler/server/worker/task/processdure/ProcedureTask.java @@ -26,6 +26,7 @@ import cn.escheduler.common.job.db.ClickHouseDataSource; import cn.escheduler.common.job.db.MySQLDataSource; import cn.escheduler.common.job.db.OracleDataSource; import cn.escheduler.common.job.db.PostgreDataSource; +import cn.escheduler.common.job.db.SQLServerDataSource; import cn.escheduler.common.process.Property; import cn.escheduler.common.task.AbstractParameters; import cn.escheduler.common.task.procedure.ProcedureParameters; @@ -121,6 +122,9 @@ public class ProcedureTask extends AbstractTask { }else if (DbType.ORACLE.name().equals(dataSource.getType().name())){ baseDataSource = JSONObject.parseObject(dataSource.getConnectionParams(), OracleDataSource.class); Class.forName(Constants.JDBC_ORACLE_CLASS_NAME); + }else if (DbType.SQLSERVER.name().equals(dataSource.getType().name())){ + baseDataSource = JSONObject.parseObject(dataSource.getConnectionParams(), SQLServerDataSource.class); + Class.forName(Constants.JDBC_SQLSERVER_CLASS_NAME); } // get jdbc connection diff --git a/escheduler-server/src/main/java/cn/escheduler/server/worker/task/sql/SqlTask.java b/escheduler-server/src/main/java/cn/escheduler/server/worker/task/sql/SqlTask.java index 2c30f328c0a322d0878006f1d261119b7b793ed6..bab755ba67d898890ec0deb94cf5b11808580fc1 100644 --- a/escheduler-server/src/main/java/cn/escheduler/server/worker/task/sql/SqlTask.java +++ b/escheduler-server/src/main/java/cn/escheduler/server/worker/task/sql/SqlTask.java @@ -126,6 +126,9 @@ public class SqlTask extends AbstractTask { }else if (DbType.ORACLE.name().equals(dataSource.getType().name())){ baseDataSource = JSONObject.parseObject(dataSource.getConnectionParams(),OracleDataSource.class); Class.forName(Constants.JDBC_ORACLE_CLASS_NAME); + }else if (DbType.SQLSERVER.name().equals(dataSource.getType().name())){ + baseDataSource = JSONObject.parseObject(dataSource.getConnectionParams(),SQLServerDataSource.class); + Class.forName(Constants.JDBC_SQLSERVER_CLASS_NAME); } Map sqlParamMap = new HashMap(); diff --git a/escheduler-server/src/test/java/cn/escheduler/server/worker/sql/SqlExecutorTest.java b/escheduler-server/src/test/java/cn/escheduler/server/worker/sql/SqlExecutorTest.java index 472dea73bc5afc4d088043c60fc23743aad401dc..120e7a997268501a43e9253cd31b46364805e344 100644 --- a/escheduler-server/src/test/java/cn/escheduler/server/worker/sql/SqlExecutorTest.java +++ b/escheduler-server/src/test/java/cn/escheduler/server/worker/sql/SqlExecutorTest.java @@ -77,6 +77,15 @@ public class SqlExecutorTest { sharedTestSqlTask(nodeName, taskAppId, tenantCode, taskInstId); } + @Test + public void testSQLServer() throws Exception { + String nodeName = "SQL Server sql test"; + String taskAppId = "3_14_27"; + String tenantCode = "demo"; + int taskInstId = 27; + sharedTestSqlTask(nodeName, taskAppId, tenantCode, taskInstId); + } + /** * Basic test template for SQLTasks, mainly test different types of DBMS types * @param nodeName node name for selected task diff --git a/escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/procedure.vue b/escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/procedure.vue index 8ffe5b11394e87697e63177e8eb9be3da3460a5d..74a41d7ff38722e6f34f55fe5a7455d0502e0c2a 100644 --- a/escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/procedure.vue +++ b/escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/procedure.vue @@ -6,7 +6,7 @@ diff --git a/escheduler-ui/src/js/conf/home/pages/datasource/pages/list/_source/createDataSource.vue b/escheduler-ui/src/js/conf/home/pages/datasource/pages/list/_source/createDataSource.vue index 4a8de42802e5b50b644f6762a5b1ca319007c3c8..10f091f6bf7a0fffd70be16053eed2f7eb5f3c8d 100644 --- a/escheduler-ui/src/js/conf/home/pages/datasource/pages/list/_source/createDataSource.vue +++ b/escheduler-ui/src/js/conf/home/pages/datasource/pages/list/_source/createDataSource.vue @@ -15,6 +15,7 @@ SPARK CLICKHOUSE ORACLE + SQLSERVER diff --git a/escheduler-ui/src/js/conf/home/store/dag/state.js b/escheduler-ui/src/js/conf/home/store/dag/state.js index 1cae24a84efeda3cc6ce8b6e9d4c5daa7437394e..6ac387abef0d41d9d72afeb9c0ed0c7b7d648ab9 100644 --- a/escheduler-ui/src/js/conf/home/store/dag/state.js +++ b/escheduler-ui/src/js/conf/home/store/dag/state.js @@ -76,6 +76,11 @@ export default { id: 5, code: 'ORACLE', disabled: false + }, + { + id: 6, + code: 'SQLSERVER', + disabled: false } ], // Alarm interface diff --git a/escheduler-ui/src/js/conf/home/store/datasource/actions.js b/escheduler-ui/src/js/conf/home/store/datasource/actions.js index b19372666f4bc243c912e409f03deba9820aaa6b..3e409ccb8be034ed4abd8d8ae0a2a2c83c8e55e0 100644 --- a/escheduler-ui/src/js/conf/home/store/datasource/actions.js +++ b/escheduler-ui/src/js/conf/home/store/datasource/actions.js @@ -20,7 +20,7 @@ import io from '@/module/io' export default { /** * Data source creation - * @param "type": string,//MYSQL, POSTGRESQL, HIVE, SPARK, CLICKHOUSE, ORACLE + * @param "type": string,//MYSQL, POSTGRESQL, HIVE, SPARK, CLICKHOUSE, ORACLE, SQLSERVER * @param "name": string, * @param "desc": string, * @param "parameter":string //{"address":"jdbc:hive2://192.168.220.189:10000","autoReconnect":"true","characterEncoding":"utf8","database":"default","initialTimeout":3000,"jdbcUrl":"jdbc:hive2://192.168.220.189:10000/default","maxReconnect":10,"password":"","useUnicode":true,"user":"hive"} @@ -49,7 +49,7 @@ export default { }, /** * Query data source list - no paging - * @param "type": string//MYSQL, POSTGRESQL, HIVE, SPARK, CLICKHOUSE, ORACLE + * @param "type": string//MYSQL, POSTGRESQL, HIVE, SPARK, CLICKHOUSE, ORACLE, SQLSERVER */ getDatasourcesList ({ state }, payload) { return new Promise((resolve, reject) => { diff --git a/pom.xml b/pom.xml index 2b0b585106a082986f9cfb4899e427f63efb304b..83b2032985d9073f5a0eedfe73bc5bf6fc885d61 100644 --- a/pom.xml +++ b/pom.xml @@ -372,6 +372,12 @@ 0.1.52 + + com.microsoft.sqlserver + mssql-jdbc + 6.1.0.jre8 + +