Added pagination to contexts

This commit is contained in:
luca.frosini 2023-09-22 19:06:05 +02:00
parent 8c5dcd0341
commit ee8bdefa8b
4 changed files with 147 additions and 6 deletions

View File

@ -85,7 +85,9 @@ public class ServerContextCache extends ContextCache {
@Override
public List<Context> renew() throws ResourceRegistryException {
ContextManagement contextManagement = new ContextManagement();
String contextsJsonString = contextManagement.allFromServer(false);
contextManagement.setForceOffset(0);
contextManagement.setForceLimit(-1);
String contextsJsonString = contextManagement.allFromDatabase(false);
List<Context> contexts = null;
try {
contexts = ElementMapper.unmarshalList(contextsJsonString);

View File

@ -1,5 +1,6 @@
package org.gcube.informationsystem.resourceregistry.contexts.entities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@ -33,6 +34,8 @@ import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityCo
import org.gcube.informationsystem.resourceregistry.instances.base.entities.EntityElementManagement;
import org.gcube.informationsystem.resourceregistry.queries.operators.QueryConditionalOperator;
import org.gcube.informationsystem.resourceregistry.queries.operators.QueryLogicalOperator;
import org.gcube.informationsystem.resourceregistry.requests.RequestUtility;
import org.gcube.informationsystem.resourceregistry.requests.ServerRequestInfo;
import org.gcube.informationsystem.resourceregistry.utils.OrientDBUtility;
import org.gcube.informationsystem.serialization.ElementMapper;
import org.gcube.informationsystem.types.reference.entities.EntityType;
@ -56,6 +59,16 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
private static Logger logger = LoggerFactory.getLogger(ContextManagement.class);
protected String name;
protected Integer forceOffset;
protected Integer forceLimit;
public void setForceOffset(Integer forceOffset) {
this.forceOffset = forceOffset;
}
public void setForceLimit(Integer forceLimit) {
this.forceLimit = forceLimit;
}
private void init() {
this.ignoreStartWithKeys.add(Context.PARENT_PROPERTY);
@ -63,6 +76,8 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
this.typeName = Context.NAME;
this.forceIncludeMeta = true;
this.forceIncludeAllMeta = true;
this.forceOffset = null;
this.forceLimit = null;
}
public ContextManagement() {
@ -412,8 +427,27 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
public String reallyGetAll(boolean polymorphic) throws ResourceRegistryException {
ObjectMapper objectMapper = new ObjectMapper();
ArrayNode arrayNode = objectMapper.createArrayNode();
ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get();
int limit = requestInfo.getLimit();
if(forceLimit!=null) {
limit = forceLimit;
}
int offset = requestInfo.getOffset();
if(forceOffset!=null) {
offset = forceOffset;
}
int position = -1;
int count = 0;
Iterable<ODocument> iterable = oDatabaseDocument.browseClass(typeName, polymorphic);
for (ODocument vertex : iterable) {
if(++position < offset) {
continue;
}
ContextManagement contextManagement = new ContextManagement();
contextManagement.setForceIncludeMeta(forceIncludeMeta);
contextManagement.setForceIncludeAllMeta(forceIncludeAllMeta);
@ -421,6 +455,9 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
try {
JsonNode jsonObject = contextManagement.serializeAsJsonNode();
arrayNode.add(jsonObject);
if(limit > 0 && ++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);
@ -433,7 +470,7 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
}
}
public String allFromServer(boolean polymorphic) throws ResourceRegistryException {
public String allFromDatabase(boolean polymorphic) throws ResourceRegistryException {
return super.all(polymorphic);
}
@ -442,9 +479,41 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
try {
ServerContextCache contextCache = ServerContextCache.getInstance();
List<Context> contexts = contextCache.getContexts();
return ElementMapper.marshal(contexts);
ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get();
int limit = requestInfo.getLimit();
if(forceLimit!=null) {
limit = forceLimit;
}
int offset = requestInfo.getOffset();
if(forceOffset!=null) {
offset = forceOffset;
}
int position = -1;
int count = 0;
if(offset==0 && limit<=0) {
return ElementMapper.marshal(contexts);
}
List<Context> requestedContexts = new ArrayList<>();
for (Context c : contexts) {
if(++position < offset) {
continue;
}
requestedContexts.add(c);
if(limit > 0 && ++count >= limit) {
break;
}
}
return ElementMapper.marshal(requestedContexts);
} catch (JsonProcessingException | ResourceRegistryException e) {
return allFromServer(polymorphic);
return allFromDatabase(polymorphic);
}
}

View File

@ -1,8 +1,10 @@
package org.gcube.informationsystem.resourceregistry.contexts;
import java.io.IOException;
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.JsonProcessingException;
@ -441,7 +443,13 @@ public class ContextManagementTest extends ContextTest {
}
private List<Context> getAll() throws Exception {
return getAll(0, -1);
}
private List<Context> getAll(Integer forceOffset, Integer forcelimit) throws Exception {
ContextManagement contextManagement = new ContextManagement();
contextManagement.setForceOffset(forceOffset);
contextManagement.setForceLimit(forcelimit);
String allString = contextManagement.all(false);
logger.trace(allString);
List<Context> all = ElementMapper.unmarshalList(Context.class, allString);
@ -494,11 +502,10 @@ public class ContextManagementTest extends ContextTest {
delete(context);
}
@Test
public void testContextCache() throws Exception {
List<Context> contexts = getAll();
logger.debug("{}", contexts);
logger.info("{}", contexts);
ServerContextCache contextCache = ServerContextCache.getInstance();
Map<UUID, String> uuidToContextFullName = contextCache.getUUIDToContextFullNameAssociation();
@ -537,4 +544,66 @@ public class ContextManagementTest extends ContextTest {
logger.debug("{} - {} : {}", uuid, fullName, context);
}
}
@Test
public void testLimitOffset() throws Exception {
int limit = 2;
List<Context> contexts = getAll(0, limit);
if(contexts.size()==0) {
return;
}
Assert.assertTrue(contexts.size() <= limit);
if(contexts.size()< limit) {
return;
}
Set<UUID> uuids = new HashSet<>();
for(Context context : contexts) {
UUID uuid = context.getID();
uuids.add(uuid);
logger.info("Found {} with UUID {} and name {}", Context.NAME, uuid, context.getName());
}
contexts = getAll(limit, limit);
if(contexts.size()>0) {
Assert.assertTrue(contexts.size() <= limit);
for(Context context : contexts) {
UUID uuid = context.getID();
Assert.assertFalse(uuids.contains(uuid));
uuids.add(uuid);
logger.info("Found {} with UUID {} and name {}", Context.NAME, uuid, context.getName());
}
if(contexts.size()<limit) {
return;
}
int doubleLimit = limit*2;
contexts = getAll(0, doubleLimit);
Assert.assertTrue(contexts.size() <= doubleLimit);
for(Context context : contexts) {
UUID uuid = context.getID();
logger.info("Checking if {} with UUID {} and name {} was contained in the previous queries", Context.NAME, uuid, context.getName());
Assert.assertTrue(uuids.contains(uuid));
logger.info("As expected got {} with UUID {} and name {}", Context.NAME, uuid, context.getName());
}
}
contexts = getAll();
Assert.assertTrue(contexts.size()>=uuids.size());
for(Context context : contexts) {
UUID uuid = context.getID();
logger.info("No limit listing: Got {} with UUID {} and name {}", Context.NAME, uuid, context.getName());
}
}
}

View File

@ -14,6 +14,7 @@
<logger name="org.gcube.informationsystem.types" level="INFO" />
<logger name="org.gcube.informationsystem.resourceregistry.dbinitialization" level="INFO" />
<logger name="org.gcube.informationsystem.utils.discovery" level="ERROR" />
<logger name="org.gcube.informationsystem.resourceregistry.contexts" level="INFO" />
<logger name="org.gcube.informationsystem.resourceregistry.types" level="TRACE" />
<logger name="org.gcube.informationsystem.resourceregistry.instances" level="TRACE" />