/** * */ package org.gcube.accounting.datamodel.implementations; import java.io.Serializable; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Calendar; import java.util.Map; import org.gcube.accounting.datamodel.BasicUsageRecord; import org.gcube.accounting.datamodel.SingleUsageRecord; import org.gcube.accounting.datamodel.UsageRecord; import org.gcube.accounting.datamodel.decorators.ComputedField; import org.gcube.accounting.datamodel.decorators.FieldAction; import org.gcube.accounting.datamodel.decorators.FieldDecorator; import org.gcube.accounting.datamodel.decorators.RequiredField; import org.gcube.accounting.datamodel.deprecationmanagement.annotations.MoveToOperationResult; import org.gcube.accounting.datamodel.validations.annotations.NotEmpty; import org.gcube.accounting.datamodel.validations.annotations.ValidInteger; import org.gcube.accounting.datamodel.validations.annotations.ValidLong; import org.gcube.accounting.exception.InvalidValueException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * */ public class JobUsageRecord extends BasicUsageRecord implements SingleUsageRecord { private static Logger logger = LoggerFactory.getLogger(JobUsageRecord.class); /** * Generated Serial Version UID */ private static final long serialVersionUID = -8648691183939346858L; protected static enum JobStatus { completed, failed }; @RequiredField @NotEmpty public static final String JOB_ID = "jobId"; @RequiredField @NotEmpty public static final String JOB_QUALIFIER = "jobQualifier"; @RequiredField @NotEmpty public static final String JOB_NAME = "jobName"; @RequiredField @ValidLong @CalculateWallDuration public static final String JOB_START_TIME = "jobStartTime"; @RequiredField @ValidLong @CalculateWallDuration public static final String JOB_END_TIME = "jobEndTime"; @MoveToOperationResult protected static final String JOB_STATUS = "jobStatus"; @ValidInteger public static final String VMS_USED = "vmsUsed"; @ComputedField @ValidLong @CalculateWallDuration protected static final String WALL_DURATION = "wallDuration"; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @FieldDecorator(managed=CalculateWallDurationAction.class) protected @interface CalculateWallDuration {} protected class CalculateWallDurationAction implements FieldAction { @Override public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException { try { long wallDuration = calculateWallDuration(); if(key.compareTo(WALL_DURATION)==0){ logger.warn("{} is automatically computed using {} and {}. This invocation has the only effect of recalculating the value. Any provided value is ignored.", WALL_DURATION, JOB_START_TIME, JOB_END_TIME); value = wallDuration; } }catch(InvalidValueException e){ } return value; } } public JobUsageRecord(){ super(); } public JobUsageRecord(Map properties) throws InvalidValueException{ super(properties); } /** * @return the Job Id */ public String getJobId() { return (String) this.resourceProperties.get(JOB_ID); } /** * @param jobId Job Id * @throws InvalidValueException if fails */ public void setJobId(String jobId) throws InvalidValueException { setResourceProperty(JOB_ID, jobId); } public String getJobQualifier() { return (String) this.resourceProperties.get(JOB_QUALIFIER); } public void setJobQualifier(String jobQualifier) throws InvalidValueException { setResourceProperty(JOB_QUALIFIER, jobQualifier); } public String getJobName() { return (String) this.resourceProperties.get(JOB_NAME); } public void setJobName(String jobName) throws InvalidValueException { setResourceProperty(JOB_NAME, jobName); } public Calendar getJobStartTime() { long millis = (Long) this.resourceProperties.get(JOB_START_TIME); return timestampStringToCalendar(millis); } public void setJobStartTime(Calendar jobStartTime) throws InvalidValueException { setResourceProperty(JOB_START_TIME, jobStartTime.getTimeInMillis()); } public Calendar getJobEndTime() { long millis = (Long) this.resourceProperties.get(JOB_END_TIME); return timestampStringToCalendar(millis); } public void setJobEndTime(Calendar jobEndTime) throws InvalidValueException { setResourceProperty(JOB_END_TIME, jobEndTime.getTimeInMillis()); } /* @Deprecated protected JobStatus getJobStatus() { return JobStatus.values()[((OperationResult) this.resourceProperties.get(OPERATION_RESULT)).ordinal()]; } @Deprecated protected void setJobStatus(JobStatus jobStatus) throws InvalidValueException { setResourceProperty(OPERATION_RESULT, jobStatus); } */ public int getVmsUsed() { return (Integer) this.resourceProperties.get(VMS_USED); } public void setVmsUsed(int vmsUsed) throws InvalidValueException { setResourceProperty(VMS_USED, vmsUsed); } protected long calculateWallDuration() throws InvalidValueException { try { long endTime = (Long) this.resourceProperties.get(JOB_END_TIME); long startTime = (Long) this.resourceProperties.get(JOB_START_TIME); long wallDuration = endTime - startTime; setResourceProperty(WALL_DURATION, wallDuration); return wallDuration; }catch(Exception e){ throw new InvalidValueException(String.format("To calculate Wall Duration both %s and %s must be set", START_TIME, END_TIME), e.getCause()); } } public long getWallDuration() { Long wallDuration = (Long) this.resourceProperties.get(WALL_DURATION); if(wallDuration == null){ try { wallDuration = calculateWallDuration(); } catch(Exception e){} } return wallDuration; } }