diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/er/entity/ResourceManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/er/entity/ResourceManagement.java index 3ed3537..b7537a6 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/er/entity/ResourceManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/er/entity/ResourceManagement.java @@ -4,6 +4,7 @@ package org.gcube.informationsystem.resourceregistry.er.entity; import java.util.Iterator; +import java.util.Map; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONObject; @@ -14,6 +15,9 @@ import org.gcube.informationsystem.model.relation.IsRelatedTo; import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceAlreadyPresentException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceNotFoundException; +import org.gcube.informationsystem.resourceregistry.api.rest.AccessPath; +import org.gcube.informationsystem.resourceregistry.context.ContextUtility; +import org.gcube.informationsystem.resourceregistry.context.SecurityContextMapper.PermissionMode; import org.gcube.informationsystem.resourceregistry.er.relation.ConsistsOfManagement; import org.gcube.informationsystem.resourceregistry.er.relation.IsRelatedToManagement; import org.gcube.informationsystem.resourceregistry.er.relation.RelationManagement; @@ -22,13 +26,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.JsonNode; +import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; import com.tinkerpop.blueprints.Direction; import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Element; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.blueprints.impls.orient.OrientEdge; import com.tinkerpop.blueprints.impls.orient.OrientEdgeType; +import com.tinkerpop.blueprints.impls.orient.OrientElement; import com.tinkerpop.blueprints.impls.orient.OrientGraph; import com.tinkerpop.blueprints.impls.orient.OrientVertex; +import com.tinkerpop.blueprints.impls.orient.OrientVertexType; /** * @author Luca Frosini (ISTI - CNR) @@ -227,5 +235,119 @@ public class ResourceManagement extends EntityManagement { return true; } + + + public String all(boolean polymorphic, Map constraint) throws ResourceRegistryException { + try { + orientGraph = ContextUtility + .getActualSecurityContextGraph(PermissionMode.READER); + + return reallyGetAll(polymorphic, constraint); + } catch (ResourceRegistryException e) { + throw e; + } catch (Exception e) { + throw new ResourceRegistryException(e); + } finally { + if (orientGraph != null) { + orientGraph.shutdown(); + } + } + } + + public String reallyGetAll(boolean polymorphic, Map constraint) throws ResourceRegistryException{ + JSONArray jsonArray = new JSONArray(); + + String relationType = constraint.get(AccessPath.RELATION_TYPE_PATH_PART); + constraint.remove(AccessPath.RELATION_TYPE_PATH_PART); + String facetType = constraint.get(AccessPath.FACET_TYPE_PATH_PART); + constraint.remove(AccessPath.FACET_TYPE_PATH_PART); + + /* + * SELECT FROM (TRAVERSE inE('isIdentifiedBy'), outV('EService') + * FROM (SELECT FROM SoftwareFacet WHERE group='VREManagement' AND name='SmartExecutor')) + * + * WHERE @class='EService' // Only is not polymorphic + */ + + boolean first = true; + + StringBuilder selectStringBuilder = new StringBuilder("SELECT FROM (TRAVERSE inE('"); + selectStringBuilder.append(relationType); + selectStringBuilder.append("'), outV('"); + selectStringBuilder.append(erType); + selectStringBuilder.append("') FROM (SELECT FROM "); + selectStringBuilder.append(facetType); + for(String key : constraint.keySet()){ + if(first){ + selectStringBuilder.append(" WHERE "); + first = false; + }else{ + selectStringBuilder.append(" AND "); + } + selectStringBuilder.append(key); + selectStringBuilder.append("="); + String value = constraint.get(key).trim(); + selectStringBuilder.append("'"); + selectStringBuilder.append(value); + selectStringBuilder.append("'"); + } + selectStringBuilder.append(" ))"); + + if(!polymorphic){ + selectStringBuilder.append(" WHERE @class='"); + selectStringBuilder.append(erType); + selectStringBuilder.append("'"); + } + + String select = selectStringBuilder.toString(); + logger.trace(select); + + + OSQLSynchQuery osqlSynchQuery = new OSQLSynchQuery( + select); + Iterable elements = orientGraph.command(osqlSynchQuery) + .execute(); + + for(Element element : elements){ + + if(polymorphic){ + OrientVertexType orientVertexType = null; + try { + OrientElement orientElement = ((OrientElement) element); + if(orientElement instanceof OrientEdge){ + continue; + } + orientVertexType = ((OrientVertex) orientElement).getType(); + }catch (Exception e) { + String error = String.format("Unable to detect type of %s. This is really strage please contact the administrator.", element.toString()); + logger.error(error, e); + throw new ResourceRegistryException(error); + } + + if(orientVertexType.getName().compareTo(erType)!=0){ + if(!orientVertexType.isSubClassOf(erType) ) { + continue; + } + } + + + } + + Vertex vertex = (Vertex) element; + + @SuppressWarnings("rawtypes") + EntityManagement entityManagement = EntityManagement.getEntityManagement(orientGraph, vertex); + try { + JSONObject jsonObject = entityManagement.serializeAsJson(); + jsonArray.put(jsonObject); + }catch (ResourceRegistryException e) { + logger.error("Unable to correctly serialize {}. It will be excluded from results. This is really strange and should not occur.", vertex.toString()); + } + } + + + return jsonArray.toString(); + } + } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/rest/Access.java b/src/main/java/org/gcube/informationsystem/resourceregistry/rest/Access.java index 2e12e77..ef9561a 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/rest/Access.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/rest/Access.java @@ -1,6 +1,8 @@ package org.gcube.informationsystem.resourceregistry.rest; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; import javax.ws.rs.DefaultValue; @@ -10,10 +12,15 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.UriInfo; import org.gcube.common.authorization.library.provider.CalledMethodProvider; +import org.gcube.informationsystem.model.entity.Facet; +import org.gcube.informationsystem.model.relation.ConsistsOf; import org.gcube.informationsystem.resourceregistry.ResourceInitializer; import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERAvailableInAnotherContextException; @@ -24,6 +31,7 @@ import org.gcube.informationsystem.resourceregistry.api.rest.AccessPath; import org.gcube.informationsystem.resourceregistry.api.rest.httputils.HTTPCall.HTTPMETHOD; import org.gcube.informationsystem.resourceregistry.er.ERManagement; import org.gcube.informationsystem.resourceregistry.er.entity.EntityManagement; +import org.gcube.informationsystem.resourceregistry.er.entity.ResourceManagement; import org.gcube.informationsystem.resourceregistry.er.relation.RelationManagement; import org.gcube.informationsystem.resourceregistry.query.Query; import org.gcube.informationsystem.resourceregistry.query.QueryImpl; @@ -213,6 +221,45 @@ public class Access { throw new ResourceRegistryException("Invalid Request"); } + + + /* + * e.g. GET /resource-registry/access/resourceInstances/EService/isIdentifiedBy/SoftwareFacet?polymorphic=true + */ + @SuppressWarnings({ "rawtypes" }) + @GET + @Path(AccessPath.RESOURCE_INSTANCES_PATH_PART + "/" + "{" + TYPE_PATH_PARAM + "}" + + "/" + "{" + AccessPath.RELATION_TYPE_PATH_PART + "}"+ "/" + "{" + AccessPath.FACET_TYPE_PATH_PART + "}") + @Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8) + public String getFilteredInstances( + @PathParam(TYPE_PATH_PARAM) String type, + @PathParam(AccessPath.RELATION_TYPE_PATH_PART) @DefaultValue(ConsistsOf.NAME) String relationType, + @PathParam(AccessPath.FACET_TYPE_PATH_PART) @DefaultValue(Facet.NAME) String facetType, + @QueryParam(AccessPath.POLYMORPHIC_PARAM) @DefaultValue("false") Boolean polymorphic, + @Context UriInfo uriInfo) + throws ResourceRegistryException { + logger.info("Requested {} ({}={}) instances", type, + AccessPath.POLYMORPHIC_PARAM, polymorphic); + + MultivaluedMap multivaluedMap = uriInfo.getQueryParameters(); + + Map constraint = new HashMap<>(); + for(String key : multivaluedMap.keySet()){ + constraint.put(key, multivaluedMap.getFirst(key)); + } + constraint.put(AccessPath.RELATION_TYPE_PATH_PART, relationType); + constraint.put(AccessPath.FACET_TYPE_PATH_PART, facetType); + + ERManagement erManagement = ERManagement.getERManagement(type); + + if (erManagement instanceof ResourceManagement) { + return ((ResourceManagement) erManagement).all(polymorphic, constraint); + } + + throw new ResourceRegistryException("Invalid Request"); + } + + /* * e.g. GET /resource-registry/access/schema/ContactFacet?polymorphic=true diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/er/entity/ResourceManagementTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/er/entity/ResourceManagementTest.java new file mode 100644 index 0000000..2a2b868 --- /dev/null +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/er/entity/ResourceManagementTest.java @@ -0,0 +1,52 @@ +package org.gcube.informationsystem.resourceregistry.er.entity; + +import java.util.HashMap; +import java.util.Map; + +import org.gcube.informationsystem.model.entity.facet.SoftwareFacet; +import org.gcube.informationsystem.model.entity.resource.Service; +import org.gcube.informationsystem.model.relation.ConsistsOf; +import org.gcube.informationsystem.resourceregistry.ScopedTest; +import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; +import org.gcube.informationsystem.resourceregistry.api.rest.AccessPath; +import org.gcube.informationsystem.resourceregistry.er.ERManagement; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ResourceManagementTest extends ScopedTest { + + private static Logger logger = LoggerFactory.getLogger(ResourceManagementTest.class); + + @Test + public void testAllWithCostraint() throws ResourceRegistryException { + String relationType = ConsistsOf.NAME; + String facetType = SoftwareFacet.NAME; + + Map constraint = new HashMap<>(); + constraint.put(AccessPath.RELATION_TYPE_PATH_PART, relationType); + constraint.put(AccessPath.FACET_TYPE_PATH_PART, facetType); + + + constraint.put(SoftwareFacet.GROUP_PROPERTY, "Gis"); + constraint.put(SoftwareFacet.NAME_PROPERTY, "Thredds"); + + String type = Service.NAME; + + @SuppressWarnings("rawtypes") + ERManagement erManagement = ERManagement.getERManagement(type); + + if (erManagement instanceof ResourceManagement) { + String ret = ((ResourceManagement) erManagement).all(false, constraint); + logger.debug(ret); + + constraint.put(AccessPath.RELATION_TYPE_PATH_PART, relationType); + constraint.put(AccessPath.FACET_TYPE_PATH_PART, facetType); + ret = ((ResourceManagement) erManagement).all(true, constraint); + logger.debug(ret); + } + + + } + +}