Search in sources :

Example 61 with ChannelSftp

use of com.jcraft.jsch.ChannelSftp in project nifi by apache.

the class SFTPTransfer method getRemoteFileInfo.

@Override
@SuppressWarnings("unchecked")
public FileInfo getRemoteFileInfo(final FlowFile flowFile, final String path, String filename) throws IOException {
    final ChannelSftp sftp = getChannel(flowFile);
    final String fullPath;
    if (path == null) {
        fullPath = filename;
        int slashpos = filename.lastIndexOf('/');
        if (slashpos >= 0 && !filename.endsWith("/")) {
            filename = filename.substring(slashpos + 1);
        }
    } else {
        fullPath = path + "/" + filename;
    }
    final Vector<LsEntry> vector;
    try {
        vector = sftp.ls(fullPath);
    } catch (final SftpException e) {
        // ls throws exception if filename is not present
        if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
            return null;
        } else {
            throw new IOException("Failed to obtain file listing for " + fullPath, e);
        }
    }
    LsEntry matchingEntry = null;
    for (final LsEntry entry : vector) {
        if (entry.getFilename().equalsIgnoreCase(filename)) {
            matchingEntry = entry;
            break;
        }
    }
    return newFileInfo(matchingEntry, path);
}
Also used : ChannelSftp(com.jcraft.jsch.ChannelSftp) SftpException(com.jcraft.jsch.SftpException) IOException(java.io.IOException) LsEntry(com.jcraft.jsch.ChannelSftp.LsEntry)

Example 62 with ChannelSftp

use of com.jcraft.jsch.ChannelSftp in project nifi by apache.

the class SFTPTransfer method ensureDirectoryExists.

@Override
public void ensureDirectoryExists(final FlowFile flowFile, final File directoryName) throws IOException {
    final ChannelSftp channel = getChannel(flowFile);
    final String remoteDirectory = directoryName.getAbsolutePath().replace("\\", "/").replaceAll("^.\\:", "");
    // eating any exceptions thrown (like if the directory already exists).
    if (disableDirectoryListing) {
        try {
            channel.mkdir(remoteDirectory);
        } catch (SftpException e) {
            if (e.id != ChannelSftp.SSH_FX_FAILURE) {
                throw new IOException("Could not blindly create remote directory due to " + e.getMessage(), e);
            }
        }
        return;
    }
    // end if disableDirectoryListing
    boolean exists;
    try {
        channel.stat(remoteDirectory);
        exists = true;
    } catch (final SftpException e) {
        if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
            // No Such File
            exists = false;
        } else {
            throw new IOException("Failed to determine if remote directory exists at " + remoteDirectory + " due to " + e, e);
        }
    }
    if (!exists) {
        // first ensure parent directories exist before creating this one
        if (directoryName.getParent() != null && !directoryName.getParentFile().equals(new File(File.separator))) {
            ensureDirectoryExists(flowFile, directoryName.getParentFile());
        }
        logger.debug("Remote Directory {} does not exist; creating it", new Object[] { remoteDirectory });
        try {
            channel.mkdir(remoteDirectory);
            logger.debug("Created {}", new Object[] { remoteDirectory });
        } catch (final SftpException e) {
            throw new IOException("Failed to create remote directory " + remoteDirectory + " due to " + e, e);
        }
    }
}
Also used : ChannelSftp(com.jcraft.jsch.ChannelSftp) SftpException(com.jcraft.jsch.SftpException) IOException(java.io.IOException) FlowFile(org.apache.nifi.flowfile.FlowFile) File(java.io.File)

Example 63 with ChannelSftp

use of com.jcraft.jsch.ChannelSftp in project nifi by apache.

the class SFTPTransfer method getListing.

private void getListing(final String path, final int depth, final int maxResults, final List<FileInfo> listing) throws IOException {
    if (maxResults < 1 || listing.size() >= maxResults) {
        return;
    }
    if (depth >= 100) {
        logger.warn(this + " had to stop recursively searching directories at a recursive depth of " + depth + " to avoid memory issues");
        return;
    }
    final boolean ignoreDottedFiles = ctx.getProperty(FileTransfer.IGNORE_DOTTED_FILES).asBoolean();
    final boolean recurse = ctx.getProperty(FileTransfer.RECURSIVE_SEARCH).asBoolean();
    final String fileFilterRegex = ctx.getProperty(FileTransfer.FILE_FILTER_REGEX).getValue();
    final Pattern pattern = (fileFilterRegex == null) ? null : Pattern.compile(fileFilterRegex);
    final String pathFilterRegex = ctx.getProperty(FileTransfer.PATH_FILTER_REGEX).getValue();
    final Pattern pathPattern = (!recurse || pathFilterRegex == null) ? null : Pattern.compile(pathFilterRegex);
    final String remotePath = ctx.getProperty(FileTransfer.REMOTE_PATH).evaluateAttributeExpressions().getValue();
    // check if this directory path matches the PATH_FILTER_REGEX
    boolean pathFilterMatches = true;
    if (pathPattern != null) {
        Path reldir = path == null ? Paths.get(".") : Paths.get(path);
        if (remotePath != null) {
            reldir = Paths.get(remotePath).relativize(reldir);
        }
        if (reldir != null && !reldir.toString().isEmpty()) {
            if (!pathPattern.matcher(reldir.toString().replace("\\", "/")).matches()) {
                pathFilterMatches = false;
            }
        }
    }
    final ChannelSftp sftp = getChannel(null);
    final boolean isPathMatch = pathFilterMatches;
    final List<LsEntry> subDirs = new ArrayList<>();
    try {
        final LsEntrySelector filter = new LsEntrySelector() {

            @Override
            public int select(final LsEntry entry) {
                final String entryFilename = entry.getFilename();
                // files regardless of ignoring dot files
                if (entryFilename.equals(".") || entryFilename.equals("..")) {
                    return LsEntrySelector.CONTINUE;
                }
                // ignoring them
                if (ignoreDottedFiles && entryFilename.startsWith(".")) {
                    return LsEntrySelector.CONTINUE;
                }
                // if is a directory and we're supposed to recurse
                if (recurse && entry.getAttrs().isDir()) {
                    subDirs.add(entry);
                    return LsEntrySelector.CONTINUE;
                }
                // FILE_FILTER_REGEX - then let's add it
                if (!entry.getAttrs().isDir() && !entry.getAttrs().isLink() && isPathMatch) {
                    if (pattern == null || pattern.matcher(entryFilename).matches()) {
                        listing.add(newFileInfo(entry, path));
                    }
                }
                if (listing.size() >= maxResults) {
                    return LsEntrySelector.BREAK;
                }
                return LsEntrySelector.CONTINUE;
            }
        };
        if (path == null || path.trim().isEmpty()) {
            sftp.ls(".", filter);
        } else {
            sftp.ls(path, filter);
        }
    } catch (final SftpException e) {
        final String pathDesc = path == null ? "current directory" : path;
        switch(e.id) {
            case ChannelSftp.SSH_FX_NO_SUCH_FILE:
                throw new FileNotFoundException("Could not perform listing on " + pathDesc + " because could not find the file on the remote server");
            case ChannelSftp.SSH_FX_PERMISSION_DENIED:
                throw new PermissionDeniedException("Could not perform listing on " + pathDesc + " due to insufficient permissions");
            default:
                throw new IOException("Failed to obtain file listing for " + pathDesc, e);
        }
    }
    for (final LsEntry entry : subDirs) {
        final String entryFilename = entry.getFilename();
        final File newFullPath = new File(path, entryFilename);
        final String newFullForwardPath = newFullPath.getPath().replace("\\", "/");
        try {
            getListing(newFullForwardPath, depth + 1, maxResults, listing);
        } catch (final IOException e) {
            logger.error("Unable to get listing from " + newFullForwardPath + "; skipping this subdirectory", e);
        }
    }
}
Also used : Path(java.nio.file.Path) Pattern(java.util.regex.Pattern) SftpException(com.jcraft.jsch.SftpException) ArrayList(java.util.ArrayList) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) ChannelSftp(com.jcraft.jsch.ChannelSftp) LsEntrySelector(com.jcraft.jsch.ChannelSftp.LsEntrySelector) LsEntry(com.jcraft.jsch.ChannelSftp.LsEntry) FlowFile(org.apache.nifi.flowfile.FlowFile) File(java.io.File)

Example 64 with ChannelSftp

use of com.jcraft.jsch.ChannelSftp in project nifi by apache.

the class SFTPTransfer method put.

@Override
public String put(final FlowFile flowFile, final String path, final String filename, final InputStream content) throws IOException {
    final ChannelSftp sftp = getChannel(flowFile);
    // destination path + filename
    final String fullPath = (path == null) ? filename : (path.endsWith("/")) ? path + filename : path + "/" + filename;
    // temporary path + filename
    String tempFilename = ctx.getProperty(TEMP_FILENAME).evaluateAttributeExpressions(flowFile).getValue();
    if (tempFilename == null) {
        final boolean dotRename = ctx.getProperty(DOT_RENAME).asBoolean();
        tempFilename = dotRename ? "." + filename : filename;
    }
    final String tempPath = (path == null) ? tempFilename : (path.endsWith("/")) ? path + tempFilename : path + "/" + tempFilename;
    try {
        sftp.put(content, tempPath);
    } catch (final SftpException e) {
        throw new IOException("Unable to put content to " + fullPath + " due to " + e, e);
    }
    final String lastModifiedTime = ctx.getProperty(LAST_MODIFIED_TIME).evaluateAttributeExpressions(flowFile).getValue();
    if (lastModifiedTime != null && !lastModifiedTime.trim().isEmpty()) {
        try {
            final DateFormat formatter = new SimpleDateFormat(FILE_MODIFY_DATE_ATTR_FORMAT, Locale.US);
            final Date fileModifyTime = formatter.parse(lastModifiedTime);
            int time = (int) (fileModifyTime.getTime() / 1000L);
            sftp.setMtime(tempPath, time);
        } catch (final Exception e) {
            logger.error("Failed to set lastModifiedTime on {} to {} due to {}", new Object[] { tempPath, lastModifiedTime, e });
        }
    }
    final String permissions = ctx.getProperty(PERMISSIONS).evaluateAttributeExpressions(flowFile).getValue();
    if (permissions != null && !permissions.trim().isEmpty()) {
        try {
            int perms = numberPermissions(permissions);
            if (perms >= 0) {
                sftp.chmod(perms, tempPath);
            }
        } catch (final Exception e) {
            logger.error("Failed to set permission on {} to {} due to {}", new Object[] { tempPath, permissions, e });
        }
    }
    final String owner = ctx.getProperty(REMOTE_OWNER).evaluateAttributeExpressions(flowFile).getValue();
    if (owner != null && !owner.trim().isEmpty()) {
        try {
            sftp.chown(Integer.parseInt(owner), tempPath);
        } catch (final Exception e) {
            logger.error("Failed to set owner on {} to {} due to {}", new Object[] { tempPath, owner, e });
        }
    }
    final String group = ctx.getProperty(REMOTE_GROUP).evaluateAttributeExpressions(flowFile).getValue();
    if (group != null && !group.trim().isEmpty()) {
        try {
            sftp.chgrp(Integer.parseInt(group), tempPath);
        } catch (final Exception e) {
            logger.error("Failed to set group on {} to {} due to {}", new Object[] { tempPath, group, e });
        }
    }
    if (!filename.equals(tempFilename)) {
        try {
            sftp.rename(tempPath, fullPath);
        } catch (final SftpException e) {
            try {
                sftp.rm(tempPath);
                throw new IOException("Failed to rename dot-file to " + fullPath + " due to " + e, e);
            } catch (final SftpException e1) {
                throw new IOException("Failed to rename dot-file to " + fullPath + " and failed to delete it when attempting to clean up", e1);
            }
        }
    }
    return fullPath;
}
Also used : ChannelSftp(com.jcraft.jsch.ChannelSftp) SftpException(com.jcraft.jsch.SftpException) SimpleDateFormat(java.text.SimpleDateFormat) DateFormat(java.text.DateFormat) IOException(java.io.IOException) SimpleDateFormat(java.text.SimpleDateFormat) Date(java.util.Date) SftpException(com.jcraft.jsch.SftpException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) JSchException(com.jcraft.jsch.JSchException)

Example 65 with ChannelSftp

use of com.jcraft.jsch.ChannelSftp in project nifi by apache.

the class SFTPUtils method connectSftp.

public static SFTPConnection connectSftp(final SFTPConfiguration conf) throws JSchException, SftpException, IOException {
    final JSch jsch = new JSch();
    final Session session = SFTPUtils.createSession(conf, jsch);
    final ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp");
    sftp.connect();
    return new SFTPConnection(session, sftp);
}
Also used : ChannelSftp(com.jcraft.jsch.ChannelSftp) JSch(com.jcraft.jsch.JSch) Session(com.jcraft.jsch.Session)

Aggregations

ChannelSftp (com.jcraft.jsch.ChannelSftp)99 SftpException (com.jcraft.jsch.SftpException)61 IOException (java.io.IOException)36 JSchException (com.jcraft.jsch.JSchException)28 Session (com.jcraft.jsch.Session)25 JSch (com.jcraft.jsch.JSch)20 Channel (com.jcraft.jsch.Channel)17 LsEntry (com.jcraft.jsch.ChannelSftp.LsEntry)17 File (java.io.File)16 Test (org.junit.Test)14 InputStream (java.io.InputStream)12 SftpATTRS (com.jcraft.jsch.SftpATTRS)11 FileNotFoundException (java.io.FileNotFoundException)9 NullProgressMonitor (org.eclipse.core.runtime.NullProgressMonitor)8 FileInputStream (java.io.FileInputStream)7 OutputStream (java.io.OutputStream)7 Path (org.apache.hadoop.fs.Path)7 CoreException (org.eclipse.core.runtime.CoreException)7 IStatus (org.eclipse.core.runtime.IStatus)7 Status (org.eclipse.core.runtime.Status)7