From 1aed843a14fbee55fc36aaba58ae2262bf9d1436 Mon Sep 17 00:00:00 2001 From: taojinlong Date: Thu, 18 Jul 2024 18:12:48 +0800 Subject: [PATCH] =?UTF-8?q?feat[=E6=95=B0=E6=8D=AE=E6=BA=90]:=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=BA=90=E6=94=AF=E6=8C=81ssh=E9=9A=A7=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datasource/provider/CalciteProvider.java | 95 +++++++++++++++---- .../datasource/provider/H2EngineProvider.java | 6 +- .../provider/MysqlEngineProvider.java | 6 +- .../java/io/dataease/datasource/type/CK.java | 8 +- .../java/io/dataease/datasource/type/Db2.java | 12 +-- .../io/dataease/datasource/type/Impala.java | 8 +- .../io/dataease/datasource/type/Mongo.java | 8 +- .../io/dataease/datasource/type/Mysql.java | 9 +- .../io/dataease/datasource/type/Oracle.java | 8 +- .../java/io/dataease/datasource/type/Pg.java | 12 +-- .../io/dataease/datasource/type/Redshift.java | 4 +- .../dataease/datasource/type/Sqlserver.java | 8 +- .../data/datasource/form/EditorDetail.vue | 83 ++++++++++++++++ .../visualized/data/datasource/form/index.vue | 3 + .../visualized/data/datasource/form/option.ts | 6 ++ pom.xml | 1 + sdk/extensions/extensions-datasource/pom.xml | 5 + .../datasource/dto/ConnectionObj.java | 35 +++++++ .../datasource/provider/Provider.java | 36 ++++++- .../datasource/vo/Configuration.java | 26 +++++ 20 files changed, 316 insertions(+), 63 deletions(-) create mode 100644 sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/ConnectionObj.java diff --git a/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java b/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java index 5918b5d88a..27f28d40da 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java @@ -1,6 +1,8 @@ package io.dataease.datasource.provider; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.Session; import io.dataease.commons.utils.CommonThreadPool; import io.dataease.dataset.utils.FieldUtils; import io.dataease.datasource.dao.auto.entity.CoreDatasource; @@ -24,7 +26,6 @@ import org.apache.calcite.adapter.jdbc.JdbcSchema; import org.apache.calcite.jdbc.CalciteConnection; import org.apache.calcite.schema.Schema; import org.apache.calcite.schema.SchemaPlus; -import org.apache.calcite.sql.SqlDialect; import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; @@ -34,6 +35,7 @@ import java.io.File; import java.io.IOException; import java.math.BigDecimal; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.sql.*; import java.util.*; import java.util.regex.Matcher; @@ -53,7 +55,6 @@ public class CalciteProvider extends Provider { private final String FILE_PATH = "/opt/dataease2.0/drivers"; private final String CUSTOM_PATH = "/opt/dataease2.0/custom-drivers/"; private static String split = "DE"; - @Resource private CommonThreadPool commonThreadPool; @@ -85,7 +86,7 @@ public class CalciteProvider extends Provider { public List getSchema(DatasourceRequest datasourceRequest) { List schemas = new ArrayList<>(); String queryStr = getSchemaSql(datasourceRequest.getDatasource()); - try (Connection con = getConnection(datasourceRequest.getDatasource()); Statement statement = getStatement(con, 30); ResultSet resultSet = statement.executeQuery(queryStr)) { + try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); Statement statement = getStatement(con.getConnection(), 30); ResultSet resultSet = statement.executeQuery(queryStr)) { while (resultSet.next()) { schemas.add(resultSet.getString(1)); } @@ -100,7 +101,7 @@ public class CalciteProvider extends Provider { List tables = new ArrayList<>(); List tablesSqls = getTablesSql(datasourceRequest); for (String tablesSql : tablesSqls) { - try (Connection con = getConnection(datasourceRequest.getDatasource()); Statement statement = getStatement(con, 30); ResultSet resultSet = statement.executeQuery(tablesSql)) { + try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); Statement statement = getStatement(con.getConnection(), 30); ResultSet resultSet = statement.executeQuery(tablesSql)) { while (resultSet.next()) { tables.add(getTableDesc(datasourceRequest, resultSet)); } @@ -111,6 +112,7 @@ public class CalciteProvider extends Provider { return tables; } + @Override public String checkStatus(DatasourceRequest datasourceRequest) throws Exception { DatasourceConfiguration.DatasourceType datasourceType = DatasourceConfiguration.DatasourceType.valueOf(datasourceRequest.getDatasource().getType()); @@ -126,7 +128,7 @@ public class CalciteProvider extends Provider { break; } String querySql = getTablesSql(datasourceRequest).get(0); - try (Connection con = getConnection(datasourceRequest.getDatasource()); Statement statement = getStatement(con, 30); ResultSet resultSet = statement.executeQuery(querySql)) { + try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); Statement statement = getStatement(con.getConnection(), 30); ResultSet resultSet = statement.executeQuery(querySql)) { } catch (Exception e) { throw e; } @@ -189,14 +191,12 @@ public class CalciteProvider extends Provider { List datasetTableFields = new ArrayList<>(); DatasourceSchemaDTO datasourceSchemaDTO = datasourceRequest.getDsList().entrySet().iterator().next().getValue(); datasourceRequest.setDatasource(datasourceSchemaDTO); - DatasourceConfiguration datasourceConfiguration = JsonUtil.parseObject(datasourceRequest.getDatasource().getConfiguration(), DatasourceConfiguration.class); - String table = datasourceRequest.getTable(); if (StringUtils.isEmpty(table)) { ResultSet resultSet = null; - try (Connection con = getConnection(datasourceRequest.getDatasource()); - Statement statement = getStatement(con, 30)) { + try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); + Statement statement = getStatement(con.getConnection(), 30)) { if (DatasourceConfiguration.DatasourceType.valueOf(datasourceSchemaDTO.getType()) == DatasourceConfiguration.DatasourceType.oracle) { statement.executeUpdate("ALTER SESSION SET CURRENT_SCHEMA = " + datasourceConfiguration.getSchema()); } @@ -215,8 +215,8 @@ public class CalciteProvider extends Provider { } } else { ResultSet resultSet = null; - try (Connection con = getConnection(datasourceRequest.getDatasource()); - Statement statement = getStatement(con, 30)) { + try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); + Statement statement = getStatement(con.getConnection(), 30)) { if (DatasourceConfiguration.DatasourceType.valueOf(datasourceSchemaDTO.getType()) == DatasourceConfiguration.DatasourceType.oracle) { statement.executeUpdate("ALTER SESSION SET CURRENT_SCHEMA = " + datasourceConfiguration.getSchema()); } @@ -251,7 +251,8 @@ public class CalciteProvider extends Provider { } @Override - public Connection getConnection(DatasourceDTO coreDatasource) throws DEException { + public ConnectionObj getConnection(DatasourceDTO coreDatasource) throws Exception { + ConnectionObj connectionObj = new ConnectionObj(); DatasourceConfiguration configuration = null; DatasourceConfiguration.DatasourceType datasourceType = DatasourceConfiguration.DatasourceType.valueOf(coreDatasource.getType()); switch (datasourceType) { @@ -290,6 +291,7 @@ public class CalciteProvider extends Provider { default: configuration = JsonUtil.parseObject(coreDatasource.getConfiguration(), Mysql.class); } + startSshSession(configuration, connectionObj, null); Properties props = new Properties(); if (StringUtils.isNotBlank(configuration.getUsername())) { props.setProperty("user", configuration.getUsername()); @@ -303,12 +305,59 @@ public class CalciteProvider extends Provider { try { Driver driverClass = (Driver) jdbcClassLoader.loadClass(driverClassName).newInstance(); conn = driverClass.connect(configuration.getJdbc(), props); + } catch (Exception e) { DEException.throwException(e.getMessage()); } - return conn; + connectionObj.setConnection(conn); + return connectionObj; } + private void startSshSession(DatasourceConfiguration configuration, ConnectionObj connectionObj, Long datacourseId) throws Exception { + if (configuration.isUseSSH()) { + if (datacourseId == null) { + configuration.setLPort(getLport(null)); + connectionObj.setLPort(configuration.getLPort()); + connectionObj.setConfiguration(configuration); + Session session = initSession(configuration); + connectionObj.setSession(session); + } else { + Integer lport = Provider.getLPorts().get(datacourseId); + configuration.setLPort(lport); + if (lport != null) { + if (Provider.getSessions().get(datacourseId) == null || !Provider.getSessions().get(datacourseId).isConnected()) { + Session session = initSession(configuration); + Provider.getSessions().put(datacourseId, session); + } + } else { + configuration.setLPort(getLport(datacourseId)); + Session session = initSession(configuration); + Provider.getSessions().put(datacourseId, session); + } + configuration.setLPort(lport); + } + } + } + + private Session initSession(DatasourceConfiguration configuration) throws Exception{ + JSch jsch = new JSch(); + Session session = jsch.getSession(configuration.getSshUserName(), configuration.getSshHost(), configuration.getSshPort()); + if (!configuration.getSshType().equalsIgnoreCase("password")) { + session.setConfig("PreferredAuthentications", "publickey"); + jsch.addIdentity("sshkey", configuration.getSshKey().getBytes(StandardCharsets.UTF_8), null, configuration.getSshKeyPassword() == null ? null : configuration.getSshKeyPassword().getBytes(StandardCharsets.UTF_8)); + } + if (configuration.getSshType().equalsIgnoreCase("password")) { + session.setPassword(configuration.getSshPassword()); + } + session.setConfig("StrictHostKeyChecking", "no"); + session.connect(); + session.setPortForwardingL(configuration.getLPort(), configuration.getHost(), configuration.getPort()); + + return session; + } + + + private DatasetTableDTO getTableDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws SQLException { DatasetTableDTO tableDesc = new DatasetTableDTO(); tableDesc.setDatasourceId(datasourceRequest.getDatasource().getId()); @@ -341,8 +390,8 @@ public class CalciteProvider extends Provider { // schema ResultSet resultSet = null; - try (Connection con = getConnection(datasourceRequest.getDatasource()); - Statement statement = getStatement(con, datasourceConfiguration.getQueryTimeout())) { + try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); + Statement statement = getStatement(con.getConnection(), datasourceConfiguration.getQueryTimeout())) { if (DatasourceConfiguration.DatasourceType.valueOf(value.getType()) == DatasourceConfiguration.DatasourceType.oracle) { statement.executeUpdate("ALTER SESSION SET CURRENT_SCHEMA = " + datasourceConfiguration.getSchema()); } @@ -752,6 +801,7 @@ public class CalciteProvider extends Provider { dataSource.setInitialSize(configuration.getInitialPoolSize()); dataSource.setMaxTotal(configuration.getMaxPoolSize()); dataSource.setMinIdle(configuration.getMinPoolSize()); + startSshSession(configuration, null, ds.getId()); schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getDataBase()); rootSchema.add(ds.getSchemaAlias(), schema); break; @@ -764,6 +814,7 @@ public class CalciteProvider extends Provider { dataSource.setMaxTotal(configuration.getMaxPoolSize()); dataSource.setMinIdle(configuration.getMinPoolSize()); dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout())); + startSshSession(configuration, null, ds.getId()); schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getDataBase()); rootSchema.add(ds.getSchemaAlias(), schema); break; @@ -776,6 +827,7 @@ public class CalciteProvider extends Provider { dataSource.setMaxTotal(configuration.getMaxPoolSize()); dataSource.setMinIdle(configuration.getMinPoolSize()); dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout())); + startSshSession(configuration, null, ds.getId()); schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getSchema()); rootSchema.add(ds.getSchemaAlias(), schema); break; @@ -788,6 +840,7 @@ public class CalciteProvider extends Provider { dataSource.setMaxTotal(configuration.getMaxPoolSize()); dataSource.setMinIdle(configuration.getMinPoolSize()); dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout())); + startSshSession(configuration, null, ds.getId()); schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getSchema()); rootSchema.add(ds.getSchemaAlias(), schema); break; @@ -800,6 +853,7 @@ public class CalciteProvider extends Provider { dataSource.setMaxTotal(configuration.getMaxPoolSize()); dataSource.setMinIdle(configuration.getMinPoolSize()); dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout())); + startSshSession(configuration, null, ds.getId()); schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getSchema()); rootSchema.add(ds.getSchemaAlias(), schema); break; @@ -812,6 +866,7 @@ public class CalciteProvider extends Provider { dataSource.setMaxTotal(configuration.getMaxPoolSize()); dataSource.setMinIdle(configuration.getMinPoolSize()); dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout())); + startSshSession(configuration, null, ds.getId()); schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getDataBase()); rootSchema.add(ds.getSchemaAlias(), schema); break; @@ -824,6 +879,7 @@ public class CalciteProvider extends Provider { dataSource.setMaxTotal(configuration.getMaxPoolSize()); dataSource.setMinIdle(configuration.getMinPoolSize()); dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout())); + startSshSession(configuration, null, ds.getId()); schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getSchema()); rootSchema.add(ds.getSchemaAlias(), schema); break; @@ -836,6 +892,7 @@ public class CalciteProvider extends Provider { dataSource.setMaxTotal(configuration.getMaxPoolSize()); dataSource.setMinIdle(configuration.getMinPoolSize()); dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout())); + startSshSession(configuration, null, ds.getId()); schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getSchema()); rootSchema.add(ds.getSchemaAlias(), schema); break; @@ -848,6 +905,7 @@ public class CalciteProvider extends Provider { dataSource.setMaxTotal(configuration.getMaxPoolSize()); dataSource.setMinIdle(configuration.getMinPoolSize()); dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout())); + startSshSession(configuration, null, ds.getId()); schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getDataBase()); rootSchema.add(ds.getSchemaAlias(), schema); break; @@ -860,6 +918,7 @@ public class CalciteProvider extends Provider { dataSource.setMaxTotal(configuration.getMaxPoolSize()); dataSource.setMinIdle(configuration.getMinPoolSize()); dataSource.setDefaultQueryTimeout(Integer.valueOf(configuration.getQueryTimeout())); + startSshSession(configuration, null, ds.getId()); schema = JdbcSchema.create(rootSchema, ds.getSchemaAlias(), dataSource, null, configuration.getDataBase()); rootSchema.add(ds.getSchemaAlias(), schema); } @@ -1196,11 +1255,15 @@ public class CalciteProvider extends Provider { } catch (Exception e) { DEException.throwException(e.getMessage()); } + Provider.getLPorts().remove(datasource.getId()); + if (Provider.getSessions().get(datasource.getId()) != null) { + Provider.getSessions().get(datasource.getId()).disconnect(); + } + Provider.getSessions().remove(datasource.getId()); } public Connection take() { - // 为了避免出现线程安全问题,这里使用 synchronized 锁,也可以使用 cas if (connection == null) { DEException.throwException("初始化连接池失败!"); } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/provider/H2EngineProvider.java b/core/core-backend/src/main/java/io/dataease/datasource/provider/H2EngineProvider.java index 5380f061d8..5cdd5dd85c 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/provider/H2EngineProvider.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/provider/H2EngineProvider.java @@ -5,6 +5,7 @@ import io.dataease.dataset.utils.TableUtils; import io.dataease.datasource.dao.auto.entity.CoreDeEngine; import io.dataease.datasource.request.EngineRequest; import io.dataease.datasource.type.H2; +import io.dataease.extensions.datasource.dto.ConnectionObj; import io.dataease.extensions.datasource.dto.DatasourceDTO; import io.dataease.extensions.datasource.dto.TableField; import io.dataease.extensions.datasource.vo.DatasourceConfiguration; @@ -13,7 +14,6 @@ import io.dataease.utils.JsonUtil; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.Statement; import java.util.Arrays; @@ -28,8 +28,8 @@ public class H2EngineProvider extends EngineProvider { int queryTimeout = configuration.getQueryTimeout(); DatasourceDTO datasource = new DatasourceDTO(); BeanUtils.copyBean(datasource, engineRequest.getEngine()); - try (Connection connection = getConnection(datasource); Statement stat = getStatement(connection, queryTimeout)) { - PreparedStatement preparedStatement = connection.prepareStatement(engineRequest.getQuery()); + try (ConnectionObj connection = getConnection(datasource); Statement stat = getStatement(connection.getConnection(), queryTimeout)) { + PreparedStatement preparedStatement = connection.getConnection().prepareStatement(engineRequest.getQuery()); preparedStatement.setQueryTimeout(queryTimeout); Boolean result = preparedStatement.execute(); } catch (Exception e) { diff --git a/core/core-backend/src/main/java/io/dataease/datasource/provider/MysqlEngineProvider.java b/core/core-backend/src/main/java/io/dataease/datasource/provider/MysqlEngineProvider.java index f06aaf8714..b42875e7a4 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/provider/MysqlEngineProvider.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/provider/MysqlEngineProvider.java @@ -5,6 +5,7 @@ import io.dataease.dataset.utils.TableUtils; import io.dataease.datasource.dao.auto.entity.CoreDeEngine; import io.dataease.datasource.request.EngineRequest; import io.dataease.datasource.type.Mysql; +import io.dataease.extensions.datasource.dto.ConnectionObj; import io.dataease.extensions.datasource.dto.DatasourceDTO; import io.dataease.extensions.datasource.dto.TableField; import io.dataease.extensions.datasource.vo.DatasourceConfiguration; @@ -13,7 +14,6 @@ import io.dataease.utils.JsonUtil; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.Statement; import java.util.Arrays; @@ -32,8 +32,8 @@ public class MysqlEngineProvider extends EngineProvider { int queryTimeout = configuration.getQueryTimeout(); DatasourceDTO datasource = new DatasourceDTO(); BeanUtils.copyBean(datasource, engineRequest.getEngine()); - try (Connection connection = getConnection(datasource); Statement stat = getStatement(connection, queryTimeout)) { - PreparedStatement preparedStatement = connection.prepareStatement(engineRequest.getQuery()); + try (ConnectionObj connection = getConnection(datasource); Statement stat = getStatement(connection.getConnection(), queryTimeout)) { + PreparedStatement preparedStatement = connection.getConnection().prepareStatement(engineRequest.getQuery()); preparedStatement.setQueryTimeout(queryTimeout); Boolean result = preparedStatement.execute(); } catch (Exception e) { diff --git a/core/core-backend/src/main/java/io/dataease/datasource/type/CK.java b/core/core-backend/src/main/java/io/dataease/datasource/type/CK.java index bb7a1b35b2..8b65006d07 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/type/CK.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/type/CK.java @@ -17,13 +17,13 @@ public class CK extends DatasourceConfiguration { } if(StringUtils.isEmpty(extraParams.trim())){ return "jdbc:clickhouse://HOSTNAME:PORT/DATABASE" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()); }else { return "jdbc:clickhouse://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()) .replace("EXTRA_PARAMS", getExtraParams().trim()); } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/type/Db2.java b/core/core-backend/src/main/java/io/dataease/datasource/type/Db2.java index 71aa870297..9a7d14663a 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/type/Db2.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/type/Db2.java @@ -18,20 +18,20 @@ public class Db2 extends DatasourceConfiguration { if(StringUtils.isEmpty(extraParams.trim())){ if (StringUtils.isEmpty(getSchema())) { return "jdbc:db2://HOSTNAME:PORT/DATABASE" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()); } else { return "jdbc:db2://HOSTNAME:PORT/DATABASE:currentSchema=SCHEMA;" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()) .replace("SCHEMA",getSchema().trim()); } }else { return "jdbc:db2://HOSTNAME:PORT/DATABASE:EXTRA_PARAMS" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()) .replace("EXTRA_PARAMS", getExtraParams().trim()); } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/type/Impala.java b/core/core-backend/src/main/java/io/dataease/datasource/type/Impala.java index a055d2e945..5d5f0d9f31 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/type/Impala.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/type/Impala.java @@ -22,13 +22,13 @@ public class Impala extends DatasourceConfiguration { } if(StringUtils.isEmpty(extraParams.trim())){ return "jdbc:impala://HOSTNAME:PORT/DATABASE" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()); }else { return "jdbc:impala://HOSTNAME:PORT/DATABASE;EXTRA_PARAMS" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()) .replace("EXTRA_PARAMS", getExtraParams().trim()); } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/type/Mongo.java b/core/core-backend/src/main/java/io/dataease/datasource/type/Mongo.java index aea0029054..885cacdf8f 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/type/Mongo.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/type/Mongo.java @@ -22,8 +22,8 @@ public class Mongo extends DatasourceConfiguration { } if (StringUtils.isEmpty(extraParams.trim())) { return "jdbc:mysql://HOSTNAME:PORT/DATABASE" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()); } else { for (String illegalParameter : illegalParameters) { @@ -33,8 +33,8 @@ public class Mongo extends DatasourceConfiguration { } return "jdbc:mysql://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()) .replace("EXTRA_PARAMS", getExtraParams().trim()); } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/type/Mysql.java b/core/core-backend/src/main/java/io/dataease/datasource/type/Mysql.java index 43bcad1528..91f77f9a5f 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/type/Mysql.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/type/Mysql.java @@ -24,8 +24,8 @@ public class Mysql extends DatasourceConfiguration { } if (StringUtils.isEmpty(extraParams.trim())) { return "jdbc:mysql://HOSTNAME:PORT/DATABASE" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()); } else { for (String illegalParameter : illegalParameters) { @@ -33,10 +33,9 @@ public class Mysql extends DatasourceConfiguration { DEException.throwException("Illegal parameter: " + illegalParameter); } } - return "jdbc:mysql://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()) .replace("EXTRA_PARAMS", getExtraParams().trim()); } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/type/Oracle.java b/core/core-backend/src/main/java/io/dataease/datasource/type/Oracle.java index aba3e0d092..885f1b6054 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/type/Oracle.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/type/Oracle.java @@ -17,13 +17,13 @@ public class Oracle extends DatasourceConfiguration { } if (StringUtils.isNotEmpty(getConnectionType()) && getConnectionType().equalsIgnoreCase("serviceName")) { return "jdbc:oracle:thin:@HOSTNAME:PORT/DATABASE" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()); }else { return "jdbc:oracle:thin:@HOSTNAME:PORT:DATABASE" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()); } } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/type/Pg.java b/core/core-backend/src/main/java/io/dataease/datasource/type/Pg.java index 178c7646f7..4bd03834e2 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/type/Pg.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/type/Pg.java @@ -18,20 +18,20 @@ public class Pg extends DatasourceConfiguration { if(StringUtils.isEmpty(extraParams.trim())){ if (StringUtils.isEmpty(getSchema())) { return "jdbc:postgresql://HOSTNAME:PORT/DATABASE" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()); } else { return "jdbc:postgresql://HOSTNAME:PORT/DATABASE?currentSchema=SCHEMA" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()) .replace("SCHEMA", getSchema().trim()); } }else { return "jdbc:postgresql://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()) .replace("EXTRA_PARAMS", getExtraParams().trim()); diff --git a/core/core-backend/src/main/java/io/dataease/datasource/type/Redshift.java b/core/core-backend/src/main/java/io/dataease/datasource/type/Redshift.java index 3b8f0a9286..e8bd8ecd35 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/type/Redshift.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/type/Redshift.java @@ -16,8 +16,8 @@ public class Redshift extends DatasourceConfiguration { return getJdbcUrl(); } return "jdbc:redshift://HOSTNAME:PORT/DATABASE" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()); } } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/type/Sqlserver.java b/core/core-backend/src/main/java/io/dataease/datasource/type/Sqlserver.java index e47ae373e0..075ca693fd 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/type/Sqlserver.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/type/Sqlserver.java @@ -22,13 +22,13 @@ public class Sqlserver extends DatasourceConfiguration { } if (StringUtils.isEmpty(extraParams.trim())) { return "jdbc:sqlserver://HOSTNAME:PORT;DatabaseName=DATABASE" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()); } else { return "jdbc:sqlserver://HOSTNAME:PORT;DatabaseName=DATABASE;EXTRA_PARAMS" - .replace("HOSTNAME", getHost().trim()) - .replace("PORT", getPort().toString().trim()) + .replace("HOSTNAME", getLHost().trim()) + .replace("PORT", getLPort().toString().trim()) .replace("DATABASE", getDataBase().trim()) .replace("EXTRA_PARAMS", getExtraParams().trim()); } diff --git a/core/core-frontend/src/views/visualized/data/datasource/form/EditorDetail.vue b/core/core-frontend/src/views/visualized/data/datasource/form/EditorDetail.vue index 644c5bf08f..d323ab79f2 100644 --- a/core/core-frontend/src/views/visualized/data/datasource/form/EditorDetail.vue +++ b/core/core-frontend/src/views/visualized/data/datasource/form/EditorDetail.vue @@ -107,6 +107,7 @@ const initForm = type => { dataBase: '', jdbcUrl: '', urlType: 'hostName', + sshType: 'password', extraParams: '', username: '', password: '', @@ -340,6 +341,7 @@ const addApiItem = item => { const activeName = ref('table') const showPriority = ref(false) +const showSSH = ref(false) const deleteItem = (item, idx) => { form.value.apiConfiguration.splice(form.value.apiConfiguration.indexOf(item), 1) @@ -1014,6 +1016,87 @@ defineExpose({ autocomplete="off" /> + SSH 设置 + + + + + { if (form.hasOwnProperty('configuration') && form.configuration.urlType == undefined) { form.configuration.urlType = 'hostName' } + if (form.hasOwnProperty('configuration') && form.configuration.sshType == undefined) { + form.configuration.sshType = 'password' + } } pid.value = nodeInfo.pid || '0' } else { diff --git a/core/core-frontend/src/views/visualized/data/datasource/form/option.ts b/core/core-frontend/src/views/visualized/data/datasource/form/option.ts index c34056591b..291b3a1b63 100644 --- a/core/core-frontend/src/views/visualized/data/datasource/form/option.ts +++ b/core/core-frontend/src/views/visualized/data/datasource/form/option.ts @@ -136,6 +136,12 @@ export interface Configuration { minPoolSize: string maxPoolSize: string queryTimeout: string + useSSH: boolean + sshHost: string + sshPort: string + sshUserName: string + sshType: string + sshPassword: string } export interface ApiConfiguration { diff --git a/pom.xml b/pom.xml index bb9b630fa1..8d1af194e7 100644 --- a/pom.xml +++ b/pom.xml @@ -52,6 +52,7 @@ 0.62.2 3.0.3 1.26.2 + 0.1.55 diff --git a/sdk/extensions/extensions-datasource/pom.xml b/sdk/extensions/extensions-datasource/pom.xml index f2da031f58..400b27ff5a 100644 --- a/sdk/extensions/extensions-datasource/pom.xml +++ b/sdk/extensions/extensions-datasource/pom.xml @@ -29,6 +29,11 @@ de + + com.jcraft + jsch + ${jsch.version} + diff --git a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/ConnectionObj.java b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/ConnectionObj.java new file mode 100644 index 0000000000..f36c4c2ca6 --- /dev/null +++ b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/dto/ConnectionObj.java @@ -0,0 +1,35 @@ +package io.dataease.extensions.datasource.dto; + +import com.jcraft.jsch.Session; +import io.dataease.extensions.datasource.provider.Provider; +import io.dataease.extensions.datasource.vo.DatasourceConfiguration; +import lombok.Data; + +import java.sql.Connection; + +@Data +public class ConnectionObj implements AutoCloseable { + + + private Connection connection; + private Session session; + private Integer lPort; + private DatasourceConfiguration configuration; + + @Override + public void close() throws Exception { + if (this.connection != null) { + this.connection.close(); + } + + if (session != null) { + System.out.println("session.disconnect()"); + session.disconnect(); + } + + if(lPort != null){ + Provider.getLPorts().remove(Long.valueOf(lPort)); + } + + } +} diff --git a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/provider/Provider.java b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/provider/Provider.java index b0381e5ba0..67dbf6fc45 100644 --- a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/provider/Provider.java +++ b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/provider/Provider.java @@ -1,10 +1,12 @@ package io.dataease.extensions.datasource.provider; +import com.jcraft.jsch.Session; import io.dataease.exception.DEException; import io.dataease.extensions.datasource.constant.SqlPlaceholderConstants; import io.dataease.extensions.datasource.dto.*; import io.dataease.extensions.datasource.model.SQLMeta; import io.dataease.extensions.datasource.vo.DatasourceConfiguration; +import lombok.Getter; import org.apache.calcite.config.Lex; import org.apache.calcite.sql.SqlDialect; import org.apache.calcite.sql.SqlNode; @@ -13,7 +15,8 @@ import org.apache.calcite.sql.parser.SqlParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.sql.Connection; +import java.io.IOException; +import java.net.Socket; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -30,7 +33,7 @@ public abstract class Provider { public abstract List getTables(DatasourceRequest datasourceRequest); - public abstract Connection getConnection(DatasourceDTO coreDatasource) throws DEException; + public abstract ConnectionObj getConnection(DatasourceDTO coreDatasource) throws Exception; public abstract String checkStatus(DatasourceRequest datasourceRequest) throws Exception; @@ -38,6 +41,11 @@ public abstract class Provider { public abstract List fetchTableField(DatasourceRequest datasourceRequest) throws DEException; + @Getter + private static final Map lPorts = new HashMap<>(); + @Getter + private static final Map sessions = new HashMap<>(); + public String rebuildSQL(String sql, SQLMeta sqlMeta, boolean crossDs, Map dsMap) { logger.info("calcite sql: " + sql); if (crossDs) { @@ -141,4 +149,28 @@ public abstract class Provider { } return sqlDialect; } + + synchronized public Integer getLport(Long datasourceId) throws Exception { + for (int i = 10000; i < 20000; i++) { + if (isPortAvailable(i) && !lPorts.values().contains(i)) { + if (datasourceId == null) { + lPorts.put((long) i, i); + } else { + lPorts.put(datasourceId, i); + } + return i; + } + } + throw new Exception("localhost无可用端口!"); + } + + public boolean isPortAvailable(int port) { + try { + Socket socket = new Socket("127.0.0.1", port); + socket.close(); + return false; + } catch (IOException e) { + return true; + } + } } diff --git a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/vo/Configuration.java b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/vo/Configuration.java index cdd0e07e25..a9673445a6 100644 --- a/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/vo/Configuration.java +++ b/sdk/extensions/extensions-datasource/src/main/java/io/dataease/extensions/datasource/vo/Configuration.java @@ -32,5 +32,31 @@ public class Configuration { private int minPoolSize = 5; private int maxPoolSize = 50; private int queryTimeout = 30; + private boolean useSSH = false; + private String sshHost; + private Integer sshPort; + private Integer lPort; + private String sshUserName; + private String sshType = "password"; + private String sshPassword; + private String sshKey; + private String sshKeyPassword; + + + public String getLHost(){ + if(useSSH){ + return "127.0.0.1"; + }else { + return this.host; + } + } + + public Integer getLPort(){ + if(useSSH && lPort != null){ + return lPort; + }else { + return this.port; + } + } }