From a1be193a3f5ae7625b22aa60087eebc2654abe0f Mon Sep 17 00:00:00 2001 From: Ramona Popa Date: Sun, 3 Nov 2019 06:47:29 +0000 Subject: [PATCH] RM-6860: Add hold service policies - Added HoldServicePolicies interface --- .../rm-service-context.xml | 1 + .../hold/HoldServiceImpl.java | 111 +++++++++++++++++- .../hold/HoldServicePolicies.java | 89 ++++++++++++++ .../test/integration/hold/CreateHoldTest.java | 69 ++++++++++- .../test/integration/hold/DeleteHoldTest.java | 72 +++++++++++- .../hold/HoldServiceImplUnitTest.java | 10 ++ 6 files changed, 347 insertions(+), 5 deletions(-) create mode 100644 rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServicePolicies.java diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml index 00e1ccddaf..a6bb75c2c1 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml @@ -1534,6 +1534,7 @@ + beforeCreateHoldPolicyDelegate; + private ClassPolicyDelegate onCreateHoldPolicyDelegate; + private ClassPolicyDelegate beforeDeleteHoldPolicyDelegate; + private ClassPolicyDelegate onDeleteHoldPolicyDelegate; + /** * Initialise hold service */ @@ -184,6 +222,12 @@ public class HoldServiceImpl extends ServiceBaseImpl return null; } }); + + // Register the policies + beforeCreateHoldPolicyDelegate = getPolicyComponent().registerClassPolicy(BeforeCreateHoldPolicy.class); + onCreateHoldPolicyDelegate = getPolicyComponent().registerClassPolicy(OnCreateHoldPolicy.class); + beforeDeleteHoldPolicyDelegate = getPolicyComponent().registerClassPolicy(BeforeDeleteHoldPolicy.class); + onDeleteHoldPolicyDelegate = getPolicyComponent().registerClassPolicy(OnDeleteHoldPolicy.class); } /** @@ -209,7 +253,6 @@ public class HoldServiceImpl extends ServiceBaseImpl transactionalResourceHelper.getSet("frozen").add(frozenNode); removeFreezeAspect(frozenNode, 1); } - return null; } }; @@ -417,6 +460,8 @@ public class HoldServiceImpl extends ServiceBaseImpl // get the root hold container NodeRef holdContainer = filePlanService.getHoldContainer(filePlan); + invokeBeforeCreateHold(holdContainer, name, reason); + // create map of properties Map properties = new HashMap<>(3); properties.put(ContentModel.PROP_NAME, name); @@ -432,7 +477,11 @@ public class HoldServiceImpl extends ServiceBaseImpl // create hold ChildAssociationRef childAssocRef = nodeService.createNode(holdContainer, ContentModel.ASSOC_CONTAINS, assocName, TYPE_HOLD, properties); - return childAssocRef.getChildRef(); + NodeRef holdNodeRef = childAssocRef.getChildRef(); + + invokeOnCreateHold(holdNodeRef); + + return holdNodeRef; } /** @@ -520,8 +569,15 @@ public class HoldServiceImpl extends ServiceBaseImpl throw new AlfrescoRuntimeException("Can't delete hold, because filing permissions for the following items are needed: " + sb.toString()); } + invokeBeforeDeleteHold(hold); + + String holdName = (String) nodeService.getProperty(hold, PROP_NAME); + Set classQNames = getTypeAndApsects(hold); + // delete the hold node nodeService.deleteNode(hold); + + invokeOnDeleteHold(holdName, classQNames); } /** @@ -809,4 +865,55 @@ public class HoldServiceImpl extends ServiceBaseImpl removeFromAllHolds(nodeRef); } } + + /** + * Invoke beforeCreateHold policy + * + * @param nodeRef node reference + * @param name hold name + * @param reason hold reason + */ + protected void invokeBeforeCreateHold(NodeRef nodeRef, String name, String reason) + { + // execute policy for node type and aspects + BeforeCreateHoldPolicy policy = beforeCreateHoldPolicyDelegate.get(getTypeAndApsects(nodeRef)); + policy.beforeCreateHold(name, reason); + } + + /** + * Invoke onCreateHold policy + * + * @param nodeRef node reference + */ + protected void invokeOnCreateHold(NodeRef nodeRef) + { + OnCreateHoldPolicy policy = onCreateHoldPolicyDelegate.get(getTypeAndApsects(nodeRef)); + policy.onCreateHold(nodeRef); + } + + /** + * Invoke beforeDeleteHold policy + * + * @param nodeRef node reference + */ + protected void invokeBeforeDeleteHold(NodeRef nodeRef) + { + BeforeDeleteHoldPolicy policy = beforeDeleteHoldPolicyDelegate.get(getTypeAndApsects(nodeRef)); + policy.beforeDeleteHold(nodeRef); + } + + /** + * Invoke onDeleteHold policy + * + * @param holdName name of the hold + * @param classQNames hold types and aspects + */ + protected void invokeOnDeleteHold(String holdName, Set classQNames) + { + // execute policy for node type and aspects + OnDeleteHoldPolicy policy = onDeleteHoldPolicyDelegate.get(classQNames); + policy.onDeleteHold(holdName); + + } + } diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServicePolicies.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServicePolicies.java new file mode 100644 index 0000000000..c5b0ae87a2 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServicePolicies.java @@ -0,0 +1,89 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.hold; + +import org.alfresco.repo.policy.ClassPolicy; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; + +/** + * Hold Service Policies + * + * @author Ramona Popa + * @since 3.3 + */ + +public interface HoldServicePolicies +{ + interface BeforeCreateHoldPolicy extends ClassPolicy + { + public static final QName QNAME = QName.createQName(NamespaceService.ALFRESCO_URI, "beforeCreateHold"); + /** + * Called before a hold is created. + * + * @param name name of the hold to be created + * @param reason reason for the hold to be created + */ + void beforeCreateHold(String name, String reason); + } + + interface OnCreateHoldPolicy extends ClassPolicy + { + public static final QName QNAME = QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateHold"); + /** + * Called when a hold is created. + * + * @param hold node reference + */ + void onCreateHold(NodeRef hold); + } + + interface BeforeDeleteHoldPolicy extends ClassPolicy + { + public static final QName QNAME = QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteHold"); + /** + * Called before a hold is deleted. + * + * @param hold node reference + */ + void beforeDeleteHold(NodeRef hold); + } + + interface OnDeleteHoldPolicy extends ClassPolicy + { + public static final QName QNAME = QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteHold"); + + /** + * Called when a hold is deleted. + * + * @param holdname name of the deleted hold + */ + void onDeleteHold(String holdname); + } +} diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/CreateHoldTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/CreateHoldTest.java index 61e49b676c..5186d1a0eb 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/CreateHoldTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/CreateHoldTest.java @@ -37,8 +37,16 @@ import java.util.HashSet; import java.util.Set; import org.alfresco.module.org_alfresco_module_rm.capability.Capability; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies.BeforeCreateHoldPolicy; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies.OnCreateHoldPolicy; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.role.Role; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.repo.policy.Behaviour.NotificationFrequency; +import org.alfresco.repo.policy.BehaviourDefinition; +import org.alfresco.repo.policy.ClassBehaviourBinding; +import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.repository.NodeRef; @@ -48,11 +56,14 @@ import org.alfresco.service.cmr.repository.NodeRef; * @author Tuna Aksoy * @since 2.3 */ -public class CreateHoldTest extends BaseRMTestCase +public class CreateHoldTest extends BaseRMTestCase implements BeforeCreateHoldPolicy, OnCreateHoldPolicy { // Test user private String testUser = null; + private boolean beforeCreateHoldFlag = false; + private boolean onCreateHoldFlag = false; + /** * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#isUserTest() */ @@ -107,7 +118,7 @@ public class CreateHoldTest extends BaseRMTestCase { // ensure the user has the correct permission to create the hold filePlanPermissionService.setPermission(holdsContainer, testUser, FILING); - + return null; } }, getAdminUserName()); @@ -134,4 +145,58 @@ public class CreateHoldTest extends BaseRMTestCase } }); } + + public void testPolicyNotificationForCreateHold() throws Exception + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + BehaviourDefinition beforeCreateHoldBehaviour; + BehaviourDefinition onCreateHoldBehaviour; + + public void given() + { + beforeCreateHoldBehaviour = policyComponent.bindClassBehaviour(BeforeCreateHoldPolicy.QNAME, + RecordsManagementModel.TYPE_HOLD_CONTAINER, + new JavaBehaviour(CreateHoldTest.this, "beforeCreateHold", NotificationFrequency.EVERY_EVENT)); + + onCreateHoldBehaviour = policyComponent.bindClassBehaviour(OnCreateHoldPolicy.QNAME, + RecordsManagementModel.TYPE_HOLD, + new JavaBehaviour(CreateHoldTest.this, "onCreateHold", NotificationFrequency.EVERY_EVENT)); + + assertFalse(beforeCreateHoldFlag); + assertFalse(onCreateHoldFlag); + } + + public void when() + { + // Create a hold + NodeRef hold = holdService.createHold(filePlan, generate(), generate(), generate()); + } + + public void then() + { + assertTrue(beforeCreateHoldFlag); + assertTrue(onCreateHoldFlag); + } + + public void after() + { + policyComponent.removeClassDefinition(beforeCreateHoldBehaviour); + policyComponent.removeClassDefinition(onCreateHoldBehaviour); + } + }); + + } + + @Override + public void beforeCreateHold(String name, String reason) + { + beforeCreateHoldFlag = true; + } + + @Override + public void onCreateHold(NodeRef hold) + { + onCreateHoldFlag = true; + } } diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java index 8396032d5d..fdf3c0367e 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java @@ -27,10 +27,19 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.hold; +import static org.alfresco.util.GUID.generate; + import java.util.ArrayList; import java.util.List; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies.BeforeDeleteHoldPolicy; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies.OnDeleteHoldPolicy; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.repo.policy.Behaviour.NotificationFrequency; +import org.alfresco.repo.policy.BehaviourDefinition; +import org.alfresco.repo.policy.ClassBehaviourBinding; +import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.service.cmr.repository.NodeRef; /** @@ -39,7 +48,7 @@ import org.alfresco.service.cmr.repository.NodeRef; * @author Roy Wetherall * @since 2.2 */ -public class DeleteHoldTest extends BaseRMTestCase +public class DeleteHoldTest extends BaseRMTestCase implements BeforeDeleteHoldPolicy, OnDeleteHoldPolicy { /** Constants for the holds */ protected static final String HOLD1_NAME = "hold one"; @@ -49,6 +58,9 @@ public class DeleteHoldTest extends BaseRMTestCase protected static final String HOLD1_DESC = "but I'll not describe them here!"; protected static final String HOLD2_DESC = "no then! that's just not on!"; + private boolean beforeDeleteHoldFlag = false; + private boolean onDeleteHoldFlag = false; + @Override protected boolean isRecordTest() { @@ -234,4 +246,62 @@ public class DeleteHoldTest extends BaseRMTestCase } }); } + + public void testPolicyNotificationForDeleteHold() throws Exception + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + BehaviourDefinition beforeDeleteHoldBehaviour; + BehaviourDefinition onDeleteHoldBehaviour; + NodeRef hold; + + public void given() + { + beforeDeleteHoldBehaviour = policyComponent.bindClassBehaviour(BeforeDeleteHoldPolicy.QNAME, + RecordsManagementModel.TYPE_HOLD, + new JavaBehaviour(DeleteHoldTest.this, "beforeDeleteHold", NotificationFrequency.EVERY_EVENT)); + + onDeleteHoldBehaviour = policyComponent.bindClassBehaviour(OnDeleteHoldPolicy.QNAME, RecordsManagementModel.TYPE_HOLD, + new JavaBehaviour(DeleteHoldTest.this, "onDeleteHold", NotificationFrequency.EVERY_EVENT)); + + // Create a hold + hold = holdService.createHold(filePlan, generate(), generate(), generate()); + + assertFalse(beforeDeleteHoldFlag); + assertFalse(beforeDeleteHoldFlag); + } + + public void when() + { + // Delete the hold + holdService.deleteHold(hold); + + } + + public void then() + { + assertTrue(beforeDeleteHoldFlag); + assertTrue(onDeleteHoldFlag); + } + + public void after() + { + policyComponent.removeClassDefinition(beforeDeleteHoldBehaviour); + policyComponent.removeClassDefinition(onDeleteHoldBehaviour); + } + }); + + } + + @Override + public void beforeDeleteHold(NodeRef hold) + { + beforeDeleteHoldFlag = true; + } + + @Override + public void onDeleteHold(String holdName) + { + onDeleteHoldFlag = true; + } } diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java index 15af11203a..15cf5f8bd1 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java @@ -39,6 +39,7 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -70,6 +71,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; +import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.invocation.InvocationOnMock; @@ -220,6 +222,10 @@ public class HoldServiceImplUnitTest extends BaseUnitTest when(mockedNodeService.createNode(eq(holdContainer), eq(ContentModel.ASSOC_CONTAINS), any(QName.class) , eq(TYPE_HOLD), any(Map.class))) .thenReturn(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, holdContainer, generateQName(), hold)); + // mocks for policies + doNothing().when(holdService).invokeBeforeCreateHold(any(), anyString(), anyString()); + doNothing().when(holdService).invokeOnCreateHold(any()); + // create hold NodeRef newHold = holdService.createHold(filePlan, HOLD_NAME, HOLD_REASON, HOLD_DESCRIPTION); assertNotNull(newHold); @@ -306,6 +312,10 @@ public class HoldServiceImplUnitTest extends BaseUnitTest @Test public void deleteHold() { + // mocks for policies + doNothing().when(holdService).invokeBeforeDeleteHold(any()); + doNothing().when(holdService).invokeOnDeleteHold(any(), any()); + // delete hold holdService.deleteHold(hold); verify(mockedNodeService).deleteNode(hold);