From 35b4ad5dbe6736dbf022d4d4e369385ac4e8e4a4 Mon Sep 17 00:00:00 2001 From: SathishK-T <166369440+SathishK-T@users.noreply.github.com> Date: Wed, 3 Jul 2024 18:32:42 +0530 Subject: [PATCH] [APPS-2905][APPS-2906][APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's (#2732) * [APPS-2907][APPS-2909] Validation Changes in Retention Schedule V1 API * [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's * [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's * [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's * [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's * [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's * [APPS-2907][APPS-2909] Defect fixes in Retention Schedule V1 API's --------- Co-authored-by: Sathish Kumar --- .../RetentionScheduleActionDefinition.java | 2 +- .../RetentionScheduleStepTests.java | 47 +++++++++++----- .../rest/api/impl/ApiNodesModelFactory.java | 37 +++++++++---- .../RetentionScheduleActionDefinition.java | 4 +- .../rm/rest/api/model/RetentionSteps.java | 3 +- .../RetentionScheduleActionRelation.java | 55 ++++++++++++++++--- .../RetentionScheduleRelation.java | 18 ++++++ .../main/webapp/definitions/gs-core-api.yaml | 37 +++++++------ 8 files changed, 151 insertions(+), 52 deletions(-) diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleActionDefinition.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleActionDefinition.java index 0c79e9f543..e743e904de 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleActionDefinition.java +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleActionDefinition.java @@ -40,7 +40,7 @@ public class RetentionScheduleActionDefinition private int periodAmount; private String period; private String periodProperty; - private boolean combineDispositionStepConditions; + private boolean combineRetentionStepConditions; private List events; private boolean eligibleOnFirstCompleteEvent; private String description; diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleStepTests.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleStepTests.java index 60359e6f74..060c22fae6 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleStepTests.java +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleStepTests.java @@ -79,7 +79,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest private static final String RETAIN_STEP = "retain"; private static final String INVALID_PERIOD = "random"; private static final String CUTOFF_STEP = "cutoff"; - private static final String DESTROY_STEP = "destroy"; + private static final String DESTROY_STEP = "destroyContent"; private static final String INVALID_PASSWORD = "wrongPassword"; @Autowired @@ -107,7 +107,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest retentionScheduleActionDefinition.setPeriodAmount(PERIOD_AMOUNT); retentionScheduleActionDefinition.setPeriodProperty(PERIOD_PROPERTY); retentionScheduleActionDefinition.setPeriod(PERIOD); - retentionScheduleActionDefinition.setCombineDispositionStepConditions(false); + retentionScheduleActionDefinition.setCombineRetentionStepConditions(false); retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(true); retentionScheduleActionDefinition.setEvents(EVENTS); } @@ -118,6 +118,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition(); //Creating the first action "transfer" should give 422 actionDefinition.setName(TRANSFER_STEP); + actionDefinition.setLocation("location"); //Create retention schedule action definition getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,createdRetentionSchedule.getId()); // Verify the status code @@ -151,6 +152,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition(); actionDefinition1.setName(TRANSFER_STEP); + actionDefinition1.setLocation("location"); getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1,retentionSchedule.getId()); assertStatusCode(CREATED); @@ -190,6 +192,20 @@ public class RetentionScheduleStepTests extends BaseRMRestTest } @Test(priority = 5) + public void combineRetentionStepConditionsNotValidForNonAccessionStep() + { + RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY)); + recordCategories.add(recordCategory.getId()); + RetentionSchedule retentionSchedule = createRetentionSchedule(recordCategory); + RetentionScheduleActionDefinition actionDefinition = getRetentionScheduleActionDefinition(); + actionDefinition.setName(RETAIN_STEP); + actionDefinition.setCombineRetentionStepConditions(true); + getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition,retentionSchedule.getId()); + + assertStatusCode(BAD_REQUEST); + } + + @Test(priority = 6) public void createRetentionScheduleWithSameStep() { RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY)); @@ -209,7 +225,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest assertStatusCode(CONFLICT); } - @Test(priority = 6) + @Test(priority = 7) public void createRetentionScheduleWithMultipleTransferStep() { RecordCategory recordCategory = createRootCategory(getRandomName(RECORD_CATEGORY)); @@ -223,16 +239,19 @@ public class RetentionScheduleStepTests extends BaseRMRestTest RetentionScheduleActionDefinition actionDefinition1 = getRetentionScheduleActionDefinition(); actionDefinition1.setName(TRANSFER_STEP); + actionDefinition1.setLocation("location"); + getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition1, retentionSchedule.getId()); RetentionScheduleActionDefinition actionDefinition2 = getRetentionScheduleActionDefinition(); actionDefinition2.setName(TRANSFER_STEP); + actionDefinition2.setLocation("location"); getRestAPIFactory().getRetentionScheduleAPI().createRetentionScheduleStep(actionDefinition2, retentionSchedule.getId()); // Verify the status code assertStatusCode(CREATED); } - @Test(priority = 7) + @Test(priority = 8) public void createRetentionScheduleStepFor201() { //Create retention schedule action definition @@ -243,11 +262,11 @@ public class RetentionScheduleStepTests extends BaseRMRestTest assertEquals(createdRetentionActionDefinition.getName(), retentionScheduleActionDefinition.getName()); assertEquals(createdRetentionActionDefinition.getDescription(), retentionScheduleActionDefinition.getDescription()); assertEquals(createdRetentionActionDefinition.getPeriodAmount(), retentionScheduleActionDefinition.getPeriodAmount()); - assertEquals(createdRetentionActionDefinition.isCombineDispositionStepConditions(), retentionScheduleActionDefinition.isCombineDispositionStepConditions()); + assertEquals(createdRetentionActionDefinition.isCombineRetentionStepConditions(), retentionScheduleActionDefinition.isCombineRetentionStepConditions()); assertEquals(createdRetentionActionDefinition.isEligibleOnFirstCompleteEvent(), retentionScheduleActionDefinition.isEligibleOnFirstCompleteEvent()); } - @Test(priority = 8) + @Test(priority = 9) public void createRetentionScheduleStepFor401() { //Create retention schedule action definition @@ -256,7 +275,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest assertStatusCode(UNAUTHORIZED); } - @Test(priority = 9) + @Test(priority = 10) public void createRetentionScheduleStepFor403() { //Create retention schedule action definition @@ -265,7 +284,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest assertStatusCode(FORBIDDEN); } - @Test(priority = 10) + @Test(priority = 11) public void retentionScheduleStepFor400() { getRestAPIFactory().getRetentionScheduleAPI().getRetentionScheduleStep(recordCategory.getId()); @@ -273,7 +292,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest assertStatusCode(BAD_REQUEST); } - @Test(priority = 11) + @Test(priority = 12) public void createRetentionScheduleStepFor404() { //Create retention schedule action definition @@ -282,7 +301,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest assertStatusCode(NOT_FOUND); } - @Test(priority = 12) + @Test(priority = 13) public void retentionScheduleStepFor403() { // Get retention schedule steps with user having no rights @@ -291,7 +310,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest assertStatusCode(FORBIDDEN); } - @Test(priority = 13) + @Test(priority = 14) public void retentionScheduleStepFor401() { getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), INVALID_PASSWORD)).getRetentionScheduleStep(createdRetentionSchedule.getId()); @@ -299,7 +318,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest assertStatusCode(UNAUTHORIZED); } - @Test(priority = 14) + @Test(priority = 15) public void retentionScheduleStepWith200() { RetentionScheduleStepCollection receiveRetentionStepCollection = getRestAPIFactory().getRetentionScheduleAPI().getRetentionScheduleStep(createdRetentionSchedule.getId()); @@ -315,7 +334,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest assertEquals(createdRetentionActionDefinition.getDescription(), retentionActionDef.getDescription()); assertEquals(createdRetentionActionDefinition.getPeriod(), retentionActionDef.getPeriod()); assertEquals(createdRetentionActionDefinition.getPeriodAmount(), retentionActionDef.getPeriodAmount()); - assertEquals(createdRetentionActionDefinition.isCombineDispositionStepConditions(), retentionActionDef.isCombineDispositionStepConditions()); + assertEquals(createdRetentionActionDefinition.isCombineRetentionStepConditions(), retentionActionDef.isCombineRetentionStepConditions()); assertEquals(createdRetentionActionDefinition.isEligibleOnFirstCompleteEvent(), retentionActionDef.isEligibleOnFirstCompleteEvent()); }); } @@ -341,7 +360,7 @@ public class RetentionScheduleStepTests extends BaseRMRestTest actionDefinition.setPeriodAmount(PERIOD_AMOUNT); actionDefinition.setPeriodProperty(PERIOD_PROPERTY); actionDefinition.setPeriod(PERIOD); - actionDefinition.setCombineDispositionStepConditions(false); + actionDefinition.setCombineRetentionStepConditions(false); actionDefinition.setEligibleOnFirstCompleteEvent(true); actionDefinition.setEvents(EVENTS); return actionDefinition; diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java index b392993023..9260cde66b 100644 --- a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java @@ -939,7 +939,7 @@ public class ApiNodesModelFactory { RetentionSchedule retentionSchedule = new RetentionSchedule(); retentionSchedule.setId(dispositionSchedule.getNodeRef().getId()); - if(dispositionSchedule.getNodeRef() != null) { + if (dispositionSchedule.getNodeRef() != null) { NodeRef parent = this.nodeService.getPrimaryParent(dispositionSchedule.getNodeRef()).getParentRef(); retentionSchedule.setParentId(parent.getId()); } @@ -984,7 +984,7 @@ public class ApiNodesModelFactory retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(dispositionActionDefinition.eligibleOnFirstCompleteEvent()); if (nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS) != null) { - retentionScheduleActionDefinition.setCombineDispositionStepConditions((Boolean) nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS)); + retentionScheduleActionDefinition.setCombineRetentionStepConditions((Boolean) nodeService.getProperty(dispositionActionDefinition.getNodeRef(), RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS)); } retentionScheduleActionDefinition.setLocation(dispositionActionDefinition.getLocation()); if (dispositionActionDefinition.getGhostOnDestroy() != null) @@ -1001,7 +1001,7 @@ public class ApiNodesModelFactory */ private void mapPeriodProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition) { - if(dispositionActionDefinition.getPeriodProperty() != null) + if (dispositionActionDefinition.getPeriodProperty() != null) { retentionScheduleActionDefinition.setPeriodProperty(dispositionActionDefinition.getPeriodProperty().toPrefixString(namespaceService)); } @@ -1078,10 +1078,20 @@ public class ApiNodesModelFactory public Map createRetentionActionDefinitionParams(RetentionScheduleActionDefinition nodeInfo) { Map actionDefinitionParams= new HashMap<>(); - actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, nodeInfo.getName()); + + String retentionActionName = nodeInfo.getName(); + + if (nodeInfo.getName().equals(RetentionSteps.DESTROY_NODE.stepName) || + nodeInfo.getName().equals(RetentionSteps.DESTROY_CONTENT.stepName)) + { + retentionActionName = "destroy"; + } + + actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_NAME, retentionActionName); actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_DESCRIPTION, nodeInfo.getDescription()); StringBuilder retentionPeriod = new StringBuilder(nodeInfo.getPeriod()).append("|"); - if(isPeriodAmountApplicable(nodeInfo.getPeriod())) + + if (isPeriodAmountApplicable(nodeInfo.getPeriod())) { retentionPeriod.append(nodeInfo.getPeriodAmount()); } @@ -1090,17 +1100,22 @@ public class ApiNodesModelFactory actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_PERIOD_PROPERTY, periodProperty); actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_EVENT_COMBINATION, nodeInfo.isEligibleOnFirstCompleteEvent()); - actionDefinitionParams.put(RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS, - nodeInfo.isCombineDispositionStepConditions()); - actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_LOCATION, - nodeInfo.getLocation()); + boolean combineConditions = nodeInfo.getName().equals(RetentionSteps.ACCESSION.stepName) && nodeInfo.isCombineRetentionStepConditions(); + actionDefinitionParams.put(RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS, combineConditions); + + if(nodeInfo.getLocation() != null && nodeInfo.getName().equals(RetentionSteps.TRANSFER.stepName)) + { + actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_LOCATION, + nodeInfo.getLocation()); + } List inputEvents = nodeInfo.getEvents(); actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_EVENT, (Serializable) inputEvents); - if (RetentionSteps.DESTROY.stepName.equals(nodeInfo.getName()) && nodeInfo.isRetainRecordMetadataAfterDestruction()) + + if (RetentionSteps.DESTROY_CONTENT.stepName.equals(nodeInfo.getName())) { actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, "ghost"); } - else + else if (RetentionSteps.DESTROY_NODE.stepName.equals(nodeInfo.getName())) { actionDefinitionParams.put(RecordsManagementModel.PROP_DISPOSITION_ACTION_GHOST_ON_DESTROY, "delete"); } diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionScheduleActionDefinition.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionScheduleActionDefinition.java index d9806e01df..3d472cfff3 100644 --- a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionScheduleActionDefinition.java +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionScheduleActionDefinition.java @@ -38,13 +38,13 @@ public class RetentionScheduleActionDefinition { private String id; private String name; + private String description; private int periodAmount; private String period; private String periodProperty; - private boolean combineDispositionStepConditions; + private boolean combineRetentionStepConditions; private List events; private boolean eligibleOnFirstCompleteEvent; - private String description; private boolean retainRecordMetadataAfterDestruction; private String location; private int index; diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSteps.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSteps.java index e8ecbd32bf..ddc5da107b 100644 --- a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSteps.java +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSteps.java @@ -35,7 +35,8 @@ public enum RetentionSteps CUTOFF("cutoff"), TRANSFER("transfer"), ACCESSION("accession"), - DESTROY("destroy"); + DESTROY_CONTENT("destroyContent"), + DESTROY_NODE("destroyNode"); public final String stepName; diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleActionRelation.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleActionRelation.java index 8e4c443751..269b6bde08 100644 --- a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleActionRelation.java +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleActionRelation.java @@ -146,6 +146,11 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi */ private void retentionScheduleStepValidation(NodeRef retentionScheduleNodeRef, RetentionScheduleActionDefinition retentionScheduleActionDefinition) { + if (checkStepNameIsEmpty(retentionScheduleActionDefinition.getName())) + { + throw new IllegalArgumentException("'name' parameter is mandatory when creating a disposition action definition"); + } + List actions = nodesModelFactory.getRetentionActions(retentionScheduleNodeRef); Set completedActions = new HashSet<>(); if (!actions.isEmpty()) @@ -155,9 +160,9 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi .collect(Collectors.toSet()); } - if (completedActions.contains(RetentionSteps.DESTROY.stepName)) + if (completedActions.contains("destroy")) { - throw new ConstraintViolatedException("Invalid Step - destroy action is already added . No other action is allowed after Destroy."); + throw new ConstraintViolatedException("Invalid Step - destroy action is already added. No other action is allowed after Destroy."); } if (checkStepAlreadyExists(completedActions, retentionScheduleActionDefinition.getName())) @@ -176,6 +181,11 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi } } + private boolean checkStepNameIsEmpty(String name) + { + return name == null || name.isEmpty(); + } + /** * this method is used to validate the request of the retention schedule * @param retentionScheduleActionDefinition retention schedule action definition @@ -187,16 +197,34 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi { throw new InvalidArgumentException("name value is invalid : " +retentionScheduleActionDefinition.getName()); } - // period value validation - if (invalidPeriodCheck(retentionScheduleActionDefinition.getPeriod())) - { - throw new InvalidArgumentException("period value is invalid : " +retentionScheduleActionDefinition.getPeriod()); - } + + validatePeriodAndPeriodProperty(retentionScheduleActionDefinition); + // event name validation if (invalidEventNameCheck(retentionScheduleActionDefinition.getEvents())) { throw new InvalidArgumentException("event value is invalid: " + retentionScheduleActionDefinition.getEvents()); } + + if (validateCombineRetentionStepConditionsForNonAccessionStep(retentionScheduleActionDefinition)) + { + throw new IllegalArgumentException("combineRetentionStepConditions property is only valid for accession step. Not valid for :" + retentionScheduleActionDefinition.getName()); + } + + if (validateLocationForNonTransferStep(retentionScheduleActionDefinition)) + { + throw new IllegalArgumentException("location property is only valid for transfer step. Not valid for :" + retentionScheduleActionDefinition.getName()); + } + } + + private void validatePeriodAndPeriodProperty(RetentionScheduleActionDefinition retentionScheduleActionDefinition) + { + // period value validation + if (invalidPeriodCheck(retentionScheduleActionDefinition.getPeriod())) + { + throw new InvalidArgumentException("period value is invalid : " +retentionScheduleActionDefinition.getPeriod()); + } + // periodProperty validation List validPeriodProperties = Arrays.asList("cm:created", "rma:cutOffDate", "rma:dispositionAsOf"); if (validPeriodProperties.stream().noneMatch(retentionScheduleActionDefinition.getPeriodProperty()::equals)) @@ -205,6 +233,19 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi } } + private boolean validateCombineRetentionStepConditionsForNonAccessionStep(RetentionScheduleActionDefinition retentionScheduleActionDefinition) + { + return !retentionScheduleActionDefinition.getName().equals(RetentionSteps.ACCESSION.stepName) + && retentionScheduleActionDefinition.isCombineRetentionStepConditions(); + } + + private boolean validateLocationForNonTransferStep(RetentionScheduleActionDefinition retentionScheduleActionDefinition) + { + return retentionScheduleActionDefinition.getLocation() != null + && !retentionScheduleActionDefinition.getName().equals(RetentionSteps.TRANSFER.stepName) + && !retentionScheduleActionDefinition.getLocation().isEmpty(); + } + private boolean checkStepAlreadyExists(Set completedActions, String stepName) { return completedActions.contains(stepName) && !stepName.equals(RetentionSteps.TRANSFER.stepName); diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java index 86583c27da..b6f1b034a1 100644 --- a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java @@ -26,9 +26,12 @@ */ package org.alfresco.rm.rest.api.retentionschedule; +import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.rest.framework.WebApiDescription; +import org.alfresco.rest.framework.core.exceptions.UnprocessableContentException; import org.alfresco.rest.framework.resource.RelationshipResource; import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; @@ -37,10 +40,12 @@ import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory; import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils; import org.alfresco.rm.rest.api.model.RetentionSchedule; import org.alfresco.rm.rest.api.recordcategories.RecordCategoriesEntityResource; +import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; import java.io.Serializable; import java.util.ArrayList; @@ -96,6 +101,11 @@ public class RetentionScheduleRelation implements RelationshipResourceAction.Rea mandatory("entity", nodeInfos); mandatory("parameters", parameters); NodeRef parentNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, recordCategoryId); + + if (checkCategoryHasAssocFolder(parentNodeRef) && nodeInfos.get(0).getIsRecordLevel()) + { + throw new UnprocessableContentException("Record level retention schedule cannot be created for a record category having folder associated."); + } List result = new ArrayList<>(); // Create the disposition schedule Map dsProps = new HashMap<>(); @@ -108,6 +118,14 @@ public class RetentionScheduleRelation implements RelationshipResourceAction.Rea return result; } + private boolean checkCategoryHasAssocFolder(NodeRef nodeRef) + { + List assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); + return assocs.stream() + .map(assoc -> nodeService.getType(assoc.getChildRef())) + .anyMatch(nodeType -> nodeType.equals(RecordsManagementModel.TYPE_RECORD_FOLDER)); + } + @Override @WebApiDescription(title = "Return a paged list of retention schedule based on the 'recordCategoryId'") public CollectionWithPagingInfo readAll(String recordCategoryId, Parameters parameters) diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/gs-core-api.yaml b/amps/ags/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/gs-core-api.yaml index 6ab10c5079..354cec9900 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/gs-core-api.yaml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/gs-core-api.yaml @@ -2683,6 +2683,8 @@ paths: description: recordCategoryId does not exist '409': description: Retention schedule already exist for the given recordCategoryId + '422': + description: Record level retention schedule cannot be created for a record category having folder associated default: description: Unexpected error schema: @@ -2742,13 +2744,13 @@ paths: ```JSON { "name":"accession", + "description":"Step Description", "periodAmount": 2, "period":"month", "periodProperty":"cm:created", - "combineDispositionStepConditions": false, + "combineRetentionStepConditions": false, "events":["versioned"], - "eligibleOnFirstCompleteEvent": true, - "description":"Step Description" + "eligibleOnFirstCompleteEvent": true } ``` operationId: createRetentionScheduleAction @@ -4534,20 +4536,20 @@ definitions: type: string name: type: string + description: + type: string periodAmount: type: integer period: type: string periodProperty: type: string - combineDispositionStepConditions: + combineRetentionStepConditions: type: boolean default: false eligibleOnFirstCompleteEvent: type: boolean default: true - description: - type: string retainRecordMetadataAfterDestruction: type: boolean location: @@ -4560,6 +4562,9 @@ definitions: type: integer RetentionStepNodeBodyCreate: type: object + required: + - name + - description properties: name: type: string @@ -4569,7 +4574,15 @@ definitions: * cutoff * accession * transfer - * destroy + * destroyContent + * destroyNode + + destroyNode step can be used to destroy content along with record metadata. + In case, record metadata needs to be retained, then destroyContent step should be used. + description: + type: string + description: | + This property is used to provide the step description. periodAmount: type: integer description: | @@ -4618,7 +4631,7 @@ definitions: * cm:created = Created Date (defult value) * rma:cutOffDate = Cut Off Date * rma:dispositionAsOf = Retention Action - combineDispositionStepConditions: + combineRetentionStepConditions: type: boolean description: | This property is only valid for **accession** step. @@ -4653,14 +4666,6 @@ definitions: description: | * false = When all events have happened * true = Whichever event is earlier - description: - type: string - description: | - This property is used to provide the step description. - retainRecordMetadataAfterDestruction: - type: boolean - description: | - This property is used to retain the metadata after record destruction. location: type: string description: |