This is an automated email from the ASF dual-hosted git repository. joewitt pushed a commit to branch support/nifi-1.15 in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/support/nifi-1.15 by this push: new ae26f65 NIFI-9509 Added PatchedSFTPEngine to correct SFTP rename flags handling ae26f65 is described below commit ae26f6580fe82afd3402d4b58762c8bb0d4d3f95 Author: exceptionfactory <exceptionfact...@apache.org> AuthorDate: Tue Dec 21 12:41:26 2021 -0600 NIFI-9509 Added PatchedSFTPEngine to correct SFTP rename flags handling - SSHJ 0.32.0 introduced support for rename flags in SFTP commands without checking the protocol version - PatchedSFTPEngine overrides the rename method to check the SFTP protocol version --- .../processors/standard/ssh/PatchedSFTPEngine.java | 72 ++++++++++++++++++++++ .../processors/standard/util/SFTPTransfer.java | 3 +- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ssh/PatchedSFTPEngine.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ssh/PatchedSFTPEngine.java new file mode 100644 index 0000000..1de696d --- /dev/null +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ssh/PatchedSFTPEngine.java @@ -0,0 +1,72 @@ +/* + * 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.nifi.processors.standard.ssh; + +import net.schmizz.sshj.common.SSHException; +import net.schmizz.sshj.connection.channel.direct.SessionFactory; +import net.schmizz.sshj.sftp.PacketType; +import net.schmizz.sshj.sftp.RenameFlags; +import net.schmizz.sshj.sftp.Request; +import net.schmizz.sshj.sftp.SFTPEngine; +import net.schmizz.sshj.sftp.SFTPException; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * Patched SFTP Engine to workaround SFTP rename issue 751 in SSHJ 0.32.0 + * + * This class can be removed once the issue is resolved in a future version of SSHJ + */ +public class PatchedSFTPEngine extends SFTPEngine { + + public PatchedSFTPEngine(final SessionFactory sessionFactory) throws SSHException { + super(sessionFactory); + } + + /** + * Override rename request packet generation to workaround handling of rename flags + * + * @param oldPath Old path of file to be renamed + * @param newPath New path of file to be renamed + * @param flags Rename flags used for SFTP Version 5 or higher + * @throws IOException Thrown on unsupported protocol version or request processing failures + */ + @Override + public void rename(final String oldPath, final String newPath, final Set<RenameFlags> flags) throws IOException { + if (operativeVersion < 1) { + throw new SFTPException("RENAME is not supported in SFTPv" + operativeVersion); + } + + final Charset remoteCharset = sub.getRemoteCharset(); + final Request request = newRequest(PacketType.RENAME) + .putString(oldPath, remoteCharset) + .putString(newPath, remoteCharset); + // SFTP Version 5 introduced rename flags according to Section 6.5 of the specification + if (operativeVersion >= 5) { + long renameFlagMask = 0L; + for (RenameFlags flag : flags) { + renameFlagMask = renameFlagMask | flag.longValue(); + } + request.putUInt32(renameFlagMask); + } + + request(request).retrieve(getTimeoutMs(), TimeUnit.MILLISECONDS).ensureStatusPacketIsOK(); + } +} diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/util/SFTPTransfer.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/util/SFTPTransfer.java index 1636bbd..13b8eec 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/util/SFTPTransfer.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/util/SFTPTransfer.java @@ -43,6 +43,7 @@ import org.apache.nifi.processor.ProcessSession; import org.apache.nifi.processor.exception.ProcessException; import org.apache.nifi.processor.io.OutputStreamCallback; import org.apache.nifi.processor.util.StandardValidators; +import org.apache.nifi.processors.standard.ssh.PatchedSFTPEngine; import org.apache.nifi.processors.standard.ssh.SSHClientProvider; import org.apache.nifi.processors.standard.ssh.StandardSSHClientProvider; import org.apache.nifi.proxy.ProxyConfiguration; @@ -559,7 +560,7 @@ public class SFTPTransfer implements FileTransfer { final Map<String, String> attributes = flowFile == null ? Collections.emptyMap() : flowFile.getAttributes(); this.sshClient = SSH_CLIENT_PROVIDER.getClient(ctx, attributes); - this.sftpClient = sshClient.newSFTPClient(); + this.sftpClient = new SFTPClient(new PatchedSFTPEngine(sshClient).init()); this.closed = false; // Configure timeout for sftp operations