diff --git a/src/main/java/org/gcube/accounting/datamodel/AggregatedUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/AggregatedUsageRecord.java index 20a5978..49b3f86 100644 --- a/src/main/java/org/gcube/accounting/datamodel/AggregatedUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/AggregatedUsageRecord.java @@ -3,34 +3,28 @@ */ package org.gcube.accounting.datamodel; -import java.util.List; - import org.gcube.accounting.exception.InvalidValueException; +import org.gcube.accounting.exception.NotAggregatableRecorsExceptions; /** * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ */ -public interface AggregatedUsageRecord extends UsageRecord { +public interface AggregatedUsageRecord extends UsageRecord { + + + public T getAggregatedUsageRecord(B b) throws InvalidValueException ; /** - * Return the id of the usage record aggregating this, null if this record - * has not been aggregated by any record. - * @return Aggregated Id The ID of the aggregation Record + * Aggregate the Record provided as parameter with this record if Aggregatable + * @throws NotAggregatableRecorsExceptions */ - public String getAggregatedUsageRecordId(); - - /** - * Set the id of the usage record aggregating this - * @param aggregatedId The ID of the aggregation Record - * @throws InvalidValueException - */ - public void setAggregatedUsageRecordId(String aggregatedId) throws InvalidValueException; + public void aggregate(T record) throws NotAggregatableRecorsExceptions; - /** + /* * * * @param records * @return - */ - public List aggregate(List records); - + * / + public Collection aggregate(List records); + */ } diff --git a/src/main/java/org/gcube/accounting/datamodel/AggregationStrategy.java b/src/main/java/org/gcube/accounting/datamodel/AggregationStrategy.java new file mode 100644 index 0000000..b091588 --- /dev/null +++ b/src/main/java/org/gcube/accounting/datamodel/AggregationStrategy.java @@ -0,0 +1,80 @@ +/** + * + */ +package org.gcube.accounting.datamodel; + +import java.io.Serializable; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashSet; +import java.util.Set; + +import org.gcube.accounting.exception.NotAggregatableRecorsExceptions; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public abstract class AggregationStrategy { + + protected T t; + protected Set aggregationField; + + public AggregationStrategy(T t){ + this.t = t; + this.aggregationField = new HashSet(); + this.aggregationField.add(BasicUsageRecord.USAGE_RECORD_TYPE); + this.aggregationField.add(BasicUsageRecord.SCOPE); + } + + protected String commonFieldHash(B record) { + try { + MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); + + String concatenation = ""; + for(String field : aggregationField){ + concatenation = concatenation + record.getResourceProperty(field).toString(); + } + + messageDigest.update(concatenation.getBytes()); + return new String(messageDigest.digest()); + }catch(NoSuchAlgorithmException e){ + throw new UnsupportedOperationException(e.getCause()); + } + } + + protected boolean isAggregable(UsageRecord record) { + for(String field : aggregationField){ + Serializable recordValue = record.getResourceProperty(field); + Serializable thisValue = t.getResourceProperty(field); + + // TODO Check THIS + if(!recordValue.equals(thisValue)){ + return false; + } + + } + + return true; + } + + public void aggregate(B record) throws NotAggregatableRecorsExceptions { + try{ + if(isAggregable(record)){ + throw new NotAggregatableRecorsExceptions("The Record provided as argument has different values for field wich must be common to be aggragatable"); + } + + @SuppressWarnings("unchecked") + AggregatedUsageRecord aggregatedUsageRecord = ((AggregatedUsageRecord) t); + aggregatedUsageRecord.aggregate(aggregatedUsageRecord.getAggregatedUsageRecord(record)); + + throw new NotAggregatableRecorsExceptions(""); + }catch(NotAggregatableRecorsExceptions e){ + throw e; + }catch(Exception ex){ + throw new NotAggregatableRecorsExceptions(ex.getCause()); + } + + } + +} diff --git a/src/main/java/org/gcube/accounting/datamodel/BasicUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/BasicUsageRecord.java index 7062e35..6a2109f 100644 --- a/src/main/java/org/gcube/accounting/datamodel/BasicUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/BasicUsageRecord.java @@ -46,31 +46,29 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable { @RequiredField @NotEmpty public static final String ID = "id"; - @RequiredField @NotEmpty public static final String CONSUMER_ID = "consumerId"; @RequiredField @ValidLong public static final String CREATION_TIME = "creationTime"; + @RequiredField @NotEmpty + protected static final String USAGE_RECORD_TYPE = "usageRecordType"; + @RequiredField @NotEmpty + 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"; - - @RequiredField @NotEmpty - protected static final String USAGE_RECORD_TYPE = "usageRecordType"; - - @RequiredField @NotEmpty - public static final String RESOURCE_SCOPE = "resourceScope"; - @AggregatedField @NotEmptyIfNotNull protected static final String AGGREGATED = "aggregated"; + /* @AggregatedField @NotEmptyIfNotNull protected static final String AGGREGATED_USAGE_RECORD_ID = "aggregatedUsageRecordId"; - - @RequiredField @ValidOperationResult - public static final String OPERATION_RESULT = "operationResult"; + */ /** resource-specific properties */ protected Map resourceProperties; @@ -114,6 +112,8 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable { } } } + + } /** @@ -124,7 +124,6 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable { this.requiredFields = new HashSet(); this.aggregatedFields = new HashSet(); this.computedFields = new HashSet(); - initializeValidation(); } @@ -158,23 +157,6 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable { setResourceProperty(ID, id); } - /* * - * {@inheritDoc} - * / - @Override - public String getCreatorId() { - return (String) this.resourceProperties.get(CREATOR_ID); - } - - /* * - * {@inheritDoc} - * / - @Override - public void setCreatorId(String creatorId) throws InvalidValueException { - setResourceProperty(CREATOR_ID, creatorId); - } - */ - /** * {@inheritDoc} */ @@ -262,33 +244,34 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable { * {@inheritDoc} */ @Override - public String getResourceScope() { - return (String) this.resourceProperties.get(RESOURCE_SCOPE); + public String getScope() { + return (String) this.resourceProperties.get(SCOPE); } /** * {@inheritDoc} */ @Override - public void setResourceScope(String scope) throws InvalidValueException { - setResourceProperty(RESOURCE_SCOPE, scope); + public void setScope(String scope) throws InvalidValueException { + 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/RawUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/RawUsageRecord.java index aa90902..54cc07a 100644 --- a/src/main/java/org/gcube/accounting/datamodel/RawUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/RawUsageRecord.java @@ -21,8 +21,8 @@ import org.gcube.accounting.datamodel.implementations.PortletUsageRecord; import org.gcube.accounting.datamodel.implementations.ServiceUsageRecord; import org.gcube.accounting.datamodel.implementations.StorageUsageRecord; import org.gcube.accounting.datamodel.implementations.TaskUsageRecord; +import org.gcube.accounting.datamodel.validations.annotations.NotEmpty; import org.gcube.accounting.datamodel.validations.annotations.NotEmptyIfNotNull; -import org.gcube.accounting.datamodel.validations.validators.NotEmptyIfNotNullValidator; import org.gcube.accounting.exception.InvalidValueException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory; * */ @Deprecated -public class RawUsageRecord extends BasicUsageRecord { +public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecord { /** * Generated Serial Version UID @@ -40,7 +40,26 @@ public class RawUsageRecord extends BasicUsageRecord { private static final long serialVersionUID = 1203390363640634895L; private static Logger logger = LoggerFactory.getLogger(RawUsageRecord.class); - + + @DeprecatedWarning @MoveToScope @NotEmpty + public static final String RESOURCE_SCOPE = "resourceScope"; + + @Target(ElementType.FIELD) + @Retention(RetentionPolicy.RUNTIME) + @FieldDecorator(managed=MoveToScopeAction.class) + protected @interface MoveToScope { } + protected class MoveToScopeAction implements FieldAction { + @Override + public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException { + if(value instanceof String){ + usageRecord.setScope((String) value); + }else{ + throw new InvalidValueException(); + } + return value; + } + } + @DeprecatedWarning @NotEmptyIfNotNull public static final String CREATOR_ID = "creatorId"; @@ -120,9 +139,10 @@ public class RawUsageRecord extends BasicUsageRecord { } - @DeprecatedWarning @MoveToAggregatedUsageRecordId + @DeprecatedWarning //@MoveToAggregatedUsageRecordId protected static final String AGGREGATED_ID = "aggregatedId"; + /* @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @FieldDecorator(managed=MoveToAggregatedUsageRecordIdAction.class) @@ -136,15 +156,18 @@ public class RawUsageRecord extends BasicUsageRecord { return value; } } + */ @NotEmptyIfNotNull @DeprecatedWarning protected static final String FULLY_QUALIFIED_CONSUMER_ID = "fullyQualifiedConsumerId"; + @Deprecated public RawUsageRecord(){ super(); this.resourceProperties.remove(USAGE_RECORD_TYPE); } + @Deprecated public RawUsageRecord(Map properties) throws InvalidValueException { super(properties); } @@ -153,6 +176,7 @@ public class RawUsageRecord extends BasicUsageRecord { * Return the identity of the entity creating this {#UsageRecord} * @return Creator ID */ + @Deprecated public String getCreatorId() { return (String) this.resourceProperties.get(CREATOR_ID); } @@ -162,6 +186,7 @@ public class RawUsageRecord extends BasicUsageRecord { * @param creatorId Creator ID * @throws InvalidValueException */ + @Deprecated public void setCreatorId(String creatorId) throws InvalidValueException { setResourceProperty(CREATOR_ID, creatorId); } @@ -170,6 +195,7 @@ public class RawUsageRecord extends BasicUsageRecord { * {@inheritDoc} */ @Override + @Deprecated public void setConsumerId(String consumerId) { try{ setConsumerId(consumerId); @@ -179,12 +205,13 @@ public class RawUsageRecord extends BasicUsageRecord { } /** - * {@inheritDoc} + * Set the accounting scope of the {#UsageRecord} + * @param scope The accounting scope of the {#UsageRecord} */ - @Override + @Deprecated public void setResourceScope(String scope) { try{ - setResourceScope(scope); + setResourceProperty(RESOURCE_SCOPE, scope); }catch(Exception e){ logger.error("Unable to Set {}", RESOURCE_SCOPE); } diff --git a/src/main/java/org/gcube/accounting/datamodel/UsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/UsageRecord.java index c708afc..185c99c 100644 --- a/src/main/java/org/gcube/accounting/datamodel/UsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/UsageRecord.java @@ -56,28 +56,29 @@ public interface UsageRecord extends Comparable{ * Return the accounting scope of the {#UsageRecord} * @return The Accounting scope of the {#UsageRecord} */ - public String getResourceScope(); + public String getScope(); /** * Set the accounting scope of the {#UsageRecord} * @param scope The accounting scope of the {#UsageRecord} * @throws InvalidValueException */ - public void setResourceScope(String scope) throws InvalidValueException; + public void setScope(String scope) throws InvalidValueException; - /** + /* * * Return the id of the usage record aggregating this, null if this record * has not been aggregated by any record. * @return Aggregated Id The ID of the aggregation Record - */ + * / public String getAggregatedUsageRecordId(); - /** + /* * * Set the id of the usage record aggregating this * @param aggregatedId The ID of the aggregation Record * @throws InvalidValueException - */ + * / public void setAggregatedUsageRecordId(String aggregatedId) throws InvalidValueException; + */ /** * Return all resource-specific properties. The returned Map is a copy of diff --git a/src/main/java/org/gcube/accounting/datamodel/implementations/ServiceUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/implementations/ServiceUsageRecord.java index 6b2cdc1..7e08fc9 100644 --- a/src/main/java/org/gcube/accounting/datamodel/implementations/ServiceUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/implementations/ServiceUsageRecord.java @@ -8,12 +8,9 @@ import java.util.Map; import org.gcube.accounting.datamodel.BasicUsageRecord; import org.gcube.accounting.datamodel.SingleUsageRecord; -import org.gcube.accounting.datamodel.decorators.AggregatedField; import org.gcube.accounting.datamodel.decorators.RequiredField; -import org.gcube.accounting.datamodel.deprecationmanagement.annotations.DeprecatedWarning; import org.gcube.accounting.datamodel.validations.annotations.NotEmpty; import org.gcube.accounting.datamodel.validations.annotations.ValidIP; -import org.gcube.accounting.datamodel.validations.annotations.ValidInteger; import org.gcube.accounting.datamodel.validations.annotations.ValidLong; import org.gcube.accounting.exception.InvalidValueException; @@ -31,19 +28,9 @@ public class ServiceUsageRecord extends BasicUsageRecord implements SingleUsageR @ValidIP public static final String CALLER_IP = "callerIP"; @RequiredField @NotEmpty - public static final String CALLER_SCOPE = "callerScope"; - @RequiredField @NotEmpty public static final String REF_HOST = "refHost"; @RequiredField @NotEmpty public static final String REF_VM = "refVM"; - - @NotEmpty @DeprecatedWarning - protected static final String DOMAIN = "domain"; - - @ValidInteger @AggregatedField - protected static final String INVOCATION_COUNT = "invocationCount"; - @ValidInteger @AggregatedField - protected static final String AVERAGE_INVOCATION_COUNT = "averageInvocationTime"; @RequiredField @NotEmpty public static final String SERVICE_CLASS = "serviceClass"; @RequiredField @NotEmpty @@ -68,14 +55,6 @@ public class ServiceUsageRecord extends BasicUsageRecord implements SingleUsageR setResourceProperty(CALLER_IP, callerIP); } - public String getCallerScope() { - return (String) this.resourceProperties.get(CALLER_SCOPE); - } - - public void setCallerScope(String callerScope) throws InvalidValueException { - setResourceProperty(CALLER_SCOPE, callerScope); - } - public String getRefHost() { return (String) this.resourceProperties.get(REF_HOST); } @@ -92,32 +71,6 @@ public class ServiceUsageRecord extends BasicUsageRecord implements SingleUsageR setResourceProperty(REF_VM, refVM); } - /* - protected String getDomain() { - return (String) this.resourceProperties.get(DOMAIN); - } - - protected void setDomain(String domain) throws InvalidValueException { - setResourceProperty(DOMAIN, domain); - } - - public String getInvocationCount() { - return (String) this.resourceProperties.get(INVOCATION_COUNT); - } - - public void setInvocationCount(String invocationCount) throws InvalidValueException { - setResourceProperty(INVOCATION_COUNT, invocationCount); - } - - public String getAverageInvocationTime() { - return (String) this.resourceProperties.get(AVERAGE_INVOCATION_COUNT); - } - - public void setAverageInvocationTime(String averageInvocationTime) throws InvalidValueException { - setResourceProperty(AVERAGE_INVOCATION_COUNT, averageInvocationTime); - } - */ - public String getServiceClass() { return (String) this.resourceProperties.get(SERVICE_CLASS); } diff --git a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/JobUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/JobUsageRecord.java index f271b82..d4b95ee 100644 --- a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/JobUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/JobUsageRecord.java @@ -4,17 +4,17 @@ package org.gcube.accounting.datamodel.implementations.aggregated; import java.io.Serializable; -import java.util.List; import java.util.Map; import org.gcube.accounting.datamodel.AggregatedUsageRecord; import org.gcube.accounting.exception.InvalidValueException; +import org.gcube.accounting.exception.NotAggregatableRecorsExceptions; /** + * This Class is for library internal use only * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * */ -public class JobUsageRecord extends org.gcube.accounting.datamodel.implementations.JobUsageRecord implements AggregatedUsageRecord { +public class JobUsageRecord extends org.gcube.accounting.datamodel.implementations.JobUsageRecord implements AggregatedUsageRecord { /** * Generated Serial Version UID @@ -35,10 +35,23 @@ public class JobUsageRecord extends org.gcube.accounting.datamodel.implementatio * {@inheritDoc} */ @Override - public List aggregate(List records) { - // TODO - throw new UnsupportedOperationException(); + public JobUsageRecord getAggregatedUsageRecord( + org.gcube.accounting.datamodel.implementations.JobUsageRecord b) + throws InvalidValueException { + // TODO Auto-generated method stub + return null; } + + /** + * {@inheritDoc} + */ + @Override + public void aggregate(JobUsageRecord record) + throws NotAggregatableRecorsExceptions { + // TODO Auto-generated method stub + + } + - + } diff --git a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/PortletUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/PortletUsageRecord.java index 0fee189..5623f15 100644 --- a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/PortletUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/PortletUsageRecord.java @@ -4,17 +4,17 @@ package org.gcube.accounting.datamodel.implementations.aggregated; import java.io.Serializable; -import java.util.List; import java.util.Map; import org.gcube.accounting.datamodel.AggregatedUsageRecord; import org.gcube.accounting.exception.InvalidValueException; +import org.gcube.accounting.exception.NotAggregatableRecorsExceptions; /** + * This Class is for library internal use only * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * */ -public class PortletUsageRecord extends org.gcube.accounting.datamodel.implementations.PortletUsageRecord implements AggregatedUsageRecord { +public class PortletUsageRecord extends org.gcube.accounting.datamodel.implementations.PortletUsageRecord implements AggregatedUsageRecord { /** @@ -31,14 +31,28 @@ public class PortletUsageRecord extends org.gcube.accounting.datamodel.implement super(properties); this.resourceProperties.put(AGGREGATED, true); } - + /** * {@inheritDoc} */ @Override - public List aggregate(List records) { - // TODO - throw new UnsupportedOperationException(); + public PortletUsageRecord getAggregatedUsageRecord( + org.gcube.accounting.datamodel.implementations.PortletUsageRecord b) + throws InvalidValueException { + // TODO Auto-generated method stub + return null; } + + /** + * {@inheritDoc} + */ + @Override + public void aggregate(PortletUsageRecord record) + throws NotAggregatableRecorsExceptions { + // TODO Auto-generated method stub + + } + + } 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 8677eea..cb79b07 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 @@ -4,29 +4,32 @@ package org.gcube.accounting.datamodel.implementations.aggregated; import java.io.Serializable; -import java.util.List; import java.util.Map; 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; /** + * This Class is for library internal use only * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * */ -public class ServiceUsageRecord extends org.gcube.accounting.datamodel.implementations.ServiceUsageRecord implements AggregatedUsageRecord { +public class ServiceUsageRecord extends org.gcube.accounting.datamodel.implementations.ServiceUsageRecord implements AggregatedUsageRecord { /** * Generated Serial Version UID */ private static final long serialVersionUID = 6387584974618335623L; - @ValidInteger @AggregatedField + @ValidInteger @AggregatedField @RequiredField protected static final String INVOCATION_COUNT = "invocationCount"; - @ValidInteger @AggregatedField - protected static final String AVERAGE_INVOCATION_COUNT = "averageInvocationTime"; + @ValidLong @AggregatedField @RequiredField + protected static final String MAX_INVOCATION_TIME = "maxInvocationTime"; + @ValidLong @AggregatedField @RequiredField + protected static final String MIN_INVOCATION_TIME = "minInvocationTime"; public ServiceUsageRecord(){ super(); @@ -37,29 +40,78 @@ public class ServiceUsageRecord extends org.gcube.accounting.datamodel.implement super(properties); this.resourceProperties.put(AGGREGATED, true); } + + protected ServiceUsageRecord(org.gcube.accounting.datamodel.implementations.ServiceUsageRecord record) throws InvalidValueException{ + super(record.getResourceProperties()); + this.setInvocationCount(1); + long duration = record.getDuration(); + this.setMinInvocationTime(duration); + this.setMaxInvocationTime(duration); + this.resourceProperties.put(AGGREGATED, true); + } - public String getInvocationCount() { - return (String) this.resourceProperties.get(INVOCATION_COUNT); + + + + public int getInvocationCount() { + return (Integer) this.resourceProperties.get(INVOCATION_COUNT); } - public void setInvocationCount(String invocationCount) throws InvalidValueException { + public void setInvocationCount(int invocationCount) throws InvalidValueException { setResourceProperty(INVOCATION_COUNT, invocationCount); } - public String getAverageInvocationTime() { - return (String) this.resourceProperties.get(AVERAGE_INVOCATION_COUNT); + public long getMaxInvocationTime() { + return (Long) this.resourceProperties.get(MAX_INVOCATION_TIME); } - public void setAverageInvocationTime(String averageInvocationTime) throws InvalidValueException { - setResourceProperty(AVERAGE_INVOCATION_COUNT, averageInvocationTime); + public void setMaxInvocationTime(long maxInvocationTime) throws InvalidValueException { + setResourceProperty(MAX_INVOCATION_TIME, maxInvocationTime); + } + + public long getMinInvocationTime() { + return (Long) this.resourceProperties.get(MIN_INVOCATION_TIME); + } + + public void setMinInvocationTime(long minInvocationTime) throws InvalidValueException { + setResourceProperty(MIN_INVOCATION_TIME, minInvocationTime); + } + + /** + * {@inheritDoc} + */ + @Override + public void aggregate(ServiceUsageRecord record) { + try { + this.setInvocationCount(this.getInvocationCount() + record.getInvocationCount()); + this.setDuration((this.getDuration() + record.getDuration()) / 2); + + long max = ((ServiceUsageRecord) record).getMaxInvocationTime(); + if(max > this.getMaxInvocationTime()){ + this.setMaxInvocationTime(max); + } + + long min = ((ServiceUsageRecord) record).getMinInvocationTime(); + if(min < this.getMinInvocationTime()){ + this.setMinInvocationTime(min); + } + + }catch(Exception e){ + throw new UnsupportedOperationException(e.getCause()); + } } /** * {@inheritDoc} */ @Override - public List aggregate(List records) { - // TODO - throw new UnsupportedOperationException(); + public ServiceUsageRecord getAggregatedUsageRecord( + org.gcube.accounting.datamodel.implementations.ServiceUsageRecord record) + throws InvalidValueException { + if(record instanceof ServiceUsageRecord){ + return (ServiceUsageRecord) record; + } + return new ServiceUsageRecord(record); } + } diff --git a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/StorageStatusUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/StorageStatusUsageRecord.java index 9f55ae2..1b37389 100644 --- a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/StorageStatusUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregated/StorageStatusUsageRecord.java @@ -10,8 +10,8 @@ import org.gcube.accounting.datamodel.validations.annotations.ValidInteger; import org.gcube.accounting.datamodel.validations.annotations.ValidLong; import org.gcube.accounting.exception.InvalidValueException; */ - /** + * This Class is for library internal use only * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ */ @Deprecated 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 8e2dc2f..27ae417 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 @@ -4,17 +4,17 @@ package org.gcube.accounting.datamodel.implementations.aggregated; import java.io.Serializable; -import java.util.List; import java.util.Map; import org.gcube.accounting.datamodel.AggregatedUsageRecord; import org.gcube.accounting.exception.InvalidValueException; +import org.gcube.accounting.exception.NotAggregatableRecorsExceptions; /** + * This Class is for library internal use only * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ - * */ -public class StorageUsageRecord extends org.gcube.accounting.datamodel.implementations.StorageUsageRecord implements AggregatedUsageRecord { +public class StorageUsageRecord extends org.gcube.accounting.datamodel.implementations.StorageUsageRecord implements AggregatedUsageRecord { /** * Generated Serial Version UID @@ -30,13 +30,27 @@ public class StorageUsageRecord extends org.gcube.accounting.datamodel.implement super(properties); this.resourceProperties.put(AGGREGATED, true); } - + /** * {@inheritDoc} */ @Override - public List aggregate(List records) { - // TODO - throw new UnsupportedOperationException(); + public StorageUsageRecord getAggregatedUsageRecord( + org.gcube.accounting.datamodel.implementations.StorageUsageRecord b) + throws InvalidValueException { + // TODO Auto-generated method stub + return null; } + + /** + * {@inheritDoc} + */ + @Override + public void aggregate(StorageUsageRecord record) + throws NotAggregatableRecorsExceptions { + // TODO Auto-generated method stub + + } + + } diff --git a/src/main/java/org/gcube/accounting/datamodel/implementations/aggregationstrategy/ServiceUsageRecordAggregationStrategy.java b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregationstrategy/ServiceUsageRecordAggregationStrategy.java new file mode 100644 index 0000000..1e8bd9b --- /dev/null +++ b/src/main/java/org/gcube/accounting/datamodel/implementations/aggregationstrategy/ServiceUsageRecordAggregationStrategy.java @@ -0,0 +1,27 @@ +/** + * + */ +package org.gcube.accounting.datamodel.implementations.aggregationstrategy; + +import org.gcube.accounting.datamodel.AggregationStrategy; +import org.gcube.accounting.datamodel.implementations.aggregated.ServiceUsageRecord; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class ServiceUsageRecordAggregationStrategy extends AggregationStrategy{ + + /** + * @param serviceUsageRecord + */ + public ServiceUsageRecordAggregationStrategy(ServiceUsageRecord serviceUsageRecord) { + super(serviceUsageRecord); + this.aggregationField.add(ServiceUsageRecord.CALLER_IP); + this.aggregationField.add(ServiceUsageRecord.REF_HOST); + this.aggregationField.add(ServiceUsageRecord.REF_VM); + this.aggregationField.add(ServiceUsageRecord.SERVICE_CLASS); + this.aggregationField.add(ServiceUsageRecord.SERVICE_NAME); + } + +} diff --git a/src/main/java/org/gcube/accounting/exception/InvalidValueException.java b/src/main/java/org/gcube/accounting/exception/InvalidValueException.java index 3c322f9..b0bc749 100644 --- a/src/main/java/org/gcube/accounting/exception/InvalidValueException.java +++ b/src/main/java/org/gcube/accounting/exception/InvalidValueException.java @@ -15,6 +15,10 @@ public class InvalidValueException extends Exception { super(message); } + public InvalidValueException(Throwable cause) { + super(cause); + } + public InvalidValueException(String message, Throwable cause) { super(message, cause); } diff --git a/src/main/java/org/gcube/accounting/exception/NotAggregatableRecorsExceptions.java b/src/main/java/org/gcube/accounting/exception/NotAggregatableRecorsExceptions.java new file mode 100644 index 0000000..b7c8d5b --- /dev/null +++ b/src/main/java/org/gcube/accounting/exception/NotAggregatableRecorsExceptions.java @@ -0,0 +1,32 @@ +/** + * + */ +package org.gcube.accounting.exception; + +/** + * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ + * + */ +public class NotAggregatableRecorsExceptions extends Exception { + + /** + * Generated serial Version UID + */ + private static final long serialVersionUID = -1477792189431118048L; + + public NotAggregatableRecorsExceptions() { + super(); + } + + public NotAggregatableRecorsExceptions(String message) { + super(message); + } + + public NotAggregatableRecorsExceptions(Throwable cause) { + super(cause); + } + + public NotAggregatableRecorsExceptions(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/gcube/accounting/persistence/Persistence.java b/src/main/java/org/gcube/accounting/persistence/Persistence.java index 2a2d47b..00b2c24 100644 --- a/src/main/java/org/gcube/accounting/persistence/Persistence.java +++ b/src/main/java/org/gcube/accounting/persistence/Persistence.java @@ -8,6 +8,7 @@ import java.util.ServiceLoader; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import org.gcube.accounting.datamodel.SingleUsageRecord; import org.gcube.accounting.datamodel.UsageRecord; import org.gcube.accounting.datamodel.implementations.ServiceUsageRecord; import org.gcube.accounting.exception.InvalidValueException; @@ -80,12 +81,12 @@ public abstract class Persistence { } } - public static UsageRecord createTestUsageRecord(){ + public static SingleUsageRecord createTestUsageRecord(){ ServiceUsageRecord serviceUsageRecord = new ServiceUsageRecord(); try { serviceUsageRecord.setConsumerId("accounting"); - serviceUsageRecord.setResourceScope("/gcube/devsec"); + serviceUsageRecord.setScope("/gcube/devsec"); //Calendar creationTime = new GregorianCalendar(); //Calendar startTime = new GregorianCalendar(); @@ -101,7 +102,7 @@ public abstract class Persistence { serviceUsageRecord.setServiceName("Accounting-Lib"); serviceUsageRecord.setRefHost("localhost"); serviceUsageRecord.setRefVM("local"); - serviceUsageRecord.setCallerScope("/gcube/devsec"); + } catch (InvalidValueException e1) { @@ -157,7 +158,7 @@ public abstract class Persistence { */ protected abstract void reallyAccount(UsageRecord usageRecord) throws Exception; - private void accountWithFallback(UsageRecord usageRecord) throws Exception { + private void accountWithFallback(SingleUsageRecord usageRecord) throws Exception { String persistenceName = getInstance().getClass().getSimpleName(); try { //logger.debug("Going to account {} using {}", usageRecord, persistenceName); @@ -186,7 +187,7 @@ public abstract class Persistence { * so that the {@link #UsageRecord} can be recorder later. * @param usageRecord the {@link #UsageRecord} to persist */ - public void account(final UsageRecord usageRecord){ + public void account(final SingleUsageRecord usageRecord){ Runnable runnable = new Runnable(){ @Override public void run(){ diff --git a/src/test/java/org/gcube/accounting/datamodel/implementation/ServiceUsageRecordTest.java b/src/test/java/org/gcube/accounting/datamodel/implementation/ServiceUsageRecordTest.java index e2aa3dd..84ceca6 100644 --- a/src/test/java/org/gcube/accounting/datamodel/implementation/ServiceUsageRecordTest.java +++ b/src/test/java/org/gcube/accounting/datamodel/implementation/ServiceUsageRecordTest.java @@ -21,12 +21,11 @@ public class ServiceUsageRecordTest { ServiceUsageRecord serviceUsageRecord = new ServiceUsageRecord(); serviceUsageRecord.setConsumerId("luca.frosini"); - serviceUsageRecord.setResourceScope("/gcube/devsec"); + serviceUsageRecord.setScope("/gcube/devsec"); serviceUsageRecord.setServiceClass("Accounting"); serviceUsageRecord.setServiceName("Accounting-Lib"); serviceUsageRecord.setRefHost("localhost"); serviceUsageRecord.setRefVM("local"); - serviceUsageRecord.setCallerScope("/gcube/devsec"); serviceUsageRecord.setResourceProperty("ConnectionTest", "Test"); diff --git a/src/test/java/org/gcube/accounting/datamodel/persistence/PersistenceTest.java b/src/test/java/org/gcube/accounting/datamodel/persistence/PersistenceTest.java index 718df53..567e56f 100644 --- a/src/test/java/org/gcube/accounting/datamodel/persistence/PersistenceTest.java +++ b/src/test/java/org/gcube/accounting/datamodel/persistence/PersistenceTest.java @@ -6,7 +6,7 @@ package org.gcube.accounting.datamodel.persistence; import java.util.Calendar; import java.util.GregorianCalendar; -import org.gcube.accounting.datamodel.UsageRecord; +import org.gcube.accounting.datamodel.SingleUsageRecord; import org.gcube.accounting.persistence.Persistence; import org.junit.Test; import org.slf4j.Logger; @@ -36,7 +36,7 @@ public class PersistenceTest { int quantity = 3000; Calendar startTestTime = new GregorianCalendar(); for(int i=0; i< quantity; i++){ - UsageRecord usageRecord = Persistence.createTestUsageRecord(); + SingleUsageRecord usageRecord = Persistence.createTestUsageRecord(); persistence.account(usageRecord); } Calendar stopTestTime = new GregorianCalendar();