From 6b3f0c24318fe97836fbfb89134b2062617d806c Mon Sep 17 00:00:00 2001 From: Sara Aspery Date: Mon, 4 Nov 2019 07:08:32 +0000 Subject: [PATCH] RM-7026 Audit Create Hold updates --- .../audit/event/CreateHoldAuditEvent.java | 30 +++--- .../audit/event/HoldUtils.java | 62 +++++++++++++ ...RecordsManagementAuditServiceImplTest.java | 74 ++++++++++++++- .../test/util/BaseRMTestCase.java | 13 +++ .../event/CreateHoldAuditEventUnitTest.java | 93 +++++++++++++++++++ 5 files changed, 251 insertions(+), 21 deletions(-) create mode 100644 rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/HoldUtils.java create mode 100644 rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEventUnitTest.java diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEvent.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEvent.java index d81c0557d9..6e585cecd3 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEvent.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEvent.java @@ -28,22 +28,17 @@ package org.alfresco.module.org_alfresco_module_rm.audit.event; import java.io.Serializable; -import java.util.HashMap; import java.util.Map; -import org.alfresco.model.ContentModel; -import org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies; -import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.repo.policy.annotation.Behaviour; import org.alfresco.repo.policy.annotation.BehaviourBean; import org.alfresco.repo.policy.annotation.BehaviourKind; +import org.alfresco.repo.policy.Behaviour.NotificationFrequency; +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.namespace.QName; -import static org.alfresco.model.ContentModel.PROP_DESCRIPTION; -import static org.apache.commons.lang3.StringUtils.isBlank; - /** * Create hold audit event. * @@ -51,12 +46,8 @@ import static org.apache.commons.lang3.StringUtils.isBlank; * @since 3.3 */ @BehaviourBean -public class CreateHoldAuditEvent extends AuditEvent implements HoldServicePolicies.OnCreateHoldPolicy +public class CreateHoldAuditEvent extends AuditEvent { - /** QNames to display for the hold's properties. */ - private static final QName HOLD_NAME = QName.createQName(RecordsManagementModel.RM_URI, "Hold Name"); - private static final QName HOLD_DESCRIPTION = QName.createQName(RecordsManagementModel.RM_URI, "Hold Description"); - /** Node Service */ private NodeService nodeService; @@ -71,20 +62,21 @@ public class CreateHoldAuditEvent extends AuditEvent implements HoldServicePolic } /** - * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies.OnCreateHoldPolicy#onCreateHold(org.alfresco.service.cmr.repository.NodeRef) + * @param childAssociationRef child association reference */ - @Override @Behaviour ( kind = BehaviourKind.CLASS, - type = "rma:hold" + type = "rma:hold", + policy = "alf:onCreateNode", + notificationFrequency= NotificationFrequency.TRANSACTION_COMMIT ) - public void onCreateHold(NodeRef holdNodeRef) + public void onCreateHold(ChildAssociationRef childAssociationRef) { - Map auditProperties = new HashMap<>(); - auditProperties.put(ContentModel.PROP_NAME, nodeService.getProperty(holdNodeRef, ContentModel.PROP_NAME)); + NodeRef holdNodeRef = childAssociationRef.getChildRef(); + + Map auditProperties = HoldUtils.makePropertiesMap(holdNodeRef, nodeService); auditProperties.put(PROP_HOLD_REASON, nodeService.getProperty(holdNodeRef, PROP_HOLD_REASON)); - auditProperties.put(PROP_DESCRIPTION, nodeService.getProperty(holdNodeRef, PROP_DESCRIPTION)); recordsManagementAuditService.auditEvent(holdNodeRef, getName(), null, auditProperties); } diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/HoldUtils.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/HoldUtils.java new file mode 100644 index 0000000000..c87aa61309 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/HoldUtils.java @@ -0,0 +1,62 @@ +/* + * #%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.audit.event; + +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * Utility class for creating audit events about holds. + * + * @author Sara Aspery + * @since 3.3 + */ +class HoldUtils +{ + /** + * Create a properties map containing the hold name for the given hold. + * + * @param nodeRef The nodeRef of the hold. + * @param nodeService The node service. + * @return A map containing the name of the hold. + */ + static Map makePropertiesMap(NodeRef nodeRef, NodeService nodeService) + { + Map auditProperties = new HashMap<>(); + + auditProperties.put(ContentModel.PROP_NAME, nodeService.getProperty(nodeRef, ContentModel.PROP_NAME)); + + return auditProperties; + } +} diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java index fd2222fae5..5633fbcf62 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java @@ -33,8 +33,6 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Set; -import java.util.stream.Stream; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditEntry; @@ -48,6 +46,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; import org.alfresco.util.EqualsHelper; +import org.alfresco.util.GUID; import org.alfresco.util.Pair; /** @@ -571,6 +570,59 @@ public class RecordsManagementAuditServiceImplTest extends BaseRMTestCase }); } + /** + * Given I have created a hold + * When I will get the RM audit filter by create hold event + * Then there will be an entry for the created hold, including the hold name and reason + */ + @org.junit.Test + public void testAuditForCreateHold() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + final static String CREATE_HOLD_AUDIT_EVENT = "Create Hold"; + + String holdName = "Hold " + GUID.generate(); + String holdReason = "Reason " + GUID.generate(); + + NodeRef hold; + Map auditEventProperties; + + @Override + public void given() + { + rmAuditService.clearAuditLog(filePlan); + hold = createHold(holdName, holdReason); + } + + @Override + public void when() + { + auditEventProperties = getAuditEntry(CREATE_HOLD_AUDIT_EVENT).getAfterProperties(); + } + + @Override + public void then() + { + // check create hold audit event includes the hold name + assertEquals("Create Hold event does not include hold name.", holdName, + auditEventProperties.get(PROP_NAME)); + + // check create hold audit event includes the hold reason + assertEquals("Create Hold event does not include hold reason.", holdReason, + auditEventProperties.get(PROP_HOLD_REASON)); + } + + @Override + public void after() + { + // Stop and delete all entries + rmAuditService.stopAuditLog(filePlan); + rmAuditService.clearAuditLog(filePlan); + } + }); + } + /** === Helper methods === */ private List getAuditTrail(String asUser) @@ -618,4 +670,22 @@ public class RecordsManagementAuditServiceImplTest extends BaseRMTestCase } }, asUser); } + + private RecordsManagementAuditEntry getAuditEntry(String auditEvent) + { + // set the audit query param for the given event + RecordsManagementAuditQueryParameters params = new RecordsManagementAuditQueryParameters(); + params.setEvent(auditEvent); + + // get the audit entries for the given event + List auditEntries; + auditEntries = getAuditTrail(params, 1, ADMIN_USER); + + // verify we have the expected audit event + RecordsManagementAuditEntry auditEntry = auditEntries.get(0); + assertEquals(auditEvent + " event is not audited.", auditEvent, auditEntry.getEvent()); + + // return the properties of the audit event + return auditEntry; + } } diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java index 21cb4ce5d8..ebd2d1ee24 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java @@ -92,6 +92,8 @@ import org.alfresco.util.GUID; import org.alfresco.util.RetryingTransactionHelperTestCase; import org.springframework.context.ApplicationContext; +import static org.alfresco.util.GUID.generate; + /** * Base test case class to use for RM unit tests. * @@ -707,6 +709,17 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase return createPerson(userName, true); } + /** + * Util method to create a hold. + * @param holdName hold name + * @param holdReason hold reason + * @return NodeRef hold node reference + */ + protected NodeRef createHold(String holdName, String holdReason) + { + return holdService.createHold(filePlan, holdName, holdReason, generate()); + } + /** * Setup multi hierarchy test data */ diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEventUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEventUnitTest.java new file mode 100644 index 0000000000..a82a77c619 --- /dev/null +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/CreateHoldAuditEventUnitTest.java @@ -0,0 +1,93 @@ +/* + * #%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.audit.event; + +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.util.GUID; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.Map; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isNull; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * Unit tests for {@link CreateHoldAuditEvent}. + * + * @author Sara Aspery + * @since 3.3 + */ +public class CreateHoldAuditEventUnitTest extends BaseUnitTest +{ + @InjectMocks + private CreateHoldAuditEvent createHoldAuditEvent; + + @Mock + private NodeService mockedNodeService; + + private NodeRef holdNodeRef; + private ChildAssociationRef childAssociationRef; + + /** Set up the mocks. */ + @Before + public void setUp() + { + initMocks(this); + + holdNodeRef = generateNodeRef(); + String holdName = "Hold " + GUID.generate(); + String holdReason = "Reason " + GUID.generate(); + childAssociationRef = generateChildAssociationRef(null, holdNodeRef); + + when(childAssociationRef.getChildRef()).thenReturn(holdNodeRef); + when(mockedNodeService.getProperty(holdNodeRef, PROP_NAME)).thenReturn(holdName); + when(mockedNodeService.getProperty(holdNodeRef, PROP_HOLD_REASON)).thenReturn(holdReason); + } + + /** + * Check that the create hold event calls an audit event. + * + */ + @Test + public void testCreateHoldCausesAuditEvent() + { + createHoldAuditEvent.onCreateHold(childAssociationRef); + verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(holdNodeRef), any(String.class), isNull(Map.class), any(Map.class)); + } +}