Search code examples
javasftpapache-commons-vfs

Is there a way to set permissions of a remote folder via VFS in Java?


I create a XML and a ZIP file and upload them via SFTP to a server. The folder structure looks something like this:

/
|
|--/incoming
       |
       |--/<hash>
             |
             |-- file.xml
             |-- file.zip

The folder <hash> is created when I upload both XML and ZIP and I need this folder to have the permissions 777.

As far as I can tell there is no way for me to change the permissions of an already created folder via VFS within Java. What I tried then was to create that folder locally, give it 777 and upload it with the XML and the ZIP inside.

My code looks like this:

File fUploadDir = new File(uploadDir);
fUploadDir.mkdir();

fUploadDir.setReadable(true, false);
fUploadDir.setWritable(true, false);
fUploadDir.setExecutable(true, false);

// Create and add ZIP and XML files...
// ...

StandardFileSystemManager manager = new StandardFileSystemManager();

// Initializes the file manager
manager.init();

File file = new File(pathToFolder);

// Setup our SFTP configuration
FileSystemOptions opts = new FileSystemOptions();
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);

String sftpUri = "sftp://" + userId + ":" + password + "@" + serverAddress + "/" + remoteDirectory;

// Create local file object
FileObject localFile = manager.resolveFile(fUploadDir.getAbsolutePath());

// Create remote file object         
FileObject remoteFile = manager.resolveFile(sftpUri, opts);

// Copy local file to sftp server
remoteFile.copyFrom(localFile, Selectors.SELECT_SELF_AND_CHILDREN);

When I execute this code the XML and the ZIP will be uploaded, but not the directory, so the structure on the SFTP server looks like this:

/
|
|--/incoming
       |
       |-- file.xml
       |-- file.zip

How can I achieve to get the folder with permissions 777 up there?


Solution

  • I've managed to change the permissions. My code looks like this:

    StandardFileSystemManager manager = new StandardFileSystemManager();
    
    String serverAddress = Config.getProperty("SFTP.SERVER.URL");
    String userId = Config.getProperty("SFTP.SERVER.USERID");
    String password = Config.getProperty("SFTP.SERVER.PASSWORD");
    String remoteDirectory = Config.getProperty("SFTP.SERVER.REMOTEPATH");
    
    JSch jsch = new JSch();
    
    Session session = jsch.getSession(userId, serverAddress, 22);
    session.setPassword(password);
    session.setConfig("StrictHostKeyChecking", "no");                
    
    session.connect();
    
    Channel channel = session.openChannel("sftp");
    channel.connect();
    ChannelSftp cSftp = (ChannelSftp) channel;
    
    // check if the file exists
    String filepath = localDirectory + File.separator + fileToFTP;
    File file = new File(filepath);
    if (!file.exists()) {
      logger.error(filepath + " existiert nicht.");
      throw new RuntimeException("Error. Local file not found");
    }
    
    // Initializes the file manager
    manager.init();
    
    // Setup our SFTP configuration
    FileSystemOptions opts = new FileSystemOptions();
    SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
    SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
    SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);
    
    // Create the SFTP URI using the host name, userid, password, remote path and file name
    String sftpUri = "sftp://" + userId + ":" + password +  "@" + serverAddress + "/" + remoteDirectory + "/" + hash + "/" + fileToFTP;
    
    // Create local file object
    FileObject localFile = manager.resolveFile(file.getAbsolutePath());
    
    // Create remote file object         
    FileObject remoteFile = manager.resolveFile(sftpUri, opts);
    
    // Copy local file to sftp server
    remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);
    
    // Set file permissions to 777.
    // 511 is the decimal representation for octal 777.
    cSftp.chmod(511, remoteDirectory + "/" + hash);
    

    As you can see, I do still use VFS, but only for the file transmission. I've created the ZIP file and uploaded it to the SFTP server into the directory incoming/<hash>. VFS will create the directory <hash> if it doesn't already exist. After the file is uploaded I change the file permissions of directory <hash> using JSch. It works pretty smooth.