diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java
index 4ab37507f0..40799556c1 100644
--- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java
+++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java
@@ -92,14 +92,28 @@ public class RestAPIFactory
return getRmRestWrapper().withSearchAPI();
}
- public Node getNodeAPI(RepoTestModel model) throws Exception
+ public Node getNodeAPI(RepoTestModel model) throws RuntimeException
{
- return getCoreAPI(null).usingNode(model);
+ try
+ {
+ return getCoreAPI(null).usingNode(model);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to load nodeAPI.", e);
+ }
}
- public Node getNodeAPI(UserModel userModel, RepoTestModel model) throws Exception
+ public Node getNodeAPI(UserModel userModel, RepoTestModel model) throws RuntimeException
{
- return getCoreAPI(userModel).usingNode(model);
+ try
+ {
+ return getCoreAPI(userModel).usingNode(model);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to load nodeAPI.", e);
+ }
}
public RMSiteAPI getRMSiteAPI()
diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/FilePlanAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/FilePlanAPI.java
index 6cbe13c13c..8309847897 100644
--- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/FilePlanAPI.java
+++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/FilePlanAPI.java
@@ -135,7 +135,7 @@ public class FilePlanAPI extends RMModelRequest
/**
* see {@link #createRootRecordCategory(RecordCategory, String, String)}
*/
- public RecordCategory createRootRecordCategory(RecordCategory recordCategoryModel, String filePlanId) throws Exception
+ public RecordCategory createRootRecordCategory(RecordCategory recordCategoryModel, String filePlanId)
{
mandatoryObject("recordCategoryModel", recordCategoryModel);
mandatoryString("filePlanId", filePlanId);
@@ -150,7 +150,7 @@ public class FilePlanAPI extends RMModelRequest
* @param filePlanId The identifier of a file plan
* @param parameters The URL parameters to add
* @return The created {@link RecordCategory}
- * @throws Exception for the following cases:
+ * @throws RuntimeException for the following cases:
*
* - {@code filePlanId} is not a valid format or {@code filePlanId} is invalid
* - authentication fails
@@ -160,7 +160,7 @@ public class FilePlanAPI extends RMModelRequest
* - model integrity exception, including node name with invalid characters
*
*/
- public RecordCategory createRootRecordCategory(RecordCategory recordCategoryModel, String filePlanId, String parameters) throws Exception
+ public RecordCategory createRootRecordCategory(RecordCategory recordCategoryModel, String filePlanId, String parameters)
{
mandatoryObject("recordCategoryModel", recordCategoryModel);
mandatoryString("filePlanId", filePlanId);
diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RecordCategoryAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RecordCategoryAPI.java
index 9dbe4d8d67..7e28bdcf04 100644
--- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RecordCategoryAPI.java
+++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RecordCategoryAPI.java
@@ -201,7 +201,7 @@ public class RecordCategoryAPI extends RMModelRequest
/**
* see {@link #createRecordCategoryChild(RecordCategoryChild, String, String)}
*/
- public RecordCategoryChild createRecordCategoryChild(RecordCategoryChild recordCategoryChildModel, String recordCategoryId) throws Exception
+ public RecordCategoryChild createRecordCategoryChild(RecordCategoryChild recordCategoryChildModel, String recordCategoryId)
{
mandatoryObject("recordCategoryChildModel", recordCategoryChildModel);
mandatoryString("recordCategoryId", recordCategoryId);
@@ -216,7 +216,7 @@ public class RecordCategoryAPI extends RMModelRequest
* @param recordCategoryId The identifier of a record category
* @param parameters The URL parameters to add
* @return The created {@link RecordCategoryChild}
- * @throws Exception for the following cases:
+ * @throws RuntimeException for the following cases:
*
* - {@code recordCategoryId} is not a valid format or {@code recordCategoryChildModel} is invalid
* - authentication fails
@@ -226,7 +226,7 @@ public class RecordCategoryAPI extends RMModelRequest
* - model integrity exception, including node name with invalid characters
*
*/
- public RecordCategoryChild createRecordCategoryChild(RecordCategoryChild recordCategoryChildModel, String recordCategoryId, String parameters) throws Exception
+ public RecordCategoryChild createRecordCategoryChild(RecordCategoryChild recordCategoryChildModel, String recordCategoryId, String parameters)
{
mandatoryObject("filePlanComponentProperties", recordCategoryChildModel);
mandatoryString("recordCategoryId", recordCategoryId);
diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RecordFolderAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RecordFolderAPI.java
index a85c6c64d9..4d83b13c17 100644
--- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RecordFolderAPI.java
+++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RecordFolderAPI.java
@@ -40,6 +40,7 @@ import static org.springframework.http.HttpMethod.PUT;
import static org.testng.Assert.fail;
import java.io.File;
+import java.io.IOException;
import java.util.Iterator;
import com.fasterxml.jackson.databind.JsonNode;
@@ -212,7 +213,7 @@ public class RecordFolderAPI extends RMModelRequest
/**
* see {@link #createRecord(Record, String, String)}
*/
- public Record createRecord(Record recordModel, String recordFolderId) throws Exception
+ public Record createRecord(Record recordModel, String recordFolderId)
{
mandatoryObject("recordModel", recordModel);
mandatoryString("recordFolderId", recordFolderId);
@@ -227,9 +228,9 @@ public class RecordFolderAPI extends RMModelRequest
* @param recordContent {@link File} pointing to the content of the electronic record to be created
* @param recordFolderId The identifier of a record folder
* @return newly created {@link Record}
- * @throws Exception for invalid recordModel JSON strings
+ * @throws RuntimeException for invalid recordModel JSON strings
*/
- public Record createRecord(Record recordModel, String recordFolderId, File recordContent) throws Exception
+ public Record createRecord(Record recordModel, String recordFolderId, File recordContent) throws RuntimeException
{
mandatoryString("recordFolderId", recordFolderId);
mandatoryObject("recordContent", recordContent);
@@ -245,7 +246,15 @@ public class RecordFolderAPI extends RMModelRequest
* to the request.
*/
RequestSpecBuilder builder = getRmRestWrapper().configureRequestSpec();
- JsonNode root = new ObjectMapper().readTree(toJson(recordModel, Record.class, FilePlanComponentMixIn.class));
+ JsonNode root;
+ try
+ {
+ root = new ObjectMapper().readTree(toJson(recordModel, Record.class, FilePlanComponentMixIn.class));
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Failed to convert model to JSON.", e);
+ }
// add request fields
Iterator fieldNames = root.fieldNames();
while (fieldNames.hasNext())
@@ -266,7 +275,7 @@ public class RecordFolderAPI extends RMModelRequest
* @param recordFolderId The identifier of a record folder
* @param parameters The URL parameters to add
* @return The created {@link Record}
- * @throws Exception for the following cases:
+ * @throws RuntimeException for the following cases:
*
* - {@code recordFolderId is not a valid format or {@code recordModel} is invalid
* - authentication fails
@@ -275,7 +284,7 @@ public class RecordFolderAPI extends RMModelRequest
* - model integrity exception, including node name with invalid characters
*
*/
- public Record createRecord(Record recordModel, String recordFolderId, String parameters) throws Exception
+ public Record createRecord(Record recordModel, String recordFolderId, String parameters)
{
mandatoryObject("recordModel", recordModel);
mandatoryString("recordFolderId", recordFolderId);
diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java
index bbf001ae3e..7597566668 100644
--- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java
+++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java
@@ -217,9 +217,9 @@ public class BaseRMRestTest extends RestTest
* @param userModel The user under whose privileges this structure is going to be created
* @param categoryName The name of the category
* @return The created category
- * @throws Exception on unsuccessful component creation
+ * @throws RuntimeException on unsuccessful component creation
*/
- public RecordCategory createRootCategory(UserModel userModel, String categoryName) throws Exception
+ public RecordCategory createRootCategory(UserModel userModel, String categoryName)
{
return createRootCategory(userModel, categoryName, RECORD_CATEGORY_TITLE);
}
@@ -244,9 +244,9 @@ public class BaseRMRestTest extends RestTest
* @param categoryName The name of the category
* @param categoryTitle The title of the category
* @return The created category
- * @throws Exception on unsuccessful component creation
+ * @throws RuntimeException on unsuccessful component creation
*/
- public RecordCategory createRootCategory(UserModel userModel, String categoryName, String categoryTitle) throws Exception
+ public RecordCategory createRootCategory(UserModel userModel, String categoryName, String categoryTitle)
{
RecordCategory recordCategoryModel = createRecordCategoryModel(categoryName, categoryTitle);
return getRestAPIFactory().getFilePlansAPI(userModel).createRootRecordCategory(recordCategoryModel, FILE_PLAN_ALIAS);
@@ -315,9 +315,9 @@ public class BaseRMRestTest extends RestTest
* @param recordCategoryId The id of the record category
* @param name The name of the folder
* @return The created folder
- * @throws Exception on unsuccessful component creation
+ * @throws RuntimeException on unsuccessful component creation
*/
- public RecordCategoryChild createFolder(UserModel user, String recordCategoryId, String name) throws Exception
+ public RecordCategoryChild createFolder(UserModel user, String recordCategoryId, String name)
{
RecordCategoryChild recordFolderModel = createRecordCategoryChildModel(name, RECORD_FOLDER_TYPE);
return getRestAPIFactory().getRecordCategoryAPI(user).createRecordCategoryChild(recordFolderModel, recordCategoryId);
@@ -455,13 +455,13 @@ public class BaseRMRestTest extends RestTest
}
/**
- * Helper method to create a randomly-named / structure in file plan
+ * Helper method to create a randomly-named [category]/[folder] structure in file plan
*
* @param user The user under whose privileges this structure is going to be created
* @return {@link RecordCategoryChild} which represents the record folder
- * @throws Exception on failed creation
+ * @throws RuntimeException on failed creation
*/
- public RecordCategoryChild createCategoryFolderInFilePlan(UserModel user) throws Exception
+ public RecordCategoryChild createCategoryFolderInFilePlan(UserModel user)
{
// create root category
RecordCategory recordCategory = createRootCategory(user, "Category " + getRandomAlphanumeric());
@@ -471,12 +471,12 @@ public class BaseRMRestTest extends RestTest
}
/**
- * Helper method to create a randomly-named / structure in file plan as the admin user
+ * Helper method to create a randomly-named [category]/[folder] structure in file plan as the admin user
*
* @return {@link RecordCategoryChild} which represents the record folder
- * @throws Exception on failed creation
+ * @throws RuntimeException on failed creation
*/
- public RecordCategoryChild createCategoryFolderInFilePlan() throws Exception
+ public RecordCategoryChild createCategoryFolderInFilePlan()
{
return createCategoryFolderInFilePlan(getAdminUser());
}
diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java
index 7cfa70a35c..a906c5217a 100644
--- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java
+++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java
@@ -46,6 +46,10 @@ import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.NO_CONTENT;
import static org.springframework.http.HttpStatus.OK;
+import org.alfresco.rest.core.RestResponse;
+import org.alfresco.rest.model.RestNodeBodyMoveCopyModel;
+import org.alfresco.rest.model.RestNodeModel;
+import org.alfresco.rest.requests.Node;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
@@ -55,8 +59,10 @@ import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.RepoTestModel;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.log.Step;
import org.testng.annotations.Test;
/**
@@ -245,6 +251,40 @@ public class DeleteRecordTests extends BaseRMRestTest
assertStatusCode(FORBIDDEN);
}
+ /**
+ *
+ * Given a record
+ * And a copy of that record
+ * When I delete the copy
+ * Then it is still possible to view the content of the original record
+ *
+ */
+ @Test(description = "Deleting copy of record doesn't delete original content")
+ @AlfrescoTest(jira="MNT-18806")
+ public void deleteCopyOfRecord()
+ {
+ Step.STEP("Create two record categories and folders.");
+ RecordCategoryChild recordFolderA = createCategoryFolderInFilePlan();
+ RecordCategoryChild recordFolderB = createCategoryFolderInFilePlan();
+
+ Step.STEP("Create a record in folder A and copy it into folder B.");
+ String recordId = getRestAPIFactory().getRecordFolderAPI()
+ .createRecord(createElectronicRecordModel(), recordFolderA.getId(), getFile(IMAGE_FILE)).getId();
+ String copyId = copyRecord(recordId, recordFolderB.getId()).getId();
+ assertStatusCode(CREATED);
+
+ Step.STEP("Check that it's possible to load the original content.");
+ getNodeContent(recordId);
+ assertStatusCode(OK);
+
+ Step.STEP("Delete the copy.");
+ deleteAndVerify(copyId);
+
+ Step.STEP("Check that the original record node and content still exist.");
+ checkNodeExists(recordId);
+ getNodeContent(recordId);
+ }
+
/**
* Utility method to delete a record and verify successful deletion
*
@@ -263,4 +303,73 @@ public class DeleteRecordTests extends BaseRMRestTest
assertStatusCode(NOT_FOUND);
}
+ /**
+ * Copy a record to a record folder.
+ *
+ * @param recordId The id of the record to copy.
+ * @param destinationFolder The id of the record folder to copy it to.
+ * @return The model returned by the copy API.
+ */
+ private RestNodeModel copyRecord(String recordId, String destinationFolder)
+ {
+ Node node = getNode(recordId);
+ RestNodeBodyMoveCopyModel copyBody = new RestNodeBodyMoveCopyModel();
+ copyBody.setTargetParentId(destinationFolder);
+ try
+ {
+ return node.copy(copyBody);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Problem copying record.", e);
+ }
+ }
+
+ /**
+ * Get the content from a node.
+ *
+ * @param nodeId
+ * @return The response containing the node content.
+ */
+ private RestResponse getNodeContent(String nodeId)
+ {
+ try
+ {
+ return getNode(nodeId).getNodeContent();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to load content for node.", e);
+ }
+ }
+
+ /**
+ * Check that the given node exists.
+ *
+ * @param nodeId The node to check.
+ */
+ private void checkNodeExists(String nodeId)
+ {
+ try
+ {
+ getNode(nodeId).getNode();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Node does not exist.", e);
+ }
+ }
+
+ /**
+ * Get the node from a record id.
+ *
+ * @param recordId The record to get.
+ * @return The node object.
+ */
+ private Node getNode(String recordId)
+ {
+ RepoTestModel repoTestModel = new RepoTestModel() {};
+ repoTestModel.setNodeRef(recordId);
+ return getRestAPIFactory().getNodeAPI(repoTestModel);
+ }
}
diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml
index ddd303c982..4cb71d28e0 100644
--- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml
+++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml
@@ -143,6 +143,7 @@
+
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java
index c2e67a2460..16c8423228 100644
--- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordAspect.java
@@ -51,9 +51,13 @@ import org.alfresco.repo.policy.annotation.BehaviourBean;
import org.alfresco.repo.policy.annotation.BehaviourKind;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
+import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.quickshare.QuickShareService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
+import org.alfresco.service.cmr.repository.ContentReader;
+import org.alfresco.service.cmr.repository.ContentService;
+import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.ScriptService;
import org.alfresco.service.namespace.QName;
@@ -94,6 +98,9 @@ public class RecordAspect extends AbstractDisposableItem
/** quickShare service */
private QuickShareService quickShareService;
+ /** File folder service */
+ private FileFolderService fileFolderService;
+
/** I18N */
private static final String MSG_CANNOT_UPDATE_RECORD_CONTENT = "rm.service.update-record-content";
@@ -130,6 +137,15 @@ public class RecordAspect extends AbstractDisposableItem
this.quickShareService = quickShareService;
}
+ /**
+ *
+ * @param fileFolderService file folder service
+ */
+ public void setFileFolderService(FileFolderService fileFolderService)
+ {
+ this.fileFolderService = fileFolderService;
+ }
+
/**
* Behaviour to ensure renditions have the appropriate extended security.
*
@@ -358,6 +374,14 @@ public class RecordAspect extends AbstractDisposableItem
{
// then remove any extended security from the newly copied record
extendedSecurityService.remove(targetNodeRef);
+
+ //create a new content URL for the copy
+ ContentReader reader = fileFolderService.getReader(targetNodeRef);
+ if (reader != null)
+ {
+ ContentWriter writer = fileFolderService.getWriter(targetNodeRef);
+ writer.putContent(reader);
+ }
}
}