/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2017 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package org.pentaho.di.job.entries.ftpdelete;
import org.pentaho.di.job.entry.validator.AndValidator;
import org.pentaho.di.job.entry.validator.JobEntryValidatorUtils;
import java.io.File;
import java.net.InetAddress;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.pentaho.di.cluster.SlaveServer;
import org.pentaho.di.core.CheckResultInterface;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.util.Utils;
import org.pentaho.di.core.Result;
import org.pentaho.di.core.RowMetaAndData;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.encryption.Encr;
import org.pentaho.di.core.exception.KettleDatabaseException;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleXMLException;
import org.pentaho.di.core.variables.VariableSpace;
import org.pentaho.di.core.xml.XMLHandler;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.job.JobMeta;
import org.pentaho.di.job.entries.ftpsget.FTPSConnection;
import org.pentaho.di.job.entries.sftp.SFTPClient;
import org.pentaho.di.job.entry.JobEntryBase;
import org.pentaho.di.job.entry.JobEntryInterface;
import org.pentaho.di.repository.ObjectId;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.resource.ResourceEntry;
import org.pentaho.di.resource.ResourceEntry.ResourceType;
import org.pentaho.di.resource.ResourceReference;
import org.pentaho.metastore.api.IMetaStore;
import org.w3c.dom.Node;
import com.enterprisedt.net.ftp.FTPClient;
import com.enterprisedt.net.ftp.FTPConnectMode;
import com.enterprisedt.net.ftp.FTPException;
import com.trilead.ssh2.Connection;
import com.trilead.ssh2.HTTPProxyData;
import com.trilead.ssh2.SFTPv3Client;
import com.trilead.ssh2.SFTPv3DirectoryEntry;
/**
* This defines an FTP job entry.
*
* @author Matt
* @since 05-11-2003
*
*/
public class JobEntryFTPDelete extends JobEntryBase implements Cloneable, JobEntryInterface {
private static Class<?> PKG = JobEntryFTPDelete.class; // for i18n purposes, needed by Translator2!!
private String serverName;
private String port;
private String userName;
private String password;
private String ftpDirectory;
private String wildcard;
private int timeout;
private boolean activeConnection;
private boolean publicpublickey;
private String keyFilename;
private String keyFilePass;
private boolean useproxy;
private String proxyHost;
private String proxyPort; /* string to allow variable substitution */
private String proxyUsername;
private String proxyPassword;
private String socksProxyHost;
private String socksProxyPort;
private String socksProxyUsername;
private String socksProxyPassword;
private String protocol;
public static final String PROTOCOL_FTP = "FTP";
public static final String PROTOCOL_FTPS = "FTPS";
public static final String PROTOCOL_SFTP = "SFTP";
public static final String PROTOCOL_SSH = "SSH";
public String SUCCESS_IF_AT_LEAST_X_FILES_DOWNLOADED = "success_when_at_least";
public String SUCCESS_IF_ERRORS_LESS = "success_if_errors_less";
public String SUCCESS_IF_ALL_FILES_DOWNLOADED = "success_is_all_files_downloaded";
private String nr_limit_success;
private String success_condition;
private boolean copyprevious;
private int FTPSConnectionType;
long NrErrors = 0;
long NrfilesDeleted = 0;
boolean successConditionBroken = false;
String targetFilename = null;
int limitFiles = 0;
FTPClient ftpclient = null;
FTPSConnection ftpsclient = null;
SFTPClient sftpclient = null;
SFTPv3Client sshclient = null;
public JobEntryFTPDelete( String n ) {
super( n, "" );
copyprevious = false;
protocol = PROTOCOL_FTP;
port = "21";
socksProxyPort = "1080";
nr_limit_success = "10";
success_condition = SUCCESS_IF_ALL_FILES_DOWNLOADED;
publicpublickey = false;
keyFilename = null;
keyFilePass = null;
serverName = null;
FTPSConnectionType = FTPSConnection.CONNECTION_TYPE_FTP;
}
public JobEntryFTPDelete() {
this( "" );
}
public Object clone() {
JobEntryFTPDelete je = (JobEntryFTPDelete) super.clone();
return je;
}
public String getXML() {
StringBuilder retval = new StringBuilder( 550 ); // 448 characters in spaces and tag names alone
retval.append( super.getXML() );
retval.append( " " ).append( XMLHandler.addTagValue( "protocol", protocol ) );
retval.append( " " ).append( XMLHandler.addTagValue( "servername", serverName ) );
retval.append( " " ).append( XMLHandler.addTagValue( "port", port ) );
retval.append( " " ).append( XMLHandler.addTagValue( "username", userName ) );
retval.append( " " ).append(
XMLHandler.addTagValue( "password", Encr.encryptPasswordIfNotUsingVariables( getPassword() ) ) );
retval.append( " " ).append( XMLHandler.addTagValue( "ftpdirectory", ftpDirectory ) );
retval.append( " " ).append( XMLHandler.addTagValue( "wildcard", wildcard ) );
retval.append( " " ).append( XMLHandler.addTagValue( "timeout", timeout ) );
retval.append( " " ).append( XMLHandler.addTagValue( "active", activeConnection ) );
retval.append( " " ).append( XMLHandler.addTagValue( "useproxy", useproxy ) );
retval.append( " " ).append( XMLHandler.addTagValue( "proxy_host", proxyHost ) );
retval.append( " " ).append( XMLHandler.addTagValue( "proxy_port", proxyPort ) );
retval.append( " " ).append( XMLHandler.addTagValue( "proxy_username", proxyUsername ) );
retval.append( " " ).append(
XMLHandler.addTagValue( "proxy_password", Encr.encryptPasswordIfNotUsingVariables( proxyPassword ) ) );
retval.append( " " ).append( XMLHandler.addTagValue( "publicpublickey", publicpublickey ) );
retval.append( " " ).append( XMLHandler.addTagValue( "keyfilename", keyFilename ) );
retval.append( " " ).append( XMLHandler.addTagValue( "keyfilepass", keyFilePass ) );
retval.append( " " ).append( XMLHandler.addTagValue( "nr_limit_success", nr_limit_success ) );
retval.append( " " ).append( XMLHandler.addTagValue( "success_condition", success_condition ) );
retval.append( " " ).append( XMLHandler.addTagValue( "copyprevious", copyprevious ) );
retval.append( " " ).append(
XMLHandler
.addTagValue( "ftps_connection_type", FTPSConnection.getConnectionTypeCode( FTPSConnectionType ) ) );
retval.append( " " ).append( XMLHandler.addTagValue( "socksproxy_host", socksProxyHost ) );
retval.append( " " ).append( XMLHandler.addTagValue( "socksproxy_port", socksProxyPort ) );
retval.append( " " ).append( XMLHandler.addTagValue( "socksproxy_username", socksProxyUsername ) );
retval.append( " " ).append(
XMLHandler.addTagValue( "socksproxy_password", Encr
.encryptPasswordIfNotUsingVariables( getSocksProxyPassword() ) ) );
return retval.toString();
}
public void loadXML( Node entrynode, List<DatabaseMeta> databases, List<SlaveServer> slaveServers,
Repository rep, IMetaStore metaStore ) throws KettleXMLException {
try {
super.loadXML( entrynode, databases, slaveServers );
protocol = XMLHandler.getTagValue( entrynode, "protocol" );
port = XMLHandler.getTagValue( entrynode, "port" );
serverName = XMLHandler.getTagValue( entrynode, "servername" );
userName = XMLHandler.getTagValue( entrynode, "username" );
password = Encr.decryptPasswordOptionallyEncrypted( XMLHandler.getTagValue( entrynode, "password" ) );
ftpDirectory = XMLHandler.getTagValue( entrynode, "ftpdirectory" );
wildcard = XMLHandler.getTagValue( entrynode, "wildcard" );
timeout = Const.toInt( XMLHandler.getTagValue( entrynode, "timeout" ), 10000 );
activeConnection = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "active" ) );
useproxy = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "useproxy" ) );
proxyHost = XMLHandler.getTagValue( entrynode, "proxy_host" );
proxyPort = XMLHandler.getTagValue( entrynode, "proxy_port" );
proxyUsername = XMLHandler.getTagValue( entrynode, "proxy_username" );
proxyPassword =
Encr.decryptPasswordOptionallyEncrypted( XMLHandler.getTagValue( entrynode, "proxy_password" ) );
publicpublickey = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "publicpublickey" ) );
keyFilename = XMLHandler.getTagValue( entrynode, "keyfilename" );
keyFilePass = XMLHandler.getTagValue( entrynode, "keyfilepass" );
nr_limit_success = XMLHandler.getTagValue( entrynode, "nr_limit_success" );
success_condition = XMLHandler.getTagValue( entrynode, "success_condition" );
copyprevious = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "copyprevious" ) );
FTPSConnectionType =
FTPSConnection.getConnectionTypeByCode( Const.NVL( XMLHandler.getTagValue(
entrynode, "ftps_connection_type" ), "" ) );
socksProxyHost = XMLHandler.getTagValue( entrynode, "socksproxy_host" );
socksProxyPort = XMLHandler.getTagValue( entrynode, "socksproxy_port" );
socksProxyUsername = XMLHandler.getTagValue( entrynode, "socksproxy_username" );
socksProxyPassword =
Encr.decryptPasswordOptionallyEncrypted( XMLHandler.getTagValue( entrynode, "socksproxy_password" ) );
} catch ( KettleXMLException xe ) {
throw new KettleXMLException( "Unable to load job entry of type 'ftp' from XML node", xe );
}
}
public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,
List<SlaveServer> slaveServers ) throws KettleException {
try {
protocol = rep.getJobEntryAttributeString( id_jobentry, "protocol" );
port = rep.getJobEntryAttributeString( id_jobentry, "port" );
serverName = rep.getJobEntryAttributeString( id_jobentry, "servername" );
userName = rep.getJobEntryAttributeString( id_jobentry, "username" );
password =
Encr.decryptPasswordOptionallyEncrypted( rep.getJobEntryAttributeString( id_jobentry, "password" ) );
ftpDirectory = rep.getJobEntryAttributeString( id_jobentry, "ftpdirectory" );
wildcard = rep.getJobEntryAttributeString( id_jobentry, "wildcard" );
timeout = (int) rep.getJobEntryAttributeInteger( id_jobentry, "timeout" );
activeConnection = rep.getJobEntryAttributeBoolean( id_jobentry, "active" );
copyprevious = rep.getJobEntryAttributeBoolean( id_jobentry, "copyprevious" );
useproxy = rep.getJobEntryAttributeBoolean( id_jobentry, "useproxy" );
proxyHost = rep.getJobEntryAttributeString( id_jobentry, "proxy_host" );
proxyPort = rep.getJobEntryAttributeString( id_jobentry, "proxy_port" );
proxyUsername = rep.getJobEntryAttributeString( id_jobentry, "proxy_username" );
proxyPassword =
Encr
.decryptPasswordOptionallyEncrypted( rep.getJobEntryAttributeString( id_jobentry, "proxy_password" ) );
publicpublickey = rep.getJobEntryAttributeBoolean( id_jobentry, "publicpublickey" );
keyFilename = rep.getJobEntryAttributeString( id_jobentry, "keyfilename" );
keyFilePass = rep.getJobEntryAttributeString( id_jobentry, "keyfilepass" );
nr_limit_success = rep.getJobEntryAttributeString( id_jobentry, "nr_limit_success" );
success_condition = rep.getJobEntryAttributeString( id_jobentry, "success_condition" );
FTPSConnectionType =
FTPSConnection.getConnectionTypeByCode( Const.NVL( rep.getJobEntryAttributeString(
id_jobentry, "ftps_connection_type" ), "" ) );
socksProxyHost = rep.getJobEntryAttributeString( id_jobentry, "socksproxy_host" );
socksProxyPort = rep.getJobEntryAttributeString( id_jobentry, "socksproxy_port" );
socksProxyUsername = rep.getJobEntryAttributeString( id_jobentry, "socksproxy_username" );
socksProxyPassword =
Encr.decryptPasswordOptionallyEncrypted( rep.getJobEntryAttributeString(
id_jobentry, "socksproxy_password" ) );
} catch ( KettleException dbe ) {
throw new KettleException( "Unable to load job entry of type 'ftp' from the repository for id_jobentry="
+ id_jobentry, dbe );
}
}
public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_job ) throws KettleException {
try {
rep.saveJobEntryAttribute( id_job, getObjectId(), "protocol", protocol );
rep.saveJobEntryAttribute( id_job, getObjectId(), "port", port );
rep.saveJobEntryAttribute( id_job, getObjectId(), "servername", serverName );
rep.saveJobEntryAttribute( id_job, getObjectId(), "username", userName );
rep.saveJobEntryAttribute( id_job, getObjectId(), "password", Encr
.encryptPasswordIfNotUsingVariables( password ) );
rep.saveJobEntryAttribute( id_job, getObjectId(), "ftpdirectory", ftpDirectory );
rep.saveJobEntryAttribute( id_job, getObjectId(), "wildcard", wildcard );
rep.saveJobEntryAttribute( id_job, getObjectId(), "timeout", timeout );
rep.saveJobEntryAttribute( id_job, getObjectId(), "active", activeConnection );
rep.saveJobEntryAttribute( id_job, getObjectId(), "copyprevious", copyprevious );
rep.saveJobEntryAttribute( id_job, getObjectId(), "useproxy", useproxy );
rep.saveJobEntryAttribute( id_job, getObjectId(), "publicpublickey", publicpublickey );
rep.saveJobEntryAttribute( id_job, getObjectId(), "keyfilename", keyFilename );
rep.saveJobEntryAttribute( id_job, getObjectId(), "keyfilepass", keyFilePass );
rep.saveJobEntryAttribute( id_job, getObjectId(), "proxy_host", proxyHost );
rep.saveJobEntryAttribute( id_job, getObjectId(), "proxy_port", proxyPort );
rep.saveJobEntryAttribute( id_job, getObjectId(), "proxy_username", proxyUsername );
rep.saveJobEntryAttribute( id_job, getObjectId(), "proxy_password", Encr
.encryptPasswordIfNotUsingVariables( proxyPassword ) );
rep.saveJobEntryAttribute( id_job, getObjectId(), "nr_limit_success", nr_limit_success );
rep.saveJobEntryAttribute( id_job, getObjectId(), "success_condition", success_condition );
rep.saveJobEntryAttribute( id_job, getObjectId(), "ftps_connection_type", FTPSConnection
.getConnectionType( FTPSConnectionType ) );
rep.saveJobEntryAttribute( id_job, getObjectId(), "socksproxy_host", socksProxyHost );
rep.saveJobEntryAttribute( id_job, getObjectId(), "socksproxy_port", socksProxyPort );
rep.saveJobEntryAttribute( id_job, getObjectId(), "socksproxy_username", socksProxyUsername );
rep.saveJobEntryAttribute( id_job, getObjectId(), "socksproxy_password", Encr
.encryptPasswordIfNotUsingVariables( socksProxyPassword ) );
} catch ( KettleDatabaseException dbe ) {
throw new KettleException(
"Unable to save job entry of type 'ftp' to the repository for id_job=" + id_job, dbe );
}
}
private boolean getStatus() {
boolean retval = false;
if ( ( NrErrors == 0 && getSuccessCondition().equals( SUCCESS_IF_ALL_FILES_DOWNLOADED ) )
|| ( NrfilesDeleted >= limitFiles && getSuccessCondition().equals( SUCCESS_IF_AT_LEAST_X_FILES_DOWNLOADED ) )
|| ( NrErrors <= limitFiles && getSuccessCondition().equals( SUCCESS_IF_ERRORS_LESS ) ) ) {
retval = true;
}
return retval;
}
public boolean isCopyPrevious() {
return copyprevious;
}
public void setCopyPrevious( boolean copyprevious ) {
this.copyprevious = copyprevious;
}
/**
* @param publickey
* The publicpublickey to set.
*/
public void setUsePublicKey( boolean publickey ) {
this.publicpublickey = publickey;
}
/**
* @return Returns the use public key.
*/
public boolean isUsePublicKey() {
return publicpublickey;
}
/**
* @param keyfilename
* The key filename to set.
*/
public void setKeyFilename( String keyfilename ) {
this.keyFilename = keyfilename;
}
/**
* @return Returns the key filename.
*/
public String getKeyFilename() {
return keyFilename;
}
/**
* @param keyFilePass
* The key file pass to set.
*/
public void setKeyFilePass( String keyFilePass ) {
this.keyFilePass = keyFilePass;
}
/**
* @return Returns the key file pass.
*/
public String getKeyFilePass() {
return keyFilePass;
}
/**
* @return the connection type
*/
public int getFTPSConnectionType() {
return FTPSConnectionType;
}
/**
* @param connectionType
* the connectionType to set
*/
public void setFTPSConnectionType( int type ) {
FTPSConnectionType = type;
}
public void setLimitSuccess( String nr_limit_successin ) {
this.nr_limit_success = nr_limit_successin;
}
public String getLimitSuccess() {
return nr_limit_success;
}
public void setSuccessCondition( String success_condition ) {
this.success_condition = success_condition;
}
public String getSuccessCondition() {
return success_condition;
}
/**
* @return Returns the directory.
*/
public String getFtpDirectory() {
return ftpDirectory;
}
/**
* @param directory
* The directory to set.
*/
public void setFtpDirectory( String directory ) {
this.ftpDirectory = directory;
}
/**
* @return Returns the password.
*/
public String getPassword() {
return password;
}
/**
* @param password
* The password to set.
*/
public void setPassword( String password ) {
this.password = password;
}
/**
* @return Returns the serverName.
*/
public String getServerName() {
return serverName;
}
/**
* @param serverName
* The serverName to set.
*/
public void setServerName( String serverName ) {
this.serverName = serverName;
}
public void setProtocol( String protocol ) {
this.protocol = protocol;
}
public String getProtocol() {
return protocol;
}
/**
* @return Returns the userName.
*/
public String getUserName() {
return userName;
}
/**
* @param userName
* The userName to set.
*/
public void setUserName( String userName ) {
this.userName = userName;
}
/**
* @return Returns the wildcard.
*/
public String getWildcard() {
return wildcard;
}
/**
* @param wildcard
* The wildcard to set.
*/
public void setWildcard( String wildcard ) {
this.wildcard = wildcard;
}
/**
* @param timeout
* The timeout to set.
*/
public void setTimeout( int timeout ) {
this.timeout = timeout;
}
/**
* @return Returns the timeout.
*/
public int getTimeout() {
return timeout;
}
/**
* @return Returns the hostname of the ftp-proxy.
*/
public String getProxyHost() {
return proxyHost;
}
/**
* @param proxyHost
* The hostname of the proxy.
*/
public void setProxyHost( String proxyHost ) {
this.proxyHost = proxyHost;
}
public boolean isUseProxy() {
return useproxy;
}
public void setUseProxy( boolean useproxy ) {
this.useproxy = useproxy;
}
/**
* @return Returns the password which is used to authenticate at the proxy.
*/
public String getProxyPassword() {
return proxyPassword;
}
/**
* @param proxyPassword
* The password which is used to authenticate at the proxy.
*/
public void setProxyPassword( String proxyPassword ) {
this.proxyPassword = proxyPassword;
}
/**
* @return Returns the port of the ftp.
*/
public String getPort() {
return port;
}
/**
* @param proxyPort
* The port of the ftp.
*/
public void setPort( String port ) {
this.port = port;
}
/**
* @return Returns the port of the ftp-proxy.
*/
public String getProxyPort() {
return proxyPort;
}
/**
* @param proxyPort
* The port of the ftp-proxy.
*/
public void setProxyPort( String proxyPort ) {
this.proxyPort = proxyPort;
}
/**
* @return Returns the username which is used to authenticate at the proxy.
*/
public String getProxyUsername() {
return proxyUsername;
}
/**
* @param proxyUsername
* The username which is used to authenticate at the proxy.
*/
public void setProxyUsername( String proxyUsername ) {
this.proxyUsername = proxyUsername;
}
/** Needed for the Vector coming from sshclient.ls() *
*/
@SuppressWarnings( "unchecked" )
public Result execute( Result previousResult, int nr ) {
log.logBasic( BaseMessages.getString( PKG, "JobEntryFTPDelete.Started", serverName ) );
RowMetaAndData resultRow = null;
Result result = previousResult;
List<RowMetaAndData> rows = result.getRows();
result.setResult( false );
NrErrors = 0;
NrfilesDeleted = 0;
successConditionBroken = false;
HashSet<String> list_previous_files = new HashSet<>();
// Here let's put some controls before stating the job
String realservername = environmentSubstitute( serverName );
String realserverpassword = Utils.resolvePassword( this, password );
String realFtpDirectory = environmentSubstitute( ftpDirectory );
int realserverport = Const.toInt( environmentSubstitute( port ), 0 );
String realUsername = environmentSubstitute( userName );
String realPassword = Utils.resolvePassword( this, password );
String realproxyhost = environmentSubstitute( proxyHost );
String realproxyusername = environmentSubstitute( proxyUsername );
String realproxypassword = Utils.resolvePassword( this, proxyPassword );
int realproxyport = Const.toInt( environmentSubstitute( proxyPort ), 0 );
String realkeyFilename = environmentSubstitute( keyFilename );
String realkeyPass = environmentSubstitute( keyFilePass );
// PDI The following is used to apply a path for SSH because the SFTPv3Client doesn't let us specify/change dirs
String sourceFolder = "";
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.Start" ) );
}
if ( copyprevious && rows.size() == 0 ) {
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.ArgsFromPreviousNothing" ) );
}
result.setResult( true );
return result;
}
try {
// Get all the files in the current directory...
String[] filelist = null;
if ( protocol.equals( PROTOCOL_FTP ) ) {
// If socks proxy server was provided
if ( !Utils.isEmpty( socksProxyHost ) ) {
if ( !Utils.isEmpty( socksProxyPort ) ) {
FTPClient.initSOCKS( environmentSubstitute( socksProxyPort ), environmentSubstitute( socksProxyHost ) );
} else {
throw new FTPException( BaseMessages.getString(
PKG, "JobEntryFTPDelete.SocksProxy.PortMissingException", environmentSubstitute( socksProxyHost ),
getName() ) );
}
// then if we have authentication information
if ( !Utils.isEmpty( socksProxyUsername ) && !Utils.isEmpty( socksProxyPassword ) ) {
FTPClient.initSOCKSAuthentication(
environmentSubstitute( socksProxyUsername ), Utils.resolvePassword( this, socksProxyPassword ) );
} else if ( !Utils.isEmpty( socksProxyUsername )
&& Utils.isEmpty( socksProxyPassword ) || Utils.isEmpty( socksProxyUsername )
&& !Utils.isEmpty( socksProxyPassword ) ) {
// we have a username without a password or vica versa
throw new FTPException( BaseMessages.getString(
PKG, "JobEntryFTPDelete.SocksProxy.IncompleteCredentials",
environmentSubstitute( socksProxyHost ), getName() ) );
}
}
// establish the connection
FTPConnect(
realservername, realUsername, realPassword, realserverport, realFtpDirectory, realproxyhost,
realproxyusername, realproxypassword, realproxyport, timeout );
filelist = ftpclient.dir();
// Some FTP servers return a message saying no files found as a string in the filenlist
// e.g. Solaris 8
// CHECK THIS !!!
if ( filelist.length == 1 ) {
String translatedWildcard = environmentSubstitute( wildcard );
if ( !Utils.isEmpty( translatedWildcard ) ) {
if ( filelist[0].startsWith( translatedWildcard ) ) {
throw new FTPException( filelist[0] );
}
}
}
} else if ( protocol.equals( PROTOCOL_FTPS ) ) {
// establish the secure connection
FTPSConnect( realservername, realUsername, realserverport, realPassword, realFtpDirectory, timeout );
// Get all the files in the current directory...
filelist = ftpsclient.getFileNames();
} else if ( protocol.equals( PROTOCOL_SFTP ) ) {
// establish the secure connection
SFTPConnect( realservername, realUsername, realserverport, realPassword, realFtpDirectory );
// Get all the files in the current directory...
filelist = sftpclient.dir();
} else if ( protocol.equals( PROTOCOL_SSH ) ) {
// establish the secure connection
SSHConnect(
realservername, realserverpassword, realserverport, realUsername, realPassword, realproxyhost,
realproxyusername, realproxypassword, realproxyport, realkeyFilename, realkeyPass );
sourceFolder = ".";
if ( realFtpDirectory != null ) {
sourceFolder = realFtpDirectory + "/";
} else {
sourceFolder = "./";
}
// NOTE: Source of the unchecked warning suppression for the declaration of this method.
Vector<SFTPv3DirectoryEntry> vfilelist = sshclient.ls( sourceFolder );
if ( vfilelist != null ) {
// Make one pass through the vfilelist to get an accurate count
// Using the two-pass method with arrays is faster than using ArrayList
int fileCount = 0;
Iterator<SFTPv3DirectoryEntry> iterator = vfilelist.iterator();
while ( iterator.hasNext() ) {
SFTPv3DirectoryEntry dirEntry = iterator.next();
if ( dirEntry != null
&& !dirEntry.filename.equals( "." ) && !dirEntry.filename.equals( ".." )
&& !isDirectory( sshclient, sourceFolder + dirEntry.filename ) ) {
fileCount++;
}
}
// Now that we have the correct count, create and fill in the array
filelist = new String[fileCount];
iterator = vfilelist.iterator();
int i = 0;
while ( iterator.hasNext() ) {
SFTPv3DirectoryEntry dirEntry = iterator.next();
if ( dirEntry != null
&& !dirEntry.filename.equals( "." ) && !dirEntry.filename.equals( ".." )
&& !isDirectory( sshclient, sourceFolder + dirEntry.filename ) ) {
filelist[i] = dirEntry.filename;
i++;
}
}
}
}
if ( isDetailed() ) {
logDetailed( "JobEntryFTPDelete.FoundNFiles", String.valueOf( filelist.length ) );
}
int found = filelist == null ? 0 : filelist.length;
if ( found == 0 ) {
result.setResult( true );
return result;
}
Pattern pattern = null;
if ( copyprevious ) {
// Copy the input row to the (command line) arguments
for ( int iteration = 0; iteration < rows.size(); iteration++ ) {
resultRow = rows.get( iteration );
// Get file names
String file_previous = resultRow.getString( 0, null );
if ( !Utils.isEmpty( file_previous ) ) {
list_previous_files.add( file_previous );
}
}
} else {
if ( !Utils.isEmpty( wildcard ) ) {
String realWildcard = environmentSubstitute( wildcard );
pattern = Pattern.compile( realWildcard );
}
}
if ( !getSuccessCondition().equals( SUCCESS_IF_ALL_FILES_DOWNLOADED ) ) {
limitFiles = Const.toInt( environmentSubstitute( getLimitSuccess() ), 10 );
}
// Get the files in the list...
for ( int i = 0; i < filelist.length && !parentJob.isStopped(); i++ ) {
if ( successConditionBroken ) {
throw new Exception( BaseMessages.getString( PKG, "JobEntryFTPDelete.SuccesConditionBroken" ) );
}
boolean getIt = false;
if ( isDebug() ) {
logDebug( BaseMessages.getString( PKG, "JobEntryFTPDelete.AnalysingFile", filelist[i] ) );
}
try {
// First see if the file matches the regular expression!
if ( copyprevious ) {
if ( list_previous_files.contains( filelist[i] ) ) {
getIt = true;
}
} else {
if ( pattern != null ) {
Matcher matcher = pattern.matcher( filelist[i] );
getIt = matcher.matches();
}
}
if ( getIt ) {
// Delete file
if ( protocol.equals( PROTOCOL_FTP ) ) {
ftpclient.delete( filelist[i] );
}
if ( protocol.equals( PROTOCOL_FTPS ) ) {
// System.out.println( "---------------" + filelist[i] );
ftpsclient.deleteFile( filelist[i] );
} else if ( protocol.equals( PROTOCOL_SFTP ) ) {
sftpclient.delete( filelist[i] );
} else if ( protocol.equals( PROTOCOL_SSH ) ) {
sshclient.rm( sourceFolder + filelist[i] );
}
if ( isDetailed() ) {
logDetailed( "JobEntryFTPDelete.RemotefileDeleted", filelist[i] );
}
updateDeletedFiles();
}
} catch ( Exception e ) {
// Update errors number
updateErrors();
logError( BaseMessages.getString( PKG, "JobFTP.UnexpectedError", e.getMessage() ) );
if ( successConditionBroken ) {
throw new Exception( BaseMessages.getString( PKG, "JobEntryFTPDelete.SuccesConditionBroken" ) );
}
}
} // end for
} catch ( Exception e ) {
updateErrors();
logError( BaseMessages.getString( PKG, "JobEntryFTPDelete.ErrorGetting", e.getMessage() ) );
logError( Const.getStackTracker( e ) );
} finally {
if ( ftpclient != null && ftpclient.connected() ) {
try {
ftpclient.quit();
ftpclient = null;
} catch ( Exception e ) {
logError( BaseMessages.getString( PKG, "JobEntryFTPDelete.ErrorQuitting", e.getMessage() ) );
}
}
if ( ftpsclient != null ) {
try {
ftpsclient.disconnect();
} catch ( Exception e ) {
logError( BaseMessages.getString( PKG, "JobEntryFTPDelete.ErrorQuitting", e.getMessage() ) );
}
}
if ( sftpclient != null ) {
try {
sftpclient.disconnect();
sftpclient = null;
} catch ( Exception e ) {
logError( BaseMessages.getString( PKG, "JobEntryFTPDelete.ErrorQuitting", e.getMessage() ) );
}
}
if ( sshclient != null ) {
try {
sshclient.close();
sshclient = null;
} catch ( Exception e ) {
logError( BaseMessages.getString( PKG, "JobEntryFTPDelete.ErrorQuitting", e.getMessage() ) );
}
}
FTPClient.clearSOCKS();
}
result.setResult( !successConditionBroken );
result.setNrFilesRetrieved( NrfilesDeleted );
result.setNrErrors( NrErrors );
return result;
}
/**
* Checks if file is a directory
*
* @param sftpClient
* @param filename
* @return true, if filename is a directory
*/
public boolean isDirectory( SFTPv3Client sftpClient, String filename ) {
try {
return sftpClient.stat( filename ).isDirectory();
} catch ( Exception e ) {
// Ignore FTP errors
}
return false;
}
private void SSHConnect( String realservername, String realserverpassword, int realserverport,
String realUsername, String realPassword, String realproxyhost, String realproxyusername,
String realproxypassword, int realproxyport, String realkeyFilename, String realkeyPass ) throws Exception {
/* Create a connection instance */
Connection conn = new Connection( realservername, realserverport );
/* We want to connect through a HTTP proxy */
if ( useproxy ) {
conn.setProxyData( new HTTPProxyData( realproxyhost, realproxyport ) );
/* Now connect */
// if the proxy requires basic authentication:
if ( !Utils.isEmpty( realproxyusername ) || !Utils.isEmpty( realproxypassword ) ) {
conn
.setProxyData( new HTTPProxyData( realproxyhost, realproxyport, realproxyusername, realproxypassword ) );
}
}
if ( timeout > 0 ) {
// Use timeout
conn.connect( null, 0, timeout * 1000 );
} else {
// Cache Host Key
conn.connect();
}
// Authenticate
boolean isAuthenticated = false;
if ( publicpublickey ) {
isAuthenticated = conn.authenticateWithPublicKey( realUsername, new File( realkeyFilename ), realkeyPass );
} else {
isAuthenticated = conn.authenticateWithPassword( realUsername, realserverpassword );
}
if ( !isAuthenticated ) {
throw new Exception( "Can not connect to " );
}
sshclient = new SFTPv3Client( conn );
}
private void SFTPConnect( String realservername, String realusername, int realport, String realpassword,
String realFTPDirectory ) throws Exception {
// Create sftp client to host ...
sftpclient = new SFTPClient( InetAddress.getByName( realservername ), realport, realusername );
// login to ftp host ...
sftpclient.login( realpassword );
// move to spool dir ...
if ( !Utils.isEmpty( realFTPDirectory ) ) {
sftpclient.chdir( realFTPDirectory );
if ( isDetailed() ) {
logDetailed( "Changed to directory [" + realFTPDirectory + "]" );
}
}
}
private void FTPSConnect( String realservername, String realusername, int realport, String realpassword,
String realFTPDirectory, int realtimeout ) throws Exception {
// Create ftps client to host ...
ftpsclient =
new FTPSConnection( getFTPSConnectionType(), realservername, realport, realusername, realpassword );
if ( !Utils.isEmpty( proxyHost ) ) {
String realProxy_host = environmentSubstitute( proxyHost );
String realProxy_username = environmentSubstitute( proxyUsername );
String realProxy_password = Utils.resolvePassword( this, proxyPassword );
ftpsclient.setProxyHost( realProxy_host );
if ( !Utils.isEmpty( realProxy_username ) ) {
ftpsclient.setProxyUser( realProxy_username );
}
if ( !Utils.isEmpty( realProxy_password ) ) {
ftpsclient.setProxyPassword( realProxy_password );
}
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.OpenedProxyConnectionOn", realProxy_host ) );
}
int proxyport = Const.toInt( environmentSubstitute( proxyPort ), 21 );
if ( proxyport != 0 ) {
ftpsclient.setProxyPort( proxyport );
}
} else {
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.OpenedConnectionTo", realservername ) );
}
}
// set activeConnection connectmode ...
if ( activeConnection ) {
ftpsclient.setPassiveMode( false );
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.SetActive" ) );
}
} else {
ftpsclient.setPassiveMode( true );
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.SetPassive" ) );
}
}
// Set the timeout
ftpsclient.setTimeOut( realtimeout );
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.SetTimeout", String.valueOf( realtimeout ) ) );
}
// now connect
ftpsclient.connect();
// move to spool dir ...
if ( !Utils.isEmpty( realFTPDirectory ) ) {
ftpsclient.changeDirectory( realFTPDirectory );
if ( isDetailed() ) {
logDetailed( "Changed to directory [" + realFTPDirectory + "]" );
}
}
}
private void FTPConnect( String realServername, String realusername, String realpassword, int realport,
String realFtpDirectory, String realProxyhost, String realproxyusername, String realproxypassword,
int realproxyport, int realtimeout ) throws Exception {
// Create ftp client to host:port ...
ftpclient = new FTPClient();
ftpclient.setRemoteAddr( InetAddress.getByName( realServername ) );
if ( realport != 0 ) {
ftpclient.setRemotePort( realport );
}
if ( !Utils.isEmpty( realProxyhost ) ) {
ftpclient.setRemoteAddr( InetAddress.getByName( realProxyhost ) );
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.OpenedProxyConnectionOn", realProxyhost ) );
}
// FIXME: Proper default port for proxy
if ( realproxyport != 0 ) {
ftpclient.setRemotePort( realproxyport );
}
} else {
ftpclient.setRemoteAddr( InetAddress.getByName( realServername ) );
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.OpenedConnectionTo", realServername ) );
}
}
// set activeConnection connectmode ...
if ( activeConnection ) {
ftpclient.setConnectMode( FTPConnectMode.ACTIVE );
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.SetActive" ) );
}
} else {
ftpclient.setConnectMode( FTPConnectMode.PASV );
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.SetPassive" ) );
}
}
// Set the timeout
ftpclient.setTimeout( realtimeout );
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.SetTimeout", String.valueOf( realtimeout ) ) );
}
// login to ftp host ...
ftpclient.connect();
String realUsername =
realusername
+ ( !Utils.isEmpty( realProxyhost ) ? "@" + realServername : "" )
+ ( !Utils.isEmpty( realproxyusername ) ? " " + realproxyusername : "" );
String realPassword = realpassword + ( !Utils.isEmpty( realproxypassword ) ? " " + realproxypassword : "" );
ftpclient.login( realUsername, realPassword );
// Remove password from logging, you don't know where it ends up.
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.LoggedIn", realUsername ) );
}
// move to spool dir ...
if ( !Utils.isEmpty( realFtpDirectory ) ) {
ftpclient.chdir( realFtpDirectory );
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "JobEntryFTPDelete.ChangedDir", realFtpDirectory ) );
}
}
}
private void updateErrors() {
NrErrors++;
if ( !getStatus() ) {
// Success condition was broken
successConditionBroken = true;
}
}
private void updateDeletedFiles() {
NrfilesDeleted++;
}
public boolean evaluates() {
return true;
}
/**
* @return the activeConnection
*/
public boolean isActiveConnection() {
return activeConnection;
}
/**
* @param activeConnection
* the activeConnection to set
*/
public void setActiveConnection( boolean passive ) {
this.activeConnection = passive;
}
public void check( List<CheckResultInterface> remarks, JobMeta jobMeta, VariableSpace space,
Repository repository, IMetaStore metaStore ) {
JobEntryValidatorUtils.andValidator().validate( this, "serverName", remarks, AndValidator.putValidators( JobEntryValidatorUtils.notBlankValidator() ) );
JobEntryValidatorUtils.andValidator().validate(
this, "targetDirectory", remarks, AndValidator.putValidators(
JobEntryValidatorUtils.notBlankValidator(), JobEntryValidatorUtils.fileExistsValidator() ) );
JobEntryValidatorUtils.andValidator().validate( this, "userName", remarks, AndValidator.putValidators( JobEntryValidatorUtils.notBlankValidator() ) );
JobEntryValidatorUtils.andValidator().validate( this, "password", remarks, AndValidator.putValidators( JobEntryValidatorUtils.notNullValidator() ) );
}
public List<ResourceReference> getResourceDependencies( JobMeta jobMeta ) {
List<ResourceReference> references = super.getResourceDependencies( jobMeta );
if ( !Utils.isEmpty( serverName ) ) {
String realServername = jobMeta.environmentSubstitute( serverName );
ResourceReference reference = new ResourceReference( this );
reference.getEntries().add( new ResourceEntry( realServername, ResourceType.SERVER ) );
references.add( reference );
}
return references;
}
/**
* @return Socks proxy host
*/
public String getSocksProxyHost() {
return this.socksProxyHost;
}
/**
* @return Socks proxy port
*/
public String getSocksProxyPort() {
return this.socksProxyPort;
}
/**
* @return Socks proxy username
*/
public String getSocksProxyUsername() {
return this.socksProxyUsername;
}
/**
* @return Socks proxy username
*/
public String getSocksProxyPassword() {
return this.socksProxyPassword;
}
/**
* @return Sets socks proxy host
*/
public void setSocksProxyHost( String socksProxyHost ) {
this.socksProxyHost = socksProxyHost;
}
/**
* @return Sets socks proxy port
*/
public void setSocksProxyPort( String socksProxyPort ) {
this.socksProxyPort = socksProxyPort;
}
/**
* @return Sets socks proxy username
*/
public void setSocksProxyUsername( String socksProxyUsername ) {
this.socksProxyUsername = socksProxyUsername;
}
/**
* @return Sets socks proxy username
*/
public void setSocksProxyPassword( String socksProxyPassword ) {
this.socksProxyPassword = socksProxyPassword;
}
}