2022-02-18 18:11:12 +01:00
|
|
|
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;
|
2022-02-24 18:09:30 +01:00
|
|
|
import org.gcube.application.cms.plugins.faults.InvalidProfileException;
|
2022-02-18 18:11:12 +01:00
|
|
|
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;
|
2022-02-23 17:13:22 +01:00
|
|
|
import org.gcube.application.cms.plugins.model.ComparableVersion;
|
2022-02-18 18:11:12 +01:00
|
|
|
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;
|
2022-02-23 17:13:22 +01:00
|
|
|
|
2022-02-24 18:09:30 +01:00
|
|
|
import java.util.ArrayList;
|
2022-02-18 18:11:12 +01:00
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
@Slf4j
|
|
|
|
public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPluginInterface {
|
|
|
|
|
|
|
|
@Data
|
2022-02-24 18:09:30 +01:00
|
|
|
private static class MappingObject{
|
2022-02-18 18:11:12 +01:00
|
|
|
private String name;
|
|
|
|
private String type;
|
|
|
|
private String path;
|
2022-02-24 18:09:30 +01:00
|
|
|
|
|
|
|
public void validate () throws RuntimeException {
|
|
|
|
if(name==null) throw new RuntimeException("Invalid mapping "+this+" : name is null");
|
|
|
|
if(type==null) throw new RuntimeException("Invalid mapping "+this+" : type is null");
|
|
|
|
if(path==null) throw new RuntimeException("Invalid mapping "+this+" : path is null");
|
|
|
|
}
|
2022-02-18 18:11:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
2022-02-24 18:09:30 +01:00
|
|
|
log.info("Indexer {} : Performing {} ",this.getDescriptor().getId(),request);
|
2022-02-18 18:11:12 +01:00
|
|
|
|
|
|
|
ProfiledDocument profiledDocument=request.getDocument();
|
|
|
|
Profile profile = request.getProfile();
|
|
|
|
Document requestArguments=request.getCallParameters();
|
|
|
|
|
2022-02-23 17:13:22 +01:00
|
|
|
IndexDocumentReport report= new IndexDocumentReport(request);
|
2022-02-18 18:11:12 +01:00
|
|
|
|
2022-02-24 18:09:30 +01:00
|
|
|
|
2022-02-18 18:11:12 +01:00
|
|
|
|
|
|
|
try{
|
|
|
|
// ********* INIT INDEX
|
|
|
|
// TODO CACHE
|
|
|
|
PostgisIndexer indexer = new PostgisIndexer(sdiCache.getObject(),profile,postgisCache.getObject());
|
|
|
|
|
2022-02-24 18:09:30 +01:00
|
|
|
Document profileConfiguration =getConfigurationFromProfile(profile).getConfiguration();
|
|
|
|
log.debug("Profile Configuration is {} ",profileConfiguration);
|
2022-02-18 18:11:12 +01:00
|
|
|
|
|
|
|
// SCHEMA
|
|
|
|
log.debug("Profile {} : Evaluating Index schema.. ",profile.getId());
|
2022-02-24 18:09:30 +01:00
|
|
|
List<PostgisTable.Field> fields = new ArrayList<>(); // TODO From Profile
|
2022-02-18 18:11:12 +01:00
|
|
|
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);
|
2022-02-24 18:09:30 +01:00
|
|
|
m.validate();
|
2022-02-18 18:11:12 +01:00
|
|
|
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
|
2022-02-23 17:13:22 +01:00
|
|
|
doc.put("projectid",profiledDocument.getId());
|
2022-02-18 18:11:12 +01:00
|
|
|
|
|
|
|
// ********************** 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())) {
|
2022-02-24 18:09:30 +01:00
|
|
|
Object bboxObject = documentNavigator.getByPath(path).get(0);
|
2022-02-18 18:11:12 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|