Search in sources :

Example 11 with FTPFile

use of org.apache.commons.net.ftp.FTPFile in project camel by apache.

the class FtpOperations method retrieveFileToFileInLocalWorkDirectory.

@SuppressWarnings("unchecked")
private boolean retrieveFileToFileInLocalWorkDirectory(String name, Exchange exchange) throws GenericFileOperationFailedException {
    File temp;
    File local = new File(FileUtil.normalizePath(endpoint.getLocalWorkDirectory()));
    OutputStream os;
    try {
        // use relative filename in local work directory
        GenericFile<FTPFile> target = (GenericFile<FTPFile>) exchange.getProperty(FileComponent.FILE_EXCHANGE_FILE);
        ObjectHelper.notNull(target, "Exchange should have the " + FileComponent.FILE_EXCHANGE_FILE + " set");
        String relativeName = target.getRelativeFilePath();
        temp = new File(local, relativeName + ".inprogress");
        local = new File(local, relativeName);
        // create directory to local work file
        local.mkdirs();
        // delete any existing files
        if (temp.exists()) {
            if (!FileUtil.deleteFile(temp)) {
                throw new GenericFileOperationFailedException("Cannot delete existing local work file: " + temp);
            }
        }
        if (local.exists()) {
            if (!FileUtil.deleteFile(local)) {
                throw new GenericFileOperationFailedException("Cannot delete existing local work file: " + local);
            }
        }
        // create new temp local work file
        if (!temp.createNewFile()) {
            throw new GenericFileOperationFailedException("Cannot create new local work file: " + temp);
        }
        // store content as a file in the local work directory in the temp handle
        os = new FileOutputStream(temp);
        // set header with the path to the local work file            
        exchange.getIn().setHeader(Exchange.FILE_LOCAL_WORK_PATH, local.getPath());
    } catch (Exception e) {
        throw new GenericFileOperationFailedException("Cannot create new local work file: " + local);
    }
    boolean result;
    try {
        GenericFile<FTPFile> target = (GenericFile<FTPFile>) exchange.getProperty(FileComponent.FILE_EXCHANGE_FILE);
        // store the java.io.File handle as the body
        target.setBody(local);
        String remoteName = name;
        String currentDir = null;
        if (endpoint.getConfiguration().isStepwise()) {
            // remember current directory
            currentDir = getCurrentDirectory();
            // change directory to path where the file is to be retrieved
            // (must do this as some FTP servers cannot retrieve using absolute path)
            String path = FileUtil.onlyPath(name);
            if (path != null) {
                changeCurrentDirectory(path);
            }
            // remote name is now only the file name as we just changed directory
            remoteName = FileUtil.stripPath(name);
        }
        log.trace("Client retrieveFile: {}", remoteName);
        result = client.retrieveFile(remoteName, os);
        // store client reply information after the operation
        exchange.getIn().setHeader(FtpConstants.FTP_REPLY_CODE, client.getReplyCode());
        exchange.getIn().setHeader(FtpConstants.FTP_REPLY_STRING, client.getReplyString());
        // change back to current directory
        if (endpoint.getConfiguration().isStepwise()) {
            changeCurrentDirectory(currentDir);
        }
    } catch (IOException e) {
        log.trace("Error occurred during retrieving file: {} to local directory. Deleting local work file: {}", name, temp);
        // failed to retrieve the file so we need to close streams and delete in progress file
        // must close stream before deleting file
        IOHelper.close(os, "retrieve: " + name, log);
        boolean deleted = FileUtil.deleteFile(temp);
        if (!deleted) {
            log.warn("Error occurred during retrieving file: " + name + " to local directory. Cannot delete local work file: " + temp);
        }
        throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
    } finally {
        // need to close the stream before rename it
        IOHelper.close(os, "retrieve: " + name, log);
    }
    log.debug("Retrieve file to local work file result: {}", result);
    if (result) {
        log.trace("Renaming local in progress file from: {} to: {}", temp, local);
        // operation went okay so rename temp to local after we have retrieved the data
        try {
            if (!FileUtil.renameFile(temp, local, false)) {
                throw new GenericFileOperationFailedException("Cannot rename local work file from: " + temp + " to: " + local);
            }
        } catch (IOException e) {
            throw new GenericFileOperationFailedException("Cannot rename local work file from: " + temp + " to: " + local, e);
        }
    }
    return result;
}
Also used : GenericFileOperationFailedException(org.apache.camel.component.file.GenericFileOperationFailedException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) FileOutputStream(java.io.FileOutputStream) FTPFile(org.apache.commons.net.ftp.FTPFile) IOException(java.io.IOException) GenericFile(org.apache.camel.component.file.GenericFile) File(java.io.File) FTPFile(org.apache.commons.net.ftp.FTPFile) GenericFile(org.apache.camel.component.file.GenericFile) GenericFileOperationFailedException(org.apache.camel.component.file.GenericFileOperationFailedException) IOException(java.io.IOException) InvalidPayloadException(org.apache.camel.InvalidPayloadException)

Example 12 with FTPFile

use of org.apache.commons.net.ftp.FTPFile in project camel by apache.

the class FtpChangedExclusiveReadLockStrategy method acquireExclusiveReadLock.

public boolean acquireExclusiveReadLock(GenericFileOperations<FTPFile> operations, GenericFile<FTPFile> file, Exchange exchange) throws Exception {
    boolean exclusive = false;
    LOG.trace("Waiting for exclusive read lock to file: " + file);
    long lastModified = Long.MIN_VALUE;
    long length = Long.MIN_VALUE;
    StopWatch watch = new StopWatch();
    long startTime = new Date().getTime();
    while (!exclusive) {
        // timeout check
        if (timeout > 0) {
            long delta = watch.taken();
            if (delta > timeout) {
                CamelLogger.log(LOG, readLockLoggingLevel, "Cannot acquire read lock within " + timeout + " millis. Will skip the file: " + file);
                // we could not get the lock within the timeout period, so return false
                return false;
            }
        }
        long newLastModified = 0;
        long newLength = 0;
        List<FTPFile> files;
        if (fastExistsCheck) {
            // use the absolute file path to only pickup the file we want to check, this avoids expensive
            // list operations if we have a lot of files in the directory
            String path = file.getAbsoluteFilePath();
            if (path.equals("/") || path.equals("\\")) {
                // special for root (= home) directory
                LOG.trace("Using fast exists to update file information in home directory");
                files = operations.listFiles();
            } else {
                LOG.trace("Using fast exists to update file information for {}", path);
                files = operations.listFiles(path);
            }
        } else {
            // fast option not enabled, so list the directory and filter the file name
            String path = file.getParent();
            if (path.equals("/") || path.equals("\\")) {
                // special for root (= home) directory
                LOG.trace("Using full directory listing in home directory to update file information. Consider enabling fastExistsCheck option.");
                files = operations.listFiles();
            } else {
                LOG.trace("Using full directory listing to update file information for {}. Consider enabling fastExistsCheck option.", path);
                files = operations.listFiles(path);
            }
        }
        LOG.trace("List files {} found {} files", file.getAbsoluteFilePath(), files.size());
        for (FTPFile f : files) {
            boolean match;
            if (fastExistsCheck) {
                // uses the absolute file path as well
                match = f.getName().equals(file.getAbsoluteFilePath()) || f.getName().equals(file.getFileNameOnly());
            } else {
                match = f.getName().equals(file.getFileNameOnly());
            }
            if (match) {
                newLength = f.getSize();
                if (f.getTimestamp() != null) {
                    newLastModified = f.getTimestamp().getTimeInMillis();
                }
            }
        }
        LOG.trace("Previous last modified: " + lastModified + ", new last modified: " + newLastModified);
        LOG.trace("Previous length: " + length + ", new length: " + newLength);
        long newOlderThan = startTime + watch.taken() - minAge;
        LOG.trace("New older than threshold: {}", newOlderThan);
        if (newLength >= minLength && ((minAge == 0 && newLastModified == lastModified && newLength == length) || (minAge != 0 && newLastModified < newOlderThan))) {
            LOG.trace("Read lock acquired.");
            exclusive = true;
        } else {
            // set new base file change information
            lastModified = newLastModified;
            length = newLength;
            boolean interrupted = sleep();
            if (interrupted) {
                // we were interrupted while sleeping, we are likely being shutdown so return false
                return false;
            }
        }
    }
    return exclusive;
}
Also used : FTPFile(org.apache.commons.net.ftp.FTPFile) Date(java.util.Date) StopWatch(org.apache.camel.util.StopWatch)

Example 13 with FTPFile

use of org.apache.commons.net.ftp.FTPFile in project camel by apache.

the class FtpProcessStrategyFactory method createGenericFileProcessStrategy.

public static GenericFileProcessStrategy<FTPFile> createGenericFileProcessStrategy(CamelContext context, Map<String, Object> params) {
    // We assume a value is present only if its value not null for String and 'true' for boolean
    Expression moveExpression = (Expression) params.get("move");
    Expression moveFailedExpression = (Expression) params.get("moveFailed");
    Expression preMoveExpression = (Expression) params.get("preMove");
    boolean isNoop = params.get("noop") != null;
    boolean isDelete = params.get("delete") != null;
    boolean isMove = moveExpression != null || preMoveExpression != null || moveFailedExpression != null;
    if (isDelete) {
        GenericFileDeleteProcessStrategy<FTPFile> strategy = new GenericFileDeleteProcessStrategy<FTPFile>();
        strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
        if (preMoveExpression != null) {
            GenericFileExpressionRenamer<FTPFile> renamer = new GenericFileExpressionRenamer<FTPFile>();
            renamer.setExpression(preMoveExpression);
            strategy.setBeginRenamer(renamer);
        }
        if (moveFailedExpression != null) {
            GenericFileExpressionRenamer<FTPFile> renamer = new GenericFileExpressionRenamer<FTPFile>();
            renamer.setExpression(moveFailedExpression);
            strategy.setFailureRenamer(renamer);
        }
        return strategy;
    } else if (isMove || isNoop) {
        GenericFileRenameProcessStrategy<FTPFile> strategy = new GenericFileRenameProcessStrategy<FTPFile>();
        strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
        if (!isNoop && moveExpression != null) {
            // move on commit is only possible if not noop
            GenericFileExpressionRenamer<FTPFile> renamer = new GenericFileExpressionRenamer<FTPFile>();
            renamer.setExpression(moveExpression);
            strategy.setCommitRenamer(renamer);
        }
        // both move and noop supports pre move
        if (moveFailedExpression != null) {
            GenericFileExpressionRenamer<FTPFile> renamer = new GenericFileExpressionRenamer<FTPFile>();
            renamer.setExpression(moveFailedExpression);
            strategy.setFailureRenamer(renamer);
        }
        // both move and noop supports pre move
        if (preMoveExpression != null) {
            GenericFileExpressionRenamer<FTPFile> renamer = new GenericFileExpressionRenamer<FTPFile>();
            renamer.setExpression(preMoveExpression);
            strategy.setBeginRenamer(renamer);
        }
        return strategy;
    } else {
        // default strategy will do nothing
        GenericFileNoOpProcessStrategy<FTPFile> strategy = new GenericFileNoOpProcessStrategy<FTPFile>();
        strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
        return strategy;
    }
}
Also used : Expression(org.apache.camel.Expression) GenericFileRenameProcessStrategy(org.apache.camel.component.file.strategy.GenericFileRenameProcessStrategy) GenericFileExpressionRenamer(org.apache.camel.component.file.strategy.GenericFileExpressionRenamer) FTPFile(org.apache.commons.net.ftp.FTPFile) GenericFileDeleteProcessStrategy(org.apache.camel.component.file.strategy.GenericFileDeleteProcessStrategy) GenericFileNoOpProcessStrategy(org.apache.camel.component.file.strategy.GenericFileNoOpProcessStrategy)

Example 14 with FTPFile

use of org.apache.commons.net.ftp.FTPFile in project camel by apache.

the class FtpConsumer method doPollDirectory.

protected boolean doPollDirectory(String absolutePath, String dirName, List<GenericFile<FTPFile>> fileList, int depth) {
    log.trace("doPollDirectory from absolutePath: {}, dirName: {}", absolutePath, dirName);
    depth++;
    // remove trailing /
    dirName = FileUtil.stripTrailingSeparator(dirName);
    // compute dir depending on stepwise is enabled or not
    String dir;
    if (isStepwise()) {
        dir = ObjectHelper.isNotEmpty(dirName) ? dirName : absolutePath;
        operations.changeCurrentDirectory(dir);
    } else {
        dir = absolutePath;
    }
    log.trace("Polling directory: {}", dir);
    List<FTPFile> files = null;
    if (isUseList()) {
        if (isStepwise()) {
            files = operations.listFiles();
        } else {
            files = operations.listFiles(dir);
        }
    } else {
        // we cannot use the LIST command(s) so we can only poll a named file
        // so created a pseudo file with that name
        FTPFile file = new FTPFile();
        file.setType(FTPFile.FILE_TYPE);
        fileExpressionResult = evaluateFileExpression();
        if (fileExpressionResult != null) {
            file.setName(fileExpressionResult);
            files = new ArrayList<FTPFile>(1);
            files.add(file);
        }
    }
    if (files == null || files.isEmpty()) {
        // no files in this directory to poll
        log.trace("No files found in directory: {}", dir);
        return true;
    } else {
        // we found some files
        log.trace("Found {} in directory: {}", files.size(), dir);
    }
    for (FTPFile file : files) {
        if (log.isTraceEnabled()) {
            log.trace("FtpFile[name={}, dir={}, file={}]", new Object[] { file.getName(), file.isDirectory(), file.isFile() });
        }
        // check if we can continue polling in files
        if (!canPollMoreFiles(fileList)) {
            return false;
        }
        if (file.isDirectory()) {
            RemoteFile<FTPFile> remote = asRemoteFile(absolutePath, file, getEndpoint().getCharset());
            if (endpoint.isRecursive() && depth < endpoint.getMaxDepth() && isValidFile(remote, true, files)) {
                // recursive scan and add the sub files and folders
                String subDirectory = file.getName();
                String path = absolutePath + "/" + subDirectory;
                boolean canPollMore = pollSubDirectory(path, subDirectory, fileList, depth);
                if (!canPollMore) {
                    return false;
                }
            }
        } else if (file.isFile()) {
            RemoteFile<FTPFile> remote = asRemoteFile(absolutePath, file, getEndpoint().getCharset());
            if (depth >= endpoint.getMinDepth() && isValidFile(remote, false, files)) {
                // matched file so add
                fileList.add(remote);
            }
        } else {
            log.debug("Ignoring unsupported remote file type: " + file);
        }
    }
    return true;
}
Also used : FTPFile(org.apache.commons.net.ftp.FTPFile)

Example 15 with FTPFile

use of org.apache.commons.net.ftp.FTPFile in project camel by apache.

the class FtpOperations method listFiles.

public List<FTPFile> listFiles(String path) throws GenericFileOperationFailedException {
    log.trace("listFiles({})", path);
    // use current directory if path not given
    if (ObjectHelper.isEmpty(path)) {
        path = ".";
    }
    try {
        final List<FTPFile> list = new ArrayList<FTPFile>();
        FTPFile[] files = client.listFiles(path);
        // can return either null or an empty list depending on FTP servers
        if (files != null) {
            list.addAll(Arrays.asList(files));
        }
        return list;
    } catch (IOException e) {
        throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
    }
}
Also used : GenericFileOperationFailedException(org.apache.camel.component.file.GenericFileOperationFailedException) ArrayList(java.util.ArrayList) FTPFile(org.apache.commons.net.ftp.FTPFile) IOException(java.io.IOException)

Aggregations

FTPFile (org.apache.commons.net.ftp.FTPFile)18 IOException (java.io.IOException)9 GenericFileOperationFailedException (org.apache.camel.component.file.GenericFileOperationFailedException)4 FileOutputStream (java.io.FileOutputStream)3 ArrayList (java.util.ArrayList)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 File (java.io.File)2 InputStream (java.io.InputStream)2 OutputStream (java.io.OutputStream)2 GenericFile (org.apache.camel.component.file.GenericFile)2 FTPClient (org.apache.commons.net.ftp.FTPClient)2 FileStatus (org.apache.hadoop.fs.FileStatus)2 Path (org.apache.hadoop.fs.Path)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 FileNotFoundException (java.io.FileNotFoundException)1 SocketException (java.net.SocketException)1 URI (java.net.URI)1 Date (java.util.Date)1 HashSet (java.util.HashSet)1 CancellationException (java.util.concurrent.CancellationException)1