Merged from branch

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/accounting/accounting-lib@119574 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Luca Frosini 2015-10-09 12:52:42 +00:00
parent b12e0f11a3
commit 78dc833d14
14 changed files with 270 additions and 81 deletions

View File

@ -162,6 +162,7 @@ public abstract class BasicUsageRecord implements UsageRecord, Serializable {
try { try {
validator = managedClass.newInstance(); validator = managedClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) { } catch (InstantiationException | IllegalAccessException e) {
logger.error("{} {}", keyString, annotation, e);
continue; continue;
} }
fieldValidators.add(validator); fieldValidators.add(validator);

View File

@ -4,23 +4,20 @@
package org.gcube.accounting.datamodel; package org.gcube.accounting.datamodel;
import java.io.Serializable; 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.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.gcube.accounting.datamodel.backwardcompatibility.MoveToCreationTime;
import org.gcube.accounting.datamodel.backwardcompatibility.MoveToScope;
import org.gcube.accounting.datamodel.backwardcompatibility.MoveToUsageRecordType;
import org.gcube.accounting.datamodel.deprecationmanagement.annotations.DeprecatedWarning;
import org.gcube.accounting.datamodel.usagerecords.JobUsageRecord; import org.gcube.accounting.datamodel.usagerecords.JobUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.PortletUsageRecord; import org.gcube.accounting.datamodel.usagerecords.PortletUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord; import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.StorageUsageRecord; import org.gcube.accounting.datamodel.usagerecords.StorageUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.TaskUsageRecord; import org.gcube.accounting.datamodel.usagerecords.TaskUsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.datamodel.decorators.FieldDecorator;
import org.gcube.accounting.datamodel.deprecationmanagement.annotations.DeprecatedWarning;
import org.gcube.accounting.datamodel.validations.annotations.NotEmpty; import org.gcube.accounting.datamodel.validations.annotations.NotEmpty;
import org.gcube.accounting.datamodel.validations.annotations.NotEmptyIfNotNull; import org.gcube.accounting.datamodel.validations.annotations.NotEmptyIfNotNull;
import org.gcube.accounting.exception.InvalidValueException; import org.gcube.accounting.exception.InvalidValueException;
@ -44,22 +41,6 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
@DeprecatedWarning @MoveToScope @NotEmpty @DeprecatedWarning @MoveToScope @NotEmpty
public static final String RESOURCE_SCOPE = "resourceScope"; public static final String RESOURCE_SCOPE = "resourceScope";
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@FieldDecorator(managed=MoveToScopeAction.class)
protected @interface MoveToScope { }
protected class MoveToScopeAction implements FieldAction {
@Override
public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException {
if(value instanceof String){
usageRecord.setScope((String) value);
}else{
throw new InvalidValueException();
}
return value;
}
}
@DeprecatedWarning @NotEmptyIfNotNull @DeprecatedWarning @NotEmptyIfNotNull
public static final String CREATOR_ID = "creatorId"; public static final String CREATOR_ID = "creatorId";
@ -69,35 +50,7 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
@DeprecatedWarning @MoveToCreationTime @DeprecatedWarning @MoveToCreationTime
protected static final String CREATE_TIME = "createTime"; protected static final String CREATE_TIME = "createTime";
@Target(ElementType.FIELD) public final static Map<String, String> resourceTypeMapping;
@Retention(RetentionPolicy.RUNTIME)
@FieldDecorator(managed=MoveToCreationTimeAction.class)
protected @interface MoveToCreationTime { }
protected class MoveToCreationTimeAction implements FieldAction {
@Override
public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException {
if(value instanceof Date){
Calendar calendar = Calendar.getInstance();
calendar.setTime((Date) value);
value = calendar;
}
if(value instanceof Long){
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis((Long) value);
value = calendar;
}
if(value instanceof Calendar){
usageRecord.setCreationTime((Calendar) value);
}else{
throw new InvalidValueException();
}
return value;
}
}
private final static Map<String, String> resourceTypeMapping;
private final static String JOB = "job"; private final static String JOB = "job";
private final static String TASK = "task"; private final static String TASK = "task";
@ -117,31 +70,15 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
@DeprecatedWarning @MoveToUsageRecordType @DeprecatedWarning @MoveToUsageRecordType
protected static final String RESOURCE_TYPE = "resourceType"; protected static final String RESOURCE_TYPE = "resourceType";
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@FieldDecorator(managed=MoveToUsageRecordTypeAction.class)
protected @interface MoveToUsageRecordType { }
protected class MoveToUsageRecordTypeAction implements FieldAction {
@Override
public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException {
if(value instanceof String){
String newValue = resourceTypeMapping.get(value);
if(newValue == null){
throw new InvalidValueException();
}
resourceProperties.put(USAGE_RECORD_TYPE, newValue);
}else{
throw new InvalidValueException();
}
return value;
}
}
@DeprecatedWarning //@MoveToAggregatedUsageRecordId @DeprecatedWarning //@MoveToAggregatedUsageRecordId
protected static final String AGGREGATED_ID = "aggregatedId"; protected static final String AGGREGATED_ID = "aggregatedId";
/**
* Redeclared to allow @MoveToUsageRecordTypeAction to access it
*/
public static final String USAGE_RECORD_TYPE = BasicUsageRecord.USAGE_RECORD_TYPE;
/* /*
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@ -265,7 +202,7 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
calendar.setTime(createTime); calendar.setTime(createTime);
setCreationTime(calendar); setCreationTime(calendar);
*/ */
logger.warn("The method is deprecated. Please modify your code as soon as possible"); //logger.warn("The method is deprecated. Please modify your code as soon as possible");
} }

View File

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

View File

@ -0,0 +1,36 @@
/**
*
*/
package org.gcube.accounting.datamodel.backwardcompatibility;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import org.gcube.accounting.datamodel.UsageRecord;
import org.gcube.accounting.datamodel.decorators.FieldAction;
import org.gcube.accounting.exception.InvalidValueException;
public class MoveToCreationTimeAction implements FieldAction {
@Override
public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException {
if(value instanceof Date){
Calendar calendar = Calendar.getInstance();
calendar.setTime((Date) value);
value = calendar;
}
if(value instanceof Long){
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis((Long) value);
value = calendar;
}
if(value instanceof Calendar){
usageRecord.setCreationTime((Calendar) value);
}else{
throw new InvalidValueException();
}
return value;
}
}

View File

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

View File

@ -0,0 +1,22 @@
/**
*
*/
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.exception.InvalidValueException;
public class MoveToScopeAction implements FieldAction {
@Override
public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException {
if(value instanceof String){
usageRecord.setScope((String) value);
}else{
throw new InvalidValueException();
}
return value;
}
}

View File

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

View File

@ -0,0 +1,29 @@
/**
*
*/
package org.gcube.accounting.datamodel.backwardcompatibility;
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;
@SuppressWarnings("deprecation")
public class MoveToUsageRecordTypeAction implements FieldAction {
@Override
public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException {
if(value instanceof String){
String newValue = RawUsageRecord.resourceTypeMapping.get(value);
if(newValue == null){
throw new InvalidValueException();
}
usageRecord.setResourceProperty(RawUsageRecord.USAGE_RECORD_TYPE, newValue);
}else{
throw new InvalidValueException();
}
return value;
}
}

View File

@ -9,6 +9,7 @@ import java.util.Map;
import org.gcube.accounting.datamodel.BasicUsageRecord; import org.gcube.accounting.datamodel.BasicUsageRecord;
import org.gcube.accounting.datamodel.decorators.RequiredField; import org.gcube.accounting.datamodel.decorators.RequiredField;
import org.gcube.accounting.datamodel.validations.annotations.FixDataVolumeSign;
import org.gcube.accounting.datamodel.validations.annotations.NotEmpty; import org.gcube.accounting.datamodel.validations.annotations.NotEmpty;
import org.gcube.accounting.datamodel.validations.annotations.NotEmptyIfNotNull; import org.gcube.accounting.datamodel.validations.annotations.NotEmptyIfNotNull;
import org.gcube.accounting.datamodel.validations.annotations.ValidDataType; import org.gcube.accounting.datamodel.validations.annotations.ValidDataType;
@ -79,7 +80,7 @@ public abstract class AbstractStorageUsageRecord extends BasicUsageRecord {
* The value is a controlled dictionary by * The value is a controlled dictionary by
* {@link #StorageUsageRecord.OperationType} * {@link #StorageUsageRecord.OperationType}
*/ */
@RequiredField @ValidOperationType @RequiredField @ValidOperationType @FixDataVolumeSign
public static final String OPERATION_TYPE = "operationType"; public static final String OPERATION_TYPE = "operationType";
/** /**
* KEY for : type of data accessed. * KEY for : type of data accessed.
@ -92,10 +93,9 @@ public abstract class AbstractStorageUsageRecord extends BasicUsageRecord {
/** /**
* Quantity of data in terms of KB * Quantity of data in terms of KB
*/ */
@RequiredField @ValidLong @RequiredField @ValidLong @FixDataVolumeSign
public static final String DATA_VOLUME = "dataVolume"; public static final String DATA_VOLUME = "dataVolume";
/** /**
* KEY for : Qualifies the data in terms of data (e.g. MIME type for the * KEY for : Qualifies the data in terms of data (e.g. MIME type for the
* Storage, domain for a database) * Storage, domain for a database)

View File

@ -24,7 +24,7 @@ public class DeprecatedWarningAction implements FieldAction {
*/ */
@Override @Override
public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException { public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException {
logger.warn("The field {} is deprecated for {}. Anyway the field will be included in the document", logger.trace("The field {} is deprecated for {}. Anyway the field will be included in the document",
key, usageRecord.getClass().getSimpleName()); key, usageRecord.getClass().getSimpleName());
return value; return value;
} }

View File

@ -0,0 +1,23 @@
/**
*
*/
package org.gcube.accounting.datamodel.validations.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.FieldDecorator;
import org.gcube.accounting.datamodel.validations.validators.FixDataVolumeSignAction;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@FieldDecorator(managed=FixDataVolumeSignAction.class)
public @interface FixDataVolumeSign {
}

View File

@ -0,0 +1,77 @@
/**
*
*/
package org.gcube.accounting.datamodel.validations.validators;
import java.io.Serializable;
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;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class FixDataVolumeSignAction implements FieldAction {
protected Long checkIt(Long dataVolume, OperationType operationType){
switch (operationType) {
case CREATE:{
dataVolume = (dataVolume > 0) ? dataVolume : -dataVolume;
break;
}
case READ:{
dataVolume = (dataVolume > 0) ? dataVolume : -dataVolume;
break;
}
case UPDATE:{
break;
}
case DELETE:{
dataVolume = (dataVolume < 0) ? dataVolume : -dataVolume;
break;
}
default:{
break;
}
}
return dataVolume;
}
/**
* {@inheritDoc}
*/
@Override
public Serializable validate(String key, Serializable value, UsageRecord usageRecord) throws InvalidValueException {
try {
if(key.compareTo(AbstractStorageUsageRecord.DATA_VOLUME)==0){
OperationType operationType = (OperationType) usageRecord.getResourceProperty(AbstractStorageUsageRecord.OPERATION_TYPE);
if(operationType!=null){
ValidLongValidator validLongValidator = new ValidLongValidator();
value = validLongValidator.validate(key, value, usageRecord);
Long dataVolume = new Long((Long) value);
value = checkIt(dataVolume, operationType);
}
}
if(key.compareTo(AbstractStorageUsageRecord.OPERATION_TYPE)==0){
Long dataVolume = (Long) usageRecord.getResourceProperty(AbstractStorageUsageRecord.DATA_VOLUME);
if(dataVolume!=null){
ValidOperationTypeValidator v = new ValidOperationTypeValidator();
value = v.validate(key, value, usageRecord);
OperationType operationType = (OperationType) value;
Long newDataVolume = checkIt(dataVolume, operationType);
usageRecord.setResourceProperty(AbstractStorageUsageRecord.DATA_VOLUME, newDataVolume);
}
}
}catch(InvalidValueException e){ }
return value;
}
}

View File

@ -79,12 +79,12 @@ public abstract class AccountingPersistence {
String fallabackPersistenceName = fallback.getClass().getSimpleName(); String fallabackPersistenceName = fallback.getClass().getSimpleName();
try { try {
logger.error("{} was not accounted succesfully from {}. Trying to use {}.", logger.error("{} was not accounted succesfully from {}. Trying to use {}.",
usageRecord.toString(), persistenceName, fallabackPersistenceName); usageRecord.toString(), persistenceName, fallabackPersistenceName, e);
fallback.reallyAccount(usageRecord); fallback.reallyAccount(usageRecord);
logger.debug("{} accounted succesfully from {}", logger.debug("{} accounted succesfully from {}",
usageRecord.toString(), fallabackPersistenceName); usageRecord.toString(), fallabackPersistenceName);
}catch(Exception ex){ }catch(Exception ex){
logger.error("{} was not accounted at all", usageRecord.toString()); logger.error("{} was not accounted at all", usageRecord.toString(), e);
} }
} }
} }

View File

@ -8,18 +8,23 @@ import java.util.Set;
import org.gcube.accounting.datamodel.BasicUsageRecord; import org.gcube.accounting.datamodel.BasicUsageRecord;
import org.gcube.accounting.datamodel.BasicUsageRecordUtility; import org.gcube.accounting.datamodel.BasicUsageRecordUtility;
import org.gcube.accounting.datamodel.basetypes.AbstractStorageUsageRecord.OperationType;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord; import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.exception.InvalidValueException; import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.api.ScopeProvider;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/ * @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
* *
*/ */
public class StorageUsageRecordTest { public class StorageUsageRecordTest {
private static Logger logger = LoggerFactory.getLogger(StorageUsageRecordTest.class);
public static Set<String> getExpectedRequiredFields(){ public static Set<String> getExpectedRequiredFields(){
Set<String> expectedRequiredFields = new HashSet<String>(); Set<String> expectedRequiredFields = new HashSet<String>();
expectedRequiredFields.add(BasicUsageRecordUtility.ID); expectedRequiredFields.add(BasicUsageRecordUtility.ID);
@ -71,4 +76,15 @@ public class StorageUsageRecordTest {
storageUsageRecord.validate(); storageUsageRecord.validate();
} }
@Test
public void signBasedOnOperation() throws InvalidValueException {
ScopeProvider.instance.set(TestUsageRecord.TEST_SCOPE);
StorageUsageRecord storageUsageRecord = TestUsageRecord.createTestStorageUsageRecordAutomaticScope();
logger.debug("{}", storageUsageRecord.toString());
storageUsageRecord.setOperationType(OperationType.DELETE);
storageUsageRecord.validate();
logger.debug("{}", storageUsageRecord.toString());
Assert.assertTrue(storageUsageRecord.getDataVolume()<0);
}
} }