gcube-cms-suite/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/SimpleLifeCycleManager.java

308 lines
15 KiB
Java

package org.gcube.application.cms.plugins.implementations;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.gcube.application.cms.implementations.faults.InvalidUserRoleException;
import org.gcube.application.cms.implementations.faults.ProjectNotFoundException;
import org.gcube.application.cms.implementations.faults.RegistrationException;
import org.gcube.application.cms.implementations.faults.UnauthorizedAccess;
import org.gcube.application.cms.plugins.IndexerPluginInterface;
import org.gcube.application.cms.plugins.LifecycleManager;
import org.gcube.application.cms.plugins.MaterializationPlugin;
import org.gcube.application.cms.plugins.faults.EventException;
import org.gcube.application.cms.plugins.faults.IndexingException;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.faults.MaterializationException;
import org.gcube.application.cms.plugins.implementations.executions.GuardedStepExecution;
import org.gcube.application.cms.plugins.reports.*;
import org.gcube.application.cms.plugins.requests.BaseExecutionRequest;
import org.gcube.application.cms.plugins.requests.BaseRequest;
import org.gcube.application.cms.plugins.requests.IndexDocumentRequest;
import org.gcube.application.cms.plugins.requests.MaterializationRequest;
import org.gcube.application.geoportal.common.model.JSONPathWrapper;
import org.gcube.application.geoportal.common.model.configuration.Configuration;
import org.gcube.application.geoportal.common.model.configuration.Index;
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.plugins.IndexerPluginDescriptor;
import org.gcube.application.geoportal.common.model.plugins.MaterializerPluginDescriptor;
import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import org.gcube.application.geoportal.common.utils.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Slf4j
public class SimpleLifeCycleManager extends AbstractLifeCycleManager implements LifecycleManager {
public static final String PLUGIN_ID="DEFAULT-SINGLE-STEP";
public SimpleLifeCycleManager() {
DESCRIPTOR.setId(PLUGIN_ID);
}
private static class Steps {
public static final OperationDescriptor PUBLISH = new OperationDescriptor("PUBLISH","Materialize & index project");
static{
PUBLISH.setAppliableToPhases(Collections.singletonList(LifecycleInformation.CommonPhases.DRAFT_PHASE));
}
}
@Override
public Configuration getCurrentConfiguration(BaseRequest req) throws ConfigurationException {
Configuration toReturn = super.getCurrentConfiguration(req);
toReturn.setIndexes(new ArrayList<>());
IndexerPluginInterface indexerPlugin;
indexerPlugin = (IndexerPluginInterface) pluginManager.getById("SDI-Indexer-Plugin");
BaseRequest indexRequest = new BaseRequest(req.getUseCaseDescriptor(),req.getCaller(),req.getContext());
// Info on Public index
try {
indexRequest.setCallParameters(getPublicIndexParams(req));
Index publicIndex = indexerPlugin.getIndex(indexRequest);
publicIndex.put("flag", "public");
toReturn.getIndexes().add(publicIndex);
}catch(ConfigurationException e){
toReturn.addErrorMessage("Unable to gather information on public GIS Centroids Index : "+e.getMessage());
log.error("Unable to gather information on public GIS Centroids Index",e);
}
return toReturn;
}
protected Document getPublicIndexParams(BaseRequest req){
Document callParameters = new Document();
callParameters.put("workspace",Files.fixFilename(req.getUseCaseDescriptor().getId()+req.getContext().getName()));
callParameters.put("indexName",Files.fixFilename(req.getUseCaseDescriptor().getId()+req.getContext().getName()+"_centroids"));
return callParameters;
}
protected Document getMaterializationParameters(BaseRequest request){
Document params = new Document();
String workspace = request.getUseCaseDescriptor().getId() + request.getContext().getId();
params.put("workspace", Files.fixFilename(workspace));
return params;
}
@Override
protected void registerSteps() {
setStep(new GuardedStepExecution(Steps.PUBLISH) {
@Override
protected StepExecutionReport run() throws Exception {
//Check Performed by Guarded Step Execution
// if(!theReport.getTheRequest().getDocument().getLifecycleInformation().getPhase().equals(LifecycleInformation.CommonPhases.DRAFT_PHASE))
// throw new StepException("Document is not in "+LifecycleInformation.CommonPhases.DRAFT_PHASE+" phase");
// Materialize
for(MaterializationPlugin mat : getMaterializers(theReport.getTheRequest()))
theReport = materializeDocument(theReport, mat, getMaterializationParameters(theReport.getTheRequest()));
if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)){
// Index
for(IndexerPluginInterface indexer : getIndexers(theReport.getTheRequest()))
theReport = index(theReport,indexer,getPublicIndexParams(theReport.getTheRequest()));
// setPhase
if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK))
theReport.getToSetLifecycleInformation().setPhase("PUBLISHED");
}
return theReport;
}
});
}
protected void blockNonDraft(EventExecutionReport report) throws InvalidPluginRequestException {
Boolean force = false;
try {
force = Boolean.parseBoolean(report.getTheRequest().getCallParameters().get("force").toString());
}catch(Throwable t){}
if(!report.getTheRequest().getDocument().getLifecycleInformation().getPhase().equals(LifecycleInformation.CommonPhases.DRAFT_PHASE) && ! force)
throw new InvalidPluginRequestException("Document is not in "+LifecycleInformation.CommonPhases.DRAFT_PHASE+" phase");
}
@Override
protected EventExecutionReport onInitDocument(EventExecutionReport report) throws InvalidPluginRequestException {
blockNonDraft(report);
return super.onInitDocument(report);
}
@Override
protected EventExecutionReport onUpdateDocument(EventExecutionReport report) {
return super.onUpdateDocument(report);
}
@Override
protected EventExecutionReport onDeleteDocument(EventExecutionReport report) throws ConfigurationException, InvalidPluginRequestException, MaterializationException, EventException {
// Block non draft only if not force
Boolean force=Boolean.parseBoolean(report.getTheRequest().getWithDefault("force","false"));
log.debug("ON DELETE for {} : force is {}",report.getTheRequest().getDocument().getId(),force);
if(!force) blockNonDraft(report);
// dematerialize all
JSONPathWrapper wrapper = new JSONPathWrapper(report.getTheRequest().getDocument().getTheDocument().toJson());
for (String s : wrapper.getMatchingPaths("$..[?(@." + RegisteredFileSet.PAYLOADS + ")]")){
log.info("Requesting dematerialization for {} ",s);
for(MaterializationPlugin mat : getMaterializers(report.getTheRequest()))
report = deMaterialize(report,mat,new Document("fileSetPath",s));
if(!report.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK))
break;
}
if(report.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK)) {
for(IndexerPluginInterface indexer : getIndexers(report.getTheRequest()))
report = deIndex(report,indexer,getPublicIndexParams(report.getTheRequest()));
}
return report;
}
@Override
protected EventExecutionReport onDeleteFileSet(EventExecutionReport theReport) throws ConfigurationException, InvalidPluginRequestException, MaterializationException, EventException {
// dematerialize selected
blockNonDraft(theReport);
for(MaterializationPlugin mat : getMaterializers(theReport.getTheRequest()))
deMaterialize(theReport,mat,
theReport.getTheRequest().getCallParameters());
// de index
for(IndexerPluginInterface indexer : getIndexers(theReport.getTheRequest()))
if(theReport.getToSetLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK))
deIndex(theReport,indexer,getPublicIndexParams(theReport.getTheRequest()));
return theReport;
}
@Override
protected void registerEvents() {
super.registerEvents();
}
protected List<IndexerPluginInterface> getIndexers(BaseRequest request) throws ConfigurationException {
log.trace("Looking for Indexers for {}",request);
ArrayList<IndexerPluginInterface> toReturn=new ArrayList<>();
UseCaseDescriptor desc = request.getUseCaseDescriptor();
List<HandlerDeclaration> indexers = desc.getHandlersByType(IndexerPluginDescriptor.INDEXER);
log.debug("Found UCD [{}] Indexers : {}",desc.getId(),indexers.size());
for (HandlerDeclaration handlerDeclaration : indexers)
toReturn.add((IndexerPluginInterface) pluginManager.getById(handlerDeclaration.getId()));
return toReturn;
}
protected List<MaterializationPlugin> getMaterializers(BaseRequest request) throws ConfigurationException {
log.trace("Looking for materializers for {}",request);
ArrayList<MaterializationPlugin> toReturn=new ArrayList<>();
UseCaseDescriptor desc = request.getUseCaseDescriptor();
List<HandlerDeclaration> materializers = desc.getHandlersByType(MaterializerPluginDescriptor.MATERIALIZER);
log.debug("Found UCD [{}] Materializers : {}",desc.getId(),materializers.size());
for (HandlerDeclaration handlerDeclaration : materializers) {
toReturn.add((MaterializationPlugin) pluginManager.getById(handlerDeclaration.getId()));
}
return toReturn;
}
protected <T extends DocumentHandlingReport> T deIndex(T report, IndexerPluginInterface indexer, Document parameters) throws InvalidPluginRequestException {
BaseExecutionRequest request = report.getTheRequest();
IndexDocumentRequest indexRequest = new IndexDocumentRequest(
request.getUseCaseDescriptor(),request.getCaller(), request.getContext(),request.getDocument());
indexRequest.setCallParameters(parameters);
IndexDocumentReport indexReport = indexer.deindex(indexRequest);
return handleReport(indexReport,report);
}
protected <T extends DocumentHandlingReport> T deMaterialize(T report, MaterializationPlugin plugin, Document parameters) throws InvalidPluginRequestException, MaterializationException {
BaseExecutionRequest request = report.getTheRequest();
MaterializationRequest matReq =
new MaterializationRequest(request.getUseCaseDescriptor(),request.getCaller(), request.getContext(), request.getDocument());
Document params = new Document();
String workspace = request.getUseCaseDescriptor().getId() + request.getContext().getId();
params.put("workspace", Files.fixFilename(workspace));
matReq.setCallParameters(params);
MaterializationReport matRep = plugin.dematerialize(matReq);
return handleReport(matRep,report);
}
protected <T extends DocumentHandlingReport> T index(T report, IndexerPluginInterface indexer, Document parameters) throws InvalidPluginRequestException {
BaseExecutionRequest request = report.getTheRequest();
IndexDocumentRequest indexRequest = new IndexDocumentRequest(
request.getUseCaseDescriptor(),request.getCaller(), request.getContext(),request.getDocument());
indexRequest.setCallParameters(parameters);
IndexDocumentReport indexReport = null;
try {
indexRequest.setCallParameters(evaluateAdditionalIndexParameters(indexRequest));
indexReport = indexer.index(indexRequest);
}catch (IndexingException e){
log.error("Unable to serve index request.",e);
indexReport = new IndexDocumentReport(indexRequest);
indexReport.setStatus(Report.Status.ERROR);
indexReport.setMessages(new ArrayList<>());
indexReport.getMessages().add("Unable to evaluate centroids : "+e.getMessage());
}
return handleReport(indexReport,report);
}
protected Document evaluateAdditionalIndexParameters(IndexDocumentRequest request) throws IndexingException {return request.getCallParameters();}
protected <T extends DocumentHandlingReport> T materializeDocument(T report,MaterializationPlugin plugin,Document parameters) throws InvalidPluginRequestException, MaterializationException {
BaseExecutionRequest request = report.getTheRequest();
MaterializationRequest matReq =
new MaterializationRequest(request.getUseCaseDescriptor(),request.getCaller(), request.getContext(), request.getDocument());
matReq.setCallParameters(parameters);
MaterializationReport matRep = plugin.materialize(matReq);
return handleReport(matRep,report);
}
private <T extends DocumentHandlingReport> T handleReport(DocumentHandlingReport toHandle, T toUpdate){
toUpdate.setResultingDocument(toHandle.getResultingDocument());
LifecycleInformation info = toUpdate.getToSetLifecycleInformation();
switch(toHandle.getStatus()){
case OK : {
info.setLastOperationStatus(LifecycleInformation.Status.OK);
if(toHandle instanceof IndexDocumentReport)
toUpdate.setToSetIdentificationReferences(((IndexDocumentReport)toHandle).getToSetIdentificationReferences());
// Propagate changes for further processings
toUpdate.getTheRequest().getDocument().setTheDocument(toHandle.getResultingDocument());
toUpdate.setToSetLifecycleInformation(toHandle.getToSetLifecycleInformation());
// if(toHandle instanceof MaterializationReport)
// toUpdate.setToSetSpatialReference(((IndexDocumentReport)toHandle).getToSetSpatialReference());
break;
}
case ERROR : {
info.setLastOperationStatus(LifecycleInformation.Status.ERROR);
toHandle.getMessages().forEach(s -> info.addErrorMessage(s));
break;
}
case WARNING : {
info.setLastOperationStatus(LifecycleInformation.Status.WARNING);
toHandle.getMessages().forEach(s -> info.addWarningMessage(s));
break;
}
}
return toUpdate;
}
}