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 {
validator = managedClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
logger.error("{} {}", keyString, annotation, e);
continue;
}
fieldValidators.add(validator);

View File

@ -4,23 +4,20 @@
package org.gcube.accounting.datamodel;
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.Date;
import java.util.HashMap;
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.PortletUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.StorageUsageRecord;
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.NotEmptyIfNotNull;
import org.gcube.accounting.exception.InvalidValueException;
@ -44,22 +41,6 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
@DeprecatedWarning @MoveToScope @NotEmpty
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
public static final String CREATOR_ID = "creatorId";
@ -69,35 +50,7 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
@DeprecatedWarning @MoveToCreationTime
protected static final String CREATE_TIME = "createTime";
@Target(ElementType.FIELD)
@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;
public final static Map<String, String> resourceTypeMapping;
private final static String JOB = "job";
private final static String TASK = "task";
@ -117,31 +70,15 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
@DeprecatedWarning @MoveToUsageRecordType
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
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)
@Retention(RetentionPolicy.RUNTIME)
@ -265,7 +202,7 @@ public class RawUsageRecord extends BasicUsageRecord implements SingleUsageRecor
calendar.setTime(createTime);
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.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.NotEmptyIfNotNull;
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
* {@link #StorageUsageRecord.OperationType}
*/
@RequiredField @ValidOperationType
@RequiredField @ValidOperationType @FixDataVolumeSign
public static final String OPERATION_TYPE = "operationType";
/**
* KEY for : type of data accessed.
@ -92,10 +93,9 @@ public abstract class AbstractStorageUsageRecord extends BasicUsageRecord {
/**
* Quantity of data in terms of KB
*/
@RequiredField @ValidLong
@RequiredField @ValidLong @FixDataVolumeSign
public static final String DATA_VOLUME = "dataVolume";
/**
* KEY for : Qualifies the data in terms of data (e.g. MIME type for the
* Storage, domain for a database)

View File

@ -24,7 +24,7 @@ public class DeprecatedWarningAction implements FieldAction {
*/
@Override
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());
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();
try {
logger.error("{} was not accounted succesfully from {}. Trying to use {}.",
usageRecord.toString(), persistenceName, fallabackPersistenceName);
usageRecord.toString(), persistenceName, fallabackPersistenceName, e);
fallback.reallyAccount(usageRecord);
logger.debug("{} accounted succesfully from {}",
usageRecord.toString(), fallabackPersistenceName);
}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.BasicUsageRecordUtility;
import org.gcube.accounting.datamodel.basetypes.AbstractStorageUsageRecord.OperationType;
import org.gcube.accounting.datamodel.basetypes.TestUsageRecord;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.common.scope.api.ScopeProvider;
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 StorageUsageRecordTest {
private static Logger logger = LoggerFactory.getLogger(StorageUsageRecordTest.class);
public static Set<String> getExpectedRequiredFields(){
Set<String> expectedRequiredFields = new HashSet<String>();
expectedRequiredFields.add(BasicUsageRecordUtility.ID);
@ -71,4 +76,15 @@ public class StorageUsageRecordTest {
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);
}
}