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 <raluca.munteanu@ness.com>
This commit is contained in:
Rodica Sutu
2021-06-02 09:29:04 +03:00
committed by GitHub
parent f6423903d7
commit 96011e4fe9
3 changed files with 111 additions and 17 deletions

View File

@@ -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<Void> 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<Void>) () -> {
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))

View File

@@ -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
* <p>
* 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<String>) 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<QName, Serializable> cutOff = new HashMap<QName, Serializable>(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<QName, Serializable> retain = new HashMap<QName, Serializable>(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<QName, Serializable> step = new HashMap<QName, Serializable>(3);
step.put(PROP_DISPOSITION_ACTION_NAME, action);
step.put(PROP_DISPOSITION_DESCRIPTION, generate());
step.put(PROP_DISPOSITION_PERIOD, period);
dispositionService.addDispositionActionDefinition(ds, step);
}
}

View File

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