gcube-cms-suite/sdi-plugins/src/main/java/org/gcube/application/cms/sdi/plugins/SDIMaterializerPlugin.java

271 lines
12 KiB
Java
Raw Normal View History

2022-02-18 18:11:12 +01:00
package org.gcube.application.cms.sdi.plugins;
2022-02-14 12:23:13 +01:00
2023-03-28 16:09:25 +02:00
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
2022-02-14 12:23:13 +01:00
import org.bson.Document;
2023-01-10 15:57:40 +01:00
import org.gcube.application.cms.implementations.utils.UserUtils;
2022-02-14 12:23:13 +01:00
import org.gcube.application.cms.plugins.MaterializationPlugin;
import org.gcube.application.cms.plugins.faults.InitializationException;
2022-03-30 12:57:14 +02:00
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
2022-02-14 12:23:13 +01:00
import org.gcube.application.cms.plugins.faults.MaterializationException;
import org.gcube.application.cms.plugins.faults.ShutDownException;
2022-03-30 12:57:14 +02:00
import org.gcube.application.cms.plugins.implementations.AbstractPlugin;
2022-02-14 12:23:13 +01:00
import org.gcube.application.cms.plugins.reports.InitializationReport;
import org.gcube.application.cms.plugins.reports.MaterializationReport;
import org.gcube.application.cms.plugins.reports.Report;
2022-02-14 12:23:13 +01:00
import org.gcube.application.cms.plugins.requests.MaterializationRequest;
2022-03-30 12:57:14 +02:00
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;
2022-03-04 14:23:20 +01:00
import org.gcube.application.geoportal.common.model.document.Project;
2022-03-30 12:57:14 +02:00
import org.gcube.application.geoportal.common.model.document.filesets.Materialization;
2022-02-14 12:23:13 +01:00
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet;
2022-03-30 12:57:14 +02:00
import org.gcube.application.geoportal.common.model.document.filesets.sdi.GCubeSDILayer;
2022-09-26 16:11:20 +02:00
import org.gcube.application.geoportal.common.model.plugins.MaterializerPluginDescriptor;
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
2022-03-04 14:23:20 +01:00
import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
2022-02-14 12:23:13 +01:00
2023-03-28 16:09:25 +02:00
import com.vdurmont.semver4j.Semver;
import lombok.Data;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
2023-04-28 14:40:44 +02:00
/**
* The Class SDIMaterializerPlugin.
*
* @author created by Fabio Sinibaldi
* @author new architect and maintainer - Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Apr 28, 2023
*/
2022-02-14 12:23:13 +01:00
@Slf4j
2022-02-18 18:11:12 +01:00
public class SDIMaterializerPlugin extends AbstractPlugin implements MaterializationPlugin {
2022-02-14 12:23:13 +01:00
2023-04-28 14:40:44 +02:00
/**
* Instantiates a new materialization config.
*/
@Data
public static class MaterializationConfig{
private String schemaField;
private String documentPath;
}
2022-02-18 18:11:12 +01:00
Map<String, SDIManagerWrapper> sdiManagerMap=null;
2022-02-16 18:29:34 +01:00
2023-04-28 14:40:44 +02:00
/**
* Gets the SDI manager.
*
* @return the SDI manager
*/
2022-02-18 18:11:12 +01:00
private SDIManagerWrapper getSDIManager(){
2023-01-10 15:57:40 +01:00
String context = UserUtils.getCurrent().getContext();
log.debug("Getting SDIManagerWrapper from cache map for context {}");
return sdiManagerMap.get(context);
2022-02-16 18:29:34 +01:00
}
2022-02-14 12:23:13 +01:00
2023-04-28 14:40:44 +02:00
/**
* Inits the in context.
*
* @return the initialization report
* @throws InitializationException the initialization exception
*/
2022-02-14 12:23:13 +01:00
@Override
2022-02-16 18:29:34 +01:00
@Synchronized
2022-02-14 12:23:13 +01:00
public InitializationReport initInContext() throws InitializationException {
2022-02-16 17:55:41 +01:00
InitializationReport report = new InitializationReport();
try{
2023-01-10 15:57:40 +01:00
String context = UserUtils.getCurrent().getContext();
2022-02-16 18:29:34 +01:00
if(getSDIManager()==null) {
log.info("Initializing in " + context);
2022-02-18 18:11:12 +01:00
sdiManagerMap.put(context,new SDIManagerWrapper());
2022-02-16 18:29:34 +01:00
}
2022-02-16 17:55:41 +01:00
report.setStatus(Report.Status.OK);
2022-02-16 18:36:42 +01:00
report.putMessage("Initialized SDI Manager in "+context+" pointing to "+getSDIManager().getGeoserverHostName());
2022-02-16 17:55:41 +01:00
} catch (SDIInteractionException e) {
throw new InitializationException("Unable to initialize SDI Manager ",e);
}
return report;
2022-02-14 12:23:13 +01:00
}
2023-04-28 14:40:44 +02:00
/**
* Inits the.
*
* @return the initialization report
* @throws InitializationException the initialization exception
*/
2022-02-14 12:23:13 +01:00
@Override
2022-02-16 18:29:34 +01:00
@Synchronized
2022-02-14 12:23:13 +01:00
public InitializationReport init() throws InitializationException {
2022-02-16 17:55:41 +01:00
InitializationReport report = new InitializationReport();
2022-02-16 18:29:34 +01:00
sdiManagerMap=new HashMap<>();
2022-02-16 17:55:41 +01:00
report.setStatus(Report.Status.OK);
return report;
2022-02-14 12:23:13 +01:00
}
2023-04-28 14:40:44 +02:00
/**
* Shutdown.
*
* @throws ShutDownException the shut down exception
*/
2022-02-14 12:23:13 +01:00
@Override
public void shutdown() throws ShutDownException {
}
/**
* Expected params :
* -workspace MANDATORY
2023-04-28 14:40:44 +02:00
* -titleField.
*
2023-04-28 14:40:44 +02:00
* @param request the request
* @return the materialization report
* @throws MaterializationException the materialization exception
* @throws InvalidPluginRequestException the invalid plugin request exception
*/
2022-02-14 12:23:13 +01:00
@Override
2022-03-04 11:30:31 +01:00
public MaterializationReport materialize(MaterializationRequest request) throws MaterializationException, InvalidPluginRequestException {
2023-04-28 14:40:44 +02:00
log.info("Serving Materialize {} : request CallParameters {}, request Context {}: ",this.getDescriptor().getId(), request.getCallParameters(), request.getContext());
log.debug("Materialize request {}",request);
2022-03-04 14:23:20 +01:00
Project project =request.getDocument();
UseCaseDescriptor useCaseDescriptor = request.getUseCaseDescriptor();
2022-08-03 11:42:02 +02:00
Document requestArguments=Serialization.convert(request.getCallParameters(),Document.class);
2022-02-14 12:23:13 +01:00
2022-02-23 17:13:22 +01:00
MaterializationReport report= new MaterializationReport(request);
2022-02-14 12:23:13 +01:00
try{
2022-03-04 14:23:20 +01:00
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());
2022-02-14 12:23:13 +01:00
2022-02-16 17:12:23 +01:00
for(Object fsConfigObj : profileConfiguration.get("registeredFileSetPaths", List.class)){
log.debug("Managing {} ",fsConfigObj);
MaterializationConfig fsConfig=Serialization.convert(fsConfigObj,MaterializationConfig.class);
2022-02-16 17:55:41 +01:00
List matchingFieldDefinitions =schemaNavigator.getByPath(fsConfig.getSchemaField());
2022-02-16 17:12:23 +01:00
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());
2022-02-16 17:55:41 +01:00
Field f = Serialization.convert(matchingFieldDefinitions.get(0),Field.class);
2022-02-14 12:23:13 +01:00
// TODO Check if schema points to RegisteredFileSet
2022-02-14 12:23:13 +01:00
2022-02-16 17:55:41 +01:00
for(Object fsObject : documentNavigator.getByPath(fsConfig.getDocumentPath())){
RegisteredFileSet fs = Serialization.convert(fsObject,RegisteredFileSet.class);
log.debug("Found {} ",fs);
2022-03-04 14:23:20 +01:00
requestArguments.putIfAbsent("basePersistencePath", useCaseDescriptor.getId());
requestArguments.putIfAbsent("documentID", project.getId());
2022-02-16 17:12:23 +01:00
if(requestArguments.containsKey("titleField"))
requestArguments.putIfAbsent("layerTitle",fs.getString(requestArguments.getString("titleField")));
else requestArguments.putIfAbsent("layerTitle",fs.getUUID());
2022-02-14 17:06:32 +01:00
2022-02-17 11:10:56 +01:00
//Add FS uuid at ws_baseName
2022-11-30 16:32:51 +01:00
String ws = request.getMandatory("workspace")+"_"+ project.getId();
ws = ws.replaceAll("\\W","_");
log.trace("Escaped WS will be {} ",ws);
requestArguments.put("workspace",ws);
2022-02-17 11:10:56 +01:00
// Actually materializing
2022-02-16 18:29:34 +01:00
RegisteredFileSet obtained = getSDIManager().materializeLayer(fs,requestArguments);
log.debug("Obtained {} ",obtained);
2022-02-24 18:09:30 +01:00
documentNavigator.setElement("$..[?(@."+ RegisteredFileSet.UUID+" == '"+fs.getUUID()+"')]",obtained);
}
}
2022-02-18 18:11:12 +01:00
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());
2022-02-14 12:23:13 +01:00
}catch (Throwable t){
log.error("Unable to materialize "+request,t);
report.setStatus(Report.Status.ERROR);
report.putMessage(t.getMessage());
2022-02-14 12:23:13 +01:00
}finally{
return report;
2022-02-14 12:23:13 +01:00
}
}
2022-03-30 12:57:14 +02:00
/**
* Expected parameters
2023-04-28 14:40:44 +02:00
* - fileSetPath.
2022-03-30 12:57:14 +02:00
*
2023-04-28 14:40:44 +02:00
* @param request the request
* @return the materialization report
* @throws MaterializationException the materialization exception
* @throws InvalidPluginRequestException the invalid plugin request exception
2022-03-30 12:57:14 +02:00
*/
2022-03-29 18:06:09 +02:00
@Override
public MaterializationReport dematerialize(MaterializationRequest request) throws MaterializationException, InvalidPluginRequestException {
2023-04-28 14:40:44 +02:00
log.info("Serving DeMaterialize {} : request CallParameters {}, request Context {}: ",this.getDescriptor().getId(), request.getCallParameters(), request.getContext());
log.debug("DeMaterialize request {}",request);
2022-03-30 12:57:14 +02:00
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<>();
2022-12-06 16:46:12 +01:00
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);
}
2022-03-30 12:57:14 +02:00
// Resetting remaining materializations
registeredFileSet.put(RegisteredFileSet.MATERIALIZATIONS,toKeep);
// Update FS in doc
wrapper.setElement(s,registeredFileSet);
}
// Resetting Document
2022-12-06 17:55:49 +01:00
report.setResultingDocument(Document.parse(wrapper.getValueCTX().jsonString()));
2022-03-30 12:57:14 +02:00
}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;
}
2022-03-29 18:06:09 +02:00
}
2022-05-18 18:24:57 +02:00
static final PluginDescriptor DESCRIPTOR=new PluginDescriptor("SDI-Default-Materializer", MaterializerPluginDescriptor.MATERIALIZER);
2022-02-16 17:12:23 +01:00
static {
DESCRIPTOR.setDescription("SDI Materializer. " +
"This plugin materialize FileSets in gCube SDI.");
2022-04-01 19:11:11 +02:00
DESCRIPTOR.setVersion(new Semver("1.0.0"));
2022-02-16 17:12:23 +01:00
}
2023-04-28 14:40:44 +02:00
/**
* Gets the descriptor.
*
* @return the descriptor
*/
2022-02-14 12:23:13 +01:00
@Override
public PluginDescriptor getDescriptor() {
2022-02-16 17:12:23 +01:00
return DESCRIPTOR;
2022-02-14 12:23:13 +01:00
}
}