diff --git a/src/main/java/org/gcube/accounting/datamodel/AggregationStrategy.java b/src/main/java/org/gcube/accounting/datamodel/AggregationStrategy.java index 7befc3b..8a797cd 100644 --- a/src/main/java/org/gcube/accounting/datamodel/AggregationStrategy.java +++ b/src/main/java/org/gcube/accounting/datamodel/AggregationStrategy.java @@ -6,6 +6,7 @@ package org.gcube.accounting.datamodel; import java.io.Serializable; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.Calendar; import java.util.HashSet; import java.util.Set; @@ -67,8 +68,21 @@ public abstract class AggregationStrategy, throw new NotAggregatableRecordsExceptions("The Record provided as argument has different values for field wich must be common to be aggragatable"); } - t.getAggregatedUsageRecord(record); - t = reallyAggregate(t); + T convertedRecord = t.getAggregatedUsageRecord(record); + + Calendar convertedStartTime = ((BasicUsageRecord) convertedRecord).getStartTimeAsCalendar(); + Calendar actualStartTime = ((BasicUsageRecord) t).getStartTimeAsCalendar(); + if(convertedStartTime.before(actualStartTime)){ + ((BasicUsageRecord) t).setStartTime(convertedStartTime); + } + + Calendar convertedEndTime = ((BasicUsageRecord) convertedRecord).getEndTimeAsCalendar(); + Calendar actualEndTime = ((BasicUsageRecord) t).getEndTimeAsCalendar(); + if(convertedEndTime.after(actualEndTime)){ + ((BasicUsageRecord) t).setEndTime(convertedEndTime); + } + + t = reallyAggregate(convertedRecord); return t; }catch(NotAggregatableRecordsExceptions e){ diff --git a/src/main/java/org/gcube/accounting/datamodel/BasicUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/BasicUsageRecord.java index 80cccef..a758113 100644 --- a/src/main/java/org/gcube/accounting/datamodel/BasicUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/BasicUsageRecord.java @@ -56,29 +56,25 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable { public static final String SCOPE = "scope"; @RequiredField @ValidOperationResult public static final String OPERATION_RESULT = "operationResult"; - - - @AggregatedField @ValidLong - protected static final String START_TIME = "startTime"; - @AggregatedField @ValidLong - protected static final String END_TIME = "endTime"; - - @AggregatedField @NotEmptyIfNotNull - protected static final String AGGREGATED = "aggregated"; - - /* - @AggregatedField @NotEmptyIfNotNull - protected static final String AGGREGATED_USAGE_RECORD_ID = "aggregatedUsageRecordId"; - */ + /** resource-specific properties */ protected Map resourceProperties; protected Map> validation; protected Set requiredFields; - protected Set aggregatedFields; protected Set computedFields; + @AggregatedField @ValidLong + protected static final String START_TIME = "startTime"; + @AggregatedField @ValidLong + protected static final String END_TIME = "endTime"; + @AggregatedField @NotEmptyIfNotNull + protected static final String AGGREGATED = "aggregated"; + + protected Set aggregatedFields; + + protected void initializeValidation() { logger.debug("Initializing Field Validators"); List fields = Arrays.asList(this.getClass().getDeclaredFields()); @@ -197,12 +193,20 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable { setResourceProperty(CREATION_TIME, creationTime.getTimeInMillis()); } + /** + * Return the left end of the time interval covered by this {#UsageRecord} + * @return Start Time + */ + protected long getStartTimeInMillis() { + return (Long) this.resourceProperties.get(START_TIME); + } + /** * Return the left end of the time interval covered by this {#UsageRecord} * @return Start Time */ protected Calendar getStartTimeAsCalendar() { - long millis = (Long) this.resourceProperties.get(START_TIME); + long millis = getStartTimeInMillis(); return timestampStringToCalendar(millis); } @@ -215,13 +219,20 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable { setResourceProperty(START_TIME, startTime.getTimeInMillis()); } + /** + * Return the right end of the time interval covered by this {#UsageRecord} + * @return End Time + */ + protected long getEndTimeInMillis() { + return (Long) this.resourceProperties.get(END_TIME); + } /** * Return the right end of the time interval covered by this {#UsageRecord} * @return End Time */ protected Calendar getEndTimeAsCalendar() { - long millis = (Long) this.resourceProperties.get(END_TIME); + long millis = getEndTimeInMillis(); return timestampStringToCalendar(millis); } @@ -233,14 +244,7 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable { protected void setEndTime(Calendar endTime) throws InvalidValueException { setResourceProperty(END_TIME, endTime.getTimeInMillis()); } - - /* - protected String getUsageRecordType() { - //return (String) this.resourceSpecificProperties.get(RESOURCE_TYPE); - return this.getClass().getSimpleName(); - } - */ - + /** * {@inheritDoc} */ @@ -257,23 +261,6 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable { setResourceProperty(SCOPE, scope); } - /* * - * {@inheritDoc} - * / - @Override - public String getAggregatedUsageRecordId() { - return (String) this.resourceProperties.get(AGGREGATED_USAGE_RECORD_ID); - } - - /* * - * {@inheritDoc} - * / - @Override - public void setAggregatedUsageRecordId(String aggregatedId) throws InvalidValueException { - setResourceProperty(AGGREGATED_USAGE_RECORD_ID, aggregatedId); - } - */ - /** * {@inheritDoc} */ diff --git a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/ServiceUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/ServiceUsageRecord.java index 5e6fef4..1691bc8 100644 --- a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/ServiceUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/ServiceUsageRecord.java @@ -25,6 +25,10 @@ public class ServiceUsageRecord extends org.gcube.accounting.datamodel.implement */ private static final long serialVersionUID = 6387584974618335623L; + // Redefining DURATION to Set @AggregatedField + @RequiredField @ValidLong @AggregatedField + public static final String DURATION = "duration"; + @RequiredField @ValidInteger @AggregatedField protected static final String INVOCATION_COUNT = "invocationCount"; @RequiredField @ValidLong @AggregatedField @@ -32,14 +36,18 @@ public class ServiceUsageRecord extends org.gcube.accounting.datamodel.implement @RequiredField @ValidLong @AggregatedField protected static final String MIN_INVOCATION_TIME = "minInvocationTime"; + private void init(){ + this.resourceProperties.put(AGGREGATED, true); + } + public ServiceUsageRecord(){ super(); - this.resourceProperties.put(AGGREGATED, true); + init(); } protected ServiceUsageRecord(Map properties) throws InvalidValueException{ super(properties); - this.resourceProperties.put(AGGREGATED, true); + init(); } public ServiceUsageRecord(org.gcube.accounting.datamodel.implementations.ServiceUsageRecord record) throws InvalidValueException{ @@ -51,7 +59,7 @@ public class ServiceUsageRecord extends org.gcube.accounting.datamodel.implement Calendar creationTime = record.getCreationTime(); this.setStartTime(creationTime); this.setEndTime(creationTime); - this.resourceProperties.put(AGGREGATED, true); + init(); } public int getInvocationCount() { diff --git a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/StorageUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/StorageUsageRecord.java index 57eb7d6..50efefc 100644 --- a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/StorageUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/StorageUsageRecord.java @@ -10,6 +10,7 @@ import org.gcube.accounting.datamodel.AggregatedUsageRecord; import org.gcube.accounting.datamodel.decorators.AggregatedField; import org.gcube.accounting.datamodel.decorators.RequiredField; import org.gcube.accounting.datamodel.validations.annotations.ValidInteger; +import org.gcube.accounting.datamodel.validations.annotations.ValidLong; import org.gcube.accounting.exception.InvalidValueException; /** @@ -23,6 +24,9 @@ public class StorageUsageRecord extends org.gcube.accounting.datamodel.implement */ private static final long serialVersionUID = 1082525518686785682L; + // Redefining DATA_VOLUME to Set @AggregatedField + @RequiredField @ValidLong @AggregatedField + public static final String DATA_VOLUME = "dataVolume"; /** * Indicate The Number of Aggregated Operation */ diff --git a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregationstrategy/StorageUsageRecordAggregationStrategy.java b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregationstrategy/StorageUsageRecordAggregationStrategy.java new file mode 100644 index 0000000..b286cb6 --- /dev/null +++ b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregationstrategy/StorageUsageRecordAggregationStrategy.java @@ -0,0 +1,41 @@ +/** + * + */ +package org.gcube.accounting.datamodel.implementations.aggregationstrategy; + +import org.gcube.accounting.datamodel.AggregationStrategy; +import org.gcube.accounting.datamodel.implementations.aggregated.StorageUsageRecord; +import org.gcube.accounting.exception.NotAggregatableRecordsExceptions; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class StorageUsageRecordAggregationStrategy extends AggregationStrategy{ + + /** + * @param serviceUsageRecord + */ + public StorageUsageRecordAggregationStrategy(StorageUsageRecord storageUsageRecord) { + super(storageUsageRecord); + this.aggregationField.add(StorageUsageRecord.RESOURCE_OWNER); + this.aggregationField.add(StorageUsageRecord.OBJECT_URI); + this.aggregationField.add(StorageUsageRecord.OPERATION_TYPE); + this.aggregationField.add(StorageUsageRecord.QUALIFIER); + this.aggregationField.add(StorageUsageRecord.DATA_TYPE); + } + + protected StorageUsageRecord reallyAggregate(StorageUsageRecord record) + throws NotAggregatableRecordsExceptions { + + try { + t.setOperationCount(t.getOperationCount() + record.getOperationCount()); + t.setDataVolume(t.getDataVolume() + record.getDataVolume()); + }catch(Exception e){ + throw new UnsupportedOperationException(e.getCause()); + } + + return t; + } + +}