geoportal-data-common/src/main/java/org/gcube/application/geoportalcommon/geoportal/ProjectsCaller.java

392 lines
13 KiB
Java

package org.gcube.application.geoportalcommon.geoportal;
import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.projects;
import java.io.File;
import java.io.FileNotFoundException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.bson.Document;
import org.gcube.application.geoportal.common.faults.InvalidRequestException;
import org.gcube.application.geoportal.common.model.configuration.Configuration;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.model.rest.QueryRequest.OrderedRequest;
import org.gcube.application.geoportal.common.model.rest.QueryRequest.OrderedRequest.Direction;
import org.gcube.application.geoportal.common.model.rest.QueryRequest.PagedRequest;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.rest.Projects;
import org.gcube.application.geoportal.common.utils.FileSets;
import org.gcube.application.geoportal.common.utils.StorageUtils;
import org.gcube.application.geoportalcommon.ConvertToDataValueObjectModel;
import org.gcube.application.geoportalcommon.ProjectDVBuilder;
import org.gcube.application.geoportalcommon.shared.ResultSetPaginatedData;
import org.gcube.application.geoportalcommon.shared.SearchingFilter;
import org.gcube.application.geoportalcommon.shared.SearchingFilter.LOGICAL_OP;
import org.gcube.application.geoportalcommon.shared.SearchingFilter.ORDER;
import org.gcube.application.geoportalcommon.shared.WhereClause;
import org.gcube.application.geoportalcommon.shared.geoportal.ProjectDV;
import org.gcube.application.geoportalcommon.shared.geoportal.config.ItemFieldDV;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
/**
* The Class ProjectsCaller.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Mar 17, 2022
*/
public class ProjectsCaller {
private static Logger LOG = LoggerFactory.getLogger(GeoportalClientCaller.class);
/**
* Gets the client.
*
* @param profileID the profile ID
* @return the client
*/
public Projects<Project> getClient(String profileID) {
LOG.info("getClient called for profileID={}", profileID);
return projects(profileID).build();
}
/**
* Creates the new.
*
* @param profileID the profile ID
* @param jsonDocument the json document
* @return the project
* @throws RemoteException the remote exception
*/
public Project createNew(String profileID, String jsonDocument) throws RemoteException {
LOG.info("createNew called on profileID={}", profileID);
Document myDocument = Document.parse(jsonDocument);
Projects<Project> client = getClient(profileID);
Project project = client.createNew(myDocument);
return project;
}
/**
* Register file set.
*
* @param profileID the profile ID
* @param project the project
* @param theFile the the file
* @param parentPath the parent path
* @param fieldName the field name
* @param fieldDefinition the field definition
* @return the project
* @throws RemoteException the remote exception
* @throws FileNotFoundException the file not found exception
* @throws JsonProcessingException the json processing exception
* @throws InvalidRequestException the invalid request exception
*/
public Project registerFileSet(String profileID, Project project, File theFile, String parentPath, String fieldName,
String fieldDefinition)
throws RemoteException, FileNotFoundException, JsonProcessingException, InvalidRequestException {
LOG.info(
"registerFileSet called with [profileID={}, projectID={}, theFile={}, parentPath={}, fieldName={}, fieldDefinition={}",
parentPath, project.getId(), theFile, parentPath, fieldName, fieldDefinition);
Projects<Project> client = getClient(profileID);
// Prepare request
RegisterFileSetRequest fsRequest = FileSets.prepareRequest(new StorageUtils(), parentPath, fieldName,
fieldDefinition, theFile);
project = client.registerFileSet(project.getId(), fsRequest);
LOG.trace("Resulting Project : " + project);
return project;
}
/**
* Gets the list for profile ID.
*
* @param profileID the profile ID
* @return the list for profile ID
* @throws Exception the exception
*/
public List<Project> getListForProfileID(String profileID) throws Exception {
LOG.info("getListForProfileID called for profileID: {}", profileID);
Projects<Project> client = (Projects<Project>) getClient(profileID);
List<Project> listProjects = new ArrayList<Project>();
Iterator<Project> projects = client.query(new QueryRequest());
for (Iterator<Project> iterator = projects; projects.hasNext();) {
Project prg = (Project) iterator.next();
listProjects.add(prg);
}
LOG.info("returning {} project/s", listProjects.size(), Project.class.getName());
return listProjects;
}
/**
* Gets the project by ID.
*
* @param profileID the profile ID
* @param projectID the project ID
* @return the project by ID
* @throws Exception the exception
*/
public Project getProjectByID(String profileID, String projectID) throws Exception {
LOG.info("getProjectByID called for profileID: {}, projectID: {}", profileID, projectID);
Projects<Project> client = (Projects<Project>) getClient(profileID);
Project project = client.getById(projectID);
LOG.info("returning project {}", project != null ? project.getId() : null);
return project;
}
/**
* Gets the configuration.
*
* @param profileID the profile ID
* @return the configuration
* @throws Exception the exception
*/
public Configuration getConfiguration(String profileID) throws Exception {
LOG.info("getConfiguration called for profileID: {} ", profileID);
Projects<Project> client = (Projects<Project>) getClient(profileID);
Configuration config = client.getConfiguration();
LOG.debug("returning: {} ", config);
return config;
}
/**
* Query on mongo.
*
* @param profileID the profile ID
* @param totalItems the total items
* @param offset the offset
* @param limit the limit
* @param filter the filter
* @param projectDVBuilder the project DV builder
* @return the result set paginated data
* @throws Exception the exception
*/
public ResultSetPaginatedData queryOnMongo(String profileID, Integer totalItems, Integer offset, Integer limit,
SearchingFilter filter, ProjectDVBuilder projectDVBuilder) throws Exception {
LOG.info("queryOnMongo called");
try {
Projects<Project> geoportalClient = getClient(profileID);
if (totalItems == null || totalItems < 0) {
// TODO MUST BE REPLACED BY COUNT
List<Project> listOfProjects = getListForProfileID(profileID);
int listConcessioniSize = listOfProjects.size();
totalItems = listConcessioniSize;
}
Integer offsetIndex = offset;
Integer limitIndex = limit;
if (offset == null || offset < 0) {
offsetIndex = 0;
}
if (limit == null || limit < 0) {
limitIndex = totalItems;
}
ResultSetPaginatedData searchedData = new ResultSetPaginatedData(offsetIndex, limitIndex, false);
searchedData.setTotalItems(totalItems);
List<ProjectDV> toReturnList = new ArrayList<ProjectDV>();
Direction sDirection = null;
List<String> orderingFields = new ArrayList<String>();
if (filter == null) {
LOG.info("No filter found, creating empty filter");
filter = new SearchingFilter();
}
ORDER order = filter.getOrder();
if (order == null) {
order = ORDER.ASC;
LOG.info("No direction/order found, using default: " + order);
}
switch (order) {
case ASC:
sDirection = Direction.ASCENDING;
break;
case DESC:
sDirection = Direction.DESCENDING;
break;
}
List<ItemFieldDV> orderByFields = filter.getOrderByFields();
if (orderByFields == null) {
orderByFields = new ArrayList<ItemFieldDV>();
}
// if (orderByFields.isEmpty()) {
// ItemFieldDV orderD = new ItemFieldDV("", Arrays.asList("name"), null, false, false, false);
// LOG.info("Order by is null, adding default: " + orderD);
// orderByFields.add(orderD);
// }
for (ItemFieldDV itemField : orderByFields) {
if (itemField.getJsonFields() != null) {
for (String field : itemField.getJsonFields()) {
orderingFields.add(field);
}
}
}
Map<String, Object> projection = filter.getProjection();
Document projectionDocument = null;
if(projection!=null && !projection.isEmpty()) {
projectionDocument = new Document(projection);
}
QueryRequest request = new QueryRequest();
PagedRequest paging = new PagedRequest();
paging.setOffset(offsetIndex);
paging.setLimit(limitIndex);
request.setPaging(paging);
OrderedRequest ordering = new OrderedRequest();
ordering.setDirection(sDirection);
ordering.setFields(orderingFields);
request.setOrdering(ordering);
Document query = new Document();
if (filter.getConditions() != null) {
for (WhereClause whereClause : filter.getConditions()) {
LOGICAL_OP searchWithOperator = whereClause.getOperator();
if (searchWithOperator == null) {
searchWithOperator = LOGICAL_OP.OR;
}
if (whereClause.getSearchInto() != null && !whereClause.getSearchInto().isEmpty()) {
Map<String, Object> searchFields = whereClause.getSearchInto();
BasicDBObjectBuilder builder = BasicDBObjectBuilder.start();
for (String key : searchFields.keySet()) {
// using regex and case-insensitive
BasicDBObject bs = new BasicDBObject();
bs.append("$regex", searchFields.get(key));
bs.append("$options", "i");
builder.append(key, bs);
}
// Building list of Document in OR clause
BasicDBList list = new BasicDBList();
Map map = builder.get().toMap();
for (Object key : map.keySet()) {
BasicDBObject value = (BasicDBObject) map.get(key);
Document doc = new Document((String) key, value);
list.add(doc);
}
// query = new Document();
query.put(searchWithOperator.getOperator(), list);
// BasicDBObject bs = new BasicDBObject();
// bs.append("$eq", "PASSED");
// query.put("report.status", bs);
}
}
}
if(projectionDocument!=null) {
request.setProjection(projectionDocument);
//THE first field specified in the projection must be not null
BasicDBObject bsNotEqualEmpty = new BasicDBObject();
bsNotEqualEmpty.append("$ne", null);
Optional<String> firstKey = projection.keySet().stream().findFirst();
if (firstKey.isPresent()) {
String firstFieldPath = firstKey.get();
query.append(firstFieldPath, bsNotEqualEmpty);
}
}
BasicDBObject bsValid_Document = new BasicDBObject();
bsValid_Document.append("$exists", true);
bsValid_Document.append("$ne", null);
query.append("_theDocument", bsValid_Document);
BasicDBObject bsDocumentExists = new BasicDBObject();
bsDocumentExists.append("$exists", false);
query.append("theDocument", bsDocumentExists);
// BasicDBObject bsNotEqualEmpty = new BasicDBObject();
// bsNotEqualEmpty.append("$ne", null);
// query.append("_theDocument.nome", bsNotEqualEmpty);
request.setFilter(query);
LOG.info("Paging offset: " + offsetIndex + ", limit: " + limitIndex);
LOG.info("Direction: " + sDirection);
LOG.info("Projection: "+projectionDocument);
LOG.info("Order by Fields: " + orderingFields);
LOG.info("Search for conditions: " + filter.getConditions());
if (query != null) {
LOG.info("Search query to JSON: " + query.toJson());
}
Iterator<Project> projects = geoportalClient.query(request);
int i = 0;
while (projects.hasNext()) {
Project project = projects.next();
ProjectDV projectDV = ConvertToDataValueObjectModel.toProjectDV(project, projectDVBuilder);
toReturnList.add(projectDV);
i++;
LOG.trace(i + ") converted: " + projectDV);
}
LOG.debug("read " + toReturnList + " project/s");
searchedData.setData(toReturnList);
// TODO WORKAROUND MUST BE REMOVE AFTER THE QUERY COUNT
// AND LIST.SIZE WILL BE AVAILABLE IN THE SERVICE
if (filter.getConditions() != null) {
searchedData.setTotalItems(toReturnList.size());
totalItems = toReturnList.size();
}
if (totalItems == limit || totalItems == 0) {
LOG.debug("Page completed returning " + totalItems + " items");
int newOffset = offsetIndex + limitIndex;
searchedData.setServerSearchFinished(newOffset > totalItems || totalItems == 0);
LOG.debug("is Search finished: " + searchedData.isServerSearchFinished());
}
return searchedData;
} catch (Exception e) {
LOG.error("Error on loading paginated and filtered list of Project: ", e);
throw new Exception("Error occurred on loading list of Project. Error: " + e.getMessage());
}
}
}