@Override public boolean mkdir(String dir) { try { this.channel.mkdir(dir); return true; } catch (SftpException e) { throw new JschRuntimeException(e); } }
@Override public boolean mkdir(String dir) { try { this.channel.mkdir(dir); return true; } catch (SftpException e) { throw new JschRuntimeException(e); } }
/** * Creates the given folder. The {@param path} can be either absolute or relative. * Allows creation of nested folders. */ public void createFolder( String path ) throws KettleJobException { try { String[] folders = path.split( "/" ); folders[ 0 ] = ( path.charAt( 0 ) != '/' ? pwd() + "/" : "" ) + folders[ 0 ]; for ( int i = 1; i < folders.length; i++ ) { folders[ i ] = folders[ i - 1 ] + "/" + folders[ i ]; } for ( String f : folders ) { if ( f.length() != 0 && !folderExists( f ) ) { c.mkdir( f ); } } } catch ( ArrayIndexOutOfBoundsException e ) { throw new KettleJobException( e ); } catch ( SftpException e ) { throw new KettleJobException( e ); } }
logger.debug(proc + " creating new directory and changing to it " + dirName); try { sftp.mkdir(dirName); sftp.cd(dirName); } catch (final SftpException e) {
/** * Create a folder with nested folders under the current user's home. */ @Test public void folderCreation_Relative_Nested() throws Exception { System.setProperty( SFTPClient.ENV_PARAM_USERAUTH_GSSAPI, "yes" ); SFTPClient client = spy( new SFTPClient( server, port, username ) { @Override JSch createJSch() { return jSch; } } ); doReturn( "/home/admin" ).when( client ).pwd(); client.login( password ); client.createFolder( "myfolder/subfolder/finalfolder" ); verify( channel, times( 3 ) ).mkdir( anyString() ); verify( channel, times( 1 ) ).mkdir( "/home/admin/myfolder" ); verify( channel, times( 1 ) ).mkdir( "/home/admin/myfolder/subfolder" ); verify( channel, times( 1 ) ).mkdir( "/home/admin/myfolder/subfolder/finalfolder" ); }
/** * Create a folder with nested folders under an existing folder given an absolute path. */ @Test public void folderCreation_Absolute_Nested() throws Exception { System.setProperty( SFTPClient.ENV_PARAM_USERAUTH_GSSAPI, "yes" ); SFTPClient client = spy( new SFTPClient( server, port, username ) { @Override JSch createJSch() { return jSch; } } ); doReturn( true ).when( client ).folderExists( "/var" ); doReturn( true ).when( client ).folderExists( "/var/ftproot" ); client.login( password ); client.createFolder( "/var/ftproot/myfolder/subfolder/finalfolder" ); verify( channel, times( 3 ) ).mkdir( anyString() ); verify( channel, times( 1 ) ).mkdir( "/var/ftproot/myfolder" ); verify( channel, times( 1 ) ).mkdir( "/var/ftproot/myfolder/subfolder" ); verify( channel, times( 1 ) ).mkdir( "/var/ftproot/myfolder/subfolder/finalfolder" ); } }
/** * Create a folder under the current user's home. */ @Test public void folderCreation_Relative_Simple() throws Exception { System.setProperty( SFTPClient.ENV_PARAM_USERAUTH_GSSAPI, "yes" ); SFTPClient client = spy( new SFTPClient( server, port, username ) { @Override JSch createJSch() { return jSch; } } ); doReturn( "/home/admin" ).when( client ).pwd(); client.login( password ); client.createFolder( "myfolder" ); verify( channel, times( 1 ) ).mkdir( anyString() ); verify( channel, times( 1 ) ).mkdir( "/home/admin/myfolder" ); }
final String previousCwd = client.pwd(); client.cd(parentDir); client.mkdir(pathName); client.cd(previousCwd); } catch (SftpException e) {
/** * Create a folder under an existing folder given an absolute path. */ @Test public void folderCreation_Absolute_Simple() throws Exception { System.setProperty( SFTPClient.ENV_PARAM_USERAUTH_GSSAPI, "yes" ); SFTPClient client = spy( new SFTPClient( server, port, username ) { @Override JSch createJSch() { return jSch; } } ); doReturn( true ).when( client ).folderExists( "/var" ); doReturn( true ).when( client ).folderExists( "/var/ftproot" ); client.login( password ); client.createFolder( "/var/ftproot/myfolder" ); verify( channel, times( 1 ) ).mkdir( anyString() ); verify( channel, times( 1 ) ).mkdir( "/var/ftproot/myfolder" ); }
@Override public boolean mkdirs(Path path, FsPermission permission) throws IOException { ChannelSftp channel = null; try { channel = this.fsHelper.getSftpChannel(); channel.mkdir(HadoopUtils.toUriPath(path)); channel.chmod(permission.toShort(), HadoopUtils.toUriPath(path)); } catch (SftpException e) { throw new IOException(e); } finally { safeDisconnect(channel); } return true; }
/** * Create a folder under an existing folder given an absolute path. * The specified folder ends with a slash. */ @Test public void folderCreation_Absolute_TrailingSlash() throws Exception { System.setProperty( SFTPClient.ENV_PARAM_USERAUTH_GSSAPI, "yes" ); SFTPClient client = spy( new SFTPClient( server, port, username ) { @Override JSch createJSch() { return jSch; } } ); doReturn( true ).when( client ).folderExists( "/var" ); doReturn( true ).when( client ).folderExists( "/var/ftproot" ); client.login( password ); client.createFolder( "/var/ftproot/myfolder/" ); verify( channel, times( 1 ) ).mkdir( anyString() ); verify( channel, times( 1 ) ).mkdir( "/var/ftproot/myfolder" ); }
@Test public void testEnsureDirectoryExistsBlindlyAlreadyExisted() throws IOException, SftpException { final ProcessContext processContext = mock(ProcessContext.class); when(processContext.getProperty(SFTPTransfer.DISABLE_DIRECTORY_LISTING)).thenReturn(new MockPropertyValue("true")); final ChannelSftp channel = mock(ChannelSftp.class); // If the dir existed, a failure exception is thrown, but should be swallowed. doThrow(new SftpException(SSH_FX_FAILURE, "Failure")).when(channel).mkdir(eq("/dir1/dir2/dir3")); final SFTPTransfer sftpTransfer = createSftpTransfer(processContext, channel); final MockFlowFile flowFile = new MockFlowFile(0); final File remoteDir = new File("/dir1/dir2/dir3"); sftpTransfer.ensureDirectoryExists(flowFile, remoteDir); // stat should not be called. verify(channel, times(0)).stat(eq("/dir1/dir2/dir3")); verify(channel).mkdir(eq("/dir1/dir2/dir3")); // dir3 was created blindly. }
@Test public void testEnsureDirectoryExistsBlindlyNotExisted() throws IOException, SftpException { final ProcessContext processContext = mock(ProcessContext.class); when(processContext.getProperty(SFTPTransfer.DISABLE_DIRECTORY_LISTING)).thenReturn(new MockPropertyValue("true")); final ChannelSftp channel = mock(ChannelSftp.class); final SFTPTransfer sftpTransfer = createSftpTransfer(processContext, channel); final MockFlowFile flowFile = new MockFlowFile(0); final File remoteDir = new File("/dir1/dir2/dir3"); sftpTransfer.ensureDirectoryExists(flowFile, remoteDir); // stat should not be called. verify(channel, times(0)).stat(eq("/dir1/dir2/dir3")); verify(channel).mkdir(eq("/dir1/dir2/dir3")); // dir3 was created blindly. }
@Test public void testEnsureDirectoryExistsParentNotExisted() throws IOException, SftpException { final ProcessContext processContext = mock(ProcessContext.class); final ChannelSftp channel = mock(ChannelSftp.class); // stat for the dir1 was successful, simulating that dir1 exists, but no dir2 and dir3. when(channel.stat("/dir1/dir2/dir3")).thenThrow(new SftpException(SSH_FX_NO_SUCH_FILE, "No such file")); when(channel.stat("/dir1/dir2")).thenThrow(new SftpException(SSH_FX_NO_SUCH_FILE, "No such file")); final SFTPTransfer sftpTransfer = createSftpTransfer(processContext, channel); final MockFlowFile flowFile = new MockFlowFile(0); final File remoteDir = new File("/dir1/dir2/dir3"); sftpTransfer.ensureDirectoryExists(flowFile, remoteDir); // Dir existence check should be done by stat verify(channel).stat(eq("/dir1/dir2/dir3")); // dir3 was not found verify(channel).stat(eq("/dir1/dir2")); // dir2 was not found, too verify(channel).stat(eq("/dir1")); // dir1 was found verify(channel).mkdir(eq("/dir1/dir2")); // dir1 existed, so dir2 was created. verify(channel).mkdir(eq("/dir1/dir2/dir3")); // then dir3 was created. }
@Test public void testEnsureDirectoryExistsBlindlyParentNotExisted() throws IOException, SftpException { final ProcessContext processContext = mock(ProcessContext.class); when(processContext.getProperty(SFTPTransfer.DISABLE_DIRECTORY_LISTING)).thenReturn(new MockPropertyValue("true")); final ChannelSftp channel = mock(ChannelSftp.class); final AtomicInteger mkdirCount = new AtomicInteger(0); doAnswer(invocation -> { final int cnt = mkdirCount.getAndIncrement(); if (cnt == 0) { // If the parent dir does not exist, no such file exception is thrown. throw new SftpException(SSH_FX_NO_SUCH_FILE, "Failure"); } else { logger.info("Created the dir successfully for the 2nd time"); } return true; }).when(channel).mkdir(eq("/dir1/dir2/dir3")); final SFTPTransfer sftpTransfer = createSftpTransfer(processContext, channel); final MockFlowFile flowFile = new MockFlowFile(0); final File remoteDir = new File("/dir1/dir2/dir3"); sftpTransfer.ensureDirectoryExists(flowFile, remoteDir); // stat should not be called. verify(channel, times(0)).stat(eq("/dir1/dir2/dir3")); // dir3 was created blindly, but failed for the 1st time, and succeeded for the 2nd time. verify(channel, times(2)).mkdir(eq("/dir1/dir2/dir3")); verify(channel).mkdir(eq("/dir1/dir2")); // dir2 was created successfully. }
@Test public void testEnsureDirectoryExistsBlindlyFailed() throws IOException, SftpException { final ProcessContext processContext = mock(ProcessContext.class); when(processContext.getProperty(SFTPTransfer.DISABLE_DIRECTORY_LISTING)).thenReturn(new MockPropertyValue("true")); final ChannelSftp channel = mock(ChannelSftp.class); doThrow(new SftpException(SSH_FX_PERMISSION_DENIED, "Permission denied")).when(channel).mkdir(eq("/dir1/dir2/dir3")); final SFTPTransfer sftpTransfer = createSftpTransfer(processContext, channel); final MockFlowFile flowFile = new MockFlowFile(0); final File remoteDir = new File("/dir1/dir2/dir3"); try { sftpTransfer.ensureDirectoryExists(flowFile, remoteDir); fail("Should fail"); } catch (IOException e) { assertEquals("Could not blindly create remote directory due to Permission denied", e.getMessage()); } // stat should not be called. verify(channel, times(0)).stat(eq("/dir1/dir2/dir3")); verify(channel).mkdir(eq("/dir1/dir2/dir3")); // dir3 was created blindly. }
@Test public void testEnsureDirectoryExistsNotExisted() throws IOException, SftpException { final ProcessContext processContext = mock(ProcessContext.class); final ChannelSftp channel = mock(ChannelSftp.class); // stat for the parent was successful, simulating that dir2 exists, but no dir3. when(channel.stat("/dir1/dir2/dir3")).thenThrow(new SftpException(SSH_FX_NO_SUCH_FILE, "No such file")); final SFTPTransfer sftpTransfer = createSftpTransfer(processContext, channel); final MockFlowFile flowFile = new MockFlowFile(0); final File remoteDir = new File("/dir1/dir2/dir3"); sftpTransfer.ensureDirectoryExists(flowFile, remoteDir); // Dir existence check should be done by stat verify(channel).stat(eq("/dir1/dir2/dir3")); // dir3 was not found verify(channel).stat(eq("/dir1/dir2")); // so, dir2 was checked verify(channel).mkdir(eq("/dir1/dir2/dir3")); // dir2 existed, so dir3 was created. }
@Test public void testEnsureDirectoryExistsNotExistedFailedToCreate() throws IOException, SftpException { final ProcessContext processContext = mock(ProcessContext.class); final ChannelSftp channel = mock(ChannelSftp.class); // stat for the parent was successful, simulating that dir2 exists, but no dir3. when(channel.stat("/dir1/dir2/dir3")).thenThrow(new SftpException(SSH_FX_NO_SUCH_FILE, "No such file")); // Failed to create dir3. doThrow(new SftpException(SSH_FX_FAILURE, "Failed")).when(channel).mkdir(eq("/dir1/dir2/dir3")); final SFTPTransfer sftpTransfer = createSftpTransfer(processContext, channel); final MockFlowFile flowFile = new MockFlowFile(0); final File remoteDir = new File("/dir1/dir2/dir3"); try { sftpTransfer.ensureDirectoryExists(flowFile, remoteDir); fail("Should fail"); } catch (IOException e) { assertEquals("Failed to create remote directory /dir1/dir2/dir3 due to 4: Failed", e.getMessage()); } // Dir existence check should be done by stat verify(channel).stat(eq("/dir1/dir2/dir3")); // dir3 was not found verify(channel).stat(eq("/dir1/dir2")); // so, dir2 was checked verify(channel).mkdir(eq("/dir1/dir2/dir3")); // dir2 existed, so dir3 was created. }
@Override public void mkdir(String path) throws IOException { map(() -> { ftp.mkdir(path); return null; }); }