001 /* 002 * $RCSfile: Scheduler.java,v $ 003 * 004 * Created on July 12, 2002, 11:04 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; 024 025 import java.util.*; 026 import java.util.logging.Level; 027 import org.apache.log4j.Logger; 028 import gov.bnl.star.offline.scheduler.util.StatisticsRecorder; 029 import gov.bnl.star.offline.scheduler.util.persistent.ReportWriter; 030 import gov.bnl.star.offline.scheduler.request.Request; 031 032 /** A scheduler able to verify a job description, chosing the target machine 033 * according to a policy and dispatch the job. 034 * <p> 035 * To create a scheduler, one has to specify a JobInitializer, a Policy and 036 * a Dispatcher. When submitting a request, the job description will be 037 * passed to the JobInitializer which will return an array of JobRequests. 038 * These will be passed one by one to the Policy and then to the Dispatcher. 039 * <p> 040 * By keeping the three function separate from each other, it is possible to 041 * change the underlying queue manager (LSF, Condor, Globus, ... ), policy 042 * or job description specifications. 043 * 044 * @author Gabriele Carcassi 045 * @version $Revision: 1.26 $ $Date: 2006/11/21 00:41:32 $ 046 */ 047 public class Scheduler { 048 static private Logger log = Logger.getLogger(Scheduler.class.getName()); 049 private JobInitializer initializer; 050 private Policy policy; 051 private Dispatcher dispatcher; 052 private Request[] requests; 053 private List jobs; 054 055 /** Creates a new scheduler, putting together an initalizer, a policy 056 * and a dispatcher. 057 * @param initializer the part of the scheduler that will create the JobRequests from the xml file 058 * @param policy the part of the scheduler that will decide how and where to execute the jobs 059 * @param dispatcher the part of the scheduler that will dispatch the processes to the underlying 060 * queue 061 */ 062 public Scheduler(JobInitializer initializer, Policy policy, 063 Dispatcher dispatcher) { 064 this.initializer = initializer; 065 this.policy = policy; 066 this.dispatcher = dispatcher; 067 log.debug("A new scheduler was created"); 068 } 069 070 /** Creates a new scheduler, putting together an initalizer, a policy 071 * and a dispatcher. In this constructor you specify the class names 072 * instead of the objects. This allows complete real time configuration of 073 * any part of the scheduler. 074 * <p> 075 * Every class specified must have a default constructor. 076 * @param initializerClassName the class name of a class inheriting from JobInitializer 077 * @param policyClassName the class name of a class inheriting from Policy 078 * @param dispatcherClassName the class name of a class inheriting from Dispatcher 079 */ 080 public Scheduler(String initializerClassName, String policyClassName,String dispatcherClassName) { 081 // Load the JobInitializer 082 try { 083 Class initializerClass = Class.forName(initializerClassName); 084 this.initializer = (JobInitializer) initializerClass.newInstance(); 085 } catch (ClassNotFoundException e) { 086 throw new RuntimeException("Can't find JobInitializer class: " + 087 initializerClassName); 088 } catch (InstantiationException e) { 089 throw new RuntimeException( 090 "The default constructor raised an exception: " + 091 initializerClassName); 092 } catch (IllegalAccessException e) { 093 throw new RuntimeException( 094 "The default constructor is not public: " + 095 initializerClassName); 096 } catch (ClassCastException e) { 097 throw new RuntimeException( 098 "The class provided as a JobInitializer doesn't implement the JobInitializer interface: " + 099 initializerClassName); 100 } 101 102 // Load the Policy 103 try { 104 Class policyClass = Class.forName(policyClassName); 105 this.policy = (Policy) policyClass.newInstance(); 106 } catch (ClassNotFoundException e) { 107 throw new RuntimeException("Can't find Policy class: " + 108 policyClassName); 109 } catch (InstantiationException e) { 110 throw new RuntimeException( 111 "The default constructor raised an exception: " + 112 policyClassName); 113 } catch (IllegalAccessException e) { 114 throw new RuntimeException( 115 "The default constructor is not public: " + policyClassName); 116 } catch (ClassCastException e) { 117 throw new RuntimeException( 118 "The class provided as a Policy doesn't implement the Policy interface: " + 119 policyClassName); 120 } 121 122 // Load the Dispatcher 123 try { 124 Class dispatcherClass = Class.forName(dispatcherClassName); 125 this.dispatcher = (Dispatcher) dispatcherClass.newInstance(); 126 } catch (ClassNotFoundException e) { 127 throw new RuntimeException("Can't find Dispatcher class: " + 128 dispatcherClassName); 129 } catch (InstantiationException e) { 130 throw new RuntimeException( 131 "The default constructor raised an exception: " + 132 dispatcherClassName); 133 } catch (IllegalAccessException e) { 134 throw new RuntimeException( 135 "The default constructor is not public: " + 136 dispatcherClassName); 137 } catch (ClassCastException e) { 138 throw new RuntimeException( 139 "The class provided as a Dispatcher doesn't implement the Dispatcher interface: " + 140 dispatcherClassName); 141 } 142 } 143 144 /** Submits a job through the scheduler. Analizes the xml file, and 145 * dispatches the job according to the policy. 146 * @param xmlFileName the filename of the job description 147 */ 148 public void submit(String xmlFileName) { 149 log.info("Scheduling job description contained in: " + xmlFileName); 150 151 //This line is needed to alow files with the "root:" protcal to be passed 152 //System.setProperty("java.protocol.handler.pkgs", "gov.bnl.star.offline.scheduler.util.protocol" ); 153 154 try { 155 requests = initializer.analizeRequest(xmlFileName); 156 } catch (Exception e) { 157 log.fatal("Job description was invalid", e); 158 throw new RuntimeException(e.getMessage()); 159 } 160 161 for (int nRequest = 0; nRequest < requests.length; nRequest++) { 162 try { 163 log.debug("String policy.assignTargetMachine(...)"); 164 jobs = policy.assignTargetMachine(requests[nRequest]); 165 } catch (Exception e) { 166 log.fatal("Policy assignment failed", e); 167 throw new RuntimeException(e.getMessage()); 168 } 169 170 try { 171 log.debug("String dispatcher.dispatch(...)"); 172 dispatcher.dispatch(requests[nRequest], jobs); 173 174 // write report file 175 (new ReportWriter()).writeReport(requests[nRequest]); 176 177 StatisticsRecorder.getInstance().recordStatistics( 178 requests[nRequest], jobs); 179 180 } catch (Exception e) { 181 log.fatal("Job dispatching failed", e); 182 throw new RuntimeException(e.getMessage()); 183 } 184 } 185 log.info("Job dispatched: " + xmlFileName +"\n"); 186 } 187 188 public Request[] getRequests() { return requests; } 189 190 public List getJobs() { return jobs; } 191 192 }