package org.gcube.application.cms.sdi.engine; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.bson.Document; import org.gcube.application.cms.plugins.requests.BaseRequest; import org.gcube.application.cms.sdi.faults.SDIInteractionException; import org.gcube.application.cms.sdi.model.CrossReferencedLayer; import org.gcube.application.geoportal.common.model.configuration.Index; import org.gcube.application.geoportal.common.model.document.filesets.GCubeSDILayer; import org.gcube.application.geoportal.common.model.legacy.SDILayerDescriptor; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; import org.gcube.application.geoportal.common.model.rest.DatabaseConnection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @Slf4j public class PostgisIndexer { public static final String INDEX_TYPE="GIS-CENTROIDS"; public static void init() throws ClassNotFoundException { Class.forName("org.postgresql.Driver"); Class.forName("org.postgis.DriverWrapper"); }; @NonNull SDIManagerWrapper manager; @NonNull UseCaseDescriptor useCaseDescriptor; @NonNull DatabaseConnection connectionParameters; PostgisDBManagerI dbManager=null; PostgisTable table = null; GCubeSDILayer indexLayer = null; String indexName = null; private List crossReferenceableLayers= new ArrayList<>(); public PostgisIndexer(SDIManagerWrapper manager, UseCaseDescriptor useCaseDescriptor, DatabaseConnection postgisConnection) throws SQLException { log.info("POSTGIS Index for {} Connecting to {} ", useCaseDescriptor.getId(),postgisConnection); this.connectionParameters=postgisConnection; dbManager=new PostgisDBManager(DriverManager. getConnection(connectionParameters.getUrl(), connectionParameters.getUser(), connectionParameters.getPwd())); this.manager=manager; this.useCaseDescriptor = useCaseDescriptor; } public void initIndex(String indexName, List fields, String workspace,String storeName) throws SQLException, SDIInteractionException { log.info("Check/init index for {} ", useCaseDescriptor.getId()); table = new PostgisTable(indexName,fields, PostgisTable.GeometryType.POINT); log.trace("Index Postgis Table is {} ",table); log.debug("Create if missing.."); // Check if table exists dbManager.create(table); log.debug("Checking/ registering index layer in GS "); this.indexName = indexName; indexLayer = manager.configureCentroidLayer(indexName,workspace,storeName,table,connectionParameters); // TODO Additional layers // Create layer // register cross related layers } HashMap crossReferenced = new HashMap<>(); public Index getIndexConfiguration(){ Index toReturn = new Index(INDEX_TYPE); // SDI Layers toReturn.put("layer",indexLayer); toReturn.put("indexName",indexName); try { toReturn.put("records", dbManager.count(table)); }catch (SQLException e) { log.warn("Unable to count records for index " + indexName, e); } toReturn.put("crossReferencedLayers",crossReferenced); return toReturn; } public void insert(Document toInsertRecord)throws SDIInteractionException { log.info("Inserting {} in index {}",toInsertRecord,table.getTablename()); try { PreparedStatement ps = dbManager.prepareInsertStatement(table, false, true); table.fillObjectsPreparedStatement(toInsertRecord, ps); ps.execute(); }catch (Throwable t ){ log.error("Unable to insert {} into {} ",toInsertRecord,table.getTablename(),t); throw new SDIInteractionException("Unable to insert record in postgis index "+table.getTablename(),t); } } public void deleteByStringValue(PostgisTable.Field field, String id) throws SDIInteractionException { log.info("Deleting {}={} from index {}",field.getName(), id,table.getTablename()); try { dbManager.deleteByFieldValue(table,field,id); }catch (Throwable t ){ log.error("Unable to delete {}={} from index {}",field.getName(), id,table.getTablename(),t); throw new SDIInteractionException("Unable to delete record in postgis index "+table.getTablename(),t); } } }