/** * Copyright 2007-2008 University Of Southern California * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package edu.isi.pegasus.planner.code.gridstart; import edu.isi.pegasus.common.logging.LogManagerFactory; import edu.isi.pegasus.planner.classes.Job; import edu.isi.pegasus.planner.common.PegasusProperties; import edu.isi.pegasus.common.logging.LogManager; import edu.isi.pegasus.planner.namespace.Dagman; import edu.isi.pegasus.planner.code.POSTScript; import java.io.File; /** * This postscript invokes the netlogger-exitcode to parse the kickstart * output and write out in netlogger format. * * * @author Karan Vahi vahi@isi.edu * @version $Revision$ */ public class NetloggerPostScript implements POSTScript { /** * The SHORTNAME for this implementation. */ public static final String SHORT_NAME = "Netlogger"; /** * The property to be set for postscript to pick up workflow id */ public static final String WORKFLOW_ID_PROPERTY = "pegasus.gridstart.workflow.id" ; /** * The LOG4j system configuration property. */ private static String LOG4J_CONF_PROPERTY = "log4j.configuration"; /** * The LogManager object which is used to log all the messages. */ protected LogManager mLogger; /** * The object holding all the properties pertaining to Pegasus. */ protected PegasusProperties mProps; /** * The path to the user postscript on the submit host. * */ protected String mPOSTScriptPath; /** * The path to the properties file created in submit directory. */ private String mPostScriptProperties; /** * the workflow id used. */ private String mWorkflowID; /** * The log4j system property */ private String mLog4jConf; /** * The default constructor. */ public NetloggerPostScript(){ //mLogger = LogManager.getInstance(); mLog4jConf = System.getProperty( NetloggerPostScript.LOG4J_CONF_PROPERTY ); } /** * Initialize the POSTScript implementation. * * @param properties the <code>PegasusProperties</code> object containing all * the properties required by Pegasus. * @param path the path to the POSTScript on the submit host. * @param submitDir the submit directory where the submit file for the job * has to be generated. * @param globalLog a global log file to use for logging * * @throws RuntimeException in case of path being null. */ public void initialize( PegasusProperties properties, String path, String submitDir , String globalLog ){ mProps = properties; mPOSTScriptPath = path == null ? this.getNetloggerExitCodePath() :path ; mLogger = LogManagerFactory.loadSingletonInstance( properties ); mPostScriptProperties = getPostScriptProperties( properties ); mWorkflowID = properties.getProperty( this.WORKFLOW_ID_PROPERTY ); } /** * Constructs the postscript that has to be invoked on the submit host * after the job has executed on the remote end. The postscript works on the * stdout of the remote job, that has been transferred back to the submit * host by Condor. * <p> * The postscript is constructed and populated as a profile * in the DAGMAN namespace. * * * @param job the <code>Job</code> object containing the job description * of the job that has to be enabled on the grid. * @param key the <code>DAGMan</code> profile key that has to be inserted. * * @return boolean true if postscript was generated,else false. */ public boolean construct(Job job, String key) { boolean constructed = false; //see if any specific postscript was specified for this job //get the value user specified for the job String postscript = mPOSTScriptPath; job.dagmanVariables.construct( Dagman.OUTPUT_KEY, (String) job.condorVariables.get( "output" ) ); ///// StringBuffer extraOptions = new StringBuffer(); //put in the postscript properties if any extraOptions.append( this.mPostScriptProperties ); //add the log4j conf option if specified if( mLog4jConf != null ){ extraOptions.append( " -D" ).append( NetloggerPostScript.LOG4J_CONF_PROPERTY ). append( "=" ).append( mLog4jConf ); } //add the -j and -w options extraOptions.append( " -j " ).append( job.getID() ). append( " -w " ).append( mWorkflowID ).append( " -f "); //put the extra options into the exitcode arguments //in the correct order. Object args = job.dagmanVariables.get( Dagman.POST_SCRIPT_ARGUMENTS_KEY ); StringBuffer arguments = (args == null ) ? //only have extra options extraOptions : //have extra options in addition to existing args new StringBuffer().append( extraOptions ) .append( " " ).append( args ); job.dagmanVariables.construct( Dagman.POST_SCRIPT_ARGUMENTS_KEY, arguments.toString() ); ////// constructed = true; //put in the postscript mLogger.log("Postscript constructed is " + postscript, LogManager.DEBUG_MESSAGE_LEVEL); job.dagmanVariables.checkKeyInNS( key, postscript ); // else{ // //Karan Nov 15,2005 VDS BUG FIX 128 // //Always remove POST_SCRIPT_ARGUMENTS // job.dagmanVariables.removeKey(Dagman.POST_SCRIPT_ARGUMENTS_KEY); // } return constructed; } /** * Returns a short textual description of the implementing class. * * @return short textual description. */ public String shortDescribe(){ return this.SHORT_NAME; } /** * Returns the path to exitcode that is to be used on the kickstart * output. * * @return the path to the exitcode script to be invoked. */ public String getNetloggerExitCodePath(){ StringBuffer sb = new StringBuffer(); sb.append(mProps.getBinDir()); sb.append(File.separator).append("netlogger-exitcode"); return sb.toString(); } /** * Returns the properties that need to be passed to the the postscript * invocation in the java format. It is of the form * "-Dprop1=value1 -Dprop2=value2 .." * * @param properties the properties object * * @return the properties list, else empty string. */ protected String getPostScriptProperties( PegasusProperties properties ){ StringBuffer sb = new StringBuffer(); appendProperty( sb, "pegasus.user.properties", properties.getPropertiesInSubmitDirectory( )); return sb.toString(); } /** * Appends a property to the StringBuffer, in the java command line format. * * @param sb the StringBuffer to append the property to. * @param key the property. * @param value the property value. */ protected void appendProperty( StringBuffer sb, String key, String value ){ sb.append( " ").append("-D").append( key ).append( "=" ).append( value ); } }