refs #1746: Separate Accounting Model and generalize solution

https://support.d4science.org/issues/1746

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/accounting/accounting-lib@121990 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Luca Frosini 2015-12-18 16:09:05 +00:00
parent c6067def1c
commit 6e4e3d4c93
78 changed files with 704 additions and 2285 deletions

View File

@ -2,6 +2,5 @@
<wb-module deploy-name="accounting-lib">
<wb-resource deploy-path="/" source-path="/src/main/java"/>
<wb-resource deploy-path="/" source-path="/src/main/resources"/>
<wb-resource deploy-path="/" source-path="/src/test/resources"/>
</wb-module>
</project-modules>

16
pom.xml
View File

@ -10,7 +10,7 @@
<groupId>org.gcube.accounting</groupId>
<artifactId>accounting-lib</artifactId>
<version>1.2.0-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<name>Accounting Library</name>
<description>Accounting Library</description>
<packaging>jar</packaging>
@ -40,6 +40,11 @@
<dependencies>
<dependency>
<groupId>org.gcube.data.publishing</groupId>
<artifactId>document-store-lib</artifactId>
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.resources.discovery</groupId>
<artifactId>ic-client</artifactId>
@ -64,8 +69,13 @@
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test Dependency -->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
<!-- Test Dependency -->
<dependency>
<groupId>org.gcube.resources</groupId>
<artifactId>registry-publisher</artifactId>

View File

@ -1,218 +0,0 @@
package org.gcube.accounting.aggregation.scheduler;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gcube.accounting.aggregation.AggregatedServiceUsageRecord;
import org.gcube.accounting.aggregation.strategy.ServiceUsageRecordAggregationStrategy;
import org.gcube.accounting.datamodel.AggregatedUsageRecord;
import org.gcube.accounting.datamodel.AggregationStrategy;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.exception.NotAggregatableRecordsExceptions;
import org.gcube.accounting.persistence.AccountingPersistenceExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public abstract class AggregationScheduler {
private static Logger logger = LoggerFactory.getLogger(AggregationScheduler.class);
public static AggregationScheduler newInstance(){
return new BufferAggregationScheduler();
}
protected int totalBufferedRecords;
@SuppressWarnings("rawtypes")
protected Map<String, List<AggregationStrategy>> records;
protected List<UsageRecord> unaggregableRecords;
@SuppressWarnings("rawtypes")
protected AggregationScheduler(){
this.records = new HashMap<String, List<AggregationStrategy>>();
unaggregableRecords = new ArrayList<UsageRecord>();
totalBufferedRecords = 0;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected Class<? extends AggregatedUsageRecord> getAggregatedUsageRecordClass(String usageRecordType) throws ClassNotFoundException {
Class<? extends AggregatedUsageRecord> clz;
String aggregatedURFullyQualifiedName;
try {
Package aggregatedPackage = AggregatedServiceUsageRecord.class.getPackage();
aggregatedURFullyQualifiedName = String.format("%s.Aggregated%s", aggregatedPackage.getName(), usageRecordType);
clz = (Class<? extends AggregatedUsageRecord>) Class.forName(aggregatedURFullyQualifiedName);
} catch (ClassNotFoundException e) {
logger.error("Unable To find the Aggregation Class for {}", usageRecordType);
throw e;
}
return clz;
}
@SuppressWarnings("rawtypes")
protected AggregatedUsageRecord instantiateAggregatedUsageRecord(UsageRecord usageRecord) throws Exception{
String usageRecordType = usageRecord.getUsageRecordType();
Class<? extends AggregatedUsageRecord> clz = getAggregatedUsageRecordClass(usageRecordType);
Class[] argTypes = { usageRecord.getClass() };
Constructor<? extends AggregatedUsageRecord> constructor = clz.getDeclaredConstructor(argTypes);
Object[] arguments = {usageRecord};
return constructor.newInstance(arguments);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected Class<? extends AggregationStrategy> getAggregattionStrategyUsageRecordClass(String usageRecordType) throws ClassNotFoundException {
Class<? extends AggregationStrategy> clz;
String aggregationStrategyName;
try {
Package aggregationStrategyPackage = ServiceUsageRecordAggregationStrategy.class.getPackage();
aggregationStrategyName = String.format("%s.%s%s", aggregationStrategyPackage.getName(), usageRecordType, AggregationStrategy.class.getSimpleName());
clz = (Class<? extends AggregationStrategy>) Class.forName(aggregationStrategyName);
} catch (Exception e) {
logger.error("Unable To find the Aggregation Strategy Class for {}", usageRecordType);
throw e;
}
return clz;
}
@SuppressWarnings("rawtypes")
protected AggregationStrategy instantiateAggregationStrategy(AggregatedUsageRecord aggregatedUsageRecord) throws Exception{
String usageRecordType = aggregatedUsageRecord.getUsageRecordType();
Class<? extends AggregationStrategy> clz = getAggregattionStrategyUsageRecordClass(usageRecordType);
Class[] argTypes = { aggregatedUsageRecord.getClass() };
Constructor<? extends AggregationStrategy> constructor = clz.getDeclaredConstructor(argTypes);
Object[] arguments = {aggregatedUsageRecord};
return constructor.newInstance(arguments);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected void madeAggregation(UsageRecord usageRecord){
String usageRecordType = usageRecord.getUsageRecordType();
List<AggregationStrategy> aggregationStrategies;
if(this.records.containsKey(usageRecordType)){
aggregationStrategies = this.records.get(usageRecordType);
boolean found = false;
for(AggregationStrategy aggregationStrategy : aggregationStrategies){
try {
aggregationStrategy.aggregate((SingleUsageRecord) usageRecord);
logger.trace("{} has been used for aggregation. Aggregated Record is {}", aggregationStrategy, aggregationStrategy.getAggregatedUsageRecord());
found = true;
break;
} catch(NotAggregatableRecordsExceptions e) {
logger.trace("{} is not usable for aggregation", aggregationStrategy);
}
}
if(found){
return;
}
}else{
aggregationStrategies = new ArrayList<AggregationStrategy>();
this.records.put(usageRecordType, aggregationStrategies);
}
AggregatedUsageRecord aggregatedUsageRecord;
if(usageRecord instanceof AggregatedUsageRecord){
// the record is already an aggregated version
aggregatedUsageRecord = (AggregatedUsageRecord) usageRecord;
}else{
try {
// Instantiate the aggregated usage record using reflection with the
// simple name of the new UsageRecord to aggregate.
// The instantiated UsageRecord is the aggregated version from
// org.gcube.accounting.datamodel.aggregation package
aggregatedUsageRecord = instantiateAggregatedUsageRecord(usageRecord);
} catch (Exception e) {
logger.error("Unable to Istantiate the Aggregation Class for {}. The Record will be persisted as is (Better than nothing).", usageRecordType);
unaggregableRecords.add(usageRecord);
totalBufferedRecords++;
return;
}
}
try {
AggregationStrategy aggregationStrategy = instantiateAggregationStrategy(aggregatedUsageRecord);
aggregationStrategies.add(aggregationStrategy);
totalBufferedRecords++;
} catch (Exception e) {
logger.error("Unable to Istantiate the Aggregation Strategy Class for {}. The Record will be persisted as is (Better than nothing).", usageRecordType);
unaggregableRecords.add(usageRecord);
}
}
public void flush(AccountingPersistenceExecutor persistenceExecutor) throws Exception{
aggregate(null, persistenceExecutor, true);
}
protected abstract void specificClear();
protected void clear(){
totalBufferedRecords=0;
records.clear();
unaggregableRecords.clear();
specificClear();
}
protected synchronized void aggregate(SingleUsageRecord usageRecord, AccountingPersistenceExecutor persistenceExecutor, boolean forceFlush) throws Exception {
if(usageRecord!=null){
logger.trace("Trying to aggregate {}", usageRecord);
madeAggregation(usageRecord);
}
if(isTimeToPersist() || forceFlush){
UsageRecord[] recordToPersist = new UsageRecord[totalBufferedRecords];
int i = 0;
@SuppressWarnings("rawtypes")
Collection<List<AggregationStrategy>> values = records.values();
for(@SuppressWarnings("rawtypes") List<AggregationStrategy> startegies : values){
for(@SuppressWarnings("rawtypes") AggregationStrategy startegy : startegies){
recordToPersist[i] = startegy.getAggregatedUsageRecord();
i++;
}
}
for(UsageRecord record : unaggregableRecords){
recordToPersist[i] = record;
i++;
}
logger.trace("It is time to persist buffered records {}", Arrays.toString(recordToPersist));
persistenceExecutor.persist(recordToPersist);
clear();
}
}
/**
* Get an usage records and try to aggregate with other buffered
* Usage Record.
* @param usageRecord the Usage Record To Buffer
* @return true if is time to persist the buffered Usage Record
* @throws Exception if fails
*/
public void aggregate(SingleUsageRecord usageRecord, AccountingPersistenceExecutor persistenceExecutor) throws Exception {
logger.trace("Going to aggregate {}", usageRecord);
aggregate(usageRecord, persistenceExecutor, false);
}
protected abstract boolean isTimeToPersist();
}

View File

@ -1,69 +0,0 @@
/**
*
*/
package org.gcube.accounting.aggregation.scheduler;
import java.util.Calendar;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
* This class implements a Simple Buffer with timeout strategy.
* It buffer a predefined number of Records before invoking a persistence.
*
*
*/
public class BufferAggregationScheduler extends AggregationScheduler {
/**
* Define the MAX number of Record to buffer.
* TODO Get from configuration
*/
protected final static int MAX_RECORDS_NUMBER = 15;
/**
* The Max amount of time elapsed form last record before after that
* the buffered record are persisted even if
* TODO Get from configuration
*/
protected final static long OLD_RECORD_MAX_TIME_ELAPSED = 1000*60*5; // 5 min
protected boolean firstOfBuffer;
protected long firstBufferedTime;
protected BufferAggregationScheduler(){
super();
this.firstOfBuffer = true;
}
@Override
protected void specificClear(){
firstOfBuffer = true;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isTimeToPersist(){
long now = Calendar.getInstance().getTimeInMillis();
if(firstOfBuffer){
firstOfBuffer = false;
firstBufferedTime = now;
}
if(totalBufferedRecords >= MAX_RECORDS_NUMBER){
return true;
}
if((now - firstBufferedTime) >= OLD_RECORD_MAX_TIME_ELAPSED){
return true;
}
return false;
}
}

View File

@ -1,61 +0,0 @@
/**
*
*/
package org.gcube.accounting.aggregation.strategy;
import org.gcube.accounting.aggregation.AggregatedServiceUsageRecord;
import org.gcube.accounting.datamodel.AggregationStrategy;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.accounting.exception.NotAggregatableRecordsExceptions;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class ServiceUsageRecordAggregationStrategy extends AggregationStrategy<AggregatedServiceUsageRecord, ServiceUsageRecord>{
/**
* @param serviceUsageRecord
*/
public ServiceUsageRecordAggregationStrategy(AggregatedServiceUsageRecord serviceUsageRecord) {
super(serviceUsageRecord);
this.aggregationField.add(AggregatedServiceUsageRecord.CALLER_HOST);
this.aggregationField.add(AggregatedServiceUsageRecord.HOST);
this.aggregationField.add(AggregatedServiceUsageRecord.SERVICE_CLASS);
this.aggregationField.add(AggregatedServiceUsageRecord.SERVICE_NAME);
this.aggregationField.add(AggregatedServiceUsageRecord.CALLED_METHOD);
}
protected long durationWeightedAverage(AggregatedServiceUsageRecord record){
long tDuration = t.getDuration() * t.getOperationCount();
long recordDuration = record.getDuration() * record.getOperationCount();
long totalOperationCount = t.getOperationCount() + record.getOperationCount();
return (tDuration + recordDuration) / totalOperationCount;
}
protected AggregatedServiceUsageRecord reallyAggregate(AggregatedServiceUsageRecord record)
throws NotAggregatableRecordsExceptions {
try {
t.setDuration(durationWeightedAverage(record));
t.setOperationCount(t.getOperationCount() + record.getOperationCount());
long max = record.getMaxInvocationTime();
if(max > t.getMaxInvocationTime()){
t.setMaxInvocationTime(max);
}
long min = record.getMinInvocationTime();
if(min < t.getMinInvocationTime()){
t.setMinInvocationTime(min);
}
}catch(Exception e){
throw new UnsupportedOperationException(e);
}
return t;
}
}

View File

@ -1,43 +0,0 @@
/**
*
*/
package org.gcube.accounting.aggregation.strategy;
import org.gcube.accounting.aggregation.AggregatedStorageUsageRecord;
import org.gcube.accounting.datamodel.AggregationStrategy;
import org.gcube.accounting.datamodel.usagerecords.StorageUsageRecord;
import org.gcube.accounting.exception.NotAggregatableRecordsExceptions;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class StorageUsageRecordAggregationStrategy extends AggregationStrategy<AggregatedStorageUsageRecord, StorageUsageRecord>{
/**
* @param serviceUsageRecord
*/
public StorageUsageRecordAggregationStrategy(AggregatedStorageUsageRecord storageUsageRecord) {
super(storageUsageRecord);
this.aggregationField.add(AggregatedStorageUsageRecord.RESOURCE_OWNER);
this.aggregationField.add(AggregatedStorageUsageRecord.RESOURCE_SCOPE);
this.aggregationField.add(AggregatedStorageUsageRecord.RESOURCE_URI);
this.aggregationField.add(AggregatedStorageUsageRecord.PROVIDER_URI);
this.aggregationField.add(AggregatedStorageUsageRecord.OPERATION_TYPE);
this.aggregationField.add(AggregatedStorageUsageRecord.DATA_TYPE);
}
protected AggregatedStorageUsageRecord reallyAggregate(AggregatedStorageUsageRecord record)
throws NotAggregatableRecordsExceptions {
try {
t.setOperationCount(t.getOperationCount() + record.getOperationCount());
t.setDataVolume(t.getDataVolume() + record.getDataVolume());
}catch(Exception e){
throw new UnsupportedOperationException(e);
}
return t;
}
}

View File

@ -3,32 +3,28 @@
*/
package org.gcube.accounting.datamodel;
import java.util.Calendar;
import org.gcube.accounting.datamodel.decorators.AggregatedField;
import org.gcube.accounting.datamodel.validations.annotations.NotEmptyIfNotNull;
import org.gcube.accounting.datamodel.validations.annotations.ValidInteger;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.datamodel.validations.annotations.ValidLong;
import org.gcube.documentstore.records.AggregatedRecord;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*/
public interface AggregatedUsageRecord<T extends AggregatedUsageRecord<T, B>, B extends SingleUsageRecord> extends UsageRecord {
@SuppressWarnings("rawtypes")
public interface AggregatedUsageRecord<A extends AggregatedUsageRecord, U extends UsageRecord> extends AggregatedRecord<A,U> {
@AggregatedField @NotEmptyIfNotNull
public static final String AGGREGATED = AggregatedRecord.AGGREGATED;
@AggregatedField @ValidInteger
public static final String OPERATION_COUNT = "operationCount";
public static final String OPERATION_COUNT = AggregatedRecord.OPERATION_COUNT;
public T getAggregatedUsageRecord(B usageRecord) throws InvalidValueException ;
@AggregatedField @ValidLong
public static final String START_TIME = AggregatedRecord.START_TIME;
public int getOperationCount();
public void setOperationCount(int operationCount) throws InvalidValueException;
public Calendar getStartTime();
public void setStartTime(Calendar startTime) throws InvalidValueException;
public Calendar getEndTime();
public void setEndTime(Calendar endTime) throws InvalidValueException;
@AggregatedField @ValidLong
public static final String END_TIME = AggregatedRecord.END_TIME;
}

View File

@ -1,129 +0,0 @@
/**
*
*/
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;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.exception.NotAggregatableRecordsExceptions;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*/
public abstract class AggregationStrategy<T extends AggregatedUsageRecord<T, B>, B extends SingleUsageRecord> {
protected T t;
protected Set<String> aggregationField;
protected void cleanExtraFields(){
Set<String> neededFields = ((BasicUsageRecord) t).requiredFields;
neededFields.addAll(((BasicUsageRecord) t).aggregatedFields);
Set<String> keysToRemove = new HashSet<String>();
Set<String> propertyKeys = ((BasicUsageRecord) t).resourceProperties.keySet();
for(String propertyName : propertyKeys){
if(!neededFields.contains(propertyName)){
keysToRemove.add(propertyName);
}
}
for(String keyToRemove : keysToRemove){
((BasicUsageRecord) t).resourceProperties.remove(keyToRemove);
}
}
public AggregationStrategy(T t){
this.t = t;
cleanExtraFields();
this.aggregationField = new HashSet<String>();
this.aggregationField.add(BasicUsageRecord.CONSUMER_ID);
this.aggregationField.add(BasicUsageRecord.USAGE_RECORD_TYPE);
this.aggregationField.add(BasicUsageRecord.SCOPE);
this.aggregationField.add(BasicUsageRecord.OPERATION_RESULT);
}
public T getAggregatedUsageRecord(){
return t;
}
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);
}
}
protected boolean isAggregable(UsageRecord record) {
for(String field : aggregationField){
Comparable<? extends Serializable> recordValue = record.getResourceProperty(field);
Comparable<? extends Serializable> thisValue = ((BasicUsageRecord) t).getResourceProperty(field);
if(!recordValue.equals(thisValue)){
return false;
}
}
return true;
}
protected abstract T reallyAggregate(T t) throws NotAggregatableRecordsExceptions;
public synchronized T aggregate(T record) throws NotAggregatableRecordsExceptions {
try{
if(!isAggregable(record)){
throw new NotAggregatableRecordsExceptions("The Record provided as argument has different values for field wich must be common to be aggragatable");
}
Calendar convertedStartTime = ((BasicUsageRecord) record).getStartTimeAsCalendar();
Calendar actualStartTime = ((BasicUsageRecord) t).getStartTimeAsCalendar();
if(convertedStartTime.before(actualStartTime)){
((BasicUsageRecord) t).setStartTime(convertedStartTime);
}
Calendar convertedEndTime = ((BasicUsageRecord) record).getEndTimeAsCalendar();
Calendar actualEndTime = ((BasicUsageRecord) t).getEndTimeAsCalendar();
if(convertedEndTime.after(actualEndTime)){
((BasicUsageRecord) t).setEndTime(convertedEndTime);
}
Calendar newCreationTime = Calendar.getInstance();
t = reallyAggregate(record);
((BasicUsageRecord) t).setCreationTime(newCreationTime);
return t;
}catch(NotAggregatableRecordsExceptions e){
throw e;
}catch(Exception ex){
throw new NotAggregatableRecordsExceptions(ex.getCause());
}
}
public T aggregate(B record) throws NotAggregatableRecordsExceptions {
T convertedRecord;
try {
convertedRecord = t.getAggregatedUsageRecord(record);
return aggregate(convertedRecord);
} catch (InvalidValueException e) {
throw new NotAggregatableRecordsExceptions(e);
}
}
}

View File

@ -5,7 +5,6 @@ package org.gcube.accounting.datamodel;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
@ -24,12 +23,12 @@ 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.validations.annotations.NotEmpty;
import org.gcube.accounting.datamodel.validations.annotations.NotEmptyIfNotNull;
import org.gcube.accounting.datamodel.validations.annotations.ValidInteger;
import org.gcube.accounting.datamodel.validations.annotations.ValidLong;
import org.gcube.accounting.datamodel.validations.annotations.ValidOperationResult;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.records.AggregatedRecord;
import org.gcube.documentstore.records.Record;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -37,7 +36,7 @@ import org.slf4j.LoggerFactory;
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public abstract class BasicUsageRecord implements UsageRecord, Serializable {
public abstract class BasicUsageRecord implements UsageRecord {
/**
* Generated Serial Version UID
@ -46,47 +45,27 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable {
private static Logger logger = LoggerFactory.getLogger(BasicUsageRecord.class);
/**
* KEY for : The unique identifier for the UsageRecord.
* The ID is automatically Created. Set the ID only if you really know what
* you are going to do.
*/
@RequiredField @NotEmpty
protected static final String ID = "id";
/**
* KEY for : The user (or the Consumer Identity, that in the S2S
* communication is another service).
*/
@RequiredField @NotEmpty
public static final String CONSUMER_ID = "consumerId";
/**
* KEY for : The instant when the UR was created. The value will be recorded
* in UTC milliseconds from the epoch.
*/
@RequiredField @ValidLong
public static final String CREATION_TIME = "creationTime";
/**
* Internal USE ONLY.
* KEY for : The Class Name of the represented {#Usage Record}
*/
@RequiredField @NotEmpty
protected static final String USAGE_RECORD_TYPE = "usageRecordType";
/**
* KEY for : The accounting scope
*/
@RequiredField @NotEmpty
public static final String SCOPE = "scope";
/**
* KEY for : The Operation Result of the accounted operation.
* The value is expressed as
* {@link #org.gcube.accounting.datamodel.UsageRecord.OperationResult}
*/
@RequiredField @ValidOperationResult
public static final String OPERATION_RESULT = "operationResult";
private static final String ID = Record.ID;
@RequiredField @NotEmpty
private static final String CONSUMER_ID = UsageRecord.CONSUMER_ID;
@RequiredField @ValidLong
private static final String CREATION_TIME = Record.CREATION_TIME;
@RequiredField @NotEmpty
private static final String RECORD_TYPE = Record.RECORD_TYPE;
// TODO MOVE TO RECORD_TYPE
@Deprecated @RequiredField @NotEmpty
public static final String USAGE_RECORD_TYPE = "usageRecordType";
@RequiredField @NotEmpty
private static final String SCOPE = UsageRecord.SCOPE;
@RequiredField @ValidOperationResult
private static final String OPERATION_RESULT = UsageRecord.OPERATION_RESULT;
/** resource-specific properties */
protected Map<String, Comparable<? extends Serializable>> resourceProperties;
@ -104,32 +83,9 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable {
protected Set<String> computedFields;
/**
* KEY for : Used in aggregated record. Represent the left end of the time
* interval covered by this {#Usage Record}
* The value will be recorded in UTC milliseconds from the epoch.
*/
@AggregatedField @ValidLong
protected static final String START_TIME = "startTime";
/**
* KEY for : Used in aggregated record. Represent the right end of the time
* interval covered by this {#Usage Record}
* The value will be recorded in UTC milliseconds from the epoch.
*/
@AggregatedField @ValidLong
protected static final String END_TIME = "endTime";
/**
* Internal USE ONLY.
* KEY for : Indicate that the record is an aggregation
*/
@AggregatedField @NotEmptyIfNotNull
protected static final String AGGREGATED = "aggregated";
/**
* KEY for : Indicate The Number of Aggregated Operation
*/
@AggregatedField @ValidInteger
protected static final String OPERATION_COUNT = "operationCount";
private static final String START_TIME = AggregatedRecord.START_TIME;
private static final String END_TIME = AggregatedRecord.END_TIME;
private static final String OPERATION_COUNT = AggregatedUsageRecord.OPERATION_COUNT;
protected Set<String> aggregatedFields;
@ -186,6 +142,23 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable {
*/
}
protected void cleanExtraFields(){
Set<String> neededFields = this.requiredFields;
neededFields.addAll(this.aggregatedFields);
Set<String> keysToRemove = new HashSet<String>();
Set<String> propertyKeys = this.resourceProperties.keySet();
for(String propertyName : propertyKeys){
if(!neededFields.contains(propertyName)){
keysToRemove.add(propertyName);
}
}
for(String keyToRemove : keysToRemove){
this.resourceProperties.remove(keyToRemove);
}
}
/**
* Initialize variable
*/
@ -206,7 +179,7 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable {
public BasicUsageRecord(){
init();
this.resourceProperties.put(ID, UUID.randomUUID().toString());
this.setUsageRecordType();
this.setRecordType();
Calendar calendar = Calendar.getInstance();
this.resourceProperties.put(CREATION_TIME, calendar.getTimeInMillis());
}
@ -214,19 +187,30 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable {
public BasicUsageRecord(Map<String, Comparable<? extends Serializable>> properties) throws InvalidValueException {
init();
setResourceProperties(properties);
if(this instanceof AggregatedUsageRecord){
this.resourceProperties.put(AggregatedUsageRecord.AGGREGATED, true);
cleanExtraFields();
}
}
@Deprecated
public String getUsageRecordType() {
return getRecordType();
}
/**
* {@inheritDoc}
*/
@Override
public String getUsageRecordType() {
return (String) this.resourceProperties.get(USAGE_RECORD_TYPE);
public String getRecordType() {
return (String) this.resourceProperties.get(RECORD_TYPE);
}
protected abstract String giveMeUsageRecordType();
@Deprecated
protected void setUsageRecordType(){
setRecordType();
}
protected void setRecordType(){
this.resourceProperties.put(RECORD_TYPE, this.giveMeUsageRecordType());
this.resourceProperties.put(USAGE_RECORD_TYPE, this.giveMeUsageRecordType());
}
@ -492,9 +476,9 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable {
* not contains all parameters in this instance, -1 is returned.
*/
@Override
public int compareTo(UsageRecord usageRecord) {
public int compareTo(Record record) {
Set<Entry<String, Comparable<? extends Serializable>>> thisSet = this.resourceProperties.entrySet();
Set<Entry<String, Comparable<? extends Serializable>>> usageRecordSet = usageRecord.getResourceProperties().entrySet();
Set<Entry<String, Comparable<? extends Serializable>>> usageRecordSet = record.getResourceProperties().entrySet();
if(thisSet.size() != usageRecordSet.size()){
return thisSet.size() - usageRecordSet.size();
}
@ -503,117 +487,5 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable {
}
return 1;
}
private static final String AGGREGATED_PREFIX = "Aggregated";
@SuppressWarnings("unchecked")
protected static Class<? extends UsageRecord> getClass(String usageRecordName, boolean aggregated) throws ClassNotFoundException {
Class<? extends UsageRecord> clz = null;
Class<? extends UsageRecord> utilityClass = org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord.class;
if(aggregated){
utilityClass = org.gcube.accounting.aggregation.AggregatedServiceUsageRecord.class;
}
String classCanonicalName = utilityClass.getCanonicalName();
classCanonicalName = classCanonicalName.replace(utilityClass.getSimpleName().replace(AGGREGATED_PREFIX, ""), usageRecordName);
try {
clz = (Class<? extends UsageRecord>) Class.forName(classCanonicalName);
} catch (ClassNotFoundException e) {
logger.error("Unable to retrieve class {}", classCanonicalName);
throw e;
}
return clz;
}
/**
* This method use the resourceType value contained in the Map to instance
* the right UsageRecord class and return it. If the type implementation
* does not exist or the validation of one or more field validation fails
* an exception is thrown
* @param usageRecordMap
* @return the instance of the UsageRecord class.
* @throws Exception if fails
*/
public static UsageRecord getUsageRecord(Map<String, Comparable<? extends Serializable>> usageRecordMap) throws Exception {
String className = (String) usageRecordMap.get(USAGE_RECORD_TYPE);
boolean aggregated = false;
try {
aggregated = (Boolean) usageRecordMap.get(AGGREGATED);
}catch(Exception e){
try{
aggregated = Boolean.parseBoolean((String)usageRecordMap.get(AGGREGATED));
} catch(Exception e1){}
}
Class<? extends UsageRecord> clz = getClass(className, aggregated);
logger.debug("Trying to instantiate {}", clz);
@SuppressWarnings("rawtypes")
Class[] usageRecordArgTypes = { Map.class };
Constructor<? extends UsageRecord> usageRecordConstructor = clz.getDeclaredConstructor(usageRecordArgTypes);
Object[] usageRecordArguments = {usageRecordMap};
UsageRecord usageRecord = usageRecordConstructor.newInstance(usageRecordArguments);
logger.debug("Created Usage Record : {}", usageRecord);
return usageRecord;
}
/*
* IT DOES NOT WORK
* @SuppressWarnings("unchecked")
* public static Map<String,Serializable> getMapFromString(String serializedMap) throws IOException, ClassNotFoundException {
* ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(serializedMap.getBytes());
* ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
* return ((Map<String,Serializable>) objectInputStream.readObject());
* }
*/
private final static String LINE_FREFIX = "{";
private final static String LINE_SUFFIX = "}";
private final static String KEY_VALUE_PAIR_SEPARATOR = ",";
private final static String KEY_VALUE_LINKER = "=";
protected static Map<String, Comparable<? extends Serializable>> getMapFromString(String serializedMap){
/* Checking line sanity */
if(!serializedMap.startsWith(LINE_FREFIX) && !serializedMap.endsWith(LINE_SUFFIX)){
return null;
}
/* Cleaning prefix and suffix to parse line */
serializedMap = serializedMap.replace(LINE_FREFIX, "");
serializedMap = serializedMap.replace(LINE_SUFFIX, "");
Map<String, Comparable<? extends Serializable>> map = new HashMap<String, Comparable<? extends Serializable>>();
String[] pairs = serializedMap.split(KEY_VALUE_PAIR_SEPARATOR);
for (int i=0;i<pairs.length;i++) {
String pair = pairs[i];
pair.trim();
String[] keyValue = pair.split(KEY_VALUE_LINKER);
String key = keyValue[0].trim();
Comparable<? extends Serializable> value = keyValue[1].trim();
map.put(key, value);
}
return map;
}
/**
*
* @param serializedMap
* @return
* @throws Exception
*/
public static UsageRecord getUsageRecord(String serializedMap) throws Exception {
Map<String,Comparable<? extends Serializable>> map = getMapFromString(serializedMap);
return getUsageRecord(map);
}
}

View File

@ -20,7 +20,7 @@ import org.gcube.accounting.datamodel.usagerecords.StorageUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.TaskUsageRecord;
import org.gcube.accounting.datamodel.validations.annotations.NotEmpty;
import org.gcube.accounting.datamodel.validations.annotations.NotEmptyIfNotNull;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory;
*
*/
@Deprecated
public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecord {
public class RawUsageRecord extends BasicUsageRecord implements UsageRecord {
/**
* Generated Serial Version UID
@ -142,8 +142,8 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
}
/**
* Set the accounting scope of the {#UsageRecord}
* @param scope The accounting scope of the {#UsageRecord}
* Set the scope of the {#UsageRecord}
* @param scope the scope of the {#UsageRecord}
*/
@Deprecated
public void setResourceScope(String scope) {
@ -186,7 +186,7 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
*/
@Deprecated
public Date getCreateTime() {
long millis = (Long) this.resourceProperties.get(CREATION_TIME);
long millis = (Long) this.resourceProperties.get(AggregatedUsageRecord.CREATION_TIME);
return timestampStringToCalendar(millis).getTime();
}
@ -213,7 +213,7 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
*/
@Deprecated
public Date getStartTime() {
long millis = (Long) this.resourceProperties.get(START_TIME);
long millis = (Long) this.resourceProperties.get(AggregatedUsageRecord.START_TIME);
return timestampStringToCalendar(millis).getTime();
}
@ -235,7 +235,7 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
*/
@Deprecated
public Date getEndTime() {
long millis = (Long) this.resourceProperties.get(END_TIME);
long millis = (Long) this.resourceProperties.get(AggregatedUsageRecord.END_TIME);
return timestampStringToCalendar(millis).getTime();
}
@ -252,8 +252,8 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
/**
* Return the identity id of the accounting owner
* @return The identity id of the accounting owner
* Return the identity id of the owner
* @return The identity id of the owner
*/
@Deprecated
public String getResourceOwner() {
@ -261,8 +261,8 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
}
/**
* Set the identity id of the accounting owner
* @param ownerID The identity id of the accounting owner
* Set the identity id of the owner
* @param ownerID The identity id of the owner
* @throws InvalidValueException
*/
@Deprecated

View File

@ -1,12 +0,0 @@
/**
*
*/
package org.gcube.accounting.datamodel;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public interface SingleUsageRecord extends UsageRecord {
}

View File

@ -1,43 +1,45 @@
package org.gcube.accounting.datamodel;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Map;
import java.util.Set;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.records.Record;
public interface UsageRecord extends Comparable<UsageRecord> {
public interface UsageRecord extends Record {
public enum OperationResult implements Serializable, Comparable<OperationResult> {
SUCCESS, FAILED
}
/**
* @return a Set containing the keys of required fields
* KEY for : The Operation Result of the accounted operation.
* The value is expressed as
* {@link #org.gcube.accounting.datamodel.UsageRecord.OperationResult}
*/
public Set<String> getRequiredFields();
public static final String OPERATION_RESULT = "operationResult";
/**
* Return the Usage Record Type
* @return {#UsageRecord} Type
* KEY for : The user (or the Consumer Identity, that in the S2S
* communication is another service).
*/
public String getUsageRecordType();
public static final String CONSUMER_ID = "consumerId";
/**
* Return the unique id for this {#UsageRecord}
* @return {#UsageRecord} Unique ID
* KEY for : The scope
*/
public String getId();
public static final String SCOPE = "scope";
/**
* The ID is automatically Created by the implementation Class.
* Set the ID only if you really know what you are going to do.
* Set the unique id for this {#UsageRecord}
* @param id {#UsageRecord} Unique ID
* @throws InvalidValueException
* @return the Operation Result of the accounted operation.
*/
public void setId(String id) throws InvalidValueException;
public OperationResult getOperationResult();
/**
* Set the Operation Result related to the accounted Usage Record
* @param operationResult the Operation Result to set
* @throws InvalidValueException
*/
public void setOperationResult(OperationResult operationResult) throws InvalidValueException;
/**
* Return the user (or the Consumer Identity, that in the S2S
@ -54,22 +56,6 @@ public interface UsageRecord extends Comparable<UsageRecord> {
*/
public void setConsumerId(String consumerId) throws InvalidValueException;
/**
* Return the instant when this {#UsageRecord} was created.
* @return the creation time for this {#UsageRecord}
*/
public Calendar getCreationTime();
/**
* The CreationTime is automatically created by the implementation Class.
* Set the CreationTime only if you really know what you are going to do.
* Set the instant when this {#UsageRecord} was created.
* @param creationTime creation time
* @throws InvalidValueException
*/
public void setCreationTime(Calendar creationTime) throws InvalidValueException;
/**
* Return the scope of this {#UsageRecord}
* @return The scope of this {#UsageRecord}
@ -77,60 +63,13 @@ public interface UsageRecord extends Comparable<UsageRecord> {
public String getScope();
/**
* Set the accounting scope of the {#UsageRecord}
* @param scope The accounting scope of the {#UsageRecord}
* Set the scope of the {#UsageRecord}
* @param scope the scope of the {#UsageRecord}
* @throws InvalidValueException
*/
public void setScope(String scope) throws InvalidValueException;
/**
* Return all resource-specific properties. The returned Map is a copy of
* the internal representation. Any modification to the returned Map MUST
* not affect the object
* @return a Map containing the properties
*/
public Map<String, Comparable<? extends Serializable>> getResourceProperties();
/**
* Set all resource-specific properties, replacing existing ones
*/
public void setResourceProperties(Map<String, Comparable<? extends Serializable>> resourceSpecificProperties) throws InvalidValueException;
/**
* Return the value of the given resource property.
* @param key the key of the requested property
* @return the value of the given resource property
*/
public Comparable<? extends Serializable> getResourceProperty(String key);
/**
* Set the value of the given resource property.
* If the key has the value of one of the predefined property, the value
* is validated.
* @param key the key of the requested property
* @param value the value of the given resource property
*/
public void setResourceProperty(String key, Comparable<? extends Serializable> value) throws InvalidValueException;
/**
* @return the Operation Result of the accounted operation.
*/
public OperationResult getOperationResult();
/**
* Set the Operation Result related to the accounted Usage Record
* @param operationResult the Operation Result to set
* @throws InvalidValueException
*/
public void setOperationResult(OperationResult operationResult) throws InvalidValueException;
/**
* Validate the Resource Record.
* The validation check if all the Required Field are set and has valid
* value.
* @throws InvalidValueException
*/
public void validate() throws InvalidValueException;
}

View File

@ -1,7 +1,7 @@
/**
*
*/
package org.gcube.accounting.aggregation;
package org.gcube.accounting.datamodel.aggregation;
import java.io.Serializable;
import java.util.Calendar;
@ -10,7 +10,8 @@ import java.util.Map;
import org.gcube.accounting.datamodel.AggregatedUsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractJobUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.JobUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.exception.NotAggregatableRecordsExceptions;
/**
* This Class is for library internal use only
@ -23,20 +24,19 @@ public class AggregatedJobUsageRecord extends AbstractJobUsageRecord implements
*/
private static final long serialVersionUID = -3376423316219914682L;
private void init(){
this.resourceProperties.put(AGGREGATED, true);
}
public AggregatedJobUsageRecord(){
super();
init();
}
public AggregatedJobUsageRecord(Map<String, Comparable<? extends Serializable>> properties) throws InvalidValueException{
super(properties);
init();
}
// TODO
public AggregatedJobUsageRecord(JobUsageRecord jobUsageRecord) throws InvalidValueException{
throw new UnsupportedOperationException();
}
@Override
public int getOperationCount() {
return super.getOperationCount();
@ -47,16 +47,6 @@ public class AggregatedJobUsageRecord extends AbstractJobUsageRecord implements
super.setOperationCount(operationCount);
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedJobUsageRecord getAggregatedUsageRecord(JobUsageRecord b)
throws InvalidValueException {
// TODO Auto-generated method stub
return null;
}
/**
* {@inheritDoc}
*/
@ -89,5 +79,32 @@ public class AggregatedJobUsageRecord extends AbstractJobUsageRecord implements
super.setEndTime(endTime);
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedJobUsageRecord aggregate(AggregatedJobUsageRecord record)
throws NotAggregatableRecordsExceptions {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedJobUsageRecord aggregate(JobUsageRecord record)
throws NotAggregatableRecordsExceptions {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
@Override
public Class<JobUsageRecord> getAggregable() {
return JobUsageRecord.class;
}
}

View File

@ -1,7 +1,7 @@
/**
*
*/
package org.gcube.accounting.aggregation;
package org.gcube.accounting.datamodel.aggregation;
import java.io.Serializable;
import java.util.Calendar;
@ -10,7 +10,8 @@ import java.util.Map;
import org.gcube.accounting.datamodel.AggregatedUsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractPortletUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.PortletUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.exception.NotAggregatableRecordsExceptions;
/**
* This Class is for library internal use only
@ -23,19 +24,18 @@ public class AggregatedPortletUsageRecord extends AbstractPortletUsageRecord imp
* Generated Serial version UID
*/
private static final long serialVersionUID = 7445526162102677455L;
private void init(){
this.resourceProperties.put(AGGREGATED, true);
}
public AggregatedPortletUsageRecord(){
super();
init();
}
public AggregatedPortletUsageRecord(Map<String, Comparable<? extends Serializable>> properties) throws InvalidValueException{
super(properties);
init();
}
// TODO
public AggregatedPortletUsageRecord(PortletUsageRecord portletUsageRecord) throws InvalidValueException {
throw new UnsupportedOperationException();
}
@Override
@ -48,16 +48,6 @@ public class AggregatedPortletUsageRecord extends AbstractPortletUsageRecord imp
super.setOperationCount(operationCount);
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedPortletUsageRecord getAggregatedUsageRecord(PortletUsageRecord usageRecord)
throws InvalidValueException {
// TODO Auto-generated method stub
return null;
}
/**
* {@inheritDoc}
*/
@ -90,4 +80,33 @@ public class AggregatedPortletUsageRecord extends AbstractPortletUsageRecord imp
super.setEndTime(endTime);
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedPortletUsageRecord aggregate(
AggregatedPortletUsageRecord record)
throws NotAggregatableRecordsExceptions {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedPortletUsageRecord aggregate(PortletUsageRecord record)
throws NotAggregatableRecordsExceptions {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
@Override
public Class<PortletUsageRecord> getAggregable() {
return PortletUsageRecord.class;
}
}

View File

@ -1,7 +1,7 @@
/**
*
*/
package org.gcube.accounting.aggregation;
package org.gcube.accounting.datamodel.aggregation;
import java.io.Serializable;
import java.util.Calendar;
@ -13,7 +13,8 @@ import org.gcube.accounting.datamodel.decorators.AggregatedField;
import org.gcube.accounting.datamodel.decorators.RequiredField;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.accounting.datamodel.validations.annotations.ValidLong;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.exception.NotAggregatableRecordsExceptions;
/**
* This Class is for library internal use only
@ -28,28 +29,22 @@ public class AggregatedServiceUsageRecord extends AbstractServiceUsageRecord imp
// Redefining DURATION to Set @AggregatedField
@RequiredField @ValidLong @AggregatedField
public static final String DURATION = org.gcube.accounting.datamodel.basetypes.AbstractServiceUsageRecord.DURATION;
public static final String DURATION = AbstractServiceUsageRecord.DURATION;
@RequiredField @ValidLong @AggregatedField
public static final String MAX_INVOCATION_TIME = "maxInvocationTime";
@RequiredField @ValidLong @AggregatedField
public static final String MIN_INVOCATION_TIME = "minInvocationTime";
private void init(){
this.resourceProperties.put(AGGREGATED, true);
}
public AggregatedServiceUsageRecord(){
super();
init();
}
public AggregatedServiceUsageRecord(Map<String, Comparable<? extends Serializable>> properties) throws InvalidValueException{
super(properties);
init();
}
public AggregatedServiceUsageRecord(org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord record) throws InvalidValueException{
public AggregatedServiceUsageRecord(ServiceUsageRecord record) throws InvalidValueException{
super(record.getResourceProperties());
this.setOperationCount(1);
long duration = record.getDuration();
@ -59,7 +54,6 @@ public class AggregatedServiceUsageRecord extends AbstractServiceUsageRecord imp
this.setCreationTime(Calendar.getInstance());
this.setStartTime(creationTime);
this.setEndTime(creationTime);
init();
}
@Override
@ -88,15 +82,6 @@ public class AggregatedServiceUsageRecord extends AbstractServiceUsageRecord imp
setResourceProperty(MIN_INVOCATION_TIME, minInvocationTime);
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedServiceUsageRecord getAggregatedUsageRecord(ServiceUsageRecord usageRecord)
throws InvalidValueException {
return new AggregatedServiceUsageRecord(usageRecord);
}
/**
* {@inheritDoc}
*/
@ -129,4 +114,59 @@ public class AggregatedServiceUsageRecord extends AbstractServiceUsageRecord imp
super.setEndTime(endTime);
}
protected long durationWeightedAverage(AggregatedServiceUsageRecord record){
long thisDuration = this.getDuration() * this.getOperationCount();
long recordDuration = record.getDuration() * record.getOperationCount();
long totalOperationCount = this.getOperationCount() + record.getOperationCount();
return (thisDuration + recordDuration) / totalOperationCount;
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedServiceUsageRecord aggregate(AggregatedServiceUsageRecord record)
throws NotAggregatableRecordsExceptions {
try {
setDuration(durationWeightedAverage(record));
setOperationCount(this.getOperationCount() + record.getOperationCount());
long max = record.getMaxInvocationTime();
if(max > this.getMaxInvocationTime()){
this.setMaxInvocationTime(max);
}
long min = record.getMinInvocationTime();
if(min < this.getMinInvocationTime()){
this.setMinInvocationTime(min);
}
}catch(Exception e){
throw new UnsupportedOperationException(e);
}
return this;
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedServiceUsageRecord aggregate(ServiceUsageRecord record)
throws NotAggregatableRecordsExceptions {
try {
return aggregate(new AggregatedServiceUsageRecord(record));
} catch (InvalidValueException e) {
throw new NotAggregatableRecordsExceptions(e.getCause());
}
}
/**
* {@inheritDoc}
*/
@Override
public Class<ServiceUsageRecord> getAggregable() {
return ServiceUsageRecord.class;
}
}

View File

@ -1,7 +1,7 @@
/**
*
*/
package org.gcube.accounting.aggregation;
package org.gcube.accounting.datamodel.aggregation;
import java.io.Serializable;
import java.util.Calendar;
@ -13,7 +13,8 @@ import org.gcube.accounting.datamodel.decorators.AggregatedField;
import org.gcube.accounting.datamodel.decorators.RequiredField;
import org.gcube.accounting.datamodel.usagerecords.StorageUsageRecord;
import org.gcube.accounting.datamodel.validations.annotations.ValidLong;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.exception.NotAggregatableRecordsExceptions;
/**
* This Class is for library internal use only
@ -28,31 +29,24 @@ public class AggregatedStorageUsageRecord extends AbstractStorageUsageRecord imp
// Redefining DATA_VOLUME to Set @AggregatedField
@RequiredField @ValidLong @AggregatedField
public static final String DATA_VOLUME = org.gcube.accounting.datamodel.basetypes.AbstractStorageUsageRecord.DATA_VOLUME;
private void init(){
this.resourceProperties.put(AGGREGATED, true);
}
public static final String DATA_VOLUME = AbstractStorageUsageRecord.DATA_VOLUME;
public AggregatedStorageUsageRecord() {
super();
init();
}
public AggregatedStorageUsageRecord(Map<String, Comparable<? extends Serializable>> properties) throws InvalidValueException{
super(properties);
init();
}
public AggregatedStorageUsageRecord(org.gcube.accounting.datamodel.usagerecords.StorageUsageRecord record) throws InvalidValueException{
public AggregatedStorageUsageRecord(StorageUsageRecord record) throws InvalidValueException{
super(record.getResourceProperties());
this.setOperationCount(1);
Calendar creationTime = record.getCreationTime();
this.setCreationTime(Calendar.getInstance());
this.setStartTime(creationTime);
this.setEndTime(creationTime);
init();
}
@Override
@ -65,15 +59,6 @@ public class AggregatedStorageUsageRecord extends AbstractStorageUsageRecord imp
super.setOperationCount(operationCount);
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedStorageUsageRecord getAggregatedUsageRecord(StorageUsageRecord usageRecord)
throws InvalidValueException {
return new AggregatedStorageUsageRecord(usageRecord);
}
/**
* {@inheritDoc}
*/
@ -105,5 +90,43 @@ public class AggregatedStorageUsageRecord extends AbstractStorageUsageRecord imp
public void setEndTime(Calendar endTime) throws InvalidValueException {
super.setEndTime(endTime);
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedStorageUsageRecord aggregate(
AggregatedStorageUsageRecord record)
throws NotAggregatableRecordsExceptions {
try {
this.setOperationCount(this.getOperationCount() + record.getOperationCount());
this.setDataVolume(this.getDataVolume() + record.getDataVolume());
}catch(Exception e){
throw new UnsupportedOperationException(e);
}
return this;
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedStorageUsageRecord aggregate(StorageUsageRecord record)
throws NotAggregatableRecordsExceptions {
try {
return aggregate(new AggregatedStorageUsageRecord(record));
} catch (InvalidValueException e) {
throw new NotAggregatableRecordsExceptions(e.getCause());
}
}
/**
* {@inheritDoc}
*/
@Override
public Class<StorageUsageRecord> getAggregable() {
return StorageUsageRecord.class;
}
}

View File

@ -1,7 +1,7 @@
/**
*
*/
package org.gcube.accounting.aggregation;
package org.gcube.accounting.datamodel.aggregation;
import java.io.Serializable;
import java.util.Calendar;
@ -10,7 +10,8 @@ import java.util.Map;
import org.gcube.accounting.datamodel.AggregatedUsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractTaskUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.TaskUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.exception.NotAggregatableRecordsExceptions;
/**
* This Class is for library internal use only
@ -23,19 +24,13 @@ public class AggregatedTaskUsageRecord extends AbstractTaskUsageRecord implement
* Generated Serial version UID
*/
private static final long serialVersionUID = 7445526162102677455L;
private void init(){
this.resourceProperties.put(AGGREGATED, true);
}
public AggregatedTaskUsageRecord(){
super();
init();
}
public AggregatedTaskUsageRecord(Map<String, Comparable<? extends Serializable>> properties) throws InvalidValueException{
super(properties);
init();
}
@Override
@ -48,16 +43,6 @@ public class AggregatedTaskUsageRecord extends AbstractTaskUsageRecord implement
super.setOperationCount(operationCount);
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedTaskUsageRecord getAggregatedUsageRecord(TaskUsageRecord usageRecord)
throws InvalidValueException {
// TODO Auto-generated method stub
return null;
}
/**
* {@inheritDoc}
*/
@ -90,4 +75,31 @@ public class AggregatedTaskUsageRecord extends AbstractTaskUsageRecord implement
super.setEndTime(endTime);
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedTaskUsageRecord aggregate(AggregatedTaskUsageRecord record)
throws NotAggregatableRecordsExceptions {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
@Override
public AggregatedTaskUsageRecord aggregate(TaskUsageRecord record)
throws NotAggregatableRecordsExceptions {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
@Override
public Class<TaskUsageRecord> getAggregable() {
return TaskUsageRecord.class;
}
}

View File

@ -0,0 +1,16 @@
/**
*
*/
package org.gcube.accounting.datamodel.backwardcompatibility;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.gcube.accounting.datamodel.decorators.FieldDecorator;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@FieldDecorator(managed=MoveToConsumerIdAction.class)
public @interface MoveToConsumerId { }

View File

@ -0,0 +1,21 @@
/**
*
*/
package org.gcube.accounting.datamodel.backwardcompatibility;
import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.datamodel.validations.validators.NotEmptyIfNotNullValidator;
import org.gcube.documentstore.exception.InvalidValueException;
public class MoveToConsumerIdAction implements FieldAction {
@Override
public Comparable<? extends Serializable> validate(String key, Comparable<? extends Serializable> value, UsageRecord usageRecord) throws InvalidValueException {
NotEmptyIfNotNullValidator neinnv = new NotEmptyIfNotNullValidator();
value = neinnv.validate(key, value, usageRecord);
usageRecord.setConsumerId((String) value);
return value;
}
}

View File

@ -9,7 +9,7 @@ import java.util.Date;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class MoveToCreationTimeAction implements FieldAction {
@Override

View File

@ -9,7 +9,7 @@ import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.UsageRecord.OperationResult;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.datamodel.validations.validators.ValidOperationResultValidator;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/

View File

@ -7,7 +7,7 @@ import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class MoveToScopeAction implements FieldAction {
@Override

View File

@ -8,7 +8,7 @@ import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractTaskUsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/

View File

@ -8,7 +8,7 @@ import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractTaskUsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/

View File

@ -8,7 +8,7 @@ import java.io.Serializable;
import org.gcube.accounting.datamodel.RawUsageRecord;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
@SuppressWarnings("deprecation")
public class MoveToUsageRecordTypeAction implements FieldAction {

View File

@ -14,7 +14,8 @@ import org.gcube.accounting.datamodel.decorators.RequiredField;
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.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.records.AggregatedRecord;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
@ -22,8 +23,6 @@ import org.gcube.accounting.exception.InvalidValueException;
*/
public abstract class AbstractJobUsageRecord extends BasicUsageRecord {
//private static final Logger logger = LoggerFactory.getLogger(AbstractJobUsageRecord.class);
/**
* Generated Serial Version UID
*/
@ -113,19 +112,7 @@ public abstract class AbstractJobUsageRecord extends BasicUsageRecord {
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);
}
@ -142,7 +129,7 @@ public abstract class AbstractJobUsageRecord extends BasicUsageRecord {
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);
AggregatedRecord.START_TIME, AggregatedRecord.END_TIME), e);
}
}

View File

@ -4,22 +4,15 @@
package org.gcube.accounting.datamodel.basetypes;
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.Map;
import org.gcube.accounting.datamodel.BasicUsageRecord;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.datamodel.decorators.FieldDecorator;
import org.gcube.accounting.datamodel.backwardcompatibility.MoveToConsumerId;
import org.gcube.accounting.datamodel.decorators.RequiredField;
import org.gcube.accounting.datamodel.deprecationmanagement.DeprecatedWarning;
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.gcube.documentstore.exception.InvalidValueException;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
@ -34,20 +27,6 @@ public abstract class AbstractPortletUsageRecord extends BasicUsageRecord {
@DeprecatedWarning @MoveToConsumerId
protected static final String USER_ID = "userId";
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@FieldDecorator(managed=MoveToConsumerIdAction.class)
protected @interface MoveToConsumerId { }
protected class MoveToConsumerIdAction implements FieldAction {
@Override
public Comparable<? extends Serializable> validate(String key, Comparable<? extends Serializable> value, UsageRecord usageRecord) throws InvalidValueException {
NotEmptyIfNotNullValidator neinnv = new NotEmptyIfNotNullValidator();
value = neinnv.validate(key, value, usageRecord);
usageRecord.setConsumerId((String) value);
return value;
}
}
@RequiredField @NotEmpty
public static final String PORTLET_ID = "portletId";
@RequiredField @NotEmpty
@ -73,28 +52,6 @@ public abstract class AbstractPortletUsageRecord extends BasicUsageRecord {
return AbstractPortletUsageRecord.class.getSimpleName().replace(ABSTRACT_TO_REPLACE, "");
}
/* *
* Use {@link #getConsumerId()} instead
* @return the Consumer ID
* /
@Deprecated
public String getUserId() {
return (String) this.resourceProperties.get(CONSUMER_ID);
}
/**
* If correct,ly set is a duplicated for Consumer Id, use
* {@link #setConsumerId()} instead.
* @param userId Consumer Id
* @throws InvalidValueException if fails
* /
@Deprecated
public void setUserId(String userId) throws InvalidValueException {
setResourceProperty(USER_ID, userId);
}
*/
public String getPortletId() {
return (String) this.resourceProperties.get(PORTLET_ID);
}

View File

@ -10,7 +10,7 @@ import org.gcube.accounting.datamodel.BasicUsageRecord;
import org.gcube.accounting.datamodel.decorators.RequiredField;
import org.gcube.accounting.datamodel.validations.annotations.NotEmpty;
import org.gcube.accounting.datamodel.validations.annotations.ValidLong;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/

View File

@ -16,7 +16,7 @@ import org.gcube.accounting.datamodel.validations.annotations.ValidDataType;
import org.gcube.accounting.datamodel.validations.annotations.ValidLong;
import org.gcube.accounting.datamodel.validations.annotations.ValidOperationType;
import org.gcube.accounting.datamodel.validations.annotations.ValidURI;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
@ -48,24 +48,6 @@ public abstract class AbstractStorageUsageRecord extends BasicUsageRecord {
@RequiredField @NotEmpty
public static final String RESOURCE_SCOPE = "resourceScope";
/*
@DeprecatedWarning @MoveToResourceURI
protected static final String OBJECT_URI = "objectURI";
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@FieldDecorator(managed=MoveToResourceURIAction.class)
protected @interface MoveToResourceURI { }
protected class MoveToResourceURIAction implements FieldAction {
@Override
public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException {
ValidURIValidator neinnv = new ValidURIValidator();
value = neinnv.validate(key, value, usageRecord);
((StorageUsageRecord) usageRecord).setResourceURI((URI) value);
return value;
}
}
*/
/**
* KEY for : The URI of the Stored Resource
*/

View File

@ -16,7 +16,7 @@ import org.gcube.accounting.datamodel.deprecationmanagement.DeprecatedWarning;
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.gcube.documentstore.exception.InvalidValueException;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
@ -118,15 +118,6 @@ public abstract class AbstractTaskUsageRecord extends BasicUsageRecord {
setResourceProperty(REF_VM, refVM);
}
/*
private String getDomain() {
return (String) this.resourceSpecificProperties.get(DOMAIN);
}
private void setDomain(String domain) throws InvalidValueException {
setResourceProperty(DOMAIN, domain);
}
*/
@Deprecated
public Calendar getUsageStartTime() {
long millis = (Long) this.resourceProperties.get(USAGE_START_TIME);

View File

@ -7,7 +7,7 @@ import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -12,7 +12,7 @@ import org.gcube.accounting.datamodel.UsageRecord.OperationResult;
import org.gcube.accounting.datamodel.usagerecords.JobUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.StorageUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -6,7 +6,7 @@ package org.gcube.accounting.datamodel.decorators;
import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/

View File

@ -7,7 +7,7 @@ import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -3,11 +3,10 @@ package org.gcube.accounting.datamodel.usagerecords;
import java.io.Serializable;
import java.util.Map;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractJobUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class JobUsageRecord extends AbstractJobUsageRecord implements SingleUsageRecord {
public class JobUsageRecord extends AbstractJobUsageRecord {
/**
* Generated Serial Version UID

View File

@ -3,11 +3,10 @@ package org.gcube.accounting.datamodel.usagerecords;
import java.io.Serializable;
import java.util.Map;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractPortletUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class PortletUsageRecord extends AbstractPortletUsageRecord implements SingleUsageRecord {
public class PortletUsageRecord extends AbstractPortletUsageRecord {
/**
* Generated Serial Version UID

View File

@ -3,11 +3,10 @@ package org.gcube.accounting.datamodel.usagerecords;
import java.io.Serializable;
import java.util.Map;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractServiceUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class ServiceUsageRecord extends AbstractServiceUsageRecord implements SingleUsageRecord {
public class ServiceUsageRecord extends AbstractServiceUsageRecord {
/**
* Generated Serial Version UID

View File

@ -3,11 +3,10 @@ package org.gcube.accounting.datamodel.usagerecords;
import java.io.Serializable;
import java.util.Map;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractStorageUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class StorageUsageRecord extends AbstractStorageUsageRecord implements SingleUsageRecord {
public class StorageUsageRecord extends AbstractStorageUsageRecord {
/**
* Generated Serial Version UID

View File

@ -3,11 +3,10 @@ package org.gcube.accounting.datamodel.usagerecords;
import java.io.Serializable;
import java.util.Map;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractTaskUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class TaskUsageRecord extends AbstractTaskUsageRecord implements SingleUsageRecord {
public class TaskUsageRecord extends AbstractTaskUsageRecord {
/**
* Generated Serial Version UID

View File

@ -9,7 +9,7 @@ import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractStorageUsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractStorageUsageRecord.OperationType;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/

View File

@ -5,7 +5,7 @@ import java.util.Map;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class NotEmptyValidator implements FieldAction{

View File

@ -4,7 +4,7 @@ import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class NotNullValidator implements FieldAction {

View File

@ -5,7 +5,7 @@ import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractStorageUsageRecord.DataType;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class ValidDataTypeValidator implements FieldAction {

View File

@ -6,7 +6,7 @@ import java.util.regex.Pattern;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -4,7 +4,7 @@ import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class ValidIntegerValidator implements FieldAction {

View File

@ -4,7 +4,7 @@ import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class ValidLongValidator implements FieldAction {

View File

@ -5,7 +5,7 @@ import java.io.Serializable;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.UsageRecord.OperationResult;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class ValidOperationResultValidator implements FieldAction {

View File

@ -6,7 +6,7 @@ import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.UsageRecord.OperationResult;
import org.gcube.accounting.datamodel.basetypes.AbstractStorageUsageRecord.OperationType;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class ValidOperationTypeValidator implements FieldAction {

View File

@ -5,7 +5,7 @@ import java.net.URI;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
public class ValidURIValidator implements FieldAction {

View File

@ -1,26 +0,0 @@
package org.gcube.accounting.exception;
public class InvalidValueException extends Exception {
/**
* Generated serial Version UID
*/
private static final long serialVersionUID = 4403699127526286772L;
public InvalidValueException() {
super();
}
public InvalidValueException(String message) {
super(message);
}
public InvalidValueException(Throwable cause) {
super(cause);
}
public InvalidValueException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -1,32 +0,0 @@
/**
*
*/
package org.gcube.accounting.exception;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class NotAggregatableRecordsExceptions extends Exception {
/**
* Generated serial Version UID
*/
private static final long serialVersionUID = -1477792189431118048L;
public NotAggregatableRecordsExceptions() {
super();
}
public NotAggregatableRecordsExceptions(String message) {
super(message);
}
public NotAggregatableRecordsExceptions(Throwable cause) {
super(cause);
}
public NotAggregatableRecordsExceptions(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -1,40 +0,0 @@
package org.gcube.accounting.messaging;
@Deprecated
public class QueueCouple {
private String broker;
private String scope;
@Deprecated
public QueueCouple(String broker, String scope) {
super();
this.broker = broker;
this.scope = scope;
}
@Deprecated
public String getBroker() {
return broker;
}
@Deprecated
public void setBroker(String broker) {
this.broker = broker;
}
@Deprecated
public String getScope() {
return scope;
}
@Deprecated
public void setScope(String scope) {
this.scope = scope;
}
}

View File

@ -1,39 +0,0 @@
package org.gcube.accounting.messaging;
import org.gcube.accounting.datamodel.RawUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.persistence.AccountingPersistence;
import org.gcube.accounting.persistence.AccountingPersistenceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class has been created for backward compatibility.
* Use {@link #Persistence} class instead
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*/
@Deprecated
public class ResourceAccounting {
private static final Logger logger = LoggerFactory.getLogger(ResourceAccounting.class);
@Deprecated
protected AccountingPersistence persistence;
@Deprecated
public ResourceAccounting() {
persistence = AccountingPersistenceFactory.getPersistence();
}
@Deprecated
public void sendAccountingMessage(RawUsageRecord message){
try {
persistence.account(message);
} catch (InvalidValueException e) {
logger.error("The Record you are going to account is not valid", e);
}
}
}

View File

@ -1,20 +0,0 @@
package org.gcube.accounting.messaging;
/**
* This class has been created for backward compatibility.
* Use {@link #Persistence} class instead
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*/
@Deprecated
public class ResourceAccountingFactory {
private static ResourceAccounting resourceAccounting = null;
@Deprecated
public static ResourceAccounting getResourceAccountingInstance() throws Exception {
if (resourceAccounting == null){
resourceAccounting= new ResourceAccounting();
}
return resourceAccounting;
}
}

View File

@ -5,8 +5,10 @@ package org.gcube.accounting.persistence;
import java.util.concurrent.TimeUnit;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.persistence.PersistenceBackendFactory;
import org.gcube.documentstore.records.Record;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
@ -32,19 +34,30 @@ public class AccountingPersistence {
* So that the program can continue the execution.
* If the persistence fails the class write that the record in a local file
* so that the {@link #UsageRecord} can be recorder later.
* @param usageRecord the {@link #UsageRecord} to persist
* @throws InvalidValueException if the Record Validation Fails
* @param record the {@link #UsageRecord} to persist
* @throws InvalidValueException
*/
public void account(final SingleUsageRecord usageRecord) throws InvalidValueException{
AccountingPersistenceBackendFactory.getPersistenceBackend().account(usageRecord);
public void account(final Record record) throws InvalidValueException {
String scope = ScopeProvider.instance.get();
try {
PersistenceBackendFactory.getPersistenceBackend(scope).account(record);
} catch (org.gcube.documentstore.exception.InvalidValueException e) {
throw new InvalidValueException(e);
}
}
public void flushAll(long timeout, TimeUnit timeUnit) throws Exception {
PersistenceBackendFactory.flushAll(timeout, timeUnit);
}
public void flush(long timeout, TimeUnit timeUnit) throws Exception {
AccountingPersistenceBackendFactory.flushAll(timeout, timeUnit);
String scope = ScopeProvider.instance.get();
PersistenceBackendFactory.flush(scope, timeout, timeUnit);
}
public void close() throws Exception{
AccountingPersistenceBackendFactory.getPersistenceBackend().close();
String scope = ScopeProvider.instance.get();
PersistenceBackendFactory.getPersistenceBackend(scope).close();
}
}

View File

@ -1,181 +0,0 @@
/**
*
*/
package org.gcube.accounting.persistence;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.gcube.accounting.aggregation.scheduler.AggregationScheduler;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*/
public abstract class AccountingPersistenceBackend {
private static final Logger logger = LoggerFactory.getLogger(AccountingPersistenceBackend.class);
protected FallbackPersistenceBackend fallbackPersistence;
protected AggregationScheduler aggregationScheduler;
protected AccountingPersistenceBackendMonitor accountingPersistenceBackendMonitor;
/**
* Pool for thread execution
*/
private ExecutorService pool;
protected AccountingPersistenceBackend(){
this.pool = Executors.newCachedThreadPool();
if(!(this instanceof FallbackPersistenceBackend)){
this.accountingPersistenceBackendMonitor = new AccountingPersistenceBackendMonitor(this);
}
}
protected AccountingPersistenceBackend(FallbackPersistenceBackend fallback, AggregationScheduler aggregationScheduler){
this();
this.fallbackPersistence = fallback;
this.aggregationScheduler = aggregationScheduler;
}
/**
* @return the fallbackPersistence
*/
public FallbackPersistenceBackend getFallbackPersistence() {
return fallbackPersistence;
}
/**
* @param fallback the fallback to set
*/
protected void setFallback(FallbackPersistenceBackend fallback) {
this.fallbackPersistence = fallback;
}
/**
* @return the aggregationScheduler
*/
public AggregationScheduler getAggregationScheduler() {
return aggregationScheduler;
}
/**
* @param aggregationScheduler the aggregationScheduler to set
*/
protected void setAggregationScheduler(AggregationScheduler aggregationScheduler) {
this.aggregationScheduler = aggregationScheduler;
}
/**
* Prepare the connection to persistence.
* This method must be used by implementation class to open
* the connection with the persistence storage, DB, file etc.
* @param configuration The configuration to create the connection
* @throws Exception if fails
*/
protected abstract void prepareConnection(AccountingPersistenceConfiguration configuration) throws Exception;
/**
* This method contains the code to save the {@link #UsageRecord}
*
*/
protected abstract void reallyAccount(UsageRecord usageRecords) throws Exception;
protected void accountWithFallback(UsageRecord... usageRecords) {
String persistenceName = this.getClass().getSimpleName();
logger.trace("Going to account {} using {} : {}", Arrays.toString(usageRecords), persistenceName, this);
for(UsageRecord usageRecord : usageRecords){
try {
logger.trace("Going to account {} using {} : {}", usageRecord, persistenceName, this);
this.reallyAccount(usageRecord);
logger.debug("{} accounted succesfully from {}.", usageRecord.toString(), persistenceName);
} catch (Exception e) {
try {
String fallabackPersistenceName = FallbackPersistenceBackend.class.getSimpleName();
logger.error("{} was not accounted succesfully from {}. Trying to use {}.",
usageRecord.toString(), persistenceName, fallabackPersistenceName, e);
fallbackPersistence.reallyAccount(usageRecord);
logger.debug("{} accounted succesfully from {}",
usageRecord.toString(), fallabackPersistenceName);
}catch(Exception ex){
logger.error("{} was not accounted at all", usageRecord.toString(), e);
}
}
}
}
protected void validateAccountAggregate(final SingleUsageRecord usageRecord, boolean validate, boolean aggregate){
try {
logger.debug("Received record to account : {}", usageRecord);
if(validate){
usageRecord.validate();
logger.trace("Record {} valid", usageRecord);
}
if(aggregate){
final AccountingPersistenceBackend persistence = this;
aggregationScheduler.aggregate(usageRecord, new AccountingPersistenceExecutor(){
@Override
public void persist(UsageRecord... usageRecords) throws Exception {
persistence.accountWithFallback(usageRecords);
}
});
}else{
this.accountWithFallback(usageRecord);
}
} catch (InvalidValueException e) {
logger.error("Error validating UsageRecord", e);
} catch (Exception e) {
logger.error("Error accounting UsageRecord", e);
}
}
/**
* Persist the {@link #UsageRecord}.
* The Record is validated first, then accounted, in a separated thread.
* So that the program can continue the execution.
* If the persistence fails the class write that the record in a local file
* so that the {@link #UsageRecord} can be recorder later.
* @param usageRecord the {@link #UsageRecord} to persist
* @throws InvalidValueException if the Record Validation Fails
*/
public void account(final SingleUsageRecord usageRecord) throws InvalidValueException{
Runnable runnable = new Runnable(){
@Override
public void run(){
validateAccountAggregate(usageRecord, true, true);
}
};
pool.execute(runnable);
}
public void flush(long timeout, TimeUnit timeUnit) throws Exception {
pool.awaitTermination(timeout, timeUnit);
final AccountingPersistenceBackend persistence = this;
aggregationScheduler.flush(new AccountingPersistenceExecutor(){
@Override
public void persist(UsageRecord... usageRecords) throws Exception {
persistence.accountWithFallback(usageRecords);
}
});
}
public abstract void close() throws Exception;
}

View File

@ -1,230 +0,0 @@
/**
*
*/
package org.gcube.accounting.persistence;
import java.io.File;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.TimeUnit;
import org.gcube.accounting.aggregation.scheduler.AggregationScheduler;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public abstract class AccountingPersistenceBackendFactory {
private static final Logger logger = LoggerFactory.getLogger(AccountingPersistenceBackendFactory.class);
public final static String HOME_SYSTEM_PROPERTY = "user.home";
private static final String ACCOUTING_FALLBACK_FILENAME = "accountingFallback.log";
private static String fallbackLocation;
private static Map<String, AccountingPersistenceBackend> accountingPersistenceBackends;
private static Map<String, Long> fallbackLastCheck;
public static final long FALLBACK_RETRY_TIME = 1000*60*10; // 10 min
/**
* @return the fallbackLastCheck
*/
protected static Long getFallbackLastCheck(String scope) {
return fallbackLastCheck.get(scope);
}
static {
accountingPersistenceBackends = new HashMap<String, AccountingPersistenceBackend>();
fallbackLastCheck = new HashMap<String, Long>();
}
private static File file(File file) throws IllegalArgumentException {
if(!file.isDirectory()){
file = file.getParentFile();
}
// Create folder structure if not exist
if (!file.exists()) {
file.mkdirs();
}
return file;
}
protected synchronized static void setFallbackLocation(String path){
if(fallbackLocation == null){
if(path==null){
path = System.getProperty(HOME_SYSTEM_PROPERTY);
}
file(new File(path));
fallbackLocation = path;
}
}
protected static FallbackPersistenceBackend createFallback(String scope){
logger.debug("Creating {} for scope {}", FallbackPersistenceBackend.class.getSimpleName(), scope);
File fallbackFile = null;
if(scope!=null){
ScopeBean bean = new ScopeBean(scope);
/* if(bean.is(Type.VRE)){ bean = bean.enclosingScope(); } */
String name = bean.name();
fallbackFile = new File(fallbackLocation, String.format("%s.%s", name, ACCOUTING_FALLBACK_FILENAME));
}else{
fallbackFile = new File(fallbackLocation, ACCOUTING_FALLBACK_FILENAME);
}
FallbackPersistenceBackend fallbackPersistence = new FallbackPersistenceBackend(fallbackFile);
fallbackPersistence.setAggregationScheduler(AggregationScheduler.newInstance());
return fallbackPersistence;
}
protected static AccountingPersistenceBackend discoverAccountingPersistenceBackend(String scope){
logger.debug("Discovering {} for scope {}",
AccountingPersistenceBackend.class.getSimpleName(), scope);
ServiceLoader<AccountingPersistenceBackend> serviceLoader = ServiceLoader.load(AccountingPersistenceBackend.class);
for (AccountingPersistenceBackend foundPersistence : serviceLoader) {
try {
String foundPersistenceClassName = foundPersistence.getClass().getSimpleName();
logger.debug("Testing {}", foundPersistenceClassName);
AccountingPersistenceConfiguration configuration = new AccountingPersistenceConfiguration(foundPersistenceClassName);
foundPersistence.prepareConnection(configuration);
/*
* Uncomment the following line of code if you want to try
* to create a test UsageRecord before setting the
* foundPersistence as default
*
* foundPersistence.accountWithFallback(TestUsageRecord.createTestServiceUsageRecord());
*/
logger.debug("{} will be used.", foundPersistenceClassName);
foundPersistence.setAggregationScheduler(AggregationScheduler.newInstance());
foundPersistence.setFallback(createFallback(scope));
return foundPersistence;
} catch (Exception e) {
logger.error(String.format("%s not initialized correctly. It will not be used. Trying the next one if any.", foundPersistence.getClass().getSimpleName()), e);
}
}
return null;
};
protected static AccountingPersistenceBackend rediscoverAccountingPersistenceBackend(AccountingPersistenceBackend actual, String scope){
Long now = Calendar.getInstance().getTimeInMillis();
Long lastCheckTimestamp = fallbackLastCheck.get(scope);
logger.debug("Last check for scope {} was {}", scope, lastCheckTimestamp);
boolean myTurn = false;
synchronized (accountingPersistenceBackends) {
if( (lastCheckTimestamp + FALLBACK_RETRY_TIME) <= now ){
logger.debug("The {} for scope {} is {}. Is time to rediscover if there is another possibility.",
AccountingPersistenceBackend.class.getSimpleName(), scope, actual.getClass().getSimpleName());
logger.trace("Renewing Last check Timestamp. The next one will be {}", now);
fallbackLastCheck.put(scope, now);
myTurn=true;
logger.debug("I win. It is my turn to rediscover {} in scope {}",
AccountingPersistenceBackend.class.getSimpleName(), scope);
}
}
if(myTurn){
AccountingPersistenceBackend discoveredPersistenceBackend = discoverAccountingPersistenceBackend(scope);
synchronized (accountingPersistenceBackends) {
if(discoveredPersistenceBackend!=null){
/*
* Passing the aggregator to the new AccountingPersistenceBackend
* so that the buffered records will be persisted with the
* new method
*
*/
discoveredPersistenceBackend.setAggregationScheduler(actual.getAggregationScheduler());
// Removing timestamp which is no more needed
fallbackLastCheck.remove(scope);
accountingPersistenceBackends.put(scope, discoveredPersistenceBackend);
/*
* Not needed because close has no effect. Removed to
* prevent problem in cases of future changes.
* try {
* actual.close();
* } catch (Exception e) {
* logger.error("Error closing {} for scope {} which has been substituted with {}.",
* actual.getClass().getSimpleName(), scope,
* discoveredPersistenceBackend.getClass().getSimpleName(), e);
* }
*
*/
return discoveredPersistenceBackend;
}
}
}
long nextCheck = (lastCheckTimestamp + FALLBACK_RETRY_TIME) - Calendar.getInstance().getTimeInMillis();
float nextCheckInSec = nextCheck/1000;
logger.debug("The {} for scope {} is going to be used is {}. Next retry in {} msec (about {} sec)",
AccountingPersistenceBackend.class.getSimpleName(), scope,
actual.getClass().getSimpleName(), nextCheck, nextCheckInSec);
return actual;
}
protected static AccountingPersistenceBackend getPersistenceBackend() {
String scope = ScopeProvider.instance.get();
if(scope==null){
logger.error("No Scope available. FallbackPersistence will be used");
return createFallback(null);
}
AccountingPersistenceBackend persistence = null;
logger.debug("Going to synchronized block in getPersistenceBackend");
synchronized (accountingPersistenceBackends) {
persistence = accountingPersistenceBackends.get(scope);
logger.debug("{} {}", AccountingPersistenceBackend.class.getSimpleName(), persistence);
if(persistence==null){
/*
* Setting FallbackPersistence and unlocking.
* This is used to avoid deadlock on IS node which try to use
* itself to query configuration.
*/
persistence = createFallback(scope);
accountingPersistenceBackends.put(scope, persistence);
long now = Calendar.getInstance().getTimeInMillis();
/* The AccountingPersistenceBackend is still to be discovered
* setting the last check advanced in time to force rediscover.
*/
fallbackLastCheck.put(scope, ((now - FALLBACK_RETRY_TIME) - 1));
}
}
if(persistence instanceof FallbackPersistenceBackend){
persistence = rediscoverAccountingPersistenceBackend(persistence, scope);
}
return persistence;
}
/**
* @param timeout
* @param timeUnit
* @throws Exception
*/
public static void flushAll(long timeout, TimeUnit timeUnit) {
for(String scope : accountingPersistenceBackends.keySet()){
AccountingPersistenceBackend apb = accountingPersistenceBackends.get(scope);
try {
logger.debug("Flushing records in scope {}", scope);
apb.flush(timeout, timeUnit);
}catch(Exception e){
logger.error("Unable to flush records in scope {} with {}", scope, apb);
}
}
}
}

View File

@ -1,95 +0,0 @@
/**
*
*/
package org.gcube.accounting.persistence;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.gcube.accounting.datamodel.BasicUsageRecord;
import org.gcube.accounting.datamodel.UsageRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*/
public class AccountingPersistenceBackendMonitor implements Runnable {
private final static Logger logger = LoggerFactory.getLogger(AccountingPersistenceBackendMonitor.class);
private final static String ELABORATION_FILE_SUFFIX = ".ELABORATION";
private final static String ELABORATION_FILE_NOT_DELETED_SUFFIX = ".ELABORATION.NOT-DELETED";
protected final ScheduledExecutorService scheduler;
protected final AccountingPersistenceBackend accountingPersistenceBackend;
public AccountingPersistenceBackendMonitor(AccountingPersistenceBackend accountingPersistenceBackend){
this.accountingPersistenceBackend = accountingPersistenceBackend;
this.scheduler = Executors.newScheduledThreadPool(1);
this.scheduler.scheduleAtFixedRate(this, 10, 10, TimeUnit.MINUTES);
}
protected void elaborateFile(File elaborationFile){
try(BufferedReader br = new BufferedReader(new FileReader(elaborationFile))) {
for(String line; (line = br.readLine()) != null; ) {
try {
UsageRecord usageRecord = BasicUsageRecord.getUsageRecord(line);
accountingPersistenceBackend.accountWithFallback(usageRecord);
} catch(Exception e){
logger.error("Was not possible parse line {} to obtain a valid UsageRecord. Going to writing back this line as string fallback file.", line, e);
FallbackPersistenceBackend fallbackPersistenceBackend = accountingPersistenceBackend.getFallbackPersistence();
try {
fallbackPersistenceBackend.printLine(line);
} catch (Exception e1) {
logger.error("Was not possible Line {} will be lost", line, e1);
}
}
}
} catch (FileNotFoundException e) {
logger.error("", e);
} catch (IOException e) {
logger.error("", e);
}
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
logger.debug("Trying to persist {}s which failed and were persisted using fallback", UsageRecord.class.getSimpleName());
FallbackPersistenceBackend fallbackPersistenceBackend = accountingPersistenceBackend.getFallbackPersistence();
File file = fallbackPersistenceBackend.getAccountingFallbackFile();
File elaborationFile = null;
synchronized (file) {
if(file.exists()){
elaborationFile = new File(file.getAbsolutePath()+ELABORATION_FILE_SUFFIX);
file.renameTo(elaborationFile);
}
}
if(elaborationFile!=null){
synchronized (elaborationFile) {
elaborateFile(elaborationFile);
boolean deleted = elaborationFile.delete();
if(!deleted){
logger.debug("Failed to delete file {}", elaborationFile.getAbsolutePath());
File elaborationFileNotDeleted = new File(elaborationFile.getAbsolutePath()+ELABORATION_FILE_NOT_DELETED_SUFFIX);
elaborationFile.renameTo(elaborationFileNotDeleted);
}
}
}
}
}

View File

@ -3,10 +3,7 @@
*/
package org.gcube.accounting.persistence;
import java.net.URI;
import java.security.Key;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -16,6 +13,8 @@ import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.Property;
import org.gcube.common.resources.gcore.utils.Group;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.persistence.PersistenceBackend;
import org.gcube.documentstore.persistence.PersistenceBackendConfiguration;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
import org.gcube.resources.discovery.icclient.ICFactory;
@ -23,107 +22,37 @@ import org.gcube.resources.discovery.icclient.ICFactory;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*/
public class AccountingPersistenceConfiguration {
public class AccountingPersistenceConfiguration extends PersistenceBackendConfiguration {
protected static final String PERSISTENCE_CLASS_NAME = "persistenceClassName";
protected static final String TARGET_SCOPE = "targetScope";
protected static final String SERVICE_ENDPOINT_CATEGORY = "Accounting";
protected static final String SERVICE_ENDPOINT_NAME = "Persistence";
protected URI uri;
protected String username;
protected String password;
protected Map<String, Property> propertyMap;
protected void init(){
this.propertyMap = new HashMap<String, Property>();
}
public static final String URL_PROPERTY_KEY = "URL";
public static final String USERNAME_PROPERTY_KEY = "username";
public static final String PASSWORD_PROPERTY_KEY = "password";
public AccountingPersistenceConfiguration(){
init();
super();
}
public AccountingPersistenceConfiguration(URI uri, String username, String password){
init();
this.uri = uri;
this.username = username;
this.password = password;
public AccountingPersistenceConfiguration(Class<? extends PersistenceBackend> clz) throws Exception {
super(clz);
ServiceEndpoint serviceEndpoint = getServiceEndpoint(SERVICE_ENDPOINT_CATEGORY, SERVICE_ENDPOINT_NAME, clz);
setValues(serviceEndpoint, clz);
}
public AccountingPersistenceConfiguration(String persistenceClassName) throws Exception {
init();
ServiceEndpoint serviceEndpoint = getServiceEndpoint(SERVICE_ENDPOINT_CATEGORY, SERVICE_ENDPOINT_NAME, persistenceClassName);
setValues(serviceEndpoint,persistenceClassName);
}
/**
* @return the uri
*/
public URI getUri() {
return uri;
}
/**
* @param uri the uri to set
*/
public void setUri(URI uri) {
this.uri = uri;
}
/**
* @return the username
*/
public String getUsername() {
return username;
}
/**
* @param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}
/**
* @return the password
*/
public String getPassword() {
return password;
}
/**
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
public void addProperty(String key, Property property){
propertyMap.put(key, property);
}
/**
* @return the propertyMap
* @throws Exception
*/
public String getProperty(String propertyKey) throws Exception {
Property propertyValue = propertyMap.get(propertyKey);
String value = propertyValue.value();
if(propertyValue.isEncrypted()){
value = decrypt(value);
}
return value;
}
protected ServiceEndpoint getServiceEndpoint(String serviceEndpointCategory, String serviceEndpointName, String persistenceClassName){
protected ServiceEndpoint getServiceEndpoint(String serviceEndpointCategory, String serviceEndpointName, Class<? extends PersistenceBackend> clz){
SimpleQuery query = ICFactory.queryFor(ServiceEndpoint.class);
query.addCondition(String.format("$resource/Profile/Category/text() eq '%s'", serviceEndpointCategory));
query.addCondition(String.format("$resource/Profile/Name/text() eq '%s'", serviceEndpointName));
query.addCondition(String.format("$resource/Profile/AccessPoint/Properties/Property/Name/text() eq '%s'", PERSISTENCE_CLASS_NAME));
query.addCondition(String.format("$resource/Profile/AccessPoint/Properties/Property/Value/text() eq '%s'", persistenceClassName));
query.addCondition(String.format("$resource/Profile/AccessPoint/Interface/Endpoint/@EntryName eq '%s'", clz.getSimpleName()));
/*
* Used in old version
* query.addCondition(String.format("$resource/Profile/AccessPoint/Properties/Property/Name/text() eq '%s'", PERSISTENCE_CLASS_NAME));
* query.addCondition(String.format("$resource/Profile/AccessPoint/Properties/Property/Value/text() eq '%s'", clz.getSimpleName()));
*/
query.setResult("$resource");
DiscoveryClient<ServiceEndpoint> client = ICFactory.clientFor(ServiceEndpoint.class);
@ -141,20 +70,28 @@ public class AccountingPersistenceConfiguration {
return StringEncrypter.getEncrypter().decrypt(encrypted);
}
protected void setValues(ServiceEndpoint serviceEndpoint, String persistenceClassName) throws Exception{
protected void setValues(ServiceEndpoint serviceEndpoint, Class<? extends PersistenceBackend> clz) throws Exception{
Group<AccessPoint> accessPoints = serviceEndpoint.profile().accessPoints();
for(AccessPoint accessPoint : accessPoints){
Collection<Property> properties = accessPoint.propertyMap().values();
if(properties.contains(new ServiceEndpoint.Property().nameAndValue(PERSISTENCE_CLASS_NAME, persistenceClassName))){
this.uri = new URI(accessPoint.address());
this.username = accessPoint.username();
if(accessPoint.name().compareTo(clz.getSimpleName())==0){
addProperty(URL_PROPERTY_KEY, accessPoint.address());
addProperty(USERNAME_PROPERTY_KEY, accessPoint.username());
String encryptedPassword = accessPoint.password();
String password = decrypt(encryptedPassword);
addProperty(PASSWORD_PROPERTY_KEY, password);
Map<String, Property> propertyMap = accessPoint.propertyMap();
for(String key : propertyMap.keySet()){
Property property = propertyMap.get(key);
String value = property.value();
if(property.isEncrypted()){
value = decrypt(value);
}
addProperty(key, value);
}
this.password = password;
this.propertyMap = accessPoint.propertyMap();
}
}
}

View File

@ -1,16 +0,0 @@
/**
*
*/
package org.gcube.accounting.persistence;
import org.gcube.accounting.datamodel.UsageRecord;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public interface AccountingPersistenceExecutor {
public void persist(UsageRecord... usageRecords)throws Exception;
}

View File

@ -3,6 +3,8 @@
*/
package org.gcube.accounting.persistence;
import org.gcube.documentstore.persistence.PersistenceBackendFactory;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
@ -10,7 +12,7 @@ package org.gcube.accounting.persistence;
public class AccountingPersistenceFactory {
public static void setFallbackLocation(String path){
AccountingPersistenceBackendFactory.setFallbackLocation(path);
PersistenceBackendFactory.setFallbackLocation(path);
}
public static AccountingPersistence getPersistence() {

View File

@ -1,75 +0,0 @@
/**
*
*/
package org.gcube.accounting.persistence;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import org.gcube.accounting.aggregation.scheduler.AggregationScheduler;
import org.gcube.accounting.datamodel.UsageRecord;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*/
public class FallbackPersistenceBackend extends AccountingPersistenceBackend {
private File accountingFallbackFile;
/**
* @return the accountingFallbackFile
*/
protected File getAccountingFallbackFile() {
return accountingFallbackFile;
}
protected FallbackPersistenceBackend(File accountingFallbackFile) {
super(null, AggregationScheduler.newInstance());
this.accountingFallbackFile = accountingFallbackFile;
}
/**
* {@inheritDoc}
*/
@Override
public void prepareConnection(AccountingPersistenceConfiguration configuration) {
// Nothing TO DO
}
/**
* {@inheritDoc}
* This method is synchronized on {@link File} used, so any actions which
* has to modify, rename or delete the file must be synchronized on this
* file. To retrieve it use {@link #getAccountingFallbackFile()} method.
* This is intended for internal library usage only so that is protected
*/
@Override
protected void reallyAccount(UsageRecord usageRecord) throws Exception {
printLine(String.valueOf( usageRecord));
}
public void printLine(String line) throws Exception {
synchronized (accountingFallbackFile) {
try(FileWriter fw = new FileWriter(accountingFallbackFile, true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw)){
out.println(line);
out.flush();
} catch( IOException e ){
throw e;
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void close() throws Exception {
// Nothing TO DO
}
}

View File

@ -0,0 +1 @@
org.gcube.accounting.persistence.AccountingPersistenceConfiguration

View File

@ -1,45 +0,0 @@
/**
*
*/
package org.gcube.accounting.aggregation;
import java.util.Set;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class ServiceUsageRecordTest {
private static Logger logger = LoggerFactory.getLogger(ServiceUsageRecordTest.class);
@Test
public void testRequiredFields() throws InvalidValueException {
ServiceUsageRecord serviceUsageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
AggregatedServiceUsageRecord aggregatedServiceUsageRecord = new AggregatedServiceUsageRecord(serviceUsageRecord);
Set<String> expectedRequiredFields = org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecordTest.getExpectedRequiredFields();
expectedRequiredFields.add(AggregatedServiceUsageRecord.DURATION);
expectedRequiredFields.add(AggregatedServiceUsageRecord.MAX_INVOCATION_TIME);
expectedRequiredFields.add(AggregatedServiceUsageRecord.MIN_INVOCATION_TIME);
logger.debug("Expected Required Fields : {}", expectedRequiredFields);
Set<String> gotRequiredFields = aggregatedServiceUsageRecord.getRequiredFields();
logger.debug("Got Required Fields : {}", gotRequiredFields);
Assert.assertTrue(expectedRequiredFields.containsAll(gotRequiredFields));
Assert.assertTrue(gotRequiredFields.containsAll(expectedRequiredFields));
}
}

View File

@ -1,15 +0,0 @@
/**
*
*/
package org.gcube.accounting.datamodel;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class BasicUsageRecordUtility {
public static final String ID = BasicUsageRecord.ID;
public static final String USAGE_RECORD_TYPE = BasicUsageRecord.USAGE_RECORD_TYPE;
}

View File

@ -3,8 +3,10 @@
*/
package org.gcube.accounting.datamodel;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.records.RecordUtility;
import org.junit.Assert;
import org.junit.Test;
@ -25,7 +27,7 @@ public class UsageRecordTest {
@Test
public void testCompareToEqualsObject() throws Exception {
UsageRecord usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
UsageRecord ur = BasicUsageRecord.getUsageRecord(usageRecord.getResourceProperties());
UsageRecord ur = (UsageRecord) RecordUtility.getRecord(usageRecord.getResourceProperties());
Assert.assertEquals(0, usageRecord.compareTo(ur));
Assert.assertEquals(0, ur.compareTo(usageRecord));
}
@ -33,7 +35,7 @@ public class UsageRecordTest {
@Test
public void testCompareToComparedAddedProperty() throws Exception {
UsageRecord usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
UsageRecord ur = BasicUsageRecord.getUsageRecord(usageRecord.getResourceProperties());
UsageRecord ur = (UsageRecord) RecordUtility.getRecord(usageRecord.getResourceProperties());
for(int i=1; i<31; i++){
ur.setResourceProperty(Integer.toString(i), i);
Assert.assertEquals(-i, usageRecord.compareTo(ur));
@ -44,7 +46,7 @@ public class UsageRecordTest {
@Test
public void testCompareToDifferentForAddedProperties() throws Exception {
UsageRecord usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
UsageRecord ur = BasicUsageRecord.getUsageRecord(usageRecord.getResourceProperties());
UsageRecord ur = (UsageRecord) RecordUtility.getRecord(usageRecord.getResourceProperties());
usageRecord.setResourceProperty(Integer.toString(1), 2);
ur.setResourceProperty(Integer.toString(2), 2);
Assert.assertEquals(1, usageRecord.compareTo(ur));

View File

@ -1,15 +1,16 @@
/**
*
*/
package org.gcube.accounting.aggregation.strategy;
package org.gcube.accounting.datamodel.aggregation;
import java.util.Set;
import org.gcube.accounting.aggregation.AggregatedServiceUsageRecord;
import org.gcube.accounting.aggregation.strategy.ServiceUsageRecordAggregationStrategy;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.exception.NotAggregatableRecordsExceptions;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecordTest;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.exception.NotAggregatableRecordsExceptions;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
@ -19,10 +20,32 @@ import org.slf4j.LoggerFactory;
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class ServiceUsageRecordAggregationStrategyTest {
public class AggregatedServiceUsageRecordTest {
private static Logger logger = LoggerFactory.getLogger(ServiceUsageRecordAggregationStrategyTest.class);
private static Logger logger = LoggerFactory.getLogger(AggregatedServiceUsageRecordTest.class);
@Test
public void testRequiredFields() throws InvalidValueException {
ServiceUsageRecord serviceUsageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
AggregatedServiceUsageRecord aggregatedServiceUsageRecord = new AggregatedServiceUsageRecord(serviceUsageRecord);
Set<String> expectedRequiredFields = ServiceUsageRecordTest.getExpectedRequiredFields();
expectedRequiredFields.add(AggregatedServiceUsageRecord.DURATION);
expectedRequiredFields.add(AggregatedServiceUsageRecord.MAX_INVOCATION_TIME);
expectedRequiredFields.add(AggregatedServiceUsageRecord.MIN_INVOCATION_TIME);
logger.debug("Expected Required Fields : {}", expectedRequiredFields);
Set<String> gotRequiredFields = aggregatedServiceUsageRecord.getRequiredFields();
logger.debug("Got Required Fields : {}", gotRequiredFields);
Assert.assertTrue(expectedRequiredFields.containsAll(gotRequiredFields));
Assert.assertTrue(gotRequiredFields.containsAll(expectedRequiredFields));
}
@Test
public void secondAsNotAggregated() throws InvalidValueException, NotAggregatableRecordsExceptions {
@ -39,12 +62,11 @@ public class ServiceUsageRecordAggregationStrategyTest {
ServiceUsageRecord serviceUsageRecord2 = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
serviceUsageRecord2.validate();
logger.debug("ServiceUsageRecord 2 : {}", serviceUsageRecord2);
ServiceUsageRecordAggregationStrategy suras = new ServiceUsageRecordAggregationStrategy(aggregated);
long firstDuration = serviceUsageRecord.getDuration();
long secondDuration = serviceUsageRecord2.getDuration();
suras.aggregate(serviceUsageRecord2);
aggregated.aggregate(serviceUsageRecord2);
logger.debug("Resulting Aggregated ServiceUsageRecord: {}", aggregated);
aggregated.validate();
@ -61,7 +83,7 @@ public class ServiceUsageRecordAggregationStrategyTest {
Assert.assertFalse(aggregated.getResourceProperties().containsKey(TestUsageRecord.TEST_PROPERTY_NAME));
Assert.assertTrue(aggregated.getUsageRecordType().compareTo(ServiceUsageRecord.class.getSimpleName())==0);
Assert.assertTrue(aggregated.getRecordType().compareTo(ServiceUsageRecord.class.getSimpleName())==0);
}
@ -84,12 +106,10 @@ public class ServiceUsageRecordAggregationStrategyTest {
logger.debug("ServiceUsageRecord 2 Converted to Aggregated: {}", converted);
converted.validate();
ServiceUsageRecordAggregationStrategy suras = new ServiceUsageRecordAggregationStrategy(aggregated);
long firstduration = aggregated.getDuration();
long secondDuration = converted.getDuration();
suras.aggregate(converted);
aggregated.aggregate(converted);
logger.debug("Resulting Aggregated ServiceUsageRecord: {}", aggregated);
aggregated.validate();
@ -105,7 +125,7 @@ public class ServiceUsageRecordAggregationStrategyTest {
}
Assert.assertFalse(aggregated.getResourceProperties().containsKey(TestUsageRecord.TEST_PROPERTY_NAME));
Assert.assertTrue(aggregated.getUsageRecordType().compareTo(ServiceUsageRecord.class.getSimpleName())==0);
Assert.assertTrue(aggregated.getRecordType().compareTo(ServiceUsageRecord.class.getSimpleName())==0);
}
protected long durationWeightedAverage(int numberA, long durationA, int numberB, long durationB){
@ -124,8 +144,6 @@ public class ServiceUsageRecordAggregationStrategyTest {
logger.debug("ServiceUsageRecord Converted to Aggregated: {}", aggregated);
aggregated.validate();
ServiceUsageRecordAggregationStrategy suras = new ServiceUsageRecordAggregationStrategy(aggregated);
for(int i=2; i<1002; i++){
ServiceUsageRecord sur = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
@ -138,7 +156,7 @@ public class ServiceUsageRecordAggregationStrategyTest {
long oldDuration = aggregated.getDuration();
long surDuration = sur.getDuration();
suras.aggregate(sur);
aggregated.aggregate(sur);
logger.debug("Resulting Aggregated ServiceUsageRecord: {}", aggregated);
aggregated.validate();
@ -161,7 +179,7 @@ public class ServiceUsageRecordAggregationStrategyTest {
Assert.assertFalse(aggregated.getResourceProperties().containsKey(TestUsageRecord.TEST_PROPERTY_NAME));
}
Assert.assertTrue(aggregated.getUsageRecordType().compareTo(ServiceUsageRecord.class.getSimpleName())==0);
Assert.assertTrue(aggregated.getRecordType().compareTo(ServiceUsageRecord.class.getSimpleName())==0);
logger.debug("Resulting Aggregated ServiceUsageRecord: {}", aggregated);
}

View File

@ -1,14 +1,14 @@
/**
*
*/
package org.gcube.accounting.aggregation.strategy;
package org.gcube.accounting.datamodel.aggregation;
import org.gcube.accounting.aggregation.strategy.StorageUsageRecordAggregationStrategy;
import org.gcube.accounting.datamodel.aggregation.AggregatedStorageUsageRecord;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.StorageUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.exception.NotAggregatableRecordsExceptions;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.exception.NotAggregatableRecordsExceptions;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
@ -18,10 +18,10 @@ import org.slf4j.LoggerFactory;
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class StorageUsageRecordAggregationStrategyTest {
public class AggregatedStorageUsageRecordTest {
private static Logger logger = LoggerFactory.getLogger(StorageUsageRecordAggregationStrategyTest.class);
private static Logger logger = LoggerFactory.getLogger(AggregatedStorageUsageRecordTest.class);
@ -33,20 +33,18 @@ public class StorageUsageRecordAggregationStrategyTest {
storageUsageRecord.validate();
logger.debug("StorageUsageRecord : {}", storageUsageRecord);
org.gcube.accounting.aggregation.AggregatedStorageUsageRecord aggregated =
new org.gcube.accounting.aggregation.AggregatedStorageUsageRecord(storageUsageRecord);
AggregatedStorageUsageRecord aggregated = new AggregatedStorageUsageRecord(storageUsageRecord);
logger.debug("StorageUsageRecord Converted to Aggregated: {}", aggregated);
aggregated.validate();
StorageUsageRecord storageUsageRecord2 = TestUsageRecord.createTestStorageUsageRecordAutomaticScope();
storageUsageRecord2.validate();
logger.debug("StorageUsageRecord 2 : {}", storageUsageRecord2);
StorageUsageRecordAggregationStrategy suras = new StorageUsageRecordAggregationStrategy(aggregated);
long firstDataVolume = storageUsageRecord.getDataVolume();
long secondDataVolume = storageUsageRecord2.getDataVolume();
suras.aggregate(storageUsageRecord2);
aggregated.aggregate(storageUsageRecord2);
logger.debug("Resulting Aggregated ServiceUsageRecord: {}", aggregated);
aggregated.validate();
@ -63,8 +61,7 @@ public class StorageUsageRecordAggregationStrategyTest {
storageUsageRecord.validate();
logger.debug("StorageUsageRecord : {}", storageUsageRecord);
org.gcube.accounting.aggregation.AggregatedStorageUsageRecord aggregated =
new org.gcube.accounting.aggregation.AggregatedStorageUsageRecord(storageUsageRecord);
AggregatedStorageUsageRecord aggregated = new AggregatedStorageUsageRecord(storageUsageRecord);
logger.debug("StorageUsageRecord Converted to Aggregated: {}", aggregated);
aggregated.validate();
@ -72,18 +69,14 @@ public class StorageUsageRecordAggregationStrategyTest {
storageUsageRecord2.setResourceProperty(TestUsageRecord.TEST_PROPERTY_NAME, TestUsageRecord.TEST_PROPERTY_VALUE);
storageUsageRecord2.validate();
logger.debug("StorageUsageRecord 2 : {}", storageUsageRecord2);
org.gcube.accounting.aggregation.AggregatedStorageUsageRecord converted =
new org.gcube.accounting.aggregation.AggregatedStorageUsageRecord(storageUsageRecord2);
AggregatedStorageUsageRecord converted = new AggregatedStorageUsageRecord(storageUsageRecord2);
logger.debug("StorageUsageRecord Converted to Aggregated: {}", converted);
converted.validate();
StorageUsageRecordAggregationStrategy suras = new StorageUsageRecordAggregationStrategy(aggregated);
long firstDataVolume = aggregated.getDataVolume();
long secondDataVolume = converted.getDataVolume();
suras.aggregate(converted);
aggregated.aggregate(converted);
logger.debug("Resulting Aggregated StorageUsageRecord: {}", aggregated);
aggregated.validate();
@ -100,13 +93,10 @@ public class StorageUsageRecordAggregationStrategyTest {
storageUsageRecord.validate();
logger.debug("StorageUsageRecord : {}", storageUsageRecord);
org.gcube.accounting.aggregation.AggregatedStorageUsageRecord aggregated =
new org.gcube.accounting.aggregation.AggregatedStorageUsageRecord(storageUsageRecord);
AggregatedStorageUsageRecord aggregated = new AggregatedStorageUsageRecord(storageUsageRecord);
logger.debug("StorageUsageRecord Converted to Aggregated: {}", aggregated);
aggregated.validate();
StorageUsageRecordAggregationStrategy suras = new StorageUsageRecordAggregationStrategy(aggregated);
for(int i=2; i<1002; i++){
StorageUsageRecord sur = TestUsageRecord.createTestStorageUsageRecordAutomaticScope();
@ -117,7 +107,7 @@ public class StorageUsageRecordAggregationStrategyTest {
long oldDataVolume = aggregated.getDataVolume();
long newDataVolume = sur.getDataVolume();
suras.aggregate(sur);
aggregated.aggregate(sur);
logger.debug("Resulting Aggregated StorageUsageRecord : {}", aggregated);
aggregated.validate();

View File

@ -7,11 +7,13 @@ import java.util.HashSet;
import java.util.Set;
import org.gcube.accounting.datamodel.BasicUsageRecord;
import org.gcube.accounting.datamodel.BasicUsageRecordUtility;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractJobUsageRecord;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.datamodel.usagerecords.JobUsageRecord;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.records.Record;
import org.junit.Assert;
import org.junit.Test;
@ -21,14 +23,16 @@ import org.junit.Test;
*/
public class JobUsageRecordTest {
@SuppressWarnings("deprecation")
public static Set<String> getExpectedRequiredFields(){
Set<String> expectedRequiredFields = new HashSet<String>();
expectedRequiredFields.add(BasicUsageRecordUtility.ID);
expectedRequiredFields.add(BasicUsageRecord.CONSUMER_ID);
expectedRequiredFields.add(BasicUsageRecord.CREATION_TIME);
expectedRequiredFields.add(BasicUsageRecordUtility.USAGE_RECORD_TYPE);
expectedRequiredFields.add(BasicUsageRecord.SCOPE);
expectedRequiredFields.add(BasicUsageRecord.OPERATION_RESULT);
expectedRequiredFields.add(Record.ID);
expectedRequiredFields.add(UsageRecord.CONSUMER_ID);
expectedRequiredFields.add(UsageRecord.CREATION_TIME);
expectedRequiredFields.add(UsageRecord.RECORD_TYPE);
expectedRequiredFields.add(BasicUsageRecord.USAGE_RECORD_TYPE);
expectedRequiredFields.add(UsageRecord.SCOPE);
expectedRequiredFields.add(UsageRecord.OPERATION_RESULT);
expectedRequiredFields.add(AbstractJobUsageRecord.JOB_ID);
expectedRequiredFields.add(AbstractJobUsageRecord.JOB_QUALIFIER);
expectedRequiredFields.add(AbstractJobUsageRecord.JOB_NAME);

View File

@ -7,10 +7,13 @@ import java.util.HashSet;
import java.util.Set;
import org.gcube.accounting.datamodel.BasicUsageRecord;
import org.gcube.accounting.datamodel.BasicUsageRecordUtility;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractServiceUsageRecord;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.records.Record;
import org.junit.Assert;
import org.junit.Test;
@ -20,20 +23,22 @@ import org.junit.Test;
*/
public class ServiceUsageRecordTest {
@SuppressWarnings("deprecation")
public static Set<String> getExpectedRequiredFields(){
Set<String> expectedRequiredFields = new HashSet<String>();
expectedRequiredFields.add(BasicUsageRecordUtility.ID);
expectedRequiredFields.add(BasicUsageRecord.CONSUMER_ID);
expectedRequiredFields.add(BasicUsageRecord.CREATION_TIME);
expectedRequiredFields.add(BasicUsageRecordUtility.USAGE_RECORD_TYPE);
expectedRequiredFields.add(BasicUsageRecord.SCOPE);
expectedRequiredFields.add(BasicUsageRecord.OPERATION_RESULT);
expectedRequiredFields.add(org.gcube.accounting.datamodel.basetypes.AbstractServiceUsageRecord.CALLER_HOST);
expectedRequiredFields.add(org.gcube.accounting.datamodel.basetypes.AbstractServiceUsageRecord.HOST);
expectedRequiredFields.add(org.gcube.accounting.datamodel.basetypes.AbstractServiceUsageRecord.SERVICE_CLASS);
expectedRequiredFields.add(org.gcube.accounting.datamodel.basetypes.AbstractServiceUsageRecord.SERVICE_NAME);
expectedRequiredFields.add(org.gcube.accounting.datamodel.basetypes.AbstractServiceUsageRecord.CALLED_METHOD);
expectedRequiredFields.add(org.gcube.accounting.datamodel.basetypes.AbstractServiceUsageRecord.DURATION);
expectedRequiredFields.add(Record.ID);
expectedRequiredFields.add(UsageRecord.CONSUMER_ID);
expectedRequiredFields.add(UsageRecord.CREATION_TIME);
expectedRequiredFields.add(UsageRecord.RECORD_TYPE);
expectedRequiredFields.add(BasicUsageRecord.USAGE_RECORD_TYPE);
expectedRequiredFields.add(UsageRecord.SCOPE);
expectedRequiredFields.add(UsageRecord.OPERATION_RESULT);
expectedRequiredFields.add(AbstractServiceUsageRecord.CALLER_HOST);
expectedRequiredFields.add(AbstractServiceUsageRecord.HOST);
expectedRequiredFields.add(AbstractServiceUsageRecord.SERVICE_CLASS);
expectedRequiredFields.add(AbstractServiceUsageRecord.SERVICE_NAME);
expectedRequiredFields.add(AbstractServiceUsageRecord.CALLED_METHOD);
expectedRequiredFields.add(AbstractServiceUsageRecord.DURATION);
return expectedRequiredFields;
}

View File

@ -7,10 +7,13 @@ import java.util.HashSet;
import java.util.Set;
import org.gcube.accounting.datamodel.BasicUsageRecord;
import org.gcube.accounting.datamodel.BasicUsageRecordUtility;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.AbstractJobUsageRecord;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.datamodel.usagerecords.JobUsageRecord;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.records.Record;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@ -38,19 +41,21 @@ public class StorageUsageRecordTest {
logger.trace("Scope reset");
}
@SuppressWarnings("deprecation")
public static Set<String> getExpectedRequiredFields(){
Set<String> expectedRequiredFields = new HashSet<String>();
expectedRequiredFields.add(BasicUsageRecordUtility.ID);
expectedRequiredFields.add(BasicUsageRecord.CONSUMER_ID);
expectedRequiredFields.add(BasicUsageRecord.CREATION_TIME);
expectedRequiredFields.add(BasicUsageRecordUtility.USAGE_RECORD_TYPE);
expectedRequiredFields.add(BasicUsageRecord.SCOPE);
expectedRequiredFields.add(BasicUsageRecord.OPERATION_RESULT);
expectedRequiredFields.add(org.gcube.accounting.datamodel.basetypes.AbstractJobUsageRecord.JOB_ID);
expectedRequiredFields.add(org.gcube.accounting.datamodel.basetypes.AbstractJobUsageRecord.JOB_QUALIFIER);
expectedRequiredFields.add(org.gcube.accounting.datamodel.basetypes.AbstractJobUsageRecord.JOB_NAME);
expectedRequiredFields.add(org.gcube.accounting.datamodel.basetypes.AbstractJobUsageRecord.JOB_START_TIME);
expectedRequiredFields.add(org.gcube.accounting.datamodel.basetypes.AbstractJobUsageRecord.JOB_END_TIME);
expectedRequiredFields.add(Record.ID);
expectedRequiredFields.add(UsageRecord.CONSUMER_ID);
expectedRequiredFields.add(UsageRecord.CREATION_TIME);
expectedRequiredFields.add(UsageRecord.RECORD_TYPE);
expectedRequiredFields.add(BasicUsageRecord.USAGE_RECORD_TYPE);
expectedRequiredFields.add(UsageRecord.SCOPE);
expectedRequiredFields.add(UsageRecord.OPERATION_RESULT);
expectedRequiredFields.add(AbstractJobUsageRecord.JOB_ID);
expectedRequiredFields.add(AbstractJobUsageRecord.JOB_QUALIFIER);
expectedRequiredFields.add(AbstractJobUsageRecord.JOB_NAME);
expectedRequiredFields.add(AbstractJobUsageRecord.JOB_START_TIME);
expectedRequiredFields.add(AbstractJobUsageRecord.JOB_END_TIME);
return expectedRequiredFields;
}
@ -66,8 +71,13 @@ public class StorageUsageRecordTest {
JobUsageRecord jobUsageRecord = TestUsageRecord.createTestJobUsageRecordAutomaticScope();
Set<String> expectedRequiredFields = getExpectedRequiredFields();
logger.debug("Expected Required Fields : {}", expectedRequiredFields);
Set<String> gotRequiredFields = jobUsageRecord.getRequiredFields();
logger.debug("Got Required Fields : {}", gotRequiredFields);
Assert.assertTrue(expectedRequiredFields.containsAll(gotRequiredFields));
Assert.assertTrue(gotRequiredFields.containsAll(expectedRequiredFields));

View File

@ -5,7 +5,8 @@ package org.gcube.accounting.datamodel.validations.validators;
import java.io.Serializable;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.datamodel.validations.validators.NotEmptyIfNotNullValidator;
import org.gcube.documentstore.exception.InvalidValueException;
import org.junit.Assert;
import org.junit.Test;

View File

@ -4,7 +4,7 @@
package org.gcube.accounting.datamodel.validations.validators;
import org.gcube.accounting.datamodel.validations.validators.ValidLongValidator;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.documentstore.exception.InvalidValueException;
import org.junit.Test;
/**

View File

@ -18,15 +18,11 @@ import org.gcube.common.resources.gcore.ServiceEndpoint.Runtime;
import org.gcube.common.resources.gcore.common.Platform;
import org.gcube.common.resources.gcore.utils.Group;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.informationsystem.publisher.AdvancedScopedPublisher;
import org.gcube.documentstore.persistence.PersistenceBackend;
import org.gcube.informationsystem.publisher.RegistryPublisherFactory;
import org.gcube.informationsystem.publisher.ScopedPublisher;
import org.gcube.informationsystem.publisher.exception.RegistryNotFoundException;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
import org.gcube.resources.discovery.icclient.ICFactory;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,41 +34,36 @@ public class AccountingPersistenceConfigurationTest {
private static final Logger logger = LoggerFactory.getLogger(AccountingPersistenceConfigurationTest.class);
public static final String PROFILE_DESCRIPTION = "This ServiceEndpoint contains the parameter to connect to DB to persist log accounting.";
public static final String RUNNING_ON = "http://localhost:5984";
private static final String PROFILE_DESCRIPTION = "This ServiceEndpoint contains the parameter to connect to DB to persist log accounting";
private static final String HOSTED_ON = "pc-frosini.isti.cnr.it";
private static final String ENDPOINT = "http://localhost:5984";
public static final String LOAD_BALANCER = "loadBalancer";
private static final String READY = "READY";
public static final String READY = "READY";
private static final String PLATFORM_NAME = "Platform Name";
private static final String TEST_VERSION = "1.0.0";
private static final short[] VERSION_SLICES = new short[]{1,6,0,0};
public static final String TEST_VERSION = "1.0.0";
public static final short[] VERSION_SLICES = new short[]{1,6,0,0};
private static final String DESCRIPTION = "Persistence Configuration Test";
public static final String DESCRIPTION = "CouchDB Server";
public static final String COUCHDB_CLASS_NAME = "AccountingPersistenceCouchDB";
private static final String FAKE_USERNAME = "fakeusername";
private static final String FAKE_PASSWORD = "fakepassword";
public static final String FAKE_USERNAME = "fakeusername";
public static final String FAKE_PASSWORD = "fakepassword";
public static final String[] SCOPES = new String[]{"/gcube", "/gcube/devNext", "/gcube/devsec"};
public static final String GCUBE_SCOPE = SCOPES[0];
public static final String GCUBE_DEVNEXT_SCOPE = SCOPES[1];
public static final String DB_NAME_PROPERTY_NAME = "dbName";
public static final String DB_NAME_PROPERTY_VALUE = "accounting";
private static final String DB_NAME_PROPERTY_KEY = "dbName";
private static final String DB_NAME_PROPERTY_VALUE = "accounting";
private abstract class AccountingPersistenceFakeDB extends PersistenceBackend {
}
public static final String[] ALL_SCOPES = new String[]{
"/gcube",
"/gcube/devsec",
"/gcube/devsec/devVRE",
"/gcube/devsec/VALEN-TINA",
"/gcube/devsec/USTORE_VRE",
"/gcube/devNext",
"/gcube/devNext/NextNext"
};
/**
* Publish the provided resource on all Service Scopes retrieved from
* Context
@ -100,19 +91,11 @@ public class AccountingPersistenceConfigurationTest {
* @throws RegistryNotFoundException if the Registry is not found so the
* resource has not be published
*/
private static void unPublishScopedResource(Resource resource) throws RegistryNotFoundException, Exception {
//StringWriter stringWriter = new StringWriter();
//Resources.marshal(resource, stringWriter);
ScopedPublisher scopedPublisher = RegistryPublisherFactory.scopedPublisher();
AdvancedScopedPublisher advancedScopedPublisher = new AdvancedScopedPublisher(scopedPublisher);
private static void unPublishScopedResource(Resource resource, List<String> scopes) throws RegistryNotFoundException, Exception {
ScopedPublisher scopedPublisher = RegistryPublisherFactory.scopedPublisher();
String id = resource.id();
logger.debug("Trying to remove {} with ID {} from {}", resource.getClass().getSimpleName(), id, ScopeProvider.instance.get());
//scopedPublisher.remove(resource, scopes);
advancedScopedPublisher.forceRemove(resource);
scopedPublisher.remove(resource, scopes);
logger.debug("{} with ID {} removed successfully", resource.getClass().getSimpleName(), id);
}
@ -134,7 +117,7 @@ public class AccountingPersistenceConfigurationTest {
Platform platform = profile.newPlatform();
platform.name(RUNNING_ON);
platform.name(PLATFORM_NAME);
platform.version(VERSION_SLICES[0]);
platform.minorVersion(VERSION_SLICES[1]);
@ -142,7 +125,7 @@ public class AccountingPersistenceConfigurationTest {
platform.revisionVersion(VERSION_SLICES[3]);
Runtime runtime = profile.newRuntime();
runtime.hostedOn(RUNNING_ON);
runtime.hostedOn(HOSTED_ON);
runtime.status(READY);
Group<AccessPoint> accessPoints = profile.accessPoints();
@ -152,17 +135,14 @@ public class AccountingPersistenceConfigurationTest {
accessPointElement.description(DESCRIPTION);
accessPointElement.credentials(FAKE_USERNAME, FAKE_PASSWORD);
accessPointElement.address(RUNNING_ON);
accessPointElement.name(LOAD_BALANCER);
accessPointElement.address(ENDPOINT);
accessPointElement.name(AccountingPersistenceFakeDB.class.getSimpleName());
Group<Property> properties = accessPointElement.properties();
Property className = new Property();
className.nameAndValue(AccountingPersistenceConfiguration.PERSISTENCE_CLASS_NAME, COUCHDB_CLASS_NAME);
properties.add(className);
Property dbName = new Property();
dbName.nameAndValue(DB_NAME_PROPERTY_NAME, DB_NAME_PROPERTY_VALUE);
dbName.nameAndValue(DB_NAME_PROPERTY_KEY, DB_NAME_PROPERTY_VALUE);
dbName.encrypted(false);
properties.add(dbName);
StringWriter stringWriter = new StringWriter();
@ -172,133 +152,59 @@ public class AccountingPersistenceConfigurationTest {
return serviceEndpoint;
}
protected void clean(){
ScopeProvider.instance.set(GCUBE_DEVNEXT_SCOPE);
SimpleQuery query = ICFactory.queryFor(ServiceEndpoint.class)
.addCondition(String.format("$resource/Profile/Category/text() eq '%s'", AccountingPersistenceConfiguration.SERVICE_ENDPOINT_CATEGORY))
.addCondition(String.format("$resource/Profile/Name/text() eq '%s'", AccountingPersistenceConfiguration.SERVICE_ENDPOINT_NAME))
.addCondition(String.format("$resource/Profile/RunTime/HostedOn/text() eq '%s'", RUNNING_ON))
.setResult("$resource");
DiscoveryClient<ServiceEndpoint> client = ICFactory.clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> serviceEndpoints = client.submit(query);
for (ServiceEndpoint serviceEndpoint : serviceEndpoints) {
try {
logger.debug("Trying to unpublish the old ServiceEndpoint with ID {} from scope {}",
serviceEndpoint.id(), GCUBE_DEVNEXT_SCOPE);
unPublishScopedResource(serviceEndpoint);
} catch(Exception e){
logger.debug("Exception trying to unpublish the old ServiceEndpoint with ID {} from scope {}",
serviceEndpoint.id(), GCUBE_DEVNEXT_SCOPE, e);
}
}
}
@Test
public void testPersistenceConfigurationFromIS() throws Exception{
ScopeProvider.instance.set(GCUBE_DEVNEXT_SCOPE);
boolean createResource = false;
ScopeProvider.instance.set(ALL_SCOPES[0]);
boolean createResource = true;
ServiceEndpoint serviceEndpoint = null;
List<String> scopes = Arrays.asList(ALL_SCOPES);
if(createResource){
List<String> scopes = Arrays.asList(SCOPES);
serviceEndpoint = createServiceEndpoint();
publishScopedResource(serviceEndpoint, scopes);
}
Thread.sleep(5000); // Waiting 5 sec
try {
AccountingPersistenceConfiguration persitenceConfiguration = new AccountingPersistenceConfiguration(COUCHDB_CLASS_NAME);
AccountingPersistenceConfiguration persitenceConfiguration = new AccountingPersistenceConfiguration(AccountingPersistenceFakeDB.class);
if(createResource){
Assert.assertTrue(persitenceConfiguration.getUri().toURL().equals(new URL(RUNNING_ON)));
Assert.assertTrue(persitenceConfiguration.getUsername().compareTo(FAKE_USERNAME)==0);
Assert.assertTrue(persitenceConfiguration.getPassword().compareTo(FAKE_PASSWORD)==0);
Assert.assertTrue(persitenceConfiguration.getProperty(DB_NAME_PROPERTY_NAME).compareTo(DB_NAME_PROPERTY_VALUE)==0);
String uri = persitenceConfiguration.getProperty(AccountingPersistenceConfiguration.URL_PROPERTY_KEY);
Assert.assertTrue(uri.compareTo(new URL(ENDPOINT).toString())==0);
String username = persitenceConfiguration.getProperty(AccountingPersistenceConfiguration.USERNAME_PROPERTY_KEY);
Assert.assertTrue(username.compareTo(FAKE_USERNAME)==0);
String password = persitenceConfiguration.getProperty(AccountingPersistenceConfiguration.PASSWORD_PROPERTY_KEY);
Assert.assertTrue(password.compareTo(FAKE_PASSWORD)==0);
String dbName = persitenceConfiguration.getProperty(DB_NAME_PROPERTY_KEY);
Assert.assertTrue(dbName.compareTo(DB_NAME_PROPERTY_VALUE)==0);
}
} finally {
if(createResource){
unPublishScopedResource(serviceEndpoint);
unPublishScopedResource(serviceEndpoint, scopes);
}
}
}
@Test
public void testPersistenceConfigurationFromISInDifferentScopes() throws Exception{
public void getUsernamePasswordForScopes() throws Exception{
for(String scope : ALL_SCOPES){
logger.debug("START ======================================================");
ScopeProvider.instance.set(scope);
try {
AccountingPersistenceConfiguration persitenceConfiguration = new AccountingPersistenceConfiguration(COUCHDB_CLASS_NAME);
logger.debug("{} : {}", AccountingPersistenceConfiguration.class.getSimpleName(), persitenceConfiguration);
}catch(IndexOutOfBoundsException e){
logger.debug("No AccountingPersistenceConfiguration : \n {} {} \n\n", e.getClass().getName(), e.getMessage());
} catch(Exception e){
logger.error("Error getting AccountingPersistenceConfiguration", e);
throw e;
}
logger.debug(" END ======================================================");
}
}
@Test
public void getUsernamePasswordForScopes() throws Exception{
for(String scope : SCOPES){
ScopeProvider.instance.set(scope);
try {
AccountingPersistenceConfiguration persitenceConfiguration = new AccountingPersistenceConfiguration(COUCHDB_CLASS_NAME);
logger.debug("{} {} - {} : {}", scope,
persitenceConfiguration.getUri(),
persitenceConfiguration.getUsername(),
persitenceConfiguration.getPassword());
AccountingPersistenceConfiguration persitenceConfiguration = new AccountingPersistenceConfiguration(AccountingPersistenceFakeDB.class);
String uri = persitenceConfiguration.getProperty(AccountingPersistenceConfiguration.URL_PROPERTY_KEY);
String username = persitenceConfiguration.getProperty(AccountingPersistenceConfiguration.USERNAME_PROPERTY_KEY);
String password = persitenceConfiguration.getProperty(AccountingPersistenceConfiguration.PASSWORD_PROPERTY_KEY);
logger.debug("{} - {} - {} - {}", scope, uri, username, password);
}catch(IndexOutOfBoundsException e){
logger.debug("No AccountingPersistenceConfiguration : \n {} {} \n\n", e.getClass().getName(), e.getMessage());
} catch(Exception e){
logger.error("Error getting AccountingPersistenceConfiguration", e);
throw e;
} finally {
logger.debug(" END ======================================================");
}
}
}
/*
@Test
public void testFiles() throws IOException{
File file = new File("./aux.txt");
logger.debug("file : {}", file.getAbsolutePath());
String aux = "AUX";
try(FileWriter fw = new FileWriter(file, true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw)){
out.println(aux);
out.flush();
} catch( IOException e ){
throw e;
}
File same = file;
logger.debug("same : {}", same.getAbsolutePath());
boolean moved = same.renameTo(new File(file.getAbsolutePath()+".RENAMED"));
logger.debug("Moved : {}", moved);
logger.debug("AFTER RENAME");
logger.debug("file : {}", file.getAbsolutePath());
logger.debug("same : {}", same.getAbsolutePath());
aux = "DONE";
try(FileWriter fw = new FileWriter(file, true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw)){
out.println(aux);
out.flush();
} catch( IOException e ){
throw e;
}
}
*/
}

View File

@ -7,12 +7,14 @@ import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.persistence.AccountingPersistence;
import org.gcube.accounting.testutility.StressTestUtility;
import org.gcube.accounting.testutility.TestOperation;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.persistence.PersistenceBackendFactory;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -21,9 +23,9 @@ import org.slf4j.LoggerFactory;
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class AccontingPersistence {
public class AccountingPersistenceTest {
private static final Logger logger = LoggerFactory.getLogger(AccontingPersistence.class);
private static final Logger logger = LoggerFactory.getLogger(AccountingPersistenceTest.class);
public static final String[] SCOPES = new String[]{
"/gcube",
@ -37,13 +39,13 @@ public class AccontingPersistence {
@Test
public void stressTest() throws Exception {
final AccountingPersistence persistence = AccountingPersistence.getInstance();
AccountingPersistenceBackendFactory.setFallbackLocation(null);
PersistenceBackendFactory.setFallbackLocation(null);
StressTestUtility.stressTest(new TestOperation() {
@Override
public void operate(int i) {
int randomNumber = ThreadLocalRandom.current().nextInt(0, 5);
ScopeProvider.instance.set(SCOPES[randomNumber]);
SingleUsageRecord usageRecord = null;
UsageRecord usageRecord = null;
switch (i%2) {
case 0:
usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
@ -51,6 +53,9 @@ public class AccontingPersistence {
case 1:
usageRecord = TestUsageRecord.createTestStorageUsageRecordAutomaticScope();
break;
default:
usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
break;
}
try {
usageRecord.setConsumerId(UUID.randomUUID().toString());

View File

@ -1,16 +1,16 @@
/**
*
*/
package org.gcube.accounting.persistence;
package org.gcube.documentstore.persistence;
import java.util.concurrent.TimeUnit;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.testutility.StressTestUtility;
import org.gcube.accounting.testutility.TestOperation;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.exception.InvalidValueException;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -19,9 +19,9 @@ import org.slf4j.LoggerFactory;
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class AccountingPersistenceBackendMonitorTest {
public class PersistenceBackendMonitorTest {
private static final Logger logger = LoggerFactory.getLogger(AccountingPersistenceBackendMonitor.class);
private static final Logger logger = LoggerFactory.getLogger(PersistenceBackendMonitorTest.class);
public static final long timeout = 5000;
public static final TimeUnit timeUnit = TimeUnit.MILLISECONDS;
@ -30,14 +30,14 @@ public class AccountingPersistenceBackendMonitorTest {
public void parsingTest() throws Exception {
ScopeProvider.instance.set("/gcube/devsec");
AccountingPersistenceBackendFactory.setFallbackLocation(null);
final AccountingPersistence persistence = AccountingPersistence.getInstance();
PersistenceBackendFactory.setFallbackLocation(null);
final PersistenceBackend persistence = PersistenceBackendFactory.getPersistenceBackend(ScopeProvider.instance.get());
StressTestUtility.stressTest(new TestOperation() {
@Override
public void operate(int i) {
SingleUsageRecord usageRecord = null;
UsageRecord usageRecord = null;
switch (i%3) {
case 0:
usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
@ -62,22 +62,23 @@ public class AccountingPersistenceBackendMonitorTest {
persistence.flush(timeout, timeUnit);
logger.debug(" END -----------------------------------------------");
AccountingPersistenceBackend accountingPersistenceBackend = AccountingPersistenceBackendFactory.getPersistenceBackend();
accountingPersistenceBackend.setFallback((FallbackPersistenceBackend) accountingPersistenceBackend);
AccountingPersistenceBackendMonitor accountingPersistenceBackendMonitor = new AccountingPersistenceBackendMonitor(accountingPersistenceBackend);
PersistenceBackend persistenceBackend = PersistenceBackendFactory.getPersistenceBackend(ScopeProvider.instance.get());
persistenceBackend.setFallback((FallbackPersistenceBackend) persistenceBackend);
PersistenceBackendMonitor temporalDataPersistenceBackendMonitor = new PersistenceBackendMonitor(persistenceBackend);
accountingPersistenceBackendMonitor.run();
temporalDataPersistenceBackendMonitor.run();
}
@Test
public void singleParsingTest() throws Exception {
ScopeProvider.instance.set("/gcube/devsec");
AccountingPersistenceBackendFactory.setFallbackLocation(null);
AccountingPersistenceBackend accountingPersistenceBackend = AccountingPersistenceBackendFactory.getPersistenceBackend();
accountingPersistenceBackend.setFallback((FallbackPersistenceBackend) accountingPersistenceBackend);
AccountingPersistenceBackendMonitor accountingPersistenceBackendMonitor = new AccountingPersistenceBackendMonitor(accountingPersistenceBackend);
accountingPersistenceBackendMonitor.run();
PersistenceBackendFactory.setFallbackLocation(null);
PersistenceBackend persistenceBackend = PersistenceBackendFactory.getPersistenceBackend(ScopeProvider.instance.get());
persistenceBackend.setFallback((FallbackPersistenceBackend) persistenceBackend);
PersistenceBackendMonitor temporalDataPersistenceBackendMonitor = new PersistenceBackendMonitor(persistenceBackend);
temporalDataPersistenceBackendMonitor.run();
}
}

View File

@ -1,17 +1,20 @@
/**
*
*/
package org.gcube.accounting.persistence;
package org.gcube.documentstore.persistence;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.accounting.testutility.StressTestUtility;
import org.gcube.accounting.testutility.TestOperation;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.exception.InvalidValueException;
import org.gcube.documentstore.persistence.FallbackPersistenceBackend;
import org.gcube.documentstore.persistence.PersistenceBackend;
import org.gcube.documentstore.persistence.PersistenceBackendFactory;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
@ -21,9 +24,9 @@ import org.slf4j.LoggerFactory;
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class AccountingPersistenceBackendTest {
public class PersistenceBackendTest {
private static Logger logger = LoggerFactory.getLogger(AccountingPersistenceBackendTest.class);
private static Logger logger = LoggerFactory.getLogger(PersistenceBackendTest.class);
public static final String[] SCOPES = new String[]{"/gcube", "/gcube/devNext"};
public static final String GCUBE_SCOPE = SCOPES[0];
@ -32,24 +35,24 @@ public class AccountingPersistenceBackendTest {
public static final long timeout = 5000;
public static final TimeUnit timeUnit = TimeUnit.MILLISECONDS;
public static AccountingPersistenceBackend getPersistence(){
public static PersistenceBackend getPersistence(){
ScopeProvider.instance.set(GCUBE_DEVNEXT_SCOPE);
AccountingPersistenceBackendFactory.setFallbackLocation(null);
return AccountingPersistenceBackendFactory.getPersistenceBackend();
PersistenceBackendFactory.setFallbackLocation(null);
return PersistenceBackendFactory.getPersistenceBackend(ScopeProvider.instance.get());
}
@Test
public void singleTestNoScope() throws Exception {
AccountingPersistenceBackendFactory.setFallbackLocation(null);
final AccountingPersistenceBackend persistence = AccountingPersistenceBackendFactory.getPersistenceBackend();
PersistenceBackendFactory.setFallbackLocation(null);
final PersistenceBackend persistence = PersistenceBackendFactory.getPersistenceBackend(null);
Assert.assertTrue(persistence instanceof FallbackPersistenceBackend);
StressTestUtility.stressTest(new TestOperation() {
@Override
public void operate(int i) {
SingleUsageRecord usageRecord;
UsageRecord usageRecord;
try {
usageRecord = TestUsageRecord.createTestServiceUsageRecordExplicitScope();
persistence.validateAccountAggregate(usageRecord, true, false);
persistence.accountValidateAggregate(usageRecord, true, false);
} catch (InvalidValueException e) {
throw new RuntimeException(e);
}
@ -61,12 +64,12 @@ public class AccountingPersistenceBackendTest {
@Test
public void singleTest() throws Exception {
final AccountingPersistenceBackend persistence = getPersistence();
final PersistenceBackend persistence = getPersistence();
StressTestUtility.stressTest(new TestOperation() {
@Override
public void operate(int i) {
SingleUsageRecord usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
persistence.validateAccountAggregate(usageRecord, true, false);
UsageRecord usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
persistence.accountValidateAggregate(usageRecord, true, false);
}
}, 1);
@ -75,24 +78,24 @@ public class AccountingPersistenceBackendTest {
@Test
public void stressTestNoAggregation() throws Exception {
final AccountingPersistenceBackend persistence = getPersistence();
final PersistenceBackend persistence = getPersistence();
StressTestUtility.stressTest(new TestOperation() {
@Override
public void operate(int i) {
SingleUsageRecord usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
persistence.validateAccountAggregate(usageRecord, true, false);
UsageRecord usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
persistence.accountValidateAggregate(usageRecord, true, false);
}
});
}
@Test
public void stressTestWithAggregation() throws Exception {
final AccountingPersistenceBackend persistence = getPersistence();
final PersistenceBackend persistence = getPersistence();
StressTestUtility.stressTest(new TestOperation() {
@Override
public void operate(int i) throws Exception {
SingleUsageRecord usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
UsageRecord usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
persistence.account(usageRecord);
}
});
@ -103,23 +106,24 @@ public class AccountingPersistenceBackendTest {
@Test
public void testScopeRecheck() throws Exception {
ScopeProvider.instance.set("/fakeScope");
PersistenceBackendFactory.setFallbackLocation(null);
logger.debug("Going to check First Time");
AccountingPersistenceBackend first = AccountingPersistenceBackendFactory.getPersistenceBackend();
logger.debug("First {} : {}", AccountingPersistenceBackend.class.getSimpleName(), first);
Long firstCheck = AccountingPersistenceBackendFactory.getFallbackLastCheck(ScopeProvider.instance.get());
PersistenceBackend first = PersistenceBackendFactory.getPersistenceBackend(ScopeProvider.instance.get());
logger.debug("First {} : {}", PersistenceBackend.class.getSimpleName(), first);
Long firstCheck = PersistenceBackendFactory.getFallbackLastCheck(ScopeProvider.instance.get());
logger.debug("First Check Time {}", firstCheck);
long startTime = Calendar.getInstance().getTimeInMillis();
long endTime = startTime;
while(endTime <= (startTime + (AccountingPersistenceBackendFactory.FALLBACK_RETRY_TIME + 100))){
while(endTime <= (startTime + (PersistenceBackendFactory.FALLBACK_RETRY_TIME + 100))){
endTime = Calendar.getInstance().getTimeInMillis();
}
logger.debug("Going to check Second Time");
AccountingPersistenceBackend second = AccountingPersistenceBackendFactory.getPersistenceBackend();
logger.debug("Second {} : {}", AccountingPersistenceBackend.class.getSimpleName(), second);
Long secondCheck = AccountingPersistenceBackendFactory.getFallbackLastCheck(ScopeProvider.instance.get());
PersistenceBackend second = PersistenceBackendFactory.getPersistenceBackend(ScopeProvider.instance.get());
logger.debug("Second {} : {}", PersistenceBackend.class.getSimpleName(), second);
Long secondCheck = PersistenceBackendFactory.getFallbackLastCheck(ScopeProvider.instance.get());
logger.debug("Second Check Time {}", secondCheck);
Assert.assertNotEquals(firstCheck, secondCheck);

View File

@ -1,16 +1,17 @@
/**
*
*/
package org.gcube.accounting.aggregation.scheduler;
package org.gcube.documentstore.records.aggregation;
import org.gcube.accounting.datamodel.SingleUsageRecord;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.accounting.persistence.AccountingPersistenceExecutor;
import org.gcube.accounting.testutility.StressTestUtility;
import org.gcube.accounting.testutility.TestOperation;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.documentstore.persistence.PersistenceExecutor;
import org.gcube.documentstore.records.Record;
import org.gcube.documentstore.records.aggregation.AggregationScheduler;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -27,12 +28,12 @@ public class AggregationSchedulerTest {
return AggregationScheduler.newInstance();
}
public static AccountingPersistenceExecutor persistenceExecutor = new AccountingPersistenceExecutor(){
public static PersistenceExecutor persistenceExecutor = new PersistenceExecutor(){
@Override
public void persist(UsageRecord... usageRecords) throws Exception {
for(UsageRecord usageRecord : usageRecords){
logger.debug("Storing : {}", usageRecord.toString());
public void persist(Record... records) throws Exception {
for(Record record : records){
logger.debug("Storing : {}", record.toString());
}
}
@ -45,7 +46,7 @@ public class AggregationSchedulerTest {
StressTestUtility.stressTest(new TestOperation() {
@Override
public void operate(int i) throws Exception {
SingleUsageRecord usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
UsageRecord usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
aggregationScheduler.aggregate(usageRecord, persistenceExecutor);
}
});
@ -78,7 +79,7 @@ public class AggregationSchedulerTest {
StressTestUtility.stressTest(new TestOperation() {
@Override
public void operate(int i) throws Exception {
SingleUsageRecord usageRecord;
UsageRecord usageRecord;
if(i%2==0){
usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
}else{
@ -97,7 +98,7 @@ public class AggregationSchedulerTest {
StressTestUtility.stressTest(new TestOperation() {
@Override
public void operate(int i) throws Exception {
SingleUsageRecord usageRecord;
UsageRecord usageRecord;
switch (i%3) {
case 0:
usageRecord = TestUsageRecord.createTestServiceUsageRecordAutomaticScope();
@ -117,16 +118,5 @@ public class AggregationSchedulerTest {
});
aggregationScheduler.flush(persistenceExecutor);
}
/*
@Test
public void stressTestDifferentAggregableAndNotAggregable() throws Exception {
StressTestUtility.stressTest(new TestOperation() {
@Override
public void operate(int i) throws Exception {
}
});
}
*/
}