源码地址:GitHub - apache/dolphinscheduler at 3.1.7-release

个人fork gitee地址:DolphinScheduler:Gitee)

后端代码更改项:

修改项1:DataSourceConstants.java

路径:dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/constants/DataSourceConstants.java

 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";
//add HANA driver message
public static final String COM_HANA_DB_JDBC_DRIVER = "com.sap.db.jdbc.Driver"; /** * validation Query */
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";
// add HANA Connect check sql
public static final String HANA_VALIDATION_QUERY = "select 1"; /** * jdbc url */ public static final String JDBC_PRESTO = "jdbc:presto://"; public static final String JDBC_REDSHIFT = "jdbc:redshift://"; public static final String JDBC_ATHENA = "jdbc:awsathena://";
// add HANA jdbc url modual
public static final String JDBC_HANA = "jdbc:sap://";

修改项2:前端映射枚举值

路径:dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/DbType.java

    H2(9, "h2"),
REDSHIFT(10,"redshift"),
ATHENA(11,"athena"),
HANA(12,"hana"),
;

修改项3:dolphinscheduler-datasource-hana模块

路径dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana,模块层级如下

pom文件

路径:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-datasource-plugin</artifactId>
<version>3.1.8-SNAPSHOT</version>
</parent> <artifactId>dolphinscheduler-datasource-hana</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name> <dependencies> <dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-spi</artifactId>
<scope>provided</scope>
</dependency> <dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-datasource-api</artifactId>
<version>${project.version}</version>
</dependency> <dependency>
<groupId>com.sap.cloud.db.jdbc</groupId>
<artifactId>ngdbc</artifactId>
<version>2.17.10</version>
</dependency> <dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<type>jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>

HanaDataSourceChannel.java

路径:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/src/main/java/org/apache/dolphinscheduler/plugin/datasource/hana/HanaDataSourceChannel.java

/*
* 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.hana; 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 HanaDataSourceChannel implements DataSourceChannel { @Override
public DataSourceClient createDataSourceClient(BaseConnectionParam baseConnectionParam, DbType dbType) {
return new HanaDataSourceClient(baseConnectionParam, dbType);
}
}

HanaDataSourceChannelFactory.java

路径:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/src/main/java/org/apache/dolphinscheduler/plugin/datasource/hana/HanaDataSourceChannelFactory.java

/*
* 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.hana; 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 HanaDataSourceChannelFactory implements DataSourceChannelFactory { @Override
public String getName() {
return "hana";
} @Override
public DataSourceChannel create() {
return new HanaDataSourceChannel();
}
}

HanaDataSourceClient.java

路径:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/src/main/java/org/apache/dolphinscheduler/plugin/datasource/hana/HanaDataSourceClient.java

/*
* 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.hana; 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 HanaDataSourceClient extends CommonDataSourceClient { public HanaDataSourceClient(BaseConnectionParam baseConnectionParam, DbType dbType) {
super(baseConnectionParam, dbType);
} }

HanaConnectionParam.java

路径:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/src/main/java/org/apache/dolphinscheduler/plugin/datasource/hana/param/HanaConnectionParam.java

/*
* 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.hana.param; import org.apache.dolphinscheduler.spi.datasource.BaseConnectionParam; public class HanaConnectionParam extends BaseConnectionParam { @Override
public String toString() {
return "HanaConnectionParam{"
+ "user='" + user + '\''
+ ", password='" + password + '\''
+ ", address='" + address + '\''
+ ", database='" + database + '\''
+ ", jdbcUrl='" + jdbcUrl + '\''
+ ", driverLocation='" + driverLocation + '\''
+ ", driverClassName='" + driverClassName + '\''
+ ", validationQuery='" + validationQuery + '\''
+ ", other='" + other + '\''
+ '}';
}
}

HanaDataSourceParamDTO.java

路径:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/src/main/java/org/apache/dolphinscheduler/plugin/datasource/hana/param/HanaDataSourceParamDTO.java

/*
* 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.hana.param; import org.apache.dolphinscheduler.plugin.datasource.api.datasource.BaseDataSourceParamDTO;
import org.apache.dolphinscheduler.spi.enums.DbType; public class HanaDataSourceParamDTO extends BaseDataSourceParamDTO { @Override
public String toString() {
return "HanaDataSourceParamDTO{"
+ "name='" + name + '\''
+ ", note='" + note + '\''
+ ", host='" + host + '\''
+ ", port=" + port
+ ", database='" + database + '\''
+ ", userName='" + userName + '\''
+ ", password='" + password + '\''
+ ", other='" + other + '\''
+ '}';
} @Override
public DbType getType() {
return DbType.HANA;
}
}

HanaDataSourceProcessor.java

dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/src/main/java/org/apache/dolphinscheduler/plugin/datasource/hana/param/HanaDataSourceProcessor.java

/*
* 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.hana.param; import org.apache.commons.lang3.StringUtils;
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 java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.*; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.google.auto.service.AutoService;
@AutoService(DataSourceProcessor.class)
public class HanaDataSourceProcessor extends AbstractDataSourceProcessor { private final Logger logger = LoggerFactory.getLogger(HanaDataSourceProcessor.class); private static final String APPEND_PARAMS = "reconnect=true";
@Override
public BaseDataSourceParamDTO castDatasourceParamDTO(String paramJson) {
return JSONUtils.parseObject(paramJson, HanaDataSourceParamDTO.class);
} @Override
public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) {
HanaConnectionParam connectionParams = (HanaConnectionParam) createConnectionParams(connectionJson);
HanaDataSourceParamDTO hanaDatasourceParamDTO = new HanaDataSourceParamDTO();
hanaDatasourceParamDTO.setUserName(connectionParams.getUser());
hanaDatasourceParamDTO.setDatabase(connectionParams.getDatabase());
String address = connectionParams.getAddress();
String[] hostSeperator = address.split(Constants.DOUBLE_SLASH);
String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(Constants.COMMA);
hanaDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(Constants.COLON)[1]));
hanaDatasourceParamDTO.setHost(hostPortArray[0].split(Constants.COLON)[0]); return hanaDatasourceParamDTO;
} @Override
public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO dataSourceParam) {
HanaDataSourceParamDTO hanaDatasourceParam = (HanaDataSourceParamDTO) dataSourceParam;
String address = String.format("%s%s:%s", DataSourceConstants.JDBC_HANA, hanaDatasourceParam.getHost(),
hanaDatasourceParam.getPort());
String jdbcUrl = String.format("%s?currentschema=%s", address, hanaDatasourceParam.getDatabase()); HanaConnectionParam hanaConnectionParam = new HanaConnectionParam();
hanaConnectionParam.setJdbcUrl(jdbcUrl);
hanaConnectionParam.setValidationQuery("select 1 from DUMMY");
hanaConnectionParam.setDatabase(hanaDatasourceParam.getDatabase());
hanaConnectionParam.setAddress(address);
hanaConnectionParam.setUser(hanaDatasourceParam.getUserName());
hanaConnectionParam.setPassword(PasswordUtils.encodePassword(hanaDatasourceParam.getPassword()));
hanaConnectionParam.setDriverClassName(getDatasourceDriver());
hanaConnectionParam.setOther(transformOther(hanaDatasourceParam.getOther())); return hanaConnectionParam;
} @Override
public ConnectionParam createConnectionParams(String connectionJson) {
return JSONUtils.parseObject(connectionJson, HanaConnectionParam.class);
} @Override
public String getDatasourceDriver() {
return DataSourceConstants.COM_HANA_DB_JDBC_DRIVER;
} @Override
public String getValidationQuery() {
return DataSourceConstants.COM_HANA_DB_JDBC_DRIVER;
} @Override
public String getJdbcUrl(ConnectionParam connectionParam) {
HanaConnectionParam hanaConnectionParam = (HanaConnectionParam) connectionParam;
String jdbcUrl = hanaConnectionParam.getJdbcUrl();
// get customize connection message,parse it to map
if (MapUtils.isNotEmpty(parseOther(hanaConnectionParam.getOther()))) {
return String.format("%s?%s&%s", jdbcUrl, hanaConnectionParam.getOther(), APPEND_PARAMS);
}
return String.format("%s&%s", jdbcUrl, APPEND_PARAMS);
} @Override
public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException {
HanaConnectionParam hanaConnectionParam = (HanaConnectionParam) connectionParam;
Class.forName(getDatasourceDriver());
String user = hanaConnectionParam.getUser();
String password = PasswordUtils.decodePassword(hanaConnectionParam.getPassword());
return DriverManager.getConnection(getJdbcUrl(connectionParam), user, password);
} @Override
public DbType getDbType() {
return DbType.HANA;
} @Override
public DataSourceProcessor create() {
logger.info("create hana datasource processor success");
return new HanaDataSourceProcessor();
} /**
* transform map to string with &
* @param otherMap connection map
* @return return the connection string format
*/
private String transformOther(Map<String, String> otherMap) {
if (MapUtils.isEmpty(otherMap)) {
return null;
}
List<String> list = new ArrayList<>();
otherMap.forEach((key, value) -> list.add(String.format("%s=%s", key, value)));
return String.join("&", list);
} /**
* transform string to map
* @param other connection string
* @return return connection map format
*/
private Map<String, String> parseOther(String other) {
if (StringUtils.isEmpty(other)) {
return null;
}
Map<String, String> otherMap = new LinkedHashMap<>();
for (String config : other.split("&")) {
otherMap.put(config.split("=")[0], config.split("=")[1]);
}
return otherMap;
}
}

HanaDataSourceProcessorTest.java

路径:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/src/test/java/org/apache/dolphinscheduler/plugin/datasource/hana/param/HanaDataSourceProcessorTest.java

/*
* 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.hana.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 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; import java.util.HashMap;
import java.util.Map; @ExtendWith(MockitoExtension.class)
public class HanaDataSourceProcessorTest { private HanaDataSourceProcessor hanaDataSourceProcessor = new HanaDataSourceProcessor(); @Test
public void testCreateConnectionParams() {
Map<String, String> props = new HashMap<>();
HanaDataSourceParamDTO mysqlDatasourceParamDTO = new HanaDataSourceParamDTO();
mysqlDatasourceParamDTO.setUserName("root");
mysqlDatasourceParamDTO.setPassword("123456");
mysqlDatasourceParamDTO.setHost("localhost");
mysqlDatasourceParamDTO.setPort(30015);
mysqlDatasourceParamDTO.setDatabase("default");
mysqlDatasourceParamDTO.setOther(props);
try (MockedStatic<PasswordUtils> mockedPasswordUtils = Mockito.mockStatic(PasswordUtils.class)) {
Mockito.when(PasswordUtils.encodePassword(Mockito.anyString())).thenReturn("test");
HanaConnectionParam connectionParams = (HanaConnectionParam) hanaDataSourceProcessor
.createConnectionParams(mysqlDatasourceParamDTO);
Assertions.assertEquals("jdbc:sap://localhost:30015", connectionParams.getAddress());
Assertions.assertEquals("jdbc:sap://localhost:30015?currentschema=default", connectionParams.getJdbcUrl());
}
} @Test
public void testCreateConnectionParams2() {
String connectionJson = "{\"user\":\"root\",\"password\":\"123456\",\"address\":\"jdbc:sap://localhost:30015\""
+ ",\"database\":\"default\",\"jdbcUrl\":\"jdbc:sap://localhost:30015?currentschema=default\"}";
HanaConnectionParam connectionParams = (HanaConnectionParam) hanaDataSourceProcessor
.createConnectionParams(connectionJson);
Assertions.assertNotNull(connectionJson);
Assertions.assertEquals("root", connectionParams.getUser());
} @Test
public void testGetDatasourceDriver() {
Assertions.assertEquals(DataSourceConstants.COM_HANA_DB_JDBC_DRIVER,
hanaDataSourceProcessor.getDatasourceDriver());
} @Test
public void testGetJdbcUrl() {
HanaConnectionParam hanaConnectionParam = new HanaConnectionParam();
hanaConnectionParam.setJdbcUrl("jdbc:sap://localhost:30015?currentschema=default");
Assertions.assertEquals(
"jdbc:sap://localhost:30015?currentschema=default&reconnect=true",
hanaDataSourceProcessor.getJdbcUrl(hanaConnectionParam));
} @Test
public void testGetDbType() {
Assertions.assertEquals(DbType.HANA, hanaDataSourceProcessor.getDbType());
} @Test
public void testGetValidationQuery() {
Assertions.assertEquals(DataSourceConstants.HANA_VALIDATION_QUERY,
hanaDataSourceProcessor.getValidationQuery());
} @Test
public void testGetDatasourceUniqueId() {
HanaConnectionParam mysqlConnectionParam = new HanaConnectionParam();
mysqlConnectionParam.setJdbcUrl("jdbc:sap://localhost:30015?currentschema=default");
mysqlConnectionParam.setUser("root");
mysqlConnectionParam.setPassword("123456");
try (MockedStatic<PasswordUtils> mockedPasswordUtils = Mockito.mockStatic(PasswordUtils.class)) {
Mockito.when(PasswordUtils.encodePassword(Mockito.anyString())).thenReturn("123456");
Assertions.assertEquals("hana@root@123456@jdbc:sap://localhost:30015?currentschema=default",
hanaDataSourceProcessor.getDatasourceUniqueId(mysqlConnectionParam, DbType.HANA));
}
}
}

JDBCDataSourceProviderTest.java

路径:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/src/test/java/org/apache/dolphinscheduler/plugin/datasource/hana/provider/JDBCDataSourceProviderTest.java

/*
* 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.hana.provider; import com.zaxxer.hikari.HikariDataSource;
import org.apache.dolphinscheduler.plugin.datasource.api.provider.JDBCDataSourceProvider;
import org.apache.dolphinscheduler.plugin.datasource.hana.param.HanaConnectionParam;
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.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class)
public class JDBCDataSourceProviderTest { @Test
public void testCreateJdbcDataSource() {
try (
MockedStatic<JDBCDataSourceProvider> mockedJDBCDataSourceProvider =
Mockito.mockStatic(JDBCDataSourceProvider.class)) {
HikariDataSource dataSource = Mockito.mock(HikariDataSource.class);
mockedJDBCDataSourceProvider
.when(() -> JDBCDataSourceProvider.createJdbcDataSource(Mockito.any(), Mockito.any()))
.thenReturn(dataSource);
Assertions.assertNotNull(
JDBCDataSourceProvider.createJdbcDataSource(new HanaConnectionParam(), DbType.HANA));
}
} @Test
public void testCreateOneSessionJdbcDataSource() {
try (
MockedStatic<JDBCDataSourceProvider> mockedJDBCDataSourceProvider =
Mockito.mockStatic(JDBCDataSourceProvider.class)) {
HikariDataSource dataSource = Mockito.mock(HikariDataSource.class);
mockedJDBCDataSourceProvider
.when(() -> JDBCDataSourceProvider.createOneSessionJdbcDataSource(Mockito.any(), Mockito.any()))
.thenReturn(dataSource);
Assertions.assertNotNull(
JDBCDataSourceProvider.createOneSessionJdbcDataSource(new HanaConnectionParam(), DbType.HANA));
}
} }

DataSourceUtilsTest.java

路径:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/src/test/java/org/apache/dolphinscheduler/plugin/datasource/hana/utils/DataSourceUtilsTest.java

/*
* 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.hana.utils; import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.common.utils.PropertyUtils;
import org.apache.dolphinscheduler.plugin.datasource.api.plugin.DataSourceClientProvider;
import org.apache.dolphinscheduler.plugin.datasource.api.utils.CommonUtils;
import org.apache.dolphinscheduler.plugin.datasource.api.utils.DataSourceUtils;
import org.apache.dolphinscheduler.plugin.datasource.api.utils.PasswordUtils;
import org.apache.dolphinscheduler.plugin.datasource.hana.param.HanaConnectionParam;
import org.apache.dolphinscheduler.plugin.datasource.hana.param.HanaDataSourceParamDTO;
import org.apache.dolphinscheduler.spi.datasource.ConnectionParam;
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.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension; import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException; @ExtendWith(MockitoExtension.class)
public class DataSourceUtilsTest { @Test
public void testCheckDatasourceParam() {
HanaDataSourceParamDTO hanaDataSourceParamDTO = new HanaDataSourceParamDTO();
hanaDataSourceParamDTO.setHost("localhost");
hanaDataSourceParamDTO.setDatabase("default");
Map<String, String> other = new HashMap<>();
other.put("reconnect", "true");
hanaDataSourceParamDTO.setOther(other);
DataSourceUtils.checkDatasourceParam(hanaDataSourceParamDTO);
Assertions.assertTrue(true);
} @Test
public void testBuildConnectionParams() {
HanaDataSourceParamDTO hanaDataSourceParamDTO = new HanaDataSourceParamDTO();
hanaDataSourceParamDTO.setHost("localhost");
hanaDataSourceParamDTO.setDatabase("default");
hanaDataSourceParamDTO.setUserName("root");
hanaDataSourceParamDTO.setPort(30015);
hanaDataSourceParamDTO.setPassword("123456"); try (
MockedStatic<PasswordUtils> mockedStaticPasswordUtils = Mockito.mockStatic(PasswordUtils.class);
MockedStatic<CommonUtils> mockedStaticCommonUtils = Mockito.mockStatic(CommonUtils.class)) {
mockedStaticPasswordUtils.when(() -> PasswordUtils.encodePassword(Mockito.anyString()))
.thenReturn("123456");
mockedStaticCommonUtils.when(CommonUtils::getKerberosStartupState).thenReturn(false);
ConnectionParam connectionParam = DataSourceUtils.buildConnectionParams(hanaDataSourceParamDTO);
Assertions.assertNotNull(connectionParam);
}
} @Test
public void testBuildConnectionParams2() {
HanaDataSourceParamDTO hanaDatasourceParamDTO = new HanaDataSourceParamDTO();
hanaDatasourceParamDTO.setHost("localhost");
hanaDatasourceParamDTO.setDatabase("default");
hanaDatasourceParamDTO.setUserName("root");
hanaDatasourceParamDTO.setPort(30015);
hanaDatasourceParamDTO.setPassword("123456");
ConnectionParam connectionParam =
DataSourceUtils.buildConnectionParams(DbType.HANA, JSONUtils.toJsonString(hanaDatasourceParamDTO));
Assertions.assertNotNull(connectionParam);
} @Test
public void testGetConnection() throws ExecutionException {
try (
MockedStatic<PropertyUtils> mockedStaticPropertyUtils = Mockito.mockStatic(PropertyUtils.class);
MockedStatic<DataSourceClientProvider> mockedStaticDataSourceClientProvider =
Mockito.mockStatic(DataSourceClientProvider.class)) {
mockedStaticPropertyUtils.when(() -> PropertyUtils.getLong("kerberos.expire.time", 24L)).thenReturn(24L);
DataSourceClientProvider clientProvider = Mockito.mock(DataSourceClientProvider.class);
mockedStaticDataSourceClientProvider.when(DataSourceClientProvider::getInstance).thenReturn(clientProvider); Connection connection = Mockito.mock(Connection.class);
Mockito.when(clientProvider.getConnection(Mockito.any(), Mockito.any())).thenReturn(connection); HanaConnectionParam connectionParam = new HanaConnectionParam();
connectionParam.setUser("root");
connectionParam.setPassword("123456");
connection = DataSourceClientProvider.getInstance().getConnection(DbType.HANA, connectionParam); Assertions.assertNotNull(connection);
}
} @Test
public void testGetJdbcUrl() {
HanaConnectionParam hanaConnectionParam = new HanaConnectionParam();
hanaConnectionParam.setJdbcUrl("jdbc:sap://localhost:30015");
String jdbcUrl = DataSourceUtils.getJdbcUrl(DbType.HANA, hanaConnectionParam);
Assertions.assertEquals(
"jdbc:sap://localhost:30015?reconnect=true",
jdbcUrl);
} @Test
public void testBuildDatasourceParamDTO() {
HanaConnectionParam connectionParam = new HanaConnectionParam();
connectionParam.setJdbcUrl(
"jdbc:sap://localhost:30015?reconnect=true");
connectionParam.setAddress("jdbc:mysql://localhost:30015");
connectionParam.setUser("root");
connectionParam.setPassword("123456"); Assertions.assertNotNull(
DataSourceUtils.buildDatasourceParamDTO(DbType.HANA, JSONUtils.toJsonString(connectionParam))); } @Test
public void testGetDatasourceProcessor() {
Assertions.assertNotNull(DataSourceUtils.getDatasourceProcessor(DbType.HANA));
} @Test
public void testGetDatasourceProcessorError() {
Assertions.assertThrows(Exception.class, () -> {
DataSourceUtils.getDatasourceProcessor(null);
});
}
}

HanaDataSourceChannelFactoryTest.java

路径:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/src/test/java/org/apache/dolphinscheduler/plugin/datasource/hana/HanaDataSourceChannelFactoryTest.java

/*
* 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.hana; import org.apache.dolphinscheduler.spi.datasource.DataSourceChannel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; public class HanaDataSourceChannelFactoryTest { @Test
public void testCreate() {
HanaDataSourceChannelFactory sourceChannelFactory = new HanaDataSourceChannelFactory();
DataSourceChannel dataSourceChannel = sourceChannelFactory.create();
Assertions.assertNotNull(dataSourceChannel);
}
}

HanaDataSourceChannelTest.java

路径:dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-hana/src/test/java/org/apache/dolphinscheduler/plugin/datasource/hana/HanaDataSourceChannelTest.java

/*
* 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.hana; import org.apache.dolphinscheduler.plugin.datasource.hana.param.HanaConnectionParam;
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.Mockito;
import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class)
public class HanaDataSourceChannelTest { @Test
public void testCreateDataSourceClient() {
HanaDataSourceChannel sourceChannel = Mockito.mock(HanaDataSourceChannel.class);
HanaDataSourceClient dataSourceClient = Mockito.mock(HanaDataSourceClient.class);
Mockito.when(sourceChannel.createDataSourceClient(Mockito.any(), Mockito.any())).thenReturn(dataSourceClient);
Assertions.assertNotNull(sourceChannel.createDataSourceClient(new HanaConnectionParam(), DbType.HANA));
}
}

修改项4:打包相关依赖

dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-all/pom.xml

dependencies中新增hana模块依赖

        <dependency>
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-datasource-hana</artifactId>
<version>${project.version}</version>
</dependency>

dolphinscheduler-datasource-plugin/pom.xml

modules中新增hana模块

<module>dolphinscheduler-datasource-hana</module>

前端UI代码变更

修改项1:types.ts

路径:dolphinscheduler-ui/src/service/modules/data-source/types.ts 新增hana选择

  | 'PRESTO'
| 'REDSHIFT'
| 'ATHENA'
| 'HANA' interface IDataSource {
id?: number

修改项6:

修改项2:use-form.ts

路径:dolphinscheduler-ui/src/views/datasource/list/use-form.ts 新增hana默认端口

    value: 'ATHENA',
label: 'ATHENA',
defaultPort: 0
},
HANA: {
value: 'HANA',
label: 'HANA',
defaultPort: 30015
}
}

修改项3:use-datasource.ts

路径:dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datasource.ts

      id: 10,
code: 'ATHENA',
disabled: false
},
{
id: 11,
code: 'HANA',
disabled: false
}
]

编译打包

dolphinscheduler-dist/target/路径下生成tar.gz包

 mvn -U clean package -Prelease -Dmaven.test.skip=true

DolphinScheduler3.1.7集成SAP HANA的更多相关文章

  1. SAP HANA专题分析目录

    针对HANA的关键技术领域, 做深度解析. 1. HANA开发规范 HANA 各种对象的应用解析.版本管理,开发规范. 2. HANA系统管理 用户.系统权限.数据权限的深度解析. HANA系统配置. ...

  2. [转载]大道至简!!!从SAP HANA作为SAP加速器的方式,看ERP on HANA的春天

    I AM A ABAPER! 科技的进步,一定会使一些东西变得越来越精简! 大道至简!!! 文章很好!!!!!!!!!!! -------------------------------------- ...

  3. SAP HANA中的SLT简介

    在以SAP系统作为主要ERP的企业中,不同系统之间的数据库数据同步是个重要的工作.对于这种需求,除了开发ABAP接口之外,也有高效的工具可用.SLT就是其中之一. SLT是SAP的第一个ETL(Ext ...

  4. 【公众号系列】SAP HANA 平台的优势

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[公众号系列]SAP HANA 平台的优势   ...

  5. 【公众号系列】SAP HANA和区块链

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[公众号系列]SAP HANA和区块链   写在 ...

  6. 如何在云端部署SAP HANA实战, Azure 上的 SAP HANA(大型实例)概述和体系结构

    什么是 Azure 上的 SAP HANA(大型实例)? Azure 上的 SAP HANA(大型实例)是一种针对 Azure 的独特解决方案. 除了提供 Azure 虚拟机以用于部署和运行 SAP ...

  7. sap hana 数据库 EBS

    SAP实时数据平台详解 ************************************************************ EBS是Oracle 公司对原有应用产品整合后的一个产 ...

  8. SAP HANA 开发模式 - 基于SAP HANA平台的多团队产品研发

    “基本”开发模式 Windows: Unix/Linux: 在基本模式下我们可以通过regi来进行激活我们的object.Regi是一个类git功能的,方便和HANA repository交互的一个命 ...

  9. 基于SAP HANA平台的多团队产品研发

    工欲善其事必先利其器.要提高多团队的开发效率,而且还是在SAP HANA平台上,建议大家还是本着“慢就是快”的原则,不要急功近利,在没有准备好团队开发的架构时就匆忙开始功能的开发.匆忙功能开发就算了, ...

  10. 利用Veeam保护SAP HANA数据库

    利用Veeam保护SAP HANA数据库 前言 针对越来越多的SAP HANA备份需求,我们Team翻译.整理.借鉴了Veeam 的SAP HANA 大神 Clemens Zerbe 和 Ali Sa ...

随机推荐

  1. 在Jupyter Notebook,沉浸式体验ChatGPT

    大家好,我是章北海mlpy 写代码,修Bug是 ChatGPT 目前最擅长的领域之一 今天向大家推荐一个刚刚开源的Python包 安装后可以直接在IPython和Jupyter Notebook中直接 ...

  2. 5219. 【GDOI2018模拟7.10】B

    5219. [GDOI2018模拟7.10]B 题目大意: 考试想法: 正解: 代码: 题目大意: 现在有一个字符串 s s s 当 s [ i ] s[i] s[i]为 I I I时 a n s [ ...

  3. redission分布式redis锁使用

    public void lock(String key, List<Long> idx) { if (CollectionUtils.isEmpty(idx)) { return; } i ...

  4. Vue3实现组件级基类的几种方法

    Vue3的组件有三种代码组织方式 纯Option API (不含setup) option API + setup 纯 setup (即composition API) 对于这三种形式,设置基类的方法 ...

  5. 2022-06-12:在N*N的正方形棋盘中,有N*N个棋子,那么每个格子正好可以拥有一个棋子。 但是现在有些棋子聚集到一个格子上了,比如: 2 0 3 0 1 0 3 0 0 如上的二维数组代表,一

    2022-06-12:在NN的正方形棋盘中,有NN个棋子,那么每个格子正好可以拥有一个棋子. 但是现在有些棋子聚集到一个格子上了,比如: 2 0 3 0 1 0 3 0 0 如上的二维数组代表,一共3 ...

  6. 2021-07-21:一张扑克有3个属性,每种属性有3种值(A、B、C),比如“AAA“,第一个属性值A,第二个属性值A,第三个属性值A,比如“BCA“,第一个属性值B,第二个属性值C,第三个属性值A

    2021-07-21:一张扑克有3个属性,每种属性有3种值(A.B.C),比如"AAA",第一个属性值A,第二个属性值A,第三个属性值A,比如"BCA",第一个 ...

  7. Linux搭建FTP服务

    欢迎来到千汐   博客名称:千秋云染博客网址:https://www.cnblogs.com/skyrainmom 寄语:在混乱不堪的世界里你只管前行,时间替会证明一切 world cookie He ...

  8. 02-初识Verilog

    1.开发环境搭建 需要使用的软件: QuartusII ModelSim Visio Notepad++ 2.初识Verilog 2.1 Verilog HDL简介 Verilog HDL是一种硬件描 ...

  9. AcWing 1209. 带分数

    题目描述: 分析: 题意就是说给定一个整数N,求给定a,b,c,求a+b/c==N且a,b,c恰好包括0-9的答案的个数,需要注意的是,b/c可能得到的是小数,所以要尽量避免除法,将等式转换为乘法格式 ...

  10. web自动化01-环境搭建

    1.自动化测试是什么? 借助工具实现 借助代码编写脚本实现  2.自动化测试需要掌握那些? web自动化测试基础 移动端自动化基础 pytest自动化测试框架 po设计模式 数据驱动 日志模块使用 自 ...