From 47039349d271b24a84c369967857cb5f6dd61227 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Tue, 18 Apr 2023 15:47:14 +0200 Subject: [PATCH] [Ticket 2124] Slow response times --- .../authorization/impl/DeleteFeature.java | 6 +- .../converter/AInprogressItemConverter.java | 10 +- .../rest/model/AInprogressSubmissionRest.java | 29 +-- .../app/rest/model/WorkflowItemRest.java | 25 +- .../app/rest/model/WorkspaceItemRest.java | 15 ++ .../WorkflowItemCollectionLinkRepository.java | 60 +++++ .../WorkflowItemItemLinkRepository.java | 60 +++++ .../WorkflowItemSubmitterLinkRepository.java | 60 +++++ ...WorkspaceItemCollectionLinkRepository.java | 60 +++++ .../WorkspaceItemItemLinkRepository.java | 60 +++++ .../WorkspaceItemSubmitterLinkRepository.java | 60 +++++ .../WorkflowItemRestLinkRepositoryIT.java | 226 ++++++++++++++++++ .../WorkspaceItemRestLinkRepositoryIT.java | 222 +++++++++++++++++ 13 files changed, 854 insertions(+), 39 deletions(-) create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemCollectionLinkRepository.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemItemLinkRepository.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemSubmitterLinkRepository.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemCollectionLinkRepository.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemItemLinkRepository.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemSubmitterLinkRepository.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestLinkRepositoryIT.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestLinkRepositoryIT.java diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/DeleteFeature.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/DeleteFeature.java index 02ca816290d0..0f5378125d8f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/DeleteFeature.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/DeleteFeature.java @@ -65,11 +65,13 @@ public class DeleteFeature implements AuthorizationFeature { @Override public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException { if (object instanceof BaseObjectRest) { + DSpaceObject dSpaceObject = (DSpaceObject) utils.getDSpaceAPIObjectFromRest(context, object); + if (object.getType().equals(WorkspaceItemRest.NAME)) { - object = ((WorkspaceItemRest)object).getItem(); + WorkspaceItem workspaceItem = (WorkspaceItem) utils.getDSpaceAPIObjectFromRest(context, object); + dSpaceObject = workspaceItem.getItem(); } - DSpaceObject dSpaceObject = (DSpaceObject) utils.getDSpaceAPIObjectFromRest(context, object); DSpaceObject parentObject = getParentObject(context, dSpaceObject); switch (object.getType()) { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java index a80c8bd948b9..309809302de4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java @@ -70,11 +70,11 @@ protected void fillFromModel(T obj, R witem, Projection projection) { submitter = obj.getSubmitter(); witem.setId(obj.getID()); - witem.setCollection(collection != null ? converter.toRest(collection, projection) : null); - witem.setItem(converter.toRest(item, projection)); - if (submitter != null) { - witem.setSubmitter(converter.toRest(submitter, projection)); - } +// witem.setCollection(collection != null ? converter.toRest(collection, projection) : null); +// witem.setItem(converter.toRest(item, projection)); +// if (submitter != null) { +// witem.setSubmitter(converter.toRest(submitter, projection)); +// } // 1. retrieve the submission definition // 2. iterate over the submission section to allow to plugin additional diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AInprogressSubmissionRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AInprogressSubmissionRest.java index 903e2866c855..79cf007ba190 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AInprogressSubmissionRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AInprogressSubmissionRest.java @@ -22,16 +22,11 @@ */ public abstract class AInprogressSubmissionRest extends BaseObjectRest { + private Date lastModified = new Date(); private Map sections; @JsonIgnore - private CollectionRest collection; - @JsonIgnore - private ItemRest item; - @JsonIgnore private SubmissionDefinitionRest submissionDefinition; - @JsonIgnore - private EPersonRest submitter; public Date getLastModified() { return lastModified; @@ -41,14 +36,6 @@ public void setLastModified(Date lastModified) { this.lastModified = lastModified; } - public ItemRest getItem() { - return item; - } - - public void setItem(ItemRest item) { - this.item = item; - } - public SubmissionDefinitionRest getSubmissionDefinition() { return submissionDefinition; } @@ -57,14 +44,6 @@ public void setSubmissionDefinition(SubmissionDefinitionRest submissionDefinitio this.submissionDefinition = submissionDefinition; } - public EPersonRest getSubmitter() { - return submitter; - } - - public void setSubmitter(EPersonRest submitter) { - this.submitter = submitter; - } - public Map getSections() { if (sections == null) { sections = new HashMap(); @@ -76,12 +55,6 @@ public void setSections(Map sections) { this.sections = sections; } - public CollectionRest getCollection() { - return collection; - } - public void setCollection(CollectionRest collection) { - this.collection = collection; - } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java index 278d5de85d3f..65fa531c5e42 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java @@ -15,10 +15,22 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest( - name = WorkflowItemRest.STEP, - method = "getStep" - ) + @LinkRest( + name = WorkflowItemRest.STEP, + method = "getStep" + ), + @LinkRest( + name = WorkflowItemRest.SUBMITTER, + method = "getWorkflowItemSubmitter" + ), + @LinkRest( + name = WorkflowItemRest.ITEM, + method = "getWorkflowItemItem" + ), + @LinkRest( + name = WorkflowItemRest.COLLECTION, + method = "getWorkflowItemCollection" + ) }) public class WorkflowItemRest extends AInprogressSubmissionRest { public static final String NAME = "workflowitem"; @@ -27,6 +39,11 @@ public class WorkflowItemRest extends AInprogressSubmissionRest { public static final String STEP = "step"; + public static final String SUBMITTER = "submitter"; + public static final String ITEM = "item"; + public static final String COLLECTION = "collection"; + + @Override public String getCategory() { return CATEGORY; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java index f0ba0981dab4..e311cd259231 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java @@ -18,6 +18,18 @@ @LinkRest( name = WorkspaceItemRest.SUPERVISION_ORDERS, method = "getSupervisionOrders" + ), + @LinkRest( + name = WorkspaceItemRest.SUBMITTER, + method = "getWorkspaceItemSubmitter" + ), + @LinkRest( + name = WorkspaceItemRest.ITEM, + method = "getWorkspaceItemItem" + ), + @LinkRest( + name = WorkspaceItemRest.COLLECTION, + method = "getWorkspaceItemCollection" ) }) public class WorkspaceItemRest extends AInprogressSubmissionRest { @@ -26,6 +38,9 @@ public class WorkspaceItemRest extends AInprogressSubmissionRest { public static final String CATEGORY = RestAddressableModel.SUBMISSION; public static final String SUPERVISION_ORDERS = "supervisionOrders"; + public static final String SUBMITTER = "submitter"; + public static final String ITEM = "item"; + public static final String COLLECTION = "collection"; @Override public String getCategory() { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemCollectionLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemCollectionLinkRepository.java new file mode 100644 index 000000000000..fa92a69e77d6 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemCollectionLinkRepository.java @@ -0,0 +1,60 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.rest.repository; + +import java.sql.SQLException; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.rest.model.CollectionRest; +import org.dspace.app.rest.model.WorkflowItemRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.core.Context; +import org.dspace.workflow.WorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +/** + * Link repository for "collection" subresource of a workflow item. + */ +@Component(WorkflowItemRest.CATEGORY + "." + WorkflowItemRest.NAME + "." + WorkflowItemRest.COLLECTION) +public class WorkflowItemCollectionLinkRepository extends AbstractDSpaceRestRepository + implements LinkRestRepository { + + @Autowired + XmlWorkflowItemService wis; + + /** + * Retrieve the item for a workflow collection. + * + * @param request - The current request + * @param id - The workflow item ID for which to retrieve the collection + * @param optionalPageable - optional pageable object + * @param projection - the current projection + * @return the item for the workflow collection + */ + @PreAuthorize("hasPermission(#id, 'WORKFLOWITEM', 'READ')") + public CollectionRest getWorkflowItemCollection(@Nullable HttpServletRequest request, Integer id, + @Nullable Pageable optionalPageable, Projection projection) { + try { + Context context = obtainContext(); + WorkflowItem witem = wis.find(context, id); + if (witem == null) { + throw new ResourceNotFoundException("No such workflow item: " + id); + } + + return converter.toRest(witem.getCollection(), projection); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemItemLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemItemLinkRepository.java new file mode 100644 index 000000000000..40624799bff4 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemItemLinkRepository.java @@ -0,0 +1,60 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.rest.repository; + +import java.sql.SQLException; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.rest.model.ItemRest; +import org.dspace.app.rest.model.WorkflowItemRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.core.Context; +import org.dspace.workflow.WorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +/** + * Link repository for "item" subresource of a workflow item. + */ +@Component(WorkflowItemRest.CATEGORY + "." + WorkflowItemRest.NAME + "." + WorkflowItemRest.ITEM) +public class WorkflowItemItemLinkRepository extends AbstractDSpaceRestRepository + implements LinkRestRepository { + + @Autowired + XmlWorkflowItemService wis; + + /** + * Retrieve the item for a workflow item. + * + * @param request - The current request + * @param id - The workflow item ID for which to retrieve the item + * @param optionalPageable - optional pageable object + * @param projection - the current projection + * @return the item for the workflow item + */ + @PreAuthorize("hasPermission(#id, 'WORKFLOWITEM', 'READ')") + public ItemRest getWorkflowItemItem(@Nullable HttpServletRequest request, Integer id, + @Nullable Pageable optionalPageable, Projection projection) { + try { + Context context = obtainContext(); + WorkflowItem witem = wis.find(context, id); + if (witem == null) { + throw new ResourceNotFoundException("No such workflow item: " + id); + } + + return converter.toRest(witem.getItem(), projection); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemSubmitterLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemSubmitterLinkRepository.java new file mode 100644 index 000000000000..b4b0ec0adfff --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemSubmitterLinkRepository.java @@ -0,0 +1,60 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.rest.repository; + +import java.sql.SQLException; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.rest.model.EPersonRest; +import org.dspace.app.rest.model.WorkflowItemRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.core.Context; +import org.dspace.workflow.WorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +/** + * Link repository for "submitter" subresource of a workflow item. + */ +@Component(WorkflowItemRest.CATEGORY + "." + WorkflowItemRest.NAME + "." + WorkflowItemRest.SUBMITTER) +public class WorkflowItemSubmitterLinkRepository extends AbstractDSpaceRestRepository + implements LinkRestRepository { + + @Autowired + XmlWorkflowItemService wis; + + /** + * Retrieve the submitter for a workflow item. + * + * @param request - The current request + * @param id - The workflow item ID for which to retrieve the submitter + * @param optionalPageable - optional pageable object + * @param projection - the current projection + * @return the submitter for the workflow item + */ + @PreAuthorize("hasPermission(#id, 'WORKFLOWITEM', 'READ')") + public EPersonRest getWorkflowItemSubmitter(@Nullable HttpServletRequest request, Integer id, + @Nullable Pageable optionalPageable, Projection projection) { + try { + Context context = obtainContext(); + WorkflowItem witem = wis.find(context, id); + if (witem == null) { + throw new ResourceNotFoundException("No such workflow item: " + id); + } + + return converter.toRest(witem.getSubmitter(), projection); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemCollectionLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemCollectionLinkRepository.java new file mode 100644 index 000000000000..c8f9373b07c7 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemCollectionLinkRepository.java @@ -0,0 +1,60 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.rest.repository; + +import java.sql.SQLException; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.rest.model.CollectionRest; +import org.dspace.app.rest.model.WorkspaceItemRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.content.WorkspaceItem; +import org.dspace.content.service.WorkspaceItemService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +/** + * Link repository for "collection" subresource of a workspace item. + */ +@Component(WorkspaceItemRest.CATEGORY + "." + WorkspaceItemRest.NAME + "." + WorkspaceItemRest.COLLECTION) +public class WorkspaceItemCollectionLinkRepository extends AbstractDSpaceRestRepository + implements LinkRestRepository { + + @Autowired + WorkspaceItemService wis; + + /** + * Retrieve the collection for a workspace item. + * + * @param request - The current request + * @param id - The workspace item ID for which to retrieve the collection + * @param optionalPageable - optional pageable object + * @param projection - the current projection + * @return the collection for the workspace item + */ + @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'READ')") + public CollectionRest getWorkspaceItemCollection(@Nullable HttpServletRequest request, Integer id, + @Nullable Pageable optionalPageable, Projection projection) { + try { + Context context = obtainContext(); + WorkspaceItem witem = wis.find(context, id); + if (witem == null) { + throw new ResourceNotFoundException("No such workspace item: " + id); + } + + return converter.toRest(witem.getCollection(), projection); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemItemLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemItemLinkRepository.java new file mode 100644 index 000000000000..48052fe5371f --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemItemLinkRepository.java @@ -0,0 +1,60 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.rest.repository; + +import java.sql.SQLException; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.rest.model.ItemRest; +import org.dspace.app.rest.model.WorkspaceItemRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.content.WorkspaceItem; +import org.dspace.content.service.WorkspaceItemService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +/** + * Link repository for "item" subresource of a workspace item. + */ +@Component(WorkspaceItemRest.CATEGORY + "." + WorkspaceItemRest.NAME + "." + WorkspaceItemRest.ITEM) +public class WorkspaceItemItemLinkRepository extends AbstractDSpaceRestRepository + implements LinkRestRepository { + + @Autowired + WorkspaceItemService wis; + + /** + * Retrieve the item for a workspace item. + * + * @param request - The current request + * @param id - The workspace item ID for which to retrieve the item + * @param optionalPageable - optional pageable object + * @param projection - the current projection + * @return the item for the workspace item + */ + @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'READ')") + public ItemRest getWorkspaceItemItem(@Nullable HttpServletRequest request, Integer id, + @Nullable Pageable optionalPageable, Projection projection) { + try { + Context context = obtainContext(); + WorkspaceItem witem = wis.find(context, id); + if (witem == null) { + throw new ResourceNotFoundException("No such workspace item: " + id); + } + + return converter.toRest(witem.getItem(), projection); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemSubmitterLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemSubmitterLinkRepository.java new file mode 100644 index 000000000000..a98de6a0b3ac --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkspaceItemSubmitterLinkRepository.java @@ -0,0 +1,60 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.rest.repository; + +import java.sql.SQLException; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.rest.model.EPersonRest; +import org.dspace.app.rest.model.WorkspaceItemRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.content.WorkspaceItem; +import org.dspace.content.service.WorkspaceItemService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +/** + * Link repository for "submitter" subresource of a workspace item. + */ +@Component(WorkspaceItemRest.CATEGORY + "." + WorkspaceItemRest.NAME + "." + WorkspaceItemRest.SUBMITTER) +public class WorkspaceItemSubmitterLinkRepository extends AbstractDSpaceRestRepository + implements LinkRestRepository { + + @Autowired + WorkspaceItemService wis; + + /** + * Retrieve the submitter for a workspace item. + * + * @param request - The current request + * @param id - The workspace item ID for which to retrieve the submitter + * @param optionalPageable - optional pageable object + * @param projection - the current projection + * @return the submitter for the workspace item + */ + @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'READ')") + public EPersonRest getWorkspaceItemSubmitter(@Nullable HttpServletRequest request, Integer id, + @Nullable Pageable optionalPageable, Projection projection) { + try { + Context context = obtainContext(); + WorkspaceItem witem = wis.find(context, id); + if (witem == null) { + throw new ResourceNotFoundException("No such workspace item: " + id); + } + + return converter.toRest(witem.getSubmitter(), projection); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestLinkRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestLinkRepositoryIT.java new file mode 100644 index 000000000000..7228a7ba0b9d --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestLinkRepositoryIT.java @@ -0,0 +1,226 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.rest; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.jayway.jsonpath.matchers.JsonPathMatchers; +import org.dspace.app.rest.matcher.CollectionMatcher; +import org.dspace.app.rest.matcher.EPersonMatcher; +import org.dspace.app.rest.matcher.ItemMatcher; +import org.dspace.app.rest.matcher.WorkflowItemMatcher; +import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.builder.CollectionBuilder; +import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.EPersonBuilder; +import org.dspace.builder.WorkflowItemBuilder; +import org.dspace.content.Collection; +import org.dspace.content.Community; +import org.dspace.eperson.EPerson; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.hamcrest.Matchers; +import org.junit.Test; + +/** + * Test suite for the WorkflowItem Link repositories + */ +public class WorkflowItemRestLinkRepositoryIT extends AbstractControllerIntegrationTest { + + @Test + /** + * The workflowitem resource endpoint must have an embeddable submitter + * + * @throws Exception + */ + public void findOneEmbedSubmitterTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@dspace.org") + .withNameInMetadata("Sub", "Mitter") + .build(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup("reviewer", admin) + .build(); + + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + .withSubmitter(submitter) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry") + .build(); + + context.restoreAuthSystemState(); + + String authToken = getAuthToken(admin.getEmail(), password); + + getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID())).andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workflow Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$", JsonPathMatchers.hasNoJsonPath("$._embedded.submitter"))); + + getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID()).param("embed", "submitter")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workflow Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$._embedded.submitter", Matchers.is( + EPersonMatcher.matchEPersonEntry(submitter)))); + + getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID() + "/submitter")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", EPersonMatcher.matchEPersonEntry(submitter))); + + } + + @Test + /** + * The workflowitem resource endpoint must have an embeddable collection + * + * @throws Exception + */ + public void findOneEmbedCollectionTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@dspace.org") + .withNameInMetadata("Sub", "Mitter") + .build(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup("reviewer", admin) + .build(); + + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + .withSubmitter(submitter) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry") + .build(); + + context.restoreAuthSystemState(); + + String authToken = getAuthToken(admin.getEmail(), password); + + getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID())).andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workflow Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$", JsonPathMatchers.hasNoJsonPath("$._embedded.collection"))); + + getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID()).param("embed", "collection")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workflow Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$._embedded.collection", Matchers.is( + CollectionMatcher.matchCollection(col1)))); + + getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID() + "/collection")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", CollectionMatcher.matchCollection(col1))); + + } + + @Test + /** + * The workflowitem resource endpoint must have an embeddable item + * + * @throws Exception + */ + public void findOneEmbedItemTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@dspace.org") + .withNameInMetadata("Sub", "Mitter") + .build(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup("reviewer", admin) + .build(); + + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + .withSubmitter(submitter) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry") + .build(); + + context.restoreAuthSystemState(); + + String authToken = getAuthToken(admin.getEmail(), password); + + getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID())).andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workflow Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$", JsonPathMatchers.hasNoJsonPath("$._embedded.item"))); + + getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID()).param("embed", "item")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workflow Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$._embedded.item", Matchers.is( + ItemMatcher.matchItemProperties(witem.getItem())))); + + getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID() + "/item")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(witem.getItem()))); + + } + + +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestLinkRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestLinkRepositoryIT.java new file mode 100644 index 000000000000..709480e8cd52 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestLinkRepositoryIT.java @@ -0,0 +1,222 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.rest; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.jayway.jsonpath.matchers.JsonPathMatchers; +import org.dspace.app.rest.matcher.CollectionMatcher; +import org.dspace.app.rest.matcher.EPersonMatcher; +import org.dspace.app.rest.matcher.ItemMatcher; +import org.dspace.app.rest.matcher.WorkspaceItemMatcher; +import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.builder.CollectionBuilder; +import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.EPersonBuilder; +import org.dspace.builder.WorkspaceItemBuilder; +import org.dspace.content.Collection; +import org.dspace.content.Community; +import org.dspace.content.WorkspaceItem; +import org.dspace.eperson.EPerson; +import org.hamcrest.Matchers; +import org.junit.Test; + +/** + * Test suite for the WorkspaceItem Link repositories + */ +public class WorkspaceItemRestLinkRepositoryIT extends AbstractControllerIntegrationTest { + + + @Test + /** + * The workspaceitem resource endpoint must have an embeddable submitter + * + * @throws Exception + */ + public void findOneEmbedSubmitterTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@dspace.org") + .withNameInMetadata("Sub", "Mitter") + .build(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + + //2. a workspace item + WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1) + .withSubmitter(submitter) + .withTitle("Workspace Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry") + .build(); + + context.restoreAuthSystemState(); + + String authToken = getAuthToken(admin.getEmail(), password); + + getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID())).andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkspaceItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workspace Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$", JsonPathMatchers.hasNoJsonPath("$._embedded.submitter"))); + + getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID()).param("embed", "submitter")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkspaceItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workspace Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$._embedded.submitter", Matchers.is( + EPersonMatcher.matchEPersonEntry(submitter)))); + + getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID() + "/submitter")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", EPersonMatcher.matchEPersonEntry(submitter))); + + } + + @Test + /** + * The workspaceitem resource endpoint must have an embeddable collection + * + * @throws Exception + */ + public void findOneEmbedCollectionTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@dspace.org") + .withNameInMetadata("Sub", "Mitter") + .build(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + + //2. a workspace item + WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1) + .withSubmitter(submitter) + .withTitle("Workspace Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry") + .build(); + + context.restoreAuthSystemState(); + + String authToken = getAuthToken(admin.getEmail(), password); + + getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID())).andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkspaceItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workspace Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$", JsonPathMatchers.hasNoJsonPath("$._embedded.collection"))); + + getClient(authToken).perform( + get("/api/submission/workspaceitems/" + witem.getID()).param("embed", "collection")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkspaceItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workspace Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$._embedded.collection", Matchers.is( + CollectionMatcher.matchCollection(col1)))); + + getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID() + "/collection")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", CollectionMatcher.matchCollection(col1))); + + } + + @Test + /** + * The workspaceitem resource endpoint must have an embeddable item + * + * @throws Exception + */ + public void findOneEmbedItemTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@dspace.org") + .withNameInMetadata("Sub", "Mitter") + .build(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + + //2. a workspace item + WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1) + .withSubmitter(submitter) + .withTitle("Workspace Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry") + .build(); + + context.restoreAuthSystemState(); + + String authToken = getAuthToken(admin.getEmail(), password); + + getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID())).andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkspaceItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workspace Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$", JsonPathMatchers.hasNoJsonPath("$._embedded.item"))); + + getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID()).param("embed", "item")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.is( + WorkspaceItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Workspace Item 1", + "2017-10-17", + "ExtraEntry")))) + .andExpect(jsonPath("$._embedded.item", Matchers.is( + ItemMatcher.matchItemProperties(witem.getItem())))); + + getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID() + "/item")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(witem.getItem()))); + + } + + +}