You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by pv...@apache.org on 2026/04/02 22:39:19 UTC

(nifi) branch main updated: NIFI-15789 Upgrade Snowflake JDBC from 3.28.0 to 4.0.2 (#11101)

This is an automated email from the ASF dual-hosted git repository.

pvillard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 56dda439fb3 NIFI-15789 Upgrade Snowflake JDBC from 3.28.0 to 4.0.2 (#11101)
56dda439fb3 is described below

commit 56dda439fb3da7de624887a44271bb0d9cae36ec
Author: David Handermann <ex...@apache.org>
AuthorDate: Thu Apr 2 17:39:12 2026 -0500

    NIFI-15789 Upgrade Snowflake JDBC from 3.28.0 to 4.0.2 (#11101)
---
 .../snowflake/PutSnowflakeInternalStage.java       |  8 ++-
 .../processors/snowflake/SnowflakeIngestIT.java    |  2 +-
 .../nifi-snowflake-services-api/pom.xml            |  6 ++-
 .../snowflake/SnowflakeConnectionWrapper.java      |  2 +-
 .../service/SnowflakeComputingConnectionPool.java  | 61 ++++++++++++++++------
 .../SnowflakeComputingConnectionPoolTest.java      |  5 +-
 .../nifi-snowflake-bundle/pom.xml                  | 12 ++++-
 7 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-processors/src/main/java/org/apache/nifi/processors/snowflake/PutSnowflakeInternalStage.java b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-processors/src/main/java/org/apache/nifi/processors/snowflake/PutSnowflakeInternalStage.java
index ddbf6fe2c59..4b75f45e65b 100644
--- a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-processors/src/main/java/org/apache/nifi/processors/snowflake/PutSnowflakeInternalStage.java
+++ b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-processors/src/main/java/org/apache/nifi/processors/snowflake/PutSnowflakeInternalStage.java
@@ -17,6 +17,8 @@
 
 package org.apache.nifi.processors.snowflake;
 
+import net.snowflake.client.api.connection.SnowflakeConnection;
+import net.snowflake.client.api.connection.UploadStreamConfig;
 import org.apache.nifi.annotation.behavior.InputRequirement;
 import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
 import org.apache.nifi.annotation.behavior.WritesAttribute;
@@ -153,8 +155,10 @@ public class PutSnowflakeInternalStage extends AbstractProcessor {
         final String stagedFileName = UUID.randomUUID().toString();
         try (final InputStream inputStream = session.read(flowFile);
                 final SnowflakeConnectionWrapper snowflakeConnection = connectionProviderService.getSnowflakeConnection()) {
-            snowflakeConnection.unwrap()
-                    .uploadStream(internalStageName, "", inputStream, stagedFileName, false);
+            final SnowflakeConnection unwrappedConnection = snowflakeConnection.unwrap();
+            // Disable compression to avoid mismatched filenames when polling for status
+            final UploadStreamConfig uploadStreamConfig = UploadStreamConfig.builder().setCompressData(false).build();
+            unwrappedConnection.uploadStream(internalStageName, stagedFileName, inputStream, uploadStreamConfig);
         } catch (SQLException e) {
             getLogger().error("Failed to upload FlowFile content to internal Snowflake stage [{}]. Staged file path [{}]", internalStageName, stagedFileName, e);
             session.transfer(session.penalize(flowFile), REL_FAILURE);
diff --git a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-processors/src/test/java/org/apache/nifi/processors/snowflake/SnowflakeIngestIT.java b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-processors/src/test/java/org/apache/nifi/processors/snowflake/SnowflakeIngestIT.java
index f8c5cdca647..c0408d7f6d5 100644
--- a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-processors/src/test/java/org/apache/nifi/processors/snowflake/SnowflakeIngestIT.java
+++ b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-processors/src/test/java/org/apache/nifi/processors/snowflake/SnowflakeIngestIT.java
@@ -90,7 +90,7 @@ class SnowflakeIngestIT {
         assumeTrue(validationResult.environment().isPresent(), validationResult.message());
         environment = validationResult.environment().get();
 
-        Class.forName("net.snowflake.client.jdbc.SnowflakeDriver");
+        Class.forName("net.snowflake.client.api.driver.SnowflakeDriver");
         initializeSnowflakeObjects();
     }
 
diff --git a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services-api/pom.xml b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services-api/pom.xml
index bfdebeab197..8bec6e24a07 100644
--- a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services-api/pom.xml
+++ b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services-api/pom.xml
@@ -30,7 +30,11 @@
             <groupId>net.snowflake</groupId>
             <artifactId>snowflake-jdbc-thin</artifactId>
         </dependency>
-
+        <!-- grpc-netty included instead of grpc-netty-shaded -->
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-utils</artifactId>
diff --git a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services-api/src/main/java/org/apache/nifi/processors/snowflake/SnowflakeConnectionWrapper.java b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services-api/src/main/java/org/apache/nifi/processors/snowflake/SnowflakeConnectionWrapper.java
index a754593215c..d8623522dcc 100644
--- a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services-api/src/main/java/org/apache/nifi/processors/snowflake/SnowflakeConnectionWrapper.java
+++ b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services-api/src/main/java/org/apache/nifi/processors/snowflake/SnowflakeConnectionWrapper.java
@@ -17,7 +17,7 @@
 
 package org.apache.nifi.processors.snowflake;
 
-import net.snowflake.client.jdbc.SnowflakeConnection;
+import net.snowflake.client.api.connection.SnowflakeConnection;
 
 import java.sql.Connection;
 import java.sql.SQLException;
diff --git a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/main/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPool.java b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/main/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPool.java
index e2ee69104b1..2b4595f38f2 100644
--- a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/main/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPool.java
+++ b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/main/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPool.java
@@ -16,8 +16,7 @@
  */
 package org.apache.nifi.snowflake.service;
 
-import net.snowflake.client.core.SFSessionProperty;
-import net.snowflake.client.jdbc.SnowflakeDriver;
+import net.snowflake.client.api.driver.SnowflakeDriver;
 import org.apache.nifi.annotation.behavior.DynamicProperties;
 import org.apache.nifi.annotation.behavior.DynamicProperty;
 import org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading;
@@ -61,9 +60,6 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
-import static net.snowflake.client.core.SFSessionProperty.AUTHENTICATOR;
-import static net.snowflake.client.core.SFSessionProperty.PRIVATE_KEY_BASE64;
-import static net.snowflake.client.core.SFSessionProperty.TOKEN;
 import static org.apache.nifi.dbcp.utils.DBCPProperties.DB_PASSWORD;
 import static org.apache.nifi.dbcp.utils.DBCPProperties.DB_USER;
 import static org.apache.nifi.dbcp.utils.DBCPProperties.EVICTION_RUN_PERIOD;
@@ -257,7 +253,7 @@ public class SnowflakeComputingConnectionPool extends AbstractDBCPConnectionPool
 
     private void refreshAccessToken() {
         if (accessTokenProvider != null) {
-            dataSource.addConnectionProperty(TOKEN.getPropertyKey(), accessTokenProvider.getAccessDetails().getAccessToken());
+            dataSource.addConnectionProperty(DriverProperty.TOKEN.getPropertyKey(), accessTokenProvider.getAccessDetails().getAccessToken());
         }
     }
 
@@ -325,8 +321,8 @@ public class SnowflakeComputingConnectionPool extends AbstractDBCPConnectionPool
             connectionProperties.put("warehouse", warehouse);
         }
         if (tokenProvider != null) {
-            connectionProperties.put(AUTHENTICATOR.getPropertyKey(), "oauth");
-            connectionProperties.put(TOKEN.getPropertyKey(), tokenProvider.getAccessDetails().getAccessToken());
+            connectionProperties.put(DriverProperty.AUTHENTICATOR.getPropertyKey(), "oauth");
+            connectionProperties.put(DriverProperty.TOKEN.getPropertyKey(), tokenProvider.getAccessDetails().getAccessToken());
         }
 
         final PropertyValue privateKeyServiceProperty = context.getProperty(PRIVATE_KEY_SERVICE);
@@ -334,8 +330,8 @@ public class SnowflakeComputingConnectionPool extends AbstractDBCPConnectionPool
             final PrivateKeyService privateKeyService = privateKeyServiceProperty.asControllerService(PrivateKeyService.class);
             final PrivateKey privateKey = privateKeyService.getPrivateKey();
             final String privateKeyBase64 = getPrivateKeyBase64(privateKey);
-            connectionProperties.put(PRIVATE_KEY_BASE64.getPropertyKey(), privateKeyBase64);
-            connectionProperties.put(AUTHENTICATOR.getPropertyKey(), AUTHENTICATOR_SNOWFLAKE_JWT);
+            connectionProperties.put(DriverProperty.PRIVATE_KEY_BASE64.getPropertyKey(), privateKeyBase64);
+            connectionProperties.put(DriverProperty.AUTHENTICATOR.getPropertyKey(), AUTHENTICATOR_SNOWFLAKE_JWT);
         }
 
         final ProxyConfigurationService proxyConfigurationService = context
@@ -343,21 +339,21 @@ public class SnowflakeComputingConnectionPool extends AbstractDBCPConnectionPool
                 .asControllerService(ProxyConfigurationService.class);
         if (proxyConfigurationService != null) {
             final ProxyConfiguration proxyConfiguration = proxyConfigurationService.getConfiguration();
-            connectionProperties.put(SFSessionProperty.USE_PROXY.getPropertyKey(), "true");
+            connectionProperties.put(DriverProperty.USE_PROXY.getPropertyKey(), Boolean.TRUE.toString());
             if (proxyConfiguration.getProxyServerHost() != null) {
-                connectionProperties.put(SFSessionProperty.PROXY_HOST.getPropertyKey(), proxyConfiguration.getProxyServerHost());
+                connectionProperties.put(DriverProperty.PROXY_HOST.getPropertyKey(), proxyConfiguration.getProxyServerHost());
             }
             if (proxyConfiguration.getProxyServerPort() != null) {
-                connectionProperties.put(SFSessionProperty.PROXY_PORT.getPropertyKey(), proxyConfiguration.getProxyServerPort().toString());
+                connectionProperties.put(DriverProperty.PROXY_PORT.getPropertyKey(), proxyConfiguration.getProxyServerPort().toString());
             }
             if (proxyConfiguration.getProxyUserName() != null) {
-                connectionProperties.put(SFSessionProperty.PROXY_USER.getPropertyKey(), proxyConfiguration.getProxyUserName());
+                connectionProperties.put(DriverProperty.PROXY_USER.getPropertyKey(), proxyConfiguration.getProxyUserName());
             }
             if (proxyConfiguration.getProxyUserPassword() != null) {
-                connectionProperties.put(SFSessionProperty.PROXY_PASSWORD.getPropertyKey(), proxyConfiguration.getProxyUserPassword());
+                connectionProperties.put(DriverProperty.PROXY_PASSWORD.getPropertyKey(), proxyConfiguration.getProxyUserPassword());
             }
             if (proxyConfiguration.getProxyType() != null) {
-                connectionProperties.put(SFSessionProperty.PROXY_PROTOCOL.getPropertyKey(), proxyConfiguration.getProxyType().name().toLowerCase());
+                connectionProperties.put(DriverProperty.PROXY_PROTOCOL.getPropertyKey(), proxyConfiguration.getProxyType().name().toLowerCase());
             }
         }
         return connectionProperties;
@@ -393,4 +389,37 @@ public class SnowflakeComputingConnectionPool extends AbstractDBCPConnectionPool
         final byte[] pemPrivateKeyBinary = pemPrivateKey.getBytes(StandardCharsets.UTF_8);
         return encoder.encodeToString(pemPrivateKeyBinary);
     }
+
+    /**
+     * Snowflake JDBC Driver Properties derived from net.snowflake.client.internal.core.SFSessionProperty
+     */
+    enum DriverProperty {
+        AUTHENTICATOR("authenticator"),
+
+        PRIVATE_KEY_BASE64("private_key_base64"),
+
+        PROXY_HOST("proxyHost"),
+
+        PROXY_PORT("proxyPort"),
+
+        PROXY_USER("proxyUser"),
+
+        PROXY_PASSWORD("proxyPassword"),
+
+        PROXY_PROTOCOL("proxyProtocol"),
+
+        TOKEN("token"),
+
+        USE_PROXY("useProxy");
+
+        private final String propertyKey;
+
+        DriverProperty(final String propertyKey) {
+            this.propertyKey = propertyKey;
+        }
+
+        String getPropertyKey() {
+            return propertyKey;
+        }
+    }
 }
diff --git a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/test/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPoolTest.java b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/test/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPoolTest.java
index 6211876719f..77358e4b4ef 100644
--- a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/test/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPoolTest.java
+++ b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/test/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPoolTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.nifi.snowflake.service;
 
-import net.snowflake.client.core.SFSessionProperty;
 import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.dbcp.utils.DBCPProperties;
 import org.apache.nifi.key.service.api.PrivateKeyService;
@@ -113,10 +112,10 @@ class SnowflakeComputingConnectionPoolTest {
         assertNotNull(connectionProperties);
         assertFalse(connectionProperties.isEmpty());
 
-        final String authenticator = connectionProperties.get(SFSessionProperty.AUTHENTICATOR.getPropertyKey());
+        final String authenticator = connectionProperties.get(SnowflakeComputingConnectionPool.DriverProperty.AUTHENTICATOR.getPropertyKey());
         assertEquals(SNOWFLAKE_JWT, authenticator);
 
-        final String privateKeyBase64 = connectionProperties.get(SFSessionProperty.PRIVATE_KEY_BASE64.getPropertyKey());
+        final String privateKeyBase64 = connectionProperties.get(SnowflakeComputingConnectionPool.DriverProperty.PRIVATE_KEY_BASE64.getPropertyKey());
         assertNotNull(privateKeyBase64);
 
         assertTrue(privateKeyBase64.startsWith(PEM_HEADER_BASE64), "PEM Header encoded with Bas64 not found");
diff --git a/nifi-extension-bundles/nifi-snowflake-bundle/pom.xml b/nifi-extension-bundles/nifi-snowflake-bundle/pom.xml
index 0dc84ff64ea..8196585de2b 100644
--- a/nifi-extension-bundles/nifi-snowflake-bundle/pom.xml
+++ b/nifi-extension-bundles/nifi-snowflake-bundle/pom.xml
@@ -24,7 +24,7 @@
         <guava.version>33.5.0-jre</guava.version>
         <protobuf.version>4.34.1</protobuf.version>
         <grpc.version>1.80.0</grpc.version>
-        <snowflake-jdbc-thin.version>3.28.0</snowflake-jdbc-thin.version>
+        <snowflake-jdbc-thin.version>4.0.2</snowflake-jdbc-thin.version>
     </properties>
 
     <modules>
@@ -89,6 +89,16 @@
                         <groupId>com.google.code.findbugs</groupId>
                         <artifactId>jsr305</artifactId>
                     </exclusion>
+                    <!-- Conscrypt Security Provider not required for Google Cloud Storage -->
+                    <exclusion>
+                        <groupId>org.conscrypt</groupId>
+                        <artifactId>conscrypt-openjdk-uber</artifactId>
+                    </exclusion>
+                    <!-- grpc-netty-shaded excluded in favor of grpc-netty -->
+                    <exclusion>
+                        <groupId>io.grpc</groupId>
+                        <artifactId>grpc-netty-shaded</artifactId>
+                    </exclusion>
                 </exclusions>
             </dependency>
         </dependencies>