From b40c63f02da16a4e9d795cf016bf69f38754c25e Mon Sep 17 00:00:00 2001 From: insist777 <84278047+insist777@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:09:02 +0800 Subject: [PATCH] [Feature][DataSource]Add trino datasource plugin (#12911) --- docs/docs/en/guide/datasource/trino.md | 22 ++ docs/docs/zh/guide/datasource/trino.md | 18 ++ docs/img/new_ui/dev/datasource/trino.png | Bin 0 -> 103766 bytes dolphinscheduler-bom/pom.xml | 7 + .../common/constants/DataSourceConstants.java | 3 + dolphinscheduler-data-quality/pom.xml | 5 + .../dolphinscheduler-datasource-all/pom.xml | 5 + .../dolphinscheduler-datasource-trino/pom.xml | 47 ++++ .../trino/TrinoDataSourceChannel.java | 31 +++ .../trino/TrinoDataSourceChannelFactory.java | 37 ++++ .../trino/TrinoDataSourceClient.java | 30 +++ .../trino/param/TrinoConnectionParam.java | 37 ++++ .../trino/param/TrinoDataSourceParamDTO.java | 42 ++++ .../trino/param/TrinoDataSourceProcessor.java | 153 +++++++++++++ .../TrinoDataSourceChannelFactoryTest.java | 34 +++ .../trino/TrinoDataSourceChannelTest.java | 45 ++++ .../param/TrinoDataSourceProcessorTest.java | 96 +++++++++ dolphinscheduler-datasource-plugin/pom.xml | 1 + dolphinscheduler-dist/release-docs/LICENSE | 1 + .../licenses/LICENSE-trino-jdbc.txt | 201 ++++++++++++++++++ .../dolphinscheduler/spi/enums/DbType.java | 2 +- .../src/service/modules/data-source/types.ts | 2 + .../src/views/datasource/list/use-form.ts | 5 + .../components/node/fields/use-datasource.ts | 5 + tools/dependencies/known-dependencies.txt | 1 + 25 files changed, 829 insertions(+), 1 deletion(-) create mode 100644 docs/docs/en/guide/datasource/trino.md create mode 100644 docs/docs/zh/guide/datasource/trino.md create mode 100644 docs/img/new_ui/dev/datasource/trino.png create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/pom.xml create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannel.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelFactory.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceClient.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoConnectionParam.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceParamDTO.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceProcessor.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelFactoryTest.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelTest.java create mode 100644 dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceProcessorTest.java create mode 100644 dolphinscheduler-dist/release-docs/licenses/LICENSE-trino-jdbc.txt diff --git a/docs/docs/en/guide/datasource/trino.md b/docs/docs/en/guide/datasource/trino.md new file mode 100644 index 0000000000..6c73ecb69c --- /dev/null +++ b/docs/docs/en/guide/datasource/trino.md @@ -0,0 +1,22 @@ +# Trino + +![Trino Datasource](../../../../img/new_ui/dev/datasource/trino.png) + +## Datasource Parameters + +| **Datasource** | **Description** | +|-------------------------|-------------------------------------------------------------------------------| +| Datasource | Select Trino. | +| Datasource Name | Enter the name of the datasource. | +| Description | Enter a description of the datasource. | +| IP/Host Name | Enter the Trino service IP. | +| Port | Enter the Trino service port. | +| Username | Set the username for Trino connection. | +| Password | Set the password for Trino connection. | +| Database Name | Enter the database name of the Trino connection. | +| jdbc connect parameters | Parameter settings for Trino connection, in JSON format. | +| Datasource Definition | Define whether the data source is a test data source or an online data source | + +## Native Supported + +Yes, could use this datasource by default. diff --git a/docs/docs/zh/guide/datasource/trino.md b/docs/docs/zh/guide/datasource/trino.md new file mode 100644 index 0000000000..55521d19dc --- /dev/null +++ b/docs/docs/zh/guide/datasource/trino.md @@ -0,0 +1,18 @@ +# Trino数据源 + +![trino](../../../../img/new_ui/dev/datasource/trino.png) + +- 数据源:选择 TRINO +- 数据源名称:输入数据源的名称 +- 描述:输入数据源的描述 +- IP 主机名:输入连接 TRINO 的 IP +- 端口:输入连接 TRINO 的端口 +- 用户名:设置连接 TRINO 的用户名 +- 密码:设置连接 TRINO 的密码 +- 数据库名:输入连接 TRINO 的数据库名称 +- Jdbc 连接参数:用于 TRINO 连接的参数设置,以 JSON 形式填写 +- 数据源定义: 定义数据源是否为测试数据源或上线数据源 + +## 是否原生支持 + +是,数据源不需要任务附加操作即可使用。 diff --git a/docs/img/new_ui/dev/datasource/trino.png b/docs/img/new_ui/dev/datasource/trino.png new file mode 100644 index 0000000000000000000000000000000000000000..2fe655c01a78bbc85bb1c78941dd756c02425783 GIT binary patch literal 103766 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%0D#=Jvx4R_8$tY=w40R#4CgMzAV@k7__7-gF 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 literal 0 HcmV?d00001 diff --git a/dolphinscheduler-bom/pom.xml b/dolphinscheduler-bom/pom.xml index ace609b50d..44db31e17f 100644 --- a/dolphinscheduler-bom/pom.xml +++ b/dolphinscheduler-bom/pom.xml @@ -100,6 +100,7 @@ 1.6.9 1.9.7 1.15 + 402 @@ -691,6 +692,12 @@ ${spring-ldap.version} + + io.trino + trino-jdbc + ${trino-jdbc.version} + + com.google.code.gson gson diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/DataSourceConstants.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/DataSourceConstants.java index cce4ec2f74..623c7e98df 100644 --- a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/DataSourceConstants.java +++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/DataSourceConstants.java @@ -35,6 +35,7 @@ public class DataSourceConstants { public static final String COM_PRESTO_JDBC_DRIVER = "com.facebook.presto.jdbc.PrestoDriver"; public static final String COM_REDSHIFT_JDBC_DRIVER = "com.amazon.redshift.jdbc42.Driver"; public static final String COM_ATHENA_JDBC_DRIVER = "com.simba.athena.jdbc.Driver"; + public static final String COM_TRINO_JDBC_DRIVER = "io.trino.jdbc.TrinoDriver"; /** * validation Query @@ -49,6 +50,7 @@ public class DataSourceConstants { public static final String PRESTO_VALIDATION_QUERY = "select 1"; public static final String REDHIFT_VALIDATION_QUERY = "select 1"; public static final String ATHENA_VALIDATION_QUERY = "select 1"; + public static final String TRINO_VALIDATION_QUERY = "select 1"; /** * jdbc url @@ -64,6 +66,7 @@ public class DataSourceConstants { public static final String JDBC_PRESTO = "jdbc:presto://"; public static final String JDBC_REDSHIFT = "jdbc:redshift://"; public static final String JDBC_ATHENA = "jdbc:awsathena://"; + public static final String JDBC_TRINO = "jdbc:trino://"; /** * database type diff --git a/dolphinscheduler-data-quality/pom.xml b/dolphinscheduler-data-quality/pom.xml index d715d1cb69..5e5ca36ff2 100644 --- a/dolphinscheduler-data-quality/pom.xml +++ b/dolphinscheduler-data-quality/pom.xml @@ -105,6 +105,11 @@ postgresql + + io.trino + trino-jdbc + + com.clickhouse clickhouse-jdbc diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-all/pom.xml b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-all/pom.xml index f5f966bba4..427c31f02e 100644 --- a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-all/pom.xml +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-all/pom.xml @@ -82,5 +82,10 @@ dolphinscheduler-datasource-presto ${project.version} + + org.apache.dolphinscheduler + dolphinscheduler-datasource-trino + ${project.version} + diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/pom.xml b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/pom.xml new file mode 100644 index 0000000000..45cc19d3f5 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/pom.xml @@ -0,0 +1,47 @@ + + + + 4.0.0 + + org.apache.dolphinscheduler + dolphinscheduler-datasource-plugin + dev-SNAPSHOT + + + dolphinscheduler-datasource-trino + jar + ${project.artifactId} + + + + org.apache.dolphinscheduler + dolphinscheduler-spi + + + + org.apache.dolphinscheduler + dolphinscheduler-datasource-api + + + + io.trino + trino-jdbc + + + diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannel.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannel.java new file mode 100644 index 0000000000..2ca06a89d7 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannel.java @@ -0,0 +1,31 @@ +/* + * 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.plugin.datasource.trino; + +import org.apache.dolphinscheduler.spi.datasource.BaseConnectionParam; +import org.apache.dolphinscheduler.spi.datasource.DataSourceChannel; +import org.apache.dolphinscheduler.spi.datasource.DataSourceClient; +import org.apache.dolphinscheduler.spi.enums.DbType; + +public class TrinoDataSourceChannel implements DataSourceChannel { + + @Override + public DataSourceClient createDataSourceClient(BaseConnectionParam baseConnectionParam, DbType dbType) { + return new TrinoDataSourceClient(baseConnectionParam, dbType); + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelFactory.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelFactory.java new file mode 100644 index 0000000000..8c9605d791 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelFactory.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.plugin.datasource.trino; + +import org.apache.dolphinscheduler.spi.datasource.DataSourceChannel; +import org.apache.dolphinscheduler.spi.datasource.DataSourceChannelFactory; + +import com.google.auto.service.AutoService; + +@AutoService(DataSourceChannelFactory.class) +public class TrinoDataSourceChannelFactory implements DataSourceChannelFactory { + + @Override + public String getName() { + return "trino"; + } + + @Override + public DataSourceChannel create() { + return new TrinoDataSourceChannel(); + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceClient.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceClient.java new file mode 100644 index 0000000000..cfa8f9b3aa --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceClient.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.plugin.datasource.trino; + +import org.apache.dolphinscheduler.plugin.datasource.api.client.CommonDataSourceClient; +import org.apache.dolphinscheduler.spi.datasource.BaseConnectionParam; +import org.apache.dolphinscheduler.spi.enums.DbType; + +public class TrinoDataSourceClient extends CommonDataSourceClient { + + public TrinoDataSourceClient(BaseConnectionParam baseConnectionParam, DbType dbType) { + super(baseConnectionParam, dbType); + } + +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoConnectionParam.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoConnectionParam.java new file mode 100644 index 0000000000..5f7fececb2 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoConnectionParam.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.plugin.datasource.trino.param; + +import org.apache.dolphinscheduler.spi.datasource.BaseConnectionParam; + +public class TrinoConnectionParam extends BaseConnectionParam { + + @Override + public String toString() { + return "TrinoConnectionParam{" + + "user='" + user + '\'' + + ", address='" + address + '\'' + + ", database='" + database + '\'' + + ", jdbcUrl='" + jdbcUrl + '\'' + + ", driverLocation='" + driverLocation + '\'' + + ", driverClassName='" + driverClassName + '\'' + + ", validationQuery='" + validationQuery + '\'' + + ", other='" + other + '\'' + + '}'; + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceParamDTO.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceParamDTO.java new file mode 100644 index 0000000000..fa58f961f4 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceParamDTO.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.plugin.datasource.trino.param; + +import org.apache.dolphinscheduler.plugin.datasource.api.datasource.BaseDataSourceParamDTO; +import org.apache.dolphinscheduler.spi.enums.DbType; + +public class TrinoDataSourceParamDTO extends BaseDataSourceParamDTO { + + @Override + public String toString() { + return "TrinoDataSourceParamDTO{" + + "name='" + name + '\'' + + ", note='" + note + '\'' + + ", host='" + host + '\'' + + ", port=" + port + + ", database='" + database + '\'' + + ", userName='" + userName + '\'' + + ", other='" + other + '\'' + + '}'; + } + + @Override + public DbType getType() { + return DbType.TRINO; + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceProcessor.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceProcessor.java new file mode 100644 index 0000000000..e4ed57554c --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/main/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceProcessor.java @@ -0,0 +1,153 @@ +/* + * 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.plugin.datasource.trino.param; + +import org.apache.dolphinscheduler.common.constants.Constants; +import org.apache.dolphinscheduler.common.constants.DataSourceConstants; +import org.apache.dolphinscheduler.common.utils.JSONUtils; +import org.apache.dolphinscheduler.plugin.datasource.api.datasource.AbstractDataSourceProcessor; +import org.apache.dolphinscheduler.plugin.datasource.api.datasource.BaseDataSourceParamDTO; +import org.apache.dolphinscheduler.plugin.datasource.api.datasource.DataSourceProcessor; +import org.apache.dolphinscheduler.plugin.datasource.api.utils.PasswordUtils; +import org.apache.dolphinscheduler.spi.datasource.BaseConnectionParam; +import org.apache.dolphinscheduler.spi.datasource.ConnectionParam; +import org.apache.dolphinscheduler.spi.enums.DbType; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +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; + +import com.google.auto.service.AutoService; + +@AutoService(DataSourceProcessor.class) +public class TrinoDataSourceProcessor extends AbstractDataSourceProcessor { + + @Override + public BaseDataSourceParamDTO castDatasourceParamDTO(String paramJson) { + return JSONUtils.parseObject(paramJson, TrinoDataSourceParamDTO.class); + } + + @Override + public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) { + TrinoConnectionParam connectionParams = (TrinoConnectionParam) createConnectionParams(connectionJson); + + String[] hostSeperator = connectionParams.getAddress().split(Constants.DOUBLE_SLASH); + String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(Constants.COMMA); + + TrinoDataSourceParamDTO TrinoDatasourceParamDTO = new TrinoDataSourceParamDTO(); + String[] split = hostPortArray[0].split(Constants.COLON); + TrinoDatasourceParamDTO.setHost(split[0]); + TrinoDatasourceParamDTO.setPort(Integer.valueOf(split[1])); + TrinoDatasourceParamDTO.setDatabase(connectionParams.getDatabase()); + TrinoDatasourceParamDTO.setUserName(connectionParams.getUser()); + TrinoDatasourceParamDTO.setOther(parseOther(connectionParams.getOther())); + + return TrinoDatasourceParamDTO; + } + + @Override + public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) { + TrinoDataSourceParamDTO TrinoParam = (TrinoDataSourceParamDTO) datasourceParam; + String address = + String.format("%s%s:%s", DataSourceConstants.JDBC_TRINO, TrinoParam.getHost(), TrinoParam.getPort()); + String jdbcUrl = address + "/" + TrinoParam.getDatabase(); + + TrinoConnectionParam TrinoConnectionParam = new TrinoConnectionParam(); + TrinoConnectionParam.setUser(TrinoParam.getUserName()); + TrinoConnectionParam.setPassword(PasswordUtils.encodePassword(TrinoParam.getPassword())); + TrinoConnectionParam.setOther(transformOther(TrinoParam.getOther())); + TrinoConnectionParam.setAddress(address); + TrinoConnectionParam.setJdbcUrl(jdbcUrl); + TrinoConnectionParam.setDatabase(TrinoParam.getDatabase()); + TrinoConnectionParam.setDriverClassName(getDatasourceDriver()); + TrinoConnectionParam.setValidationQuery(getValidationQuery()); + TrinoConnectionParam.setProps(TrinoParam.getOther()); + + return TrinoConnectionParam; + } + + @Override + public ConnectionParam createConnectionParams(String connectionJson) { + return JSONUtils.parseObject(connectionJson, TrinoConnectionParam.class); + } + + @Override + public String getDatasourceDriver() { + return DataSourceConstants.COM_TRINO_JDBC_DRIVER; + } + + @Override + public String getValidationQuery() { + return DataSourceConstants.TRINO_VALIDATION_QUERY; + } + + @Override + public String getJdbcUrl(ConnectionParam connectionParam) { + TrinoConnectionParam TrinoConnectionParam = (TrinoConnectionParam) connectionParam; + if (StringUtils.isNotEmpty(TrinoConnectionParam.getOther())) { + return String.format("%s?%s", TrinoConnectionParam.getJdbcUrl(), TrinoConnectionParam.getOther()); + } + return TrinoConnectionParam.getJdbcUrl(); + } + + @Override + public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException { + TrinoConnectionParam TrinoConnectionParam = (TrinoConnectionParam) connectionParam; + Class.forName(getDatasourceDriver()); + return DriverManager.getConnection(getJdbcUrl(connectionParam), + TrinoConnectionParam.getUser(), PasswordUtils.decodePassword(TrinoConnectionParam.getPassword())); + } + + @Override + public DbType getDbType() { + return DbType.TRINO; + } + + @Override + public DataSourceProcessor create() { + return new TrinoDataSourceProcessor(); + } + + 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-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelFactoryTest.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelFactoryTest.java new file mode 100644 index 0000000000..8f62560126 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelFactoryTest.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.plugin.datasource.trino; + +import org.apache.dolphinscheduler.spi.datasource.DataSourceChannel; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class TrinoDataSourceChannelFactoryTest { + + @Test + public void testCreate() { + TrinoDataSourceChannelFactory sourceChannelFactory = new TrinoDataSourceChannelFactory(); + DataSourceChannel dataSourceChannel = sourceChannelFactory.create(); + sourceChannelFactory.getName(); + Assertions.assertNotNull(dataSourceChannel); + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelTest.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelTest.java new file mode 100644 index 0000000000..17f4098c52 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/TrinoDataSourceChannelTest.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.plugin.datasource.trino; + +import org.apache.dolphinscheduler.common.constants.DataSourceConstants; +import org.apache.dolphinscheduler.plugin.datasource.trino.param.TrinoConnectionParam; +import org.apache.dolphinscheduler.spi.enums.DbType; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class TrinoDataSourceChannelTest { + + @Test + public void testCreateDataSourceClient() { + TrinoDataSourceChannel sourceChannel = new TrinoDataSourceChannel(); + TrinoConnectionParam trinoConnectionParam = new TrinoConnectionParam(); + trinoConnectionParam.setValidationQuery(DataSourceConstants.TRINO_VALIDATION_QUERY); + trinoConnectionParam.setDriverLocation(DataSourceConstants.COM_TRINO_JDBC_DRIVER); + trinoConnectionParam.setDriverClassName(DataSourceConstants.COM_TRINO_JDBC_DRIVER); + try { + sourceChannel.createDataSourceClient(trinoConnectionParam, DbType.TRINO); + } catch (Exception e) { + Assertions.assertEquals(RuntimeException.class, e.getClass()); + } + } +} diff --git a/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceProcessorTest.java b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceProcessorTest.java new file mode 100644 index 0000000000..71ad9f7ea0 --- /dev/null +++ b/dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-trino/src/test/java/org/apache/dolphinscheduler/plugin/datasource/trino/param/TrinoDataSourceProcessorTest.java @@ -0,0 +1,96 @@ +/* + * 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.plugin.datasource.trino.param; + +import org.apache.dolphinscheduler.common.constants.DataSourceConstants; +import org.apache.dolphinscheduler.plugin.datasource.api.utils.PasswordUtils; +import org.apache.dolphinscheduler.spi.enums.DbType; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class TrinoDataSourceProcessorTest { + + private TrinoDataSourceProcessor TrinoDatasourceProcessor = new TrinoDataSourceProcessor(); + + @Test + public void testCreateConnectionParams() { + Map props = new HashMap<>(); + props.put("serverTimezone", "utc"); + TrinoDataSourceParamDTO TrinoDatasourceParamDTO = new TrinoDataSourceParamDTO(); + TrinoDatasourceParamDTO.setHost("localhost"); + TrinoDatasourceParamDTO.setPort(8080); + TrinoDatasourceParamDTO.setDatabase("default"); + TrinoDatasourceParamDTO.setUserName("trino"); + TrinoDatasourceParamDTO.setPassword("trino"); + TrinoDatasourceParamDTO.setOther(props); + try (MockedStatic mockedStaticPasswordUtils = Mockito.mockStatic(PasswordUtils.class)) { + mockedStaticPasswordUtils.when(() -> PasswordUtils.encodePassword(Mockito.anyString())).thenReturn("test"); + TrinoConnectionParam connectionParams = (TrinoConnectionParam) TrinoDatasourceProcessor + .createConnectionParams(TrinoDatasourceParamDTO); + Assertions.assertEquals("jdbc:trino://localhost:8080", connectionParams.getAddress()); + Assertions.assertEquals("jdbc:trino://localhost:8080/default", connectionParams.getJdbcUrl()); + } + } + + @Test + public void testCreateConnectionParams2() { + String connectionJson = + "{\"user\":\"trino\",\"password\":\"trino\",\"address\":\"jdbc:trino://localhost:8080\"" + + ",\"database\":\"default\",\"jdbcUrl\":\"jdbc:trino://localhost:8080/default\"}"; + TrinoConnectionParam connectionParams = (TrinoConnectionParam) TrinoDatasourceProcessor + .createConnectionParams(connectionJson); + Assertions.assertNotNull(connectionParams); + Assertions.assertEquals("trino", connectionParams.getUser()); + } + + @Test + public void testGetDatasourceDriver() { + Assertions.assertEquals(DataSourceConstants.COM_TRINO_JDBC_DRIVER, + TrinoDatasourceProcessor.getDatasourceDriver()); + } + + @Test + public void testGetJdbcUrl() { + TrinoConnectionParam TrinoConnectionParam = new TrinoConnectionParam(); + TrinoConnectionParam.setJdbcUrl("jdbc:postgresql://localhost:8080/default"); + TrinoConnectionParam.setOther("other"); + Assertions.assertEquals("jdbc:postgresql://localhost:8080/default?other", + TrinoDatasourceProcessor.getJdbcUrl(TrinoConnectionParam)); + + } + + @Test + public void testGetDbType() { + Assertions.assertEquals(DbType.TRINO, TrinoDatasourceProcessor.getDbType()); + } + + @Test + public void testGetValidationQuery() { + Assertions.assertEquals(DataSourceConstants.TRINO_VALIDATION_QUERY, + TrinoDatasourceProcessor.getValidationQuery()); + } +} diff --git a/dolphinscheduler-datasource-plugin/pom.xml b/dolphinscheduler-datasource-plugin/pom.xml index 81877cf2d0..78979924bb 100644 --- a/dolphinscheduler-datasource-plugin/pom.xml +++ b/dolphinscheduler-datasource-plugin/pom.xml @@ -41,6 +41,7 @@ dolphinscheduler-datasource-all dolphinscheduler-datasource-redshift dolphinscheduler-datasource-athena + dolphinscheduler-datasource-trino diff --git a/dolphinscheduler-dist/release-docs/LICENSE b/dolphinscheduler-dist/release-docs/LICENSE index 25ac08c856..ff012b0a5a 100644 --- a/dolphinscheduler-dist/release-docs/LICENSE +++ b/dolphinscheduler-dist/release-docs/LICENSE @@ -401,6 +401,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt. protostuff-collectionschema 1.7.2: https://github.com/protostuff/protostuff/protostuff-collectionschema Apache-2.0 prometheus client_java(simpleclient) 0.15.0: https://github.com/prometheus/client_java, Apache 2.0 snowflake snowflake-2010: https://github.com/twitter-archive/snowflake/tree/snowflake-2010, Apache 2.0 + trino-jdbc 402: https://mvnrepository.com/artifact/io.trino/trino-jdbc/402, Apache 2.0 kubernetes-client 5.10.2: https://mvnrepository.com/artifact/io.fabric8/kubernetes-client/5.10.2, Apache 2.0 kubernetes-model-admissionregistration 5.10.2: https://mvnrepository.com/artifact/io.fabric8/kubernetes-model-admissionregistration/5.10.2, Apache 2.0 kubernetes-model-apiextensions 5.10.2: https://mvnrepository.com/artifact/io.fabric8/kubernetes-model-apiextensions/5.10.2, Apache 2.0 diff --git a/dolphinscheduler-dist/release-docs/licenses/LICENSE-trino-jdbc.txt b/dolphinscheduler-dist/release-docs/licenses/LICENSE-trino-jdbc.txt new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/dolphinscheduler-dist/release-docs/licenses/LICENSE-trino-jdbc.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. 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 index cd00bf1234..50aeeffbcd 100644 --- 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 @@ -40,7 +40,7 @@ public enum DbType { H2(9, "h2"), REDSHIFT(10, "redshift"), ATHENA(11, "athena"), - ; + TRINO(12, "trino"); @EnumValue private final int code; diff --git a/dolphinscheduler-ui/src/service/modules/data-source/types.ts b/dolphinscheduler-ui/src/service/modules/data-source/types.ts index ad431353c7..3e5f06dc52 100644 --- a/dolphinscheduler-ui/src/service/modules/data-source/types.ts +++ b/dolphinscheduler-ui/src/service/modules/data-source/types.ts @@ -27,6 +27,7 @@ type IDataBase = | 'PRESTO' | 'REDSHIFT' | 'ATHENA' + | 'TRINO' type IDataBaseLabel = | 'MYSQL' @@ -40,6 +41,7 @@ type IDataBaseLabel = | 'PRESTO' | 'REDSHIFT' | 'ATHENA' +| 'TRINO' interface IDataSource { id?: number diff --git a/dolphinscheduler-ui/src/views/datasource/list/use-form.ts b/dolphinscheduler-ui/src/views/datasource/list/use-form.ts index 2fb12b6efe..d2e67d0096 100644 --- a/dolphinscheduler-ui/src/views/datasource/list/use-form.ts +++ b/dolphinscheduler-ui/src/views/datasource/list/use-form.ts @@ -293,6 +293,11 @@ export const datasourceType: IDataBaseOptionKeys = { value: 'ATHENA', label: 'ATHENA', defaultPort: 0 + }, + TRINO: { + value: 'TRINO', + label: 'TRINO', + defaultPort: 8080 } } diff --git a/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datasource.ts b/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datasource.ts index d0610c350d..f47803e21c 100644 --- a/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datasource.ts +++ b/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datasource.ts @@ -92,6 +92,11 @@ export function useDatasource( id: 10, code: 'ATHENA', disabled: false + }, + { + id: 12, + code: 'TRINO', + disabled: false } ] diff --git a/tools/dependencies/known-dependencies.txt b/tools/dependencies/known-dependencies.txt index e109dbc8fb..ea74729853 100644 --- a/tools/dependencies/known-dependencies.txt +++ b/tools/dependencies/known-dependencies.txt @@ -371,3 +371,4 @@ opentracing-util-0.33.0.jar jdom2-2.0.6.1.jar jettison-1.1.jar stax-api-1.0.1.jar +trino-jdbc-402.jar