From 07730153ca3514b2d0077e03c8d1e4b6937a0e82 Mon Sep 17 00:00:00 2001 From: "francesco.mangiacrapa" Date: Tue, 28 Mar 2023 15:45:21 +0200 Subject: [PATCH] #24859 integrated the Geoportal Gis Link --- sdi-plugins/CHANGELOG.md | 4 + sdi-plugins/pom.xml | 9 +- .../cms/sdi/engine/DBConstants.java | 2 + .../cms/sdi/plugins/SDIIndexerPlugin.java | 553 +++++++++--------- 4 files changed, 293 insertions(+), 275 deletions(-) diff --git a/sdi-plugins/CHANGELOG.md b/sdi-plugins/CHANGELOG.md index c6f8674..9c1b001 100644 --- a/sdi-plugins/CHANGELOG.md +++ b/sdi-plugins/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog for org.gcube.application.cms.sdi-plugins +## [v1.1.0-SNAPSHOT] + +- Integrated the field 'geov_link' (Geoportal GisViewer link) in the centroid layer [#24859] + ## [v1.0.4] - 2023-03-06 - Fixed the import from joda-time to java.time - [#24702] Fixed the default-lc-managers dependency diff --git a/sdi-plugins/pom.xml b/sdi-plugins/pom.xml index 651cbf0..d16c89b 100644 --- a/sdi-plugins/pom.xml +++ b/sdi-plugins/pom.xml @@ -5,7 +5,7 @@ 4.0.0 sdi-plugins - 1.0.4 + 1.1.0-SNAPSHOT gCube CMS - SDI Plugins @@ -85,12 +85,19 @@ 1.14 + + org.gcube.portlets.user + uri-resolver-manager + [1.0.0,2.0.0-SNAPSHOT) + + org.gcube.application.cms cms-test-commons test + diff --git a/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/engine/DBConstants.java b/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/engine/DBConstants.java index 381d259..4617b41 100644 --- a/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/engine/DBConstants.java +++ b/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/engine/DBConstants.java @@ -18,6 +18,8 @@ public class DBConstants { public static final String PROJECT_ID="projectid"; public static final String DISPLAYED="displayed_project"; + + public static final String GEOVIEWER_LINK_FIELD="geov_link"; public static final String XCOORD_FIELD="xcoord"; diff --git a/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/plugins/SDIIndexerPlugin.java b/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/plugins/SDIIndexerPlugin.java index 8987e04..414b5ff 100644 --- a/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/plugins/SDIIndexerPlugin.java +++ b/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/plugins/SDIIndexerPlugin.java @@ -33,6 +33,9 @@ import org.gcube.application.geoportal.common.model.plugins.IndexerPluginDescrip import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; +import org.gcube.portlets.user.uriresolvermanager.UriResolverManager; +import org.gcube.portlets.user.uriresolvermanager.resolvers.query.GeoportalResolverQueryStringBuilder; +import org.gcube.portlets.user.uriresolvermanager.resolvers.query.GeoportalResolverQueryStringBuilder.RESOLVE_AS; import org.geojson.Crs; import org.geojson.GeoJsonObject; import org.geojson.LngLatAlt; @@ -42,283 +45,285 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; @Slf4j public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPluginInterface { - - static final PluginDescriptor DESCRIPTOR=new PluginDescriptor(Constants.INDEXER_PLUGIN_ID, - IndexerPluginDescriptor.INDEXER); - - - - - static final ArrayList BBOX_EVALUATORS=new ArrayList<>(); - - static { - DESCRIPTOR.setDescription("SDI Indexer. " + - "Manage Centroids layers."); - DESCRIPTOR.setVersion(new Semver("1.0.0")); - - BBOX_EVALUATORS.add(new BBOXPathScanner()); - BBOX_EVALUATORS.add(new BBOXByCoordinatePaths()); - - - - } - - @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 - * - centroidRecord (OPT) - * - * @param request - * @return - */ - - @Override - public IndexDocumentReport index(IndexDocumentRequest request) throws InvalidPluginRequestException { - - log.info("Indexer {} : Serving Index Request {} ",this.getDescriptor().getId(),request); - - Project project =request.getDocument(); - UseCaseDescriptor useCaseDescriptor = request.getUseCaseDescriptor(); - Document requestArguments=request.getCallParameters(); - - IndexDocumentReport report= new IndexDocumentReport(request); - - - - try{ - // ********* INIT INDEX - // TODO CACHE - PostgisIndexer indexer = getIndexer(useCaseDescriptor,requestArguments); - - Document profileConfiguration =getConfigurationFromProfile(useCaseDescriptor).getConfiguration(); - log.debug("UseCaseDescriptor Configuration is {} ",profileConfiguration); - - - // ************* PREPARE RECORD - - - JSONPathWrapper documentNavigator=new JSONPathWrapper(Serialization.write(project)); - - Document centroidDoc = new Document(); - if(requestArguments.containsKey("centroidRecord")) - centroidDoc.putAll(requestArguments.get("centroidRecords",Document.class)); - // DEFAULT VALUES - centroidDoc.put(DBConstants.Defaults.PROJECT_ID, project.getId()); - centroidDoc.put(DBConstants.Defaults.DISPLAYED,true); - - - - // ********************** EVALAUTE POSITION - log.debug("indexing UseCaseDescriptor {} : Evaluating Centroid... ", useCaseDescriptor.getId()); - SpatialReference reference =null; - List refs=project.getIdentificationReferenceByType(SpatialReference.SPATIAL_REFERENCE_TYPE); - if(!refs.isEmpty()){ - - // Use existing Reference - - reference = Serialization.convert(refs.get(0), SpatialReference.class); - - log.debug("Using already defined spatial reference " + reference); - - - GeoJsonObject object = Serialization.convert(reference.getGeoJson(), GeoJsonObject.class); - - GCubeSDILayer.BBOX bbox = GCubeSDILayer.BBOX.fromGeoJSON(object.getBbox()); - - log.info("Found declared BBOX {} ", bbox); - Double pointX = (bbox.getMaxX() + bbox.getMinX())/2; - Double pointY = (bbox.getMaxY() + bbox.getMinY())/2; - String wkt = String.format("POINT (%1$f %2$f) ", - pointX, pointY); - - - centroidDoc.put("geom", wkt); - - } else{ - // unable to use current Spatial reference, try evaluating it - log.debug("UseCaseDescriptor {} : Getting evaluation paths from useCaseDescriptor.. ", useCaseDescriptor.getId()); - - // for each configuration option try until found - GCubeSDILayer.BBOX toSet = null; - for(BBOXEvaluator evaluator : BBOX_EVALUATORS){ - log.trace("UCD {}, Project {}. Evaluating BBOX with {}",useCaseDescriptor.getId(),project.getId(),evaluator); - try{ - if(evaluator.isConfigured(profileConfiguration)){ - toSet=evaluator.evaluate(profileConfiguration,useCaseDescriptor,documentNavigator); - if(toSet!=null) { - log.info("UCD {}, Project {}. Evaluated BBOX {} with method {}", - useCaseDescriptor.getId(),project.getId(),toSet,evaluator); - break; - } - } - }catch (Throwable t){ - log.warn("UCD {}, Project {}. Exception with {}", - useCaseDescriptor.getId(),project.getId(),evaluator,t); - } - } - if(toSet== null) - throw new IndexingException("No BBOX has been evaluated from project"); - - Double pointX=(toSet.getMaxX()+toSet.getMinX())/2; - Double pointY = (toSet.getMaxY()+toSet.getMinY())/2; - log.info("Evaluated BBOX {} ",toSet); - String wkt = String .format("POINT (%1$f %2$f) ", - pointX, pointY); - //TODO support altitude - Double pointZ= 0d; - - - centroidDoc.put("geom",wkt); - - Point point = new Point(); - point.setCoordinates(new LngLatAlt(pointX,pointY,pointZ)); - point.setBbox(toSet.asGeoJSONArray()); - - //TODO Manage CRS - point.setCrs(new Crs()); - reference = new SpatialReference(Serialization.asDocument(point)); - log.info("UCD {} project {}, Setting Spatial Reference {} ",useCaseDescriptor.getId(),project.getId(),Serialization.write(reference)); - report.addIdentificationReference(reference); - } - - - - //*********** Additional Values from useCaseDescriptor - - log.info("Setting additional values to centroid from mappings .."); - for(MappingObject m : getMappings(useCaseDescriptor)){ - List foundValues = documentNavigator.getByPath(m.getPath()); - Object toSetValue=null; - if(!foundValues.isEmpty()) { - // NB CSV for multiple values - StringBuilder b=new StringBuilder(); - foundValues.forEach(o-> { - // Parser returns list of list - if (o instanceof Collection) ((Collection) o).forEach(v ->b.append(v + ",")); - else b.append(o+","); - }); - b.deleteCharAt(b.length()-1); - toSetValue = b.toString(); - } - log.trace("Setting {} = {} in centroid doc ",m.getName(),toSetValue); - centroidDoc.put(m.getName(),toSetValue); - } - - log.info("Inserting Centroid {} into {} ",Serialization.write(centroidDoc.toJson()),indexer); - indexer.insert(centroidDoc); - - // Support to HIDE AND DISPLAY as requested by invoker - if(requestArguments.containsKey("_toHideIds")){ - - List ids = Serialization.convert(requestArguments.get("_toHideIds"),List.class); - log.info("Requested to hide centroids {} ",ids); - indexer.updateIsVisible(false,ids); - } - - if(requestArguments.containsKey("_toDisplayIds")){ - List ids = Serialization.convert(requestArguments.get("_toDisplayIds"),List.class); - - log.info("Requested to display centroids {} ",ids); - indexer.updateIsVisible(true,ids); - } - - - - 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; - } - } - - private List getMappings(UseCaseDescriptor useCaseDescriptor) throws InvalidProfileException { - return MappingObject.getMappingsFromUCD(useCaseDescriptor, getDescriptor().getId()); - } - - @Override - public IndexDocumentReport deindex(IndexDocumentRequest request) throws InvalidPluginRequestException { - log.info("Indexer {} : Serving Index Request {} ",this.getDescriptor().getId(),request); - IndexDocumentReport report= new IndexDocumentReport(request); - try{ - PostgisIndexer indexer = getIndexer(request.getUseCaseDescriptor(),request.getCallParameters()); - indexer.removeByFieldValue(PostgisIndexer.StandardFields.PROJECT_ID,request.getDocument().getId()); - }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; - } - } - - /** - * Expected parameters : - * workspace - * indexName - * - * @param request - * @return - * @throws ConfigurationException - */ - @Override - public Index getIndex(BaseRequest request) throws ConfigurationException { - try { - return getIndexer(request.getUseCaseDescriptor(), request.getCallParameters()).getIndexConfiguration(); - }catch(Throwable t ){ - throw new ConfigurationException("Unable to get Postgis index for ucd "+request.getUseCaseDescriptor().getId()+" in "+ request.getContext(),t); - } - } - - // Inits index - // TODO CACHE - private PostgisIndexer getIndexer(UseCaseDescriptor ucd,Document params) throws ConfigurationException, SQLException, InvalidProfileException, SDIInteractionException { - PostgisIndexer indexer = new PostgisIndexer(sdiCache.getObject(), ucd, postgisCache.getObject()); - - List mappingObjects = getMappings(ucd); - List fields = PostgisTable.Field.fromMappings(mappingObjects); - - indexer.initIndex(params.getString("indexName"), - fields, - params.getString("workspace"), - params.getString("indexName")); - return indexer; - } - - - - - - - - + static final PluginDescriptor DESCRIPTOR = new PluginDescriptor(Constants.INDEXER_PLUGIN_ID, + IndexerPluginDescriptor.INDEXER); + + static final ArrayList BBOX_EVALUATORS = new ArrayList<>(); + + static { + DESCRIPTOR.setDescription("SDI Indexer. " + "Manage Centroids layers."); + DESCRIPTOR.setVersion(new Semver("1.0.0")); + + BBOX_EVALUATORS.add(new BBOXPathScanner()); + BBOX_EVALUATORS.add(new BBOXByCoordinatePaths()); + + } + + @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 - flagInternalIndex: + * boolean - centroidRecord (OPT) + * + * @param request + * @return + */ + + @Override + public IndexDocumentReport index(IndexDocumentRequest request) throws InvalidPluginRequestException { + + log.info("Indexer {} : Serving Index Request {} ", this.getDescriptor().getId(), request); + + Project project = request.getDocument(); + UseCaseDescriptor useCaseDescriptor = request.getUseCaseDescriptor(); + Document requestArguments = request.getCallParameters(); + + IndexDocumentReport report = new IndexDocumentReport(request); + + try { + // ********* INIT INDEX + // TODO CACHE + PostgisIndexer indexer = getIndexer(useCaseDescriptor, requestArguments); + + Document profileConfiguration = getConfigurationFromProfile(useCaseDescriptor).getConfiguration(); + log.debug("UseCaseDescriptor Configuration is {} ", profileConfiguration); + + // ************* PREPARE RECORD + + JSONPathWrapper documentNavigator = new JSONPathWrapper(Serialization.write(project)); + + Document centroidDoc = new Document(); + if (requestArguments.containsKey("centroidRecord")) + centroidDoc.putAll(requestArguments.get("centroidRecords", Document.class)); + // DEFAULT VALUES + centroidDoc.put(DBConstants.Defaults.PROJECT_ID, project.getId()); + centroidDoc.put(DBConstants.Defaults.DISPLAYED, true); + + boolean isInternalIndex = false; + try { + isInternalIndex = requestArguments.getBoolean("flagInternalIndex"); + log.debug("flagInternalIndex read as {} ", isInternalIndex); + } catch (Exception e) { + // TODO: handle exception + } + log.info("flagInternalIndex is {} ", isInternalIndex); + + try { + log.debug("Trying to generate Geoportal Gis Link..."); + //Contacting the Geoportal-Resolver via UriResolverManager + UriResolverManager uriResolverManager = new UriResolverManager("GEO"); + GeoportalResolverQueryStringBuilder builder = new GeoportalResolverQueryStringBuilder(project.getProfileID(),project.getId()); + builder.scope(request.getContext().getId()); + + if(isInternalIndex) { + builder.resolverAs(RESOLVE_AS.PRIVATE); + }else { + builder.resolverAs(RESOLVE_AS.PUBLIC); + } + Map params = builder.buildQueryParameters(); + String shortLink = uriResolverManager.getLink(params, true); + log.info("Geoportal GisViewer link is {} ", shortLink); + centroidDoc.put(DBConstants.Defaults.GEOVIEWER_LINK_FIELD, shortLink); + }catch (Exception e) { + // TODO: handle exception + } + + + // ********************** EVALAUTE POSITION + log.debug("indexing UseCaseDescriptor {} : Evaluating Centroid... ", useCaseDescriptor.getId()); + SpatialReference reference = null; + List refs = project + .getIdentificationReferenceByType(SpatialReference.SPATIAL_REFERENCE_TYPE); + if (!refs.isEmpty()) { + + // Use existing Reference + + reference = Serialization.convert(refs.get(0), SpatialReference.class); + + log.debug("Using already defined spatial reference " + reference); + + GeoJsonObject object = Serialization.convert(reference.getGeoJson(), GeoJsonObject.class); + + GCubeSDILayer.BBOX bbox = GCubeSDILayer.BBOX.fromGeoJSON(object.getBbox()); + + log.info("Found declared BBOX {} ", bbox); + Double pointX = (bbox.getMaxX() + bbox.getMinX()) / 2; + Double pointY = (bbox.getMaxY() + bbox.getMinY()) / 2; + String wkt = String.format("POINT (%1$f %2$f) ", pointX, pointY); + + centroidDoc.put("geom", wkt); + + } else { + // unable to use current Spatial reference, try evaluating it + log.debug("UseCaseDescriptor {} : Getting evaluation paths from useCaseDescriptor.. ", + useCaseDescriptor.getId()); + + // for each configuration option try until found + GCubeSDILayer.BBOX toSet = null; + for (BBOXEvaluator evaluator : BBOX_EVALUATORS) { + log.trace("UCD {}, Project {}. Evaluating BBOX with {}", useCaseDescriptor.getId(), project.getId(), + evaluator); + try { + if (evaluator.isConfigured(profileConfiguration)) { + toSet = evaluator.evaluate(profileConfiguration, useCaseDescriptor, documentNavigator); + if (toSet != null) { + log.info("UCD {}, Project {}. Evaluated BBOX {} with method {}", + useCaseDescriptor.getId(), project.getId(), toSet, evaluator); + break; + } + } + } catch (Throwable t) { + log.warn("UCD {}, Project {}. Exception with {}", useCaseDescriptor.getId(), project.getId(), + evaluator, t); + } + } + if (toSet == null) + throw new IndexingException("No BBOX has been evaluated from project"); + + Double pointX = (toSet.getMaxX() + toSet.getMinX()) / 2; + Double pointY = (toSet.getMaxY() + toSet.getMinY()) / 2; + log.info("Evaluated BBOX {} ", toSet); + String wkt = String.format("POINT (%1$f %2$f) ", pointX, pointY); + // TODO support altitude + Double pointZ = 0d; + + centroidDoc.put("geom", wkt); + + Point point = new Point(); + point.setCoordinates(new LngLatAlt(pointX, pointY, pointZ)); + point.setBbox(toSet.asGeoJSONArray()); + + // TODO Manage CRS + point.setCrs(new Crs()); + reference = new SpatialReference(Serialization.asDocument(point)); + log.info("UCD {} project {}, Setting Spatial Reference {} ", useCaseDescriptor.getId(), project.getId(), + Serialization.write(reference)); + report.addIdentificationReference(reference); + } + + // *********** Additional Values from useCaseDescriptor + + log.info("Setting additional values to centroid from mappings .."); + for (MappingObject m : getMappings(useCaseDescriptor)) { + List foundValues = documentNavigator.getByPath(m.getPath()); + Object toSetValue = null; + if (!foundValues.isEmpty()) { + // NB CSV for multiple values + StringBuilder b = new StringBuilder(); + foundValues.forEach(o -> { + // Parser returns list of list + if (o instanceof Collection) + ((Collection) o).forEach(v -> b.append(v + ",")); + else + b.append(o + ","); + }); + b.deleteCharAt(b.length() - 1); + toSetValue = b.toString(); + } + log.trace("Setting {} = {} in centroid doc ", m.getName(), toSetValue); + centroidDoc.put(m.getName(), toSetValue); + } + + log.info("Inserting Centroid {} into {} ", Serialization.write(centroidDoc.toJson()), indexer); + indexer.insert(centroidDoc); + + // Support to HIDE AND DISPLAY as requested by invoker + if (requestArguments.containsKey("_toHideIds")) { + + List ids = Serialization.convert(requestArguments.get("_toHideIds"), List.class); + log.info("Requested to hide centroids {} ", ids); + indexer.updateIsVisible(false, ids); + } + + if (requestArguments.containsKey("_toDisplayIds")) { + List ids = Serialization.convert(requestArguments.get("_toDisplayIds"), List.class); + + log.info("Requested to display centroids {} ", ids); + indexer.updateIsVisible(true, ids); + } + + 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; + } + } + + private List getMappings(UseCaseDescriptor useCaseDescriptor) throws InvalidProfileException { + return MappingObject.getMappingsFromUCD(useCaseDescriptor, getDescriptor().getId()); + } + + @Override + public IndexDocumentReport deindex(IndexDocumentRequest request) throws InvalidPluginRequestException { + log.info("Indexer {} : Serving Index Request {} ", this.getDescriptor().getId(), request); + IndexDocumentReport report = new IndexDocumentReport(request); + try { + PostgisIndexer indexer = getIndexer(request.getUseCaseDescriptor(), request.getCallParameters()); + indexer.removeByFieldValue(PostgisIndexer.StandardFields.PROJECT_ID, request.getDocument().getId()); + } 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; + } + } + + /** + * Expected parameters : workspace indexName + * + * @param request + * @return + * @throws ConfigurationException + */ + @Override + public Index getIndex(BaseRequest request) throws ConfigurationException { + try { + return getIndexer(request.getUseCaseDescriptor(), request.getCallParameters()).getIndexConfiguration(); + } catch (Throwable t) { + throw new ConfigurationException("Unable to get Postgis index for ucd " + + request.getUseCaseDescriptor().getId() + " in " + request.getContext(), t); + } + } + + // Inits index + // TODO CACHE + private PostgisIndexer getIndexer(UseCaseDescriptor ucd, Document params) + throws ConfigurationException, SQLException, InvalidProfileException, SDIInteractionException { + PostgisIndexer indexer = new PostgisIndexer(sdiCache.getObject(), ucd, postgisCache.getObject()); + + List mappingObjects = getMappings(ucd); + List fields = PostgisTable.Field.fromMappings(mappingObjects); + + indexer.initIndex(params.getString("indexName"), fields, params.getString("workspace"), + params.getString("indexName")); + return indexer; + } }