package org.gcube.application.cms.plugins.implementations; import lombok.extern.slf4j.Slf4j; import org.bson.Document; 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.*; import org.gcube.application.cms.plugins.implementations.executions.GuardedStepExecution; import org.gcube.application.cms.plugins.reports.*; import org.gcube.application.cms.plugins.requests.*; 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 { // dematerialize all blockNonDraft(report); 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 getIndexers(BaseRequest request) throws ConfigurationException { log.trace("Looking for Indexers for {}",request); ArrayList toReturn=new ArrayList<>(); UseCaseDescriptor desc = request.getUseCaseDescriptor(); List 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 getMaterializers(BaseRequest request) throws ConfigurationException { log.trace("Looking for materializers for {}",request); ArrayList toReturn=new ArrayList<>(); UseCaseDescriptor desc = request.getUseCaseDescriptor(); List 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 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 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 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 = indexer.index(indexRequest); return handleReport(indexReport,report); } protected 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 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; } }