From 7c02b295e253a048f2f1588b78cd8874bbb73321 Mon Sep 17 00:00:00 2001 From: Waleed Fateem Date: Sun, 23 Jun 2024 22:11:50 +0200 Subject: [PATCH 1/2] SNOW-1094021: Add Properties setter/getter in SnowflakeBasicaDataSource --- .../client/jdbc/SnowflakeBasicDataSource.java | 8 +++++ .../client/jdbc/ConnectionLatestIT.java | 35 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/main/java/net/snowflake/client/jdbc/SnowflakeBasicDataSource.java b/src/main/java/net/snowflake/client/jdbc/SnowflakeBasicDataSource.java index 074e3f878..934a898fd 100644 --- a/src/main/java/net/snowflake/client/jdbc/SnowflakeBasicDataSource.java +++ b/src/main/java/net/snowflake/client/jdbc/SnowflakeBasicDataSource.java @@ -231,4 +231,12 @@ public void setPrivateKeyFile(String location, String password) { public void setTracing(String tracing) { this.properties.put("tracing", tracing); } + + public Properties getProperties() { + return this.properties; + } + + public void setProperties(Properties props) { + this.properties.putAll(props); + } } diff --git a/src/test/java/net/snowflake/client/jdbc/ConnectionLatestIT.java b/src/test/java/net/snowflake/client/jdbc/ConnectionLatestIT.java index 0e7ab4648..f95618c3b 100644 --- a/src/test/java/net/snowflake/client/jdbc/ConnectionLatestIT.java +++ b/src/test/java/net/snowflake/client/jdbc/ConnectionLatestIT.java @@ -1367,4 +1367,39 @@ public void testDataSourceOktaGenerates429StatusCode() throws Exception { thread.join(); } } + + @Test + @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) + public void testDataSourceGetProperties() { + Map params = getConnectionParameters(); + SnowflakeBasicDataSource ds = new SnowflakeBasicDataSource(); + ds.setAccount(params.get("account")); + ds.setAuthenticator("snowflake"); + ds.setTracing("all"); + Properties props = ds.getProperties(); + assertEquals(params.get("account"), props.get("account")); + assertEquals("snowflake", props.get("authenticator")); + assertEquals("all", props.get("tracing")); + } + + @Test + @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) + public void testDataSourceSetProperties() { + Map params = getConnectionParameters(); + SnowflakeBasicDataSource ds = new SnowflakeBasicDataSource(); + ds.setAccount(params.get("account")); + ds.setAuthenticator("snowflake"); + ds.setTracing("all"); + Properties props = new Properties(); + props.put("role", "test_role"); + props.put("connection_property_key_1", "connection_property_value_1"); + props.put("connection_property_key_2", "connection_property_value_2"); + ds.setProperties(props); + Properties mergedProps = ds.getProperties(); + assertEquals(params.get("account"), mergedProps.get("account")); + assertEquals("snowflake", mergedProps.get("authenticator")); + assertEquals("all", mergedProps.get("tracing")); + assertEquals("connection_property_value_1", mergedProps.get("connection_property_key_1")); + assertEquals("connection_property_value_2", mergedProps.get("connection_property_key_2")); + } } From ad93f13402620fd9397f31ef8fa5c2d6c40d071d Mon Sep 17 00:00:00 2001 From: Waleed Fateem Date: Mon, 1 Jul 2024 10:51:27 -0500 Subject: [PATCH 2/2] SNOW-1094021: Add Properties setters in SnowflakeBasicaDataSource --- .../client/jdbc/SnowflakeBasicDataSource.java | 158 ++++++++++++++++-- .../client/jdbc/ConnectionLatestIT.java | 93 ++++++++--- 2 files changed, 210 insertions(+), 41 deletions(-) diff --git a/src/main/java/net/snowflake/client/jdbc/SnowflakeBasicDataSource.java b/src/main/java/net/snowflake/client/jdbc/SnowflakeBasicDataSource.java index 934a898fd..00358be5c 100644 --- a/src/main/java/net/snowflake/client/jdbc/SnowflakeBasicDataSource.java +++ b/src/main/java/net/snowflake/client/jdbc/SnowflakeBasicDataSource.java @@ -13,6 +13,7 @@ import java.util.Properties; import java.util.logging.Logger; import javax.sql.DataSource; +import net.snowflake.client.core.SFSessionProperty; import net.snowflake.client.log.ArgSupplier; import net.snowflake.client.log.SFLogger; import net.snowflake.client.log.SFLoggerFactory; @@ -22,6 +23,7 @@ public class SnowflakeBasicDataSource implements DataSource, Serializable { private static final long serialversionUID = 1L; private static final String AUTHENTICATOR_SNOWFLAKE_JWT = "SNOWFLAKE_JWT"; private static final String AUTHENTICATOR_OAUTH = "OAUTH"; + private static final String AUTHENTICATOR_USERNAME_PASSWORD_MFA = "USERNAME_PASSWORD_MFA"; private String url; private String serverName; @@ -88,12 +90,12 @@ public Connection getConnection() throws SQLException { public Connection getConnection(String username, String password) throws SQLException { if (!AUTHENTICATOR_OAUTH.equalsIgnoreCase( authenticator)) { // For OAuth, no username is required - properties.put("user", username); + properties.put(SFSessionProperty.USER.getPropertyKey(), username); } // The driver needs password for OAUTH as part of SNOW-533673 feature request. if (!AUTHENTICATOR_SNOWFLAKE_JWT.equalsIgnoreCase(authenticator)) { - properties.put("password", password); + properties.put(SFSessionProperty.PASSWORD.getPropertyKey(), password); } try { @@ -119,7 +121,8 @@ public void setLogWriter(PrintWriter out) throws SQLException { @Override public int getLoginTimeout() throws SQLException { try { - return Integer.parseInt(properties.getProperty("loginTimeout")); + return Integer.parseInt( + properties.getProperty(SFSessionProperty.LOGIN_TIMEOUT.getPropertyKey())); } catch (NumberFormatException e) { return 0; } @@ -127,7 +130,7 @@ public int getLoginTimeout() throws SQLException { @Override public void setLoginTimeout(int seconds) throws SQLException { - properties.put("loginTimeout", Integer.toString(seconds)); + properties.put(SFSessionProperty.LOGIN_TIMEOUT.getPropertyKey(), Integer.toString(seconds)); } @Override @@ -150,19 +153,19 @@ public void setUrl(String url) { } public void setDatabaseName(String databaseName) { - properties.put("db", databaseName); + properties.put(SFSessionProperty.DATABASE.getPropertyKey(), databaseName); } public void setSchema(String schema) { - properties.put("schema", schema); + properties.put(SFSessionProperty.SCHEMA.getPropertyKey(), schema); } public void setWarehouse(String warehouse) { - properties.put("warehouse", warehouse); + properties.put(SFSessionProperty.WAREHOUSE.getPropertyKey(), warehouse); } public void setRole(String role) { - properties.put("role", role); + properties.put(SFSessionProperty.ROLE.getPropertyKey(), role); } public void setUser(String user) { @@ -182,7 +185,7 @@ public void setPortNumber(int portNumber) { } public void setAccount(String account) { - this.properties.put("account", account); + this.properties.put(SFSessionProperty.ACCOUNT.getPropertyKey(), account); } public void setSsl(boolean ssl) { @@ -191,12 +194,12 @@ public void setSsl(boolean ssl) { public void setAuthenticator(String authenticator) { this.authenticator = authenticator; - this.properties.put("authenticator", authenticator); + this.properties.put(SFSessionProperty.AUTHENTICATOR.getPropertyKey(), authenticator); } public void setOauthToken(String oauthToken) { this.setAuthenticator(AUTHENTICATOR_OAUTH); - this.properties.put("token", oauthToken); + this.properties.put(SFSessionProperty.TOKEN.getPropertyKey(), oauthToken); } public String getUrl() { @@ -217,26 +220,145 @@ public String getUrl() { public void setPrivateKey(PrivateKey privateKey) { this.setAuthenticator(AUTHENTICATOR_SNOWFLAKE_JWT); - this.properties.put("privateKey", privateKey); + this.properties.put(SFSessionProperty.PRIVATE_KEY.getPropertyKey(), privateKey); } public void setPrivateKeyFile(String location, String password) { this.setAuthenticator(AUTHENTICATOR_SNOWFLAKE_JWT); - this.properties.put("private_key_file", location); + this.properties.put(SFSessionProperty.PRIVATE_KEY_FILE.getPropertyKey(), location); if (!Strings.isNullOrEmpty(password)) { - this.properties.put("private_key_file_pwd", password); + this.properties.put(SFSessionProperty.PRIVATE_KEY_FILE_PWD.getPropertyKey(), password); } } public void setTracing(String tracing) { - this.properties.put("tracing", tracing); + this.properties.put(SFSessionProperty.TRACING.getPropertyKey(), tracing); } - public Properties getProperties() { + protected Properties getProperties() { return this.properties; } - public void setProperties(Properties props) { - this.properties.putAll(props); + public void setAllowUnderscoresInHost(boolean allowUnderscoresInHost) { + this.properties.put( + SFSessionProperty.ALLOW_UNDERSCORES_IN_HOST.getPropertyKey(), + String.valueOf(allowUnderscoresInHost)); + } + + public void setDisableGcsDefaultCredentials(boolean isGcsDefaultCredentialsDisabled) { + this.properties.put( + SFSessionProperty.DISABLE_GCS_DEFAULT_CREDENTIALS.getPropertyKey(), + String.valueOf(isGcsDefaultCredentialsDisabled)); + } + + public void setDisableSamlURLCheck(boolean disableSamlURLCheck) { + this.properties.put( + SFSessionProperty.DISABLE_SAML_URL_CHECK.getPropertyKey(), + String.valueOf(disableSamlURLCheck)); + } + + public void setPasscode(String passcode) { + this.setAuthenticator(AUTHENTICATOR_USERNAME_PASSWORD_MFA); + this.properties.put(SFSessionProperty.PASSCODE.getPropertyKey(), passcode); + } + + public void setPasscodeInPassword(boolean isPasscodeInPassword) { + this.properties.put( + SFSessionProperty.PASSCODE_IN_PASSWORD.getPropertyKey(), + String.valueOf(isPasscodeInPassword)); + if (isPasscodeInPassword) { + this.setAuthenticator(AUTHENTICATOR_USERNAME_PASSWORD_MFA); + } + } + + public void setDisableSocksProxy(boolean ignoreJvmSocksProxy) { + this.properties.put( + SFSessionProperty.DISABLE_SOCKS_PROXY.getPropertyKey(), + String.valueOf(ignoreJvmSocksProxy)); + } + + public void setNonProxyHosts(String nonProxyHosts) { + this.properties.put(SFSessionProperty.NON_PROXY_HOSTS.getPropertyKey(), nonProxyHosts); + } + + public void setProxyHost(String proxyHost) { + this.properties.put(SFSessionProperty.PROXY_HOST.getPropertyKey(), proxyHost); + } + + public void setProxyPassword(String proxyPassword) { + this.properties.put(SFSessionProperty.PROXY_PASSWORD.getPropertyKey(), proxyPassword); + } + + public void setProxyPort(int proxyPort) { + this.properties.put(SFSessionProperty.PROXY_PORT.getPropertyKey(), Integer.toString(proxyPort)); + } + + public void setProxyProtocol(String proxyProtocol) { + this.properties.put(SFSessionProperty.PROXY_PROTOCOL.getPropertyKey(), proxyProtocol); + } + + public void setProxyUser(String proxyUser) { + this.properties.put(SFSessionProperty.PROXY_USER.getPropertyKey(), proxyUser); + } + + public void setUseProxy(boolean useProxy) { + this.properties.put(SFSessionProperty.USE_PROXY.getPropertyKey(), String.valueOf(useProxy)); + } + + public void setNetworkTimeout(int networkTimeoutSeconds) { + this.properties.put( + SFSessionProperty.NETWORK_TIMEOUT.getPropertyKey(), + Integer.toString(networkTimeoutSeconds)); + } + + public void setQueryTimeout(int queryTimeoutSeconds) { + this.properties.put( + SFSessionProperty.QUERY_TIMEOUT.getPropertyKey(), Integer.toString(queryTimeoutSeconds)); + } + + public void setApplication(String application) { + this.properties.put(SFSessionProperty.APPLICATION.getPropertyKey(), application); + } + + public void setClientConfigFile(String clientConfigFile) { + this.properties.put(SFSessionProperty.CLIENT_CONFIG_FILE.getPropertyKey(), clientConfigFile); + } + + public void setEnablePatternSearch(boolean enablePatternSearch) { + this.properties.put( + SFSessionProperty.ENABLE_PATTERN_SEARCH.getPropertyKey(), + String.valueOf(enablePatternSearch)); + } + + public void setEnablePutGet(boolean enablePutGet) { + this.properties.put( + SFSessionProperty.ENABLE_PUT_GET.getPropertyKey(), String.valueOf(enablePutGet)); + } + + public void setArrowTreatDecimalAsInt(boolean treatDecimalAsInt) { + this.properties.put( + SFSessionProperty.JDBC_ARROW_TREAT_DECIMAL_AS_INT.getPropertyKey(), + String.valueOf(treatDecimalAsInt)); + } + + public void setMaxHttpRetries(int maxHttpRetries) { + this.properties.put( + SFSessionProperty.MAX_HTTP_RETRIES.getPropertyKey(), Integer.toString(maxHttpRetries)); + } + + public void setOcspFailOpen(boolean ocspFailOpen) { + this.properties.put( + SFSessionProperty.OCSP_FAIL_OPEN.getPropertyKey(), String.valueOf(ocspFailOpen)); + } + + public void setPutGetMaxRetries(int putGetMaxRetries) { + this.properties.put( + SFSessionProperty.PUT_GET_MAX_RETRIES.getPropertyKey(), Integer.toString(putGetMaxRetries)); + } + + public void setStringsQuotedForColumnDef(boolean stringsQuotedForColumnDef) { + this.properties.put( + SFSessionProperty.STRINGS_QUOTED.getPropertyKey(), + String.valueOf(stringsQuotedForColumnDef)); } } diff --git a/src/test/java/net/snowflake/client/jdbc/ConnectionLatestIT.java b/src/test/java/net/snowflake/client/jdbc/ConnectionLatestIT.java index f95618c3b..fe791b86a 100644 --- a/src/test/java/net/snowflake/client/jdbc/ConnectionLatestIT.java +++ b/src/test/java/net/snowflake/client/jdbc/ConnectionLatestIT.java @@ -55,6 +55,7 @@ import net.snowflake.client.core.ObjectMapperFactory; import net.snowflake.client.core.QueryStatus; import net.snowflake.client.core.SFSession; +import net.snowflake.client.core.SFSessionProperty; import net.snowflake.client.core.SecurityUtil; import net.snowflake.client.core.SessionUtil; import net.snowflake.client.jdbc.telemetryOOB.TelemetryService; @@ -1368,38 +1369,84 @@ public void testDataSourceOktaGenerates429StatusCode() throws Exception { } } + /** Test added in JDBC driver version > 3.16.1 */ @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) - public void testDataSourceGetProperties() { + public void testDataSourceSetters() { Map params = getConnectionParameters(); SnowflakeBasicDataSource ds = new SnowflakeBasicDataSource(); + + ds.setTracing("all"); + ds.setApplication("application_name"); ds.setAccount(params.get("account")); ds.setAuthenticator("snowflake"); - ds.setTracing("all"); + ds.setArrowTreatDecimalAsInt(true); + ds.setAllowUnderscoresInHost(true); + ds.setClientConfigFile("/some/path/file.json"); + ds.setDisableGcsDefaultCredentials(false); + ds.setDisableSamlURLCheck(false); + ds.setDisableSocksProxy(false); + ds.setEnablePatternSearch(true); + ds.setDatabaseName("DB_NAME"); + ds.setEnablePutGet(false); + ds.setMaxHttpRetries(5); + ds.setNetworkTimeout(10); + ds.setOcspFailOpen(false); + ds.setProxyHost("proxyHost.com"); + ds.setProxyPort(8080); + ds.setProxyProtocol("http"); + ds.setProxyUser("proxyUser"); + ds.setProxyPassword("proxyPassword"); + ds.setPutGetMaxRetries(3); + ds.setStringsQuotedForColumnDef(true); + Properties props = ds.getProperties(); assertEquals(params.get("account"), props.get("account")); assertEquals("snowflake", props.get("authenticator")); assertEquals("all", props.get("tracing")); - } + assertEquals("application_name", props.get(SFSessionProperty.APPLICATION.getPropertyKey())); + assertEquals("snowflake", props.get(SFSessionProperty.AUTHENTICATOR.getPropertyKey())); + assertEquals( + "true", props.get(SFSessionProperty.JDBC_ARROW_TREAT_DECIMAL_AS_INT.getPropertyKey())); + assertEquals("true", props.get(SFSessionProperty.ALLOW_UNDERSCORES_IN_HOST.getPropertyKey())); + assertEquals( + "/some/path/file.json", props.get(SFSessionProperty.CLIENT_CONFIG_FILE.getPropertyKey())); + assertEquals( + "false", props.get(SFSessionProperty.DISABLE_GCS_DEFAULT_CREDENTIALS.getPropertyKey())); + assertEquals("false", props.get(SFSessionProperty.DISABLE_SAML_URL_CHECK.getPropertyKey())); + assertEquals("false", props.get(SFSessionProperty.DISABLE_SOCKS_PROXY.getPropertyKey())); + assertEquals("true", props.get(SFSessionProperty.ENABLE_PATTERN_SEARCH.getPropertyKey())); + assertEquals("DB_NAME", props.get(SFSessionProperty.DATABASE.getPropertyKey())); + assertEquals("false", props.get(SFSessionProperty.ENABLE_PUT_GET.getPropertyKey())); + assertEquals("5", props.get(SFSessionProperty.MAX_HTTP_RETRIES.getPropertyKey())); + assertEquals("10", props.get(SFSessionProperty.NETWORK_TIMEOUT.getPropertyKey())); + assertEquals("false", props.get(SFSessionProperty.OCSP_FAIL_OPEN.getPropertyKey())); + assertEquals("proxyHost.com", props.get(SFSessionProperty.PROXY_HOST.getPropertyKey())); + assertEquals("8080", props.get(SFSessionProperty.PROXY_PORT.getPropertyKey())); + assertEquals("http", props.get(SFSessionProperty.PROXY_PROTOCOL.getPropertyKey())); + assertEquals("proxyUser", props.get(SFSessionProperty.PROXY_USER.getPropertyKey())); + assertEquals("proxyPassword", props.get(SFSessionProperty.PROXY_PASSWORD.getPropertyKey())); + assertEquals("3", props.get(SFSessionProperty.PUT_GET_MAX_RETRIES.getPropertyKey())); + assertEquals("true", props.get(SFSessionProperty.STRINGS_QUOTED.getPropertyKey())); + + ds.setOauthToken("a_token"); + assertEquals("OAUTH", props.get(SFSessionProperty.AUTHENTICATOR.getPropertyKey())); + assertEquals("a_token", props.get(SFSessionProperty.TOKEN.getPropertyKey())); + + ds.setPasscodeInPassword(true); + assertEquals("true", props.get(SFSessionProperty.PASSCODE_IN_PASSWORD.getPropertyKey())); + assertEquals( + "USERNAME_PASSWORD_MFA", props.get(SFSessionProperty.AUTHENTICATOR.getPropertyKey())); - @Test - @ConditionalIgnoreRule.ConditionalIgnore(condition = RunningOnGithubAction.class) - public void testDataSourceSetProperties() { - Map params = getConnectionParameters(); - SnowflakeBasicDataSource ds = new SnowflakeBasicDataSource(); - ds.setAccount(params.get("account")); - ds.setAuthenticator("snowflake"); - ds.setTracing("all"); - Properties props = new Properties(); - props.put("role", "test_role"); - props.put("connection_property_key_1", "connection_property_value_1"); - props.put("connection_property_key_2", "connection_property_value_2"); - ds.setProperties(props); - Properties mergedProps = ds.getProperties(); - assertEquals(params.get("account"), mergedProps.get("account")); - assertEquals("snowflake", mergedProps.get("authenticator")); - assertEquals("all", mergedProps.get("tracing")); - assertEquals("connection_property_value_1", mergedProps.get("connection_property_key_1")); - assertEquals("connection_property_value_2", mergedProps.get("connection_property_key_2")); + ds.setPrivateKeyFile("key.p8", "pwd"); + assertEquals("key.p8", props.get(SFSessionProperty.PRIVATE_KEY_FILE.getPropertyKey())); + assertEquals("pwd", props.get(SFSessionProperty.PRIVATE_KEY_FILE_PWD.getPropertyKey())); + assertEquals("SNOWFLAKE_JWT", props.get(SFSessionProperty.AUTHENTICATOR.getPropertyKey())); + + ds.setPasscodeInPassword(false); + ds.setPasscode("a_passcode"); + assertEquals("false", props.get(SFSessionProperty.PASSCODE_IN_PASSWORD.getPropertyKey())); + assertEquals( + "USERNAME_PASSWORD_MFA", props.get(SFSessionProperty.AUTHENTICATOR.getPropertyKey())); + assertEquals("a_passcode", props.get(SFSessionProperty.PASSCODE.getPropertyKey())); } }