accounting-lib/src/main/java/org/gcube/accounting/datamodel/RawUsageRecord.java

454 lines
11 KiB
Java

/**
*
*/
package org.gcube.accounting.datamodel;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import org.gcube.accounting.datamodel.validators.NotEmptyIfNotNull;
import org.gcube.accounting.datamodel.validators.ValidLong;
import org.gcube.accounting.exception.InvalidValueException;
import org.gcube.common.validator.annotations.FieldValidator;
import org.gcube.common.validator.annotations.NotEmpty;
import org.gcube.common.validator.annotations.ValidityChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR) http://www.lucafrosini.com/
*
*/
public class RawUsageRecord implements UsageRecord, Serializable {
private static Logger logger = LoggerFactory.getLogger(RawUsageRecord.class);
@NotEmpty
public static final String ID = "id";
@NotEmpty
public static final String CREATOR_ID = "creatorId";
@NotEmpty
public static final String CONSUMER_ID = "consumerId";
@ValidLong
public static final String CREATION_TIME = "creationTime";
@ValidLong
public static final String START_TIME = "startTime";
@ValidLong
public static final String END_TIME = "endTime";
@NotEmpty
public static final String RESOURCE_TYPE = "resourceType";
@NotEmpty
public static final String RESOURCE_SCOPE = "resourceScope";
@NotEmpty
public static final String RESOURCE_OWNER = "resourceOwner";
@NotEmptyIfNotNull
public static final String AGGREGATED_ID = "aggregatedId";
/**
* Generated Serial Version UID
*/
private static final long serialVersionUID = -2060728578456796388L;
/**
* resource-specific properties
*/
protected Map<String, Serializable> resourceSpecificProperties;
protected final Map<String, List<FieldValidator<? extends Annotation>>> validation;
protected void initializeValidation() {
logger.debug("Initializing Field Validators");
List<Field> fields = Arrays.asList(this.getClass().getDeclaredFields());
for(Field field : fields){
String keyString;
try {
keyString = (String) field.get(null);
} catch (Exception e) {
continue;
}
List<FieldValidator<? extends Annotation>> fieldValidators = new ArrayList<FieldValidator<? extends Annotation>>();
validation.put(keyString, fieldValidators);
for (Annotation annotation : field.getAnnotations()){
if (annotation.annotationType().isAnnotationPresent(ValidityChecker.class)){
Class<? extends FieldValidator<?>> managedClass = ((ValidityChecker)annotation.annotationType().getAnnotation(ValidityChecker.class)).managed();
FieldValidator<?> validator;
try {
validator = managedClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
continue;
}
fieldValidators.add(validator);
}
}
}
}
public RawUsageRecord(){
this.resourceSpecificProperties = new HashMap<String, Serializable>();
this.validation = new HashMap<String, List<FieldValidator<? extends Annotation>>>();
initializeValidation();
this.resourceSpecificProperties.put(ID, UUID.randomUUID().toString());
this.resourceSpecificProperties.put(RESOURCE_TYPE, this.getClass().getSimpleName());
}
public RawUsageRecord(Map<String, Serializable> properties) throws InvalidValueException {
this.validation = new HashMap<String, List<FieldValidator<? extends Annotation>>>();
initializeValidation();
setResourceSpecificProperties(properties);
}
/**
* {@inheritDoc}
*/
@Override
public String getId() {
return (String) this.resourceSpecificProperties.get(ID);
}
/**
* {@inheritDoc}
*/
@Override
public void setId(String id) throws InvalidValueException {
setResourceSpecificProperty(ID, id);
}
/**
* {@inheritDoc}
*/
@Override
public String getCreatorId() {
return (String) this.resourceSpecificProperties.get(CREATOR_ID);
}
/**
* {@inheritDoc}
*/
@Override
public void setCreatorId(String creatorId) throws InvalidValueException {
setResourceSpecificProperty(CREATOR_ID, creatorId);
}
/**
* {@inheritDoc}
*/
@Override
public String getConsumerId() {
return (String) this.resourceSpecificProperties.get(CONSUMER_ID);
}
/**
* {@inheritDoc}
*/
@Override
public void setConsumerId(String consumerId) throws InvalidValueException {
setResourceSpecificProperty(CONSUMER_ID, consumerId);
}
protected Calendar timestampStringToCalendar(long millis){
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(millis);
return calendar;
}
/**
* {@inheritDoc}
*/
@Override
public Calendar getCreationTime() {
long millis = (Long) this.resourceSpecificProperties.get(CREATION_TIME);
return timestampStringToCalendar(millis);
}
/**
* {@inheritDoc}
*/
@Override
public void setCreationTime(Calendar creationTime) throws InvalidValueException {
setResourceSpecificProperty(CREATION_TIME, creationTime.getTimeInMillis());
}
/**
* {@inheritDoc}
*/
@Override
@Deprecated
public void setCreateTime(Date createTime) throws InvalidValueException {
Calendar calendar = Calendar.getInstance();
calendar.setTime(createTime);
setCreationTime(calendar);
}
/**
* {@inheritDoc}
*/
@Override
public Calendar getStartTime() {
long millis = (Long) this.resourceSpecificProperties.get(START_TIME);
return timestampStringToCalendar(millis);
}
/**
* {@inheritDoc}
*/
@Override
public void setStartTime(Calendar startTime) throws InvalidValueException {
setResourceSpecificProperty(START_TIME, startTime.getTimeInMillis());
}
/**
* {@inheritDoc}
*/
@Override
@Deprecated
public void setStartTime(Date startTime) throws InvalidValueException {
Calendar calendar = Calendar.getInstance();
calendar.setTime(startTime);
setStartTime(calendar);
}
/**
* {@inheritDoc}
*/
@Override
public Calendar getEndTime() {
long millis = (Long) this.resourceSpecificProperties.get(END_TIME);
return timestampStringToCalendar(millis);
}
/**
* {@inheritDoc}
*/
@Override
public void setEndTime(Calendar endTime) throws InvalidValueException {
setResourceSpecificProperty(END_TIME, endTime.getTimeInMillis());
}
/**
* {@inheritDoc}
*/
@Override
@Deprecated
public void setEndTime(Date endTime) throws InvalidValueException {
Calendar calendar = Calendar.getInstance();
calendar.setTime(endTime);
setEndTime(calendar);
}
/**
* {@inheritDoc}
*/
@Override
public String getUsageRecordType() {
return (String) this.resourceSpecificProperties.get(RESOURCE_TYPE);
}
/**
* {@inheritDoc}
*/
@Override
@Deprecated
public String getResourceType(){
return getUsageRecordType();
}
/**
* {@inheritDoc}
*/
@Deprecated
public void setResourceType(String resourceType){}
/**
* {@inheritDoc}
*/
@Override
public String getResourceScope() {
return (String) this.resourceSpecificProperties.get(RESOURCE_SCOPE);
}
/**
* {@inheritDoc}
*/
@Override
public void setResourceScope(String scope) throws InvalidValueException {
setResourceSpecificProperty(RESOURCE_SCOPE, scope);
}
/**
* {@inheritDoc}
*/
@Override
public String getResourceOwner() {
return (String) this.resourceSpecificProperties.get(RESOURCE_OWNER);
}
/**
* {@inheritDoc}
*/
@Override
public void setResourceOwner(String owner) throws InvalidValueException {
setResourceSpecificProperty(RESOURCE_OWNER, owner);
}
/**
* {@inheritDoc}
*/
@Override
public String getAggregatedId() {
return (String) this.resourceSpecificProperties.get(AGGREGATED_ID);
}
/**
* {@inheritDoc}
*/
@Override
public void setAggregatedId(String aggregatedId) throws InvalidValueException {
setResourceSpecificProperty(AGGREGATED_ID, aggregatedId);
}
/**
* {@inheritDoc}
*/
@Override
public Map<String, Serializable> getResourceSpecificProperties() {
return this.resourceSpecificProperties;
}
/**
* {@inheritDoc}
*/
@Override
public void setResourceSpecificProperties(Map<String, Serializable> properties) throws InvalidValueException {
validate(properties);
this.resourceSpecificProperties = new HashMap<String, Serializable>(properties);
}
/**
* {@inheritDoc}
*/
@Override
public Serializable getResourceSpecificProperty(String key) {
return this.resourceSpecificProperties.get(key);
}
/**
* {@inheritDoc}
*/
@Override
public void setResourceSpecificProperty(String key, Serializable value) throws InvalidValueException {
validateField(key, value);
this.resourceSpecificProperties.put(key, value);
}
protected void validateField(String key, Serializable serializable) throws InvalidValueException {
List<FieldValidator<? extends Annotation>> fieldValidators = validation.get(key);
if(fieldValidators!=null){
for(FieldValidator<? extends Annotation> fieldValidator : fieldValidators){
if(!fieldValidator.isValid(serializable)){
throw new InvalidValueException(fieldValidator.getErrorSuffix());
}
}
}
}
protected void validate(Map<String, Serializable> properties) throws InvalidValueException{
// TODO Change the behaviour. Get the list of validator and check the
// field in properties Map
for(String key : properties.keySet()){
Serializable serializable = properties.get(key);
validateField(key, serializable);
}
}
/**
* {@inheritDoc}
*/
@Override
public void validate() throws InvalidValueException{
validate(this.resourceSpecificProperties);
}
@Override
public String toString(){
/*
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("{");
boolean first = true;
for(String key : this.resourceSpecificProperties.keySet()){
if(!first){
stringBuilder.append(", \"");
}else {
stringBuilder.append("\"");
first = false;
}
stringBuilder.append(key);
stringBuilder.append("\":\"");
stringBuilder.append(this.resourceSpecificProperties.get(key));
stringBuilder.append("\"");
}
stringBuilder.append("}");
return stringBuilder.toString();
*/
return resourceSpecificProperties.toString();
}
/**
* {@inheritDoc}
*/
@Override
@Deprecated
public String getFullyQualifiedConsumerId() {
return getConsumerId();
}
/**
* {@inheritDoc}
*/
@Override
@Deprecated
public void setFullyQualifiedConsumerId(String fqcid) { }
/**
* Compare this UsageRecord instance with the one provided as argument
* @param usageRecord the Usage Record to compare
* @return 0 is and only if the UsageRecord provided as parameter
* contains all and ONLY the parameters contained in this instance.
* If the number of parameters differs, the methods return the difference
* between the number of parameter in this instance and the ones in the
* UsageRecord provided as parameter.
* If the size is the same but the UsageRecord provided as parameter does
* not contains all parameters in this instance, -1 is returned.
*/
@Override
public int compareTo(UsageRecord usageRecord) {
Set<Entry<String, Serializable>> thisSet = this.resourceSpecificProperties.entrySet();
Set<Entry<String, Serializable>> usageRecordSet = usageRecord.getResourceSpecificProperties().entrySet();
if(thisSet.size() != usageRecordSet.size()){
return thisSet.size() - usageRecordSet.size();
}
if(usageRecordSet.containsAll(thisSet)){
return 0;
}
return 1;
}
}