This commit is contained in:
Fabio Sinibaldi 2022-03-18 18:35:43 +01:00
parent c8ad2a1004
commit 6957fe0ea6
8 changed files with 311 additions and 93 deletions

View File

@ -0,0 +1,28 @@
package org.gcube.application.geoportal.common.model.document;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
import org.gcube.application.geoportal.common.model.document.accounting.AccountingInfo;
import org.gcube.application.geoportal.common.model.document.accounting.User;
import java.time.LocalDateTime;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public class Lock {
public static final String ID="_id";
public static final String INFO="_info";
public static final String OPERATION="_operation";
@JsonProperty(INFO)
private AccountingInfo info;
@JsonProperty(ID)
private String id;
@JsonProperty(OPERATION)
private String operation;
}

View File

@ -8,6 +8,9 @@ import org.gcube.application.geoportal.common.model.document.accounting.Publicat
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.document.temporal.TemporalReference;
import java.util.Arrays;
import java.util.Objects;
@NoArgsConstructor
@AllArgsConstructor
@ -26,6 +29,7 @@ public class Project {
public static final String SPATIAL_REFERENCE="_spatialReference";
public static final String TEMPORAL_REFERENCE="_temporalReference";
public static final String THE_DOCUMENT="_theDocument";
public static final String LOCK="_lock";
// CORE METADATA
@ -59,4 +63,22 @@ public class Project {
@JsonProperty(THE_DOCUMENT)
private Document theDocument;
@JsonProperty(LOCK)
private Lock lock;
/**
* Similar to equals but without checking following fields
*
* lock
* @param o
* @return
*/
public boolean isEquivalent(Object o) {
if (this == o) return true;
if (!(o instanceof Project)) return false;
Project project = (Project) o;
return Objects.equals(getId(), project.getId()) && Objects.equals(getVersion(), project.getVersion()) && Objects.equals(getInfo(), project.getInfo()) && Objects.equals(getProfileID(), project.getProfileID()) && Objects.equals(getProfileVersion(), project.getProfileVersion()) && Objects.equals(getLifecycleInformation(), project.getLifecycleInformation()) && Arrays.equals(getRelationships(), project.getRelationships()) && Objects.equals(getSpatialReference(), project.getSpatialReference()) && Objects.equals(getTemporalReference(), project.getTemporalReference()) && Objects.equals(getTheDocument(), project.getTheDocument());
}
}

View File

@ -10,6 +10,9 @@ import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.service.model.internal.faults.DeletionException;
import org.gcube.application.geoportal.service.model.internal.faults.InvalidLockException;
import org.gcube.application.geoportal.service.model.internal.faults.ProjectLockedException;
import org.gcube.application.geoportal.service.model.internal.faults.ProjectNotFoundException;
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
import java.io.IOException;
@ -22,7 +25,7 @@ public interface MongoManagerI<T> {
public T registerNew(Document toRegister) throws IOException, StepException, EventException;
// update
public T update(String id,Document toSetDocument) throws IOException, StepException, EventException;
public T update(String id,Document toSetDocument) throws IOException, StepException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException;
// delete
@ -30,17 +33,17 @@ public interface MongoManagerI<T> {
// get By ID
public T getByID(String id) throws IOException;
public T getByID(String id) throws IOException, ProjectNotFoundException;
// query
public Iterable<Document> query(QueryRequest request);
public Iterable<T> filter(QueryRequest request);
public T performStep(String id, String step, Document options) throws IOException, StepException;
public T performStep(String id, String step, Document options) throws IOException, StepException, ProjectLockedException, ProjectNotFoundException, InvalidLockException;
public T registerFileSet(String id, RegisterFileSetRequest request) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException;
public T deleteFileSet(String id, String destination, Boolean force) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException;
public T registerFileSet(String id, RegisterFileSetRequest request) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException;
public T deleteFileSet(String id, String destination, Boolean force) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException;
public Configuration getConfiguration()throws ConfigurationException;
}

View File

@ -3,8 +3,12 @@ package org.gcube.application.geoportal.service.engine.mongo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.FindOneAndReplaceOptions;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import com.vdurmont.semver4j.Semver;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.ArrayStack;
import org.apache.commons.io.IOUtils;
@ -45,9 +49,8 @@ import org.gcube.application.geoportal.service.engine.WorkspaceManager;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.service.engine.providers.PluginManager;
import org.gcube.application.geoportal.service.engine.providers.ProfileMapCache;
import org.gcube.application.geoportal.service.model.internal.faults.DeletionException;
import org.gcube.application.geoportal.service.model.internal.faults.*;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.geoportal.service.model.internal.faults.RegistrationException;
import org.gcube.application.geoportal.service.utils.UserUtils;
import org.gcube.common.storagehub.client.dsl.FolderContainer;
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
@ -56,6 +59,7 @@ import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.SerializedLambda;
import java.net.URL;
import java.security.InvalidParameterException;
import java.time.LocalDateTime;
@ -97,6 +101,71 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
return useCaseDescriptor.getId();
}
protected Project lock(String id,String op) throws ProjectNotFoundException, ProjectLockedException, JsonProcessingException {
log.trace("Locking {} cause {} ",id,op);
Lock lock = new Lock();
lock.setId(UUID.randomUUID().toString());
lock.setInfo(UserUtils.getCurrent().asInfo());
lock.setOperation(op);
// find one and update
// filter : id, lock == null
// update with new Lock object
Document filter = new Document(mongoIDFieldName(),asId(id)).append("$or",Arrays.asList(
new Document(Project.LOCK,new Document("$exists",false)),
new Document(Project.LOCK,new Document("$type","null"))));
log.debug("Lock filter is {} ",filter.toJson());
Object obj = getCollection().findOneAndUpdate(
// filter by id and missing lock
filter,
// update lock info
new Document("$set",new Document(Project.LOCK, Serialization.asDocument(lock))),
new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)
);
if(obj == null){
// unable to lock, verify cause
Project p=getByID(id);
if(p.getLock()!=null) throw new ProjectLockedException("Project already locked : "+p.getLock());
else {
log.error("Unable to lock {} ",id);
log.debug("Existing project is {} ",p);
throw new RuntimeException("Unable to lock unlocked project "+id);
}
} else return Serialization.convert(obj,Project.class);
}
protected Project unlockAndUpdate(Project proj) throws InvalidLockException, ProjectNotFoundException, JsonProcessingException {
log.trace("Unlocking {} lock is {} ",proj.getId(),proj.getLock());
// find one and update
Lock oldLock = proj.getLock();
proj.setLock(null);
Document filter = new Document(mongoIDFieldName(),asId(proj.getId())).append(Project.LOCK+"."+Lock.ID,oldLock.getId());
Object obj = getCollection().findOneAndReplace(
// filter by id and missing lock
filter,
// update lock info
asDocumentWithId(proj),
new FindOneAndReplaceOptions().returnDocument(ReturnDocument.AFTER));
if(obj== null){
// can-t unlock, check cause
Project p = getByID(proj.getId());
throw new InvalidLockException("Found lock for "+p.getId()+" is "+p.getLock()+", expected is "+oldLock);
}return Serialization.convert(obj,Project.class);
// filter : id, lock id
// update with project (NB without lock)
// if none matched
// not found if proj id non existent
// else invalid lock
// return null;
}
@Getter(lazy = true)
private final LifecycleManager manager=getLCManager();
@ -163,20 +232,24 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
ObjectId id =insertDoc(asDocumentWithId(toRegister));
log.info("Obtained id {} ",id);
return getByID(id.toHexString());
try {
return getByID(id.toHexString());
}catch (ProjectNotFoundException e){
throw new WebApplicationException("Unexpected exception while registering project ",e);
}
}
@Override
public Project update(String id, Document toSet) throws IOException, EventException {
public Project update(String id, Document toSet) throws IOException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException {
log.trace("Replacing {} ",toSet);
Project toUpdate=getByID(id);
toUpdate.setTheDocument(toSet);
toUpdate.getLifecycleInformation().cleanState();
toUpdate=onUpdate(toUpdate);
Project toReturn =convert(replaceDoc(asDocumentWithId(toUpdate),new ObjectId(id)), Project.class);
log.debug("Updated Project is {}",toReturn);
return toReturn;
Project toUpdate=lock(id,"Manual update");
try {
toUpdate.setTheDocument(toSet);
toUpdate.getLifecycleInformation().cleanState();
toUpdate = onUpdate(toUpdate);
}finally{
return unlockAndUpdate(toUpdate);
}
}
@ -192,7 +265,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
public void delete(String id,boolean force) throws DeletionException {
log.debug("Deleting by ID {}, force {}",id,force);
try{
Project doc =getByID(id);
Project doc =lock(id,"Deletion { force : "+force+"}");
// TODO INVOKE LIFECYCLE
@ -218,9 +291,9 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
}
@Override
public Project getByID(String id) throws WebApplicationException{
public Project getByID(String id) throws ProjectNotFoundException{
Document doc=getDocById(asId(id));
if(doc==null) throw new WebApplicationException("No document with ID "+id);
if(doc==null) throw new ProjectNotFoundException("No document with ID "+id);
return convert(doc, Project.class);
}
@ -250,8 +323,8 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
@Override
public Project performStep(String id, String step, Document options) throws StepException, JsonProcessingException {
Project document = getByID(id);
public Project performStep(String id, String step, Document options) throws StepException, JsonProcessingException, ProjectLockedException, ProjectNotFoundException, InvalidLockException {
Project document = lock(id,"Step "+step+" execution");
try{
document.getLifecycleInformation().cleanState();
document = step(document, step, options);
@ -268,7 +341,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
step,document.getLifecycleInformation().getLastOperationStatus());
log.debug("LifecycleInformation is {} ",document.getLifecycleInformation());
if(log.isTraceEnabled())log.trace("Document is {} ",Serialization.write(document));
return convert(replaceDoc(asDocumentWithId(document),new ObjectId(id)), Project.class);
return unlockAndUpdate(document);
}
}
@ -287,103 +360,119 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
*
*/
@Override
public Project registerFileSet(String id, RegisterFileSetRequest request) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException {
public Project registerFileSet(String id, RegisterFileSetRequest request) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException {
log.info("Registering Fileset for {} [useCaseDescriptor ID {}], Request is {} ",id, useCaseDescriptor.getId(),request);
List<TempFile> files=request.getStreams();
Document attributes =request.getAttributes();
Project doc=getByID(id);
doc.getLifecycleInformation().cleanState();
doc.getLifecycleInformation().setLastOperationStatus(LifecycleInformation.Status.OK);
Project doc=lock(id,"Register Fileset");
try {
doc.getLifecycleInformation().cleanState();
doc.getLifecycleInformation().setLastOperationStatus(LifecycleInformation.Status.OK);
WorkspaceManager ws=new WorkspaceManager();
StorageUtils storage=ImplementationProvider.get().getEngineByManagedClass(StorageUtils.class);
WorkspaceManager ws = new WorkspaceManager();
StorageUtils storage = ImplementationProvider.get().getEngineByManagedClass(StorageUtils.class);
log.debug("Checking field {} definition in {}",request.getFieldDefinitionPath(), useCaseDescriptor.getId());
Field fieldDefinition=getFieldDefinition(useCaseDescriptor,request.getFieldDefinitionPath());
log.debug("Checking field {} definition in {}", request.getFieldDefinitionPath(), useCaseDescriptor.getId());
Field fieldDefinition = getFieldDefinition(useCaseDescriptor, request.getFieldDefinitionPath());
JSONPathWrapper docWrapper=new JSONPathWrapper(doc.getTheDocument().toJson());
JSONPathWrapper docWrapper = new JSONPathWrapper(doc.getTheDocument().toJson());
List<String> matchingPaths = docWrapper.getMatchingPaths(request.getParentPath());
if(matchingPaths.size()>1) throw new WebApplicationException("Multiple Destination matching parent path "+request.getParentPath(),Response.Status.BAD_REQUEST);
if(matchingPaths.isEmpty()) throw new WebApplicationException("PArent path not found at "+request.getParentPath(),Response.Status.BAD_REQUEST);
List<String> matchingPaths = docWrapper.getMatchingPaths(request.getParentPath());
if (matchingPaths.size() > 1)
throw new WebApplicationException("Multiple Destination matching parent path " + request.getParentPath(), Response.Status.BAD_REQUEST);
if (matchingPaths.isEmpty())
throw new WebApplicationException("PArent path not found at " + request.getParentPath(), Response.Status.BAD_REQUEST);
String parentMatchingPath = matchingPaths.get(0);
List<Object> foundElementsByMatchingPaths = docWrapper.getByPath(parentMatchingPath);
if(foundElementsByMatchingPaths == null || foundElementsByMatchingPaths.isEmpty())
throw new WebApplicationException("No element found at "+ parentMatchingPath,Response.Status.BAD_REQUEST);
String parentMatchingPath = matchingPaths.get(0);
List<Object> foundElementsByMatchingPaths = docWrapper.getByPath(parentMatchingPath);
if (foundElementsByMatchingPaths == null || foundElementsByMatchingPaths.isEmpty())
throw new WebApplicationException("No element found at " + parentMatchingPath, Response.Status.BAD_REQUEST);
Document parent = Serialization.asDocument(foundElementsByMatchingPaths.get(0));
Document parent = Serialization.asDocument(foundElementsByMatchingPaths.get(0));
// PREPARE REGISTERED FS
// PREPARE REGISTERED FS
// MANAGE CLASH
switch (request.getClashOption()){
switch (request.getClashOption()) {
case REPLACE_EXISTING: {
if(fieldDefinition.isCollection())
throw new WebApplicationException("Cannot replace repeatable field "+request.getFieldDefinitionPath()+".",Response.Status.BAD_REQUEST);
if (fieldDefinition.isCollection())
throw new WebApplicationException("Cannot replace repeatable field " + request.getFieldDefinitionPath() + ".", Response.Status.BAD_REQUEST);
// DELETE EXISTING AND PUT
RegisteredFileSet toDelete = Serialization.convert(parent.get(request.getFieldName()),RegisteredFileSet.class);
if(!(toDelete == null)&&!(toDelete.isEmpty()))
deleteFileSetRoutine(toDelete,false,ws);
RegisteredFileSet toDelete = Serialization.convert(parent.get(request.getFieldName()), RegisteredFileSet.class);
if (!(toDelete == null) && !(toDelete.isEmpty()))
deleteFileSetRoutine(toDelete, false, ws);
RegisteredFileSet fs = prepareRegisteredFileSet(doc.getInfo(),doc.getId(), useCaseDescriptor.getId(), request.getAttributes(),files,storage,ws);
log.debug("Registered Fileset for [ID {} useCaseDescriptor {}] is {} ",fs,doc.getId(),doc.getProfileID());
docWrapper.putElement(parentMatchingPath,request.getFieldName(),fs);
break;}
RegisteredFileSet fs = prepareRegisteredFileSet(doc.getInfo(), doc.getId(), useCaseDescriptor.getId(), request.getAttributes(), files, storage, ws);
log.debug("Registered Fileset for [ID {} useCaseDescriptor {}] is {} ", fs, doc.getId(), doc.getProfileID());
docWrapper.putElement(parentMatchingPath, request.getFieldName(), fs);
break;
}
case MERGE_EXISTING: {
if(fieldDefinition.isCollection())
throw new WebApplicationException("Cannot merge repeatable field "+request.getFieldDefinitionPath()+".",Response.Status.BAD_REQUEST);
RegisteredFileSet original = Serialization.convert(parent.get(request.getFieldName()),RegisteredFileSet.class);
if (fieldDefinition.isCollection())
throw new WebApplicationException("Cannot merge repeatable field " + request.getFieldDefinitionPath() + ".", Response.Status.BAD_REQUEST);
RegisteredFileSet original = Serialization.convert(parent.get(request.getFieldName()), RegisteredFileSet.class);
// MERGE ATTRIBUTES AND PUT
Document toUseAttributes=request.getAttributes();
if(original!=null) toUseAttributes.putAll(original);
RegisteredFileSet fs = prepareRegisteredFileSet(doc.getInfo(),doc.getId(), useCaseDescriptor.getId(), toUseAttributes,files,storage,ws);
log.debug("Registered Fileset for [ID {} useCaseDescriptor {}] is {} ",fs,doc.getId(),doc.getProfileID());
docWrapper.putElement(parentMatchingPath,request.getFieldName(),fs);
break;}
Document toUseAttributes = request.getAttributes();
if (original != null) toUseAttributes.putAll(original);
RegisteredFileSet fs = prepareRegisteredFileSet(doc.getInfo(), doc.getId(), useCaseDescriptor.getId(), toUseAttributes, files, storage, ws);
log.debug("Registered Fileset for [ID {} useCaseDescriptor {}] is {} ", fs, doc.getId(), doc.getProfileID());
docWrapper.putElement(parentMatchingPath, request.getFieldName(), fs);
break;
}
case APPEND: {
if(!fieldDefinition.isCollection())
throw new WebApplicationException("Cannot add to single field "+request.getFieldDefinitionPath()+".",Response.Status.BAD_REQUEST);
RegisteredFileSet fs = prepareRegisteredFileSet(doc.getInfo(),doc.getId(), useCaseDescriptor.getId(), request.getAttributes(),files,storage,ws);
log.debug("Registered Fileset for [ID {} useCaseDescriptor {}] is {} ",fs,doc.getId(),doc.getProfileID());
if (!fieldDefinition.isCollection())
throw new WebApplicationException("Cannot add to single field " + request.getFieldDefinitionPath() + ".", Response.Status.BAD_REQUEST);
RegisteredFileSet fs = prepareRegisteredFileSet(doc.getInfo(), doc.getId(), useCaseDescriptor.getId(), request.getAttributes(), files, storage, ws);
log.debug("Registered Fileset for [ID {} useCaseDescriptor {}] is {} ", fs, doc.getId(), doc.getProfileID());
docWrapper.addElementToArray(String.format("%1ds['%2$s']",parentMatchingPath,request.getFieldName()),fs);
break;}
default: {throw new WebApplicationException("Unexpected clash policy "+request.getClashOption(),Response.Status.BAD_REQUEST);}
docWrapper.addElementToArray(String.format("%1ds['%2$s']", parentMatchingPath, request.getFieldName()), fs);
break;
}
default: {
throw new WebApplicationException("Unexpected clash policy " + request.getClashOption(), Response.Status.BAD_REQUEST);
}
}
log.debug("Setting result on profiled document");
doc.setTheDocument(Document.parse(docWrapper.getValueCTX().jsonString()));
log.debug("Setting result on profiled document");
doc.setTheDocument(Document.parse(docWrapper.getValueCTX().jsonString()));
doc=onUpdate(doc);
return convert(replaceDoc(asDocumentWithId(doc),new ObjectId(id)), Project.class);
doc = onUpdate(doc);
}finally {
return unlockAndUpdate(doc);
}
}
@Override
public Project deleteFileSet(String id, String path, Boolean force) throws ConfigurationException, StorageHubException, JsonProcessingException, DeletionException, EventException {
public Project deleteFileSet(String id, String path, Boolean force) throws ConfigurationException, StorageHubException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException {
log.info("Deleting Fileset for {} [useCaseDescriptor ID {}], at {} [force {} ]",id, useCaseDescriptor.getId(),path,force);
Project doc = getByID(id);
doc.getLifecycleInformation().cleanState();
doc.getLifecycleInformation().cleanState().setLastOperationStatus(LifecycleInformation.Status.OK);
Project doc = lock(id,"Fileset Deletion");
try {
doc.getLifecycleInformation().cleanState();
doc.getLifecycleInformation().cleanState().setLastOperationStatus(LifecycleInformation.Status.OK);
JSONPathWrapper wrapper = new JSONPathWrapper(doc.getTheDocument().toJson());
List<String> matchingPaths=wrapper.getMatchingPaths(path);
if(matchingPaths.isEmpty()) throw new WebApplicationException("No Registered FileSet found at "+path,Response.Status.BAD_REQUEST);
if(matchingPaths.size()>1) throw new WebApplicationException("Multiple Fileset ("+matchingPaths.size()+") matching "+path,Response.Status.BAD_REQUEST);
RegisteredFileSet fs = Serialization.convert(wrapper.getByPath(path),RegisteredFileSet.class);
log.debug("Going to delete {}",fs);
deleteFileSetRoutine(fs,force,new WorkspaceManager());
log.debug("Removing FS from document [ID : ] by path {}",id,path);
wrapper.setElement(path,null);
doc=onUpdate(doc);
return convert(replaceDoc(asDocumentWithId(doc),new ObjectId(id)), Project.class);
JSONPathWrapper wrapper = new JSONPathWrapper(doc.getTheDocument().toJson());
List<String> matchingPaths = wrapper.getMatchingPaths(path);
if (matchingPaths.isEmpty())
throw new WebApplicationException("No Registered FileSet found at " + path, Response.Status.BAD_REQUEST);
if (matchingPaths.size() > 1)
throw new WebApplicationException("Multiple Fileset (" + matchingPaths.size() + ") matching " + path, Response.Status.BAD_REQUEST);
RegisteredFileSet fs = Serialization.convert(wrapper.getByPath(path), RegisteredFileSet.class);
log.debug("Going to delete {}", fs);
deleteFileSetRoutine(fs, force, new WorkspaceManager());
log.debug("Removing FS from document [ID : ] by path {}", id, path);
wrapper.setElement(path, null);
doc = onUpdate(doc);
}finally {
return unlockAndUpdate(doc);
}
}
@Override
@ -477,19 +566,19 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
}
}
private Project triggerEvent(Project theDocument, String event, Document parameters) {
private Project triggerEvent(Project project, String event, Document parameters) {
try{
log.info("[UseCaseDescriptor {}] triggering event {} on {}" , useCaseDescriptor.getId(),event,getManager().getDescriptor());
AccountingInfo user= UserUtils.getCurrent().asInfo();
EventExecutionRequest request= new EventExecutionRequest(useCaseDescriptor,user.getUser(),user.getContext(),theDocument,event);
EventExecutionRequest request= new EventExecutionRequest(useCaseDescriptor,user.getUser(),user.getContext(),project,event);
log.debug("Triggering {}",request);
DocumentHandlingReport report = getManager().onEvent(request);
return report.prepareResult();
} catch (Throwable t){
log.error("Unable to trigger event "+event,t);
theDocument.getLifecycleInformation().addErrorMessage("Unable to trigger "+event+" cause : "+ t.getMessage());
theDocument.getLifecycleInformation().setLastOperationStatus(LifecycleInformation.Status.ERROR);
return theDocument;
project.getLifecycleInformation().addErrorMessage("Unable to trigger "+event+" cause : "+ t.getMessage());
project.getLifecycleInformation().setLastOperationStatus(LifecycleInformation.Status.ERROR);
return project;
}
}

View File

@ -0,0 +1,22 @@
package org.gcube.application.geoportal.service.model.internal.faults;
public class InvalidLockException extends Exception{
public InvalidLockException() {
}
public InvalidLockException(String message) {
super(message);
}
public InvalidLockException(String message, Throwable cause) {
super(message, cause);
}
public InvalidLockException(Throwable cause) {
super(cause);
}
public InvalidLockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,22 @@
package org.gcube.application.geoportal.service.model.internal.faults;
public class ProjectLockedException extends Exception{
public ProjectLockedException() {
}
public ProjectLockedException(String message) {
super(message);
}
public ProjectLockedException(String message, Throwable cause) {
super(message, cause);
}
public ProjectLockedException(Throwable cause) {
super(cause);
}
public ProjectLockedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,22 @@
package org.gcube.application.geoportal.service.model.internal.faults;
public class ProjectNotFoundException extends Exception {
public ProjectNotFoundException() {
}
public ProjectNotFoundException(String message) {
super(message);
}
public ProjectNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public ProjectNotFoundException(Throwable cause) {
super(cause);
}
public ProjectNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -1,6 +1,9 @@
package org.gcube.application.geoportal.service.rest;
import lombok.extern.slf4j.Slf4j;
import org.gcube.application.geoportal.service.model.internal.faults.InvalidLockException;
import org.gcube.application.geoportal.service.model.internal.faults.ProjectLockedException;
import org.gcube.application.geoportal.service.model.internal.faults.ProjectNotFoundException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response.Status;
@ -32,8 +35,15 @@ public abstract class GuardedMethod<T> {
result=run();
return this;
}catch(WebApplicationException e) {
log.error("Throwing Web Application Exception ",e);
log.error("Throwing Web Application Exception ", e);
throw e;
}catch(ProjectNotFoundException e){
throw new WebApplicationException("Project not found", e,Status.NOT_FOUND);
}catch(ProjectLockedException e){
throw new WebApplicationException("Project is currently locked", e,Status.PRECONDITION_FAILED);
}catch(InvalidLockException e){
log.error("Lock exception ",e);
throw new WebApplicationException("Conflicts found in locks", e,Status.CONFLICT);
}catch(Throwable t) {
log.error("Unexpected error ",t);
throw new WebApplicationException("Unexpected internal error", t,Status.INTERNAL_SERVER_ERROR);