Skip to content

Commit

Permalink
Merge pull request #9602 from wseyler/SP-6596(9.3)
Browse files Browse the repository at this point in the history
[SP-6596] - Backport of PDI-20160 - Cannot extract files from SFTP se…
  • Loading branch information
smmribeiro authored Sep 19, 2024
2 parents c75544e + 9eee375 commit 500775e
Showing 1 changed file with 64 additions and 38 deletions.
102 changes: 64 additions & 38 deletions engine/src/main/java/org/pentaho/di/job/entries/sftp/SFTPClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,9 @@ public class SFTPClient {
/**
* Init Helper Class with connection settings
*
* @param serverIP
* IP address of remote server
* @param serverPort
* port of remote server
* @param userName
* username of remote server
* @param serverIP IP address of remote server
* @param serverPort port of remote server
* @param userName username of remote server
* @throws KettleJobException
*/
public SFTPClient( InetAddress serverIP, int serverPort, String userName ) throws KettleJobException {
Expand All @@ -100,37 +97,29 @@ public SFTPClient( InetAddress serverIP, int serverPort, String userName ) throw
/**
* Init Helper Class with connection settings
*
* @param serverIP
* IP address of remote server
* @param serverPort
* port of remote server
* @param userName
* username of remote server
* @param privateKeyFilename
* filename of private key
* @param serverIP IP address of remote server
* @param serverPort port of remote server
* @param userName username of remote server
* @param privateKeyFilename filename of private key
* @throws KettleJobException
*/
public SFTPClient( InetAddress serverIP, int serverPort, String userName, String privateKeyFilename ) throws KettleJobException {
public SFTPClient( InetAddress serverIP, int serverPort, String userName, String privateKeyFilename )
throws KettleJobException {
this( serverIP, serverPort, userName, privateKeyFilename, null );
}

/**
* Init Helper Class with connection settings
*
* @param serverIP
* IP address of remote server
* @param serverPort
* port of remote server
* @param userName
* username of remote server
* @param privateKeyFilename
* filename of private key
* @param passPhrase
* passphrase
* @param serverIP IP address of remote server
* @param serverPort port of remote server
* @param userName username of remote server
* @param privateKeyFilename filename of private key
* @param passPhrase passphrase
* @throws KettleJobException
*/
public SFTPClient( InetAddress serverIP, int serverPort, String userName, String privateKeyFilename,
String passPhrase ) throws KettleJobException {
String passPhrase ) throws KettleJobException {

if ( serverIP == null || serverPort <= 0 || userName == null || userName.equals( "" ) ) {
throw new KettleJobException(
Expand All @@ -153,7 +142,7 @@ public SFTPClient( InetAddress serverIP, int serverPort, String userName, String
this.passphrase = passPhrase;
passPhraseBytes = getPrivateKeyPassPhrase().getBytes();
} else {
passPhraseBytes = new byte[0];
passPhraseBytes = new byte[ 0 ];
}
jsch.addIdentity( getUserName(), getFileContent( prvkey ), null, passPhraseBytes );
}
Expand All @@ -174,9 +163,35 @@ private static byte[] getFileContent( String vfsFileName ) throws KettleFileExce

public void login( String password ) throws KettleJobException {
this.password = password;
// up to a total of 6 seconds delay max per connection attempt
int maxConnectionAttempts = 62;
int delayBetweenEachAttempts = 100; // milliseconds

while ( true ) {
try {
if ( tryCreateNewConnection( ) ) {
break;
}

session.setPassword( this.getPassword() );
if ( --maxConnectionAttempts <= 0 ) {
throw new KettleJobException( "Max connection attempts reached" );
}
Thread.sleep( delayBetweenEachAttempts );
// incrementing delay by 100 milliseconds
delayBetweenEachAttempts += 100;

} catch ( InterruptedException ex ) {
Thread.currentThread().interrupt();
throw new KettleJobException( "Interrupted during a retry ", ex );
} catch ( Exception e ) {
throw new KettleJobException( "An unexpected error has occurred ", e );
}
}
}

private boolean tryCreateNewConnection( ) {
try {
session.setPassword( this.getPassword() );
java.util.Properties config = new java.util.Properties();
config.put( "StrictHostKeyChecking", "no" );
// set compression property
Expand All @@ -186,13 +201,24 @@ public void login( String password ) throws KettleJobException {
config.put( COMPRESSION_S2C, compress );
config.put( COMPRESSION_C2S, compress );
}
config.put( "ConnectTimeout", "30000" );
config.put( "SocketTimeout", "30000" );
session.setConfig( config );
session.connect();

if ( !session.isConnected() ) {
session.setTimeout( 30000 );
session.setServerAliveInterval( 15000 );
session.connect();
}

Channel sftpChannel = session.openChannel( "sftp" );
sftpChannel.connect();
this.channel = (ChannelSftp) sftpChannel;

return true;
} catch ( JSchException e ) {
throw new KettleJobException( e );
System.err.println( "Initial connection attempt failed: " + e.getMessage() );
return false;
}
}

Expand All @@ -206,24 +232,23 @@ public void chdir( String dirToChangeTo ) throws KettleJobException {
}

/**
*
* @return Files in current directory
* @throws KettleJobException
*/
public String[] dir() throws KettleJobException {
try {
Vector<ChannelSftp.LsEntry> entries = channel.ls( "." );
if (entries == null) {
if ( entries == null ) {
return null;
}

List<String> files = entries.stream()
.filter( lse -> lse != null && !lse.getAttrs().isDir() )
.map( ChannelSftp.LsEntry::getFilename )
.collect( Collectors.toList() );
.filter( lse -> lse != null && !lse.getAttrs().isDir() )
.map( ChannelSftp.LsEntry::getFilename )
.collect( Collectors.toList() );

// uses depend on being null when empty
return files.isEmpty() ? null : files.toArray( new String[files.size()] );
return files.isEmpty() ? null : files.toArray( new String[ files.size() ] );

} catch ( SftpException e ) {
throw new KettleJobException( e );
Expand All @@ -245,10 +270,10 @@ public void get( FileObject localFile, String remoteFile ) throws KettleJobExcep
}

/**
* @deprecated use {@link #get(FileObject, String)}
* @param localFilePath
* @param remoteFile
* @throws KettleJobException
* @deprecated use {@link #get(FileObject, String)}
*/
@Deprecated
public void get( String localFilePath, String remoteFile ) throws KettleJobException {
Expand Down Expand Up @@ -389,7 +414,8 @@ public boolean folderExists( String foldername ) {
return retval;
}

public void setProxy( String host, String port, String user, String pass, String proxyType ) throws KettleJobException {
public void setProxy( String host, String port, String user, String pass, String proxyType )
throws KettleJobException {

if ( Utils.isEmpty( host ) || Const.toInt( port, 0 ) == 0 ) {
throw new KettleJobException( "Proxy server name must be set and server port must be greater than zero." );
Expand Down

0 comments on commit 500775e

Please sign in to comment.