From 7c4625c2d9dd14b580bde1b4e4ac86a7c7498f7d Mon Sep 17 00:00:00 2001 From: "luca.frosini" Date: Tue, 20 Dec 2016 17:36:17 +0000 Subject: [PATCH] refs #6273: Manage Propagation Constraint on Resource Registry https://support.d4science.org/issues/6273 git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/information-system/resource-registry@141292 82a268e6-3cf1-43bd-a215-b396298e98cf --- .../context/SecurityContext.java | 66 +++---- .../ermanagement/EmbeddedMangement.java | 1 - .../ermanagement/entity/EntityManagement.java | 26 +-- .../ermanagement/entity/FacetManagement.java | 3 +- .../entity/ResourceManagement.java | 2 +- .../relation/RelationManagement.java | 164 +++++++++++++++--- .../resources/utils/ContextUtility.java | 18 +- 7 files changed, 206 insertions(+), 74 deletions(-) diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/context/SecurityContext.java b/src/main/java/org/gcube/informationsystem/resourceregistry/context/SecurityContext.java index c135efc..6d85da3 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/context/SecurityContext.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/context/SecurityContext.java @@ -3,7 +3,6 @@ */ package org.gcube.informationsystem.resourceregistry.context; -import java.util.Iterator; import java.util.UUID; import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseEnvironment; @@ -17,12 +16,9 @@ import com.orientechnologies.orient.core.metadata.security.OSecurity; import com.orientechnologies.orient.core.metadata.security.OSecurityRole.ALLOW_MODES; import com.orientechnologies.orient.core.metadata.security.OUser; import com.orientechnologies.orient.core.record.impl.ODocument; -import com.tinkerpop.blueprints.Direction; -import com.tinkerpop.blueprints.Edge; -import com.tinkerpop.blueprints.Vertex; -import com.tinkerpop.blueprints.impls.orient.OrientEdge; +import com.tinkerpop.blueprints.Element; +import com.tinkerpop.blueprints.impls.orient.OrientElement; import com.tinkerpop.blueprints.impls.orient.OrientGraph; -import com.tinkerpop.blueprints.impls.orient.OrientVertex; /** * @author Luca Frosini (ISTI - CNR) @@ -37,42 +33,52 @@ public class SecurityContext { public static final String DEFAULT_READER_ROLE = "reader"; public static void addToSecurityContext(OrientGraph orientGraph, - Vertex vertex, UUID context) { + Element element, UUID context) { OSecurity oSecurity = orientGraph.getRawGraph().getMetadata() .getSecurity(); - SecurityContext.addToSecurityContext(oSecurity, vertex, context); + SecurityContext.addToSecurityContext(oSecurity, element, context); } - public static void addToSecurityContext(OSecurity oSecurity, Vertex vertex, + public static void addToSecurityContext(OSecurity oSecurity, Element element, UUID context) { - OrientVertex orientVertex = (OrientVertex) vertex; - + OrientElement orientElement = (OrientElement) element; SecurityContext.allowSecurityContextRoles(oSecurity, - orientVertex.getRecord(), context); - orientVertex.save(); - - Iterable iterable = vertex.getEdges(Direction.BOTH); - Iterator iterator = iterable.iterator(); - while (iterator.hasNext()) { - OrientEdge edge = (OrientEdge) iterator.next(); - SecurityContext.allowSecurityContextRoles(oSecurity, - edge.getRecord(), context); - edge.save(); - } + orientElement.getRecord(), context); + orientElement.save(); } - public static void addToSecurityContext(OrientGraph orientGraph, Edge edge, - UUID context) { + public static void removeFromSecurityContext(OrientGraph orientGraph, + Element element, UUID context) { OSecurity oSecurity = orientGraph.getRawGraph().getMetadata() .getSecurity(); - SecurityContext.addToSecurityContext(oSecurity, edge, context); + SecurityContext.removeFromSecurityContext(oSecurity, element, context); + } + + public static void removeFromSecurityContext(OSecurity oSecurity, Element element, + UUID context) { + OrientElement orientElement = (OrientElement) element; + SecurityContext.disallowSecurityContextRoles(oSecurity, + orientElement.getRecord(), context); + orientElement.save(); } - public static void addToSecurityContext(OSecurity oSecurity, Edge edge, - UUID context) { - OrientEdge orientEdge = (OrientEdge) edge; - SecurityContext.allowSecurityContextRoles(oSecurity, - orientEdge.getRecord(), context); + protected static void disallowSecurityContextRoles(OSecurity oSecurity, + ODocument oDocument, UUID context) { + oSecurity.denyRole(oDocument, ORestrictedOperation.ALLOW_ALL, + SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.WRITER, + SecurityContextMapper.SecurityType.ROLE, context)); + + oSecurity.denyRole(oDocument, ORestrictedOperation.ALLOW_READ, + SecurityContextMapper.getSecurityRoleOrUserName( + SecurityContextMapper.PermissionMode.READER, + SecurityContextMapper.SecurityType.ROLE, context)); + + oDocument.save(); + // oSecurity.denyRole(oDocument, ORestrictedOperation.ALLOW_ALL, + // DEFAULT_WRITER_ROLE); + // oSecurity.denyRole(oDocument, ORestrictedOperation.ALLOW_READ, + // DEFAULT_READER_ROLE); } protected static void allowSecurityContextRoles(OSecurity oSecurity, diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/EmbeddedMangement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/EmbeddedMangement.java index 0f4f1e6..63db996 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/EmbeddedMangement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/EmbeddedMangement.java @@ -21,7 +21,6 @@ import com.orientechnologies.orient.core.record.impl.ODocument; /** * @author Luca Frosini (ISTI - CNR) - * */ public class EmbeddedMangement { diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/EntityManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/EntityManagement.java index 03e18eb..d17381c 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/EntityManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/EntityManagement.java @@ -13,7 +13,6 @@ import org.gcube.informationsystem.model.embedded.Header; import org.gcube.informationsystem.model.entity.Entity; import org.gcube.informationsystem.model.entity.Facet; import org.gcube.informationsystem.model.entity.Resource; -import org.gcube.informationsystem.model.relation.ConsistsOf; import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAlreadyPresentException; @@ -301,16 +300,11 @@ public abstract class EntityManagement { public boolean reallyAddToContext() throws ContextException, ResourceRegistryException { - getVertex(); - ContextUtility.addToActualContext(orientGraph, vertex); + ContextUtility.addToActualContext(orientGraph, getVertex()); - Iterable edges = vertex.getEdges(Direction.OUT, ConsistsOf.NAME); + Iterable edges = vertex.getEdges(Direction.OUT); - /* - * Use this when the add integrity directive are inserted Iterable - * edges = vertex.getEdges(Direction.OUT); - */ for (Edge edge : edges) { @SuppressWarnings("rawtypes") RelationManagement relationManagement = RelationManagement @@ -323,7 +317,19 @@ public abstract class EntityManagement { public boolean reallyRemoveFromContext() throws ContextException, ResourceRegistryException { - throw new UnsupportedOperationException(); + + ContextUtility.removeFromActualContext(orientGraph, getVertex()); + + Iterable edges = vertex.getEdges(Direction.OUT); + + for (Edge edge : edges) { + @SuppressWarnings("rawtypes") + RelationManagement relationManagement = RelationManagement + .getRelationManagement(orientGraph, edge); + relationManagement.reallyRemoveFromContext(); + } + + return true; } @SuppressWarnings("rawtypes") @@ -337,7 +343,7 @@ public abstract class EntityManagement { entityManagement = new FacetManagement(orientGraph); } else { String error = String.format("{%s is not a %s nor a %s. " - + "This is really strange ad should not occur. " + + "This is really strange and should not occur. " + "Please Investigate it.", vertex, Resource.NAME, Facet.NAME); throw new ResourceRegistryException(error); diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/FacetManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/FacetManagement.java index dce6aaf..e909f12 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/FacetManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/FacetManagement.java @@ -52,8 +52,7 @@ public class FacetManagement extends EntityManagement { } public boolean reallyDelete() throws FacetNotFoundException, ResourceRegistryException { - Vertex facet = getVertex(); - facet.remove(); + getVertex().remove(); return true; } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/ResourceManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/ResourceManagement.java index ddb7687..33b0464 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/ResourceManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/entity/ResourceManagement.java @@ -193,7 +193,7 @@ public class ResourceManagement extends EntityManagement { } - ((OrientVertex) vertex).remove(); + vertex.remove(); return true; } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/relation/RelationManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/relation/RelationManagement.java index b947f0e..a7bc41a 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/relation/RelationManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/ermanagement/relation/RelationManagement.java @@ -13,6 +13,7 @@ import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.gcube.informationsystem.model.embedded.Header; import org.gcube.informationsystem.model.embedded.PropagationConstraint; +import org.gcube.informationsystem.model.embedded.PropagationConstraint.AddConstraint; import org.gcube.informationsystem.model.embedded.PropagationConstraint.RemoveConstraint; import org.gcube.informationsystem.model.entity.Entity; import org.gcube.informationsystem.model.entity.Facet; @@ -257,11 +258,51 @@ public abstract class RelationManagement { protected Edge reallyCreate(Vertex source, Vertex target) throws ResourceRegistryException { - // TODO Check the relation compatibility between source and target - logger.trace("Creating {} ({}) beetween {} -> {}", - Relation.class.getSimpleName(), relationType, - Utility.toJsonString(source, true), - Utility.toJsonString(target, true)); + + EntityManagement sourceEntityManagement = EntityManagement + .getEntityManagement(orientGraph, source); + EntityManagement targetEntityManagement = EntityManagement + .getEntityManagement(orientGraph, target); + if (!(sourceEntityManagement instanceof ResourceManagement)) { + String error = String.format( + "Any type of %s can have only a %s as %s. " + + "Cannot instatiate %s beetween %s -> %s ", + Relation.NAME, Resource.NAME, Relation.SOURCE_PROPERTY, + relationType, sourceEntityManagement.serialize(), + targetEntityManagement.serialize()); + throw new ResourceRegistryException(error); + } + + if (this instanceof IsRelatedToManagement) { + if (!(targetEntityManagement instanceof ResourceManagement)) { + String error = String.format("A %s can have only a %s as %s. " + + "Cannot instatiate %s beetween %s -> %s ", baseType, + Resource.NAME, Relation.TARGET_PROPERTY, relationType, + sourceEntityManagement.serialize(), + targetEntityManagement.serialize()); + throw new ResourceRegistryException(error); + } + } else if (this instanceof ConsistsOfManagement) { + if (!(targetEntityManagement instanceof FacetManagement)) { + String error = String.format("A %s can have only a %s as %s. " + + "Cannot instatiate %s beetween %s -> %s ", baseType, + Facet.NAME, Relation.TARGET_PROPERTY, relationType, + sourceEntityManagement.serialize(), + targetEntityManagement.serialize()); + throw new ResourceRegistryException(error); + } + } else { + String error = String.format("{%s is not a %s nor a %s. " + + "This is really strange and should not occur. " + + "Please Investigate it.", this, + IsRelatedToManagement.class.getSimpleName(), + ConsistsOfManagement.class.getSimpleName()); + throw new ResourceRegistryException(error); + } + + logger.trace("Creating {} beetween {} -> {}", relationType, + sourceEntityManagement.serialize(), + targetEntityManagement.serialize()); edge = orientGraph.addEdge(null, source, target, relationType); @@ -304,12 +345,10 @@ public abstract class RelationManagement { public Edge reallyUpdate() throws ResourceRegistryException { - logger.debug("Trying to update {} : {}", relationClass.getSimpleName(), - jsonNode); + logger.debug("Trying to update {} : {}", relationType, jsonNode); Edge edge = getEdge(); - ERManagement.updateProperties(edge, jsonNode, ignoreKeys, - ignoreStartWithKeys); + ERManagement.updateProperties(edge, jsonNode, ignoreKeys, ignoreStartWithKeys); if (ConsistsOf.class.isAssignableFrom(relationClass)) { JsonNode target = jsonNode.get(Relation.TARGET_PROPERTY); @@ -328,23 +367,106 @@ public abstract class RelationManagement { public boolean reallyAddToContext() throws ContextException, ResourceRegistryException { - getEdge(); - // TODO check add integrity directive + ContextUtility.addToActualContext(orientGraph, getEdge()); - ContextUtility.addToActualContext(orientGraph, edge); + AddConstraint addConstraint = AddConstraint.unpropagate; - Vertex vertex = edge.getVertex(Direction.IN); - EntityManagement entityManagement = EntityManagement - .getEntityManagement(orientGraph, vertex); - entityManagement.reallyAddToContext(); + try { + PropagationConstraint propagationConstraint = Utility.getEmbedded( + PropagationConstraint.class, edge, + Relation.PROPAGATION_CONSTRAINT); + if (propagationConstraint.getAddConstraint() != null) { + addConstraint = propagationConstraint.getAddConstraint(); + } + } catch (Exception e) { + logger.warn("Error while getting {} from {}. Assuming {}. " + + "This is really strange and should not occur. " + + "Please Investigate it.", + Relation.PROPAGATION_CONSTRAINT, + Utility.toJsonString(edge, true), addConstraint); + } + + Vertex target = edge.getVertex(Direction.IN); + + switch (addConstraint) { + case propagate: + EntityManagement entityManagement = EntityManagement + .getEntityManagement(orientGraph, target); + entityManagement.reallyAddToContext(); + break; + + case unpropagate: + break; + + default: + break; + } return true; } + protected boolean removeFromContextTargetVertex(Vertex target) + throws ResourceRegistryException { + EntityManagement entityManagement = EntityManagement + .getEntityManagement(orientGraph, target); + if (entityManagement != null) { + entityManagement.reallyRemoveFromContext(); + return true; + } else { + return false; + } + } + public boolean reallyRemoveFromContext() throws ContextException, ResourceRegistryException { - throw new UnsupportedOperationException(); + getEdge(); + + RemoveConstraint removeConstraint = RemoveConstraint.keep; + + try { + PropagationConstraint propagationConstraint = Utility.getEmbedded( + PropagationConstraint.class, edge, + Relation.PROPAGATION_CONSTRAINT); + if (propagationConstraint.getRemoveConstraint() != null) { + removeConstraint = propagationConstraint.getRemoveConstraint(); + } + } catch (Exception e) { + logger.warn("Error while getting {} from {}. Assuming {}. " + + "This is really strange and should not occur. " + + "Please Investigate it.", + Relation.PROPAGATION_CONSTRAINT, + Utility.toJsonString(edge, true), removeConstraint); + } + + Vertex target = edge.getVertex(Direction.IN); + ContextUtility.removeFromActualContext(orientGraph, edge); + + switch (removeConstraint) { + case cascade: + removeFromContextTargetVertex(target); + break; + + case cascadeWhenOrphan: + Iterable iterable = target.getEdges(Direction.IN); + Iterator iterator = iterable.iterator(); + if (iterator.hasNext()) { + logger.trace( + "{} point to {} which is not orphan. Giving {} directive, it will be not remove from current context.", + edge, target, removeConstraint); + } else { + removeFromContextTargetVertex(target); + } + break; + + case keep: + break; + + default: + break; + } + + return true; } protected EntityManagement getEntityManagement() @@ -404,8 +526,9 @@ public abstract class RelationManagement { try { PropagationConstraint propagationConstraint = Utility.getEmbedded( - PropagationConstraint.class, edge, Relation.PROPAGATION_CONSTRAINT); - if(propagationConstraint.getRemoveConstraint()!=null){ + PropagationConstraint.class, edge, + Relation.PROPAGATION_CONSTRAINT); + if (propagationConstraint.getRemoveConstraint() != null) { removeConstraint = propagationConstraint.getRemoveConstraint(); } } catch (Exception e) { @@ -413,8 +536,7 @@ public abstract class RelationManagement { + "This is really strange and should not occur. " + "Please Investigate it.", Relation.PROPAGATION_CONSTRAINT, - Utility.toJsonString(edge, true), - RemoveConstraint.keep); + Utility.toJsonString(edge, true), removeConstraint); } Vertex target = edge.getVertex(Direction.IN); diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/ContextUtility.java b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/ContextUtility.java index d5738a0..8d3aeef 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/ContextUtility.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/resources/utils/ContextUtility.java @@ -24,7 +24,7 @@ import org.slf4j.LoggerFactory; import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; import com.orientechnologies.orient.core.metadata.security.OSecurity; import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; -import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Element; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.blueprints.impls.orient.OrientGraph; import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory; @@ -39,31 +39,31 @@ public class ContextUtility { private static final Logger logger = LoggerFactory .getLogger(ContextUtility.class); - public static UUID addToActualContext(OrientGraph orientGraph, Vertex vertex) + public static UUID addToActualContext(OrientGraph orientGraph, Element element) throws ContextException { UUID contextUUID = ContextUtility.getActualContextUUID(); - SecurityContext.addToSecurityContext(orientGraph, vertex, contextUUID); + SecurityContext.addToSecurityContext(orientGraph, element, contextUUID); return contextUUID; } - public static UUID addToActualContex(OSecurity oSecurity, Vertex vertex) + public static UUID addToActualContex(OSecurity oSecurity, Element element) throws ContextException { UUID contextUUID = ContextUtility.getActualContextUUID(); - SecurityContext.addToSecurityContext(oSecurity, vertex, contextUUID); + SecurityContext.addToSecurityContext(oSecurity, element, contextUUID); return contextUUID; } - public static UUID addToActualContext(OrientGraph orientGraph, Edge edge) + public static UUID removeFromActualContext(OrientGraph orientGraph, Element element) throws ContextException { UUID contextUUID = ContextUtility.getActualContextUUID(); - SecurityContext.addToSecurityContext(orientGraph, edge, contextUUID); + SecurityContext.removeFromSecurityContext(orientGraph, element, contextUUID); return contextUUID; } - public static UUID addToActualContext(OSecurity oSecurity, Edge edge) + public static UUID removeFromActualContext(OSecurity oSecurity, Element element) throws ContextException { UUID contextUUID = ContextUtility.getActualContextUUID(); - SecurityContext.addToSecurityContext(oSecurity, edge, contextUUID); + SecurityContext.removeFromSecurityContext(oSecurity, element, contextUUID); return contextUUID; }