@Signature public Memory stat(Environment env, String path) throws SftpException { try { SftpATTRS attrs = getWrappedObject().stat(path); return ArrayMemory.ofNullableBean(env, attrs); } catch (SftpException e) { if ("2: No such file".equals(e.toString())) { return Memory.NULL; } throw e; } }
public boolean folderExists( String foldername ) { boolean retval = false; try { SftpATTRS attrs = c.stat( foldername ); if ( attrs == null ) { return false; } if ( ( attrs.getFlags() & SftpATTRS.SSH_FILEXFER_ATTR_PERMISSIONS ) == 0 ) { throw new KettleJobException( "Unknown permissions error" ); } retval = attrs.isDir(); } catch ( Exception e ) { // Folder can not be found! } return retval; }
@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. }
try { channel.stat(remoteDirectory);
@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. }
public FileType getFileType( String filename ) throws KettleJobException { try { SftpATTRS attrs = c.stat( filename ); if ( attrs == null ) { return FileType.IMAGINARY; } if ( ( attrs.getFlags() & SftpATTRS.SSH_FILEXFER_ATTR_PERMISSIONS ) == 0 ) { throw new KettleJobException( "Unknown permissions error" ); } if ( attrs.isDir() ) { return FileType.FOLDER; } else { return FileType.FILE; } } catch ( Exception e ) { throw new KettleJobException( e ); } }
@Test public void testEnsureDirectoryExistsAlreadyExisted() throws IOException, SftpException { final ProcessContext processContext = mock(ProcessContext.class); 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); // Dir existence check should be done by stat verify(channel).stat(eq("/dir1/dir2/dir3")); }
@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 testEnsureDirectoryExistsFailedToStat() 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_FAILURE, "Failure")); 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 determine if remote directory exists at /dir1/dir2/dir3 due to 4: Failure", e.getMessage()); } // Dir existence check should be done by stat verify(channel).stat(eq("/dir1/dir2/dir3")); }
@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 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. }
@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. }
@Override public FileStatus getFileStatus(Path path) throws IOException { ChannelSftp channelSftp = null; ChannelExec channelExec1 = null; ChannelExec channelExec2 = null; try { channelSftp = this.fsHelper.getSftpChannel(); SftpATTRS sftpAttrs = channelSftp.stat(HadoopUtils.toUriPath(path)); FsPermission permission = new FsPermission((short) sftpAttrs.getPermissions()); channelExec1 = this.fsHelper.getExecChannel("id " + sftpAttrs.getUId()); String userName = IOUtils.toString(channelExec1.getInputStream()); channelExec2 = this.fsHelper.getExecChannel("id " + sftpAttrs.getGId()); String groupName = IOUtils.toString(channelExec2.getInputStream()); FileStatus fs = new FileStatus(sftpAttrs.getSize(), sftpAttrs.isDir(), 1, 0l, sftpAttrs.getMTime(), sftpAttrs.getATime(), permission, StringUtils.trimToEmpty(userName), StringUtils.trimToEmpty(groupName), path); return fs; } catch (SftpException e) { throw new IOException(e); } finally { safeDisconnect(channelSftp); safeDisconnect(channelExec1); safeDisconnect(channelExec2); } }
public static boolean fileExists(RemoteFileTemplate<LsEntry> template, final String... fileNames) { if (template != null) { return template.execute(session -> { ChannelSftp channel = (ChannelSftp) session.getClientInstance(); for (int i = 0; i < fileNames.length; i++) { try { SftpATTRS stat = channel.stat("si.sftp.sample/" + fileNames[i]); if (stat == null) { System.out.println("stat returned null for " + fileNames[i]); return false; } } catch (SftpException e) { System.out.println("Remote file not present: " + e.getMessage() + ": " + fileNames[i]); return false; } } return true; }); } else { return false; } }
@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. }
protected RemoteFile fillInAttributes(String path) { try { SftpATTRS attributes = sftp.stat(path); return fillInAttributes(path, attributes); } catch (SftpException e) { return handleNoSuchFileException(path, e); } }
private void setPermissions(String path, int permissions) throws SftpException { if (permissions > -1) { SftpATTRS attrs = channel.stat(path); attrs.setPERMISSIONS(permissions); channel.setStat(path, attrs); } }
protected RemoteFile fillInAttributes(String path) { try { SftpATTRS attributes = sftp.stat(path); return fillInAttributes(path, attributes); } catch (SftpException e) { return handleNoSuchFileException(path, e); } }
@Test public void returnNullOnUnexistingFile() throws Exception { when(channel.stat(any())).thenThrow(new SftpException(SSH_FX_NO_SUCH_FILE, "No such file")); assertThat(client.getAttributes(path), is(nullValue())); }
public void chgrp(String path, int gid) throws SshException { try { SftpATTRS attrs = channel.stat(path); attrs.setUIDGID(attrs.getUId(), gid); channel.setStat(path, attrs); } catch (SftpException e) { throw new net.sf.sshapi.sftp.SftpException(e.id, e.getLocalizedMessage(), e); } }