gcube-cms-suite/concessioni-lifecycle/src/main/java/org/gcube/application/cms/sdi/plugins/SDIIndexerPlugin.java

196 lines
7.6 KiB
Java

package org.gcube.application.cms.sdi.plugins;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.gcube.application.cms.plugins.IndexerPluginInterface;
import org.gcube.application.cms.plugins.faults.InitializationException;
import org.gcube.application.cms.plugins.model.PluginDescriptor;
import org.gcube.application.cms.plugins.reports.IndexDocumentReport;
import org.gcube.application.cms.plugins.reports.InitializationReport;
import org.gcube.application.cms.plugins.reports.Report;
import org.gcube.application.cms.plugins.requests.IndexDocumentRequest;
import org.gcube.application.cms.sdi.engine.PostgisIndexer;
import org.gcube.application.cms.sdi.engine.PostgisTable;
import org.gcube.application.cms.sdi.faults.SDIInteractionException;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.geoportal.common.model.JSONPathWrapper;
import org.gcube.application.cms.plugins.model.ComparableVersion;
import org.gcube.application.geoportal.common.model.document.ProfiledDocument;
import org.gcube.application.geoportal.common.model.document.filesets.GCubeSDILayer;
import org.gcube.application.geoportal.common.model.profile.Profile;
import java.util.List;
@Slf4j
public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPluginInterface {
@Data
private class MappingObject{
private String name;
private String type;
private String path;
}
private static final PluginDescriptor DESCRIPTOR=new PluginDescriptor("SDI-Indexer-Plugin",
PluginDescriptor.BaseTypes.INDEXER);
static {
DESCRIPTOR.setDescription("SDI Indexer. " +
"Manage Centroids layers.");
DESCRIPTOR.setVersion(new ComparableVersion("1.0.0"));
}
@Override
public PluginDescriptor getDescriptor() {
return DESCRIPTOR;
}
@Override
public InitializationReport initInContext() throws InitializationException {
InitializationReport report = new InitializationReport();
report.setStatus(Report.Status.OK);
return report;
}
/**
* Expected parameters :
* - indexName (unique)
* - workspace
*
* @param request
* @return
*/
@Override
public IndexDocumentReport index(IndexDocumentRequest request) {
log.info("Indxer {} : Performing {} ",this.getDescriptor().getId(),request);
ProfiledDocument profiledDocument=request.getDocument();
Profile profile = request.getProfile();
Document requestArguments=request.getCallParameters();
Document profileConfiguration =getConfigurationFromProfile(profile).getConfiguration();
IndexDocumentReport report= new IndexDocumentReport(request);
log.debug("Profile Configuration is {} ",profileConfiguration);
try{
// ********* INIT INDEX
// TODO CACHE
PostgisIndexer indexer = new PostgisIndexer(sdiCache.getObject(),profile,postgisCache.getObject());
// SCHEMA
log.debug("Profile {} : Evaluating Index schema.. ",profile.getId());
List<PostgisTable.Field> fields = null; // TODO From Profile
fields.add(new PostgisTable.Field("geom", PostgisTable.FieldType.GEOMETRY));
fields.add(new PostgisTable.Field("projectid", PostgisTable.FieldType.TEXT));
List mappingObjs= profileConfiguration.get("explicitFieldMapping",List.class);
if(mappingObjs!=null){
mappingObjs.forEach(o -> {
log.trace("Mapping is {} ",o);
MappingObject m = Serialization.convert(o,MappingObject.class);
fields.add(new PostgisTable.Field(m.getName(), PostgisTable.FieldType.valueOf(m.getType())));
});
}
indexer.initIndex(requestArguments.getString("indexName"),
fields,
requestArguments.getString("workspace"),
requestArguments.getString("indexName"));
// ************* PREPARE RECORD
JSONPathWrapper documentNavigator=new JSONPathWrapper(Serialization.write(profiledDocument));
Document doc = requestArguments;
// DEFAULT VALUES
doc.put("projectid",profiledDocument.getId());
// ********************** EVALAUTE POSITION
log.debug("indexing Profile {} : Evaluating Centroid... ",profile.getId());
if(profiledDocument.getSpatialReference()!=null){
log.debug("Using user defined spatial reference "+profiledDocument.getSpatialReference());
//TODO USE GEOJSON Position
throw new Exception("Not yet implemented");
}else {
log.debug("Profile {} : Getting evaluation paths from profile.. ",profile.getId());
List bboxEvaluationPaths = profileConfiguration.get("bboxEvaluation",List.class);
if(bboxEvaluationPaths==null || bboxEvaluationPaths.isEmpty())
throw new Exception("Missing configuration bboxEvaluation");
GCubeSDILayer.BBOX toSet = null;
for(Object pathObj : bboxEvaluationPaths){
log.debug("Profile {} : Evaluating path {} ",profile.getId(),pathObj);
for(String path : documentNavigator.getMatchingPaths(pathObj.toString())) {
Object bboxObject = documentNavigator.getByPath(path);
log.info("Matched path {}, value is {} ",path,bboxObject);
GCubeSDILayer.BBOX box = Serialization.convert(bboxObject, GCubeSDILayer.BBOX.class);
if(toSet == null) toSet = box;
if(box.getMaxX()>toSet.getMaxX()) toSet.setMaxX(box.getMaxX());
if(box.getMaxY()>toSet.getMaxY()) toSet.setMaxY(box.getMaxY());
if(box.getMinX()<toSet.getMinX()) toSet.setMinX(box.getMinX());
if(box.getMinY()<toSet.getMinY()) toSet.setMinY(box.getMinY());
}
}
log.info("Evaluated BBOX {} ",toSet);
String wkt = String .format("POINT (%1$d %2$d) ",
toSet.getMaxX()-toSet.getMinX(),
toSet.getMaxY()-toSet.getMinY());
// TODO SET Spatial reference
doc.put("geom",wkt);
}
//*********** Additional Values from profile
log.info("Setting additional values");
if(mappingObjs!=null){
mappingObjs.forEach(o -> {
log.trace("Mapping is {} ",o);
MappingObject m = Serialization.convert(o,MappingObject.class);
doc.put(m.getName(),documentNavigator.getByPath(m.getPath()).get(0));
});
}
indexer.insert(doc);
String finalDocument = documentNavigator.getValueCTX().jsonString();
log.debug("Final document after indexing is {} ",finalDocument);
report.setResultingDocument(Document.parse(finalDocument));
report.setStatus(Report.Status.OK);
}catch (SDIInteractionException e){
log.error("Unable to index "+request,e);
report.setStatus(Report.Status.ERROR);
report.putMessage(e.getMessage());
}catch (Throwable t){
log.error("Unable to index "+request,t);
report.setStatus(Report.Status.ERROR);
report.putMessage(t.getMessage());
}finally{
return report;
}
}
}