Fixed cascading management on add and remove from context

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/information-system/resource-registry@146290 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Luca Frosini 2017-03-23 12:37:15 +00:00
parent 1647e73e8d
commit 09dae86c43
7 changed files with 280 additions and 55 deletions

View File

@ -31,9 +31,9 @@ import org.gcube.informationsystem.model.relation.IsRelatedTo;
import org.gcube.informationsystem.model.relation.Relation; import org.gcube.informationsystem.model.relation.Relation;
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.EntityNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetNotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceNotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationNotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException;
import org.gcube.informationsystem.resourceregistry.context.ContextUtility; import org.gcube.informationsystem.resourceregistry.context.ContextUtility;
@ -320,10 +320,10 @@ public abstract class ERManagement<ERType extends ER, El extends Element> {
public abstract JSONObject serializeAsJson() public abstract JSONObject serializeAsJson()
throws ResourceRegistryException; throws ResourceRegistryException;
public abstract El reallyUpdate() throws EntityNotFoundException, public abstract El reallyUpdate() throws ERNotFoundException,
ResourceRegistryException; ResourceRegistryException;
public abstract boolean reallyDelete() throws EntityNotFoundException, public abstract boolean reallyDelete() throws ERNotFoundException,
ResourceRegistryException; ResourceRegistryException;
public abstract boolean reallyAddToContext() throws ContextException, public abstract boolean reallyAddToContext() throws ContextException,
@ -342,8 +342,7 @@ public abstract class ERManagement<ERType extends ER, El extends Element> {
} }
protected void throwElementNotFoundException(ResourceRegistryException e) protected void throwElementNotFoundException(ResourceRegistryException e)
throws EntityNotFoundException, RelationNotFoundException, throws ERNotFoundException, ResourceRegistryException {
ResourceRegistryException {
if (Resource.class.isAssignableFrom(erTypeClass)) { if (Resource.class.isAssignableFrom(erTypeClass)) {
throw new ResourceNotFoundException(e); throw new ResourceNotFoundException(e);
@ -389,7 +388,7 @@ public abstract class ERManagement<ERType extends ER, El extends Element> {
} }
} }
public String read() throws EntityNotFoundException, public String read() throws ERNotFoundException,
ResourceRegistryException { ResourceRegistryException {
try { try {
orientGraph = ContextUtility orientGraph = ContextUtility
@ -409,7 +408,7 @@ public abstract class ERManagement<ERType extends ER, El extends Element> {
} }
} }
public String update() throws RelationNotFoundException, public String update() throws ERNotFoundException,
ResourceRegistryException { ResourceRegistryException {
try { try {
@ -439,7 +438,7 @@ public abstract class ERManagement<ERType extends ER, El extends Element> {
} }
} }
public boolean delete() throws FacetNotFoundException, public boolean delete() throws ERNotFoundException,
ResourceRegistryException { ResourceRegistryException {
logger.debug("Going to delete {} with UUID {}", baseType, uuid); logger.debug("Going to delete {} with UUID {}", baseType, uuid);
@ -475,7 +474,7 @@ public abstract class ERManagement<ERType extends ER, El extends Element> {
} }
} }
public boolean addToContext() throws ContextException { public boolean addToContext() throws ERNotFoundException, ContextException {
logger.debug("Going to add {} with UUID {} to actual Context", logger.debug("Going to add {} with UUID {} to actual Context",
baseType, uuid); baseType, uuid);
@ -505,7 +504,7 @@ public abstract class ERManagement<ERType extends ER, El extends Element> {
} }
} }
public boolean removeFromContext() throws ContextException { public boolean removeFromContext() throws ERNotFoundException, ContextException {
logger.debug("Going to remove {} with UUID {} from actual Context", logger.debug("Going to remove {} with UUID {} from actual Context",
baseType, uuid); baseType, uuid);

View File

@ -148,7 +148,7 @@ public abstract class EntityManagement<E extends Entity> extends
ResourceRegistryException { ResourceRegistryException {
ContextUtility.removeFromActualContext(orientGraph, getElement()); ContextUtility.removeFromActualContext(orientGraph, getElement());
Iterable<Edge> edges = element.getEdges(Direction.OUT); Iterable<Edge> edges = element.getEdges(Direction.OUT);
for (Edge edge : edges) { for (Edge edge : edges) {

View File

@ -27,6 +27,7 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegis
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.relation.RelationNotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationNotFoundException;
import org.gcube.informationsystem.resourceregistry.context.ContextUtility; import org.gcube.informationsystem.resourceregistry.context.ContextUtility;
import org.gcube.informationsystem.resourceregistry.context.SecurityContextMapper;
import org.gcube.informationsystem.resourceregistry.context.SecurityContextMapper.PermissionMode; import org.gcube.informationsystem.resourceregistry.context.SecurityContextMapper.PermissionMode;
import org.gcube.informationsystem.resourceregistry.er.ERManagement; import org.gcube.informationsystem.resourceregistry.er.ERManagement;
import org.gcube.informationsystem.resourceregistry.er.entity.EntityManagement; import org.gcube.informationsystem.resourceregistry.er.entity.EntityManagement;
@ -305,28 +306,50 @@ public abstract class RelationManagement<R extends Relation> extends
Vertex target = element.getVertex(Direction.IN); Vertex target = element.getVertex(Direction.IN);
switch (addConstraint) { switch (addConstraint) {
case propagate: case propagate:
/* /*
* The relation must be added only in the case the target vertex * The relation must be added only in the case the target vertex
* must be added. Otherwise we have a relation which point to an * must be added. Otherwise we have a relation which point to an
* entity outside of the context. * entity outside of the context.
*/ */
ContextUtility.addToActualContext(orientGraph, getElement()); ContextUtility.addToActualContext(orientGraph, getElement());
EntityManagement entityManagement = EntityManagement EntityManagement entityManagement = EntityManagement
.getEntityManagement(orientGraph, target); .getEntityManagement(orientGraph, target);
entityManagement.reallyAddToContext(); entityManagement.reallyAddToContext();
break; break;
case unpropagate: case unpropagate:
break; break;
default: default:
break; break;
} }
return true; return true;
} }
public boolean forcedAddToContext() throws ContextException,
ResourceRegistryException {
getElement();
/* Adding source to Context */
Vertex source = element.getVertex(Direction.OUT);
EntityManagement entityManagement = EntityManagement
.getEntityManagement(orientGraph, source);
entityManagement.reallyAddToContext();
/* Adding target to Context */
Vertex target = element.getVertex(Direction.IN);
entityManagement = EntityManagement
.getEntityManagement(orientGraph, target);
entityManagement.reallyAddToContext();
ContextUtility.addToActualContext(orientGraph, getElement());
return true;
}
protected boolean removeFromContextTargetVertex(Vertex target) protected boolean removeFromContextTargetVertex(Vertex target)
throws ResourceRegistryException { throws ResourceRegistryException {
EntityManagement entityManagement = EntityManagement EntityManagement entityManagement = EntityManagement
@ -338,7 +361,7 @@ public abstract class RelationManagement<R extends Relation> extends
return false; return false;
} }
} }
@Override @Override
public boolean reallyRemoveFromContext() throws ContextException, public boolean reallyRemoveFromContext() throws ContextException,
ResourceRegistryException { ResourceRegistryException {
@ -364,33 +387,48 @@ public abstract class RelationManagement<R extends Relation> extends
Vertex target = element.getVertex(Direction.IN); Vertex target = element.getVertex(Direction.IN);
/* /*
* In any removeConstraint value the relation MUSt be removed from * In any removeConstraint value the relation MUST be removed from
* context to avoid to have edge having a source outside of the context. * context to avoid to have edge having a source outside of the context.
*/ */
ContextUtility.removeFromActualContext(orientGraph, element); ContextUtility.removeFromActualContext(orientGraph, element);
switch (removeConstraint) { switch (removeConstraint) {
case cascade: 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.",
element, target, removeConstraint);
} else {
removeFromContextTargetVertex(target); removeFromContextTargetVertex(target);
} break;
break;
case cascadeWhenOrphan:
case keep: Iterable<Edge> iterable = target.getEdges(Direction.IN);
break; Iterator<Edge> iterator = iterable.iterator();
int count = 0;
default: OrientEdge edge = null;
break; while (iterator.hasNext()) {
edge = (OrientEdge) iterator.next();
OrientEdge thisOrientEdge = (OrientEdge) element;
if(edge.compareTo(thisOrientEdge)!=0){
if(thisOrientEdge.getOutVertex().compareTo(edge.getOutVertex())!=0){
count++;
break;
}else{
ContextUtility.removeFromActualContext(orientGraph, edge);
}
}
}
if (count>0) {
logger.trace(
"{} point to {} which is not orphan ({} exists). Giving {} directive, it will be not remove from current context.",
element, target, edge, removeConstraint);
} else {
removeFromContextTargetVertex(target);
}
break;
case keep:
break;
default:
break;
} }
return true; return true;
@ -602,4 +640,35 @@ public abstract class RelationManagement<R extends Relation> extends
} }
} }
@Override
public boolean addToContext() throws ContextException {
logger.debug("Going to add {} with UUID {} to actual Context",
baseType, uuid);
try {
orientGraph = SecurityContextMapper.getSecurityContextFactory(
SecurityContextMapper.ADMIN_SECURITY_CONTEXT_UUID,
PermissionMode.WRITER).getTx();
boolean added = forcedAddToContext();
orientGraph.commit();
logger.info("{} with UUID {} successfully added to actual Context",
baseType, uuid);
return added;
} catch (Exception e) {
logger.error("Unable to add {} with UUID {} to actual Context",
baseType, uuid, e);
if (orientGraph != null) {
orientGraph.rollback();
}
throw new ContextException(e);
} finally {
if (orientGraph != null) {
orientGraph.shutdown();
}
}
}
} }

View File

@ -59,7 +59,7 @@ public class ScopedTest {
GCUBE_DEVSEC = properties.getProperty(GCUBE_DEVSEC_VARNAME); GCUBE_DEVSEC = properties.getProperty(GCUBE_DEVSEC_VARNAME);
GCUBE_DEVSEC_DEVVRE = properties.getProperty(GCUBE_DEVSEC_DEVVRE_VARNAME); GCUBE_DEVSEC_DEVVRE = properties.getProperty(GCUBE_DEVSEC_DEVVRE_VARNAME);
DEFAULT_TEST_SCOPE = GCUBE_DEVNEXT; DEFAULT_TEST_SCOPE = GCUBE_DEVNEXT_NEXTNEXT;
ALTERNATIVE_TEST_SCOPE = GCUBE_DEVSEC; ALTERNATIVE_TEST_SCOPE = GCUBE_DEVSEC;
} }

View File

@ -194,7 +194,7 @@ public class ContextManagementImplTest {
logger.debug("The DB should be now clean"); logger.debug("The DB should be now clean");
} }
@Test //@Test
public void createDevContext() throws Exception { public void createDevContext() throws Exception {
String gcubeJson = contextManagementImpl.create(null, "gcube"); String gcubeJson = contextManagementImpl.create(null, "gcube");
Context gcubeContext = ISMapper.unmarshal(Context.class, gcubeJson); Context gcubeContext = ISMapper.unmarshal(Context.class, gcubeJson);

View File

@ -9,7 +9,7 @@ import java.util.Calendar;
import java.util.UUID; import java.util.UUID;
import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONObject;
import org.gcube.common.scope.api.ScopeProvider; import org.gcube.informationsystem.impl.embedded.PropagationConstraintImpl;
import org.gcube.informationsystem.impl.entity.facet.AccessPointFacetImpl; import org.gcube.informationsystem.impl.entity.facet.AccessPointFacetImpl;
import org.gcube.informationsystem.impl.entity.facet.CPUFacetImpl; import org.gcube.informationsystem.impl.entity.facet.CPUFacetImpl;
import org.gcube.informationsystem.impl.entity.facet.EventFacetImpl; import org.gcube.informationsystem.impl.entity.facet.EventFacetImpl;
@ -26,6 +26,9 @@ import org.gcube.informationsystem.impl.relation.consistsof.HasVolatileMemoryImp
import org.gcube.informationsystem.impl.relation.isrelatedto.HostsImpl; import org.gcube.informationsystem.impl.relation.isrelatedto.HostsImpl;
import org.gcube.informationsystem.impl.utils.ISMapper; import org.gcube.informationsystem.impl.utils.ISMapper;
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.AddConstraint;
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;
import org.gcube.informationsystem.model.entity.facet.AccessPointFacet; import org.gcube.informationsystem.model.entity.facet.AccessPointFacet;
@ -46,9 +49,13 @@ import org.gcube.informationsystem.model.relation.isrelatedto.Hosts;
import org.gcube.informationsystem.resourceregistry.ScopedTest; import org.gcube.informationsystem.resourceregistry.ScopedTest;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextNotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceNotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationNotFoundException;
import org.gcube.informationsystem.resourceregistry.er.SmartgearResourcesTest;
import org.gcube.informationsystem.resourceregistry.er.entity.FacetManagement; import org.gcube.informationsystem.resourceregistry.er.entity.FacetManagement;
import org.gcube.informationsystem.resourceregistry.er.entity.ResourceManagement; import org.gcube.informationsystem.resourceregistry.er.entity.ResourceManagement;
import org.gcube.informationsystem.resourceregistry.er.relation.IsRelatedToManagement;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -304,10 +311,149 @@ public class MultiContextTest extends ScopedTest {
// @Test // @Test
public void addTest() throws ResourceNotFoundException, public void addTest() throws ResourceNotFoundException,
ContextNotFoundException, ResourceRegistryException { ContextNotFoundException, ResourceRegistryException {
ScopeProvider.instance.set("/gcube/devNext/NextNext");
ResourceManagement resourceManagement = new ResourceManagement(); ResourceManagement resourceManagement = new ResourceManagement();
resourceManagement.setUUID(UUID.fromString("")); resourceManagement.setUUID(UUID.fromString(""));
resourceManagement.addToContext(); resourceManagement.addToContext();
} }
@Test
public void testAddAndRemoveFromContext() throws Exception {
/* Creating HostingNode */
ResourceManagement resourceManagement = new ResourceManagement();
resourceManagement.setElementType(HostingNode.NAME);
resourceManagement.setJSON(SmartgearResourcesTest.HOSTING_NODE);
String hnJson = resourceManagement.create();
logger.debug("Created : {}", hnJson);
HostingNode hostingNode = ISMapper.unmarshal(HostingNode.class, hnJson);
logger.debug("Unmarshalled {} {}", HostingNode.NAME, hostingNode);
UUID hnUUID = hostingNode.getHeader().getUUID();
/* Creating EService */
resourceManagement = new ResourceManagement();
resourceManagement.setElementType(EService.NAME);
resourceManagement.setJSON(SmartgearResourcesTest.ESERVICE);
String eservicejson = resourceManagement.create();
logger.debug("Created : {}", eservicejson);
EService eService = ISMapper.unmarshal(EService.class, eservicejson);
logger.debug("Unmarshalled {} {}", EService.NAME, eService);
UUID eServiceUUID = eService.getHeader().getUUID();
/* Creating Hosts Relation */
PropagationConstraint propagationConstraint = new PropagationConstraintImpl();
propagationConstraint
.setRemoveConstraint(RemoveConstraint.cascade);
propagationConstraint
.setAddConstraint(AddConstraint.propagate);
Hosts<HostingNode, EService> hosts = new HostsImpl<>(hostingNode, eService,
propagationConstraint);
IsRelatedToManagement isRelatedToManagement = new IsRelatedToManagement();
isRelatedToManagement.setElementType(Hosts.NAME);
String hostsJson = ISMapper.marshal(hosts);
isRelatedToManagement.setJSON(hostsJson);
String createdHostsJson = isRelatedToManagement.create(hnUUID, eServiceUUID);
logger.debug("Created : {}", createdHostsJson);
@SuppressWarnings("unchecked")
Hosts<HostingNode, EService> createdHosts = ISMapper.unmarshal(Hosts.class, createdHostsJson);
UUID hostsUUID = createdHosts.getHeader().getUUID();
/* ------------------------------------------------------------------ */
logger.debug("Switching to alternative scope");
ScopedTest.setContext(ScopedTest.ALTERNATIVE_TEST_SCOPE);
/*
* resourceManagement = new ResourceManagement();
* resourceManagement.setUUID(hnUUID);
* resourceManagement.addToContext();
* resourceManagement = new ResourceManagement();
* resourceManagement.setUUID(eServiceUUID);
* resourceManagement.addToContext();
*
* This code is commented because the addToContext
* on relation enforce addToContext both on source
* and target
*
*/
isRelatedToManagement = new IsRelatedToManagement();
isRelatedToManagement.setUUID(hostsUUID);
isRelatedToManagement.addToContext();
/* The addTocontext on the relation adds the source and target too.
* So that I MUST be able to read HostinNode and EService
*/
resourceManagement = new ResourceManagement();
resourceManagement.setUUID(hnUUID);
resourceManagement.read();
resourceManagement = new ResourceManagement();
resourceManagement.setUUID(eServiceUUID);
resourceManagement.read();
/* ------------------------------------------------------------------ */
logger.debug("Setting back default scope");
ScopedTest.setContext(ScopedTest.DEFAULT_TEST_SCOPE);
resourceManagement = new ResourceManagement();
resourceManagement.setUUID(hnUUID);
boolean removed = resourceManagement.removeFromContext();
Assert.assertTrue(removed);
/* The cascading MUST remove the relation and the target so that
* I MUST not be able to read Hosts relation and EService
*/
resourceManagement = new ResourceManagement();
resourceManagement.setUUID(eServiceUUID);
try {
resourceManagement.read();
String error = String.format("{} with UUID {} should not be visible.", EService.NAME, eServiceUUID);
logger.trace(error);
throw new Exception(error);
}catch (EntityNotFoundException e) {
// OK
}
isRelatedToManagement = new IsRelatedToManagement();
isRelatedToManagement.setUUID(hostsUUID);
try {
isRelatedToManagement.read();
String error = String.format("{} with UUID {} should not be visible.", Hosts.NAME, hostsUUID);
logger.trace(error);
throw new Exception(error);
}catch (RelationNotFoundException e) {
// OK
}
/* ------------------------------------------------------------------ */
logger.debug("Switching to alternative scope again");
ScopedTest.setContext(ScopedTest.ALTERNATIVE_TEST_SCOPE);
// TODO checks here
resourceManagement = new ResourceManagement();
resourceManagement.setUUID(hnUUID);
boolean deleted = resourceManagement.delete();
Assert.assertTrue(deleted);
}
} }

View File

@ -99,7 +99,7 @@ public class SmartgearResourcesTest extends ScopedTest {
resourceManagement.setUUID(hnUUID); resourceManagement.setUUID(hnUUID);
String read = resourceManagement.read(); String read = resourceManagement.read();
HostingNode readHN = ISMapper.unmarshal(HostingNode.class, read); HostingNode readHN = ISMapper.unmarshal(HostingNode.class, read);
logger.debug("Read {} {}", EService.NAME, readHN); logger.debug("Read {} {}", HostingNode.NAME, readHN);
Assert.assertTrue(hnUUID.compareTo(readHN.getHeader().getUUID()) == 0); Assert.assertTrue(hnUUID.compareTo(readHN.getHeader().getUUID()) == 0);
@ -109,6 +109,17 @@ public class SmartgearResourcesTest extends ScopedTest {
Assert.assertTrue(deleted); Assert.assertTrue(deleted);
} }
public void deleteResource() throws Exception {
UUID uuid = UUID.fromString("");
ResourceManagement resourceManagement = new ResourceManagement();
resourceManagement.setUUID(uuid);
//resourceManagement.removeFromContext();
boolean deleted = resourceManagement.delete();
Assert.assertTrue(deleted);
}
@Test @Test
public void testEService() throws JsonParseException, JsonMappingException, public void testEService() throws JsonParseException, JsonMappingException,
IOException, ResourceRegistryException { IOException, ResourceRegistryException {