org/objectweb/proactive/core/process/filetransfer/FileTransferWorkShop.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
00028  * 
00029  * ################################################################
00030  */ 
00031 package org.objectweb.proactive.core.process.filetransfer;
00032 
00033 import java.io.File;
00034 import java.io.Serializable;
00035 import java.util.ArrayList;
00036 import java.util.HashMap;
00037 import java.util.Iterator;
00038 
00039 import org.apache.log4j.Logger;
00040 import org.objectweb.proactive.core.util.log.Loggers;
00041 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00042 import org.objectweb.proactive.core.process.filetransfer.FileTransferDefinition.FileDescription;
00043 
00056 public class FileTransferWorkShop implements Serializable {
00057         private static final String PROCESSDEFAULT_KEYWORD = "processDefault";
00058     private static final String IMPLICIT_KEYWORD = "implicit";
00059     private static final String[] ALLOWED_COPY_PROTOCOLS = {
00060             PROCESSDEFAULT_KEYWORD, "scp", "unicore", "rcp", "nordugrid", "pftp"
00061         };
00062     private static final String[] URLPROTOCOLS = { "file://", "http://", "ftp://" };
00063     protected static Logger logger = ProActiveLogger.getLogger(Loggers.DEPLOYMENT_FILETRANSFER);
00064 
00065     /* Reference to filetransfer definitions */
00066     private HashMap<String, FileTransferDefinition> fileTransfers;
00067 
00068     /*Array with protocols to try*/
00069     private String[] copyProtocol;
00070     private String processDefault;
00071     private boolean isImplicit;
00072     public StructureInformation srcInfoParams;
00073     public StructureInformation dstInfoParams;
00074 
00080     public FileTransferWorkShop(String processDefault) {
00081         //Verification of ilegal name for processDefault=="processDefault"
00082         if ((processDefault == null) || (processDefault.length() <= 0) ||
00083                 processDefault.equalsIgnoreCase(PROCESSDEFAULT_KEYWORD)) {
00084             logger.error("Illegal processDefault value=" + processDefault +
00085                 " in " + this.getClass() + ". Falling back to dummy.");
00086             this.processDefault = "dummy";
00087         } else {
00088             this.processDefault = processDefault;
00089         }
00090 
00091         isImplicit = false;
00092         fileTransfers = new HashMap<String, FileTransferDefinition>();
00093         copyProtocol = new String[0];
00094         srcInfoParams = new StructureInformation();
00095         dstInfoParams = new StructureInformation();
00096     }
00097 
00098     public String toString() {
00099         StringBuilder sb = new StringBuilder();
00100 
00101         //Queue variables
00102         sb.append("isImplicit     = ").append(isImplicit).append("\n");
00103         sb.append("processDefault = ").append(processDefault).append("\n");
00104 
00105         //Copy Protocol
00106         sb.append("copyProtocols  = ");
00107         for (int i = 0; i < copyProtocol.length; i++)
00108             sb.append(copyProtocol[i]).append(",");
00109         sb.append("\n");
00110 
00111         //SrcInfo
00112         sb.append("Src Information Parameters\n");
00113         sb.append(srcInfoParams).append("\n");
00114 
00115         //DstInfo
00116         sb.append("Dst Information Parameters\n");
00117         sb.append(dstInfoParams).append("\n");
00118 
00119         //FileTransfers
00120         Iterator<String> it = fileTransfers.keySet().iterator();
00121         while (it.hasNext()) {
00122             FileTransferDefinition ft = fileTransfers.get(it.next());
00123 
00124             sb.append(ft.toString()).append("\n");
00125         }
00126 
00127         while ((sb.length() > 0) && (sb.charAt(sb.length() - 1) == '\n'))
00128             sb.deleteCharAt(sb.length() - 1);
00129 
00130         return sb.toString();
00131     }
00132 
00137     public synchronized void addFileTransfer(FileTransferDefinition ft) {
00138         if (ft == null) {
00139             return;
00140         }
00141         if (ft.getId().equalsIgnoreCase(IMPLICIT_KEYWORD)) {
00142             logger.warn("Warning, ignoring addFileTransfer with keyword id=" +
00143                 IMPLICIT_KEYWORD);
00144             return;
00145         }
00146 
00147         fileTransfers.put(ft.getId(), ft);
00148     }
00149 
00156     public void setFileTransferCopyProtocol(String copyProtocolString) {
00157         copyProtocol = copyProtocolString.split("\\s*,\\s*");
00158     }
00159 
00166     public CopyProtocol[] getCopyProtocols() {
00167         ArrayList<CopyProtocol> alist = new ArrayList<CopyProtocol>();
00168 
00169         StringBuilder skippedProtocols = new StringBuilder();
00170         for (int i = 0; i < copyProtocol.length; i++) {
00171             if (!isAllowedProtocol(copyProtocol[i])) {
00172                 skippedProtocols.append(copyProtocol[i]).append(" ");
00173                 continue;
00174             }
00175             alist.add(copyProtocolFactory(copyProtocol[i]));
00176         }
00177 
00178         if (skippedProtocols.length() > 0) {
00179             logger.warn("Unknown copyprotocols will be skipped:" +
00180                 skippedProtocols.toString());
00181         }
00182 
00183         //if no Protocol is defined use the default
00184         if (alist.size() <= 0) {
00185             if (logger.isDebugEnabled()) {
00186                 logger.debug("No CopyProtocols found, using default protocol:" +
00187                     processDefault);
00188             }
00189 
00190             alist.add(copyProtocolFactory(PROCESSDEFAULT_KEYWORD));
00191         }
00192 
00193         return alist.toArray(new CopyProtocol[0]);
00194     }
00195 
00212     public CopyProtocol copyProtocolFactory(String protocolname) {
00213         CopyProtocol cp;
00214 
00215         if (protocolname.equalsIgnoreCase("scp")) {
00216             cp = new SecureCopyProtocol(protocolname);
00217         } else if (protocolname.equalsIgnoreCase(PROCESSDEFAULT_KEYWORD)) {
00218             //Note: this will produce an infinit recursion if
00219             // processDefault==PROCESSDEFAULT_KEYWORD
00220             cp = copyProtocolFactory(processDefault); //cool recursive call
00221             cp.setDefaultProtocol(true);
00222             return cp;
00223         } else if (protocolname.equalsIgnoreCase("rcp")) {
00224             cp = new RemoteFileCopy(protocolname);
00225         } else {
00226             cp = new DummyCopyProtocol(protocolname); //pftp, unicore, nordugrid are created here
00227             return cp;
00228         }
00229 
00230         //Default values for almost all copy protocols (except dummies)
00231         cp.setFileTransferDefinitions(getAllFileTransferDefinitions());
00232         cp.setSrcInfo(srcInfoParams);
00233         cp.setDstInfo(dstInfoParams);
00234 
00235         return cp;
00236     }
00237 
00242     public synchronized FileTransferDefinition[] getAllFileTransferDefinitions() {
00243         ArrayList<FileTransferDefinition> ftList = new ArrayList<FileTransferDefinition>();
00244 
00245         Iterator<String> it = fileTransfers.keySet().iterator();
00246         while (it.hasNext()) {
00247             FileTransferDefinition ft = fileTransfers.get(it.next());
00248 
00249             ftList.add(ft);
00250         }
00251 
00252         return ftList.toArray(new FileTransferDefinition[0]);
00253     }
00254 
00260     public void setFileTransferStructureSrcInfo(String name, String value) {
00261         srcInfoParams.setInfoParameter(name, value);
00262     }
00263 
00269     public void setFileTransferStructureDstInfo(String name, String value) {
00270         dstInfoParams.setInfoParameter(name, value);
00271     }
00272 
00279     public boolean check() {
00280         FileTransferDefinition ft;
00281 
00282         if (fileTransfers.size() <= 0) {
00283             if (logger.isDebugEnabled()) {
00284                 logger.debug("No file transfer required.");
00285             }
00286             return false;
00287         }
00288 
00289         //Checking FileTransfer definitions
00290         boolean retval = false;
00291         Iterator<String> it = fileTransfers.keySet().iterator();
00292         while (it.hasNext()) {
00293             ft = fileTransfers.get(it.next());
00294             if (ft.isEmpty()) {
00295                 logger.warn("Warning: FileTransfer definition id=" +
00296                     ft.getId() + " is empty or undefined.");
00297                 continue;
00298             }
00299 
00300             //Obs: this might be a problem with Retrieve
00301             if (checkLocalFileExistance(ft)) {
00302                 retval = true; //At least one file to transfer
00303             }
00304         }
00305         return retval;
00306     }
00307 
00315     public boolean isImplicit() {
00316         return isImplicit;
00317     }
00318 
00319     public void setImplicit(boolean implicit) {
00320         this.isImplicit = implicit;
00321     }
00322 
00328     public boolean isAllowedProtocol(String protocol) {
00329         for (int i = 0; i < ALLOWED_COPY_PROTOCOLS.length; i++)
00330             if (ALLOWED_COPY_PROTOCOLS[i].equalsIgnoreCase(protocol)) {
00331                 return true;
00332             }
00333 
00334         return false;
00335     }
00336 
00342     public FileDescription[] getAllFileDescriptions(){
00343     
00344         ArrayList<FileDescription> fd = new ArrayList<FileDescription>();
00345 
00346         Iterator<String> it = fileTransfers.keySet().iterator();
00347         while (it.hasNext()) {
00348             FileTransferDefinition ft = fileTransfers.get(it.next());
00349             
00350             FileDescription fdesc[]=ft.getAllFiles();
00351             for(int i=0; i < fdesc.length ; i++)
00352                 fd.add(fdesc[i]);
00353         }
00354         
00355         return fd.toArray(new FileDescription[0]);
00356     }
00357     
00364     public String getAbsoluteSrcPath(FileDescription fileDesc) {
00365         return buildFilePathString(srcInfoParams.getPrefix(),
00366             srcInfoParams.getFileSeparator(), fileDesc.getSrcName());
00367     }
00368 
00369     public String getAbsoluteDstPath(FileDescription fileDesc) {
00370         return buildFilePathString(dstInfoParams.getPrefix(),
00371             dstInfoParams.getFileSeparator(), fileDesc.getDestName());
00372     }
00373     
00374     public static String buildFilePathString(StructureInformation infoParam,
00375         String filename) {
00376         return buildFilePathString(infoParam.getPrefix(),
00377             infoParam.getFileSeparator(), filename);
00378     }
00379 
00380     public static String buildFilePathString(String prefix, String fileSep,
00381         String filename) {
00382 
00383         /*
00384          *BORDER CONDITIONS
00385          */
00386         
00387         //Trim white spaces
00388         prefix = prefix.trim();
00389         fileSep = fileSep.trim();
00390         filename = filename.trim();
00391 
00392         //Asign a default filesep if needed
00393         if (fileSep.length() <= 0) {
00394             fileSep = "/";
00395         }
00396 
00397         //Remove trailing slash of filename if needed
00398         if (filename.endsWith(fileSep)) {
00399             filename.substring(0, filename.length() - 1);
00400         }
00401 
00402         //Remove trailing slash from prefix if needed
00403         if (prefix.endsWith(fileSep)) {
00404             prefix.substring(0, prefix.length() - 1);
00405         }
00406 
00407         /*
00408          * CASES EVALUATION
00409          */
00410 
00411         // -case1: filename starts from root path, nothing to do
00412         // -case2: filename starts with procol "http://", "ftp://", nothing to do
00413         // -case3: no prefix, nothing to do
00414         if ((filename.charAt(0) == fileSep.charAt(0)) ||
00415                 begginsWithProtocol(filename) || (prefix.length() <= 0)) {
00416             return filename;
00417         }
00418 
00419         //-case3: prefix is defined
00420         StringBuilder sb = new StringBuilder();
00421         sb.append(prefix).append(fileSep).append(filename);
00422         return sb.toString();
00423     }
00424 
00425     public static boolean begginsWithProtocol(String s) {
00426         for (int i = 0; i < URLPROTOCOLS.length; i++) {
00427             if (s.startsWith(URLPROTOCOLS[i])) {
00428                 return true;
00429             }
00430         }
00431 
00432         return false;
00433     }
00434 
00435     public boolean checkLocalFileExistance(FileTransferDefinition ft) {
00436         boolean atLeastOneFile = false;
00437 
00438         FileTransferDefinition.FileDescription[] files = ft.getAll();
00439 
00440         File f;
00441         String filefullname;
00442         for (int i = 0; i < files.length; i++) {
00443             filefullname = getAbsoluteSrcPath(files[i]);
00444 
00445             if (begginsWithProtocol(filefullname)) {
00446 
00447                 /* Can't yet check existance for http:// or ftp://
00448                  * Therefore, we suppose the file exists.
00449                  * But we can check: file://
00450                  */
00451                 if (!filefullname.startsWith("file://")) {
00452                     atLeastOneFile = true;
00453                     continue;
00454                 }
00455 
00456                 filefullname = stripProtocol(filefullname);
00457             }
00458 
00459             f = new File(filefullname);
00460 
00461             if (!f.exists()) {
00462                 logger.warn("Warning, nonexistent: " + filefullname);
00463             } else if (!f.canRead()) {
00464                 logger.warn("Warning, unreadble: " + filefullname);
00465             } else {
00466                 atLeastOneFile = true; //at least one dir is found
00467             }
00468 
00469             if (files[i].isDir() && !f.isDirectory()) {
00470                 logger.warn("Warning, not a directory: " + filefullname);
00471             }
00472         }
00473 
00474         return atLeastOneFile;
00475     }
00476 
00477     public static boolean isLocalReadable(String filenamepath) {
00478         if (begginsWithProtocol(filenamepath)) {
00479             if (!filenamepath.startsWith("file://")) {
00480                 return false;
00481             }
00482 
00483             filenamepath = stripProtocol(filenamepath);
00484         }
00485 
00486         File f = new File(filenamepath);
00487 
00488         return f.canRead();
00489     }
00490 
00491     public static boolean isRemote(String filenamepath) {
00492         if (begginsWithProtocol(filenamepath) &&
00493                 !filenamepath.startsWith("file://")) {
00494             return true;
00495         }
00496         return false;
00497     }
00498 
00499     public static String stripProtocol(String filename) {
00500         int i = filename.indexOf("://");
00501 
00502         if ((filename.length() - i - 3) > 0) {
00503             return filename.substring(i + 3);
00504         }
00505 
00506         return "";
00507     }
00508 
00509     public class StructureInformation implements Serializable {
00510 
00511         /* FileTransferQueue specific information */
00512         String prefix;
00513         String hostname;
00514         String username;
00515         String password;
00516         String fileSeparator;
00517 
00518         public StructureInformation() {
00519             prefix = "";
00520             hostname = "";
00521             username = "";
00522             password = "";
00523             fileSeparator = "/";
00524         }
00525 
00526         public void setInfoParameter(String name, String value) {
00527             if (name.equalsIgnoreCase("prefix")) {
00528                 value = value.trim();
00529                 //delete ending file separators
00530                 while ((value.length() > 0) &&
00531                         (value.endsWith("/") || value.endsWith("\\")))
00532                     value = value.substring(0, value.length() - 1);
00533 
00534                 if (value.length() > 0) {
00535                     prefix = value;
00536                 }
00537             } else if (name.equalsIgnoreCase("hostname")) {
00538                 hostname = value;
00539             } else if (name.equalsIgnoreCase("username")) {
00540                 username = value;
00541             } else if (name.equalsIgnoreCase("password")) {
00542                 password = value;
00543             } else if (name.equalsIgnoreCase("fileseparator")) {
00544                 fileSeparator = value;
00545             } else {
00546                 logger.warn("Skipping:" + name + "=" + value +
00547                     ". Unknown FileTransfer information parameter.");
00548             }
00549         }
00550 
00551         public String toString() {
00552             StringBuilder sb = new StringBuilder();
00553 
00554             sb.append("prefix        = ").append(prefix).append("\n");
00555             sb.append("hostname      = ").append(hostname).append("\n");
00556             sb.append("username      = ").append(username).append("\n");
00557             sb.append("password      = ").append(password).append("\n");
00558             sb.append("fileSeparator = ").append(fileSeparator);
00559 
00560             return sb.toString();
00561         }
00562 
00566         public String getFileSeparator() {
00567             return fileSeparator;
00568         }
00569 
00573         public void setFileSeparator(String fileSeparator) {
00574             this.fileSeparator = fileSeparator;
00575         }
00576 
00580         public String getPrefix() {
00581             return prefix;
00582         }
00583 
00587         public void setPrefix(String prefix) {
00588             this.prefix = prefix;
00589         }
00590 
00594         public String getHostname() {
00595             return hostname;
00596         }
00597 
00601         public String getUsername() {
00602             return username;
00603         }
00604 
00608         public void setHostname(String hostname) {
00609             this.hostname = hostname;
00610         }
00611 
00615         public void setUsername(String username) {
00616             this.username = username;
00617         }
00618     }
00619 }

Generated on Mon Jan 22 15:16:08 2007 for ProActive by  doxygen 1.5.1