Source Code Cross Referenced for Scriptor.java in  » Workflow-Engines » pegasus-2.1.0 » org » griphyn » vdl » planner » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Workflow Engines » pegasus 2.1.0 » org.griphyn.vdl.planner 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * This file or a portion of this file is licensed under the terms of
003:         * the Globus Toolkit Public License, found in file GTPL, or at
004:         * http://www.globus.org/toolkit/download/license.html. This notice must
005:         * appear in redistributions of this file, with or without modification.
006:         *
007:         * Redistributions of this Software, with or without modification, must
008:         * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009:         * some other similar material which is provided with the Software (if
010:         * any).
011:         *
012:         * Copyright 1999-2004 University of Chicago and The University of
013:         * Southern California. All rights reserved.
014:         */
015:
016:        package org.griphyn.vdl.planner;
017:
018:        import java.io.*;
019:        import java.util.*;
020:        import org.griphyn.common.util.Version;
021:        import org.griphyn.common.util.Currently;
022:        import org.griphyn.common.util.Separator;
023:        import org.griphyn.common.util.VDSProperties;
024:        import org.griphyn.vdl.Chimera;
025:        import org.griphyn.vdl.dax.*;
026:        import org.griphyn.vdl.classes.LFN;
027:        import org.griphyn.vdl.util.Logging;
028:        import org.griphyn.common.catalog.*;
029:        import org.griphyn.common.catalog.replica.*;
030:        import org.griphyn.common.catalog.transformation.TCMode;
031:
032:        /**
033:         * This class generates the shell scripts from a DAX. There is a script
034:         * for each job in the dag, and there is a control script to coordinate
035:         * these jobs.<p>
036:         *
037:         * The scripts are assembled mostly from template files and substitutions.
038:         * The template files reside in <code>$PEGASUS_HOME/share</code>:<p>
039:         *
040:         * <table border="1">
041:         * <tr><th>template</th><th>purpose</th></tr>
042:         * <tr><td>sp-job-1.tmpl</td><td>start of job script</td></tr>
043:         * <tr><td>sp-job-2.tmpl</td><td>unused</td></tr>
044:         * <tr><td>sp-job-3.tmpl</td><td>final portion of job script</td></tr>
045:         * <tr><td>sp-master-1.tmpl</td><td>start of master script</td></tr>
046:         * <tr><td>sp-master-2.tmpl</td><td>intermediary of master script</td></tr>
047:         * <tr><td>sp-master-3.tmpl</td><td>final portion of master script</td></tr>
048:         * <tr><td>sp-master-job.tmpl</td><td>Invocation of job from master</td></tr>
049:         * </table>
050:         *
051:         * The following substitutions are available by default. Some substitutions
052:         * are only available during job generation:<p>
053:         *
054:         * <table border="1">
055:         * <tr><th>variable</th><th>purpose</th></tr>
056:         * <tr><td>DAXLABEL</td><td>user-given label of the workflow</td></tr>
057:         * <tr><td>DV</td><td>Job: fully-qualified DV of job</td></tr>
058:         * <tr><td>FILELIST</td><td>Job: Name of file of output mappings</td></tr>
059:         * <tr><td>HOME</td><td>JRE system property user.home</td></tr>
060:         * <tr><td>JOBID</td><td>Job: the IDxxxxx of the current job</td></tr>
061:         * <tr><td>JOBLOG</td><td>Job: the log file of the job</td></tr>
062:         * <tr><td>JOBSCRIPT</td><td>Job: name of script file for job</td></tr>
063:         * <tr><td>KICKSTART</td><td>if set, path to local kickstart</td><tr>
064:         * <tr><td>LOGFILE</td><td>Name of master log file</td></tr>
065:         * <tr><td>NOW</td><tr>Start time stamp of processing (compile time)</td></tr>
066:         * <tr><td>REGISTER</td><td>0 or 1 for replica registration</td></tr>
067:         * <tr><td>TR</td><td>Job: fully-qualified TR of job</td></tr>
068:         * <tr><td>USER</td><td>JRE system property user.name</td></tr>
069:         * </table>
070:         * 
071:         * @author Jens-S. Vöckler
072:         * @author Yong Zhao
073:         * @version $Revision: 50 $
074:         *
075:         */
076:        public class Scriptor {
077:            /**
078:             * the directory to put the scripts
079:             */
080:            private String m_dirName;
081:
082:            /**
083:             * the dag structure
084:             */
085:            private ADAG m_adag;
086:
087:            /**
088:             * name of the dag
089:             */
090:            private String m_dagName;
091:
092:            /**
093:             * replica catalog
094:             */
095:            private RCWrapper m_rc;
096:
097:            /**
098:             * site catalog (optional)
099:             */
100:            private SCWrapper m_sc;
101:
102:            /**
103:             * transformation catalog
104:             */
105:            private TCWrapper m_tc;
106:
107:            /**
108:             * the hash that holds all the lfn->pfn mapping
109:             */
110:            private HashMap m_filenameMap;
111:
112:            /**
113:             * the name of the master log file.
114:             */
115:            private String m_logFile;
116:
117:            /**
118:             * whether to register output files
119:             */
120:            private boolean m_register;
121:
122:            /**
123:             * path to kickstart
124:             */
125:            private String m_kickstart;
126:
127:            /**
128:             * buffered writer for control script file
129:             */
130:            private BufferedWriter m_master;
131:
132:            /**
133:             * Stores the reference to the logger.
134:             */
135:            private Logging m_log;
136:
137:            /**
138:             * holds the location where templates reside.
139:             */
140:            private File m_dataDir;
141:
142:            /**
143:             * holds the mapping for permissable substitutions.
144:             */
145:            private Map m_substitute = null;
146:
147:            /**
148:             * a private copy of this environment's notion of a line separator.
149:             */
150:            private final static String newline = System.getProperty(
151:                    "line.separator", "\r\n");
152:
153:            /** 
154:             * Constructor
155:             *
156:             * @param dirName names the directory into which to produce the scripts.
157:             * @param adag is the DAX as a parsed data structure in memory.
158:             * @param rc is the replica catalog wrapper.
159:             * @param sc is the site catalog wrapper, may be <code>null</code>.
160:             * @param tc is the transformation catalog wrapper.
161:             * @param fnMap is a map containing all filesnames in the DAG. 
162:             * @param dataDir is the location of $PEGASUS_HOME/share from properties.
163:             */
164:            public Scriptor(String dirName, ADAG adag, RCWrapper rc,
165:                    SCWrapper sc, TCWrapper tc, HashMap fnMap, File dataDir) {
166:                m_dirName = dirName;
167:                m_adag = adag;
168:                m_dataDir = dataDir;
169:
170:                // set dag name
171:                m_dagName = adag.getName();
172:                if (m_dagName == null)
173:                    m_dagName = m_dirName;
174:
175:                m_rc = rc;
176:                m_sc = sc;
177:                m_tc = tc;
178:                m_filenameMap = fnMap;
179:
180:                m_logFile = m_dagName + ".log";
181:                m_register = true;
182:                m_kickstart = null;
183:                if (m_sc != null) {
184:                    String kl = m_sc.getGridLaunch();
185:                    if (kl != null) {
186:                        File k = new File(kl);
187:                        if (k.exists())
188:                            m_kickstart = kl;
189:                    }
190:                }
191:                m_log = Logging.instance();
192:
193:                // prepare substitutions
194:                m_substitute = new TreeMap();
195:                m_substitute.put("NOW", Currently.iso8601(false, true, false,
196:                        new Date()));
197:                m_substitute.put("DAXLABEL", m_dagName);
198:                m_substitute.put("USER", System.getProperty("user.name"));
199:                m_substitute.put("HOME", System.getProperty("user.home"));
200:                m_substitute.put("LOGFILE", m_logFile);
201:                if (m_kickstart != null)
202:                    m_substitute.put("KICKSTART", m_kickstart);
203:                m_substitute.put("REGISTER", m_register ? "1" : "0");
204:            }
205:
206:            /**
207:             * Sets the flag indicating whether to register output files.
208:             * @param b is a flag to set the registration state.
209:             * @see #getRegister()
210:             */
211:            public void setRegister(boolean b) {
212:                this .m_register = b;
213:                addSubstitution("REGISTER", b ? "1" : "0");
214:            }
215:
216:            /**
217:             * Gets the flag indicating whether to register output files.
218:             * @return true, if output files are going to be registered. 
219:             * @see #setRegister(boolean)
220:             */
221:            public boolean getRegister() {
222:                return this .m_register;
223:            }
224:
225:            /**
226:             * Sets kickstart path, if the path is null, kickstart will not be used.
227:             * @param kickstart the path to invoke kickstart
228:             * @see #getKickstart()
229:             */
230:            public void setKickstart(String kickstart) {
231:                m_kickstart = kickstart;
232:                if (kickstart != null)
233:                    addSubstitution("KICKSTART", kickstart);
234:                else
235:                    removeSubstitution("KICKSTART");
236:            }
237:
238:            /**
239:             * Gets the current kickstart path. The location may be null. 
240:             * @return the path to kickstart, or <code>null</code>
241:             * @see #setKickstart( String )
242:             */
243:            public String getKickstart() {
244:                return this .m_kickstart;
245:            }
246:
247:            /**
248:             * Inserts a substitution into the substitutable variables.
249:             *
250:             * @param key is the template variable name
251:             * @param value is the replacement 
252:             * @return the previous setting, or <code>null</code>.
253:             * @see #getSubstitution( String )
254:             */
255:            public String addSubstitution(String key, String value) {
256:                return (String) m_substitute.put(key, value);
257:            }
258:
259:            /**
260:             * Obtains the setting of a substitutable variable. 
261:             * @param key is the template variable name to query for.
262:             * @return the current setting, or <code>null</code>, if the
263:             * variable does not exist. 
264:             * @see #addSubstitution( String, String )
265:             */
266:            public String getSubstitution(String key) {
267:                String result = null;
268:
269:                if (m_substitute.containsKey(key)) {
270:                    result = (String) m_substitute.get(key);
271:                    if (result == null)
272:                        result = new String();
273:                }
274:
275:                return result;
276:            }
277:
278:            /** 
279:             * Removes a substition.
280:             * @param key is the template variable name to query for.
281:             * @return the current setting, or <code>null</code>, if the
282:             * variable does not exist. 
283:             * @see #addSubstitution( String, String )
284:             */
285:            public String removeSubstitution(String key) {
286:                return (String) m_substitute.remove(key);
287:            }
288:
289:            /**
290:             * Writes the control script head, including functions for file
291:             * registration.
292:             *
293:             * @return the name of the control (master) script.
294:             * @throws IOException if writing to the master script somehow failes.
295:             */
296:            public String initializeControlScript() throws IOException {
297:                // control script output filename
298:                String controlScript = m_dagName + ".sh";
299:                File controlFile = new File(m_dirName, controlScript);
300:                String fullPath = controlFile.getAbsolutePath();
301:
302:                // existence checks before overwriting
303:                if (controlFile.exists()) {
304:                    m_log.log("planner", 0, "Warning: Master file " + fullPath
305:                            + " already exists, overwriting");
306:                    controlFile.delete();
307:                }
308:
309:                // open master for writing
310:                m_master = new BufferedWriter(new FileWriter(controlFile));
311:
312:                // copy template while substituting
313:                m_log.log("planner", 1, "writing control script header");
314:                copyFromTemplate(m_master, "sp-master-1.tmpl");
315:
316:                // done
317:                return controlScript;
318:            }
319:
320:            /**
321:             * Adds scripts between stages.
322:             * @exception IOException if adding to the master script fails for
323:             * some reason.
324:             */
325:            public void intermediateControlScript() throws IOException {
326:                m_log
327:                        .log("planner", 1,
328:                                "writing control script between stages");
329:                copyFromTemplate(m_master, "sp-master-2.tmpl");
330:            }
331:
332:            /**
333:             * Write the control script tail to the control file.
334:             * @exception IOException if adding to the master script fails for
335:             * some reason.
336:             */
337:            public void finalizeControlScript() throws IOException {
338:                m_log.log("planner", 1, "writing control script tail");
339:                copyFromTemplate(m_master, "sp-master-3.tmpl");
340:
341:                // close master
342:                m_master.flush();
343:                m_master.close();
344:                m_master = null;
345:            }
346:
347:            /**
348:             * Converts a variable into the substituted value. Most of this is just
349:             * a hash lookup, but some are more dynamic.
350:             *
351:             * @param key is the variable to replace
352:             * @return the replacement string, which may be empty, never <code>null</code>.
353:             */
354:            private String convertVariable(String key) {
355:                if (key.equals("NOW")) {
356:                    return Currently.iso8601(false, true, false, new Date());
357:                } else {
358:                    return getSubstitution(key);
359:                }
360:            }
361:
362:            /**
363:             * Copies a template file into the open writer. During copy,
364:             * certain substitutions may take place. The substitutable variables
365:             * are dynamically adjusted from the main class.
366:             *
367:             * @param w is the writer open for writing.
368:             * @param tfn is the template base file name.
369:             * @throws IOException in case some io operation goes wrong.
370:             */
371:            public void copyFromTemplate(Writer w, String tfn)
372:                    throws IOException {
373:                // determine location
374:                File source = new File(m_dataDir, tfn);
375:                if (source.exists()) {
376:                    // template exists, use it
377:                    LineNumberReader lnr = new LineNumberReader(new FileReader(
378:                            source));
379:
380:                    String line, key, value;
381:                    while ((line = lnr.readLine()) != null) {
382:                        StringBuffer sb = new StringBuffer(line);
383:
384:                        // substitute all substitutables
385:                        int circuitBreaker = 0;
386:                        for (int p1 = sb.indexOf("@@"); p1 != -1; p1 = sb
387:                                .indexOf("@@")) {
388:                            int p2 = sb.indexOf("@@", p1 + 2) + 2;
389:                            if (p2 == -1)
390:                                throw new IOException(
391:                                        "unclosed @@var@@ element");
392:                            key = sb.substring(p1 + 2, p2 - 2);
393:                            if ((value = convertVariable(key)) == null) {
394:                                // does not exist
395:                                m_log
396:                                        .log(
397:                                                "planner",
398:                                                0,
399:                                                "Warning: "
400:                                                        + source
401:                                                        + ":"
402:                                                        + lnr.getLineNumber()
403:                                                        + ": Requesting unknown substitution for "
404:                                                        + key);
405:                                value = new String();
406:                            } else {
407:                                // protocol substitution
408:                                m_log.log("planner", 3, "Substituting " + key
409:                                        + " => " + value);
410:                            }
411:                            sb.replace(p1, p2, value);
412:
413:                            if (++circuitBreaker > 32) {
414:                                m_log.log("planner", 0, "Warning: "
415:                                        + lnr.getLineNumber()
416:                                        + ": circuit breaker triggered");
417:                                break;
418:                            }
419:                        }
420:
421:                        w.write(sb.toString());
422:                        w.write(newline);
423:                    }
424:
425:                    // free file handle resource
426:                    lnr.close();
427:                } else {
428:                    // template does not exist
429:                    throw new IOException("template " + tfn + " not found");
430:                }
431:            }
432:
433:            /**
434:             * Processes each job in the adag. Also checks for input file
435:             * existence, if necessary.
436:             *
437:             * @param jobID is the DAX-unique job id to generate a scripts for.
438:             * @param checkInputFiles if set, checks in the filesystem for the
439:             * existence of all input files into the job.
440:             * @return the name of the job control script.
441:             * @throws IOException for failure to write any job related files.
442:             */
443:            public String processJob(String jobID, boolean checkInputFiles)
444:                    throws IOException {
445:                Logging.instance()
446:                        .log("planner", 0, "processing job: " + jobID);
447:
448:                // get the job reference from ADAG
449:                Job job = m_adag.getJob(jobID);
450:
451:                // script file for this job
452:                String scriptBase = job.getName() + "_" + jobID;
453:                String scriptFile = scriptBase + ".sh";
454:
455:                // file to hold the output file list
456:                String outputList = scriptBase + ".lst";
457:                File of = new File(m_dirName, outputList);
458:                String outputFullPath = of.getAbsolutePath();
459:                if (of.exists()) {
460:                    m_log.log("planner", 0, "Warning: output list file "
461:                            + outputList + " already exists, overwriting");
462:                    of.delete();
463:                }
464:
465:                // add to substitutions - temporarily
466:                addSubstitution("JOBSCRIPT", scriptFile);
467:                addSubstitution("FILELIST", outputList);
468:                addSubstitution("JOBID", jobID);
469:                addSubstitution("TR", Separator.combine(job.getNamespace(), job
470:                        .getName(), job.getVersion()));
471:                addSubstitution("DV", Separator.combine(job.getDVNamespace(),
472:                        job.getDVName(), job.getDVVersion()));
473:
474:                // create file with all mappings for just this job
475:                BufferedWriter obw = new BufferedWriter(new FileWriter(of));
476:                Map lfnMap = new HashMap(); // store mappings for job
477:
478:                for (Iterator i = job.iterateUses(); i.hasNext();) {
479:                    Filename fn = (Filename) i.next();
480:                    String lfn = fn.getFilename();
481:
482:                    // look up LFN in hash
483:                    String pfn = (String) m_filenameMap.get(lfn);
484:                    if (pfn == null) {
485:                        // can't find the lfn in the filename list
486:                        m_log.log("planner", 0, "ERROR: LFN " + lfn
487:                                + "is not in the "
488:                                + "<filename> list, please check the DAX!");
489:                        return null;
490:                    } else {
491:                        lfnMap.put(lfn, pfn);
492:                    }
493:
494:                    // check if input files exist
495:                    if (checkInputFiles) {
496:                        if (fn.getLink() == LFN.INPUT) {
497:                            if (!(new File(pfn)).canRead()) {
498:                                m_log.log("planner", 0,
499:                                        "Warning: Unable to read LFN " + lfn);
500:                            }
501:                        }
502:                    }
503:
504:                    // write the output file list entry: LFN PFN [abs]
505:                    if (fn.getLink() == LFN.OUTPUT) {
506:                        obw.write(lfn + " " + pfn + newline);
507:                    }
508:                }
509:
510:                // finish writing file of output files
511:                obw.flush();
512:                obw.close();
513:
514:                // generate the script for this job
515:                boolean result = generateJobScript(job, scriptFile, outputList,
516:                        lfnMap);
517:                if (result) {
518:                    // OK: now add script invocation to master
519:                    m_log.log("planner", 1, "adding job " + jobID
520:                            + " to master script");
521:                    copyFromTemplate(m_master, "sp-master-job.tmpl");
522:                } else {
523:                    m_log.log("planner", 0, "Warning: ignoring script "
524:                            + scriptFile);
525:                }
526:
527:                // always clean up
528:                removeSubstitution("JOBSCRIPT");
529:                removeSubstitution("FILELIST");
530:                removeSubstitution("JOBID");
531:                removeSubstitution("TR");
532:                removeSubstitution("DV");
533:
534:                return (result ? scriptFile : null);
535:            }
536:
537:            /**
538:             * Extracts all profiles contained within the job description.
539:             *
540:             * @param job is the job description from the DAX
541:             * @param lfnMap is the mapping to PFNs.
542:             * @return a map of maps. The outer map is indexed by the lower-cased
543:             * namespace identifier. The inner map is indexed by the key within
544:             * the particular namespace. An empty map is possible.
545:             */
546:            private Map extractProfilesFromJob(Job job, Map lfnMap) {
547:                Map result = new HashMap();
548:                Map submap = null;
549:
550:                for (Iterator i = job.iterateProfile(); i.hasNext();) {
551:                    org.griphyn.vdl.dax.Profile p = (org.griphyn.vdl.dax.Profile) i
552:                            .next();
553:                    String ns = p.getNamespace().trim().toLowerCase();
554:                    String key = p.getKey().trim();
555:
556:                    // recreate the vlaue
557:                    StringBuffer sb = new StringBuffer(8);
558:                    for (Iterator j = p.iterateLeaf(); j.hasNext();) {
559:                        Leaf l = (Leaf) j.next();
560:                        if (l instanceof  PseudoText) {
561:                            sb.append(((PseudoText) l).getContent());
562:                        } else {
563:                            String lfn = ((Filename) l).getFilename();
564:                            sb.append((String) lfnMap.get(lfn));
565:                        }
566:                    }
567:                    String value = sb.toString().trim();
568:
569:                    // insert at the right place into the result map
570:                    if (result.containsKey(ns)) {
571:                        submap = (Map) result.get(ns);
572:                    } else {
573:                        result.put(ns, (submap = new HashMap()));
574:                    }
575:                    submap.put(key, value);
576:                }
577:
578:                return result;
579:            }
580:
581:            /**
582:             * Combines profiles from two map of maps, with regards to priority.
583:             *
584:             * @param high is the higher priority profile
585:             * @param low is the lower priority profile
586:             * @return a new map with the combination of the two profiles
587:             */
588:            private Map combineProfiles(Map high, Map low) {
589:                Set allKeys = new TreeSet(low.keySet());
590:                allKeys.addAll(high.keySet());
591:
592:                Map result = new HashMap();
593:                for (Iterator i = allKeys.iterator(); i.hasNext();) {
594:                    String key = (String) i.next();
595:                    boolean h = high.containsKey(key);
596:                    boolean l = low.containsKey(key);
597:                    if (h && l) {
598:                        Map temp = new HashMap((Map) low.get(key));
599:                        temp.putAll((Map) high.get(key));
600:                        result.put(key, temp);
601:                    } else {
602:                        if (h)
603:                            result.put(key, high.get(key));
604:                        else
605:                            result.put(key, low.get(key));
606:                    }
607:                }
608:
609:                return result;
610:            }
611:
612:            /**
613:             * Extracts the environment settings from the combined profiles.
614:             *
615:             * @param profiles is the combined profile map of maps
616:             * @return a string with combined profiles, or <code>null</code>,
617:             * if not applicable.
618:             */
619:            private String extractEnvironment(Map profiles) {
620:                String result = null;
621:
622:                if (profiles.containsKey("env")) {
623:                    StringBuffer sb = new StringBuffer();
624:                    Map env = (Map) profiles.get("env");
625:                    for (Iterator i = env.keySet().iterator(); i.hasNext();) {
626:                        String key = (String) i.next();
627:                        String value = (String) env.get(key);
628:
629:                        sb.append(key).append("='").append(value);
630:                        sb.append("'; export ").append(key).append(newline);
631:                    }
632:                    result = sb.toString();
633:                }
634:
635:                return result;
636:            }
637:
638:            /**
639:             * Generates the script for each job.
640:             *
641:             * @param job is an ADAG job for which to generate the script.
642:             * @param scriptFile is the basename of the script for the job.
643:             * @param outputList is the name of a file containing output files. 
644:             * @param lfnMap is a map of LFN to PFN. 
645:             * @return true if all is well, false to signal an error
646:             */
647:            private boolean generateJobScript(Job job, String scriptFile,
648:                    String outputList, Map lfnMap) throws IOException {
649:                String jobID = job.getID();
650:                File f = new File(m_dirName, scriptFile);
651:                String scriptFullPath = f.getAbsolutePath();
652:                if (f.exists()) {
653:                    m_log.log("planner", 1, "Warning: Script file "
654:                            + scriptFile + " already exists, overwriting");
655:                    f.delete();
656:                }
657:
658:                // kickstart output file
659:                // String kickLog = scriptFullPath.substring(0,scriptFullPath.length()-3) + ".out";
660:                String kickLog = scriptFile.substring(0,
661:                        scriptFile.length() - 3)
662:                        + ".out";
663:
664:                BufferedWriter bw = new BufferedWriter(new FileWriter(f));
665:                copyFromTemplate(bw, "sp-job-1.tmpl");
666:
667:                // full definition name of this job's transformation
668:                String fqdn = Separator.combine(job.getNamespace(), job
669:                        .getName(), job.getVersion());
670:
671:                // extract TR profiles
672:                Map tr_profiles = extractProfilesFromJob(job, lfnMap);
673:
674:                // lookup job in TC
675:                List tc = m_tc.lookup(job.getNamespace(), job.getName(), job
676:                        .getVersion(), "local");
677:                if (tc == null || tc.size() == 0) {
678:                    m_log.log("planner", 0, "ERROR: Transformation " + fqdn
679:                            + " on site \"local\" not found in TC");
680:                    return false;
681:                } else if (tc.size() > 1) {
682:                    m_log.log("planner", 0, "Warning: Found " + tc.size()
683:                            + " matches for " + fqdn + " in TC, using first");
684:                }
685:                TransformationCatalogEntry tce = (TransformationCatalogEntry) tc
686:                        .get(0);
687:
688:                // extract SC profiles
689:                Map sc_profiles = (m_sc == null ? new HashMap() : m_sc
690:                        .getProfiles());
691:
692:                // extract TC profiles
693:                Map tc_profiles = m_tc.getProfiles(tce);
694:
695:                // combine profiles by priority
696:                Map temp = combineProfiles(tc_profiles, sc_profiles);
697:                Map profiles = combineProfiles(temp, tr_profiles);
698:
699:                // pfnHint has been deprecated !
700:                if (profiles.containsKey("hints")) {
701:                    m_log.log("planner", 0,
702:                            "Warning: The hints profile namespace "
703:                                    + "has been deprecated, ignoring keys "
704:                                    + ((Map) profiles.get("hints")).keySet()
705:                                            .toString());
706:                }
707:
708:                // assemble environment variables from profile
709:                String executable = tce.getPhysicalTransformation();
710:                String environment = extractEnvironment(profiles);
711:
712:                // for web service
713:                boolean service = profiles.containsKey("ws");
714:                String invokews = null;
715:                String wsenv = null;
716:
717:                if (service) {
718:                    // lookup special web service invocation executable
719:                    tc = m_tc.lookup(null, "invokews", null, "local");
720:                    if (tc == null || tc.size() == 0) {
721:                        // not found
722:                        m_log.log("planner", 0,
723:                                "ERROR: Transformation invokews not found!");
724:                        return false;
725:                    } else if (tc.size() > 1) {
726:                        m_log.log("planner", 0, "Warning: Found " + tc.size()
727:                                + " matches for invokews in TC, using first");
728:                    }
729:                    tce = (TransformationCatalogEntry) tc.get(0);
730:                    invokews = tce.getPhysicalTransformation();
731:
732:                    // combine profiles by priority
733:                    temp = combineProfiles(m_tc.getProfiles(tce), sc_profiles);
734:                    // wsenv = extractEnvironment( combineProfiles( temp, tr_profiles ) );
735:                    wsenv = extractEnvironment(temp);
736:                }
737:
738:                // collect commandline arguments for invocation
739:                StringBuffer argument = new StringBuffer();
740:                for (Iterator i = job.iterateArgument(); i.hasNext();) {
741:                    Leaf l = (Leaf) i.next();
742:                    if (l instanceof  PseudoText) {
743:                        argument.append(((PseudoText) l).getContent());
744:                    } else {
745:                        String lfn = ((Filename) l).getFilename();
746:                        argument.append(lfnMap.get(lfn));
747:                    }
748:                }
749:
750:                StringBuffer ks_arg = null;
751:                if (m_kickstart != null) {
752:                    ks_arg = new StringBuffer(80);
753:                    ks_arg.append("-R local -l ").append(kickLog);
754:                    ks_arg.append(" -n \"").append(getSubstitution("TR"));
755:                    ks_arg.append("\" -N \"").append(getSubstitution("DV"));
756:                    ks_arg.append('"');
757:                }
758:
759:                // process stdin
760:                Filename fn = job.getStdin();
761:                if (fn != null) {
762:                    if (m_kickstart != null) {
763:                        ks_arg.append(" -i ").append(
764:                                (String) lfnMap.get(fn.getFilename()));
765:                    } else {
766:                        argument.append(" < ").append(
767:                                (String) lfnMap.get(fn.getFilename()));
768:                    }
769:                }
770:
771:                // process stdout
772:                fn = job.getStdout();
773:                if (fn != null) {
774:                    if (m_kickstart != null) {
775:                        ks_arg.append(" -o ").append(
776:                                (String) lfnMap.get(fn.getFilename()));
777:                    } else {
778:                        argument.append(" > ").append(
779:                                (String) lfnMap.get(fn.getFilename()));
780:                    }
781:                }
782:
783:                // process stderr
784:                fn = job.getStderr();
785:                if (fn != null) {
786:                    if (m_kickstart != null) {
787:                        ks_arg.append(" -e ").append(
788:                                (String) lfnMap.get(fn.getFilename()));
789:                    } else {
790:                        argument.append(" 2> ").append(
791:                                (String) lfnMap.get(fn.getFilename()));
792:                    }
793:                }
794:
795:                // environment of job
796:                if (environment != null) {
797:                    bw.write("# regular job environment setup" + newline
798:                            + environment + newline);
799:                }
800:
801:                if (service) {
802:                    //
803:                    // web service invocation
804:                    //
805:                    Map in = (Map) profiles.get("ws");
806:                    Map out = new HashMap(in.size());
807:                    for (Iterator i = in.keySet().iterator(); i.hasNext();) {
808:                        String key = (String) i.next();
809:                        String value = (String) in.get(key);
810:                        out.put(key.trim().toLowerCase(), value.trim());
811:                    }
812:
813:                    // check that all required arguments are present
814:                    if (!(out.containsKey("porttype")
815:                            && out.containsKey("operation") && out
816:                            .containsKey("input"))) {
817:                        m_log.log("planner", 0,
818:                                "ERROR: You must specify portType, operation, and input "
819:                                        + "for a web service invocation!");
820:                        return false;
821:                    }
822:
823:                    // extra environment for web service? 
824:                    if (wsenv != null) {
825:                        bw.write("# extra WS invocation environment" + newline
826:                                + wsenv + newline);
827:                    }
828:
829:                    // invocation of web service
830:                    bw.write(invokews + " -I " + out.get("input"));
831:                    if (out.containsKey("output"))
832:                        bw.write(" -O " + out.get("output"));
833:
834:                    // rest of invocation
835:                    bw
836:                            .write(" -p " + out.get("porttype") + " -o "
837:                                    + out.get("operation") + " " + executable
838:                                    + newline);
839:                } else {
840:                    //
841:                    // call the executable with argument in the script
842:                    //
843:                    if (m_kickstart != null)
844:                        bw.write(m_kickstart + " " + ks_arg.toString() + " ");
845:
846:                    bw.write(executable + " " + argument + newline);
847:                }
848:
849:                copyFromTemplate(bw, "sp-job-3.tmpl");
850:
851:                // done
852:                bw.flush();
853:                bw.close();
854:                return true;
855:            }
856:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.