diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java index a47e99e..adf3617 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java @@ -38,6 +38,8 @@ import org.gcube.informationsystem.resourceregistry.instances.base.entities.Enti import org.gcube.informationsystem.resourceregistry.instances.model.ERManagement; import org.gcube.informationsystem.resourceregistry.instances.model.Operation; import org.gcube.informationsystem.resourceregistry.instances.model.relations.RelationManagement; +import org.gcube.informationsystem.resourceregistry.requests.RequestUtility; +import org.gcube.informationsystem.resourceregistry.requests.ServerRequestInfo; import org.gcube.informationsystem.resourceregistry.types.TypesCache; import org.gcube.informationsystem.resourceregistry.utils.MetadataUtility; import org.gcube.informationsystem.resourceregistry.utils.OrientDBUtility; @@ -495,20 +497,35 @@ public abstract class EntityManagement public String reallyGetAll(boolean polymorphic) throws ResourceRegistryException { ObjectMapper objectMapper = new ObjectMapper(); ArrayNode arrayNode = objectMapper.createArrayNode(); - + + ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get(); + int limit = requestInfo.getLimit(); + int offset = requestInfo.getOffset(); + + int position = -1; + int count = 0; + Iterable iterable = oDatabaseDocument.browseClass(typeName, polymorphic); for(ODocument vertex : iterable) { + if(++position < offset) { + continue; + } + EntityManagement entityManagement = ElementManagementUtility.getEntityManagement(getWorkingContext(), oDatabaseDocument, (OVertex) vertex); try { entityManagement.setAsEntryPoint(); JsonNode jsonNode = entityManagement.serializeAsJsonNode(); arrayNode.add(jsonNode); + if(++count >= limit) { + break; + } } catch(ResourceRegistryException e) { logger.error("Unable to correctly serialize {}. It will be excluded from results. {}", vertex.toString(), OrientDBUtility.SHOULD_NOT_OCCUR_ERROR_MESSAGE); } } + try { return objectMapper.writeValueAsString(arrayNode); } catch(JsonProcessingException e) { diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/relations/RelationManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/relations/RelationManagement.java index eb35694..0ce6f9c 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/relations/RelationManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/relations/RelationManagement.java @@ -39,6 +39,8 @@ import org.gcube.informationsystem.resourceregistry.instances.model.Operation; import org.gcube.informationsystem.resourceregistry.instances.model.entities.EntityManagement; import org.gcube.informationsystem.resourceregistry.instances.model.entities.FacetManagement; import org.gcube.informationsystem.resourceregistry.instances.model.entities.ResourceManagement; +import org.gcube.informationsystem.resourceregistry.requests.RequestUtility; +import org.gcube.informationsystem.resourceregistry.requests.ServerRequestInfo; import org.gcube.informationsystem.resourceregistry.types.TypesCache; import org.gcube.informationsystem.resourceregistry.utils.MetadataUtility; import org.gcube.informationsystem.resourceregistry.utils.OrientDBUtility; @@ -777,11 +779,23 @@ public abstract class RelationManagement serializeEdges(Iterable edges, boolean postFilterPolymorphic) + private Collection serializeEdges(Iterable edges, boolean postFilterPolymorphic) throws ResourceRegistryException { + + ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get(); + int limit = requestInfo.getLimit(); + int offset = requestInfo.getOffset(); + + int position = -1; + int count = 0; + // Map visitedSourceResources = new HashMap<>(); List serilizedEdges = new ArrayList<>(); for(ODocument d : edges) { + if(++position < offset) { + continue; + } + OEdge edge = (OEdge) d; if(postFilterPolymorphic && getOClass().isSubClassOf(typeName)) { @@ -792,6 +806,9 @@ public abstract class RelationManagement= limit) { + break; + } } return serilizedEdges; } 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 4ba2bcf..43c88bc 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/rest/Access.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/rest/Access.java @@ -220,6 +220,7 @@ public class Access extends BaseRest { ServerRequestInfo serverRequestInfo = initRequestInfo(); serverRequestInfo.checkAllBooleanQueryParameters(); + serverRequestInfo.checkLimitOffset(); ElementManagement erManagement = ElementManagementUtility.getERManagement(type); return erManagement.all(polymorphic); diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/instances/ERManagementTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/instances/ERManagementTest.java index 17e235f..d1ff057 100644 --- a/src/test/java/org/gcube/informationsystem/resourceregistry/instances/ERManagementTest.java +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/instances/ERManagementTest.java @@ -3,15 +3,20 @@ */ package org.gcube.informationsystem.resourceregistry.instances; +import java.io.IOException; import java.net.URI; import java.net.URL; import java.util.Calendar; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; +import org.gcube.com.fasterxml.jackson.core.JsonParseException; +import org.gcube.com.fasterxml.jackson.databind.JsonMappingException; import org.gcube.common.encryption.encrypter.StringEncrypter; import org.gcube.informationsystem.base.reference.IdentifiableElement; import org.gcube.informationsystem.model.impl.properties.EncryptedImpl; @@ -115,6 +120,8 @@ public class ERManagementTest extends ContextTest { ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get(); requestInfo.setIncludeMeta(true); requestInfo.setAllMeta(true); + requestInfo.setLimit(1000); + requestInfo.setOffset(0); } public static SoftwareFacet getSoftwareFacet() { @@ -730,4 +737,72 @@ public class ERManagementTest extends ContextTest { logger.debug("{}", ret); } + + @Test + public void testLimitOffsetWithHostingNode() throws ResourceRegistryException, JsonParseException, JsonMappingException, IOException { + ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get(); + int limit = 2; + requestInfo.setLimit(limit); + requestInfo.setOffset(0); + + ResourceManagement resourceManagement = new ResourceManagement(); + resourceManagement.setElementType(HostingNode.NAME); + String ret = resourceManagement.all(true); + logger.debug("{}", ret); + + List list = ElementMapper.unmarshalList(HostingNode.class, ret); + if(list.size()==0) { + return; + } + Assert.assertTrue(list.size() < 3); + + if(list.size()<2) { + return; + } + + Set uuids = new HashSet<>(); + for(HostingNode hn : list) { + UUID uuid = hn.getID(); + uuids.add(uuid); + logger.debug("Found {} with UUID {}", HostingNode.NAME, uuid); + } + + requestInfo.setOffset(2); + ret = resourceManagement.all(true); + logger.debug("{}", ret); + list = ElementMapper.unmarshalList(HostingNode.class, ret); + if(list.size()>0) { + Assert.assertTrue(list.size() < 3); + + for(HostingNode hn : list) { + UUID uuid = hn.getID(); + Assert.assertFalse(uuids.contains(uuid)); + uuids.add(uuid); + logger.debug("Found {} with UUID {}", HostingNode.NAME, uuid); + } + + if(list.size()<2) { + return; + } + + + int doubleLimit = limit*2; + requestInfo.setOffset(0); + requestInfo.setLimit(doubleLimit); + ret = resourceManagement.all(true); + logger.debug("{}", ret); + list = ElementMapper.unmarshalList(HostingNode.class, ret); + + Assert.assertTrue(list.size() <= doubleLimit); + + for(HostingNode hn : list) { + UUID uuid = hn.getID(); + logger.debug("Checking if {} with UUID {} was containe din the previous queries", HostingNode.NAME, uuid); + Assert.assertTrue(uuids.contains(uuid)); + logger.debug("As expected got {} with UUID {}", HostingNode.NAME, uuid); + } + } + + + } }