001 /* 002 * $RCSFile$ 003 * 004 * Created on July 12, 2002, 11:29 AM 005 * 006 * This file is part of the STAR Scheduler. 007 * Copyright (c) 2002-2006 STAR Collaboration - Brookhaven National Laboratory 008 * 009 * STAR Scheduler is free software; you can redistribute it and/or modify 010 * it under the terms of the GNU General Public License as published by 011 * the Free Software Foundation; either version 2 of the License, or 012 * (at your option) any later version. 013 * 014 * STAR Scheduler is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public License 020 * along with STAR Scheduler; if not, write to the Free Software 021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 022 */ 023 package gov.bnl.star.offline.scheduler.initializer; 024 025 import gov.bnl.star.offline.scheduler.*; 026 import gov.bnl.star.offline.scheduler.request.Request; 027 import gov.bnl.star.offline.scheduler.request.RequestFactory; 028 029 import gov.bnl.star.offline.scheduler.util.FilesystemToolkit; 030 import gov.bnl.star.offline.scheduler.util.ConfigToolkit; 031 import gov.bnl.star.offline.scheduler.util.ThreadSafeFilesystemToolkit; 032 033 034 import java.io.*; 035 import java.io.File; 036 import java.net.URI; 037 038 import java.net.URL; 039 import java.util.*; 040 import java.util.ArrayList; 041 042 import java.util.logging.Level; 043 import org.apache.log4j.Logger; 044 045 046 /** Example class to test the scheduler. 047 * 048 * @author Gabriele Carcassi / Levente Hajdu 049 * @version $Revision: 1.23 $ $Date: 2006/11/21 00:41:35 $ 050 */ 051 public class XMLInitializer implements JobInitializer { 052 static private Logger log = Logger.getLogger(XMLInitializer.class.getName()); 053 054 /** Holds value of property defaultFileListSyntax. */ 055 private String defaultFileListSyntax; 056 057 /** Creates a new instance of SimpleInitializer */ 058 public XMLInitializer() { } 059 060 ThreadSafeFilesystemToolkit threadSafeFilesystemToolkit = new ThreadSafeFilesystemToolkit(); 061 062 private Map prepareDefaults() { 063 Map defaults = new Hashtable(); 064 if (defaultFileListSyntax != null) 065 defaults.put("fileListSyntax", defaultFileListSyntax); 066 return defaults; 067 } 068 069 public Request[] analizeRequest(String xmlFileName) { 070 071 log.info("Analyzing the request using XMLInitializer: " + 072 xmlFileName); 073 log.info("Parsing the XML file " + xmlFileName); 074 System.out.print("Reading request description file : " + xmlFileName); 075 076 Request[] requests; 077 078 try { 079 Map defaults = prepareDefaults(); 080 RequestFactory.setDefaults(defaults); 081 Request request = RequestFactory.parseXML(xmlFileName); 082 requests = new Request[] {request}; 083 } catch (Exception e) { 084 log.fatal("Parsing failed !", e); 085 System.out.println("There was an error processing the request XML file."); 086 throw new RuntimeException(e.getMessage()); 087 } 088 089 090 log.debug("Check current scheduling limitations"); 091 092 093 if(! ConfigToolkit.getToolkit().isFlagSet("SUMS_FLAG_IGNORE_ERRORS")){ 094 095 for (int nRequest = 0; nRequest < requests.length; nRequest++) { 096 if (!validateRequest(requests[nRequest])) { 097 throw new RuntimeException("Since the job description wasn't valid, no jobs will be submitted\n" + 098 "Note: If you believe your job to be valid you can suppress most scheduler errors with the \"-u ie\" option. Example: star-submit -u ie myjob.xml"); 099 } 100 } 101 102 } 103 104 return requests; 105 } 106 107 boolean validateRequest(Request request) { 108 boolean valid = true; 109 110 // Check whether input file exists 111 //if ((request.getStdIn() != null) && !FilesystemToolkit.checkIfFileExists(request.getStdIn(), false)) { //replaced for a thread safe version 112 if ((request.getStdIn() != null) && !threadSafeFilesystemToolkit.threadSafeCheckIfFileExists(request.getStdIn(), false)) { 113 valid = false; 114 log.warn("The file for stdin doesn't exist. Stdin was '" + request.getStdIn() + "'"); 115 System.out.println("The file for stdin doesn't exist. Stdin was '" + request.getStdIn() + "'"); 116 } 117 118 // Check whether output and error directory exists 119 //if ((request.getStdOut() != null) && !FilesystemToolkit.checkIfDirExists(request.getStdOut(), false)) { //replaced for a thread safe version 120 if ((request.getStdOut() != null) && !threadSafeFilesystemToolkit.threadSafeCheckIfDirExists(request.getStdOut(), false)) { 121 valid = false; 122 log.warn("The directory for stdout doesn't exist. Stdout was '" + request.getStdOut() + "'"); 123 System.out.println( "The directory for stdout doesn't exist. Stdout was '" + request.getStdOut() + "'"); 124 } 125 126 //if ((request.getStdErr() != null) && !FilesystemToolkit.checkIfDirExists(request.getStdErr(), false)) { //replaced for a thread safe version 127 if ((request.getStdErr() != null) && !threadSafeFilesystemToolkit.threadSafeCheckIfDirExists(request.getStdErr(), false)) { 128 valid = false; 129 log.warn("The directory for stderr doesn't exist. Stderr was '" + request.getStdErr() + "'"); 130 System.out.println("The directory for stderr doesn't exist. Stderr was '" + request.getStdErr() + "'"); 131 } 132 133 // Check whether specified input files exist 134 if(checkIfFilesExistLocally){ 135 for (int nFile = 0; nFile < request.getInputList().size(); nFile++) { 136 if ( request.getInputList().get(nFile) instanceof URL) { 137 138 //if (! FilesystemToolkit.checkIfFileExists((URL) request.getInputList().get(nFile), true)){ //replaced because it can hang if the file system goes down 139 if (! threadSafeFilesystemToolkit.threadSafeCheckIfFileExists((URL) request.getInputList().get(nFile), true)){ 140 141 valid = false; 142 System.out.println("Could not find file '"+request.getInputList().get(nFile)+"'"); 143 } 144 } 145 } 146 } 147 148 149 if (!request.getMail() && (request.getStdOut() == null)) { 150 log.warn("The output file wasn't specified and the mail attribute wasn't enabled."); 151 System.out.println("Output file wasn't specified."); 152 System.out.println("You have to add in your xml something like <stdout URL=\"file:/star/u/username/scheduler/out/$JOBID.out\" />"); 153 System.out.println("Refer to the documentation on how to specify an output file for your job."); 154 valid = false; 155 } 156 157 for (int n=0; n < request.getOutputList().size(); n++) { 158 OutputFile out = (OutputFile) request.getOutputList().get(n); 159 boolean validOut = verifyOutput(out); 160 if (valid) valid = validOut; 161 } 162 163 // Check whether inputOrder was used with local files 164 if (request.getInputOrder() != null) { 165 for (int n=0; (n < request.getInputList().size()) && (valid); n++) { 166 if (!(request.getInputList().get(n) instanceof CatalogQuery)) { 167 valid = false; 168 System.out.println("You can only use the inputOrder option with catalog queries"); 169 log.error("User tried to use the inputOrder option with non catalog queries input"); 170 } 171 } 172 } 173 174 // Check whether inputs and nProcesses are not declared in the same request 175 if ((request.getNProcesses() != -1) && (request.getInputList().size() != 0)) { 176 valid = false; 177 System.out.println("You cannot set nProcesses for a request that also has inputs"); 178 log.error("You cannot set nProcesses for a request that also has inputs"); 179 } 180 181 if (!valid) { 182 log.error("Job request was not valid"); 183 } 184 185 return valid; 186 } 187 188 static boolean verifyOutput(OutputFile output) { 189 boolean valid = true; 190 if ((output.getToURL() != null) && (output.getActionList().size() != 0)) { 191 System.out.println("You can't mix the toURL attribute for output and the outputActions. Use the <copy> action instead. "); 192 valid = false; 193 } 194 195 if (output.getToURL() != null) { 196 if (!FilesystemToolkit.checkIfDirExists(output.getToURL(), false)) { 197 198 System.out.println( "The directory for the output doesn't exist. It was '" + output.getToURL() + "'"); 199 200 } 201 } 202 203 //TODO rewrite to check output action id's 204 // List actions = output.getActionList(); 205 // List refs = new ArrayList(); 206 // for (int nAction = 0; nAction<actions.size(); nAction++) { 207 // OutputAction action = (OutputAction) actions.get(nAction); 208 // if (action.getFileRef() != null) { 209 // if (!refs.contains(action.getFileRef())) { 210 // if (action.isReferenceGenerator()) { 211 // refs.add(action.getFileRef()); 212 // } else { 213 // System.out.println("Output action <" + action.getName() + "> can't be the first action"); 214 // valid = false; 215 // } 216 // } else { 217 // if (action.isReferenceGenerator()) { 218 // System.out.println("Output action <" + action.getName() + "> must be the first action"); 219 // valid = false; 220 // } else { 221 // } 222 // } 223 // } 224 // } 225 226 227 228 229 return valid; 230 } 231 232 /** Getter for property defaultFileListSyntax. 233 * @return Value of property defaultFileListSyntax. 234 * 235 */ 236 public String getDefaultFileListSyntax() { 237 return this.defaultFileListSyntax; 238 } 239 240 /** Setter for property defaultFileListSyntax. 241 * @param defaultFileListSyntax New value of property defaultFileListSyntax. 242 * 243 */ 244 public void setDefaultFileListSyntax(String defaultFileListSyntax) { 245 this.defaultFileListSyntax = defaultFileListSyntax; 246 } 247 248 249 boolean checkIfFilesExistLocally = true; 250 public void setCheckIfFilesExistLocally(boolean checkIfFilesExistLocally){this.checkIfFilesExistLocally = checkIfFilesExistLocally;} 251 public boolean getCheckIfFilesExistLocally() {return checkIfFilesExistLocally;} 252 253 254 }