All pastes #631459 Raw Edit

Unnamed

public text v1 · immutable
#631459 ·published 2007-07-23 23:50 UTC
rendered paste body
I am writing an ftp client that uploads a file to more than one 
(many) ftp servers simultaneously. I want to add some fault tolerance 
so that if one server goes offline during the transfer, the upload is 
completed to the running servers. I've tried to capture this 
situation by blocking packets (via iptables) on one ftp server, and 
seeing if it triggers a timeout condition/exception (from setting 
setSoTimeout) in the ftp client, but unfortuantley the connection 
only hangs. Note I am using rwinston's 
commons-net-ftp-2.0.0-SNAPSHOT.jar. The code below is a command line 
example of the ftp client. Any suggestions?

Thanks

import java.io.OutputStream;
import org.apache.commons.net.ftp.FTPClient;
public class FTPServer {
   boolean online = true;
   FTPClient client = null;
   String hostname = null;
   OutputStream os = null;
}

import java.io.FileInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;

import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPReply;


public class Fdb {
    public static final String USAGE =
       "Usage: Fdb <local file>\n" +
       "\nUploads local file to remote ftp servers in binary transfer mode.\n";

    public static void main(String[] args) {
       String[]    ftphost = { "filedb1.test", "filedb2.test"};
       FTPServer[] ftpsvr = new FTPServer[ftphost.length];
       File fl = null;
       FileInputStream is = null;

       if (args.length == 0) {
          System.out.println(USAGE);
          System.exit(-1);
       }

       try {
          fl = new File(args[0]);
          is = new FileInputStream(fl);
       } catch (Exception e) {
          System.exit(-1);
       }

       // data type initialization
       for (int i = 0; i < ftpsvr.length; ++i) {
          ftpsvr[i] = new FTPServer();
          ftpsvr[i].client = new FTPClient();
          ftpsvr[i].client.setConnectTimeout(1000); // one sec timeout
          try {
             ftpsvr[i].client.setSoTimeout(1000);
          } catch(Exception e) {}
          ftpsvr[i].client.addProtocolCommandListener(new PrintCommandListener(
                   new PrintWriter(System.out)));
          ftpsvr[i].hostname = ftphost[i];
       }

       // ftp connections
       for (int i = 0; i < ftpsvr.length; i++) {
          try {
             ftpsvr[i].client.connect(ftpsvr[i].hostname);

             if (FTPReply.isPositiveCompletion(ftpsvr[i].client.getReplyCode())) {
                System.out.println(ftpsvr[i].hostname + " ftp connection");
                ftpsvr[i].online = true;
                System.out.println(ftpsvr[i].hostname + " marked server online");
             } else {
                System.out.println(ftpsvr[i].hostname + " no ftp connection");
                System.out.println(ftpsvr[i].hostname + " marked server offline");
             }
          } catch (Exception e) {
             ftpsvr[i].online = false;
          }
       }

       // connection negotiation
       for (int i = 0; i < ftpsvr.length; i++) {
          if (ftpsvr[i].online) {
             ftpsvr[i].client.enterLocalPassiveMode();
             try {
                ftpsvr[i].client.login("ftp", "");
                ftpsvr[i].client.setFileType(FTPClient.BINARY_FILE_TYPE);
                ftpsvr[i].client.changeWorkingDirectory("/pub/incoming");

                // added random number for testing purposes
                ftpsvr[i].os = ftpsvr[i].client.storeFileStream((new Random()).nextInt(1000) + args[0]);
             } catch (java.io.IOException e) {
                ftpsvr[i].online = false;
             }
          }
       }

       // Writing input byte streams to ftp server destinations
       byte buf[] = new byte[8192];

       int bytesRead = 0;

       try {
          bytesRead = is.read(buf);
       } catch(Exception e) {}

       System.out.println("writing data");
       while (bytesRead != -1) {
          // write data out to ftp servers
          for (int i = 0; i < ftpsvr.length; i++) {
             try {
                if (ftpsvr[i].online) {
                   if (FTPReply.isPositivePreliminary(ftpsvr[i].client.getReplyCode())
                         && ftpsvr[i].os != null) {
                      System.out.print(".");
                      ftpsvr[i].os.write(buf, 0, bytesRead);
                   } else {
                      System.out.println("non - positive reply on " + ftpsvr[i].hostname);
                   }
                }
             } catch (Exception e1) {
                // here we're assuming any exception was generated by
                // an I/O fault related to writing to the ftp server,
                // thus the server is offline

                System.out.println("**FAULT writing to " + ftpsvr[i].hostname);
                ftpsvr[i].online = false;
             }
          }

          try {
             bytesRead = is.read(buf);
          } catch (Exception e) {}
       }

       System.out.println("done.");
       try {
          is.close();
       } catch (Exception e) {}

      for (int i = 0; i < ftpsvr.length; i++) {
         if (ftpsvr[i].online) {
            System.out.println("closing output stream " + ftpsvr[i].hostname);
            try {
               ftpsvr[i].os.close();
               ftpsvr[i].client.completePendingCommand();
               ftpsvr[i].client.logout();
               ftpsvr[i].client.disconnect();
            } catch (Exception e) {}
         }
      }
    }
}