diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/DatabaseEnvironment.java b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/DatabaseEnvironment.java index 3d725f3..6d357ca 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/DatabaseEnvironment.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/DatabaseEnvironment.java @@ -4,19 +4,26 @@ import java.io.File; import java.io.InputStream; import java.net.URL; import java.security.Key; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.ServiceLoader; import java.util.UUID; import org.gcube.common.encryption.SymmetricKey; +import org.gcube.informationsystem.base.reference.AccessType; import org.gcube.informationsystem.base.reference.ISConstants; +import org.gcube.informationsystem.base.reference.ISManageable; import org.gcube.informationsystem.resourceregistry.context.ContextUtility; import org.gcube.informationsystem.resourceregistry.context.security.AdminSecurityContext; import org.gcube.informationsystem.resourceregistry.context.security.ContextSecurityContext; import org.gcube.informationsystem.resourceregistry.context.security.SchemaSecurityContext; import org.gcube.informationsystem.resourceregistry.context.security.SecurityContext.PermissionMode; +import org.gcube.informationsystem.types.reference.TypeDefinition; import org.gcube.informationsystem.utils.discovery.ISMDiscovery; +import org.gcube.informationsystem.utils.discovery.RegistrationProvider; import org.gcube.informationsystem.utils.discovery.SchemaAction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -202,8 +209,27 @@ public class DatabaseEnvironment { schemaSecurityContext.create(); + + List packages = new ArrayList(); + + @SuppressWarnings("rawtypes") + Class tdClz = TypeDefinition.class; + packages.add(tdClz.getPackage()); + + AccessType[] accessTypes = AccessType.values(); + for(AccessType accessType : accessTypes) { + Class clz = accessType.getTypeClass(); + packages.add(clz.getPackage()); + } + + ServiceLoader regsitrationProviders = ServiceLoader + .load(RegistrationProvider.class); + for(RegistrationProvider registrationProvider : regsitrationProviders) { + packages.addAll(registrationProvider.getPackagesToRegister()); + } + SchemaAction schemaAction = new SchemaActionImpl(); - ISMDiscovery.manageISM(schemaAction); + ISMDiscovery.manageISM(schemaAction, packages); } logger.info("Database Connection has been properly initialized"); 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 1a2f36f..b00eb1d 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SchemaActionImpl.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/dbinitialization/SchemaActionImpl.java @@ -44,7 +44,7 @@ public class SchemaActionImpl implements SchemaAction { } else if(IsRelatedTo.class.isAssignableFrom(r)) { schemaManagement.create(json, AccessType.IS_RELATED_TO); } else { - schemaManagement.create(json, AccessType.RELATION); + schemaManagement.create(json, AccessType.BASE_RELATION); } } catch(SchemaAlreadyPresentException sape) { logger.warn("{} already exists. It will be ignored", TypeBinder.getType(r)); @@ -66,7 +66,7 @@ public class SchemaActionImpl implements SchemaAction { } else if(Resource.class.isAssignableFrom(e)) { schemaManagement.create(json, AccessType.RESOURCE); } else { - schemaManagement.create(json, AccessType.ENTITY); + schemaManagement.create(json, AccessType.BASE_ENTITY); } } catch(SchemaAlreadyPresentException sape) { logger.warn("{} already exists. It will be ignored", TypeBinder.getType(e)); @@ -82,7 +82,7 @@ public class SchemaActionImpl implements SchemaAction { ((SchemaManagementImpl) schemaManagement).setTypeName(TypeBinder.getType(e)); String json = TypeBinder.serializeType(e); logger.trace(json); - schemaManagement.create(json, AccessType.PROPERTY); + schemaManagement.create(json, AccessType.BASE_PROPERTY); } catch(SchemaAlreadyPresentException sape) { logger.warn("{} already exists. It will be ignored", TypeBinder.getType(e)); } catch(Exception ex) { 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 bba7097..b483e69 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/rest/SchemaManager.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/rest/SchemaManager.java @@ -80,6 +80,7 @@ public class SchemaManager { AccessType accessType = null; String firstGotType = null; try { + @SuppressWarnings("unchecked") Set superClasses = TypeBinder.deserializeTypeDefinition(json).getSuperClasses(); if(superClasses.size()==0) { throw new ResourceRegistryException("No superclasses defined"); diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/schema/SchemaContextManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/schema/SchemaContextManagement.java index 9f6a4ab..e584282 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/schema/SchemaContextManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/schema/SchemaContextManagement.java @@ -3,9 +3,9 @@ package org.gcube.informationsystem.resourceregistry.schema; import java.util.Iterator; import org.gcube.informationsystem.base.reference.AccessType; -import org.gcube.informationsystem.model.reference.entities.Entity; -import org.gcube.informationsystem.model.reference.properties.Property; -import org.gcube.informationsystem.model.reference.relations.Relation; +import org.gcube.informationsystem.base.reference.entities.BaseEntity; +import org.gcube.informationsystem.base.reference.properties.BaseProperty; +import org.gcube.informationsystem.base.reference.relations.BaseRelation; import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaException; import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException; import org.gcube.informationsystem.resourceregistry.context.ContextUtility; @@ -63,13 +63,13 @@ public class SchemaContextManagement implements SchemaManagement { orientGraph = adminSecurityContext.getGraph(PermissionMode.WRITER); @SuppressWarnings("rawtypes") - TypeDefinition typeDefinition = TypeBinder.deserializeTypeDefinition(json); + TypeDefinition typeDefinition = TypeBinder.deserializeTypeDefinition(json); - if(Entity.class.isAssignableFrom(baseType.getTypeClass())) { + if(BaseEntity.class.isAssignableFrom(baseType.getTypeClass())) { OrientVertex orientVertex = orientGraph.addVertex("class:" + typeDefinition.getName()); orientVertex.setProperty(SCHEMA, json); orientVertex.save(); - } else if(Relation.class.isAssignableFrom(baseType.getTypeClass())) { + } else if(BaseRelation.class.isAssignableFrom(baseType.getTypeClass())) { @SuppressWarnings("rawtypes") String sourceClass = ((RelationTypeDefinition) typeDefinition).getSourceType(); Vertex source = getVertex(orientGraph, sourceClass); @@ -82,7 +82,7 @@ public class SchemaContextManagement implements SchemaManagement { orientEdge.setProperty(SCHEMA, json); orientEdge.save(); - } else if(Property.class.isAssignableFrom(baseType.getTypeClass())) { + } else if(BaseProperty.class.isAssignableFrom(baseType.getTypeClass())) { ODocument doc = new ODocument(typeDefinition.getName()); doc.field(SCHEMA, json); doc.save(); diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/schema/SchemaManagementImpl.java b/src/main/java/org/gcube/informationsystem/resourceregistry/schema/SchemaManagementImpl.java index 7fc9a6a..26edb4d 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/schema/SchemaManagementImpl.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/schema/SchemaManagementImpl.java @@ -5,6 +5,7 @@ package org.gcube.informationsystem.resourceregistry.schema; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.Callable; @@ -16,6 +17,9 @@ import javax.activation.UnsupportedDataTypeException; import org.gcube.informationsystem.base.reference.AccessType; import org.gcube.informationsystem.base.reference.ISManageable; +import org.gcube.informationsystem.base.reference.entities.BaseEntity; +import org.gcube.informationsystem.base.reference.properties.BaseProperty; +import org.gcube.informationsystem.base.reference.relations.BaseRelation; import org.gcube.informationsystem.model.reference.entities.Entity; import org.gcube.informationsystem.model.reference.entities.Resource; import org.gcube.informationsystem.model.reference.properties.Property; @@ -28,12 +32,20 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.Schema import org.gcube.informationsystem.resourceregistry.context.ContextUtility; import org.gcube.informationsystem.resourceregistry.context.security.AdminSecurityContext; import org.gcube.informationsystem.resourceregistry.context.security.SecurityContext.PermissionMode; +import org.gcube.informationsystem.types.Type; import org.gcube.informationsystem.types.TypeBinder; import org.gcube.informationsystem.types.reference.TypeDefinition; +import org.gcube.informationsystem.types.reference.entities.EntityTypeDefinition; import org.gcube.informationsystem.types.reference.properties.PropertyDefinition; +import org.gcube.informationsystem.types.reference.properties.PropertyTypeDefinition; +import org.gcube.informationsystem.types.reference.relations.RelationTypeDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.orientechnologies.orient.core.db.ODatabaseSession; import com.orientechnologies.orient.core.exception.OSchemaException; import com.orientechnologies.orient.core.metadata.OMetadata; @@ -127,28 +139,54 @@ public class SchemaManagementImpl implements SchemaManagement { } } - protected static TypeDefinition getTypeDefinition(OClass oClass) throws SchemaException { + @SuppressWarnings("rawtypes") + protected static TypeDefinition getTypeDefinition(OClass oClass) throws SchemaException { + // TODO OrientSerilizatoin is not acceptable anymore since TypeDefiniton introduction + ODocument oDocument = ((OClassImpl) oClass).toStream(); String json = oDocument.toJSON(); try { - return TypeBinder.deserializeTypeDefinition(json); + ObjectMapper mapper = new ObjectMapper(); + ObjectNode node = (ObjectNode) mapper.readTree(json); + + if(oClass.isSubClassOf(BaseProperty.NAME)) { + node.put(ISManageable.CLASS_PROPERTY, PropertyTypeDefinition.NAME); + } else if(oClass.isSubClassOf(BaseEntity.NAME)) { + node.put(ISManageable.CLASS_PROPERTY, EntityTypeDefinition.NAME); + } else if(oClass.isSubClassOf(BaseRelation.NAME)) { + node.put(ISManageable.CLASS_PROPERTY, RelationTypeDefinition.NAME); + } + + + ArrayNode arrayNode = (ArrayNode) node.get(TypeDefinition.PROPERTIES_PROPERTY); + Iterator iterator = arrayNode.iterator(); + while(iterator.hasNext()) { + ObjectNode propertyNode = (ObjectNode) iterator.next(); + propertyNode.put(ISManageable.CLASS_PROPERTY, PropertyDefinition.NAME); + } + + String managedJson = mapper.writeValueAsString(node); + logger.trace("{} -> {}", json, managedJson); + + return TypeBinder.deserializeTypeDefinition(managedJson); } catch(Exception e) { throw new SchemaException(e); } } - protected static String getTypeDefinitionAsString(OClass oClass) throws SchemaException { - + @SuppressWarnings({"rawtypes"}) + protected static String getTypeDefinitionAsString(OClass oClass) throws SchemaException { try { - TypeDefinition typeDefinition = getTypeDefinition(oClass); + TypeDefinition typeDefinition = getTypeDefinition(oClass); return TypeBinder.serializeTypeDefinition(typeDefinition); } catch(Exception e) { throw new SchemaException(e); } } - protected List getSuperclassesAndCheckCompliancy(ODatabaseSession oDatabaseSession, - TypeDefinition typeDefinition, String baseType) throws SchemaException { + @SuppressWarnings({"unchecked", "rawtypes"}) + protected List getSuperclassesAndCheckCompliancy(ODatabaseSession oDatabaseSession, + TypeDefinition typeDefinition, String baseType) throws SchemaException { Set superClasses = typeDefinition.getSuperClasses(); if(baseType != null) { @@ -182,15 +220,35 @@ public class SchemaManagementImpl implements SchemaManagement { return oSuperclasses; } + private static List baseTypes; + private static List typeDefinitionTypes; + + static { + baseTypes = new ArrayList(); + baseTypes.add(BaseProperty.NAME); + baseTypes.add(BaseEntity.NAME); + baseTypes.add(BaseRelation.NAME); + + typeDefinitionTypes = new ArrayList(); + typeDefinitionTypes.add(PropertyTypeDefinition.NAME); + typeDefinitionTypes.add(EntityTypeDefinition.NAME); + typeDefinitionTypes.add(RelationTypeDefinition.NAME); + } + protected String registerTypeSchema(String jsonSchema, AccessType baseType) throws SchemaException { ODatabaseSession oDatabaseSession = null; try { - logger.info("Trying to register {} {}", baseType.getName(), jsonSchema); - - @SuppressWarnings("rawtypes") - TypeDefinition typeDefinition = TypeBinder.deserializeTypeDefinition(jsonSchema); + TypeDefinition typeDefinition = null; + try { + typeDefinition = TypeBinder.deserializeTypeDefinition(jsonSchema); + logger.info("Trying to register {} {} : {}", baseType.getName(), typeDefinition.getName(), jsonSchema); + }catch (Exception e) { + logger.error("Error while trying to register {} {}", baseType.getName(), jsonSchema); + throw e; + } + if(typeName.compareTo(typeDefinition.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, typeDefinition.getName()); @@ -206,9 +264,9 @@ public class SchemaManagementImpl implements SchemaManagement { OClass oClass = null; - if(Entity.class.isAssignableFrom(baseType.getTypeClass())) { + if(BaseEntity.class.isAssignableFrom(baseType.getTypeClass())) { oClass = oDatabaseSession.createVertexClass(typeDefinition.getName()); - } else if(Relation.class.isAssignableFrom(baseType.getTypeClass())) { + } else if(BaseRelation.class.isAssignableFrom(baseType.getTypeClass())) { oClass = oDatabaseSession.createEdgeClass(typeDefinition.getName()); /* @@ -217,7 +275,7 @@ public class SchemaManagementImpl implements SchemaManagement { * typeDefinition.getInBaseType(); */ - } else if(Property.class.isAssignableFrom(baseType.getTypeClass())) { + } else if(BaseProperty.class.isAssignableFrom(baseType.getTypeClass())) { oClass = oSchema.createClass(typeDefinition.getName()); } else { String error = String.format("Allowed superclass are %s, %s, %s, or any subclasses of them.", @@ -247,30 +305,40 @@ public class SchemaManagementImpl implements SchemaManagement { typeDefinition.getName()); } - if(typeDefinition.getName().compareTo(Property.NAME) != 0) { + if(! baseTypes.contains(typeDefinition.getName())) { List oSuperclasses = getSuperclassesAndCheckCompliancy(oDatabaseSession, typeDefinition, baseType.getName()); oClass.setSuperClasses(oSuperclasses); } + @SuppressWarnings("unchecked") + Set propertyDefinitions = typeDefinition.getProperties(); if(Resource.class.isAssignableFrom(baseType.getTypeClass())) { - Set propertyDefinitions = typeDefinition.getProperties(); if(propertyDefinitions != null && propertyDefinitions.size() > 0) { throw new SchemaCreationException("A Resource cannot contains any properties."); } } else { - for(PropertyDefinition propertyDefinition : typeDefinition.getProperties()) { + for(PropertyDefinition propertyDefinition : propertyDefinitions) { OType oType = OType.getById(propertyDefinition.getType().byteValue()); - switch(oType) { - case EMBEDDEDLIST: - throw new UnsupportedDataTypeException(oType.name() - + " support is currently disabled due to OrientDB bug see https://github.com/orientechnologies/orientdb/issues/7354"); - case EMBEDDEDSET: - throw new UnsupportedDataTypeException(oType.name() - + " support is currently disabled due to OrientDB bug see https://github.com/orientechnologies/orientdb/issues/7354"); - default: - break; + + /* + * Types update is not allowed, + * hence bug https://github.com/orientechnologies/orientdb/issues/7354 cannot occur + * Excluding the check from types used for type definition + * + */ + if(!typeDefinitionTypes.contains(typeDefinition.getName())) { + switch(oType) { + case EMBEDDEDLIST: + throw new UnsupportedDataTypeException(Type.OType.PROPERTYLIST + + " support is currently disabled due to OrientDB bug see https://github.com/orientechnologies/orientdb/issues/7354"); + case EMBEDDEDSET: + throw new UnsupportedDataTypeException(Type.OType.PROPERTYSET + + " support is currently disabled due to OrientDB bug see https://github.com/orientechnologies/orientdb/issues/7354"); + default: + break; + } } OProperty op = oClass.createProperty(propertyDefinition.getName(), oType); @@ -342,6 +410,7 @@ public class SchemaManagementImpl implements SchemaManagement { } } + @SuppressWarnings("unchecked") protected String getSchema(String type, boolean includeSubtypes) throws SchemaNotFoundException, SchemaException { ODatabaseSession oDatabaseSession = null; try { diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/ContextTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/ContextTest.java index 29b923e..b0213ad 100644 --- a/src/test/java/org/gcube/informationsystem/resourceregistry/ContextTest.java +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/ContextTest.java @@ -49,15 +49,21 @@ public class ContextTest { } // PARENT_DEFAULT_TEST_SCOPE = "/pred4s" - // DEFAULT_TEST_SCOPE_NAME = PARENT_DEFAULT_TEST_SCOPE + "preprod"; + // DEFAULT_TEST_SCOPE_NAME = PARENT_DEFAULT_TEST_SCOPE + "/preprod"; // ALTERNATIVE_TEST_SCOPE = DEFAULT_TEST_SCOPE_NAME + "/preVRE"; PARENT_DEFAULT_TEST_SCOPE = "/gcube"; - DEFAULT_TEST_SCOPE = PARENT_DEFAULT_TEST_SCOPE + "devNext"; + DEFAULT_TEST_SCOPE = PARENT_DEFAULT_TEST_SCOPE + "/devNext"; ALTERNATIVE_TEST_SCOPE = DEFAULT_TEST_SCOPE + "/NextNext"; DEFAULT_TEST_SCOPE_ANOTHER_USER = "lucio.lelii_" + DEFAULT_TEST_SCOPE; + + try { + setContextByName(DEFAULT_TEST_SCOPE); + } catch(Exception e) { + throw new RuntimeException(e); + } } public static String getCurrentScope(String token) throws ObjectNotFound, Exception { diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/er/DiscoveryTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/er/DiscoveryTest.java index b2f771d..77c8944 100644 --- a/src/test/java/org/gcube/informationsystem/resourceregistry/er/DiscoveryTest.java +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/er/DiscoveryTest.java @@ -34,7 +34,7 @@ public class DiscoveryTest { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("["); boolean first = true; - for (Class resource : resourceDiscovery.getDiscovered()) { + for (Class resource : resourceDiscovery.getDiscovered()) { if(first) { first = false; }else { diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/schema/SchemaManagementImplTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/schema/SchemaManagementImplTest.java index 2bad8d0..6fd900e 100644 --- a/src/test/java/org/gcube/informationsystem/resourceregistry/schema/SchemaManagementImplTest.java +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/schema/SchemaManagementImplTest.java @@ -60,7 +60,8 @@ public class SchemaManagementImplTest { public void getFacetSchema() throws Exception { String json = new SchemaManagementImpl().read(ContactFacet.NAME, false); logger.info(json); - List> typeDefinitions = TypeBinder.deserializeTypeDefinitions(json); + @SuppressWarnings("rawtypes") + List typeDefinitions = TypeBinder.deserializeTypeDefinitions(json); logger.info("{}", typeDefinitions); }