This is an automated email from the ASF dual-hosted git repository.
tpalfy 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 30f0f4c71a4 NIFI-16385 Made connection validation optional in SMB
components (#11719)
30f0f4c71a4 is described below
commit 30f0f4c71a4522c6421f12eba81fd0d06e4f8648
Author: Peter Turcsanyi <[email protected]>
AuthorDate: Fri Sep 25 15:16:49 2026 +0200
NIFI-16385 Made connection validation optional in SMB components (#11719)
Signed-off-by: Tamas Palfy <[email protected]>
---
.../org/apache/nifi/processors/smb/GetSmbFile.java | 2 ++
.../org/apache/nifi/processors/smb/PutSmbFile.java | 2 ++
.../services/smb/SmbjClientProviderService.java | 2 ++
.../nifi/services/smb/SmbjClientProvider.java | 37 ++++++++++++++++++++--
.../java/org/apache/nifi/smb/common/SmbClient.java | 23 ++++++++------
.../org/apache/nifi/smb/common/SmbProperties.java | 10 ++++++
.../java/org/apache/nifi/smb/common/SmbUtils.java | 5 ++-
7 files changed, 69 insertions(+), 12 deletions(-)
diff --git
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-processors/src/main/java/org/apache/nifi/processors/smb/GetSmbFile.java
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-processors/src/main/java/org/apache/nifi/processors/smb/GetSmbFile.java
index 5860926e41d..99ffa22e837 100644
---
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-processors/src/main/java/org/apache/nifi/processors/smb/GetSmbFile.java
+++
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-processors/src/main/java/org/apache/nifi/processors/smb/GetSmbFile.java
@@ -76,6 +76,7 @@ import static
org.apache.nifi.processors.smb.util.LocalSmbProperties.DOMAIN;
import static org.apache.nifi.processors.smb.util.LocalSmbProperties.PASSWORD;
import static
org.apache.nifi.processors.smb.util.LocalSmbProperties.SMB_CLIENT_PROVIDER_SERVICE;
import static org.apache.nifi.processors.smb.util.LocalSmbProperties.USERNAME;
+import static org.apache.nifi.smb.common.SmbProperties.CONNECTION_VALIDATION;
import static org.apache.nifi.smb.common.SmbProperties.ENABLE_DFS;
import static
org.apache.nifi.smb.common.SmbProperties.OLD_ENABLE_DFS_PROPERTY_NAME;
import static
org.apache.nifi.smb.common.SmbProperties.OLD_SMB_DIALECT_PROPERTY_NAME;
@@ -221,6 +222,7 @@ public class GetSmbFile extends AbstractProcessor {
SMB_DIALECT,
USE_ENCRYPTION,
ENABLE_DFS,
+ CONNECTION_VALIDATION,
TIMEOUT
);
diff --git
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-processors/src/main/java/org/apache/nifi/processors/smb/PutSmbFile.java
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-processors/src/main/java/org/apache/nifi/processors/smb/PutSmbFile.java
index cfda90ec298..8bd0ad10d24 100644
---
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-processors/src/main/java/org/apache/nifi/processors/smb/PutSmbFile.java
+++
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-processors/src/main/java/org/apache/nifi/processors/smb/PutSmbFile.java
@@ -68,6 +68,7 @@ import static
org.apache.nifi.processors.smb.util.LocalSmbProperties.SMB_DIALECT
import static org.apache.nifi.processors.smb.util.LocalSmbProperties.TIMEOUT;
import static org.apache.nifi.processors.smb.util.LocalSmbProperties.USERNAME;
import static
org.apache.nifi.processors.smb.util.LocalSmbProperties.USE_ENCRYPTION;
+import static org.apache.nifi.smb.common.SmbProperties.CONNECTION_VALIDATION;
import static
org.apache.nifi.smb.common.SmbProperties.OLD_ENABLE_DFS_PROPERTY_NAME;
import static
org.apache.nifi.smb.common.SmbProperties.OLD_SMB_DIALECT_PROPERTY_NAME;
import static
org.apache.nifi.smb.common.SmbProperties.OLD_TIMEOUT_PROPERTY_NAME;
@@ -164,6 +165,7 @@ public class PutSmbFile extends AbstractProcessor {
SMB_DIALECT,
USE_ENCRYPTION,
ENABLE_DFS,
+ CONNECTION_VALIDATION,
TIMEOUT);
private static final Set<Relationship> RELATIONSHIPS = Set.of(
diff --git
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-client/src/main/java/org/apache/nifi/services/smb/SmbjClientProviderService.java
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-client/src/main/java/org/apache/nifi/services/smb/SmbjClientProviderService.java
index 0b438746839..029c3907ea6 100644
---
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-client/src/main/java/org/apache/nifi/services/smb/SmbjClientProviderService.java
+++
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-client/src/main/java/org/apache/nifi/services/smb/SmbjClientProviderService.java
@@ -32,6 +32,7 @@ import java.util.List;
import java.util.Map;
import static org.apache.nifi.smb.common.SmbProperties.AUTHENTICATION_TYPE;
+import static org.apache.nifi.smb.common.SmbProperties.CONNECTION_VALIDATION;
import static org.apache.nifi.smb.common.SmbProperties.DOMAIN;
import static org.apache.nifi.smb.common.SmbProperties.ENABLE_DFS;
import static org.apache.nifi.smb.common.SmbProperties.HOSTNAME;
@@ -70,6 +71,7 @@ public class SmbjClientProviderService extends
AbstractControllerService impleme
SMB_DIALECT,
USE_ENCRYPTION,
ENABLE_DFS,
+ CONNECTION_VALIDATION,
TIMEOUT
);
diff --git
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/services/smb/SmbjClientProvider.java
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/services/smb/SmbjClientProvider.java
index 9f2162538ba..809dd5890ee 100644
---
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/services/smb/SmbjClientProvider.java
+++
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/services/smb/SmbjClientProvider.java
@@ -16,9 +16,11 @@
*/
package org.apache.nifi.services.smb;
+import com.hierynomus.protocol.transport.TransportException;
import com.hierynomus.smbj.SMBClient;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.auth.GSSAuthenticationContext;
+import com.hierynomus.smbj.common.SMBRuntimeException;
import com.hierynomus.smbj.connection.Connection;
import com.hierynomus.smbj.session.Session;
import com.hierynomus.smbj.share.DiskShare;
@@ -94,14 +96,17 @@ public class SmbjClientProvider implements
SmbClientProvider, Closeable {
@Override
public SmbClientService getClient(final ComponentLog logger, final
Map<String, String> attributes) throws IOException {
- final Connection connection =
smbClient.connect(getHostname(attributes), getPort(attributes));
+ final String hostname = getHostname(attributes);
+ final Integer port = getPort(attributes);
final URI serviceLocation = getServiceLocation(attributes);
+ final AuthenticationContext authenticationContext =
createAuthenticationContext(logger);
+
final Session session;
final Share share;
try {
- session =
connection.authenticate(createAuthenticationContext(logger));
+ session = createSession(hostname, port, authenticationContext);
} catch (Exception e) {
throw new IOException("Could not create session for share " +
serviceLocation, e);
}
@@ -121,6 +126,34 @@ public class SmbjClientProvider implements
SmbClientProvider, Closeable {
return new SmbjClientService(session, (DiskShare) share,
getServiceLocation(attributes), logger);
}
+ private Session createSession(String hostname, int port,
AuthenticationContext authenticationContext) throws IOException {
+ Connection connection = smbClient.connect(hostname, port);
+
+ try {
+ return connection.authenticate(authenticationContext);
+ } catch (SMBRuntimeException e) {
+ if (e.getCause() != null && e.getCause() instanceof
TransportException) {
+ logger.info("Stale connection found, unregistering it and
creating a new one");
+
+ closeConnection(connection);
+ connection = smbClient.connect(hostname, port);
+
+ return connection.authenticate(authenticationContext);
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ private void closeConnection(final Connection connection) {
+ try {
+ if (connection != null) {
+ connection.close(true);
+ }
+ } catch (Exception e) {
+ logger.info("Could not close connection to {}",
getServiceLocation(), e);
+ }
+ }
private void closeSession(final Session session, URI serviceLocation) {
try {
diff --git
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbClient.java
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbClient.java
index 92dec5f957f..b170f78e136 100644
---
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbClient.java
+++
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbClient.java
@@ -29,7 +29,7 @@ import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
- * Extends {@link SMBClient} with connection health check.
+ * Extends {@link SMBClient} with optional connection health check.
* <br/>
* Workaround to https://github.com/hierynomus/smbj/issues/796.
* <br/><br/>
@@ -49,20 +49,21 @@ class SmbClient extends SMBClient {
private static final Logger LOGGER =
LoggerFactory.getLogger(SmbClient.class);
- private SMBEventBus bus;
+ private final SMBEventBus bus;
- private SmbClient(final SmbConfig config, final SMBEventBus bus) {
+ private final boolean connectionValidationEnabled;
+
+ private SmbClient(final SmbConfig config, final SMBEventBus bus, final
boolean connectionValidationEnabled) {
super(config, bus);
+
+ this.bus = bus;
+ this.connectionValidationEnabled = connectionValidationEnabled;
}
- static SmbClient create(final SmbConfig config) {
+ static SmbClient create(final SmbConfig config, final boolean
connectionValidationEnabled) {
final SMBEventBus bus = new SMBEventBus();
- final SmbClient client = new SmbClient(config, bus);
-
- client.bus = bus;
-
- return client;
+ return new SmbClient(config, bus, connectionValidationEnabled);
}
@Override
@@ -74,6 +75,10 @@ class SmbClient extends SMBClient {
public synchronized Connection connect(final String hostname, final int
port) throws IOException {
final Connection connection = super.connect(hostname, port);
+ if (!connectionValidationEnabled) {
+ return connection;
+ }
+
try {
// SMB2 ECHO message can only be sent if this is not a new
connection (and health check is only needed in this case)
if (!connection.release()) {
diff --git
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbProperties.java
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbProperties.java
index be2e88f4c0c..a14b2e0c318 100644
---
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbProperties.java
+++
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbProperties.java
@@ -162,6 +162,16 @@ public class SmbProperties {
.defaultValue("false")
.build();
+ public static final PropertyDescriptor CONNECTION_VALIDATION = new
PropertyDescriptor.Builder()
+ .name("Connection Validation")
+ .description("When enabled, validates reused SMB connections with
an SMB2 ECHO request and replaces stale connections. Please note " +
+ "that Windows and Linux/Samba servers support this way of
validation but others may not. Connection validation must be enabled " +
+ "when DFS is used.")
+ .required(true)
+ .allowableValues("true", "false")
+ .defaultValue("true")
+ .build();
+
public static final PropertyDescriptor TIMEOUT = new
PropertyDescriptor.Builder()
.name("Timeout")
.description("Timeout for read and write operations.")
diff --git
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbUtils.java
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbUtils.java
index b705c5c38a5..bcc5c3aeee1 100644
---
a/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbUtils.java
+++
b/nifi-extension-bundles/nifi-smb-bundle/nifi-smb-smbj-common/src/main/java/org/apache/nifi/smb/common/SmbUtils.java
@@ -21,6 +21,7 @@ import com.hierynomus.smbj.SmbConfig;
import org.apache.nifi.context.PropertyContext;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.apache.nifi.smb.common.SmbProperties.CONNECTION_VALIDATION;
import static org.apache.nifi.smb.common.SmbProperties.ENABLE_DFS;
import static org.apache.nifi.smb.common.SmbProperties.SMB_DIALECT;
import static org.apache.nifi.smb.common.SmbProperties.TIMEOUT;
@@ -33,7 +34,9 @@ public final class SmbUtils {
}
public static SMBClient buildSmbClient(final PropertyContext context) {
- return SmbClient.create(buildSmbConfig(context));
+ final boolean connectionValidationEnabled =
context.getProperty(CONNECTION_VALIDATION).asBoolean();
+
+ return SmbClient.create(buildSmbConfig(context),
connectionValidationEnabled);
}
static SmbConfig buildSmbConfig(final PropertyContext context) {