refs #200: Create accouting-lib library
https://support.d4science.org/issues/200 Implementing library git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/accounting/accounting-lib@115264 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
3b60f5168c
commit
b7fef09600
|
@ -3,26 +3,54 @@
|
|||
*/
|
||||
package org.gcube.accounting.datamodel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.accounting.exception.InvalidValueException;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*/
|
||||
public interface AggregatedUsageRecord extends UsageRecord {
|
||||
public interface AggregatedUsageRecord<T> extends UsageRecord {
|
||||
|
||||
/**
|
||||
* Return the id of the usage record aggregating this
|
||||
* @return Aggregated Id
|
||||
* Return the id of the usage record aggregating this, null if this record
|
||||
* has not been aggregated by any record.
|
||||
* This method id deprecated. Use {@link #getAggregatedUsageRecordId()}
|
||||
* instead.
|
||||
* @return Aggregated Id The ID of the aggregation Record
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public String getAggregatedId();
|
||||
|
||||
/**
|
||||
* Set the id of the usage record aggregating this
|
||||
* @param aggregatedId
|
||||
* Set the id of the usage record aggregating this.
|
||||
* This method id deprecated. Use {@link #setAggregatedUsageRecordId()}
|
||||
* instead.
|
||||
* @param aggregatedId The ID of the aggregation Record
|
||||
* @throws InvalidValueException
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void setAggregatedId(String aggregatedId) throws InvalidValueException;
|
||||
|
||||
/**
|
||||
* Return the id of the usage record aggregating this, null if this record
|
||||
* has not been aggregated by any record.
|
||||
* @return Aggregated Id The ID of the aggregation Record
|
||||
*/
|
||||
public String getAggregatedUsageRecordId();
|
||||
|
||||
/**
|
||||
* Set the id of the usage record aggregating this
|
||||
* @param aggregatedId The ID of the aggregation Record
|
||||
* @throws InvalidValueException
|
||||
*/
|
||||
public void setAggregatedUsageRecordId(String aggregatedId) throws InvalidValueException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param records
|
||||
* @return
|
||||
*/
|
||||
public List<T> aggregate(List<T> records);
|
||||
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory;
|
|||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public abstract class RawUsageRecord<T> implements UsageRecord, Serializable {
|
||||
public abstract class RawUsageRecord implements UsageRecord, Serializable {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(RawUsageRecord.class);
|
||||
|
||||
|
@ -489,11 +489,6 @@ public abstract class RawUsageRecord<T> implements UsageRecord, Serializable {
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected List<T> aggregate(List<T> records){
|
||||
// TODO implements
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package org.gcube.accounting.datamodel.deprecationmanagement.annotations;
|
||||
|
||||
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.ValidatorField;
|
||||
import org.gcube.accounting.datamodel.deprecationmanagement.validators.MoveToAggregatedUsageRecordIdValidator;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ValidatorField(managed=MoveToAggregatedUsageRecordIdValidator.class)
|
||||
public @interface MoveToOperationResult {
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@ import java.io.Serializable;
|
|||
|
||||
import org.gcube.accounting.datamodel.UsageRecord;
|
||||
import org.gcube.accounting.datamodel.decorators.ValidatorAction;
|
||||
import org.gcube.accounting.datamodel.validations.validators.NotEmptyIfNotNullValidator;
|
||||
import org.gcube.accounting.exception.InvalidValueException;
|
||||
|
||||
/**
|
||||
|
@ -20,6 +21,8 @@ public class MoveToAggregatedUsageRecordIdValidator implements ValidatorAction {
|
|||
*/
|
||||
@Override
|
||||
public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException {
|
||||
NotEmptyIfNotNullValidator neinnv = new NotEmptyIfNotNullValidator();
|
||||
value = neinnv.validate(key, value, usageRecord);
|
||||
usageRecord.setAggregatedUsageRecordId((String) value);
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.accounting.datamodel.deprecationmanagement.validators;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.gcube.accounting.datamodel.UsageRecord;
|
||||
import org.gcube.accounting.datamodel.UsageRecord.OperationResult;
|
||||
import org.gcube.accounting.datamodel.decorators.ValidatorAction;
|
||||
import org.gcube.accounting.datamodel.validations.validators.ValidOperationResultValidator;
|
||||
import org.gcube.accounting.exception.InvalidValueException;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class MoveToOperationResutlValidator implements ValidatorAction {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException {
|
||||
ValidOperationResultValidator vorv = new ValidOperationResultValidator();
|
||||
value = vorv.validate(key, value, usageRecord);
|
||||
usageRecord.setOperationResult((OperationResult) value);
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,12 +4,12 @@
|
|||
package org.gcube.accounting.datamodel.implementations;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.accounting.datamodel.RawUsageRecord;
|
||||
import org.gcube.accounting.datamodel.SingleUsageRecord;
|
||||
import org.gcube.accounting.datamodel.decorators.ComputedField;
|
||||
import org.gcube.accounting.datamodel.decorators.RequiredField;
|
||||
import org.gcube.accounting.datamodel.deprecationmanagement.annotations.MoveToOperationResult;
|
||||
import org.gcube.accounting.datamodel.validations.annotations.NotEmpty;
|
||||
import org.gcube.accounting.datamodel.validations.annotations.ValidInteger;
|
||||
import org.gcube.accounting.datamodel.validations.annotations.ValidLong;
|
||||
|
@ -20,7 +20,7 @@ import org.gcube.accounting.exception.InvalidValueException;
|
|||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class JobUsageRecord extends RawUsageRecord<JobUsageRecord> implements SingleUsageRecord {
|
||||
public class JobUsageRecord extends RawUsageRecord implements SingleUsageRecord {
|
||||
|
||||
/**
|
||||
* Generated Serial Version UID
|
||||
|
@ -42,7 +42,7 @@ public class JobUsageRecord extends RawUsageRecord<JobUsageRecord> implements Si
|
|||
@RequiredField @ValidLong
|
||||
public static final String JOB_END_TIME = "jobEndTime";
|
||||
|
||||
@ValidOperationResult
|
||||
@ValidOperationResult @MoveToOperationResult
|
||||
protected static final String JOB_STATUS = "jobStatus";
|
||||
|
||||
@ValidInteger
|
||||
|
@ -143,13 +143,4 @@ public class JobUsageRecord extends RawUsageRecord<JobUsageRecord> implements Si
|
|||
return wallDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<JobUsageRecord> aggregate(List<JobUsageRecord> records) {
|
||||
// TODO implements
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
*/
|
||||
package org.gcube.accounting.datamodel.implementations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.accounting.datamodel.RawUsageRecord;
|
||||
import org.gcube.accounting.datamodel.SingleUsageRecord;
|
||||
import org.gcube.accounting.datamodel.decorators.RequiredField;
|
||||
|
@ -17,21 +15,21 @@ import org.gcube.accounting.exception.InvalidValueException;
|
|||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class PortletUsageRecord extends RawUsageRecord<PortletUsageRecord> implements SingleUsageRecord {
|
||||
public class PortletUsageRecord extends RawUsageRecord implements SingleUsageRecord {
|
||||
|
||||
/**
|
||||
* Generated Serial Version UID
|
||||
*/
|
||||
private static final long serialVersionUID = 8339324883678974869L;
|
||||
|
||||
@DeprecatedWarning @NotEmptyIfNotNull
|
||||
@NotEmptyIfNotNull @DeprecatedWarning
|
||||
protected static final String USER_ID = "userId";
|
||||
|
||||
@RequiredField @NotEmpty
|
||||
public static final String PORTLET_ID = "portletId";
|
||||
@RequiredField @NotEmpty
|
||||
public static final String OPERATION_ID = "operationId";
|
||||
// TODO More
|
||||
// TODO check ASL for more field
|
||||
|
||||
public PortletUsageRecord(){
|
||||
super();
|
||||
|
@ -63,13 +61,4 @@ public class PortletUsageRecord extends RawUsageRecord<PortletUsageRecord> imple
|
|||
setResourceSpecificProperty(OPERATION_ID, operationId);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<PortletUsageRecord> aggregate(List<PortletUsageRecord> records) {
|
||||
// TODO implements
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
*/
|
||||
package org.gcube.accounting.datamodel.implementations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.accounting.datamodel.RawUsageRecord;
|
||||
import org.gcube.accounting.datamodel.SingleUsageRecord;
|
||||
import org.gcube.accounting.datamodel.decorators.AggregatedField;
|
||||
import org.gcube.accounting.datamodel.decorators.RequiredField;
|
||||
import org.gcube.accounting.datamodel.deprecationmanagement.annotations.DeprecatedWarning;
|
||||
import org.gcube.accounting.datamodel.validations.annotations.NotEmpty;
|
||||
|
@ -18,7 +17,7 @@ import org.gcube.accounting.exception.InvalidValueException;
|
|||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class ServiceUsageRecord extends RawUsageRecord<ServiceUsageRecord> implements SingleUsageRecord {
|
||||
public class ServiceUsageRecord extends RawUsageRecord implements SingleUsageRecord {
|
||||
|
||||
/**
|
||||
* Generated Serial Version UID
|
||||
|
@ -33,11 +32,11 @@ public class ServiceUsageRecord extends RawUsageRecord<ServiceUsageRecord> imple
|
|||
public static final String REF_HOST = "refHost";
|
||||
@RequiredField @NotEmpty
|
||||
public static final String REF_VM = "refVM";
|
||||
@DeprecatedWarning @NotEmpty
|
||||
@NotEmpty @DeprecatedWarning
|
||||
public static final String DOMAIN = "domain";
|
||||
@ValidInteger
|
||||
@ValidInteger @AggregatedField
|
||||
protected static final String INVOCATION_COUNT = "invocationCount";
|
||||
@ValidInteger
|
||||
@ValidInteger @AggregatedField
|
||||
protected static final String AVERAGE_INVOCATION_COUNT = "averageInvocationTime";
|
||||
@NotEmpty
|
||||
public static final String SERVICE_CLASS = "serviceClass";
|
||||
|
@ -120,12 +119,4 @@ public class ServiceUsageRecord extends RawUsageRecord<ServiceUsageRecord> imple
|
|||
setResourceSpecificProperty(SERVICE_NAME, serviceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<ServiceUsageRecord> aggregate(List<ServiceUsageRecord> records) {
|
||||
// TODO implements
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
*/
|
||||
package org.gcube.accounting.datamodel.implementations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.accounting.datamodel.RawUsageRecord;
|
||||
import org.gcube.accounting.datamodel.SingleUsageRecord;
|
||||
import org.gcube.accounting.datamodel.decorators.RequiredField;
|
||||
|
@ -19,7 +17,7 @@ import org.gcube.accounting.exception.InvalidValueException;
|
|||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class StorageUsageUsageRecord extends RawUsageRecord<StorageUsageUsageRecord> implements SingleUsageRecord {
|
||||
public class StorageUsageUsageRecord extends RawUsageRecord implements SingleUsageRecord {
|
||||
|
||||
/**
|
||||
* Generated Serial Version UID
|
||||
|
@ -127,12 +125,4 @@ public class StorageUsageUsageRecord extends RawUsageRecord<StorageUsageUsageRec
|
|||
setResourceSpecificProperty(RESOURCE_OWNER, owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<StorageUsageUsageRecord> aggregate(List<StorageUsageUsageRecord> records) {
|
||||
// TODO implements
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
package org.gcube.accounting.datamodel.implementations;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.accounting.datamodel.RawUsageRecord;
|
||||
import org.gcube.accounting.datamodel.SingleUsageRecord;
|
||||
|
@ -20,7 +19,7 @@ import org.gcube.accounting.exception.InvalidValueException;
|
|||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class TaskUsageRecord extends RawUsageRecord<TaskUsageRecord> implements SingleUsageRecord {
|
||||
public class TaskUsageRecord extends RawUsageRecord implements SingleUsageRecord {
|
||||
|
||||
/**
|
||||
* Generated Serial Version UID
|
||||
|
@ -200,12 +199,4 @@ public class TaskUsageRecord extends RawUsageRecord<TaskUsageRecord> implements
|
|||
setResourceSpecificProperty(PROCESSORS, processors);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<TaskUsageRecord> aggregate(List<TaskUsageRecord> records) {
|
||||
// TODO implements
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.accounting.datamodel.implementations.aggregated;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.accounting.datamodel.AggregatedUsageRecord;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class JobUsageRecord extends org.gcube.accounting.datamodel.implementations.JobUsageRecord implements AggregatedUsageRecord<JobUsageRecord> {
|
||||
|
||||
/**
|
||||
* Generated Serial Version UID
|
||||
*/
|
||||
private static final long serialVersionUID = -3376423316219914682L;
|
||||
|
||||
public JobUsageRecord(){
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<JobUsageRecord> aggregate(List<JobUsageRecord> records) {
|
||||
// TODO implements
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.accounting.datamodel.implementations.aggregated;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.accounting.datamodel.AggregatedUsageRecord;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class PortletUsageRecord extends org.gcube.accounting.datamodel.implementations.PortletUsageRecord implements AggregatedUsageRecord<PortletUsageRecord> {
|
||||
|
||||
|
||||
/**
|
||||
* Generated Serial version UID
|
||||
*/
|
||||
private static final long serialVersionUID = 7445526162102677455L;
|
||||
|
||||
public PortletUsageRecord(){
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<PortletUsageRecord> aggregate(List<PortletUsageRecord> records) {
|
||||
// TODO implements
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.accounting.datamodel.implementations.aggregated;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.accounting.datamodel.AggregatedUsageRecord;
|
||||
import org.gcube.accounting.datamodel.decorators.AggregatedField;
|
||||
import org.gcube.accounting.datamodel.validations.annotations.ValidInteger;
|
||||
import org.gcube.accounting.exception.InvalidValueException;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class ServiceUsageRecord extends org.gcube.accounting.datamodel.implementations.ServiceUsageRecord implements AggregatedUsageRecord<ServiceUsageRecord> {
|
||||
|
||||
/**
|
||||
* Generated Serial Version UID
|
||||
*/
|
||||
private static final long serialVersionUID = 6387584974618335623L;
|
||||
|
||||
@ValidInteger @AggregatedField
|
||||
protected static final String INVOCATION_COUNT = "invocationCount";
|
||||
@ValidInteger @AggregatedField
|
||||
protected static final String AVERAGE_INVOCATION_COUNT = "averageInvocationTime";
|
||||
|
||||
public ServiceUsageRecord(){
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public String getInvocationCount() {
|
||||
return (String) this.resourceSpecificProperties.get(INVOCATION_COUNT);
|
||||
}
|
||||
|
||||
public void setInvocationCount(String invocationCount) throws InvalidValueException {
|
||||
setResourceSpecificProperty(INVOCATION_COUNT, invocationCount);
|
||||
}
|
||||
|
||||
public String getAverageInvocationTime() {
|
||||
return (String) this.resourceSpecificProperties.get(AVERAGE_INVOCATION_COUNT);
|
||||
}
|
||||
|
||||
public void setAverageInvocationTime(String averageInvocationTime) throws InvalidValueException {
|
||||
setResourceSpecificProperty(AVERAGE_INVOCATION_COUNT, averageInvocationTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<ServiceUsageRecord> aggregate(List<ServiceUsageRecord> records) {
|
||||
// TODO implements
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
|
@ -3,8 +3,6 @@
|
|||
*/
|
||||
package org.gcube.accounting.datamodel.implementations.aggregated;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.accounting.datamodel.RawUsageRecord;
|
||||
import org.gcube.accounting.datamodel.validations.annotations.NotEmpty;
|
||||
import org.gcube.accounting.datamodel.validations.annotations.ValidInteger;
|
||||
|
@ -14,7 +12,8 @@ import org.gcube.accounting.exception.InvalidValueException;
|
|||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*/
|
||||
public class StorageStatusUsageRecord extends RawUsageRecord<StorageStatusUsageRecord> {
|
||||
@Deprecated
|
||||
public class StorageStatusUsageRecord extends RawUsageRecord {
|
||||
|
||||
/**
|
||||
* Generated Serial Version UID
|
||||
|
@ -76,13 +75,4 @@ public class StorageStatusUsageRecord extends RawUsageRecord<StorageStatusUsageR
|
|||
setResourceSpecificProperty(DATA_COUNT, dataCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<StorageStatusUsageRecord> aggregate(List<StorageStatusUsageRecord> records) {
|
||||
// TODO implements
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.accounting.datamodel.implementations.aggregated;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.accounting.datamodel.AggregatedUsageRecord;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
|
||||
*
|
||||
*/
|
||||
public class StorageUsageUsageRecord extends org.gcube.accounting.datamodel.implementations.StorageUsageUsageRecord implements AggregatedUsageRecord<StorageUsageUsageRecord> {
|
||||
|
||||
/**
|
||||
* Generated Serial Version UID
|
||||
*/
|
||||
private static final long serialVersionUID = 1082525518686785682L;
|
||||
|
||||
public StorageUsageUsageRecord(){
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<StorageUsageUsageRecord> aggregate(List<StorageUsageUsageRecord> records) {
|
||||
// TODO implements
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue