diff --git a/README.md b/README.md
index e45a6da7469..141ef3a0d1c 100644
--- a/README.md
+++ b/README.md
@@ -323,4 +323,3 @@ Unicons by IconScout: [https://github.com/Iconscout/unicons](https://github.com/
- Mailing List: [https://dev.eclipse.org/mailman/listinfo/dirigible-dev](https://dev.eclipse.org/mailman/listinfo/dirigible-dev)
- Issues: [https://github.com/eclipse/dirigible/issues](https://github.com/eclipse/dirigible/issues)
- Eclipse Foundation Help Desk: https://gitlab.eclipse.org/eclipsefdn/helpdesk
-
diff --git a/components/data/data-source-snowpark/src/main/java/org/eclipse/dirigible/components/data/source/snowpark/SnowflakeDatabaseConfigurator.java b/components/data/data-source-snowpark/src/main/java/org/eclipse/dirigible/components/data/source/snowpark/SnowflakeDatabaseConfigurator.java
index b830dab3df1..6726d2dcad8 100644
--- a/components/data/data-source-snowpark/src/main/java/org/eclipse/dirigible/components/data/source/snowpark/SnowflakeDatabaseConfigurator.java
+++ b/components/data/data-source-snowpark/src/main/java/org/eclipse/dirigible/components/data/source/snowpark/SnowflakeDatabaseConfigurator.java
@@ -21,6 +21,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
+import java.util.Objects;
import java.util.concurrent.TimeUnit;
@Component
@@ -37,6 +38,21 @@ public boolean isApplicable(DatabaseSystem databaseSystem) {
@Override
public void apply(HikariConfig config) {
+ setCommonConfigurations(config);
+
+ boolean registeredUsernameAndPass = StringUtils.isNotBlank(config.getUsername()) && StringUtils.isNotBlank(config.getPassword());
+
+ if (registeredUsernameAndPass && userAndPassAreNotDummyValues(config)) {
+ logger.info("There ARE registered username and pass for config [{}] and they will be used.", config);
+ config.addDataSourceProperty("user", config.getUsername());
+ config.addDataSourceProperty("password", config.getPassword());
+
+ } else {
+ configureOAuth(config);
+ }
+ }
+
+ private void setCommonConfigurations(HikariConfig config) {
config.setConnectionTestQuery("SELECT 1"); // connection validation query
config.setKeepaliveTime(TimeUnit.MINUTES.toMillis(5)); // validation execution interval, must be bigger than idle timeout
config.setMaxLifetime(TimeUnit.MINUTES.toMillis(9)); // recreate connections after specified time
@@ -44,36 +60,37 @@ public void apply(HikariConfig config) {
config.addDataSourceProperty("CLIENT_SESSION_KEEP_ALIVE", true);
config.addDataSourceProperty("CLIENT_SESSION_KEEP_ALIVE_HEARTBEAT_FREQUENCY", 900);
+ }
+
+ private void configureOAuth(HikariConfig config) {
+ if (!hasTokenFile()) {
+ throw new IllegalStateException("There in no username and/or password (or both are dummy values) for provided config [" + config
+ + "]. Assuming it should use oauth token but there is no token file at " + TOKEN_FILE_PATH);
+ }
+
+ logger.info("Missing username and/or password for config [{}]. OAuth token will be used.", config);
+
+ config.setUsername(null);
+ config.setPassword(null);
+ config.addDataSourceProperty("authenticator", "OAUTH");
+ config.addDataSourceProperty("token", loadTokenFile());
addDataSourcePropertyIfConfigAvailable("SNOWFLAKE_WAREHOUSE", "warehouse", config);
+
+ // automatically populated by Snowflake unless explicitly set
+ // https://docs.snowflake.com/en/developer-guide/snowpark-container-services/additional-considerations-services-jobs
addDataSourcePropertyIfConfigAvailable("SNOWFLAKE_ACCOUNT", "account", config);
addDataSourcePropertyIfConfigAvailable("SNOWFLAKE_DATABASE", "db", config);
addDataSourcePropertyIfConfigAvailable("SNOWFLAKE_SCHEMA", "schema", config);
- String url;
- if (hasTokenFile()) {
- logger.info("There IS token file. OAuth will be added to [{}]", config);
-
- config.setUsername(null);
- config.setPassword(null);
- config.addDataSourceProperty("authenticator", "OAUTH");
- config.addDataSourceProperty("token", loadTokenFile());
- url = "jdbc:snowflake://" + Configuration.get("SNOWFLAKE_HOST") + ":" + Configuration.get("SNOWFLAKE_PORT");
- } else {
- logger.info("There is NO token file. User/password will be added to [{}]", config);
-
- addDataSourcePropertyIfConfigAvailable("SNOWFLAKE_ROLE", "role", config);
- addDataSourcePropertyIfConfigAvailable("SNOWFLAKE_USERNAME", "user", config);
- addDataSourcePropertyIfConfigAvailable("SNOWFLAKE_PASSWORD", "password", config);
+ String url = "jdbc:snowflake://" + Configuration.get("SNOWFLAKE_HOST") + ":" + Configuration.get("SNOWFLAKE_PORT");
- url = Configuration.get("SNOWFLAKE_URL", config.getJdbcUrl());
- }
- logger.info("Built url [{}]", url);
+ logger.info("Will be used url [{}] for config [{}]", url, config);
config.addDataSourceProperty("url", url);
config.setJdbcUrl(url);
}
- private static String loadTokenFile() {
+ private String loadTokenFile() {
try {
return new String(Files.readAllBytes(Paths.get(TOKEN_FILE_PATH)));
} catch (IOException ex) {
@@ -81,7 +98,7 @@ private static String loadTokenFile() {
}
}
- private static boolean hasTokenFile() {
+ private boolean hasTokenFile() {
return Files.exists(Paths.get(TOKEN_FILE_PATH));
}
@@ -95,4 +112,18 @@ private void addDataSourcePropertyIfConfigAvailable(String configName, String pr
}
}
+ private boolean userAndPassAreNotDummyValues(HikariConfig config) {
+ return isNotDummyValue(config.getUsername()) && isNotDummyValue(config.getPassword());
+ }
+
+ /**
+ * Note: needed for backward compatibility with Snowflake native applications until they are updated
+ *
+ * @param value
+ * @return
+ */
+ private boolean isNotDummyValue(String value) {
+ return !Objects.equals(value, "not-used-in-snowpark-scenario");
+ }
+
}
diff --git a/components/data/data-sources/src/main/java/org/eclipse/dirigible/components/data/sources/domain/DataSource.java b/components/data/data-sources/src/main/java/org/eclipse/dirigible/components/data/sources/domain/DataSource.java
index 2c7799ddf63..398277120e2 100644
--- a/components/data/data-sources/src/main/java/org/eclipse/dirigible/components/data/sources/domain/DataSource.java
+++ b/components/data/data-sources/src/main/java/org/eclipse/dirigible/components/data/sources/domain/DataSource.java
@@ -9,22 +9,15 @@
*/
package org.eclipse.dirigible.components.data.sources.domain;
-import java.util.ArrayList;
-import java.util.List;
+import com.google.gson.annotations.Expose;
+import jakarta.persistence.*;
import org.eclipse.dirigible.components.base.artefact.Artefact;
import org.eclipse.dirigible.components.base.encryption.Encrypted;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
-import com.google.gson.annotations.Expose;
-import jakarta.persistence.CascadeType;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.OneToMany;
-import jakarta.persistence.Table;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* The Class DataSource.
@@ -53,12 +46,12 @@ public class DataSource extends Artefact {
private String url;
/** The username. */
- @Column(name = "DS_USERNAME", columnDefinition = "VARCHAR", nullable = false, length = 255)
+ @Column(name = "DS_USERNAME", columnDefinition = "VARCHAR", nullable = true, length = 255)
@Expose
private String username;
/** The password. */
- @Column(name = "DS_PASSWORD", columnDefinition = "VARCHAR", nullable = false, length = 255)
+ @Column(name = "DS_PASSWORD", columnDefinition = "VARCHAR", nullable = true, length = 255)
@Expose
@Encrypted
private String password;
diff --git a/components/data/data-sources/src/main/java/org/eclipse/dirigible/components/data/sources/service/CustomDataSourcesService.java b/components/data/data-sources/src/main/java/org/eclipse/dirigible/components/data/sources/service/CustomDataSourcesService.java
index a47afae95d7..b08571c1a50 100644
--- a/components/data/data-sources/src/main/java/org/eclipse/dirigible/components/data/sources/service/CustomDataSourcesService.java
+++ b/components/data/data-sources/src/main/java/org/eclipse/dirigible/components/data/sources/service/CustomDataSourcesService.java
@@ -38,57 +38,68 @@ public class CustomDataSourcesService {
public void initialize() {
String customDataSourcesList = Configuration.get("DIRIGIBLE_DATABASE_CUSTOM_DATASOURCES");
if ((customDataSourcesList != null) && !"".equals(customDataSourcesList)) {
- if (logger.isTraceEnabled()) {
- logger.trace("Custom datasources list: " + customDataSourcesList);
- }
+ logger.trace("Custom datasources list: [{}]", customDataSourcesList);
StringTokenizer tokens = new StringTokenizer(customDataSourcesList, ",");
while (tokens.hasMoreTokens()) {
String name = tokens.nextToken();
- if (logger.isInfoEnabled()) {
- logger.info("Initializing a custom datasource with name: " + name);
- }
+ logger.info("Initializing a custom datasource with name [{}]", name);
saveDataSource(name);
}
} else {
- if (logger.isTraceEnabled()) {
- logger.trace("No custom datasources configured");
- }
- }
- if (logger.isDebugEnabled()) {
- logger.debug(this.getClass()
- .getCanonicalName()
- + " module initialized.");
+ logger.trace("No custom datasources configured");
}
+ logger.debug("[{}] module initialized.", this.getClass()
+ .getCanonicalName());
}
/**
* Save data source model.
*
* @param name the name
- * @return the data source
*/
private void saveDataSource(String name) {
- String databaseDriver = Configuration.get(name + "_DRIVER");
- String databaseUrl = Configuration.get(name + "_URL");
- String databaseUsername = Configuration.get(name + "_USERNAME");
- String databasePassword = Configuration.get(name + "_PASSWORD");
- String databaseSchema = Configuration.get(name + "_SCHEMA");
+ String databaseDriver = getRequiredParameter(name, "DRIVER");
+ String databaseUrl = getRequiredParameter(name, "URL");
+ String databaseUsername = getOptionalParameter(name, "USERNAME");
+ String databasePassword = getOptionalParameter(name, "PASSWORD");
+ String databaseSchema = getOptionalParameter(name, "SCHEMA");
- if ((databaseDriver != null) && (databaseUrl != null) && (databaseUsername != null) && (databasePassword != null)) {
- org.eclipse.dirigible.components.data.sources.domain.DataSource ds =
- new org.eclipse.dirigible.components.data.sources.domain.DataSource("ENV_" + name, name, null, databaseDriver,
- databaseUrl, databaseUsername, databasePassword);
- ds.setSchema(databaseSchema);
- ds.updateKey();
- ds.setLifecycle(ArtefactLifecycle.NEW);
- DataSource maybe = dataSourceService.findByKey(ds.getKey());
- if (maybe != null) {
- dataSourceService.delete(maybe);
- }
- dataSourceService.save(ds);
- } else {
- throw new IllegalArgumentException("Invalid configuration for the custom datasource: " + name);
+ org.eclipse.dirigible.components.data.sources.domain.DataSource ds =
+ new org.eclipse.dirigible.components.data.sources.domain.DataSource("ENV_" + name, name, null, databaseDriver, databaseUrl,
+ databaseUsername, databasePassword);
+ ds.setSchema(databaseSchema);
+ ds.updateKey();
+ ds.setLifecycle(ArtefactLifecycle.NEW);
+ DataSource maybe = dataSourceService.findByKey(ds.getKey());
+ if (maybe != null) {
+ dataSourceService.delete(maybe);
+ }
+ dataSourceService.save(ds);
+ }
+
+ private String getRequiredParameter(String dataSourceName, String suffix) {
+ String configName = createConfigName(dataSourceName, suffix);
+ String value = Configuration.get(configName);
+ if (null == value || value.trim()
+ .isEmpty()) {
+ throw new IllegalArgumentException("Missing required configuration parameter [" + configName + "] for data source ["
+ + dataSourceName + "]. The value is: " + value);
+ }
+ return value;
+ }
+
+ private String createConfigName(String dataSourceName, String suffix) {
+ return dataSourceName + "_" + suffix;
+ }
+
+ private String getOptionalParameter(String dataSourceName, String suffix) {
+ String configName = createConfigName(dataSourceName, suffix);
+ String value = Configuration.get(configName);
+ if (null == value || value.trim()
+ .isEmpty()) {
+ logger.info("Optional parameter [{}] for data source [{}] is missing. The value is: [{}]", configName, dataSourceName, value);
}
+ return value;
}
}
diff --git a/components/ide/ide-ui-databases/src/main/resources/META-INF/dirigible/ide-databases/dialogs/database-dialog.html b/components/ide/ide-ui-databases/src/main/resources/META-INF/dirigible/ide-databases/dialogs/database-dialog.html
index 5c6e740dfc8..5d480aea01d 100644
--- a/components/ide/ide-ui-databases/src/main/resources/META-INF/dirigible/ide-databases/dialogs/database-dialog.html
+++ b/components/ide/ide-ui-databases/src/main/resources/META-INF/dirigible/ide-databases/dialogs/database-dialog.html
@@ -59,10 +59,9 @@
- Username
+ Username
+ ng-model="database.username">
@@ -77,7 +76,7 @@
Parameters
diff --git a/components/ide/ide-ui-databases/src/main/resources/META-INF/dirigible/ide-databases/dialogs/database-dialog.js b/components/ide/ide-ui-databases/src/main/resources/META-INF/dirigible/ide-databases/dialogs/database-dialog.js
index 217dc1f984f..793fdbe6ef4 100644
--- a/components/ide/ide-ui-databases/src/main/resources/META-INF/dirigible/ide-databases/dialogs/database-dialog.js
+++ b/components/ide/ide-ui-databases/src/main/resources/META-INF/dirigible/ide-databases/dialogs/database-dialog.js
@@ -29,13 +29,23 @@ dbdialog.controller('DBDialogController', ['$scope', 'messageHub', 'ViewParamete
$scope.editMode = false;
$scope.urls = {
- "org.h2.Driver": "jdbc:h2:path/name",
- "org.postgresql.Driver": "jdbc:postgresql://host:port/database",
- "com.mysql.cj.jdbc.Driver": "jdbc:mysql://host:port/database",
- "org.mariadb.jdbc.Driver": "jdbc:mariadb://host:port/database",
- "com.sap.db.jdbc.Driver": "jdbc:sap://host:port/?encrypt=true&validateCertificate=false",
- "net.snowflake.client.jdbc.SnowflakeDriver": "jdbc:snowflake://account_identifier.snowflakecomputing.com/?db=SNOWFLAKE_SAMPLE_DATA&schema=TPCH_SF1000",
- "org.eclipse.dirigible.mongodb.jdbc.Driver": "jdbc:mongodb://host:port/database",
+ "org.h2.Driver": "jdbc:h2:/",
+ "org.postgresql.Driver": "jdbc:postgresql://:/",
+ "com.mysql.cj.jdbc.Driver": "jdbc:mysql://:/",
+ "org.mariadb.jdbc.Driver": "jdbc:mariadb://:/",
+ "com.sap.db.jdbc.Driver": "jdbc:sap://:/?encrypt=true&validateCertificate=false",
+ "net.snowflake.client.jdbc.SnowflakeDriver": "jdbc:snowflake://.snowflakecomputing.com",
+ "org.eclipse.dirigible.mongodb.jdbc.Driver": "jdbc:mongodb://:/",
+ };
+
+ $scope.parameters = {
+ 'org.h2.Driver': '',
+ 'org.postgresql.Driver': '',
+ 'com.mysql.cj.jdbc.Driver': '',
+ 'org.mariadb.jdbc.Driver': '',
+ 'com.sap.db.jdbc.Driver': '',
+ 'net.snowflake.client.jdbc.SnowflakeDriver': 'db=,schema=',
+ 'org.eclipse.dirigible.mongodb.jdbc.Driver': '',
};
$scope.drivers = [
@@ -61,6 +71,7 @@ dbdialog.controller('DBDialogController', ['$scope', 'messageHub', 'ViewParamete
$scope.database.url = $scope.urls[$scope.database.driver];
$scope.database.username = "";
$scope.database.password = "";
+ $scope.database.parameters = $scope.parameters[$scope.database.driver];
};
function getTopic() {
diff --git a/components/platform-ide/view-databases/src/main/resources/META-INF/dirigible/view-databases/dialogs/database-dialog.html b/components/platform-ide/view-databases/src/main/resources/META-INF/dirigible/view-databases/dialogs/database-dialog.html
index f8d3e52cfd4..0bd2415065b 100644
--- a/components/platform-ide/view-databases/src/main/resources/META-INF/dirigible/view-databases/dialogs/database-dialog.html
+++ b/components/platform-ide/view-databases/src/main/resources/META-INF/dirigible/view-databases/dialogs/database-dialog.html
@@ -51,9 +51,8 @@
- Username
-
+ Username
+
@@ -65,7 +64,7 @@
Parameters
-
diff --git a/components/platform-ide/view-databases/src/main/resources/META-INF/dirigible/view-databases/dialogs/database-dialog.js b/components/platform-ide/view-databases/src/main/resources/META-INF/dirigible/view-databases/dialogs/database-dialog.js
index cfadbc36e62..fcb4fbaa677 100644
--- a/components/platform-ide/view-databases/src/main/resources/META-INF/dirigible/view-databases/dialogs/database-dialog.js
+++ b/components/platform-ide/view-databases/src/main/resources/META-INF/dirigible/view-databases/dialogs/database-dialog.js
@@ -27,13 +27,23 @@ dbdialog.controller('DBDialogController', ($scope, ViewParameters, Dialogs) => {
};
$scope.urls = {
- 'org.h2.Driver': 'jdbc:h2:path/name',
- 'org.postgresql.Driver': 'jdbc:postgresql://host:port/database',
- 'com.mysql.cj.jdbc.Driver': 'jdbc:mysql://host:port/database',
- 'org.mariadb.jdbc.Driver': 'jdbc:mariadb://host:port/database',
- 'com.sap.db.jdbc.Driver': 'jdbc:sap://host:port/?encrypt=true&validateCertificate=false',
- 'net.snowflake.client.jdbc.SnowflakeDriver': 'jdbc:snowflake://account_identifier.snowflakecomputing.com/?db=SNOWFLAKE_SAMPLE_DATA&schema=TPCH_SF1000',
- 'org.eclipse.dirigible.mongodb.jdbc.Driver': 'jdbc:mongodb://host:port/database',
+ "org.h2.Driver": "jdbc:h2:/",
+ "org.postgresql.Driver": "jdbc:postgresql://:/",
+ "com.mysql.cj.jdbc.Driver": "jdbc:mysql://:/",
+ "org.mariadb.jdbc.Driver": "jdbc:mariadb://:/",
+ "com.sap.db.jdbc.Driver": "jdbc:sap://:/?encrypt=true&validateCertificate=false",
+ "net.snowflake.client.jdbc.SnowflakeDriver": "jdbc:snowflake://.snowflakecomputing.com",
+ "org.eclipse.dirigible.mongodb.jdbc.Driver": "jdbc:mongodb://:/",
+ };
+
+ $scope.parameters = {
+ 'org.h2.Driver': '',
+ 'org.postgresql.Driver': '',
+ 'com.mysql.cj.jdbc.Driver': '',
+ 'org.mariadb.jdbc.Driver': '',
+ 'com.sap.db.jdbc.Driver': '',
+ 'net.snowflake.client.jdbc.SnowflakeDriver': 'db=,schema=',
+ 'org.eclipse.dirigible.mongodb.jdbc.Driver': '',
};
$scope.drivers = [
@@ -59,6 +69,7 @@ dbdialog.controller('DBDialogController', ($scope, ViewParameters, Dialogs) => {
$scope.database.url = $scope.urls[$scope.database.driver];
$scope.database.username = '';
$scope.database.password = '';
+ $scope.database.parameters = $scope.parameters[$scope.database.driver];
};
$scope.save = () => {