You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/SDIManager.java

323 lines
12 KiB
Java

package org.gcube.application.geoportal.service.engine;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import org.gcube.application.geoportal.common.model.legacy.BBOX;
import org.gcube.application.geoportal.common.model.legacy.GeoServerContent;
import org.gcube.application.geoportal.common.model.legacy.PersistedContent;
import org.gcube.application.geoportal.common.model.legacy.SDILayerDescriptor;
import org.gcube.application.geoportal.common.model.legacy.WorkspaceContent;
import org.gcube.application.geoportal.common.utils.Files;
import org.gcube.application.geoportal.service.model.internal.faults.SDIInteractionException;
import org.gcube.common.storagehub.client.dsl.FileContainer;
import org.gcube.data.transfer.library.DataTransferClient;
import org.gcube.data.transfer.library.TransferResult;
import org.gcube.data.transfer.library.faults.RemoteServiceException;
import org.gcube.data.transfer.model.Destination;
import org.gcube.data.transfer.model.DestinationClashPolicy;
import org.gcube.data.transfer.model.RemoteFileDescriptor;
import org.gcube.spatial.data.gis.GISInterface;
import org.gcube.spatial.data.gis.is.AbstractGeoServerDescriptor;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher.UploadMethod;
import it.geosolutions.geoserver.rest.GeoServerRESTReader;
import it.geosolutions.geoserver.rest.decoder.RESTFeatureType;
import it.geosolutions.geoserver.rest.decoder.RESTLayer;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
import it.geosolutions.geoserver.rest.encoder.datastore.GSPostGISDatastoreEncoder;
import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SDIManager {
static private String DEFAULT_CRS="EPSG:4326";
private GISInterface gis;
@Getter
private DataTransferClient dtGeoServer;
private String geoserverHostName;
public SDIManager() throws SDIInteractionException {
try{
log.debug("Initializing GIS Interface..");
gis=GISInterface.get();
AbstractGeoServerDescriptor geoserver=gis.getCurrentGeoServer();
if(geoserver==null)
throw new Exception("Unable to contact data transfer for geoserver ");
log.debug("Found geoserver descriptor "+geoserver);
geoserverHostName=new URL(gis.getCurrentGeoServer().getUrl()).getHost();
log.debug("Contacting Data Transfer from geoserver {} ",geoserverHostName);
dtGeoServer=DataTransferClient.getInstanceByEndpoint("http://"+geoserverHostName);
if(!gis.getCurrentGeoServer().getReader().existGeoserver())
throw new Exception("Geoserver not reachable");
}catch(Exception e) {
throw new SDIInteractionException("Unable to initialize SDI Manager",e);
}
}
public RemoteFileDescriptor getGeoServerRemoteFolder() throws RemoteServiceException {
return dtGeoServer.getWebClient().getInfo("geoserver/GNA");
}
public String createWorkspace(String toCreate) throws SDIInteractionException {
try {
if(!gis.getCurrentGeoServer().getReader().getWorkspaceNames().contains(toCreate)) {
log.debug("Creating workspace : "+toCreate);
if(!gis.getCurrentGeoServer().getPublisher().createWorkspace(toCreate))
throw new SDIInteractionException("Unable to create workspace "+toCreate);
}else log.debug("Workspace "+toCreate+" exists.");
return toCreate;
} catch (IllegalArgumentException | MalformedURLException e) {
throw new SDIInteractionException("Unable to create workspace "+toCreate,e);
}
}
// GEOSERVER-PERSISTENCE-ID / GNA / PROJECT-ID/ LAYER-ID /FILENAME(no extension)/...
public GeoServerContent pushShapeLayerFileSet(SDILayerDescriptor currentElement,String workspace, String projectId) throws SDIInteractionException{
try {
// String remoteFolder=null;
// String fileName=null;
log.debug("Publishing "+currentElement+" files to geoserver @ "+geoserverHostName);
GeoServerContent content=new GeoServerContent();
content.setGeoserverHostName(geoserverHostName);
content.setWorkspace(workspace);
WorkspaceManager wsManager=new WorkspaceManager();
currentElement.getActualContent().forEach((PersistedContent c)->{
try {
if(c instanceof WorkspaceContent) {
WorkspaceContent wc=(WorkspaceContent) c;
FileContainer fc=wsManager.getFileById(wc.getStorageID());
String completeFilename=Files.fixFilename(fc.get().getName());
String filename=completeFilename.contains(".")?completeFilename.substring(0, completeFilename.lastIndexOf(".")):completeFilename;
Destination destination=new Destination(completeFilename);
destination.setCreateSubfolders(true);
destination.setOnExistingFileName(DestinationClashPolicy.REWRITE);
destination.setOnExistingSubFolder(DestinationClashPolicy.APPEND);
destination.setPersistenceId("geoserver");
destination.setSubFolder("GNA/"+projectId+"/"+
currentElement.getMongo_id()+"/"+filename);
log.debug("Sending "+wc+" to "+destination);
TransferResult result=dtGeoServer.httpSource(fc.getPublicLink(), destination);
log.debug("Transferred "+result);
content.getFileNames().add(completeFilename);
content.setGeoserverPath(result.getRemotePath().substring(0,result.getRemotePath().lastIndexOf("/")));
}
}catch(Throwable t) {
log.warn("Unable to transfer Persisted content"+c,t);
}
});
if(content.getFileNames().isEmpty())
throw new SDIInteractionException("No Persisted content found in "+currentElement);
String completeFileName=content.getFileNames().get(0);
String filename=completeFileName.contains(".")?completeFileName.substring(0, completeFileName.lastIndexOf(".")):completeFileName;
String remoteFolder=content.getGeoserverPath();
String toSetLayerName=filename;
int count=0;
while(gis.getCurrentGeoServer().getReader().getLayer(workspace,toSetLayerName)!=null){
count++;
toSetLayerName=filename+"_"+count;
log.debug("layer for "+filename+" already existing, trying "+toSetLayerName);
};
String storeName=toSetLayerName+"_store";
content.setStore(storeName);
content.setFeatureType(toSetLayerName);
GeoServerRESTPublisher publisher=gis.getCurrentGeoServer().getPublisher();
log.debug("Trying to create remote workspace : "+workspace);
createWorkspace(workspace);
log.debug("Publishing remote folder "+remoteFolder);
URL directoryPath=new URL("file:"+remoteFolder+"/"+filename+".shp");
//TODO Evaluate SRS
boolean published=publisher.publishShp(
workspace,
storeName,
null,
toSetLayerName,
// UploadMethod.FILE, // neeeds zip
UploadMethod.EXTERNAL, // needs shp
directoryPath.toURI(),
DEFAULT_CRS, //SRS
""); // default style
if(!published) {
throw new SDIInteractionException("Unable to publish layer "+toSetLayerName+" under "+workspace+". Unknown Geoserver fault.");
}
currentElement.setLayerName(toSetLayerName);
GeoServerRESTReader reader=gis.getCurrentGeoServer().getReader();
RESTLayer l=reader.getLayer(workspace, toSetLayerName);
RESTFeatureType f= reader.getFeatureType(l);
/*http://geoserver1.dev.d4science.org/geoserver/gna_conc_18/wms?
service=WMS&version=1.1.0&request=GetMap&layers=gna_conc_18:pos&
styles=&bbox=8.62091913167495,40.62975046683799,8.621178639172953,40.630257904721645&
width=392&height=768&srs=EPSG:4326&format=application/openlayers */
currentElement.setWmsLink(
String.format("https://%1$s/geoserver/%2$s/wms?"
+"service=WMS&version=1.1.0&request=GetMap&layers=%2$s:%3$s&"
+ "styles=&bbox=%4$f,%5$f,%6$f,%7$f&srs=%8$s&format=application/openlayers&width=%9$d&height=%10$d",
geoserverHostName,
workspace,
toSetLayerName,
f.getMinX(),
f.getMinY(),
f.getMaxX(),
f.getMaxY(),
DEFAULT_CRS,
400,
400));
currentElement.setWorkspace(workspace);
currentElement.setBbox(new BBOX(f.getMaxY(), f.getMaxX(), f.getMinY(), f.getMinX()));
// TODO Metadata
return content;
// } catch (InvalidSourceException | SourceNotSetException | FailedTransferException | InitializationException
// | InvalidDestinationException | DestinationNotSetException e) {
// throw new SDIInteractionException("Unable to transfer fileSet for content "+currentElement,e);
} catch (SDIInteractionException e) {
throw e;
} catch (Throwable t) {
throw new SDIInteractionException("Unexpected internal fault while interacting with SDI.",t);
}
}
private String createStoreFromPostgisDB(String workspace,String storeName) throws SDIInteractionException {
//SET BY PROVISIONING
GSPostGISDatastoreEncoder encoder=new GSPostGISDatastoreEncoder(storeName);
encoder.setJndiReferenceName("java:comp/env/jdbc/postgres");
encoder.setLooseBBox(true);
encoder.setDatabaseType("postgis");
encoder.setEnabled(true);
encoder.setFetchSize(1000);
encoder.setValidateConnections(true);
try {
log.debug("Looking for datastore "+storeName+" under "+workspace);
if(gis.getCurrentGeoServer().getReader().getDatastore(workspace,storeName)==null)
if(!gis.getCurrentGeoServer().getDataStoreManager().create(workspace, encoder))
throw new SDIInteractionException("Unable to create store "+storeName+" in "+workspace);
log.debug("Store "+storeName+" exists under "+workspace);
return storeName;
} catch (IllegalArgumentException | MalformedURLException e) {
throw new SDIInteractionException("Unable to create store "+storeName,e);
}
}
private String publishStyle(File sldFile,String name) throws SDIInteractionException {
try {
if(!gis.getCurrentGeoServer().getReader().existsStyle(name)) {
log.debug("Registering style "+name);
if(!gis.getCurrentGeoServer().getPublisher().publishStyle(sldFile, name))
throw new SDIInteractionException("Unable to register style "+name);
}else log.debug("Style "+name+" already existing");
return name;
} catch (IllegalArgumentException | MalformedURLException e) {
throw new SDIInteractionException("Unable to create style "+name,e);
}
}
public String configureCentroidLayer(String name,String workspace,String storeName) throws SDIInteractionException {
GSFeatureTypeEncoder fte=new GSFeatureTypeEncoder();
fte.setAbstract("Centroid layer for "+name);
fte.setEnabled(true);
fte.setNativeCRS(DEFAULT_CRS);
fte.setTitle(name);
fte.setName(name);
String style="clustered_centroids";
GSLayerEncoder layerEncoder=new GSLayerEncoder();
layerEncoder.setDefaultStyle(style);
layerEncoder.setEnabled(true);
layerEncoder.setQueryable(true);
try {
//Checking workspace
createWorkspace(workspace);
//Checking store
createStoreFromPostgisDB(workspace, storeName);
//Checkig layer
publishStyle(Files.getFileFromResources("styles/clustered_points.sld"),style);
if(gis.getCurrentGeoServer().getReader().getLayer(workspace, name)==null)
if(!gis.getCurrentGeoServer().getPublisher().publishDBLayer(workspace, storeName, fte, layerEncoder))
throw new SDIInteractionException("Unable to create layer "+name);
log.debug("layer "+name+" already exists");
return name;
} catch (IllegalArgumentException | MalformedURLException e) {
throw new SDIInteractionException("Unable to create layer "+name,e);
}
}
public void deleteContent(GeoServerContent toDelete) throws IllegalArgumentException, MalformedURLException, RemoteServiceException {
log.debug("Deleting geoserver layer "+toDelete);
//delete layer
GeoServerRESTPublisher publisher=gis.getCurrentGeoServer().getPublisher();
//delete store
publisher.removeDatastore(toDelete.getWorkspace(), toDelete.getStore(), true);
//delete WS if empty
GeoServerRESTReader reader=gis.getCurrentGeoServer().getReader();
if(reader.getDatastores(toDelete.getWorkspace()).isEmpty()) {
log.debug("Deleting emtpy workspace "+toDelete.getWorkspace());
publisher.removeWorkspace(toDelete.getWorkspace(), true);
}
//delete file
dtGeoServer.getWebClient().delete(toDelete.getGeoserverPath());
}
}