package org.gcube.application.cms.concessioni.plugins; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.bson.BsonDocument; import org.bson.BsonString; import org.bson.BsonValue; import org.bson.Document; import org.gcube.application.cms.plugins.IndexerPluginInterface; import org.gcube.application.cms.plugins.MaterializationPlugin; import org.gcube.application.cms.plugins.PluginManagerInterface; import org.gcube.application.cms.plugins.faults.*; import org.gcube.application.cms.plugins.model.ComparableVersion; import org.gcube.application.cms.plugins.reports.*; import org.gcube.application.cms.plugins.requests.*; import org.gcube.application.cms.serialization.Serialization; import org.gcube.application.cms.custom.gna.concessioni.model.ProfiledConcessione; import org.gcube.application.cms.plugins.LifecycleManager; import org.gcube.application.cms.plugins.model.PluginDescriptor; import org.gcube.application.geoportal.common.model.configuration.Index; import org.gcube.application.geoportal.common.model.document.*; import org.gcube.application.geoportal.common.model.document.access.Access; import org.gcube.application.geoportal.common.model.document.access.AccessPolicy; 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.document.lifecycle.TriggeredEvents; import org.gcube.application.geoportal.common.model.legacy.report.ConstraintCheck; import org.gcube.application.geoportal.common.model.configuration.Configuration; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; import org.gcube.application.geoportal.common.utils.ContextUtils; import org.gcube.application.geoportal.common.utils.Files; import java.util.ArrayList; @Slf4j public class ConcessioniLifeCycleManager implements LifecycleManager { private static class Phases { public static final String PENDING_APPROVAL="Pending Approval"; } private static final PluginDescriptor DESCRIPTOR=new PluginDescriptor("GNA-CONCESSIONI-LC", PluginDescriptor.BaseTypes.LIFECYCLE_MANAGER); static { DESCRIPTOR.setDescription("GNA Concessioni. This plugin supports custom lifecycle management for the GNA Concessioni UseCase."); DESCRIPTOR.setVersion(new ComparableVersion("1.0.0")); } @Setter PluginManagerInterface pluginManager; @Override public InitializationReport initInContext() throws InitializationException { InitializationReport report = new InitializationReport(); try{ report.setStatus(Report.Status.OK); } catch (Throwable e) { log.error("Unable to initialize plugins in {} ",ContextUtils.getCurrentScope(),e); report.setStatus(Report.Status.WARNING); report.putMessage("Unable to initialize plugins in "+ ContextUtils.getCurrentScope()+" : "+e.getMessage()); } return report; } @Override public InitializationReport init() throws InitializationException { InitializationReport report = new InitializationReport(); try{ report.setStatus(Report.Status.OK); } catch (Throwable e) { log.error("Unable to initialize plugins ",e); report.setStatus(Report.Status.WARNING); report.putMessage("Unable to initialize plugins : "+e.getMessage()); } return report; } @Override public void shutdown() throws ShutDownException { } @Override public StepExecutionReport performStep(StepExecutionRequest request) throws StepException, InvalidPluginRequestException { log.info("Serving Request {}",request); StepExecutionReport report=new StepExecutionReport(request); report.setStatus(Report.Status.OK); LifecycleInformation info=report.getToSetLifecycleInformation(); info.setLastOperationStatus(LifecycleInformation.Status.OK); info.setLastInvokedStep(request.getStep()); try { MaterializationPlugin plugin; IndexerPluginInterface indexerPlugin; plugin= (MaterializationPlugin) pluginManager.getById("SDI-Default-Materializer"); indexerPlugin = (IndexerPluginInterface) pluginManager.getById("SDI-Indexer-Plugin"); switch (request.getStep()) { case "SUBMIT-FOR-REVIEW" :{ //TODO Checks if(!request.getDocument().getLifecycleInformation().getPhase().equals(LifecycleInformation.DRAFT_PHASE)) throw new StepException("Document is not in Draft phase"); //Materialize layers MaterializationRequest matReq = new MaterializationRequest(request.getUseCaseDescriptor(),request.getCaller(), request.getContext(), request.getDocument()); matReq.setDocument(request.getDocument()); matReq.setUseCaseDescriptor(request.getUseCaseDescriptor()); Document params = new Document(); String workspace = request.getUseCaseDescriptor().getId() + request.getContext().getId(); params.put("workspace", Files.fixFilename(workspace)); matReq.setCallParameters(params); MaterializationReport matRep = plugin.materialize(matReq); report.setResultingDocument(matRep.getResultingDocument()); switch(matRep.getStatus()){ case OK : { info.setPhase(Phases.PENDING_APPROVAL); //TODO Index-confidential //TODO Notifications break; } case ERROR : { info.setLastOperationStatus(LifecycleInformation.Status.ERROR); matRep.getMessages().forEach(s -> info.addErrorMessage(s)); break; } case WARNING : { info.setLastOperationStatus(LifecycleInformation.Status.WARNING); matRep.getMessages().forEach(s -> info.addWarningMessage(s)); break; } } } break; case "REJECT-DRAFT":{ // Notification // Set break; } case "APPROVE DRAFT":{ // Index-published if(!request.getDocument().getLifecycleInformation().getPhase() .equals(Phases.PENDING_APPROVAL)) throw new StepException("Document is not in "+Phases.PENDING_APPROVAL+" phase"); IndexDocumentRequest indexRequest = new IndexDocumentRequest(request.getUseCaseDescriptor(),request.getCaller(), request.getContext(),request.getDocument()); Document callParameters = getPublicIndexParams(request); indexRequest.setCallParameters(callParameters); IndexDocumentReport indexReport = indexerPlugin.index(indexRequest); switch(indexReport.getStatus()){ case OK : { info.setPhase("PUBLISHED"); report.setToSetSpatialReference(indexReport.getToSetSpatialReference()); break; } case ERROR : { info.setLastOperationStatus(LifecycleInformation.Status.ERROR); indexReport.getMessages().forEach(s -> info.addErrorMessage(s)); break; } case WARNING : { info.setLastOperationStatus(LifecycleInformation.Status.WARNING); indexReport.getMessages().forEach(s -> info.addWarningMessage(s)); break; } } break; } default: throw new StepException("Invalid Step " + request.getStep()); } }catch (StepException e){ throw e; }catch (Throwable t){ log.error("Unable to perform step "+request.getStep(),t); String msg = "Unable to execute Step "+request.getStep()+". Error was "+t.getMessage(); report.setStatus(Report.Status.ERROR); report.putMessage(msg); info.setLastOperationStatus(LifecycleInformation.Status.ERROR); info.addErrorMessage(msg); } return report; } @Override public EventExecutionReport onEvent(EventExecutionRequest request) throws EventException, InvalidPluginRequestException { log.info("Executing Event {}",request); EventExecutionReport report=new EventExecutionReport(request); TriggeredEvents info=new TriggeredEvents(); info.setEvent(request.getEvent()); info.setLastOperationStatus(LifecycleInformation.Status.OK); report.setStatus(Report.Status.OK); try { switch(request.getEvent()){ case EventExecutionRequest.Events.ON_INIT_DOCUMENT: // Set Defaults as for on update case EventExecutionRequest.Events.ON_UPDATE_DOCUMENT: { log.debug("Setting default values.."); // TODO implement defaults for concessione // report.setResult(setDefaults(request.getDocument())); break; } case EventExecutionRequest.Events.ON_DELETE_DOCUMENT: { //DELETE ALL break; } default: throw new EventException("Unexpected Event "+request.getEvent()); } }catch (EventException e){ throw e; }catch (Throwable t){ log.error("Unable to execute on event "+request.getEvent(),t); String msg = "Unable to execute on event "+request.getEvent()+". Error was "+t.getMessage(); info.setLastOperationStatus(LifecycleInformation.Status.ERROR); info.addErrorMessage(msg); report.setStatus(Report.Status.ERROR); report.putMessage(msg); }finally{ report.getToSetLifecycleInformation().addEventReport(info); } return report; } @Override public Configuration getCurrentConfiguration(BaseRequest req) throws ConfigurationException { Configuration toReturn = new Configuration(); 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); } // Info on internal_index try { indexRequest.setCallParameters(getInternalIndexParams(req)); Index internalIndex = indexerPlugin.getIndex(indexRequest); internalIndex.put("flag", "internal"); toReturn.getIndexes().add(internalIndex); }catch(ConfigurationException e){ toReturn.addErrorMessage("Unable to gather information on internal GIS Centroids Index : "+e.getMessage()); log.error("Unable to gather information on internal GIS Centroids Index",e); } return toReturn; } @Override public PluginDescriptor getDescriptor() { return DESCRIPTOR; } private Document getInternalIndexParams(BaseRequest req){ Document callParameters = new Document(); callParameters.put("workspace",Files.fixFilename(req.getUseCaseDescriptor().getId()+"_internal_"+req.getContext().getName())); callParameters.put("indexName",Files.fixFilename(req.getUseCaseDescriptor().getId()+"_internal_"+req.getContext().getName()+"_centroids")); return callParameters; } private 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; } // STATIC ROUTINES private static final Project setDefaults(Project document){ ProfiledConcessione c=Serialization.convert(document,ProfiledConcessione.class); Document doc=c.getTheDocument(); doc.putIfAbsent(ProfiledConcessione.SOGGETTO,new String[]{"Research Excavation","Archaeology"}); doc.putIfAbsent(ProfiledConcessione.DSCRIZIONE_CONTENUTO,"Relazione di fine scavo e relativo abstract; selezione di immagini rappresentative;" + " posizionamento topografico dell'area indagata, pianta di fine scavo."); // Super Section c.getInfo().getAccess().setLicense( ConstraintCheck.defaultFor(c.getInfo().getAccess().getLicense(), "CC0-1.0").evaluate()); //RELAZIONE // TODO NB provare se object gia' presente sia usando Document che sub Object doc.putIfAbsent(ProfiledConcessione.RELAZIONE_SCAVO,new Document()); Document rel=Serialization.convert(doc.get(ProfiledConcessione.RELAZIONE_SCAVO), Document.class); rel.putIfAbsent(ProfiledConcessione.Sections.TITOLO,doc.getString(ProfiledConcessione.NOME)+" relazione di scavo"); rel.putIfAbsent(ProfiledConcessione.SOGGETTO,doc.get(ProfiledConcessione.SOGGETTO)); rel.putIfAbsent(RegisteredFileSet.CREATION_INFO,c.getInfo().getCreationInfo()); rel.putIfAbsent(RegisteredFileSet.ACCESS,c.getInfo().getAccess()); Access relAccess=Serialization.convert(rel.get(RegisteredFileSet.ACCESS),Access.class); relAccess.setLicense(ConstraintCheck.defaultFor(relAccess.getLicense(),"CC-BY-4.0").evaluate()); relAccess.setPolicy(ConstraintCheck.defaultFor(relAccess.getPolicy(), AccessPolicy.OPEN).evaluate()); //ABSTRACT Relazione doc.putIfAbsent(ProfiledConcessione.ABSTRACT_RELAZIONE,new Document()); Document abs=Serialization.convert(doc.get(ProfiledConcessione.ABSTRACT_RELAZIONE),Document.class); abs.putIfAbsent(ProfiledConcessione.Sections.TITOLO,doc.getString(ProfiledConcessione.NOME)+" abstract relazione di scavo"); abs.putIfAbsent(RegisteredFileSet.CREATION_INFO,c.getInfo().getCreationInfo()); abs.putIfAbsent(RegisteredFileSet.ACCESS,c.getInfo().getAccess()); Access absAccess=Serialization.convert(abs.get(RegisteredFileSet.ACCESS),Access.class); absAccess.setLicense(ConstraintCheck.defaultFor(absAccess.getLicense(),"CC-BY-4.0").evaluate()); absAccess.setPolicy(ConstraintCheck.defaultFor(absAccess.getPolicy(), AccessPolicy.OPEN).evaluate()); //TODO complete setDefaults //IMMAGINI RAPPRESENTATIVE if(doc.containsKey(ProfiledConcessione.IMMAGINI_RAPPRESENTATIVE)) { for (BsonValue bsonValue : doc.toBsonDocument(null, null). getArray(ProfiledConcessione.IMMAGINI_RAPPRESENTATIVE)) { BsonDocument imgDocument = bsonValue.asDocument(); imgDocument.putIfAbsent(ProfiledConcessione.SOGGETTO,new BsonString(doc.getString(ProfiledConcessione.SOGGETTO))); // imgDocument.putIfAbsent(RegisteredFileSet.CREATION_INFO,this.getInfo().getCreationInfo()); // imgDocument.putIfAbsent(RegisteredFileSet.CREATION_INFO,new BsonDocument(new Document())); // imgDocument.putIfAbsent(RegisteredFileSet.ACCESS,this.getInfo().getAccess()); // Access absAccess=rel.get(RegisteredFileSet.ACCESS,Access.class); // absAccess.setLicense(ConstraintCheck.defaultFor(absAccess.getLicense(),"CC-BY-4.0").evaluate()); // absAccess.setPolicy(ConstraintCheck.defaultFor(absAccess.getPolicy(), AccessPolicy.OPEN).evaluate()); } } return c; } }