From a518f982354368a9dce92085c48f6c83a5430d18 Mon Sep 17 00:00:00 2001 From: Luca Frosini Date: Thu, 11 Feb 2021 14:35:54 +0100 Subject: [PATCH] Refactoring code to simplify type management and to have a better support for types cache. --- .../dbinitialization/SchemaActionImpl.java | 42 ++---- .../instances/base/ElementManagement.java | 12 +- .../base/ElementManagementUtility.java | 2 +- .../properties/PropertyElementManagement.java | 12 +- .../model/entities/EntityManagement.java | 5 +- .../resourceregistry/rest/SchemaManager.java | 32 +--- .../resourceregistry/types/CachedType.java | 134 +++++++++++++++++ .../types/SchemaManagement.java | 94 ++++++------ .../resourceregistry/types/TypesCache.java | 141 ++---------------- .../types/SchemaManagementImplTest.java | 140 +++++------------ 10 files changed, 266 insertions(+), 348 deletions(-) create mode 100644 src/main/java/org/gcube/informationsystem/resourceregistry/types/CachedType.java diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SchemaActionImpl.java b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SchemaActionImpl.java index 006d7e6..e8d9ed6 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SchemaActionImpl.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SchemaActionImpl.java @@ -1,15 +1,10 @@ package org.gcube.informationsystem.resourceregistry.dbinitialization; -import org.gcube.informationsystem.base.reference.AccessType; import org.gcube.informationsystem.base.reference.entities.EntityElement; import org.gcube.informationsystem.base.reference.properties.PropertyElement; import org.gcube.informationsystem.base.reference.relations.RelationElement; -import org.gcube.informationsystem.model.reference.entities.Facet; -import org.gcube.informationsystem.model.reference.entities.Resource; import org.gcube.informationsystem.model.reference.properties.Header; import org.gcube.informationsystem.model.reference.properties.Property; -import org.gcube.informationsystem.model.reference.relations.ConsistsOf; -import org.gcube.informationsystem.model.reference.relations.IsRelatedTo; import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaAlreadyPresentException; import org.gcube.informationsystem.resourceregistry.types.SchemaManagement; import org.gcube.informationsystem.types.TypeMapper; @@ -29,16 +24,8 @@ public class SchemaActionImpl implements SchemaAction { throws Exception { try { SchemaManagement schemaManagement = new SchemaManagement(); - schemaManagement.setTypeName(TypeMapper.getType(r)); - String json = TypeMapper.serializeType(r); - logger.trace(json); - if(ConsistsOf.class.isAssignableFrom(r)) { - schemaManagement.create(json, AccessType.CONSISTS_OF); - } else if(IsRelatedTo.class.isAssignableFrom(r)) { - schemaManagement.create(json, AccessType.IS_RELATED_TO); - } else { - schemaManagement.create(json, AccessType.RELATION_ELEMENT); - } + schemaManagement.setTypeAndTypeName(r); + schemaManagement.create(); } catch(SchemaAlreadyPresentException sape) { logger.warn("{} already exists. It will be ignored", TypeMapper.getType(r)); } catch(Exception ex) { @@ -51,16 +38,8 @@ public class SchemaActionImpl implements SchemaAction { public void manageEntityClass(Class e) throws Exception { try { SchemaManagement schemaManagement = new SchemaManagement(); - schemaManagement.setTypeName(TypeMapper.getType(e)); - String json = TypeMapper.serializeType(e); - logger.trace(json); - if(Facet.class.isAssignableFrom(e)) { - schemaManagement.create(json, AccessType.FACET); - } else if(Resource.class.isAssignableFrom(e)) { - schemaManagement.create(json, AccessType.RESOURCE); - } else { - schemaManagement.create(json, AccessType.ENTITY_ELEMENT); - } + schemaManagement.setTypeAndTypeName(e); + schemaManagement.create(); } catch(SchemaAlreadyPresentException sape) { logger.warn("{} already exists. It will be ignored", TypeMapper.getType(e)); } catch(Exception ex) { @@ -73,17 +52,14 @@ public class SchemaActionImpl implements SchemaAction { public

void managePropertyClass(Class

p) throws Exception { try { SchemaManagement schemaManagement = new SchemaManagement(); + schemaManagement.setTypeAndTypeName(p); + if(p.equals(Property.class) || p.equals(Header.class) ) { + ((SchemaManagement) schemaManagement).setSkipTypeDefinitionCreation(true); + } + schemaManagement.create(); schemaManagement.setTypeName(TypeMapper.getType(p)); String json = TypeMapper.serializeType(p); logger.trace(json); - if(Property.class.isAssignableFrom(p)) { - if(p.equals(Property.class) || p.equals(Header.class) ) { - ((SchemaManagement) schemaManagement).setSkipTypeDefinitionCreation(true); - } - schemaManagement.create(json, AccessType.PROPERTY); - }else { - schemaManagement.create(json, AccessType.PROPERTY_ELEMENT); - } } catch(SchemaAlreadyPresentException sape) { logger.warn("{} already exists. It will be ignored", TypeMapper.getType(p)); } catch(Exception ex) { diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java index a9d7361..5a188d4 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java @@ -40,6 +40,7 @@ import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityCo import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode; import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseEnvironment; import org.gcube.informationsystem.resourceregistry.instances.base.properties.PropertyElementManagement; +import org.gcube.informationsystem.resourceregistry.types.CachedType; import org.gcube.informationsystem.resourceregistry.types.TypesCache; import org.gcube.informationsystem.resourceregistry.utils.HeaderOrient; import org.gcube.informationsystem.resourceregistry.utils.HeaderUtility; @@ -149,18 +150,16 @@ public abstract class ElementManagement { checkJsonNode(); } - public void setJson(String jsonRepresentation) throws ResourceRegistryException { + public void setJson(String json) throws ResourceRegistryException { ObjectMapper mapper = new ObjectMapper(); try { - this.jsonNode = mapper.readTree(jsonRepresentation); + this.jsonNode = mapper.readTree(json); } catch(IOException e) { throw new ResourceRegistryException(e); } checkJsonNode(); } - - public void setoDatabaseDocument(ODatabaseDocument oDatabaseDocument) { this.oDatabaseDocument = oDatabaseDocument; } @@ -175,8 +174,9 @@ public abstract class ElementManagement { oClass = ElementManagementUtility.getOClass(element); } else { TypesCache typesCache = TypesCache.getInstance(); - oClass = TypesCache.getInstance().getTypeOClass(elementType); - AccessType gotAccessType = typesCache.getBaseAccessType(elementType); + CachedType cachedType = typesCache.getType(elementType); + oClass = cachedType.getOClass(); + AccessType gotAccessType = cachedType.getAccessType(); if(accessType!=gotAccessType) { throw new SchemaException(elementType + " is not a " + accessType.getName()); } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagementUtility.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagementUtility.java index 5ad2d65..7b12141 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagementUtility.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagementUtility.java @@ -40,7 +40,7 @@ public class ElementManagementUtility { @SuppressWarnings("rawtypes") public static ElementManagement getERManagement(String type) throws ResourceRegistryException { - AccessType accessType = TypesCache.getInstance().getBaseAccessType(type); + AccessType accessType = TypesCache.getInstance().getType(type).getAccessType(); ElementManagement erManagement = null; diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/properties/PropertyElementManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/properties/PropertyElementManagement.java index b9b79ec..fd55875 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/properties/PropertyElementManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/properties/PropertyElementManagement.java @@ -18,6 +18,7 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.Schema import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException; import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseEnvironment; import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagement; +import org.gcube.informationsystem.resourceregistry.types.CachedType; import org.gcube.informationsystem.resourceregistry.types.TypesCache; import org.gcube.informationsystem.resourceregistry.utils.EncryptedOrient; import org.gcube.informationsystem.resourceregistry.utils.HeaderUtility; @@ -55,8 +56,9 @@ public class PropertyElementManagement { try { TypesCache typesCache = TypesCache.getInstance(); - oClass = typesCache.getTypeOClass(type); - AccessType gotAccessType = typesCache.getBaseAccessType(type); + CachedType cachedType = typesCache.getType(type); + oClass = cachedType.getOClass(); + AccessType gotAccessType = cachedType.getAccessType(); if(AccessType.PROPERTY_ELEMENT!=gotAccessType) { throw new SchemaException(type + " is not a " + AccessType.PROPERTY_ELEMENT.getName()); } @@ -127,9 +129,11 @@ public class PropertyElementManagement { if(type==null) { return jsonNode; } + TypesCache typesCache = TypesCache.getInstance(); - OClass oClass = typesCache.getTypeOClass(type); - AccessType gotAccessType = typesCache.getBaseAccessType(type); + CachedType cachedType = typesCache.getType(type); + OClass oClass = cachedType.getOClass(); + AccessType gotAccessType = cachedType.getAccessType(); if(AccessType.PROPERTY_ELEMENT!=gotAccessType) { throw new SchemaException(type + " is not a " + AccessType.PROPERTY_ELEMENT.getName()); } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java index 6eff640..9862eaf 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java @@ -779,13 +779,14 @@ public abstract class EntityManagement extends EntityElementMa try { oDatabaseDocument = getWorkingContext().getDatabaseDocument(PermissionMode.READER); - AccessType relationAccessType = TypesCache.getInstance().getBaseAccessType(relationType); + TypesCache typesCache = TypesCache.getInstance(); + AccessType relationAccessType = typesCache.getType(relationType).getAccessType(); if(relationAccessType != AccessType.IS_RELATED_TO && relationAccessType != AccessType.CONSISTS_OF) { String error = String.format("%s must be a relation type", relationType); throw new ResourceRegistryException(error); } - AccessType referenceAccessType = TypesCache.getInstance().getBaseAccessType(referenceType); + AccessType referenceAccessType = typesCache.getType(referenceType).getAccessType(); if(referenceAccessType != AccessType.RESOURCE && referenceAccessType != AccessType.FACET) { String error = String.format("%s must be a en entity type", referenceType); throw new ResourceRegistryException(error); diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/rest/SchemaManager.java b/src/main/java/org/gcube/informationsystem/resourceregistry/rest/SchemaManager.java index 19c9ec1..724ed49 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/rest/SchemaManager.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/rest/SchemaManager.java @@ -1,7 +1,5 @@ package org.gcube.informationsystem.resourceregistry.rest; -import java.util.Set; - import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; @@ -15,7 +13,6 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.gcube.common.authorization.library.provider.CalledMethodProvider; -import org.gcube.informationsystem.base.reference.AccessType; import org.gcube.informationsystem.resourceregistry.ResourceInitializer; import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaException; @@ -23,8 +20,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.Schema import org.gcube.informationsystem.resourceregistry.api.rest.AccessPath; import org.gcube.informationsystem.resourceregistry.api.rest.TypePath; import org.gcube.informationsystem.resourceregistry.types.SchemaManagement; -import org.gcube.informationsystem.resourceregistry.types.TypesCache; -import org.gcube.informationsystem.types.TypeMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,33 +62,16 @@ public class SchemaManager { @Path("{" + AccessPath.TYPE_PATH_PARAM + "}") @Consumes({MediaType.TEXT_PLAIN, ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8}) @Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8) - public Response create(@PathParam(AccessPath.TYPE_PATH_PARAM) String type, String json) + public Response create(@PathParam(AccessPath.TYPE_PATH_PARAM) String typeName, String json) throws SchemaException, ResourceRegistryException { - logger.info("Requested {} creation with schema {}", type, json); + logger.info("Requested {} creation with schema {}", typeName, json); // setRESTCalledMethod(HTTPMETHOD.PUT, type); CalledMethodProvider.instance.set("createType"); - AccessType accessType = null; - String firstGotType = null; - try { - Set superClasses = TypeMapper.deserializeTypeDefinition(json).getSuperClasses(); - if(superClasses.size()==0) { - throw new ResourceRegistryException("No superclasses defined"); - } - for(String superClass : superClasses) { - accessType = TypesCache.getInstance().getBaseAccessType(superClass); - break; - } - } catch (ResourceRegistryException e) { - throw e; - } catch(Exception e) { - String error = String.format("Cannot register %s schema. Superclass %s not found", type, firstGotType); - throw new ResourceRegistryException(error); - } - SchemaManagement schemaManagement = new SchemaManagement(); - schemaManagement.setTypeName(type); - String ret = schemaManagement.create(json, accessType); + schemaManagement.setTypeName(typeName); + schemaManagement.setJson(json); + String ret = schemaManagement.create(); return Response.status(Status.CREATED).entity(ret).type(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8) .build(); } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/types/CachedType.java b/src/main/java/org/gcube/informationsystem/resourceregistry/types/CachedType.java new file mode 100644 index 0000000..8839db1 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/types/CachedType.java @@ -0,0 +1,134 @@ +package org.gcube.informationsystem.resourceregistry.types; + +import java.util.Set; + +import org.gcube.informationsystem.base.reference.AccessType; +import org.gcube.informationsystem.model.reference.entities.Facet; +import org.gcube.informationsystem.model.reference.entities.Resource; +import org.gcube.informationsystem.model.reference.properties.Property; +import org.gcube.informationsystem.model.reference.relations.ConsistsOf; +import org.gcube.informationsystem.model.reference.relations.IsRelatedTo; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaException; +import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException; +import org.gcube.informationsystem.resourceregistry.contexts.ContextUtility; +import org.gcube.informationsystem.resourceregistry.contexts.security.AdminSecurityContext; +import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode; +import org.gcube.informationsystem.types.reference.Type; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.orientechnologies.orient.core.db.document.ODatabaseDocument; +import com.orientechnologies.orient.core.metadata.OMetadata; +import com.orientechnologies.orient.core.metadata.schema.OClass; +import com.orientechnologies.orient.core.metadata.schema.OSchema; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +public class CachedType { + + private static Logger logger = LoggerFactory.getLogger(CachedType.class); + + protected final String typeName; + + protected OClass oClass; + + protected AccessType accessType; + + protected Type type; + protected Set superTypes; + protected Set specilisationTypes; + + + public CachedType(String typeName) { + this.typeName = typeName; + } + + private OClass retrieveOClass() throws SchemaException, SchemaNotFoundException, ResourceRegistryException { + ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); + ODatabaseDocument oDatabaseDocument = null; + try { + logger.debug("GettingType {} schema", type); + AdminSecurityContext adminSecurityContext = ContextUtility.getAdminSecurityContext(); + oDatabaseDocument = adminSecurityContext.getDatabaseDocument(PermissionMode.READER); + OMetadata oMetadata = oDatabaseDocument.getMetadata(); + OSchema oSchema = oMetadata.getSchema(); + try { + OClass oClass = oSchema.getClass(typeName); + if(oClass == null) { + throw new SchemaNotFoundException(typeName + " was not registered"); + } + return oClass; + } catch(SchemaNotFoundException snfe) { + throw snfe; + } catch(Exception e) { + throw new SchemaException(e.getMessage()); + } + } catch(ResourceRegistryException e) { + throw e; + } catch(Exception e) { + throw new ResourceRegistryException(e); + } finally { + if(oDatabaseDocument != null) { + oDatabaseDocument.close(); + } + + if(current!=null) { + current.activateOnCurrentThread(); + } + } + + + } + + public synchronized OClass getOClass() throws SchemaNotFoundException, SchemaException, ResourceRegistryException { + if(oClass==null) { + oClass = retrieveOClass(); + } + return oClass; + } + + + private AccessType getAccessTypeFromOClass(OClass oClass) throws ResourceRegistryException { + if(oClass.isSubClassOf(Resource.NAME)) { + return AccessType.RESOURCE; + } else if(oClass.isSubClassOf(Facet.NAME)) { + return AccessType.FACET; + } else if(oClass.isSubClassOf(ConsistsOf.NAME)) { + return AccessType.CONSISTS_OF; + } else if(oClass.isSubClassOf(IsRelatedTo.NAME)) { + return AccessType.IS_RELATED_TO; + } else if(oClass.isSubClassOf(Property.NAME)) { + return AccessType.PROPERTY; + }else { + throw new ResourceRegistryException(typeName + " is not a base type"); + } + } + + + public synchronized AccessType getAccessType() throws SchemaNotFoundException, SchemaException, ResourceRegistryException { + if(accessType==null) { + if(type!=null) { + accessType = type.getAccessType(); + }else { + accessType = getAccessTypeFromOClass(getOClass()); + } + } + return accessType; + } + + public Type getType() { + return type; + } + + public synchronized Set getSuperTypes() { + return superTypes; + } + + public synchronized Set getSpecilisationTypes() { + return specilisationTypes; + } + + +} diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/types/SchemaManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/types/SchemaManagement.java index e7b30a7..36ac893 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/types/SchemaManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/types/SchemaManagement.java @@ -14,6 +14,7 @@ import java.util.Set; import javax.activation.UnsupportedDataTypeException; import org.gcube.informationsystem.base.reference.AccessType; +import org.gcube.informationsystem.base.reference.Element; import org.gcube.informationsystem.base.reference.IdentifiableElement; import org.gcube.informationsystem.base.reference.entities.EntityElement; import org.gcube.informationsystem.base.reference.properties.PropertyElement; @@ -25,6 +26,7 @@ import org.gcube.informationsystem.model.reference.properties.Property; import org.gcube.informationsystem.model.reference.relations.ConsistsOf; import org.gcube.informationsystem.model.reference.relations.IsRelatedTo; import org.gcube.informationsystem.model.reference.relations.Relation; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaAlreadyPresentException; import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaCreationException; import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaException; @@ -71,6 +73,8 @@ public class SchemaManagement { private static Logger logger = LoggerFactory.getLogger(SchemaManagement.class); protected String typeName; + protected String json; + protected Type type; protected boolean skipVersionCheckOnUpdate; @@ -92,6 +96,15 @@ public class SchemaManagement { this.skipTypeDefinitionCreation = skipTypeDefinitionCreation; } + public void setJson(String json) throws ResourceRegistryException { + this.json = json; + try { + this.type = TypeMapper.deserializeTypeDefinition(json); + }catch (Exception e) { + logger.error("Unable to create type definition from provided json {}", json); + throw new SchemaCreationException("Unable to create type definition from provided json" + json, e); + } + } public SchemaManagement() { this.skipTypeDefinitionCreation = false; @@ -106,6 +119,11 @@ public class SchemaManagement { this.typeName = typeName; } + public void setTypeAndTypeName(Class clz) { + this.type = TypeMapper.createTypeDefinition(clz); + this.typeName = type.getName(); + } + /* private static TypeDefinition getOClassTypeDefinition(OClass oClass) throws SchemaException { try { @@ -313,7 +331,7 @@ public class SchemaManagement { typeList.add(ConsistsOfType.NAME); } - protected void registerTypeSchema(Type type, AccessType baseElementAccessType) + protected void registerTypeSchema(Type type) throws SchemaAlreadyPresentException, SchemaException { ODatabaseDocument oDatabaseDocument = null; @@ -334,11 +352,13 @@ public class SchemaManagement { OClass oClass = null; - if(EntityElement.class.isAssignableFrom(baseElementAccessType.getTypeClass())) { + AccessType accessType = type.getAccessType(); + + if(EntityElement.class.isAssignableFrom(accessType.getTypeClass())) { oClass = oDatabaseDocument.createVertexClass(type.getName()); - } else if(RelationElement.class.isAssignableFrom(baseElementAccessType.getTypeClass())) { + } else if(RelationElement.class.isAssignableFrom(accessType.getTypeClass())) { oClass = oDatabaseDocument.createEdgeClass(type.getName()); - } else if(PropertyElement.class.isAssignableFrom(baseElementAccessType.getTypeClass())) { + } else if(PropertyElement.class.isAssignableFrom(accessType.getTypeClass())) { oClass = oSchema.createClass(type.getName()); } else { String error = String.format("Allowed superclass are %s, %s, %s, or any subclasses of them.", @@ -370,7 +390,7 @@ public class SchemaManagement { if(!baseElementTypes.contains(type.getName())) { List oSuperclasses = getSuperclassesAndCheckCompliancy(oDatabaseDocument, type, - baseElementAccessType.getName()); + accessType.getName()); oClass.setSuperClasses(oSuperclasses); } @@ -451,7 +471,7 @@ public class SchemaManagement { oDatabaseDocument.commit(); - logger.info("{} {} registered successfully", baseElementAccessType.getName(), type.getName()); + logger.info("{} {} registered successfully", accessType.getName(), type.getName()); } catch(Exception e) { oSchema.dropClass(type.getName()); throw e; @@ -714,23 +734,16 @@ public class SchemaManagement { } } - public String create(String jsonSchema, AccessType accessType) throws SchemaAlreadyPresentException, SchemaException { - Type typeDefinition = null; + public String create() throws SchemaAlreadyPresentException, SchemaException { try { - try { - typeDefinition = TypeMapper.deserializeTypeDefinition(jsonSchema); - logger.info("Trying to register {} {} : {}", accessType.getName(), typeDefinition.getName(), - jsonSchema); - } catch(Exception e) { - logger.error("Error while trying to register {} {}", accessType.getName(), jsonSchema); - throw new SchemaCreationException(e); - } + AccessType accessType = type.getAccessType(); + logger.info("Trying to register {} {} : {}", accessType.getName(), type.getName(), json); - registerTypeSchema(typeDefinition, accessType); + registerTypeSchema(type); ElementManagement erManagement = null; - switch(accessType) { + switch(type.getAccessType()) { case PROPERTY: erManagement = new PropertyTypeDefinitionManagement(); break; @@ -747,16 +760,15 @@ public class SchemaManagement { erManagement = new ConsistsOfTypeDefinitionManagement(); break; default: - break; + return json; } - String ret = null; - if(erManagement!=null && !skipTypeDefinitionCreation) { - erManagement.setJson(jsonSchema); + String ret = json; + if(!skipTypeDefinitionCreation) { + erManagement.setJson(json); ret = erManagement.create(); - }else { - ret = TypeMapper.serializeTypeDefinition(typeDefinition); } + return ret; } catch(SchemaAlreadyPresentException e) { throw e; @@ -780,24 +792,17 @@ public class SchemaManagement { return true; } - public String update(String jsonSchema, AccessType accessType) + public String update() throws SchemaNotFoundException, SchemaException { try { - Type newTypeDefinition = null; - try { - newTypeDefinition = TypeMapper.deserializeTypeDefinition(jsonSchema); - logger.info("Trying to update {} {} : {}", accessType.getName(), newTypeDefinition.getName(), - jsonSchema); - } catch(Exception e) { - logger.error("Error while trying to deserialise provided type definition {}", jsonSchema); - throw new SchemaCreationException(e); - } + AccessType accessType = type.getAccessType(); + logger.info("Trying to update {} {} : {}", accessType.getName(), type.getName(), json); - if(typeName.compareTo(newTypeDefinition.getName()) != 0) { + if(typeName.compareTo(type.getName()) != 0) { String error = String.format( "Provided type name path argument %s does not match with the type name in the definition %S. Please be coherent.", - typeName, newTypeDefinition.getName()); + typeName, type.getName()); throw new SchemaCreationException(error); } @@ -805,26 +810,25 @@ public class SchemaManagement { throw new SchemaException(typeName + " is a base type. Cannot update the definition of base types."); } - ElementManagement erManagement = getTypeManagement(accessType, newTypeDefinition.getName()); + ElementManagement erManagement = getTypeManagement(accessType, type.getName()); Type actualTypeDefinition = getType(erManagement); if(!skipVersionCheckOnUpdate) { - if(newTypeDefinition.getVersion().compareTo(actualTypeDefinition.getVersion())<=0) { - throw new SchemaAlreadyPresentException("The type " + newTypeDefinition.getName() + + if(type.getVersion().compareTo(actualTypeDefinition.getVersion())<=0) { + throw new SchemaAlreadyPresentException("The type " + type.getName() + " exists and the existing version (.i.e " + actualTypeDefinition.getVersion().toString() + - ") is greater of equal to the one provided for update (i.e. " + newTypeDefinition.getVersion() + ")"); + ") is greater of equal to the one provided for update (i.e. " + type.getVersion() + ")"); } } - updateTypeSchema(actualTypeDefinition, newTypeDefinition, accessType); + updateTypeSchema(actualTypeDefinition, type, accessType); - String ret = null; + String ret = json; if(erManagement!=null) { - erManagement.setJson(jsonSchema); + erManagement.setJson(json); ret = erManagement.update(); - }else { - ret = TypeMapper.serializeTypeDefinition(newTypeDefinition); } + return ret; } catch(SchemaException e) { throw e; diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/types/TypesCache.java b/src/main/java/org/gcube/informationsystem/resourceregistry/types/TypesCache.java index 001bc47..5c718c1 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/types/TypesCache.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/types/TypesCache.java @@ -1,30 +1,14 @@ package org.gcube.informationsystem.resourceregistry.types; import java.util.HashMap; -import java.util.List; import java.util.Map; -import org.gcube.informationsystem.base.reference.AccessType; -import org.gcube.informationsystem.model.reference.entities.Facet; -import org.gcube.informationsystem.model.reference.entities.Resource; -import org.gcube.informationsystem.model.reference.properties.Property; -import org.gcube.informationsystem.model.reference.relations.ConsistsOf; -import org.gcube.informationsystem.model.reference.relations.IsRelatedTo; -import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; -import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaException; -import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException; -import org.gcube.informationsystem.resourceregistry.contexts.ContextUtility; -import org.gcube.informationsystem.resourceregistry.contexts.security.AdminSecurityContext; -import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode; -import org.gcube.informationsystem.types.reference.Type; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.orientechnologies.orient.core.db.document.ODatabaseDocument; -import com.orientechnologies.orient.core.metadata.OMetadata; -import com.orientechnologies.orient.core.metadata.schema.OClass; -import com.orientechnologies.orient.core.metadata.schema.OSchema; - +/** + * @author Luca Frosini (ISTI - CNR) + */ public class TypesCache { private static Logger logger = LoggerFactory.getLogger(TypesCache.class); @@ -38,117 +22,20 @@ public class TypesCache { return typesCache; } - protected final Map oClasses; - protected final Map accessTypes; - protected final Map types; - protected final Map> superTypes; - protected final Map> specilisationTypes; - + protected final Map cachedTypes; private TypesCache() { - oClasses = new HashMap<>(); - accessTypes = new HashMap<>(); - types = new HashMap<>(); - superTypes = new HashMap<>(); - specilisationTypes = new HashMap<>(); + cachedTypes = new HashMap<>(); } - - public synchronized AccessType getBaseAccessType(String type) throws ResourceRegistryException { - AccessType accessType = accessTypes.get(type); - if(accessType==null) { - - OClass oClass = getTypeOClass(type); - - if(oClass.isSubClassOf(Resource.NAME)) { - accessType = AccessType.RESOURCE; - } else if(oClass.isSubClassOf(Facet.NAME)) { - accessType = AccessType.FACET; - } else if(oClass.isSubClassOf(ConsistsOf.NAME)) { - accessType = AccessType.CONSISTS_OF; - } else if(oClass.isSubClassOf(IsRelatedTo.NAME)) { - accessType = AccessType.IS_RELATED_TO; - } else if(oClass.isSubClassOf(Property.NAME)) { - accessType = AccessType.PROPERTY; - }else { - throw new ResourceRegistryException(type + "is not a base type"); - } - - accessTypes.put(type, accessType); - } - return accessType; - } - - /* - public void checkAccessType(OClass oClass, String type, AccessType accessType) throws SchemaException { - if(accessType != null && type.compareTo(accessType.getName()) != 0) { - if(!oClass.isSubClassOf(accessType.getName())) { - throw new SchemaException(type + " is not a " + accessType.getName()); - } - } - } - */ - - private OClass getTypeOClass(OSchema oSchema, String type) - throws SchemaException, SchemaNotFoundException { - try { - OClass oClass= oClasses.get(type); - if(oClass==null) { - oClass = oSchema.getClass(type); - if(oClass == null) { - throw new SchemaNotFoundException(type + " was not registered"); - } - oClasses.put(type, oClass); - } - return oClass; - } catch(SchemaNotFoundException snfe) { - throw snfe; - } catch(Exception e) { - throw new SchemaException(e.getMessage()); - } - } - - public synchronized OClass getTypeOClass(ODatabaseDocument oDatabaseDocument, String type) - throws SchemaException, SchemaNotFoundException { - - synchronized (oClasses) { - OClass oClass = oClasses.get(type); - if(oClass!=null) { - return oClass; - } - } - - OMetadata oMetadata = oDatabaseDocument.getMetadata(); - OSchema oSchema = oMetadata.getSchema(); - return getTypeOClass(oSchema, type); - } - - public synchronized OClass getTypeOClass(String type) - throws SchemaException, ResourceRegistryException { - - OClass oClass = oClasses.get(type); - if(oClass!=null) { - return oClass; - } - - ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); - ODatabaseDocument oDatabaseDocument = null; - try { - logger.debug("GettingType {} schema", type); - AdminSecurityContext adminSecurityContext = ContextUtility.getAdminSecurityContext(); - oDatabaseDocument = adminSecurityContext.getDatabaseDocument(PermissionMode.READER); - return getTypeOClass(oDatabaseDocument, type); - } catch(ResourceRegistryException e) { - throw e; - } catch(Exception e) { - throw new ResourceRegistryException(e); - } finally { - if(oDatabaseDocument != null) { - oDatabaseDocument.close(); - } - - if(current!=null) { - current.activateOnCurrentThread(); - } + + public CachedType getType(String typeName) { + CachedType cachedType = cachedTypes.get(typeName); + if(cachedType == null ) { + logger.trace("{} not in cache. Going to create {} instance", typeName, CachedType.class.getSimpleName()); + cachedType = new CachedType(typeName); + cachedTypes.put(typeName, cachedType); } + return cachedType; } + } diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/types/SchemaManagementImplTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/types/SchemaManagementImplTest.java index 25f7f53..48e475f 100644 --- a/src/test/java/org/gcube/informationsystem/resourceregistry/types/SchemaManagementImplTest.java +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/types/SchemaManagementImplTest.java @@ -24,14 +24,8 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.Schema import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaException; import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException; import org.gcube.informationsystem.types.TypeMapper; -import org.gcube.informationsystem.types.impl.entities.EntityTypeImpl; -import org.gcube.informationsystem.types.impl.properties.PropertyTypeImpl; -import org.gcube.informationsystem.types.impl.relations.RelationTypeImpl; import org.gcube.informationsystem.types.reference.Type; -import org.gcube.informationsystem.types.reference.entities.EntityType; -import org.gcube.informationsystem.types.reference.properties.PropertyType; import org.gcube.informationsystem.types.reference.relations.RelationType; -import org.gcube.informationsystem.utils.ElementMapper; import org.gcube.informationsystem.utils.TypeVersion; import org.gcube.resourcemanagement.model.reference.entities.facets.AccessPointFacet; import org.gcube.resourcemanagement.model.reference.entities.facets.ContactFacet; @@ -40,7 +34,9 @@ import org.gcube.resourcemanagement.model.reference.entities.resources.EService; import org.gcube.resourcemanagement.model.reference.entities.resources.RunningPlugin; import org.gcube.resourcemanagement.model.reference.entities.resources.Service; import org.gcube.resourcemanagement.model.reference.properties.ValueSchema; +import org.gcube.resourcemanagement.model.reference.relations.consistsof.HasVolatileMemory; import org.gcube.resourcemanagement.model.reference.relations.isrelatedto.Hosts; +import org.gcube.resourcemanagement.model.reference.relations.isrelatedto.Uses; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; @@ -215,117 +211,64 @@ public class SchemaManagementImplTest extends ContextTest { } + + protected String create(Class clz) throws SchemaAlreadyPresentException, SchemaException { + SchemaManagement schemaManagement = new SchemaManagement(); + schemaManagement.setTypeAndTypeName(clz); + String ret = schemaManagement.create(); + logger.debug(ret); + return ret; + } + + protected String update(Class clz, boolean skipVersionCheckOnUpdate) throws SchemaAlreadyPresentException, SchemaException, SchemaNotFoundException { + SchemaManagement schemaManagement = new SchemaManagement(); + schemaManagement.setTypeAndTypeName(clz); + schemaManagement.setSkipVersionCheckOnUpdate(skipVersionCheckOnUpdate); + String ret = schemaManagement.update(); + logger.debug(ret); + return ret; + } + @Test(expected=SchemaAlreadyPresentException.class) public void createPropertyType() throws Exception { - PropertyType propertyTypeDefinition = new PropertyTypeImpl<>(ValueSchema.class); - - SchemaManagement schemaManagement = new SchemaManagement(); - ((SchemaManagement) schemaManagement).setTypeName(ValueSchema.NAME); - String ret = schemaManagement.create(ElementMapper.marshal(propertyTypeDefinition), AccessType.PROPERTY); - - logger.debug(ret); - + create(ValueSchema.class); } @Test(expected=SchemaAlreadyPresentException.class) public void createEncryptedType() throws Exception { - PropertyType propertyTypeDefinition = new PropertyTypeImpl<>(Encrypted.class); - - SchemaManagement schemaManagement = new SchemaManagement(); - ((SchemaManagement) schemaManagement).setTypeName(Encrypted.NAME); - String ret = schemaManagement.create(ElementMapper.marshal(propertyTypeDefinition), AccessType.PROPERTY); - - logger.debug(ret); - + create(Encrypted.class); } @Test(expected=SchemaAlreadyPresentException.class) public void createContextType() throws Exception { - EntityType entityTypeDefinition = new EntityTypeImpl(Context.class); - - SchemaManagement schemaManagement = new SchemaManagement(); - ((SchemaManagement) schemaManagement).setTypeName(Context.NAME); - String ret = schemaManagement.create(ElementMapper.marshal(entityTypeDefinition), AccessType.ENTITY_ELEMENT); - - logger.debug(ret); - + create(Context.class); } @Test(expected=SchemaAlreadyPresentException.class) public void createFacetType() throws Exception { - EntityType entityTypeDefinition = new EntityTypeImpl(AccessPointFacet.class); - - SchemaManagement schemaManagement = new SchemaManagement(); - ((SchemaManagement) schemaManagement).setTypeName(AccessPointFacet.NAME); - String ret = schemaManagement.create(ElementMapper.marshal(entityTypeDefinition), AccessType.FACET); - - logger.debug(ret); - + create(AccessPointFacet.class); } @Test(expected=SchemaAlreadyPresentException.class) public void createResourceType() throws Exception { - EntityType entityTypeDefinition = new EntityTypeImpl(EService.class); - - SchemaManagement schemaManagement = new SchemaManagement(); - ((SchemaManagement) schemaManagement).setTypeName(EService.NAME); - String ret = schemaManagement.create(ElementMapper.marshal(entityTypeDefinition), AccessType.RESOURCE); - - logger.debug(ret); - - entityTypeDefinition = new EntityTypeImpl(RunningPlugin.class); - - schemaManagement = new SchemaManagement(); - ((SchemaManagement) schemaManagement).setTypeName(RunningPlugin.NAME); - ret = schemaManagement.create(ElementMapper.marshal(entityTypeDefinition), AccessType.RESOURCE); - - logger.debug(ret); - + create(EService.class); + create(RunningPlugin.class); } - @Test + // @Test(expected=SchemaAlreadyPresentException.class) public void createRelationTypeDefinitionType() throws Exception { - @SuppressWarnings({"unchecked", "rawtypes"}) - RelationType relationTypeDefinition = new RelationTypeImpl(RelationType.class); - - SchemaManagement schemaManagement = new SchemaManagement(); - ((SchemaManagement) schemaManagement).setTypeName(RelationType.NAME); - - String ret = ElementMapper.marshal(relationTypeDefinition); - - //String ret = schemaManagement.create(ISMapper.marshal(relationTypeDefinition), AccessType.BASE_RELATION); - - logger.debug(ret); - + create(RelationType.class); } - /* @Test(expected=SchemaAlreadyPresentException.class) public void createIsRelatedToType() throws Exception { - @SuppressWarnings("unchecked") - RelationTypeDefinition relationTypeDefinition = new RelationTypeDefinitionImpl((Class>) Uses.class); - - SchemaManagement schemaManagement = new SchemaManagementImpl(); - ((SchemaManagementImpl) schemaManagement).setTypeName(Uses.NAME); - String ret = schemaManagement.create(ISMapper.marshal(relationTypeDefinition), AccessType.IS_RELATED_TO); - - logger.debug(ret); - + create(Uses.class); } @Test(expected=SchemaAlreadyPresentException.class) public void createConsistsOfType() throws Exception { - @SuppressWarnings("unchecked") - RelationTypeDefinition relationTypeDefinition = new RelationTypeDefinitionImpl((Class>) HasVolatileMemory.class); - - SchemaManagement schemaManagement = new SchemaManagementImpl(); - ((SchemaManagementImpl) schemaManagement).setTypeName(HasVolatileMemory.NAME); - String ret = schemaManagement.create(ISMapper.marshal(relationTypeDefinition), AccessType.CONSISTS_OF); - - logger.debug(ret); - + create(HasVolatileMemory.class); } - */ private void compareTypes(Type type, Type typeManaged) { Assert.assertTrue(type.getName().compareTo(typeManaged.getName())==0); @@ -358,39 +301,30 @@ public class SchemaManagementImplTest extends ContextTest { @SuppressWarnings("unchecked") Class[] classes = new Class[]{TestFacet.class, TestFacet1_0_1.class, TestFacet1_0_2.class}; for(Class c : classes) { - SchemaManagement schemaManagement = new SchemaManagement(); - Type type = TypeMapper.createTypeDefinition(c); - schemaManagement.setTypeName(type.getName()); - + Type type = TypeMapper.createTypeDefinition(c); String ret = null; if(c == TestFacet.class) { logger.info("Going to create {} : {}", type.getName(), TypeMapper.serializeTypeDefinition(type)); - ret = schemaManagement.create(TypeMapper.serializeTypeDefinition(type), AccessType.FACET); + ret = create(c); logger.info("Created {} : {}", type.getName(), ret); } else { logger.info("Going to update {} : {}", type.getName(), TypeMapper.serializeTypeDefinition(type)); - ret = schemaManagement.update(TypeMapper.serializeTypeDefinition(type), AccessType.FACET); + ret = update(c, false); logger.info("Updated {} : {}", type.getName(), ret); } - Type typeManaged = TypeMapper.deserializeTypeDefinition(ret); + Type typeManaged = TypeMapper.deserializeTypeDefinition(ret); compareTypes(type, typeManaged); } - SchemaManagement schemaManagement = new SchemaManagement(); - Type type = TypeMapper.createTypeDefinition(TestFacet.class); - schemaManagement.setTypeName(type.getName()); - schemaManagement.setSkipVersionCheckOnUpdate(true); + Type type = TypeMapper.createTypeDefinition(TestFacet.class); logger.info("Going to update {} : {}", type.getName(), TypeMapper.serializeTypeDefinition(type)); - String ret = schemaManagement.update(TypeMapper.serializeTypeDefinition(type), AccessType.FACET); + String ret = update(TestFacet.class, true); logger.info("Updated {} : {}", type.getName(), ret); Type typeManaged = TypeMapper.deserializeTypeDefinition(ret); - compareTypes(type, typeManaged); - - schemaManagement.setSkipVersionCheckOnUpdate(false); - + } catch (Exception e) { throw e; } finally {