Validating instances
This commit is contained in:
parent
b276fecdc8
commit
03271c0e41
|
@ -46,6 +46,12 @@ import org.gcube.informationsystem.resourceregistry.types.TypesCache;
|
||||||
import org.gcube.informationsystem.resourceregistry.utils.HeaderOrient;
|
import org.gcube.informationsystem.resourceregistry.utils.HeaderOrient;
|
||||||
import org.gcube.informationsystem.resourceregistry.utils.HeaderUtility;
|
import org.gcube.informationsystem.resourceregistry.utils.HeaderUtility;
|
||||||
import org.gcube.informationsystem.resourceregistry.utils.Utility;
|
import org.gcube.informationsystem.resourceregistry.utils.Utility;
|
||||||
|
import org.gcube.informationsystem.types.PropertyTypeName;
|
||||||
|
import org.gcube.informationsystem.types.PropertyTypeName.BaseType;
|
||||||
|
import org.gcube.informationsystem.types.impl.properties.PropertyDefinitionImpl;
|
||||||
|
import org.gcube.informationsystem.types.reference.Type;
|
||||||
|
import org.gcube.informationsystem.types.reference.entities.FacetType;
|
||||||
|
import org.gcube.informationsystem.types.reference.properties.PropertyDefinition;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -453,8 +459,6 @@ public abstract class ElementManagement<El extends OElement> {
|
||||||
|
|
||||||
public abstract String reallyGetAll(boolean polymorphic) throws ResourceRegistryException;
|
public abstract String reallyGetAll(boolean polymorphic) throws ResourceRegistryException;
|
||||||
|
|
||||||
public abstract void sanityCheck() throws SchemaViolationException, ResourceRegistryException;
|
|
||||||
|
|
||||||
public String all(boolean polymorphic) throws ResourceRegistryException {
|
public String all(boolean polymorphic) throws ResourceRegistryException {
|
||||||
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
|
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
|
||||||
try {
|
try {
|
||||||
|
@ -1042,4 +1046,101 @@ public abstract class ElementManagement<El extends OElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getNotNullErrorMessage(String fieldName) {
|
||||||
|
StringBuffer stringBuffer = new StringBuffer();
|
||||||
|
stringBuffer.append("The type ");
|
||||||
|
stringBuffer.append(typeName);
|
||||||
|
stringBuffer.append(" defines the fields ");
|
||||||
|
stringBuffer.append(fieldName);
|
||||||
|
stringBuffer.append(" as not nullable. Null or no value has been provided instead.");
|
||||||
|
return stringBuffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getMandatoryErrorMessage(String fieldName) {
|
||||||
|
StringBuffer stringBuffer = new StringBuffer();
|
||||||
|
stringBuffer.append("The type ");
|
||||||
|
stringBuffer.append(typeName);
|
||||||
|
stringBuffer.append(" defines the fields ");
|
||||||
|
stringBuffer.append(fieldName);
|
||||||
|
stringBuffer.append(" as mandatory but no value has been provided.");
|
||||||
|
return stringBuffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get not only the properties defined in the type but also the properties
|
||||||
|
* defined in the super types
|
||||||
|
*/
|
||||||
|
protected Set<PropertyDefinition> getAllProperties() throws SchemaException, ResourceRegistryException{
|
||||||
|
TypesCache typesCache = TypesCache.getInstance();
|
||||||
|
CachedType cachedType = typesCache.getCachedType(typeName);
|
||||||
|
Type type = (FacetType) cachedType.getType();
|
||||||
|
|
||||||
|
Set<PropertyDefinition> definedProperties = type.getProperties();
|
||||||
|
|
||||||
|
Set<CachedType> cachedSuperTypes = new HashSet<>();
|
||||||
|
List<String> superTypes = cachedType.getSuperTypes();
|
||||||
|
for(String superTypeName : superTypes) {
|
||||||
|
CachedType cachedSuperType = typesCache.getCachedType(superTypeName);
|
||||||
|
cachedSuperTypes.add(cachedSuperType);
|
||||||
|
|
||||||
|
Type superType = cachedSuperType.getType();
|
||||||
|
definedProperties.addAll(superType.getProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
return definedProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sanityCheck() throws SchemaViolationException, ResourceRegistryException {
|
||||||
|
// OrientDB distributed mode does not support
|
||||||
|
// mandatory and notnull constraints due to technical problem
|
||||||
|
// https://www.orientdb.com/docs/last/java/Graph-Schema-Property.html#using-constraints
|
||||||
|
// Going to validate them here
|
||||||
|
|
||||||
|
JsonNode instances = createCompleteJsonNode();
|
||||||
|
|
||||||
|
Set<PropertyDefinition> definedProperties = getAllProperties();
|
||||||
|
|
||||||
|
|
||||||
|
for(PropertyDefinition propertyDefinition : definedProperties) {
|
||||||
|
String fieldName = propertyDefinition.getName();
|
||||||
|
|
||||||
|
if(propertyDefinition.isMandatory() && !instances.has(fieldName)) {
|
||||||
|
if(propertyDefinition.isNotnull()) {
|
||||||
|
// If the field is mandatory but null value is accepted I add the
|
||||||
|
// field as null value
|
||||||
|
element.setProperty(fieldName, null);
|
||||||
|
} else {
|
||||||
|
throw new SchemaViolationException(getMandatoryErrorMessage(fieldName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode jsonNode = instances.get(fieldName);
|
||||||
|
|
||||||
|
if(!propertyDefinition.isNotnull() && jsonNode==null) {
|
||||||
|
throw new SchemaViolationException(getNotNullErrorMessage(fieldName));
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyTypeName propertyTypeName = ((PropertyDefinitionImpl) propertyDefinition).getPropertyTypeName();
|
||||||
|
BaseType baseType = propertyTypeName.getBaseType();
|
||||||
|
switch (baseType) {
|
||||||
|
case PROPERTY:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIST: case SET: case MAP:
|
||||||
|
|
||||||
|
propertyTypeName.getGenericBaseType();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// leaving the rest of validation to OrientDB
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,6 +162,9 @@ public abstract class RelationElementManagement<SEM extends EntityElementManagem
|
||||||
OVertex source = (OVertex) getSourceEntityManagement().getElement();
|
OVertex source = (OVertex) getSourceEntityManagement().getElement();
|
||||||
OVertex target = (OVertex) getTargetEntityManagement().getElement();
|
OVertex target = (OVertex) getTargetEntityManagement().getElement();
|
||||||
|
|
||||||
|
// TODO check source and target type compatibility
|
||||||
|
|
||||||
|
|
||||||
logger.trace("Going to create {} beetween {} -> {}", typeName, source.toString(), target.toString());
|
logger.trace("Going to create {} beetween {} -> {}", typeName, source.toString(), target.toString());
|
||||||
|
|
||||||
element = oDatabaseDocument.newEdge(source, target, typeName);
|
element = oDatabaseDocument.newEdge(source, target, typeName);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package org.gcube.informationsystem.resourceregistry.instances.model.entities;
|
package org.gcube.informationsystem.resourceregistry.instances.model.entities;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
||||||
import org.gcube.informationsystem.base.reference.AccessType;
|
import org.gcube.informationsystem.base.reference.AccessType;
|
||||||
import org.gcube.informationsystem.model.reference.entities.Facet;
|
import org.gcube.informationsystem.model.reference.entities.Facet;
|
||||||
|
@ -10,11 +8,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegis
|
||||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetAlreadyPresentException;
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetAlreadyPresentException;
|
||||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetAvailableInAnotherContextException;
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetAvailableInAnotherContextException;
|
||||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetNotFoundException;
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetNotFoundException;
|
||||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaViolationException;
|
|
||||||
import org.gcube.informationsystem.resourceregistry.types.CachedType;
|
|
||||||
import org.gcube.informationsystem.resourceregistry.types.TypesCache;
|
|
||||||
import org.gcube.informationsystem.types.reference.entities.FacetType;
|
|
||||||
import org.gcube.informationsystem.types.reference.properties.PropertyDefinition;
|
|
||||||
|
|
||||||
import com.orientechnologies.orient.core.record.OVertex;
|
import com.orientechnologies.orient.core.record.OVertex;
|
||||||
|
|
||||||
|
@ -66,62 +59,4 @@ public class FacetManagement extends EntityManagement<Facet> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getNotNullErrorMessage(String fieldName) {
|
|
||||||
StringBuffer stringBuffer = new StringBuffer();
|
|
||||||
stringBuffer.append("The type ");
|
|
||||||
stringBuffer.append(typeName);
|
|
||||||
stringBuffer.append(" defines the fields ");
|
|
||||||
stringBuffer.append(fieldName);
|
|
||||||
stringBuffer.append(" as not nullable. Null or no value has been provided instead.");
|
|
||||||
return stringBuffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getMandatoryErrorMessage(String fieldName) {
|
|
||||||
StringBuffer stringBuffer = new StringBuffer();
|
|
||||||
stringBuffer.append("The type ");
|
|
||||||
stringBuffer.append(typeName);
|
|
||||||
stringBuffer.append(" defines the fields ");
|
|
||||||
stringBuffer.append(fieldName);
|
|
||||||
stringBuffer.append(" as mandatory but no value has been provided.");
|
|
||||||
return stringBuffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sanityCheck() throws SchemaViolationException, ResourceRegistryException {
|
|
||||||
// OrientDB distributed mode does not support
|
|
||||||
// mandatory and notnull constraints due to technical problem
|
|
||||||
// https://www.orientdb.com/docs/last/java/Graph-Schema-Property.html#using-constraints
|
|
||||||
// Going to validate them here
|
|
||||||
|
|
||||||
JsonNode facetInstance = createCompleteJsonNode();
|
|
||||||
|
|
||||||
TypesCache typesCache = TypesCache.getInstance();
|
|
||||||
CachedType cachedType = typesCache.getCachedType(typeName);
|
|
||||||
FacetType facetType = (FacetType) cachedType.getType();
|
|
||||||
Set<PropertyDefinition> definedProperties = facetType.getProperties();
|
|
||||||
for(PropertyDefinition propertyDefinition : definedProperties) {
|
|
||||||
String fieldName = propertyDefinition.getName();
|
|
||||||
|
|
||||||
if(propertyDefinition.isMandatory() && !facetInstance.has(fieldName)) {
|
|
||||||
if(propertyDefinition.isNotnull()) {
|
|
||||||
// If the field is mandatory but null value is accepted I add the
|
|
||||||
// field as null value
|
|
||||||
element.setProperty(fieldName, null);
|
|
||||||
} else {
|
|
||||||
throw new SchemaViolationException(getMandatoryErrorMessage(fieldName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonNode jsonNode = facetInstance.get(fieldName);
|
|
||||||
|
|
||||||
if(!propertyDefinition.isNotnull() && jsonNode==null) {
|
|
||||||
throw new SchemaViolationException(getNotNullErrorMessage(fieldName));
|
|
||||||
}
|
|
||||||
|
|
||||||
// leaving the rest of validation to OrientDB
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -399,6 +399,11 @@ public class ResourceManagement extends EntityManagement<Resource> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default sanity check is not valid for resources which do not have properties
|
||||||
|
* and instead must be validated in terms of facets.
|
||||||
|
* The Resource Header is managed with dedicated code for all instaces.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void sanityCheck() throws SchemaViolationException, ResourceRegistryException {
|
public void sanityCheck() throws SchemaViolationException, ResourceRegistryException {
|
||||||
JsonNode resourceInstance = createCompleteJsonNode();
|
JsonNode resourceInstance = createCompleteJsonNode();
|
||||||
|
|
|
@ -197,7 +197,7 @@ public class CachedType {
|
||||||
return accessType;
|
return accessType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> internaGetSuperTypes() throws SchemaException, ResourceRegistryException {
|
private List<String> internalGetSuperTypes() throws SchemaException, ResourceRegistryException {
|
||||||
if(superTypes==null) {
|
if(superTypes==null) {
|
||||||
superTypes = getAllSuperclasses(superClassesToBeExcluded);
|
superTypes = getAllSuperclasses(superClassesToBeExcluded);
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ public class CachedType {
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized List<String> getSuperTypes() throws SchemaException, ResourceRegistryException {
|
public synchronized List<String> getSuperTypes() throws SchemaException, ResourceRegistryException {
|
||||||
return internaGetSuperTypes();
|
return internalGetSuperTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized List<String> getSubTypes() throws SchemaException, ResourceRegistryException {
|
public synchronized List<String> getSubTypes() throws SchemaException, ResourceRegistryException {
|
||||||
|
|
Loading…
Reference in New Issue