/**
* 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.classes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import edu.isi.pegasus.common.util.Version;
import edu.isi.pegasus.planner.common.PegasusProperties;
import java.io.File;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.Properties;
/**
* A Data class containing the metrics about the planning instance.
*
* @author Karan Vahi
* @version $Revision$
*/
public class PlannerMetrics extends Data{
/**
* The base submit directory where the files are being created.
*/
private String mBaseSubmitDirectory;
/**
* The relative submit directory for this run.
*/
private String mRelativeSubmitDirectory;
/*
* The file to which the metrics should be written out in the submit directory
*/
private File mMetricsFileInSubmitDirectory;
/**
* The path to the DAX that was planned by the workflow.
*/
private String mDAXPath;
/**
* The pointer to the properties file that was used.
*/
private String mPropertiesPath;
/**
* The user who planned the workflow.
*/
private String mUser;
/**
* The VOGroup to which the user belonged to.
*/
private String mVOGroup;
/**
* The number formatter to format the run submit dir entries.
*/
private NumberFormat mNumFormatter;
/**
* The name of the client
*/
@Expose @SerializedName( "client" ) private final String mClient = "pegasus-plan";
/**
* The planner version
*/
@Expose @SerializedName( "version" ) private final String mVersion = new Version().getVersion();
/**
* The name of the client
*/
@Expose @SerializedName( "type" ) private String mType ;
/**
* The start time for the planning.
*/
@Expose @SerializedName("start_time") private double mStartTime;
/**
* The end time for the planning.
*/
@Expose @SerializedName("end_time") private double mEndTime;
/**
* The planning duration
*/
@Expose @SerializedName("duration") private double mDuration;
/**
* the exitcode of the planner
*/
@Expose @SerializedName("exitcode") private int mExitcode;
/**
* The Root Workflow UUID.
*/
@Expose @SerializedName( "root_wf_uuid" ) private String mRootWorkflowUUID;
/**
* The UUID associated with the workflow.
*/
@Expose @SerializedName( "wf_uuid" ) private String mWorkflowUUID;
/**
* The data configuration mode
*/
@Expose @SerializedName( "data_config" )private String mDataConfiguration;
/**
* The arguments with which the planner was invoked with
*/
@Expose @SerializedName( "planner_args" )private String mPlannerArguments;
/**
* A boolean indicating whether pmc was used or not.
*/
@Expose @SerializedName( "uses_pmc" )private boolean mUsesPMC;
/**
* The metrics about the workflow.
*/
@Expose @SerializedName("wf_metrics") private WorkflowMetrics mWFMetrics;
/**
* The application metrics that need to be forwarded
*/
@Expose @SerializedName( "app_metrics" ) private Properties mApplicationMetrics;
/**
* The error message to be logged
*/
@Expose @SerializedName( "error" ) private String mErrorMessage;
/**
* The default metrics.
*/
public PlannerMetrics() {
//the exitcode is explicitly set to -1
//it should be set when the planner ends with the correct exitcode
mExitcode = -1;
mNumFormatter = new DecimalFormat( "#.###" );
mType = "metrics";
mPlannerArguments = "";
mUsesPMC = false;
//we want metrics to be serialized only if user specified
//mApplicationMetrics = new Properties();
}
/**
* Returns the UUID for the Root workflow
*
* @return the UUID of the workflow
*/
public String getRootWorkflowUUID() {
return this.mRootWorkflowUUID;
}
/**
* Sets the root UUID for the workflow
*
* @param uuid the UUID of the workflow
*/
public void setRootWorkflowUUID( String uuid ) {
this.mRootWorkflowUUID = uuid;
}
/**
* Returns the UUID for the workflow
*
* @return the UUID of the workflow
*/
public String getWorkflowUUID() {
return this.mWorkflowUUID;
}
/**
* Sets the UUID for the workflow
*
* @param uuid the UUID of the workflow
*/
public void setWorkflowUUID( String uuid ) {
this.mWorkflowUUID = uuid;
}
/**
* Returns the workflow metrics.
*
* @return the workflow metrics.
*/
public WorkflowMetrics getWorkflowMetrics(){
return mWFMetrics;
}
/**
* Sets the workflow metrics.
*
* @param metrics the workflow metrics.
*/
public void setWorkflowMetrics( WorkflowMetrics metrics ){
mWFMetrics = metrics;
}
/**
* Sets the app metrics that need to be forwarded.
*
* @param metrics the application metrics
*/
public void setApplicationMetrics( Properties properties ){
this.mApplicationMetrics = properties;
}
/**
* Sets the app metrics that need to be forwarded.
*
* @param metrics the application metrics
*/
public void setApplicationMetrics( PegasusProperties properties ){
//figure out the application name if set
String name = properties.getProperty( PegasusProperties.PEGASUS_APP_METRICS_PREFIX );
if( name != null ){
mApplicationMetrics = properties.matchingSubset( PegasusProperties.PEGASUS_APP_METRICS_PREFIX, false );
//add the name
mApplicationMetrics.setProperty( "name", name );
}
}
/**
* Returns the application specific metrics that will be forwarded to the
* server
*
* @return the application metrics
*/
public Properties getApplicationMetrics( ){
return this.mApplicationMetrics;
}
/**
* Returns the username.
*
* @return the user.
*/
public String getUser( ){
return mUser;
}
/**
* Sets the user.
*
* @param user the user.
*/
public void setUser( String user ){
mUser = user;
}
/**
* Sets the metrics
*
* @param type the metrics type
*/
public void setMetricsType( String type ){
mType = type;
}
/**
* Convenience setter method
*
* @param type the metrics type
*/
public void setMetricsTypeToError( ){
mType = "error";
}
/**
* Returns the metric type
*
* @return metrics type
*/
public String getMetricsType( ){
return mType;
}
/**
* Sets the vo group
*
* @param group the vo group.
*/
public void setVOGroup( String group ){
this.mVOGroup = group;
}
/**
* Returns the VO Group.
*
* @return the VO Group to which the user belongs
*/
public String getVOGroup( ){
return this.mVOGroup;
}
/**
* Sets the path to the properties file for the run.
*
* @param path the path to the properties file.
*/
public void setProperties( String path ){
mPropertiesPath = path;
}
/**
* Returns the path to the properties file for the run.
*
* @return the path to the properties file.
*/
public String getProperties( ){
return mPropertiesPath;
}
/**
* Sets the path to the base submit directory.
*
* @param base the path to the base submit directory.
*/
public void setBaseSubmitDirectory( String base ){
mBaseSubmitDirectory = base;
}
/**
* Returns the path to the base submit directory.
*
* @return the path to the base submit directory.
*/
public String getBaseSubmitDirectory( ){
return mBaseSubmitDirectory;
}
/**
* Sets the path to the submit directory relative to the base.
*
* @param relative the relative path from the base submit directory.
*/
public void setRelativeSubmitDirectory( String relative ){
mRelativeSubmitDirectory = relative;
}
/**
* Returns the path to the relative submit directory.
*
* @return the path to the relative submit directory.
*/
public String getRelativeSubmitDirectory( ){
return mRelativeSubmitDirectory;
}
/**
* Sets the metrics file location in the submit directory
*
* @param f the file pointing to the metrics file
*/
public void setMetricsFileLocationInSubmitDirectory( File f ){
this.mMetricsFileInSubmitDirectory = f;
}
/**
* Sets the metrics file location in the submit directory
*
* @return the file pointing to the metrics file. can be null
*/
public File getMetricsFileLocationInSubmitDirectory( ){
return this.mMetricsFileInSubmitDirectory;
}
/**
* Sets the path to the DAX.
*
* @param path the path to the DAX file.
*/
public void setDAX( String path ){
mDAXPath = path;
}
/**
* Sets the path to the DAX.
*
* @return the path to the DAX file.
*/
public String getDAX( ){
return mDAXPath;
}
/**
* The data configuration
*
* @param configuration the data configuration
*/
public void setDataConfiguration(String configuration) {
mDataConfiguration = configuration;
}
/**
* Returns the data configuration
*
* @return the data configuration
*/
public String getDataConfiguration( ) {
return mDataConfiguration ;
}
/**
* Sets the planner options
*
* @param options options
*/
public void setPlannerOptions(PlannerOptions options) {
this.setPlannerOptions( options.getOriginalArgString() );
}
/**
*Sets The planner options
*
* @param arguments options
*/
public void setPlannerOptions(String arguments) {
mPlannerArguments = arguments;
}
/**
* Returns the planner arguments
*
* @return the data configuration
*/
public String getPlannerArguments( ) {
return mPlannerArguments ;
}
/**
* Returns boolean indicating whether PMC was used or not
*
* @return
*/
public boolean usesPMC() {
return this.mUsesPMC;
}
/**
* Sets the uses PMC parameter
*
* @param usesPMC
*/
public void setUsesPMC(boolean usesPMC) {
mUsesPMC = usesPMC;
}
/**
* Set the start time for the planning operation.
*
* @param start the start time.
*/
public void setStartTime( Date start ){
double t = start.getTime();
//mStartTime = mNumFormatter.format( t/1000 );
mStartTime = t/1000;
}
/**
* Set the start time for the planning operation.
*
* @param start the start time.
*/
public void setStartTime( double start ){
mStartTime = start;
}
/**
* Returns the start time for the planning operation as epoch with
* millisecond precision
*
* @return the start time.
*/
public double getStartTime( ){
return mStartTime;
}
/**
* Set the end time for the planning operation.
*
* @param end the end time.
*/
public void setEndTime( Date end ){
double t = end.getTime();
//mEndTime = mNumFormatter.format( t/1000 );
mEndTime = t/1000;
}
/**
* Set the end time for the planning operation.
*
* @param end the end time.
*/
public void setEndTime( double end ){
mEndTime = end;
}
/**
* Returns the end time for the planning operation as epoch with
* millisecond precision
*
* @return the end time.
*/
public double getEndTime( ){
return mEndTime;
}
/**
* Returns the duration for the planning
*
* @return the duration
*/
public double getDuration( ){
return mDuration;
}
/**
* Sets the user.
*
* @param duration the duration
*/
public void setDuration( double duration ){
mDuration = duration;
}
/**
* Returns the exitcode for the planner
*
* @return the exitcode
*/
public int getExitcode( ){
return mExitcode;
}
/**
* Sets the exitcode for the planner.
*
* @param exitcode the exitcode
*/
public void setExitcode( int exitcode ){
mExitcode = exitcode;
}
/**
* Set the error message that we want to log
*
* @param error error
*/
public void setErrorMessage(String error ) {
mErrorMessage = error;
}
/**
* Returns the error message that we want to log
*
* @return the error message
*/
public String getErrorMessage( ) {
return mErrorMessage;
}
/**
* Converts the planner metrics to JSON
*
* @return the planner metrics in JSON
*/
public String toJson(){
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
return gson.toJson( this );
}
/**
* Converts the planner metrics to JSON
*
* @return the planner metrics in JSON
*/
public String toPrettyJson(){
//Gson gson = new Gson();
//Gson gson = new GsonBuilder().setPrettyPrinting().create();
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create();
return gson.toJson( this );
}
/**
* Returns a textual description of the object.
*
* @return Object
*/
public String toString(){
StringBuffer sb = new StringBuffer();
sb.append( "{" ).append( "\n" );
append( sb, "client", this.mClient );
append( sb, "version", this.mVersion );
append( sb, "user", this.mUser );
append( sb, "vogroup", this.mVOGroup );
append( sb, "submitdir.base", this.mBaseSubmitDirectory );
append( sb, "submitdir.relative", this.mRelativeSubmitDirectory );
append( sb, "planning.start", mNumFormatter.format( mStartTime ) );
append( sb, "planning.end", mNumFormatter.format( mEndTime ) );
append( sb, "planning.arguments", mPlannerArguments );
append( sb, "uses_pmc", Boolean.toString(this.usesPMC()) );
append( sb, "duration" , Double.toString( mDuration ) );
append( sb, "exitcode" , Integer.toString( mExitcode ) );
append( sb, "error" , mErrorMessage );
append( sb, "properties", this.mPropertiesPath );
append( sb, "dax", this.mDAXPath );
append( sb, "data.configuration", this.mDataConfiguration );
append( sb, "root.wf.uuid", this.mRootWorkflowUUID );
append( sb, "wf.uuid", this.mWorkflowUUID );
sb.append( this.getWorkflowMetrics() );
if( this.mApplicationMetrics != null ){
append( sb, "app.metrics", this.mApplicationMetrics.toString() );
}
sb.append( "}" ).append( "\n" );
return sb.toString();
}
/**
* Appends a key=value pair to the StringBuffer.
*
* @param buffer the StringBuffer that is to be appended to.
* @param key the key.
* @param value the value.
*/
protected void append( StringBuffer buffer, String key, String value ){
buffer.append( key ).append( " = " ).append( value ).append( "\n" );
}
/**
* Returns the clone of the object.
*
* @return the clone
*/
public Object clone(){
PlannerMetrics pm;
try {
pm = ( PlannerMetrics )super.clone();
}
catch (CloneNotSupportedException e) {
//somewhere in the hierarch chain clone is not implemented
throw new RuntimeException( "Clone not implemented in the base class of " +
this.getClass().getName(),
e);
}
pm.mNumFormatter = (NumberFormat) this.mNumFormatter.clone();
pm.setUser( this.mUser );
pm.setVOGroup( this.mVOGroup );
pm.setBaseSubmitDirectory( this.mBaseSubmitDirectory );
pm.setRelativeSubmitDirectory( this.mRelativeSubmitDirectory );
pm.setProperties( this.mPropertiesPath );
pm.setDAX( this.mDAXPath );
pm.setDataConfiguration( this.mDataConfiguration );
pm.setPlannerOptions( this.mPlannerArguments);
pm.setUsesPMC( this.mUsesPMC );
pm.setStartTime( this.mStartTime );
pm.setEndTime( this.mEndTime );
pm.setDuration( this.mDuration );
pm.setExitcode( this.mExitcode );
pm.setErrorMessage( this.mErrorMessage );
if( this.mApplicationMetrics != null ){
pm.setApplicationMetrics( (Properties) this.mApplicationMetrics.clone());
}
return pm;
}
}