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:
parent
c6067def1c
commit
6e4e3d4c93
|
@ -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
16
pom.xml
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.accounting.datamodel;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public interface SingleUsageRecord extends UsageRecord {
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 { }
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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{
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.gcube.accounting.persistence.AccountingPersistenceConfiguration
|
|
@ -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));
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
|
@ -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 {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
Loading…
Reference in New Issue