From 96011e4fe943d94e4823c1cc9f04da250ca30a99 Mon Sep 17 00:00:00 2001 From: Rodica Sutu Date: Wed, 2 Jun 2021 09:29:04 +0300 Subject: [PATCH] Feature/rm 7103 changes from governance pr#1421 (#508) * RM-7103: [AGS] Updating record retention schedule to a longer period fails - Run as system user when setting the disposition property on the node. * RM-7103: [AGS] Updating record retention schedule to a longer period fails - Added test * RM-7103: [AGS] Updating record retention schedule to a longer period fails - Removed unnecessary parentheses * RM-7103: [AGS] Updating record retention schedule to a longer period fails - Added missing constants * RM-7103: [AGS] Updating record retention schedule to a longer period fails - Replaced with lambda expression Co-authored-by: Raluca Munteanu --- .../disposition/DispositionServiceImpl.java | 12 +- .../DispositionScheduleInheritanceTest.java | 114 +++++++++++++++--- .../test/util/CommonRMTestUtils.java | 2 + 3 files changed, 111 insertions(+), 17 deletions(-) diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java index f4ee94b739..ae68e87193 100644 --- a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java @@ -59,6 +59,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState; +import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.ChildAssociationRef; @@ -330,18 +331,23 @@ public class DispositionServiceImpl extends ServiceBaseImpl final String dispositionActionName = dsNextAction.getNextActionName(); final Date dispositionActionDate = dsNextAction.getNextActionDateAsOf(); - // check if current transaction is a READ ONLY one and if true set the property on the node + RunAsWork runAsWork = () -> { + nodeService.setProperty(action, PROP_DISPOSITION_AS_OF, dispositionActionDate); + return null; + }; + + // if the current transaction is READ ONLY set the property on the node // in a READ WRITE transaction if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY)) { transactionService.getRetryingTransactionHelper().doInTransaction((RetryingTransactionCallback) () -> { - getInternalNodeService().setProperty(action, PROP_DISPOSITION_AS_OF, dispositionActionDate); + AuthenticationUtil.runAsSystem(runAsWork); return null; }, false, true); } else { - getInternalNodeService().setProperty(action, PROP_DISPOSITION_AS_OF, dispositionActionDate); + AuthenticationUtil.runAsSystem(runAsWork); } if (dsNextAction.getWriteMode().equals(WriteMode.DATE_AND_NAME)) diff --git a/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/DispositionScheduleInheritanceTest.java b/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/DispositionScheduleInheritanceTest.java index eae04fb59e..e55fe0e7b6 100644 --- a/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/DispositionScheduleInheritanceTest.java +++ b/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/DispositionScheduleInheritanceTest.java @@ -31,11 +31,14 @@ import static org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestU import static org.alfresco.util.GUID.generate; import java.io.Serializable; +import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; import org.alfresco.module.org_alfresco_module_rm.action.impl.RetainAction; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils; @@ -73,7 +76,7 @@ public class DispositionScheduleInheritanceTest extends BaseRMTestCase category1 = filePlanService.createRecordCategory(filePlan, generate()); // create record level disposition schedule for category1 - createDispositionSchedule(category1); + createDispositionScheduleCutOffAndRetainImmediately(category1); // create subcategory1 under category1 NodeRef subcategory1 = filePlanService.createRecordCategory(category1, generate()); @@ -109,22 +112,105 @@ public class DispositionScheduleInheritanceTest extends BaseRMTestCase }); } - private void createDispositionSchedule(NodeRef category) + /** + * Given a root record category A with a retention schedule set to cut off after 10 days + * and another root record category B with a retention schedule set to cut off after 5 days containing a + * subcategory + * When moving the subcategory into the first root category + * Then records under the subcategory inherit the retention schedule of the parent record category + * The cut off date is updated to the new one, since the initial date was before the new one + *

+ * Please see https://alfresco.atlassian.net/browse/RM-7103 + */ + public void testRetentionScheduleInheritance_APPS7103() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + NodeRef category1; + NodeRef subcategory2; + NodeRef record; + Date asOfDateBeforeMove; + + @Override + public void given() + { + // create root category1 + category1 = filePlanService.createRecordCategory(filePlan, generate()); + + // create record level disposition schedule for category1 + createDispositionScheduleCutOff(category1, CutOffAction.NAME, CommonRMTestUtils.PERIOD_TEN_DAYS); + + // create root category2 + NodeRef category2 = filePlanService.createRecordCategory(filePlan, generate()); + + // create record level disposition schedule for category2 + createDispositionScheduleCutOff(category2, CutOffAction.NAME, CommonRMTestUtils.PERIOD_FIVE_DAYS); + + // create subcategory2 under category2 + subcategory2 = filePlanService.createRecordCategory(category2, generate()); + + // create folder under subcategory2 + folder = recordFolderService.createRecordFolder(subcategory2, generate()); + + // file record in folder and complete it + record = utils.createRecord(folder, generate(), generate()); + utils.completeRecord(record); + + //store the date to check if it was updated + asOfDateBeforeMove = dispositionService.getNextDispositionAction(record).getAsOfDate(); + } + + @Override + public void when() throws Exception + { + // move subcategory2 under category1 + fileFolderService.move(subcategory2, category1, null); + } + + @Override + public void then() throws Exception + { + dispositionService.getDispositionSchedule(record); + // check the next disposition action + DispositionAction dispositionActionAfterMove = dispositionService.getNextDispositionAction(record); + assertNotNull(dispositionActionAfterMove); + assertEquals(CutOffAction.NAME, dispositionActionAfterMove.getName()); + assertNotNull(dispositionActionAfterMove.getAsOfDate()); + assertTrue(dispositionActionAfterMove.getAsOfDate().after(asOfDateBeforeMove)); + + // check the search aspect details + assertTrue(nodeService.hasAspect(record, ASPECT_RM_SEARCH)); + assertEquals(CutOffAction.NAME, nodeService.getProperty(record, PROP_RS_DISPOSITION_ACTION_NAME)); + assertNotNull(nodeService.getProperty(record, PROP_RS_DISPOSITION_ACTION_AS_OF)); + assertNull((List) nodeService.getProperty(record, PROP_RS_DISPOSITION_EVENTS)); + assertNotNull(nodeService.getProperty(record, PROP_RS_DISPOITION_INSTRUCTIONS)); + assertNotNull(nodeService.getProperty(record, PROP_RS_DISPOITION_AUTHORITY)); + assertTrue((Boolean) nodeService.getProperty(record, PROP_RS_HAS_DISPOITION_SCHEDULE)); + } + }); + } + + private void createDispositionScheduleCutOff(NodeRef category, String action, String period) { DispositionSchedule ds = utils.createDispositionSchedule(category, DEFAULT_DISPOSITION_INSTRUCTIONS, DEFAULT_DISPOSITION_DESCRIPTION, true, false, false); - // CUTOFF immediately - Map cutOff = new HashMap(3); - cutOff.put(PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); - cutOff.put(PROP_DISPOSITION_DESCRIPTION, generate()); - cutOff.put(PROP_DISPOSITION_PERIOD, CommonRMTestUtils.PERIOD_IMMEDIATELY); - dispositionService.addDispositionActionDefinition(ds, cutOff); + createDispositionScheduleStep(ds, action, period); + } - // RETAIN immediately - Map retain = new HashMap(3); - retain.put(PROP_DISPOSITION_ACTION_NAME, RetainAction.NAME); - retain.put(PROP_DISPOSITION_DESCRIPTION, generate()); - retain.put(PROP_DISPOSITION_PERIOD, CommonRMTestUtils.PERIOD_IMMEDIATELY); - dispositionService.addDispositionActionDefinition(ds, retain); + private void createDispositionScheduleCutOffAndRetainImmediately(NodeRef category) + { + DispositionSchedule ds = utils.createDispositionSchedule(category, DEFAULT_DISPOSITION_INSTRUCTIONS, DEFAULT_DISPOSITION_DESCRIPTION, true, false, false); + + createDispositionScheduleStep(ds, CutOffAction.NAME, CommonRMTestUtils.PERIOD_IMMEDIATELY); + createDispositionScheduleStep(ds, RetainAction.NAME, CommonRMTestUtils.PERIOD_IMMEDIATELY); + } + + private void createDispositionScheduleStep(DispositionSchedule ds, String action, String period) + { + Map step = new HashMap(3); + step.put(PROP_DISPOSITION_ACTION_NAME, action); + step.put(PROP_DISPOSITION_DESCRIPTION, generate()); + step.put(PROP_DISPOSITION_PERIOD, period); + dispositionService.addDispositionActionDefinition(ds, step); } } diff --git a/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java b/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java index 523ebaf9a0..2543f63225 100644 --- a/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java +++ b/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java @@ -84,6 +84,8 @@ public class CommonRMTestUtils implements RecordsManagementModel public static final String DEFAULT_EVENT_NAME = "case_closed"; public static final String PERIOD_NONE = "none|0"; public static final String PERIOD_IMMEDIATELY = "immediately|0"; + public static final String PERIOD_FIVE_DAYS = "day|5"; + public static final String PERIOD_TEN_DAYS = "day|10"; public static final String PERIOD_ONE_WEEK = "week|1"; public static final String PERIOD_ONE_YEAR = "year|1"; public static final String PERIOD_THREE_YEARS = "year|3";