[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 <ST28@ford.com>
This commit is contained in:
SathishK-T
2024-07-03 18:32:42 +05:30
committed by GitHub
parent 90b91b87ef
commit 35b4ad5dbe
8 changed files with 151 additions and 52 deletions

View File

@@ -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<QName, Serializable> createRetentionActionDefinitionParams(RetentionScheduleActionDefinition nodeInfo)
{
Map<QName, Serializable> 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<String> 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");
}

View File

@@ -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<String> events;
private boolean eligibleOnFirstCompleteEvent;
private String description;
private boolean retainRecordMetadataAfterDestruction;
private String location;
private int index;

View File

@@ -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;

View File

@@ -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<DispositionActionDefinition> actions = nodesModelFactory.getRetentionActions(retentionScheduleNodeRef);
Set<String> 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<String> 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<String> completedActions, String stepName)
{
return completedActions.contains(stepName) && !stepName.equals(RetentionSteps.TRANSFER.stepName);

View File

@@ -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<RetentionSchedule> result = new ArrayList<>();
// Create the disposition schedule
Map<QName, Serializable> dsProps = new HashMap<>();
@@ -108,6 +118,14 @@ public class RetentionScheduleRelation implements RelationshipResourceAction.Rea
return result;
}
private boolean checkCategoryHasAssocFolder(NodeRef nodeRef)
{
List<ChildAssociationRef> 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<RetentionSchedule> readAll(String recordCategoryId, Parameters parameters)