001: /*
002: * <copyright>
003: *
004: * Copyright 2003-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026: package org.cougaar.lib.vishnu.client;
027:
028: import com.bbn.vishnu.scheduling.Scheduler; //import com.bbn.vishnu.scheduling.Task;
029:
030: import java.io.File;
031: import java.io.FileNotFoundException;
032: import java.io.FileOutputStream;
033: import java.io.InputStream;
034: import java.io.IOException;
035: import java.io.StringReader;
036:
037: import java.text.ParseException;
038: import java.text.SimpleDateFormat;
039:
040: import java.util.ArrayList;
041: import java.util.Collection;
042: import java.util.Date;
043: import java.util.Enumeration;
044: import java.util.HashMap;
045: import java.util.List;
046: import java.util.Map;
047: import java.util.Vector;
048:
049: import org.apache.xerces.dom.DocumentImpl;
050: import org.apache.xerces.parsers.DOMParser;
051: import org.apache.xerces.parsers.SAXParser;
052:
053: import org.cougaar.planning.ldm.asset.Asset;
054: import org.cougaar.planning.ldm.plan.Task;
055: import org.cougaar.lib.param.ParamMap;
056: import org.cougaar.util.StringKey;
057: import org.cougaar.util.log.Logger;
058:
059: import org.w3c.dom.Document;
060:
061: import org.xml.sax.helpers.DefaultHandler;
062: import org.xml.sax.Attributes;
063: import org.xml.sax.InputSource;
064: import org.xml.sax.SAXException;
065:
066: /**
067: * Internal mode.
068: * <p>
069: * Creates an internal instance of the scheduler and talks to it, instead
070: * of to a web server.
071: *
072: */
073: public class InternalMode extends ExternalMode {
074: protected boolean writeXMLToFile = false;
075: protected boolean newDecoder = false;
076: protected boolean writeVSHToFile = false;
077:
078: /** just calls localSetup */
079: public InternalMode(ModeListener parent, VishnuComm comm,
080: XMLProcessor xmlProcessor, VishnuDomUtil domUtil,
081: VishnuConfig config, ResultHandler resultHandler,
082: ParamMap myParamTable, Logger logger) {
083: super (parent, comm, xmlProcessor, domUtil, config,
084: resultHandler, myParamTable, logger);
085: localSetup();
086: try {
087: if (myParamTable.hasParam("writeXMLToFile"))
088: writeXMLToFile = myParamTable
089: .getBooleanParam("writeXMLToFile");
090: else
091: writeXMLToFile = false;
092:
093: if (myParamTable.hasParam("writeVSHToFile"))
094: writeVSHToFile = myParamTable
095: .getBooleanParam("writeVSHToFile");
096: else
097: writeVSHToFile = false;
098:
099: if (myParamTable.hasParam("newDecoder"))
100: newDecoder = myParamTable.getBooleanParam("newDecoder");
101: else
102: newDecoder = false;
103: } catch (Exception e) {
104: }
105: }
106:
107: /** Create a new scheduler if in batch mode or if called the first time */
108: public void setupScheduler() {
109: if (!incrementalScheduling || sched == null) {
110: sched = new Scheduler();
111: sched.setNewDecoder(newDecoder);
112: if (logger.isInfoEnabled())
113: logger.info(getName()
114: + ".setupScheduler - created scheduler "
115: + sched);
116:
117: sched.setupInternalObjects();
118: sched.getData().readEverything();
119: }
120: }
121:
122: /**
123: * Place to handle rescinded tasks. <p>
124: *
125: * Sends XML to unfreeze the task assignment and delete it.
126: * @param removedTasks changed assets found in the container
127: * @see com.bbn.vishnu.scheduling.Scheduler#setupInternal
128: */
129: public void handleRemovedTasks(Enumeration removedTasks) {
130: if (incrementalScheduling) {
131: Vector knownTasks = new Vector();
132: for (; removedTasks.hasMoreElements();) {
133: Task task = (Task) removedTasks.nextElement();
134:
135: if (sched.getData().getTask(task.getUID().toString()) != null)
136: knownTasks.add(task);
137: }
138:
139: Document docToSend = xmlProcessor.prepareRescind(knownTasks
140: .elements(), parent.getTaskName());
141:
142: comm.serializeAndPostData(docToSend);
143:
144: if (logger.isInfoEnabled())
145: logger
146: .info("InternalMode.handleRemovedTasks - telling scheduler "
147: + sched + " to remove tasks.");
148:
149: // try {
150: sched.setupInternal(comm.getBuffer(), false);
151: // } catch (Exception e) {
152: // if (logger.isDebugEnabled())
153: // logger.debug ("InternalMode.handleRemovedTasks - " +
154: // "got exception related to a task that the scheduler didn't know about.\n" +
155: // " Is this innocuous?");
156: // }
157: comm.clearBuffer();
158: }
159: }
160:
161: /**
162: * Place to handle unfrozen tasks. <p>
163: *
164: * Sends XML to unfreeze the task assignment
165: * @param newAssets changed assets found in the container
166: * @see com.bbn.vishnu.scheduling.Scheduler#setupInternal
167: */
168: public void unfreezeTasks(Collection tasks) {
169: if (incrementalScheduling) {
170: Vector knownTasks = new Vector();
171: for (java.util.Iterator iter = tasks.iterator(); iter
172: .hasNext();) {
173: Task task = (Task) iter.next();
174:
175: if (sched.getData().getTask(task.getUID().toString()) != null)
176: knownTasks.add(task);
177: else {
178: logger.warn("skipping unfreezing unknown task "
179: + task.getUID());
180: }
181: }
182:
183: Document docToSend = xmlProcessor
184: .prepareUnfreeze(knownTasks);
185:
186: comm.serializeAndPostData(docToSend);
187:
188: if (logger.isInfoEnabled())
189: logger
190: .info("InternalMode.unfreezeTasks - telling scheduler "
191: + sched + " to remove tasks.");
192:
193: sched.setupInternal(comm.getBuffer(), false);
194: comm.clearBuffer();
195: }
196: }
197:
198: public Collection getTaskKeys() {
199: com.bbn.vishnu.scheduling.Task[] tasks = sched.getData()
200: .getTasks();
201: Collection taskKeys = new java.util.HashSet();
202:
203: for (int i = 0; i < tasks.length; i++) {
204: taskKeys.add(tasks[i].getKey());
205: }
206:
207: return taskKeys;
208: }
209:
210: /**
211: * <pre>
212: * Run internally. Give the scheduler the contents of
213: * the internalBuffer (in VishnuComm), which has captured all the xml output
214: * that would normally go to the various URLs if in external mode.
215: *
216: * Then, parse the results using an XMLResultHandler, which is just a SAX
217: * Parser and the AssignmentHandler, which just calls parseStartElement and
218: * parseEndElement. The AssignmentHandler will call methods in the VishnuPlugin
219: * to create plan elements for each assignment.
220: *
221: * </pre>
222: * @see XMLResultHandler#parseStartElement
223: * @see XMLResultHandler#parseEndElement
224: */
225: public void run() {
226: int unhandledTasks = prepareScheduler();
227:
228: try {
229: if (logger.isDebugEnabled())
230: for (int i = 0; i < sched.getData().getResources().length; i++) {
231: logger.debug(getName() + ".run - Known Resource #"
232: + i + " : \n"
233: + sched.getData().getResources()[i]);
234: }
235:
236: // sched is the scheduler...
237: sched.scheduleInternal(null, false);
238:
239: // the second argument controls whether to include frozen assignments in those returned
240: String assignments = sched.getXMLAssignments(true,
241: !incrementalScheduling);
242:
243: if (writeXMLToFile) {
244: if (logger.isInfoEnabled())
245: logger
246: .info(getName()
247: + ".run - writing assignments to XML file.");
248: comm.writeBufferToFile("assignments", sched
249: .getXMLAssignments(false,
250: !incrementalScheduling));
251: // logger.info(getName () + ".run - writing complete Vishnu problem to XML file.");
252: //comm.writeBufferToFile("complete", sched.toXML());
253: }
254: dumpPostProcess();
255:
256: if (logger.isInfoEnabled())
257: logger.info(getName()
258: + ".run - scheduled assignments were : "
259: + assignments);
260:
261: SAXParser parser = new SAXParser();
262: parser.setContentHandler(((XMLResultHandler) resultHandler)
263: .getAssignmentHandler());
264: try {
265: parser.parse(new InputSource(new StringReader(
266: assignments)));
267: } catch (SAXException sax) {
268: logger.error(getName() + ".run - Got sax exception:\n"
269: + sax, sax);
270: } catch (IOException ioe) {
271: logger.error(getName()
272: + ".run - Could not open file : \n" + ioe, ioe);
273: } catch (NullPointerException npe) {
274: logger
275: .error(
276: getName()
277: + ".run - ERROR - no assignments were made, badly confused : \n"
278: + npe, npe);
279: }
280: } catch (Exception e) {
281: logger.error(getName()
282: + ".run - Got error running scheduler : "
283: + e.getMessage(), e);
284: } finally {
285: cleanUpAfterScheduling(unhandledTasks);
286: }
287: }
288:
289: /** Method to hide domain-specific output routines */
290: protected void dumpPostProcess() {
291: if (writeVSHToFile) {
292: if (logger.isInfoEnabled())
293: logger
294: .info(getName()
295: + ".run - writing complete Vishnu problem to VSH file (vishnu XML format).");
296: comm.writeBufferToFile_withBackup("complete", ".vsh", sched
297: .toXML());
298: }
299: }
300:
301: /**
302: * Implemented for SchedulerLifecycle
303: * <p>
304: * Call SAXParser in scheduler to set it up with the specs, object format, etc.
305: * @see com.bbn.vishnu.scheduling.Scheduler#setupInternal
306: */
307: public void initializeWithFormat() {
308: if (logger.isInfoEnabled())
309: logger.info("InternalMode - initializing scheduler "
310: + sched + " with format.");
311:
312: sched.setupInternal(comm.getBuffer(), false);
313: comm.clearBuffer();
314: }
315:
316: /**
317: * Call setupInternal to initialize scheduler with task and asset data
318: * @see com.bbn.vishnu.scheduling.Scheduler#setupInternal
319: */
320: protected int prepareScheduler() {
321: // sched is the scheduler...
322: if (comm.getBuffer().length() != 0) {
323: sched.setupInternal(comm.getBuffer(), false);
324: comm.clearBuffer();
325: }
326:
327: return parent.getNumTasks();
328: }
329:
330: /**
331: * send other data, if it hasn't already been sent
332: * @see com.bbn.vishnu.scheduling.Scheduler#setupInternal
333: */
334: protected void sendOtherData() {
335: if (comm.getBuffer().length() != 0) {
336: sched.setupInternal(comm.getBuffer(), false);
337: comm.clearBuffer();
338: }
339: super .sendOtherData();
340: }
341:
342: /**
343: * Inform of # of unhandled tasks <br>
344: * Freeze all assignments if incremental mode
345: */
346: protected void cleanUpAfterScheduling(int unhandledTasks) {
347: Date start = new Date();
348:
349: comm.clearBuffer();
350:
351: if (incrementalScheduling) {
352: if (logger.isDebugEnabled())
353: logger
354: .debug(getName()
355: + ".cleanUpAfterScheduling - sending freeze all.");
356:
357: serializeAndPostDoc(xmlProcessor.prepareFreezeAll());
358: sched.getData().checkpointFrozen();
359: }
360:
361: if (showTiming) {
362: domUtil.reportTime(getName() + ".cleanUpAfterScheduling"
363: + " - created successful plan elements for "
364: + (unhandledTasks - parent.getNumTasks())
365: + " tasks in ", start);
366: } else {
367: if (logger.isInfoEnabled())
368: logger.info(getName()
369: + " - created successful plan elements for "
370: + (unhandledTasks - parent.getNumTasks())
371: + " tasks.");
372: }
373: }
374:
375: /**
376: * Serialize and post telling scheduler to setupInternal
377: *
378: * @see com.bbn.vishnu.scheduling.Scheduler#setupInternal
379: */
380: protected void serializeAndPostDoc(Document doc) {
381: comm.serializeAndPostData(doc);
382: sched.setupInternal(comm.getBuffer(), false);
383: comm.clearBuffer();
384: }
385:
386: /** name of this object */
387: protected String getName() {
388: return parent.getName() + "-InternalMode";
389: }
390:
391: /** queries the scheduler to get a full specification of the problem
392: * (including specs, logic, gaspecs, objects, assignments, etc)
393: */
394: public String dumpToXML() {
395: try {
396: return sched.toXML();
397: } catch (Exception e) {
398: return "";
399: }
400: }
401:
402: /** seeds the scheduler with the given chromosome
403: * in format "Cid*%*id*%*..."
404: */
405: public void seedScheduler(String seedChrom) {
406: sched.seedChromosome(seedChrom);
407: }
408:
409: Map myNameToDescrip;
410: String singleAssetClassName;
411: boolean alwaysClearDatabase;
412: /** the internal scheduler instance */
413: protected Scheduler sched;
414:
415: private final SimpleDateFormat format = new SimpleDateFormat(
416: "yyyy-MM-dd HH:mm:ss");
417: }
|