use of com.jcraft.jsch.SftpException 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);
}
}
}
use of com.jcraft.jsch.SftpException 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);
}
}
}
use of com.jcraft.jsch.SftpException 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;
}
use of com.jcraft.jsch.SftpException in project nifi by apache.
the class SFTPTransfer method getChannel.
private ChannelSftp getChannel(final FlowFile flowFile) throws IOException {
if (sftp != null) {
String sessionhost = session.getHost();
String desthost = ctx.getProperty(HOSTNAME).evaluateAttributeExpressions(flowFile).getValue();
if (sessionhost.equals(desthost)) {
// destination matches so we can keep our current session
return sftp;
} else {
// this flowFile is going to a different destination, reset session
close();
}
}
final JSch jsch = new JSch();
try {
final String username = ctx.getProperty(USERNAME).evaluateAttributeExpressions(flowFile).getValue();
final Session session = jsch.getSession(username, ctx.getProperty(HOSTNAME).evaluateAttributeExpressions(flowFile).getValue(), ctx.getProperty(PORT).evaluateAttributeExpressions(flowFile).asInteger().intValue());
final String hostKeyVal = ctx.getProperty(HOST_KEY_FILE).getValue();
if (hostKeyVal != null) {
jsch.setKnownHosts(hostKeyVal);
}
final Properties properties = new Properties();
properties.setProperty("StrictHostKeyChecking", ctx.getProperty(STRICT_HOST_KEY_CHECKING).asBoolean() ? "yes" : "no");
properties.setProperty("PreferredAuthentications", "publickey,password,keyboard-interactive");
final PropertyValue compressionValue = ctx.getProperty(FileTransfer.USE_COMPRESSION);
if (compressionValue != null && "true".equalsIgnoreCase(compressionValue.getValue())) {
properties.setProperty("compression.s2c", "zlib@openssh.com,zlib,none");
properties.setProperty("compression.c2s", "zlib@openssh.com,zlib,none");
} else {
properties.setProperty("compression.s2c", "none");
properties.setProperty("compression.c2s", "none");
}
session.setConfig(properties);
final String privateKeyFile = ctx.getProperty(PRIVATE_KEY_PATH).evaluateAttributeExpressions(flowFile).getValue();
if (privateKeyFile != null) {
jsch.addIdentity(privateKeyFile, ctx.getProperty(PRIVATE_KEY_PASSPHRASE).evaluateAttributeExpressions(flowFile).getValue());
}
final String password = ctx.getProperty(FileTransfer.PASSWORD).evaluateAttributeExpressions(flowFile).getValue();
if (password != null) {
session.setPassword(password);
}
final int connectionTimeoutMillis = ctx.getProperty(FileTransfer.CONNECTION_TIMEOUT).asTimePeriod(TimeUnit.MILLISECONDS).intValue();
session.setTimeout(connectionTimeoutMillis);
session.connect();
this.session = session;
this.closed = false;
sftp = (ChannelSftp) session.openChannel("sftp");
sftp.connect(connectionTimeoutMillis);
session.setTimeout(ctx.getProperty(FileTransfer.DATA_TIMEOUT).asTimePeriod(TimeUnit.MILLISECONDS).intValue());
if (!ctx.getProperty(USE_KEEPALIVE_ON_TIMEOUT).asBoolean()) {
// do not send keepalive message on SocketTimeoutException
session.setServerAliveCountMax(0);
}
try {
this.homeDir = sftp.getHome();
} catch (SftpException e) {
// For some combination of server configuration and user home directory, getHome() can fail with "2: File not found"
// Since homeDir is only used tor SEND provenance event transit uri, this is harmless. Log and continue.
logger.debug("Failed to retrieve {} home directory due to {}", new Object[] { username, e.getMessage() });
}
return sftp;
} catch (JSchException e) {
throw new IOException("Failed to obtain connection to remote host due to " + e.toString(), e);
}
}
use of com.jcraft.jsch.SftpException in project Lucee by lucee.
the class SFTPClientImpl method listFiles.
@Override
public FTPFile[] listFiles(String pathname) throws IOException {
pathname = cleanPath(pathname);
List<FTPFile> files = new ArrayList<FTPFile>();
try {
Vector list = channelSftp.ls(pathname);
Iterator<ChannelSftp.LsEntry> it = list.iterator();
ChannelSftp.LsEntry entry;
SftpATTRS attrs;
FTPFile file;
String fileName;
while (it.hasNext()) {
entry = it.next();
attrs = entry.getAttrs();
fileName = entry.getFilename();
if (fileName.equals(".") || fileName.equals(".."))
continue;
file = new FTPFile();
files.add(file);
// is dir
file.setType(attrs.isDir() ? FTPFile.DIRECTORY_TYPE : FTPFile.FILE_TYPE);
file.setTimestamp(Caster.toCalendar(attrs.getMTime() * 1000L, null, Locale.ENGLISH));
file.setSize(attrs.isDir() ? 0 : attrs.getSize());
FTPConstant.setPermission(file, attrs.getPermissions());
file.setName(fileName);
}
handleSucess();
} catch (SftpException e) {
handleFail(e, stopOnError);
}
return files.toArray(new FTPFile[files.size()]);
}
Aggregations