diff --git a/src/main/java/org/gcube/accounting/datamodel/RawUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/RawUsageRecord.java index ebba25e..8a2831d 100644 --- a/src/main/java/org/gcube/accounting/datamodel/RawUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/RawUsageRecord.java @@ -17,8 +17,10 @@ import java.util.Map.Entry; import java.util.Set; import java.util.UUID; +import org.gcube.accounting.datamodel.annotations.Aggregated; import org.gcube.accounting.datamodel.annotations.NotEmpty; import org.gcube.accounting.datamodel.annotations.NotEmptyIfNotNull; +import org.gcube.accounting.datamodel.annotations.Required; import org.gcube.accounting.datamodel.annotations.ValidLong; import org.gcube.accounting.datamodel.annotations.ValidOperationResult; import org.gcube.accounting.datamodel.annotations.ValidityChecker; @@ -35,30 +37,29 @@ public abstract class RawUsageRecord implements UsageRecord, Serializable { private static Logger logger = LoggerFactory.getLogger(RawUsageRecord.class); - @NotEmpty + @Required @NotEmpty public static final String ID = "id"; - @NotEmpty + @Required @NotEmpty public static final String CREATOR_ID = "creatorId"; - @NotEmpty + @Required @NotEmpty public static final String CONSUMER_ID = "consumerId"; - @ValidLong + @Required @ValidLong public static final String CREATION_TIME = "creationTime"; - @ValidLong + @Aggregated @ValidLong protected static final String START_TIME = "startTime"; - @ValidLong + @Aggregated @ValidLong protected static final String END_TIME = "endTime"; - @NotEmpty - public static final String RESOURCE_TYPE = "resourceType"; - @NotEmpty + @Required @NotEmpty + protected static final String RESOURCE_TYPE = "resourceType"; + @Required @NotEmpty public static final String RESOURCE_SCOPE = "resourceScope"; @NotEmpty - public static final String RESOURCE_OWNER = "resourceOwner"; - @NotEmptyIfNotNull + protected static final String RESOURCE_OWNER = "resourceOwner"; + @Aggregated @NotEmptyIfNotNull protected static final String AGGREGATED_ID = "aggregatedId"; @NotEmptyIfNotNull protected static final String AGGREGATED_USAGE_RECORD_ID = "aggregatedUsageRecordId"; - - @ValidOperationResult + @Required @ValidOperationResult public static final String OPERATION_RESULT = "operationResult"; /** @@ -383,25 +384,23 @@ public abstract class RawUsageRecord implements UsageRecord, Serializable { */ @Override public void setResourceSpecificProperty(String key, Serializable value) throws InvalidValueException { - validateField(key, value); - this.resourceSpecificProperties.put(key, value); + Serializable checkedValue = validateField(key, value); + this.resourceSpecificProperties.put(key, checkedValue); } - protected void validateField(String key, Serializable serializable) throws InvalidValueException { + protected Serializable validateField(String key, Serializable serializable) throws InvalidValueException { + Serializable checkedValue = serializable; List> fieldValidators = validation.get(key); if(fieldValidators!=null){ for(FieldValidator fieldValidator : fieldValidators){ - if(!fieldValidator.isValid(serializable)){ - throw new InvalidValueException(fieldValidator.getErrorSuffix()); - } + checkedValue = fieldValidator.validate(checkedValue); } } + return checkedValue; } protected void validate(Map properties) throws InvalidValueException{ - // TODO Change the behavior. Get the list of validators and check the - // field in properties Map for(String key : properties.keySet()){ Serializable serializable = properties.get(key); validateField(key, serializable); diff --git a/src/main/java/org/gcube/accounting/datamodel/annotations/Aggregated.java b/src/main/java/org/gcube/accounting/datamodel/annotations/Aggregated.java new file mode 100644 index 0000000..60eee5a --- /dev/null +++ b/src/main/java/org/gcube/accounting/datamodel/annotations/Aggregated.java @@ -0,0 +1,12 @@ +package org.gcube.accounting.datamodel.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Aggregated { + +} diff --git a/src/main/java/org/gcube/accounting/datamodel/annotations/Required.java b/src/main/java/org/gcube/accounting/datamodel/annotations/Required.java new file mode 100644 index 0000000..4806dfb --- /dev/null +++ b/src/main/java/org/gcube/accounting/datamodel/annotations/Required.java @@ -0,0 +1,12 @@ +package org.gcube.accounting.datamodel.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Required { + +} diff --git a/src/main/java/org/gcube/accounting/datamodel/implementations/JobUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/implementations/JobUsageRecord.java index c63eb32..5caf8e3 100644 --- a/src/main/java/org/gcube/accounting/datamodel/implementations/JobUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/implementations/JobUsageRecord.java @@ -8,6 +8,7 @@ import java.util.Calendar; import org.gcube.accounting.datamodel.RawUsageRecord; import org.gcube.accounting.datamodel.SingleUsageRecord; import org.gcube.accounting.datamodel.annotations.NotEmpty; +import org.gcube.accounting.datamodel.annotations.Required; import org.gcube.accounting.datamodel.annotations.ValidInteger; import org.gcube.accounting.datamodel.annotations.ValidLong; import org.gcube.accounting.exception.InvalidValueException; @@ -23,26 +24,26 @@ public class JobUsageRecord extends RawUsageRecord implements SingleUsageRecord */ private static final long serialVersionUID = -8648691183939346858L; - public static enum JOB_STATUS { + public static enum JobStatus { completed, failed }; - @NotEmpty + @Required @NotEmpty public static final String JOB_ID = "jobId"; - @NotEmpty + @Required @NotEmpty public static final String JOB_QUALIFIER = "jobQualifier"; - @NotEmpty + @Required @NotEmpty public static final String JOB_NAME = "jobName"; - @ValidLong + @Required @ValidLong public static final String JOB_START_TIME = "jobStartTime"; - @ValidLong + @Required @ValidLong public static final String JOB_END_TIME = "jobEndTime"; @NotEmpty - public static final String JOB_STATUS = "jobStatus"; + protected static final String JOB_STATUS = "jobStatus"; @ValidInteger public static final String VMS_USED = "vmsUsed"; @ValidLong - public static final String WALL_DURATION = "wallDuration"; + protected static final String WALL_DURATION = "wallDuration"; public JobUsageRecord(){ super(); @@ -99,12 +100,14 @@ public class JobUsageRecord extends RawUsageRecord implements SingleUsageRecord } - public JOB_STATUS getJobStatus() { - return (JOB_STATUS) this.resourceSpecificProperties.get(JOB_STATUS); + @Deprecated + public JobStatus getJobStatus() { + return JobStatus.values()[((OperationResult) this.resourceSpecificProperties.get(OPERATION_RESULT)).ordinal()]; } - public void setJobStatus(JOB_STATUS jobStatus) throws InvalidValueException { - setResourceSpecificProperty(JOB_STATUS, jobStatus); + @Deprecated + public void setJobStatus(JobStatus jobStatus) throws InvalidValueException { + setResourceSpecificProperty(OPERATION_RESULT, OperationResult.values()[jobStatus.ordinal()]); } public int getVmsUsed() { @@ -115,13 +118,24 @@ public class JobUsageRecord extends RawUsageRecord implements SingleUsageRecord setResourceSpecificProperty(VMS_USED, vmsUsed); } - public long getWallDuration() { - return (Integer) this.resourceSpecificProperties.get(WALL_DURATION); - } - - public void setWallDuration(long wallDuration) throws InvalidValueException { - setResourceSpecificProperty(WALL_DURATION, wallDuration); + protected void calculateWallDuration() throws InvalidValueException { + try { + long endTime = (Long) this.resourceSpecificProperties.get(JOB_END_TIME); + long startTime = (Long) this.resourceSpecificProperties.get(JOB_START_TIME); + long wallDuration = endTime - startTime; + setResourceSpecificProperty(WALL_DURATION, 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() throws InvalidValueException { + Long wallDuration = (Long) this.resourceSpecificProperties.get(WALL_DURATION); + if(wallDuration == null){ + calculateWallDuration(); + } + return wallDuration; + } }