Skip to content

Commit

Permalink
#1158 Move workflow check in CRUDTransaction
Browse files Browse the repository at this point in the history
- Check status of Item or Collection with database object (for
thread-safety)
  • Loading branch information
MPDLTam committed Dec 23, 2019
1 parent 81e570c commit 32d3c2d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 29 deletions.
64 changes: 64 additions & 0 deletions src/main/java/de/mpg/imeji/j2j/transaction/CRUDTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.NotImplementedException;
import org.apache.jena.query.Dataset;
import org.apache.jena.query.ReadWrite;

import de.mpg.imeji.exceptions.ImejiException;
import de.mpg.imeji.exceptions.NotFoundException;
import de.mpg.imeji.exceptions.WorkflowException;
import de.mpg.imeji.j2j.controler.ResourceController;
import de.mpg.imeji.logic.model.Properties;
import de.mpg.imeji.logic.model.aspects.CloneURI;
import de.mpg.imeji.logic.workflow.WorkflowValidator;

/**
* {@link Transaction} for CRUD methods
Expand Down Expand Up @@ -51,6 +57,7 @@ public CRUDTransaction(List<Object> objects, CRUDTransactionType type, String mo
protected void execute(Dataset ds) throws ImejiException {
final ResourceController rc = new ResourceController(getModel(ds), lazy);
for (final Object o : objects) {
checkObjectStatus(rc, o);
invokeResourceController(rc, o);
}
}
Expand All @@ -59,6 +66,62 @@ public List<Object> getResults() {
return this.results;
}

/**
* For data objects that have a status (i.e. Item or CollectionImeji) check whether the status
* allows proceeding with a create, update or delete operation.
*
* @param object
* @throws NotFoundException
* @throws WorkflowException
*/
private void checkObjectStatus(ResourceController resourceController, Object object) throws NotFoundException, WorkflowException {

if (object instanceof Properties) {

if (this.type == CRUDTransactionType.CREATE || this.type == CRUDTransactionType.UPDATE || this.type == CRUDTransactionType.DELETE) {
// check status of database object and not client object
Object databaseObject = getCorrespondingObjectInDatabase(object, resourceController);
WorkflowValidator workflowManager = new WorkflowValidator();
switch (this.type) {
case CREATE:
workflowManager.isCreateAllowed((Properties) databaseObject);
break;
case DELETE:
workflowManager.isDeleteAllowed((Properties) databaseObject);
break;
case UPDATE:
workflowManager.isUpdateAllowed((Properties) databaseObject);
break;
default:
// error
}
}
}
}

/**
* Given a data object that has been manipulated by a client, read the corresponding data object
* from database. Useful in order to determine if database object has changed since it was last
* read by the client.
*
* @param clientImejiDataObject
* @param resourceController
* @return
* @throws NotFoundException
*/
private Object getCorrespondingObjectInDatabase(Object clientImejiDataObject, ResourceController resourceController)
throws NotFoundException {

if (clientImejiDataObject instanceof CloneURI) {
Object currentObjectInJena = resourceController.read(((CloneURI) clientImejiDataObject).cloneURI());
return currentObjectInJena;
} else {
throw new NotImplementedException("Could not process update request, interface CloneURI not implemented but should be in class "
+ clientImejiDataObject.getClass());
}
}



/**
* Make the CRUD operation for one {@link Object} thanks to the {@link ResourceController}
Expand Down Expand Up @@ -88,6 +151,7 @@ private void invokeResourceController(ResourceController rc, Object o) throws Im
}
}


@Override
protected ReadWrite getLockType() {
switch (type) {
Expand Down
29 changes: 0 additions & 29 deletions src/main/java/de/mpg/imeji/logic/db/writer/WriterFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import de.mpg.imeji.exceptions.SearchIndexBulkFailureException;
import de.mpg.imeji.exceptions.SearchIndexFailureException;
import de.mpg.imeji.exceptions.UnprocessableError;
import de.mpg.imeji.exceptions.WorkflowException;
import de.mpg.imeji.logic.config.Imeji;
import de.mpg.imeji.logic.db.indexretry.RetryIndex;
import de.mpg.imeji.logic.db.indexretry.model.RetryBaseRequest;
Expand All @@ -34,7 +33,6 @@
import de.mpg.imeji.logic.model.CollectionImeji;
import de.mpg.imeji.logic.model.ContentVO;
import de.mpg.imeji.logic.model.Item;
import de.mpg.imeji.logic.model.Properties;
import de.mpg.imeji.logic.model.Subscription;
import de.mpg.imeji.logic.model.User;
import de.mpg.imeji.logic.model.UserGroup;
Expand All @@ -48,7 +46,6 @@
import de.mpg.imeji.logic.util.ObjectsHelper;
import de.mpg.imeji.logic.validation.ValidatorFactory;
import de.mpg.imeji.logic.validation.impl.Validator;
import de.mpg.imeji.logic.workflow.WorkflowValidator;

/**
* Facade implementing Writer {@link Authorization}
Expand All @@ -62,7 +59,6 @@ public class WriterFacade {
private static final Logger LOGGER = LogManager.getLogger(WriterFacade.class);
private final Writer writer;
private final SearchIndexer indexer;
private final WorkflowValidator workflowManager = new WorkflowValidator();
private final ExecutorService executor = Executors.newCachedThreadPool();

/**
Expand Down Expand Up @@ -114,7 +110,6 @@ public List<Object> create(List<Object> objects, User user) throws ImejiExceptio
if (objects.isEmpty()) {
return objects;
}
checkWorkflow(objects, "create");
checkSecurity(objects, user, true);
validate(objects, Validator.Method.CREATE);
List<Object> createdObjects = writeAndIndex(new CreateTask(objects, user), new IndexTask());
Expand All @@ -132,7 +127,6 @@ public void delete(List<Object> objects, User user) throws ImejiException {
if (objects.isEmpty()) {
return;
}
checkWorkflow(objects, "delete");
checkSecurity(objects, user, false);
validate(objects, Validator.Method.DELETE);
writeAndIndex(new DeleteTask(objects, user), new DeleteIndexTask());
Expand All @@ -149,7 +143,6 @@ public List<Object> update(List<Object> objects, final User user, boolean doChec
if (objects.isEmpty()) {
return objects;
}
checkWorkflow(objects, "update");
if (doCheckSecurity) {
checkSecurity(objects, user, false);
}
Expand Down Expand Up @@ -192,7 +185,6 @@ public Object changeElement(ChangeMember changeMember, User user) throws ImejiEx
}

List<Object> imejiDataObjectList = Arrays.asList(changeMember.getImejiDataObject());
checkWorkflow(imejiDataObjectList, "update");
checkSecurity(imejiDataObjectList, user, true);
Object valueToSet = changeMember.getValue();
validate(valueToSet, Validator.Method.UPDATE);
Expand All @@ -216,7 +208,6 @@ public List<Object> editElements(List<ChangeMember> changeElements, User user) t

List<Object> imejiDataObjectList =
changeElements.stream().map(dataObject -> dataObject.getImejiDataObject()).collect(Collectors.toList());
checkWorkflow(imejiDataObjectList, "update");
checkSecurity(imejiDataObjectList, user, true);
for (ChangeMember changeMember : changeElements) {
Object valueToSet = changeMember.getValue();
Expand Down Expand Up @@ -317,7 +308,6 @@ private List<Object> writeToDatabase(Callable<List<Object>> databaseTask) throws
throw new ImejiException(execExept.getMessage());
}
}

return objectsInDatabase;
}

Expand Down Expand Up @@ -428,25 +418,6 @@ private void validate(Object object, Validator.Method method) throws Unprocessab
validator.validate(object, method);
}

private void checkWorkflow(List<Object> objects, String operation) throws WorkflowException {

for (final Object o : objects) {
if (o instanceof Properties) {
switch (operation) {
case "create":
workflowManager.isCreateAllowed((Properties) o);
break;
case "delete":
workflowManager.isDeleteAllowed((Properties) o);
break;
case "update":
workflowManager.isUpdateAllowed((Properties) o);
break;
}
}
}
}

/**
* Check {@link Security} for WRITE operations
*
Expand Down

0 comments on commit 32d3c2d

Please sign in to comment.