0001: /*
0002: * This file or a portion of this file is licensed under the terms of
0003: * the Globus Toolkit Public License, found in file GTPL, or at
0004: * http://www.globus.org/toolkit/download/license.html. This notice must
0005: * appear in redistributions of this file, with or without modification.
0006: *
0007: * Redistributions of this Software, with or without modification, must
0008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
0009: * some other similar material which is provided with the Software (if
0010: * any).
0011: *
0012: * Copyright 1999-2004 University of Chicago and The University of
0013: * Southern California. All rights reserved.
0014: */
0015: package org.griphyn.cPlanner.classes;
0016:
0017: import org.griphyn.cPlanner.namespace.Condor;
0018: import org.griphyn.cPlanner.namespace.Dagman;
0019: import org.griphyn.cPlanner.namespace.ENV;
0020: import org.griphyn.cPlanner.namespace.Globus;
0021: import org.griphyn.cPlanner.namespace.Hints;
0022: import org.griphyn.cPlanner.namespace.VDS;
0023:
0024: import org.griphyn.cPlanner.common.LogManager;
0025: import org.griphyn.cPlanner.common.PegasusProperties;
0026:
0027: import org.griphyn.cPlanner.partitioner.graph.GraphNodeContent;
0028:
0029: import org.griphyn.common.catalog.TransformationCatalogEntry;
0030:
0031: import org.griphyn.common.util.Separator;
0032:
0033: import java.util.Iterator;
0034: import java.util.List;
0035: import java.util.Set;
0036: import java.util.HashSet;
0037:
0038: import java.io.Writer;
0039: import java.io.StringWriter;
0040: import java.io.IOException;
0041:
0042: /**
0043: * The object of this class holds the information to generate a submit file about
0044: * one particular job making the Dag.
0045: *
0046: * @author Karan Vahi
0047: * @author Gaurang Mehta
0048: * @version $Revision: 222 $
0049: */
0050:
0051: public class SubInfo extends Data implements GraphNodeContent {
0052:
0053: /**
0054: * Denotes a job that does not fall into the other categories. It might
0055: * denote an error condition or a faulty logic in the planner.
0056: */
0057: public static final int UNASSIGNED_JOB = 0;
0058:
0059: /**
0060: * Denotes a compute job. Generally these are the jobs that are specified in
0061: * the DAX.
0062: */
0063: public static final int COMPUTE_JOB = 1;
0064:
0065: /**
0066: * Denotea a job that is used to stage in the input files for a compute job.
0067: */
0068: public static final int STAGE_IN_JOB = 2;
0069:
0070: /**
0071: * Denotes a job that transfers the date generated by a compute job to the
0072: * output pool specified by the user.
0073: */
0074: public static final int STAGE_OUT_JOB = 3;
0075:
0076: /**
0077: * Denotes a job that registers in the replica mechanism the materialized
0078: * files.
0079: */
0080: public static final int REPLICA_REG_JOB = 4;
0081:
0082: /**
0083: * Denotes a job that transfers the output of a compute node to the site
0084: * where the child compute node is to be generated.
0085: */
0086: public static final int INTER_POOL_JOB = 5;
0087:
0088: /**
0089: * Denotes a job that creates directories at the remote pools.
0090: */
0091: public static final int CREATE_DIR_JOB = 6;
0092:
0093: /**
0094: * Denotes a job for which the executable has been staged as part of the
0095: * workflow.
0096: */
0097: public static final int STAGED_COMPUTE_JOB = 7;
0098:
0099: /**
0100: * Denotes a cleanup job, that removes the files that from the remote
0101: * working directories of the remote sites.
0102: */
0103: public static final int CLEANUP_JOB = 8;
0104:
0105: /**
0106: * The delimiter that has to be used to combine the name for the staged
0107: * executable.
0108: */
0109: private static String DELIMITER = PegasusProperties.getInstance()
0110: .getStagingDelimiter();
0111:
0112: /**
0113: * The type of the job. Pegasus tags the jobs according to the function of
0114: * the job. The jobs are tagged according to the functionality they serve in
0115: * the VDS super node. The job class can be
0116: *
0117: * unassigned
0118: * compute job
0119: * stage-in
0120: * stage-out
0121: * replica registration
0122: * inter-pool transfer
0123: * create-dir job
0124: * staged-compute job
0125: */
0126: public int jobClass;
0127:
0128: /**
0129: * Identifies of which VDS Super Node is a job associated with.
0130: * VDS Supernode is identified by the jobName of the compute node in the
0131: * super node.
0132: */
0133: public String jobID;
0134:
0135: /**
0136: * The name of the job.
0137: */
0138: public String jobName;
0139:
0140: /**
0141: * The logical name of the transformation which is executed as a part of
0142: * this job. Note: The tc is looked up by namespace__logicalName_version.
0143: */
0144: public String logicalName;
0145:
0146: /**
0147: * The logical id of the job as referred to in the dax.
0148: */
0149: public String logicalId;
0150:
0151: /**
0152: * The namespace to which the transformation is bound.
0153: */
0154: public String namespace;
0155:
0156: /**
0157: * The version of the transformation.
0158: */
0159: public String version;
0160:
0161: /**
0162: * The name of the derivation in Chimera that generated the job.
0163: */
0164: public String dvName;
0165:
0166: /**
0167: * The namespace to which the derivation is bound.
0168: *
0169: */
0170: public String dvNamespace;
0171:
0172: /**
0173: * The version of the derivation.
0174: */
0175: public String dvVersion;
0176:
0177: /**
0178: * The globus Scheduler for the job.
0179: */
0180: public String globusScheduler;
0181:
0182: /**
0183: * The path of the executable on the machine at which the job is executed.
0184: */
0185: public String executable;
0186:
0187: /**
0188: * The universe in which the job has to be executed. Can be standard,
0189: * vanilla or globus.
0190: */
0191: public String condorUniverse;
0192:
0193: /**
0194: * File which contains stdin (keyboard input).
0195: */
0196: public String stdIn;
0197:
0198: /**
0199: * File which contains stdout.
0200: */
0201: public String stdOut;
0202:
0203: /**
0204: * File which contains standard error.
0205: */
0206: public String stdErr;
0207:
0208: /**
0209: * The arguements for the job. It is the contains the arguments for the
0210: * job. This string is put in the arguments in Condor Submit File.
0211: */
0212: public String strargs;
0213:
0214: /**
0215: * Contains the input files for the submit file. They are vector of
0216: * PegasusFile Objects which store the transiency information of each
0217: * logical file.
0218: *
0219: * @see org.griphyn.cPlanner.classes.PegasusFile
0220: */
0221: public Set inputFiles;
0222:
0223: /**
0224: * Contains the output files for the submit file. They are vector of
0225: * PegasusFile Objects which store the transiency information of each logical
0226: * file.
0227: *
0228: * @see org.griphyn.cPlanner.classes.PegasusFile
0229: */
0230: public Set outputFiles;
0231:
0232: /**
0233: * The pool on which this job has been decided to be executed by the
0234: * Interpool Engine.
0235: *
0236: */
0237: public String executionPool;
0238:
0239: //the namespace variables
0240:
0241: /**
0242: * The namespace object containing the globus rsl attributes which the user
0243: * specifies in the dax, or the pool file or the properties file.
0244: */
0245: public Globus globusRSL;
0246:
0247: /**
0248: * For Condor Namespace. This contains the extra Condor options which one
0249: * may want to specify. These are copied straightaway to the Submit file.
0250: */
0251: public Condor condorVariables;
0252:
0253: /**
0254: * To accomodate the environment variables which might needed to be set.
0255: */
0256: public ENV envVariables;
0257:
0258: /**
0259: * The DAGMAN namespace profile variable holding the dagman profiles.
0260: * It holds the prescript and the postscripts for the jobs.
0261: */
0262: public Dagman dagmanVariables;
0263:
0264: /**
0265: * To accomodate all the hints that maybe passed through the DAX.
0266: */
0267: public Hints hints;
0268:
0269: /**
0270: * The VDS namespace variable.
0271: */
0272: public VDS vdsNS;
0273:
0274: /**
0275: * Identifies the level of the job in the dax. The level is bottom up
0276: * from the final child node.
0277: */
0278: public int level;
0279:
0280: /**
0281: * The relative path to the submit directory for the job, from the workflows
0282: * base submit directory.
0283: */
0284: // private String submitDirectory;
0285:
0286: /**
0287: * Intialises the member variables.
0288: */
0289: public SubInfo() {
0290: jobName = "";
0291: namespace = "";
0292: logicalName = "";
0293: logicalId = "";
0294: version = "";
0295: dvName = null;
0296: dvNamespace = null;
0297: dvVersion = null;
0298: jobID = "";
0299: globusScheduler = "";
0300: executable = "";
0301: condorUniverse = "";
0302: stdIn = "";
0303: stdOut = "";
0304: stdErr = "";
0305: inputFiles = new HashSet();
0306: outputFiles = new HashSet();
0307: strargs = "";
0308: envVariables = new ENV();
0309: executionPool = new String();
0310: globusRSL = new Globus();
0311: condorVariables = new Condor();
0312: dagmanVariables = new Dagman();
0313: hints = new Hints();
0314: vdsNS = new VDS();
0315: jobClass = UNASSIGNED_JOB;
0316: level = -1;
0317: // submitDirectory = null;
0318: }
0319:
0320: /**
0321: * Overloaded constructor. Does a shallow copy of the job object passed.
0322: *
0323: * @param job the <code>SubInfo</code> object containing the job description.
0324: */
0325: public SubInfo(SubInfo job) {
0326: jobName = job.jobName;
0327: namespace = job.namespace;
0328: logicalName = job.logicalName;
0329: logicalId = job.logicalId;
0330: version = job.version;
0331: dvName = job.dvName;
0332: dvNamespace = job.dvNamespace;
0333: dvVersion = job.dvVersion;
0334: jobID = job.jobID;
0335: globusScheduler = job.globusScheduler;
0336: executable = job.executable;
0337: condorUniverse = job.condorUniverse;
0338: stdIn = job.stdIn;
0339: stdOut = job.stdOut;
0340: stdErr = job.stdErr;
0341: inputFiles = job.inputFiles;
0342: outputFiles = job.outputFiles;
0343: strargs = job.strargs;
0344: envVariables = job.envVariables;
0345: executionPool = job.executionPool;
0346: globusRSL = job.globusRSL;
0347: condorVariables = job.condorVariables;
0348: dagmanVariables = job.dagmanVariables;
0349: hints = job.hints;
0350: vdsNS = job.vdsNS;
0351: jobClass = job.getJobType();
0352: level = job.level;
0353: // submitDirectory = job.submitDirectory;
0354: }
0355:
0356: /**
0357: * Returns a new copy of the Object.
0358: *
0359: * @return clone of the object.
0360: */
0361: public Object clone() {
0362: SubInfo newSub = new SubInfo();
0363:
0364: newSub.condorUniverse = this .condorUniverse;
0365: newSub.envVariables = (ENV) this .envVariables.clone();
0366: newSub.executable = this .executable;
0367: newSub.globusScheduler = this .globusScheduler;
0368: for (Iterator it = this .inputFiles.iterator(); it.hasNext();) {
0369: newSub.addInputFile((PegasusFile) ((PegasusFile) it.next())
0370: .clone());
0371: }
0372: for (Iterator it = this .outputFiles.iterator(); it.hasNext();) {
0373: newSub
0374: .addOutputFile((PegasusFile) ((PegasusFile) it
0375: .next()).clone());
0376: }
0377:
0378: newSub.jobName = this .jobName;
0379: newSub.logicalName = this .logicalName;
0380: newSub.logicalId = this .logicalId;
0381: newSub.stdErr = this .stdErr;
0382: newSub.stdIn = this .stdIn;
0383: newSub.stdOut = this .stdOut;
0384: newSub.strargs = this .strargs;
0385: newSub.executionPool = this .executionPool;
0386: newSub.globusRSL = this .globusRSL == null ? null
0387: : (Globus) this .globusRSL.clone();
0388:
0389: newSub.condorVariables = this .condorVariables == null ? null
0390: : (Condor) this .condorVariables.clone();
0391: newSub.dagmanVariables = this .dagmanVariables == null ? null
0392: : (Dagman) this .dagmanVariables.clone();
0393: newSub.vdsNS = this .vdsNS == null ? null : (VDS) this .vdsNS
0394: .clone();
0395:
0396: newSub.hints = (Hints) this .hints.clone();
0397: newSub.jobID = this .jobID;
0398: newSub.jobClass = this .jobClass;
0399:
0400: newSub.dvName = this .dvName;
0401: newSub.namespace = this .namespace;
0402: newSub.version = this .version;
0403: newSub.dvNamespace = this .dvNamespace;
0404: newSub.dvVersion = this .dvVersion;
0405:
0406: newSub.level = this .level;
0407: // newSub.submitDirectory = this.submitDirectory == null ? null : new String(this.submitDirectory);
0408:
0409: return newSub;
0410: }
0411:
0412: /**
0413: * Set the universe associated with the job.
0414: *
0415: * @param universe the universe to be associated.
0416: */
0417: public void setUniverse(String universe) {
0418: this .condorUniverse = universe;
0419: }
0420:
0421: /**
0422: * Returns the universe associated with the job.
0423: *
0424: * @return the universe associate with job .
0425: */
0426: public String getUniverse() {
0427: return this .condorUniverse;
0428: }
0429:
0430: /**
0431: * Adds an input file to the underlying collection of input files
0432: * associated with the job.
0433: *
0434: * @param file the <code>PegasusFile</code> containing the input file.
0435: */
0436: public void addInputFile(PegasusFile file) {
0437: this .inputFiles.add(file);
0438: }
0439:
0440: /**
0441: * Sets the input files associated with the job.
0442: *
0443: * @param ipFiles Set of <code>PegasusFile</code> objects containing the input files.
0444: */
0445: public void setInputFiles(Set ipFiles) {
0446: this .inputFiles = ipFiles;
0447: }
0448:
0449: /**
0450: * Returns the set of input files associated with the job.
0451: *
0452: * @return Set of <code>PegasusFile</code> objects containing the input files.
0453: */
0454: public Set getInputFiles() {
0455: return this .inputFiles;
0456: }
0457:
0458: /**
0459: * Adds an output file to the underlying collection of output files
0460: * associated with the job.
0461: *
0462: * @param file the <code>PegasusFile</code> containing the output file.
0463: */
0464: public void addOutputFile(PegasusFile file) {
0465: this .outputFiles.add(file);
0466: }
0467:
0468: /**
0469: * Sets the output files associated with the job.
0470: *
0471: * @param opFiles Set of <code>PegasusFile</code> objects containing the
0472: * output files.
0473: */
0474: public void setOutputFiles(Set opFiles) {
0475: this .outputFiles = opFiles;
0476: }
0477:
0478: /**
0479: * Returns the set of output files associated with the job.
0480: *
0481: * @return Set of <code>PegasusFile</code> objects containing the output files.
0482: */
0483: public Set getOutputFiles() {
0484: return this .outputFiles;
0485: }
0486:
0487: /**
0488: * Sets the type of the job.
0489: *
0490: * @param type the type of the job.
0491: * @exception IllegalArgumentException if the job type is outside its legal
0492: * range.
0493: *
0494: * @see #UNASSIGNED_JOB
0495: * @see #COMPUTE_JOB
0496: * @see #STAGE_IN_JOB
0497: * @see #STAGE_OUT_JOB
0498: * @see #REPLICA_REG_JOB
0499: * @see #INTER_POOL_JOB
0500: * @see #CREATE_DIR_JOB
0501: * @see #STAGED_COMPUTE_JOB
0502: * @see #CLEANUP_JOB
0503: */
0504: public void setJobType(int type) {
0505: if (typeInRange(type)) {
0506: jobClass = type;
0507: } else {
0508: throw new IllegalArgumentException("Invalid Job type "
0509: + type);
0510: }
0511: }
0512:
0513: /**
0514: * Sets the site handle of the site, where teh job is to be executed
0515: *
0516: * @param site the site handle.
0517: */
0518: public void setSiteHandle(String site) {
0519: this .executionPool = site;
0520: }
0521:
0522: /**
0523: * Returns the handle of the site where the job is scheduled.
0524: *
0525: * @return site handle.
0526: */
0527: public String getSiteHandle() {
0528: return executionPool;
0529: }
0530:
0531: /**
0532: * Sets the path to the executable on the remote grid site. This executable
0533: * is invoked whenever a job is run on the remote grid site.
0534: *
0535: * @param path the path to the underlying transformation on the remote grid
0536: * site.
0537: *
0538: * @see #getSiteHandle()
0539: */
0540: public void setRemoteExecutable(String path) {
0541: this .executable = path;
0542: }
0543:
0544: /**
0545: * Returns the path of the underlying executable on the remote grid site.
0546: *
0547: * @return the path to the executable if set.
0548: */
0549: public String getRemoteExecutable() {
0550: return this .executable;
0551: }
0552:
0553: /**
0554: * Sets the remote jobmanager on which the job has to run.
0555: *
0556: * @param jobmanager the jobmanager url.
0557: *
0558: * @see #getJobManager()
0559: */
0560: public void setJobManager(String jobmanager) {
0561: this .globusScheduler = jobmanager;
0562: }
0563:
0564: /**
0565: * Returnss the remote jobmanager on which the job has to run.
0566: *
0567: * @return the jobmanager url.
0568: *
0569: * @see #setJobManager()
0570: */
0571: public String getJobManager() {
0572: return this .globusScheduler;
0573: }
0574:
0575: /**
0576: * Sets the file to which the stdout of the job needs to be written to
0577: * at the remote grid site. Should be just the basename. The file appears
0578: * in the remote working directory for that job.
0579: *
0580: * @param fileName the basename of the file.
0581: */
0582: public void setStdOut(String fileName) {
0583: this .stdOut = fileName;
0584: }
0585:
0586: /**
0587: * Returns the file to which the stdout of the job is written to.
0588: *
0589: * @return the basename of the file.
0590: */
0591: public String getStdOut() {
0592: return this .stdOut;
0593: }
0594:
0595: /**
0596: * Sets the file to which the stderr of the job needs to be written to
0597: * at the remote grid site. Should be just the basename. The file appears
0598: * in the remote working directory for that job.
0599: *
0600: * @param fileName the basename of the file.
0601: */
0602: public void setStdErr(String fileName) {
0603: this .stdErr = fileName;
0604: }
0605:
0606: /**
0607: * Returns the file to which the stderr of the job is written to.
0608: *
0609: * @return the basename of the file.
0610: */
0611: public String getStdErr() {
0612: return this .stdErr;
0613: }
0614:
0615: /**
0616: * Sets the file to from which to pick up the stdin for the job. The file
0617: * is tracked via Replica Catalog, and is staged to the remote grid site.
0618: *
0619: * @param fileName the basename of the file.
0620: */
0621: public void setStdIn(String fileName) {
0622: this .stdIn = fileName;
0623: }
0624:
0625: /**
0626: * Returns the file from which the stdin is picked up.
0627: *
0628: * @return the basename of the file.
0629: */
0630: public String getStdIn() {
0631: return this .stdIn;
0632: }
0633:
0634: /**
0635: * Returns the ID associated with the job. Unfortunately currently it is
0636: * the job name.
0637: *
0638: * @return the ID of the job.
0639: */
0640: public String getID() {
0641: return getName();
0642: }
0643:
0644: /**
0645: * Returns the name of the job.
0646: *
0647: * @return String
0648: */
0649: public String getName() {
0650: return jobName;
0651: }
0652:
0653: /**
0654: * Setter method to set the name of the job.
0655: *
0656: * @param name the name of the job.
0657: */
0658: public void setName(String name) {
0659: jobName = name;
0660: }
0661:
0662: /**
0663: * Returns the logical id of the job.
0664: *
0665: * @return String
0666: */
0667: public String getLogicalID() {
0668: return logicalId;
0669: }
0670:
0671: /**
0672: * Setter method to set the logical id of the job.
0673: *
0674: * @param id the logical id of the job.
0675: */
0676: public void setLogicalID(String id) {
0677: logicalId = id;
0678: }
0679:
0680: /**
0681: * Returns the name of the compute job of VDS supernode containing this job.
0682: *
0683: * @return String
0684: */
0685: public String getVDSSuperNode() {
0686: return this .jobID;
0687: }
0688:
0689: /**
0690: * Setter method to the name of the compute job of VDS supernode containing
0691: * this job.
0692: *
0693: * @param name the name of the job.
0694: */
0695: public void setVDSSuperNode(String name) {
0696: this .jobID = name;
0697: }
0698:
0699: /**
0700: * Returns the type of the job. Returns the value matching the jobClass.
0701: *
0702: * @return int value of job class.
0703: */
0704: public int getJobType() {
0705: return this .jobClass;
0706: }
0707:
0708: /**
0709: * Gets the textual description of the type associated with the job.
0710: *
0711: * @return the textual description of the type associated with the job.
0712: */
0713: public String getJobTypeDescription() {
0714: return getJobTypeDescription(this .jobClass);
0715: }
0716:
0717: /**
0718: * Gets the textual description of the type that can be associated
0719: * with a job.
0720: *
0721: * @param type the type of the job.
0722: *
0723: * @return the textual description of the type associated with the job.
0724: */
0725: public String getJobTypeDescription(int type) {
0726: String desc = null;
0727:
0728: switch (type) {
0729: case COMPUTE_JOB:
0730: desc = "Compute Job";
0731: break;
0732:
0733: case STAGE_IN_JOB:
0734: desc = "Stage In Job";
0735: break;
0736:
0737: case STAGE_OUT_JOB:
0738: desc = "Stage Out Job";
0739: break;
0740:
0741: case REPLICA_REG_JOB:
0742: desc = "Replica Registration Job";
0743: break;
0744:
0745: case UNASSIGNED_JOB:
0746: desc = "Unassigned Job";
0747: break;
0748:
0749: case CREATE_DIR_JOB:
0750: desc = "Create Directory job";
0751: break;
0752:
0753: case STAGED_COMPUTE_JOB:
0754: desc = "Staged Compute job";
0755: break;
0756:
0757: default:
0758: desc = "Unknown Job";
0759: break;
0760:
0761: }
0762:
0763: return desc;
0764: }
0765:
0766: /**
0767: * Returns the namespace of the underlying transformation.
0768: *
0769: * @return namespace
0770: */
0771: public String getTXNamespace() {
0772: return namespace;
0773: }
0774:
0775: /**
0776: * Sets the transformation namespace to be associated with the job.
0777: *
0778: * @param ns the namespace.
0779: */
0780: public void setTXNamespace(String ns) {
0781: this .namespace = ns;
0782: }
0783:
0784: /**
0785: * Returns the name of the underlying transformation.
0786: *
0787: * @return name
0788: */
0789: public String getTXName() {
0790: return logicalName;
0791: }
0792:
0793: /**
0794: * Sets the transformation name of the underlying transformation.
0795: *
0796: * @param name the logical name of the transformation.
0797: */
0798: public void setTXName(String name) {
0799: this .logicalName = name;
0800: }
0801:
0802: /**
0803: * Returns the version of the underlying transformation.
0804: *
0805: * @return version
0806: */
0807: public String getTXVersion() {
0808: return version;
0809: }
0810:
0811: /**
0812: * Sets the version of the underlying transformation.
0813: *
0814: * @param vs the version.
0815: */
0816: public void setTXVersion(String vs) {
0817: this .version = vs;
0818: }
0819:
0820: /**
0821: * Sets the various attributes of underlying transformation.
0822: *
0823: * @param ns the namespace of the transformation.
0824: * @param name the logical name of the transformation.
0825: * @param vs the version of the transformation.
0826: */
0827: public void setTransformation(String ns, String name, String vs) {
0828: this .setTXNamespace(ns);
0829: this .setTXName(name);
0830: this .setTXVersion(vs);
0831: }
0832:
0833: /**
0834: * Constructs the fully qualified name of a transformation with
0835: * which to query the TC, including the namespace and version.
0836: *
0837: * @return the complete tranformation name.
0838: */
0839: public String getCompleteTCName() {
0840: return Separator.combine(namespace, logicalName, version);
0841: }
0842:
0843: /**
0844: * Returns the namespace of the underlying derivation.
0845: *
0846: * @return namespace
0847: */
0848: public String getDVNamespace() {
0849: return dvNamespace;
0850: }
0851:
0852: /**
0853: * Sets the derivation namespace to be associated with the job.
0854: *
0855: * @param ns the namespace.
0856: */
0857: public void setDVNamespace(String ns) {
0858: this .dvNamespace = ns;
0859: }
0860:
0861: /**
0862: * Returns the name of the underlying derivation.
0863: *
0864: * @return name
0865: */
0866: public String getDVName() {
0867: return dvName;
0868: }
0869:
0870: /**
0871: * Sets the derivation name of the underlying derivation.
0872: *
0873: * @param name the logical name of the derivation.
0874: */
0875: public void setDVName(String name) {
0876: this .dvName = name;
0877: }
0878:
0879: /**
0880: * Returns the version of the underlying derivation.
0881: *
0882: * @return version
0883: */
0884: public String getDVVersion() {
0885: return dvVersion;
0886: }
0887:
0888: /**
0889: * Sets the version of the underlying derivation.
0890: *
0891: * @param vs the version.
0892: */
0893: public void setDVVersion(String vs) {
0894: this .dvVersion = vs;
0895: }
0896:
0897: /**
0898: * Sets the various attributes of underlying derivation.
0899: *
0900: * @param ns the namespace of the derivation.
0901: * @param name the logical name of the derivation.
0902: * @param vs the version of the derivation.
0903: */
0904: public void setDerivation(String ns, String name, String vs) {
0905: this .setDVNamespace(ns);
0906: this .setDVName(name);
0907: this .setDVVersion(vs);
0908: }
0909:
0910: /**
0911: * Returns the level associated with the job.
0912: *
0913: * @return int designating the level
0914: */
0915: public int getLevel() {
0916: return level;
0917: }
0918:
0919: /**
0920: * Sets the level for the job.
0921: *
0922: * @param value the level
0923: */
0924: public void setLevel(int value) {
0925: level = value;
0926: }
0927:
0928: /**
0929: * Constructs the fully qualified name of the corresponding derivation used
0930: * to generate this job in Chimera including the namespace and version.
0931: *
0932: * @return the complete derivation name.
0933: */
0934: public String getCompleteDVName() {
0935: return (dvName == null) ? null : Separator.combine(dvNamespace,
0936: dvName, dvVersion);
0937: }
0938:
0939: /**
0940: * Returns the basename for the staged executable corresponding to the
0941: * job.
0942: *
0943: * @return the staged executable basename
0944: */
0945: public String getStagedExecutableBaseName() {
0946: return getStagedExecutableBaseName(namespace, logicalName,
0947: version);
0948: }
0949:
0950: /**
0951: * Returns the basename for the staged executable corresponding to the
0952: * job.
0953: *
0954: * @param txNamespace is the namespace in which the TR resides, may be null.
0955: * @param txName is the base name of the transformation, must not be null.
0956: * @param txVersion is the version of the TR, may be null
0957: *
0958: * @return the staged executable basename
0959: */
0960: public static String getStagedExecutableBaseName(
0961: String txNamespace, String txName, String txVersion) {
0962: return combine(txNamespace, txName, txVersion);
0963: }
0964:
0965: /**
0966: * Returns the submit directory path relative to the workflow submit
0967: * directory.
0968: *
0969: * @return the directory name, if set else null.
0970: */
0971: // public String getSubmitDirectory(){
0972: // return this.submitDirectory;
0973: // }
0974: /**
0975: * Sets the submit directory path relative to the workflow submit
0976: * directory.
0977: *
0978: * @param directory the directory name.
0979: */
0980: // public void setSubmitDirectory(String directory){
0981: // this.submitDirectory = directory;
0982: // }
0983: /**
0984: * Returns the argument string with which the job has to be invoked.
0985: *
0986: * @return the argument string.
0987: */
0988: public String getArguments() {
0989: return this .strargs;
0990: }
0991:
0992: /**
0993: * Sets the argument string with which the job has to be invoked.
0994: *
0995: * @param arguments the argument string.
0996: */
0997: public void setArguments(String arguments) {
0998: this .strargs = arguments;
0999: }
1000:
1001: /**
1002: * Combines the three components together into a single string as
1003: * namespace-name-version.
1004: *
1005: * @param namespace is the namespace in which the TR resides, may be null.
1006: * @param name is the base name of the transformation, must not be null.
1007: * @param version is the version of the TR, may be null.
1008: *
1009: * @return the concatenated form .
1010: */
1011: private static String combine(String namespace, String name,
1012: String version) {
1013: StringBuffer result = new StringBuffer(32);
1014: if (namespace != null) {
1015: result.append(namespace).append(DELIMITER);
1016: }
1017: result.append(name);
1018: if (version != null) {
1019: result.append(DELIMITER).append(version);
1020: }
1021: return result.toString();
1022: }
1023:
1024: /**
1025: * It sets the prescript for the job. The argument string is assumed to be
1026: * empty.
1027: *
1028: * @param path the path to the script that has to be run as a prescript.
1029: */
1030: public void setPreScript(String path) {
1031: setPreScript(path, "");
1032: }
1033:
1034: /**
1035: * It sets the prescript for the job.
1036: *
1037: * @param path the path to the script that has to be run as a prescript.
1038: * @param arguments the arguments to the prescript,
1039: */
1040: public void setPreScript(String path, String arguments) {
1041: //this.preScript = script;
1042: //construct directly as we know keys are valid.
1043: dagmanVariables.construct(Dagman.PRE_SCRIPT_KEY, path);
1044: dagmanVariables.construct(Dagman.PRE_SCRIPT_ARGUMENTS_KEY,
1045: arguments);
1046: }
1047:
1048: /**
1049: * Returns the path to the prescript for the job if set.
1050: *
1051: * @return the path to the script that has to be run as a prescript, else
1052: * null if no prescript has been set.
1053: */
1054: public String getPreScriptPath() {
1055: Object obj = dagmanVariables.get(Dagman.PRE_SCRIPT_KEY);
1056: return (obj == null) ? null : (String) obj;
1057: }
1058:
1059: /**
1060: * Returns the arguments to the prescript for the job if set.
1061: *
1062: * @return the argumetns to the prescript script that has to be run as a
1063: * prescript, else null if no prescript has been set.
1064: */
1065: public String getPreScriptArguments() {
1066: Object obj = dagmanVariables
1067: .get(Dagman.PRE_SCRIPT_ARGUMENTS_KEY);
1068: return (obj == null) ? null : (String) obj;
1069: }
1070:
1071: /**
1072: * Returns whether the job type value for the job is in range or not.
1073: *
1074: * @param type the job type.
1075: *
1076: * @return true if the value is in range.
1077: * false if the value is not in range.
1078: */
1079: public boolean typeInRange(int type) {
1080: return (type >= this .UNASSIGNED_JOB && type <= this .CLEANUP_JOB);
1081: }
1082:
1083: /**
1084: * Updates all the profile namespaces with the information associated in
1085: * the transformation catalog for this job.
1086: * It ends up updating already existing information, and adds supplemental
1087: * new information if present in the transformation catalog.
1088: * The method does not explicitly check whehter the data object passed refers
1089: * to this job or not. The calling method should ensure this.
1090: *
1091: * @param entry the <code>TCEntry</code> object corresponding to the
1092: * entry in the Transformation Catalog for the job.
1093: */
1094: public void updateProfiles(TransformationCatalogEntry entry) {
1095: condorVariables.checkKeyInNS(entry);
1096: dagmanVariables.checkKeyInNS(entry);
1097: globusRSL.checkKeyInNS(entry);
1098: envVariables.checkKeyInNS(entry);
1099: vdsNS.checkKeyInNS(entry);
1100: }
1101:
1102: /**
1103: * Updates all the profile namespaces with the information specified by the
1104: * user in the properties file, that apply to this job.
1105: * It ends up updating already existing information, and adds supplemental
1106: * new information if present in the properties file.
1107: * The method does not explicitly check whehter the data object passed refers
1108: * to this job or not. The calling method should ensure this.
1109: *
1110: * @param properties the <code>PegasusProperties</code> object containing
1111: * the user properties.
1112: */
1113: public void updateProfiles(PegasusProperties properties) {
1114: condorVariables.checkKeyInNS(properties, executionPool);
1115: dagmanVariables.checkKeyInNS(properties, executionPool);
1116: globusRSL.checkKeyInNS(properties, executionPool);
1117: envVariables.checkKeyInNS(properties, executionPool);
1118: vdsNS.checkKeyInNS(properties, executionPool);
1119: }
1120:
1121: /**
1122: * Updates all the profile namespaces with the information specified in
1123: * list of profile objects passed. Pool catalog returns profile information
1124: * as a list of <code>Profile</code> objects that need to be propogated to
1125: * the job.
1126: * It ends up updating already existing information, and adds supplemental
1127: * new information if present in the properties file.
1128: *
1129: *
1130: * @param profiles the list of <code>Profile</code> objects that need to be
1131: * incorporated in the jobs profile namespaces.
1132: */
1133: public void updateProfiles(List profiles) {
1134: if (profiles == null || profiles.isEmpty()) {
1135: //nothing to put in the namespaces
1136: return;
1137: }
1138:
1139: Profile profile = null;
1140: for (Iterator it = profiles.iterator(); it.hasNext();) {
1141: profile = (Profile) it.next();
1142:
1143: if (profile.getProfileNamespace().equals(Profile.CONDOR))
1144: condorVariables.checkKeyInNS(profile);
1145:
1146: else if (profile.getProfileNamespace().equals(
1147: Profile.GLOBUS))
1148: globusRSL.checkKeyInNS(profile);
1149:
1150: else if (profile.getProfileNamespace().equals(Profile.ENV))
1151: envVariables.checkKeyInNS(profile);
1152:
1153: else if (profile.getProfileNamespace().equals(Profile.VDS))
1154: vdsNS.checkKeyInNS(profile);
1155:
1156: else if (profile.getProfileNamespace().equals(
1157: Profile.DAGMAN))
1158: dagmanVariables.checkKeyInNS(profile);
1159: else {
1160: //unkown profile.
1161: mLogger.log("Unknown Profile: " + profile + " for job"
1162: + this .jobName,
1163: LogManager.WARNING_MESSAGE_LEVEL);
1164: }
1165:
1166: }
1167:
1168: }
1169:
1170: /**
1171: * Merges profiles from another job to this job in a controlled fashion.
1172: * The merging of the profile is dependant upon the namespace to which it
1173: * belongs. Some profiles maybe overriden, others maybe summed up etc.
1174: *
1175: * @param job the <code>SubInfo</code> object containing the job description
1176: * for the job whose profiles have to be merged into this job.
1177: *
1178: */
1179: public void mergeProfiles(SubInfo job) {
1180: this .globusRSL.merge(job.globusRSL);
1181: this .envVariables.merge(job.envVariables);
1182: this .condorVariables.merge(job.condorVariables);
1183: this .dagmanVariables.merge(job.dagmanVariables);
1184: this .vdsNS.merge(job.vdsNS);
1185: this .hints.merge(job.hints);
1186: }
1187:
1188: /**
1189: * Checks if an object is similar to the one referred to by this class.
1190: * We compare the primary key to determine if it is the same or not.
1191: *
1192: * @param obj the object for which equalsto is applied.
1193: *
1194: * @return true if the primary key (jobName) match.
1195: * else false.
1196: */
1197: public boolean equals(Object obj) {
1198: if (obj instanceof SubInfo) {
1199: SubInfo job = (SubInfo) obj;
1200:
1201: return job.jobName.equals(this .jobName) ? true : false;
1202: }
1203: //objects are of different type. cannot be compared
1204: return false;
1205: }
1206:
1207: /**
1208: * Returns a boolean value denoting whether the job is MPI or not.
1209: * If no job type is specified in the globus rsl for the job, the job is
1210: * assumed to be non mpi.
1211: *
1212: * @return boolean true if jobtype=mpi set in the globus rsl.
1213: * false in all other cases.
1214: */
1215: public boolean isMPIJob() {
1216: boolean mpi = false;
1217: //sanity checks
1218: if (this .globusRSL == null
1219: || !(globusRSL.containsKey("jobtype"))) {
1220: return false;
1221: }
1222:
1223: return (((String) globusRSL.get("jobtype"))
1224: .equalsIgnoreCase("mpi")) ? true : //the job type is set to mpi
1225: false;
1226:
1227: }
1228:
1229: /**
1230: * Returns whether a job should be run in the work directory or not.
1231: * If a job is not run in the work directory, then it should be run
1232: * in the submit directory. That would be the case if the job has been
1233: * scheduled to site "local" and the class of the job coressponds to the
1234: * auxillary jobs that have been created by Pegasus.
1235: *
1236: * @return boolean true to indicate job can run in work directory,
1237: * false job cant be run.
1238: */
1239: public boolean runInWorkDirectory() {
1240: return !(executionPool != null
1241: && executionPool.equalsIgnoreCase("local") && (jobClass > this .COMPUTE_JOB && jobClass <= this .CREATE_DIR_JOB));
1242: }
1243:
1244: /**
1245: * Resets all the profiles associated with the job.
1246: */
1247: public void resetProfiles() {
1248: envVariables = new ENV();
1249: globusRSL = new Globus();
1250: condorVariables = new Condor();
1251: dagmanVariables = new Dagman();
1252: hints = new Hints();
1253: vdsNS = new VDS();
1254: }
1255:
1256: /**
1257: * Returns a textual description of the object.
1258: *
1259: * @return textual description of the job.
1260: */
1261: public String toString() {
1262: String str = this .globusRSL == null ? null : this .globusRSL
1263: .toString();
1264: String cVar = this .condorVariables == null ? null
1265: : this .condorVariables.toString();
1266: String envStr = this .envVariables == null ? null
1267: : this .envVariables.toString();
1268:
1269: StringBuffer sb = new StringBuffer();
1270: String newline = System.getProperty("line.separator", "\r\n");
1271:
1272: sb.append("[");
1273: append(sb, "Job Name", this .jobName, newline);
1274: append(sb, "Logical Id", this .logicalId, newline);
1275: append(sb, "Transformation", this .getCompleteTCName(), newline);
1276: append(sb, "Derivation", this .getCompleteDVName(), newline);
1277: append(sb, "Level", new Integer(this .level).toString(), newline);
1278: append(sb, "Job Type Description",
1279: getJobTypeDescription(this .jobClass), newline);
1280: append(sb, "Job Id", this .jobID, newline);
1281: append(sb, "Executable", this .executable, newline);
1282: append(sb, "Condor Universe", this .condorUniverse, newline);
1283: append(sb, "Globus Scheduler", this .globusScheduler, newline);
1284: append(sb, "Standard Output", this .stdOut, newline);
1285: append(sb, "Standard Input", this .stdIn, newline);
1286: append(sb, "Standard Error", this .stdErr, newline);
1287: append(sb, "Argument String", this .strargs, newline);
1288: append(sb, "Execution Site", this .executionPool, newline);
1289: append(sb, "Globus RSL", str, newline);
1290: append(sb, "Environment Variables", envStr, newline);
1291: append(sb, "Dagman Variables", this .dagmanVariables, newline);
1292: append(sb, "Hints", this .hints, newline);
1293: append(sb, "Input Files ", this .inputFiles, newline);
1294: append(sb, "Output Files ", this .outputFiles, newline);
1295: append(sb, "Condor Variables\n", cVar, newline);
1296: append(sb, "VDS Profiles", vdsNS, newline);
1297: sb.append("]");
1298: return sb.toString();
1299:
1300: }
1301:
1302: /**
1303: * Returns the DOT description of the object. This is used for visualizing
1304: * the workflow.
1305: *
1306: * @return String containing the Partition object in XML.
1307: *
1308: * @exception IOException if something fishy happens to the stream.
1309: */
1310: public String toDOT() throws IOException {
1311: Writer writer = new StringWriter(32);
1312: toDOT(writer, "");
1313: return writer.toString();
1314: }
1315:
1316: /**
1317: * Returns the DOT description of the object. This is used for visualizing
1318: * the workflow.
1319: *
1320: * @param stream is a stream opened and ready for writing. This can also
1321: * be a StringWriter for efficient output.
1322: * @param indent is a <code>String</code> of spaces used for pretty
1323: * printing. The initial amount of spaces should be an empty
1324: * string. The parameter is used internally for the recursive
1325: * traversal.
1326: *
1327: *
1328: * @exception IOException if something fishy happens to the stream.
1329: */
1330: public void toDOT(Writer stream, String indent) throws IOException {
1331: String newLine = System.getProperty("line.separator", "\r\n");
1332:
1333: //write out the node
1334: stream.write(indent);
1335: stream.write(getID());
1336: stream.write(" ");
1337: stream.write("[");
1338:
1339: //write out the color for the node
1340: stream.write("color=");
1341: stream.write(getDOTColor());
1342: stream.write(",");
1343:
1344: //write out the style
1345: stream.write("style=filled,");
1346:
1347: //write out the label
1348: stream.write("label=");
1349: stream.write("\"");
1350: stream.write(getID());
1351: stream.write("\"");
1352:
1353: stream.write("]");
1354:
1355: stream.write(newLine);
1356: stream.flush();
1357: }
1358:
1359: /**
1360: * Returns the color with which DOT should color the node representing the
1361: * job.
1362: *
1363: * @return the color.
1364: */
1365: protected String getDOTColor() {
1366: int type = this .getJobType();
1367:
1368: String color;
1369: switch (type) {
1370:
1371: case 1: //this.COMPUTE_JOB:
1372: color = "blueviolet";
1373: break;
1374:
1375: case 2: //this.STAGE_IN_JOB:
1376: color = "gold";
1377: break;
1378:
1379: case 3: //this.STAGE_OUT_JOB:
1380: color = "goldenrod";
1381: break;
1382:
1383: case 5: //this.INTER_POOL_JOB:
1384: color = "goldenrod4";
1385: break;
1386:
1387: case 4: //this.REPLICA_REG_JOB:
1388: color = "orange";
1389: break;
1390:
1391: case 6: //this.CREATE_DIR_JOB:
1392: color = "darkturquoise";
1393: break;
1394:
1395: case 7: //this.STAGED_COMPUTE_JOB:
1396: color = "violet";
1397: break;
1398:
1399: case 8: //this.CLEANUP_JOB:
1400: color = "deepskyblue";
1401: break;
1402:
1403: default:
1404: color = "grey";
1405: }
1406:
1407: return color;
1408: }
1409:
1410: /**
1411: * Appends a key value mapping to the StringBuffer.
1412: *
1413: * @param sb StringBuffer to which the mapping has to be appended.
1414: * @param key the field.
1415: * @param value the value of the field.
1416: * @param newLine the newLineSeparator to be used.
1417: */
1418: private void append(StringBuffer sb, String key, Object value,
1419: String newLine) {
1420: String openingBrace = "{";
1421: String closingBrace = "}";
1422: String pointsTo = " -> ";
1423: String separator = ",";
1424: sb.append(newLine).append(openingBrace).append(key).append(
1425: pointsTo).append(value).append(closingBrace).append(
1426: separator);
1427: }
1428:
1429: }
|