229 lines
11 KiB
Java
229 lines
11 KiB
Java
package org.gcube.application.cms.sdi.plugins;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
|
||
import org.bson.Document;
|
||
import org.gcube.application.cms.implementations.utils.UserUtils;
|
||
import org.gcube.application.cms.plugins.MaterializationPlugin;
|
||
import org.gcube.application.cms.plugins.faults.InitializationException;
|
||
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
|
||
import org.gcube.application.cms.plugins.faults.MaterializationException;
|
||
import org.gcube.application.cms.plugins.faults.ShutDownException;
|
||
import org.gcube.application.cms.plugins.implementations.AbstractPlugin;
|
||
import org.gcube.application.cms.plugins.reports.InitializationReport;
|
||
import org.gcube.application.cms.plugins.reports.MaterializationReport;
|
||
import org.gcube.application.cms.plugins.reports.Report;
|
||
import org.gcube.application.cms.plugins.requests.MaterializationRequest;
|
||
import org.gcube.application.cms.sdi.engine.SDIManagerWrapper;
|
||
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.geoportal.common.model.document.Project;
|
||
import org.gcube.application.geoportal.common.model.document.filesets.Materialization;
|
||
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet;
|
||
import org.gcube.application.geoportal.common.model.document.filesets.sdi.GCubeSDILayer;
|
||
import org.gcube.application.geoportal.common.model.plugins.MaterializerPluginDescriptor;
|
||
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
|
||
import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field;
|
||
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
|
||
|
||
import com.vdurmont.semver4j.Semver;
|
||
|
||
import lombok.Data;
|
||
import lombok.Synchronized;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
|
||
@Slf4j
|
||
public class SDIMaterializerPlugin extends AbstractPlugin implements MaterializationPlugin {
|
||
|
||
@Data
|
||
public static class MaterializationConfig{
|
||
private String schemaField;
|
||
private String documentPath;
|
||
}
|
||
|
||
Map<String, SDIManagerWrapper> sdiManagerMap=null;
|
||
|
||
|
||
private SDIManagerWrapper getSDIManager(){
|
||
String context = UserUtils.getCurrent().getContext();
|
||
log.debug("Getting SDIManagerWrapper from cache map for context {}");
|
||
return sdiManagerMap.get(context);
|
||
}
|
||
|
||
@Override
|
||
@Synchronized
|
||
public InitializationReport initInContext() throws InitializationException {
|
||
InitializationReport report = new InitializationReport();
|
||
try{
|
||
String context = UserUtils.getCurrent().getContext();
|
||
if(getSDIManager()==null) {
|
||
log.info("Initializing in " + context);
|
||
sdiManagerMap.put(context,new SDIManagerWrapper());
|
||
}
|
||
report.setStatus(Report.Status.OK);
|
||
report.putMessage("Initialized SDI Manager in "+context+" pointing to "+getSDIManager().getGeoserverHostName());
|
||
} catch (SDIInteractionException e) {
|
||
throw new InitializationException("Unable to initialize SDI Manager ",e);
|
||
}
|
||
return report;
|
||
}
|
||
|
||
@Override
|
||
@Synchronized
|
||
public InitializationReport init() throws InitializationException {
|
||
InitializationReport report = new InitializationReport();
|
||
sdiManagerMap=new HashMap<>();
|
||
report.setStatus(Report.Status.OK);
|
||
return report;
|
||
}
|
||
|
||
@Override
|
||
public void shutdown() throws ShutDownException {
|
||
|
||
}
|
||
|
||
/**
|
||
* Expected params :
|
||
* -workspace MANDATORY
|
||
* -titleField
|
||
*
|
||
* @param request
|
||
* @return
|
||
* @throws MaterializationException
|
||
*/
|
||
@Override
|
||
public MaterializationReport materialize(MaterializationRequest request) throws MaterializationException, InvalidPluginRequestException {
|
||
log.info("Materializer {} : Performing {} ",this.getDescriptor().getId(),request);
|
||
Project project =request.getDocument();
|
||
UseCaseDescriptor useCaseDescriptor = request.getUseCaseDescriptor();
|
||
Document requestArguments=Serialization.convert(request.getCallParameters(),Document.class);
|
||
|
||
MaterializationReport report= new MaterializationReport(request);
|
||
|
||
try{
|
||
Document profileConfiguration =getConfigurationFromProfile(useCaseDescriptor).getConfiguration();
|
||
log.debug("UseCaseDescriptor Configuration is {} ",profileConfiguration);
|
||
JSONPathWrapper documentNavigator=new JSONPathWrapper(project.getTheDocument().toJson());
|
||
JSONPathWrapper schemaNavigator=new JSONPathWrapper(useCaseDescriptor.getSchema().toJson());
|
||
|
||
for(Object fsConfigObj : profileConfiguration.get("registeredFileSetPaths", List.class)){
|
||
log.debug("Managing {} ",fsConfigObj);
|
||
MaterializationConfig fsConfig=Serialization.convert(fsConfigObj,MaterializationConfig.class);
|
||
List matchingFieldDefinitions =schemaNavigator.getByPath(fsConfig.getSchemaField());
|
||
if(matchingFieldDefinitions==null || matchingFieldDefinitions.isEmpty())
|
||
throw new MaterializationException("Invalid Field Definition path in configuration [NO MATCH] : "+
|
||
fsConfig.getSchemaField());
|
||
if(matchingFieldDefinitions.size()>1)
|
||
throw new MaterializationException("Invalid Field Definition path in configuration [MATCHES "+matchingFieldDefinitions.size()+"] : "+
|
||
fsConfig.getSchemaField());
|
||
|
||
Field f = Serialization.convert(matchingFieldDefinitions.get(0),Field.class);
|
||
|
||
// TODO Check if schema points to RegisteredFileSet
|
||
|
||
for(Object fsObject : documentNavigator.getByPath(fsConfig.getDocumentPath())){
|
||
RegisteredFileSet fs = Serialization.convert(fsObject,RegisteredFileSet.class);
|
||
log.debug("Found {} ",fs);
|
||
requestArguments.putIfAbsent("basePersistencePath", useCaseDescriptor.getId());
|
||
requestArguments.putIfAbsent("documentID", project.getId());
|
||
if(requestArguments.containsKey("titleField"))
|
||
requestArguments.putIfAbsent("layerTitle",fs.getString(requestArguments.getString("titleField")));
|
||
else requestArguments.putIfAbsent("layerTitle",fs.getUUID());
|
||
|
||
//Add FS uuid at ws_baseName
|
||
String ws = request.getMandatory("workspace")+"_"+ project.getId();
|
||
ws = ws.replaceAll("\\W","_");
|
||
log.trace("Escaped WS will be {} ",ws);
|
||
|
||
requestArguments.put("workspace",ws);
|
||
|
||
// Actually materializing
|
||
RegisteredFileSet obtained = getSDIManager().materializeLayer(fs,requestArguments);
|
||
log.debug("Obtained {} ",obtained);
|
||
documentNavigator.setElement("$..[?(@."+ RegisteredFileSet.UUID+" == '"+fs.getUUID()+"')]",obtained);
|
||
}
|
||
}
|
||
|
||
String finalDocument = documentNavigator.getValueCTX().jsonString();
|
||
log.debug("Final document after materialization is {} ",finalDocument);
|
||
report.setResultingDocument(Document.parse(finalDocument));
|
||
report.setStatus(Report.Status.OK);
|
||
}catch (SDIInteractionException e){
|
||
log.error("Unable to materialize "+request,e);
|
||
report.setStatus(Report.Status.ERROR);
|
||
report.putMessage(e.getMessage());
|
||
}catch (Throwable t){
|
||
log.error("Unable to materialize "+request,t);
|
||
report.setStatus(Report.Status.ERROR);
|
||
report.putMessage(t.getMessage());
|
||
}finally{
|
||
return report;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Expected parameters
|
||
* - fileSetPath
|
||
*
|
||
* @param request
|
||
* @return
|
||
* @throws MaterializationException
|
||
* @throws InvalidPluginRequestException
|
||
*/
|
||
@Override
|
||
public MaterializationReport dematerialize(MaterializationRequest request) throws MaterializationException, InvalidPluginRequestException {
|
||
log.info("Serving DeMaterialization {} ",request);
|
||
MaterializationReport report= new MaterializationReport(request);
|
||
try{
|
||
SDIManagerWrapper sdi=getSDIManager();
|
||
JSONPathWrapper wrapper = new JSONPathWrapper(request.getDocument().getTheDocument().toJson());
|
||
for(String s : wrapper.getMatchingPaths(request.getMandatory("fileSetPath"))){
|
||
log.debug("Found matching {} ",s);
|
||
RegisteredFileSet registeredFileSet=Serialization.convert(wrapper.getByPath(s).get(0),RegisteredFileSet.class);
|
||
List<Object> toKeep = new ArrayList<>();
|
||
if(registeredFileSet.getMaterializations()!=null)
|
||
for(Object matObj : registeredFileSet.getMaterializations()){
|
||
Materialization mat = Serialization.convert(matObj,Materialization.class);
|
||
if(mat.getType().equals(GCubeSDILayer.GCUBE_SDY_LAYER_TYPE)) {
|
||
log.debug("Deleting Layer {} ",mat);
|
||
sdi.deleteLayer(Serialization.convert(matObj, GCubeSDILayer.class));
|
||
}else toKeep.add(matObj);
|
||
}
|
||
// Resetting remaining materializations
|
||
registeredFileSet.put(RegisteredFileSet.MATERIALIZATIONS,toKeep);
|
||
// Update FS in doc
|
||
wrapper.setElement(s,registeredFileSet);
|
||
|
||
}
|
||
// Resetting Document
|
||
report.setResultingDocument(Document.parse(wrapper.getValueCTX().jsonString()));
|
||
}catch (SDIInteractionException e){
|
||
log.error("Unable to materialize "+request,e);
|
||
report.setStatus(Report.Status.ERROR);
|
||
report.putMessage(e.getMessage());
|
||
}catch (Throwable t){
|
||
log.error("Unable to materialize "+request,t);
|
||
report.setStatus(Report.Status.ERROR);
|
||
report.putMessage(t.getMessage());
|
||
}finally{
|
||
return report;
|
||
}
|
||
}
|
||
|
||
static final PluginDescriptor DESCRIPTOR=new PluginDescriptor("SDI-Default-Materializer", MaterializerPluginDescriptor.MATERIALIZER);
|
||
static {
|
||
DESCRIPTOR.setDescription("SDI Materializer. " +
|
||
"This plugin materialize FileSets in gCube SDI.");
|
||
DESCRIPTOR.setVersion(new Semver("1.0.0"));
|
||
}
|
||
|
||
@Override
|
||
public PluginDescriptor getDescriptor() {
|
||
return DESCRIPTOR;
|
||
}
|
||
}
|