gcube-cms-suite/concessioni-lifecycle/src/main/java/org/gcube/application/cms/concessioni/plugins/ConcessioniLifeCycleManager...

373 lines
17 KiB
Java

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;
}
}