diff --git a/src/main/java/org/gcube/accounting/datamodel/AggregationStrategy.java b/src/main/java/org/gcube/accounting/datamodel/AggregationStrategy.java index 8a797cd..57c941e 100644 --- a/src/main/java/org/gcube/accounting/datamodel/AggregationStrategy.java +++ b/src/main/java/org/gcube/accounting/datamodel/AggregationStrategy.java @@ -28,6 +28,10 @@ public abstract class AggregationStrategy, this.aggregationField.add(BasicUsageRecord.SCOPE); this.aggregationField.add(BasicUsageRecord.OPERATION_RESULT); } + + public T getAggregatedUsageRecord(){ + return t; + } protected String commonFieldHash(B record) { try { @@ -64,7 +68,7 @@ public abstract class AggregationStrategy, public T aggregate(B record) throws NotAggregatableRecordsExceptions { try{ - if(isAggregable(record)){ + if(!isAggregable(record)){ throw new NotAggregatableRecordsExceptions("The Record provided as argument has different values for field wich must be common to be aggragatable"); } @@ -82,8 +86,11 @@ public abstract class AggregationStrategy, ((BasicUsageRecord) t).setEndTime(convertedEndTime); } + Calendar newCreationTime = Calendar.getInstance(); t = reallyAggregate(convertedRecord); + t.setCreationTime(newCreationTime); + return t; }catch(NotAggregatableRecordsExceptions e){ throw e; diff --git a/src/main/java/org/gcube/accounting/datamodel/TestUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/TestUsageRecord.java new file mode 100644 index 0000000..449bbe8 --- /dev/null +++ b/src/main/java/org/gcube/accounting/datamodel/TestUsageRecord.java @@ -0,0 +1,72 @@ +/** + * + */ +package org.gcube.accounting.datamodel; + +import org.gcube.accounting.datamodel.UsageRecord.OperationResult; +import org.gcube.accounting.datamodel.implementations.ServiceUsageRecord; +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 TestUsageRecord { + + private static final Logger logger = LoggerFactory.getLogger(TestUsageRecord.class); + + public final static String TEST_CONSUMER_ID = "name.surname"; + public final static String TEST_SCOPE = "/infrastructure/vo"; + + public final static String TEST_SERVICE_CLASS = "TestServiceClass"; + public final static String TEST_SERVICE_NAME = "TestServiceName"; + + public final static String TEST_REF_HOST = "localhost"; + public final static String TEST_REF_VM = "local"; + + public final static String TEST_PROPERTY_NAME = "TestPropertyName"; + public final static String TEST_PROPERTY_VALUE = "TestPropertyValue"; + + private final static long MIN = 60; + private final static long MAX = 1000; + + /** + * Generate A Random long in a range between min and max. + * This function is internally used to set random duration. + * @return the generated random long + */ + public static long generateRandomLong(long min, long max){ + return min + (int)(Math.random() * ((max - min) + 1)); + } + + /** + * Create a valid SingleUsageRecord + * @return the created UsageRecord + */ + public static SingleUsageRecord createTestUsageRecord() { + ServiceUsageRecord serviceUsageRecord = new ServiceUsageRecord(); + try { + serviceUsageRecord.setConsumerId(TEST_CONSUMER_ID); + serviceUsageRecord.setScope(TEST_SCOPE); + serviceUsageRecord.setOperationResult(OperationResult.SUCCESS); + + serviceUsageRecord.setServiceClass(TEST_SERVICE_CLASS); + serviceUsageRecord.setServiceName(TEST_SERVICE_NAME); + + serviceUsageRecord.setRefHost(TEST_REF_HOST); + serviceUsageRecord.setRefVM(TEST_REF_VM); + + serviceUsageRecord.setDuration(generateRandomLong(MIN, MAX)); + + serviceUsageRecord.setResourceProperty(TEST_PROPERTY_NAME, TEST_PROPERTY_VALUE); + + } catch (InvalidValueException e) { + logger.error(" ------ You SHOULD NOT SEE THIS MESSAGE. Error Creating a test Usage Record", e.getCause()); + } + return serviceUsageRecord; + + } + +} diff --git a/src/main/java/org/gcube/accounting/datamodel/aggregation/ServiceUsageRecord.java b/src/main/java/org/gcube/accounting/datamodel/aggregation/ServiceUsageRecord.java index 6e7249c..373bcbe 100644 --- a/src/main/java/org/gcube/accounting/datamodel/aggregation/ServiceUsageRecord.java +++ b/src/main/java/org/gcube/accounting/datamodel/aggregation/ServiceUsageRecord.java @@ -57,6 +57,7 @@ public class ServiceUsageRecord extends org.gcube.accounting.datamodel.implement this.setMinInvocationTime(duration); this.setMaxInvocationTime(duration); Calendar creationTime = record.getCreationTime(); + this.setCreationTime(creationTime); this.setStartTime(creationTime); this.setEndTime(creationTime); init(); diff --git a/src/main/java/org/gcube/accounting/datamodel/aggregation/aggregationstrategy/ServiceUsageRecordAggregationStrategy.java b/src/main/java/org/gcube/accounting/datamodel/aggregation/aggregationstrategy/ServiceUsageRecordAggregationStrategy.java index cd51310..f193006 100644 --- a/src/main/java/org/gcube/accounting/datamodel/aggregation/aggregationstrategy/ServiceUsageRecordAggregationStrategy.java +++ b/src/main/java/org/gcube/accounting/datamodel/aggregation/aggregationstrategy/ServiceUsageRecordAggregationStrategy.java @@ -18,7 +18,7 @@ public class ServiceUsageRecordAggregationStrategy extends AggregationStrategy= secondDuration){ + Assert.assertTrue(aggregated.getMaxInvocationTime() == firstduration); + Assert.assertTrue(aggregated.getMinInvocationTime() == secondDuration); + }else{ + Assert.assertTrue(aggregated.getMaxInvocationTime() == secondDuration); + Assert.assertTrue(aggregated.getMinInvocationTime() == firstduration); + } + + + } + + @Test + public void secondAsAggregated() throws InvalidValueException, NotAggregatableRecordsExceptions { + + ServiceUsageRecord serviceUsageRecord = (ServiceUsageRecord) TestUsageRecord.createTestUsageRecord(); + serviceUsageRecord.validate(); + logger.debug("ServiceUsageRecord : {}", serviceUsageRecord); + + org.gcube.accounting.datamodel.aggregation.ServiceUsageRecord aggregated = + new org.gcube.accounting.datamodel.aggregation.ServiceUsageRecord(serviceUsageRecord); + logger.debug("ServiceUsageRecord Converted to Aggregated: {}", aggregated); + aggregated.validate(); + + ServiceUsageRecord serviceUsageRecord2 = (ServiceUsageRecord) TestUsageRecord.createTestUsageRecord(); + serviceUsageRecord2.validate(); + logger.debug("ServiceUsageRecord 2 : {}", serviceUsageRecord2); + org.gcube.accounting.datamodel.aggregation.ServiceUsageRecord converted2 = + new org.gcube.accounting.datamodel.aggregation.ServiceUsageRecord(serviceUsageRecord2); + logger.debug("ServiceUsageRecord 2 Converted to Aggregated: {}", converted2); + converted2.validate(); + + ServiceUsageRecordAggregationStrategy suras = new ServiceUsageRecordAggregationStrategy(aggregated); + + long firstduration = aggregated.getDuration(); + long secondDuration = converted2.getDuration(); + + suras.aggregate(converted2); + logger.debug("Resulting Aggregated ServiceUsageRecord: {}", aggregated); + aggregated.validate(); + + Assert.assertTrue(aggregated.getDuration() == ((firstduration + secondDuration)/2)); + Assert.assertTrue(aggregated.getInvocationCount() == 2); + + if(firstduration >= secondDuration){ + Assert.assertTrue(aggregated.getMaxInvocationTime() == firstduration); + Assert.assertTrue(aggregated.getMinInvocationTime() == secondDuration); + }else{ + Assert.assertTrue(aggregated.getMaxInvocationTime() == secondDuration); + Assert.assertTrue(aggregated.getMinInvocationTime() == firstduration); + } + } + + @Test + public void aggregationStressTest() throws InvalidValueException, NotAggregatableRecordsExceptions { + + ServiceUsageRecord serviceUsageRecord = (ServiceUsageRecord) TestUsageRecord.createTestUsageRecord(); + serviceUsageRecord.validate(); + logger.debug("ServiceUsageRecord : {}", serviceUsageRecord); + + org.gcube.accounting.datamodel.aggregation.ServiceUsageRecord aggregated = + new org.gcube.accounting.datamodel.aggregation.ServiceUsageRecord(serviceUsageRecord); + logger.debug("ServiceUsageRecord Converted to Aggregated: {}", aggregated); + aggregated.validate(); + + ServiceUsageRecordAggregationStrategy suras = new ServiceUsageRecordAggregationStrategy(aggregated); + + for(int i=2; i<1002; i++){ + + ServiceUsageRecord sur = (ServiceUsageRecord) TestUsageRecord.createTestUsageRecord(); + sur.validate(); + logger.debug("Cycle ServiceUsageRecord {}: {}", i, sur); + + + long minInvocationTime = aggregated.getMinInvocationTime(); + long maxInvocationTime = aggregated.getMaxInvocationTime(); + long oldDuration = aggregated.getDuration(); + long newDuration = sur.getDuration(); + + suras.aggregate(sur); + logger.debug("Resulting Aggregated ServiceUsageRecord: {}", aggregated); + aggregated.validate(); + + Assert.assertTrue(aggregated.getDuration() == ((oldDuration + newDuration)/2)); + Assert.assertTrue(aggregated.getInvocationCount() == i); + + if(minInvocationTime >= newDuration){ + Assert.assertTrue(aggregated.getMinInvocationTime() == newDuration); + }else{ + Assert.assertTrue(aggregated.getMinInvocationTime() == minInvocationTime); + } + + if(maxInvocationTime >= newDuration){ + Assert.assertTrue(aggregated.getMaxInvocationTime() == maxInvocationTime); + }else{ + Assert.assertTrue(aggregated.getMaxInvocationTime() == newDuration); + } + + } + + logger.debug("Resulting Aggregated ServiceUsageRecord: {}", aggregated); + } + +} 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 567e56f..c88780e 100644 --- a/src/test/java/org/gcube/accounting/datamodel/persistence/PersistenceTest.java +++ b/src/test/java/org/gcube/accounting/datamodel/persistence/PersistenceTest.java @@ -7,6 +7,7 @@ import java.util.Calendar; import java.util.GregorianCalendar; import org.gcube.accounting.datamodel.SingleUsageRecord; +import org.gcube.accounting.datamodel.TestUsageRecord; import org.gcube.accounting.persistence.Persistence; import org.junit.Test; import org.slf4j.Logger; @@ -36,7 +37,7 @@ public class PersistenceTest { int quantity = 3000; Calendar startTestTime = new GregorianCalendar(); for(int i=0; i< quantity; i++){ - SingleUsageRecord usageRecord = Persistence.createTestUsageRecord(); + SingleUsageRecord usageRecord = TestUsageRecord.createTestUsageRecord(); persistence.account(usageRecord); } Calendar stopTestTime = new GregorianCalendar();