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 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() { 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; } } }