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
This commit is contained in:
Luca Frosini 2016-12-20 17:36:17 +00:00
parent 19206b90b7
commit 7c4625c2d9
7 changed files with 206 additions and 74 deletions

View File

@ -3,7 +3,6 @@
*/ */
package org.gcube.informationsystem.resourceregistry.context; package org.gcube.informationsystem.resourceregistry.context;
import java.util.Iterator;
import java.util.UUID; import java.util.UUID;
import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseEnvironment; 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.OSecurityRole.ALLOW_MODES;
import com.orientechnologies.orient.core.metadata.security.OUser; import com.orientechnologies.orient.core.metadata.security.OUser;
import com.orientechnologies.orient.core.record.impl.ODocument; import com.orientechnologies.orient.core.record.impl.ODocument;
import com.tinkerpop.blueprints.Direction; import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Edge; import com.tinkerpop.blueprints.impls.orient.OrientElement;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientEdge;
import com.tinkerpop.blueprints.impls.orient.OrientGraph; import com.tinkerpop.blueprints.impls.orient.OrientGraph;
import com.tinkerpop.blueprints.impls.orient.OrientVertex;
/** /**
* @author Luca Frosini (ISTI - CNR) * @author Luca Frosini (ISTI - CNR)
@ -37,42 +33,52 @@ public class SecurityContext {
public static final String DEFAULT_READER_ROLE = "reader"; public static final String DEFAULT_READER_ROLE = "reader";
public static void addToSecurityContext(OrientGraph orientGraph, public static void addToSecurityContext(OrientGraph orientGraph,
Vertex vertex, UUID context) { Element element, UUID context) {
OSecurity oSecurity = orientGraph.getRawGraph().getMetadata() OSecurity oSecurity = orientGraph.getRawGraph().getMetadata()
.getSecurity(); .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) { UUID context) {
OrientVertex orientVertex = (OrientVertex) vertex; OrientElement orientElement = (OrientElement) element;
SecurityContext.allowSecurityContextRoles(oSecurity, SecurityContext.allowSecurityContextRoles(oSecurity,
orientVertex.getRecord(), context); orientElement.getRecord(), context);
orientVertex.save(); orientElement.save();
Iterable<Edge> iterable = vertex.getEdges(Direction.BOTH);
Iterator<Edge> iterator = iterable.iterator();
while (iterator.hasNext()) {
OrientEdge edge = (OrientEdge) iterator.next();
SecurityContext.allowSecurityContextRoles(oSecurity,
edge.getRecord(), context);
edge.save();
}
} }
public static void addToSecurityContext(OrientGraph orientGraph, Edge edge, public static void removeFromSecurityContext(OrientGraph orientGraph,
UUID context) { Element element, UUID context) {
OSecurity oSecurity = orientGraph.getRawGraph().getMetadata() OSecurity oSecurity = orientGraph.getRawGraph().getMetadata()
.getSecurity(); .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, protected static void disallowSecurityContextRoles(OSecurity oSecurity,
UUID context) { ODocument oDocument, UUID context) {
OrientEdge orientEdge = (OrientEdge) edge; oSecurity.denyRole(oDocument, ORestrictedOperation.ALLOW_ALL,
SecurityContext.allowSecurityContextRoles(oSecurity, SecurityContextMapper.getSecurityRoleOrUserName(
orientEdge.getRecord(), context); 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, protected static void allowSecurityContextRoles(OSecurity oSecurity,

View File

@ -21,7 +21,6 @@ import com.orientechnologies.orient.core.record.impl.ODocument;
/** /**
* @author Luca Frosini (ISTI - CNR) * @author Luca Frosini (ISTI - CNR)
*
*/ */
public class EmbeddedMangement { public class EmbeddedMangement {

View File

@ -13,7 +13,6 @@ import org.gcube.informationsystem.model.embedded.Header;
import org.gcube.informationsystem.model.entity.Entity; import org.gcube.informationsystem.model.entity.Entity;
import org.gcube.informationsystem.model.entity.Facet; import org.gcube.informationsystem.model.entity.Facet;
import org.gcube.informationsystem.model.entity.Resource; 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.ResourceRegistryException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException; import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAlreadyPresentException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAlreadyPresentException;
@ -301,16 +300,11 @@ public abstract class EntityManagement<E extends Entity> {
public boolean reallyAddToContext() throws ContextException, public boolean reallyAddToContext() throws ContextException,
ResourceRegistryException { ResourceRegistryException {
getVertex();
ContextUtility.addToActualContext(orientGraph, vertex); ContextUtility.addToActualContext(orientGraph, getVertex());
Iterable<Edge> edges = vertex.getEdges(Direction.OUT, ConsistsOf.NAME); Iterable<Edge> edges = vertex.getEdges(Direction.OUT);
/*
* Use this when the add integrity directive are inserted Iterable<Edge>
* edges = vertex.getEdges(Direction.OUT);
*/
for (Edge edge : edges) { for (Edge edge : edges) {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
RelationManagement relationManagement = RelationManagement RelationManagement relationManagement = RelationManagement
@ -323,7 +317,19 @@ public abstract class EntityManagement<E extends Entity> {
public boolean reallyRemoveFromContext() throws ContextException, public boolean reallyRemoveFromContext() throws ContextException,
ResourceRegistryException { ResourceRegistryException {
throw new UnsupportedOperationException();
ContextUtility.removeFromActualContext(orientGraph, getVertex());
Iterable<Edge> edges = vertex.getEdges(Direction.OUT);
for (Edge edge : edges) {
@SuppressWarnings("rawtypes")
RelationManagement relationManagement = RelationManagement
.getRelationManagement(orientGraph, edge);
relationManagement.reallyRemoveFromContext();
}
return true;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@ -337,7 +343,7 @@ public abstract class EntityManagement<E extends Entity> {
entityManagement = new FacetManagement(orientGraph); entityManagement = new FacetManagement(orientGraph);
} else { } else {
String error = String.format("{%s is not a %s nor a %s. " 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, + "Please Investigate it.", vertex, Resource.NAME,
Facet.NAME); Facet.NAME);
throw new ResourceRegistryException(error); throw new ResourceRegistryException(error);

View File

@ -52,8 +52,7 @@ public class FacetManagement extends EntityManagement<Facet> {
} }
public boolean reallyDelete() throws FacetNotFoundException, ResourceRegistryException { public boolean reallyDelete() throws FacetNotFoundException, ResourceRegistryException {
Vertex facet = getVertex(); getVertex().remove();
facet.remove();
return true; return true;
} }

View File

@ -193,7 +193,7 @@ public class ResourceManagement extends EntityManagement<Resource> {
} }
((OrientVertex) vertex).remove(); vertex.remove();
return true; return true;
} }

View File

@ -13,6 +13,7 @@ import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONObject;
import org.gcube.informationsystem.model.embedded.Header; import org.gcube.informationsystem.model.embedded.Header;
import org.gcube.informationsystem.model.embedded.PropagationConstraint; 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.embedded.PropagationConstraint.RemoveConstraint;
import org.gcube.informationsystem.model.entity.Entity; import org.gcube.informationsystem.model.entity.Entity;
import org.gcube.informationsystem.model.entity.Facet; import org.gcube.informationsystem.model.entity.Facet;
@ -257,11 +258,51 @@ public abstract class RelationManagement<R extends Relation> {
protected Edge reallyCreate(Vertex source, Vertex target) protected Edge reallyCreate(Vertex source, Vertex target)
throws ResourceRegistryException { throws ResourceRegistryException {
// TODO Check the relation compatibility between source and target
logger.trace("Creating {} ({}) beetween {} -> {}", EntityManagement sourceEntityManagement = EntityManagement
Relation.class.getSimpleName(), relationType, .getEntityManagement(orientGraph, source);
Utility.toJsonString(source, true), EntityManagement targetEntityManagement = EntityManagement
Utility.toJsonString(target, true)); .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); edge = orientGraph.addEdge(null, source, target, relationType);
@ -304,12 +345,10 @@ public abstract class RelationManagement<R extends Relation> {
public Edge reallyUpdate() throws ResourceRegistryException { public Edge reallyUpdate() throws ResourceRegistryException {
logger.debug("Trying to update {} : {}", relationClass.getSimpleName(), logger.debug("Trying to update {} : {}", relationType, jsonNode);
jsonNode);
Edge edge = getEdge(); Edge edge = getEdge();
ERManagement.updateProperties(edge, jsonNode, ignoreKeys, ERManagement.updateProperties(edge, jsonNode, ignoreKeys, ignoreStartWithKeys);
ignoreStartWithKeys);
if (ConsistsOf.class.isAssignableFrom(relationClass)) { if (ConsistsOf.class.isAssignableFrom(relationClass)) {
JsonNode target = jsonNode.get(Relation.TARGET_PROPERTY); JsonNode target = jsonNode.get(Relation.TARGET_PROPERTY);
@ -328,23 +367,106 @@ public abstract class RelationManagement<R extends Relation> {
public boolean reallyAddToContext() throws ContextException, public boolean reallyAddToContext() throws ContextException,
ResourceRegistryException { 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); try {
EntityManagement entityManagement = EntityManagement PropagationConstraint propagationConstraint = Utility.getEmbedded(
.getEntityManagement(orientGraph, vertex); PropagationConstraint.class, edge,
entityManagement.reallyAddToContext(); 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; 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, public boolean reallyRemoveFromContext() throws ContextException,
ResourceRegistryException { 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<Edge> iterable = target.getEdges(Direction.IN);
Iterator<Edge> 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() protected EntityManagement getEntityManagement()
@ -404,8 +526,9 @@ public abstract class RelationManagement<R extends Relation> {
try { try {
PropagationConstraint propagationConstraint = Utility.getEmbedded( PropagationConstraint propagationConstraint = Utility.getEmbedded(
PropagationConstraint.class, edge, Relation.PROPAGATION_CONSTRAINT); PropagationConstraint.class, edge,
if(propagationConstraint.getRemoveConstraint()!=null){ Relation.PROPAGATION_CONSTRAINT);
if (propagationConstraint.getRemoveConstraint() != null) {
removeConstraint = propagationConstraint.getRemoveConstraint(); removeConstraint = propagationConstraint.getRemoveConstraint();
} }
} catch (Exception e) { } catch (Exception e) {
@ -413,8 +536,7 @@ public abstract class RelationManagement<R extends Relation> {
+ "This is really strange and should not occur. " + "This is really strange and should not occur. "
+ "Please Investigate it.", + "Please Investigate it.",
Relation.PROPAGATION_CONSTRAINT, Relation.PROPAGATION_CONSTRAINT,
Utility.toJsonString(edge, true), Utility.toJsonString(edge, true), removeConstraint);
RemoveConstraint.keep);
} }
Vertex target = edge.getVertex(Direction.IN); Vertex target = edge.getVertex(Direction.IN);

View File

@ -24,7 +24,7 @@ import org.slf4j.LoggerFactory;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.metadata.security.OSecurity; import com.orientechnologies.orient.core.metadata.security.OSecurity;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; 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.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientGraph; import com.tinkerpop.blueprints.impls.orient.OrientGraph;
import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory; import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory;
@ -39,31 +39,31 @@ public class ContextUtility {
private static final Logger logger = LoggerFactory private static final Logger logger = LoggerFactory
.getLogger(ContextUtility.class); .getLogger(ContextUtility.class);
public static UUID addToActualContext(OrientGraph orientGraph, Vertex vertex) public static UUID addToActualContext(OrientGraph orientGraph, Element element)
throws ContextException { throws ContextException {
UUID contextUUID = ContextUtility.getActualContextUUID(); UUID contextUUID = ContextUtility.getActualContextUUID();
SecurityContext.addToSecurityContext(orientGraph, vertex, contextUUID); SecurityContext.addToSecurityContext(orientGraph, element, contextUUID);
return contextUUID; return contextUUID;
} }
public static UUID addToActualContex(OSecurity oSecurity, Vertex vertex) public static UUID addToActualContex(OSecurity oSecurity, Element element)
throws ContextException { throws ContextException {
UUID contextUUID = ContextUtility.getActualContextUUID(); UUID contextUUID = ContextUtility.getActualContextUUID();
SecurityContext.addToSecurityContext(oSecurity, vertex, contextUUID); SecurityContext.addToSecurityContext(oSecurity, element, contextUUID);
return contextUUID; return contextUUID;
} }
public static UUID addToActualContext(OrientGraph orientGraph, Edge edge) public static UUID removeFromActualContext(OrientGraph orientGraph, Element element)
throws ContextException { throws ContextException {
UUID contextUUID = ContextUtility.getActualContextUUID(); UUID contextUUID = ContextUtility.getActualContextUUID();
SecurityContext.addToSecurityContext(orientGraph, edge, contextUUID); SecurityContext.removeFromSecurityContext(orientGraph, element, contextUUID);
return contextUUID; return contextUUID;
} }
public static UUID addToActualContext(OSecurity oSecurity, Edge edge) public static UUID removeFromActualContext(OSecurity oSecurity, Element element)
throws ContextException { throws ContextException {
UUID contextUUID = ContextUtility.getActualContextUUID(); UUID contextUUID = ContextUtility.getActualContextUUID();
SecurityContext.addToSecurityContext(oSecurity, edge, contextUUID); SecurityContext.removeFromSecurityContext(oSecurity, element, contextUUID);
return contextUUID; return contextUUID;
} }