diff --git a/rm-automation/rm-automation-community-rest-api/pom.xml b/rm-automation/rm-automation-community-rest-api/pom.xml
index f178cc8d3b..202a565fe6 100644
--- a/rm-automation/rm-automation-community-rest-api/pom.xml
+++ b/rm-automation/rm-automation-community-rest-api/pom.xml
@@ -15,7 +15,8 @@
false
alfresco-governance-services-community-share
alfresco-governance-services-community-repo
- 1.38
+ 1.50
+ 3.0.41
2.0.0
2.7.9.1
@@ -57,11 +58,20 @@
restapi
${tas.restapi.version}
-
- com.fasterxml.jackson.core
- jackson-databind
-
-
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ org.alfresco.tas
+ utility
+
+
+
+
+ org.alfresco.tas
+ utility
+ ${tas.utility.version}
org.projectlombok
diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java
index 13bd6e21d2..d26fd26d37 100644
--- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java
+++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java
@@ -30,6 +30,8 @@ import static lombok.AccessLevel.PROTECTED;
import javax.annotation.Resource;
+import lombok.Getter;
+import lombok.Setter;
import org.alfresco.rest.requests.Node;
import org.alfresco.rest.requests.coreAPI.RestCoreAPI;
import org.alfresco.rest.requests.search.SearchAPI;
@@ -46,16 +48,13 @@ import org.alfresco.rest.rm.community.requests.gscore.api.TransferAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.TransferContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI;
-import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.data.DataUserAIS;
import org.alfresco.utility.model.RepoTestModel;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
-import lombok.Getter;
-import lombok.Setter;
-
/**
* REST API Factory which provides access to the APIs
*
@@ -68,7 +67,7 @@ public class RestAPIFactory
{
@Autowired
@Getter (value = PROTECTED)
- private DataUser dataUser;
+ private DataUserAIS dataUser;
@Resource(name = "RMRestWrapper")
@Getter
diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/util/CommonTestUtils.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/util/CommonTestUtils.java
index 7c8b528af0..dbe6a0862d 100644
--- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/util/CommonTestUtils.java
+++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/util/CommonTestUtils.java
@@ -37,6 +37,11 @@ import java.util.UUID;
*/
public class CommonTestUtils
{
+ /**
+ * The default pattern used for the user full name when users are created with tas utility
+ */
+ public static final String USER_FULLNAME_PATTERN = "FN-%1$s LN-%1$s";
+
/** Private constructor to prevent instantiation. */
private CommonTestUtils()
{
diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/RMRolesAndActionsAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/RMRolesAndActionsAPI.java
index 6ce10de83d..7f524b0121 100644
--- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/RMRolesAndActionsAPI.java
+++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/RMRolesAndActionsAPI.java
@@ -47,6 +47,7 @@ import org.alfresco.dataprep.AlfrescoHttpClientFactory;
import org.alfresco.dataprep.UserService;
import org.alfresco.rest.core.v0.BaseAPI;
import org.alfresco.rest.core.v0.RMEvents;
+import org.alfresco.utility.data.DataUserAIS;
import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HttpResponse;
@@ -90,6 +91,8 @@ public class RMRolesAndActionsAPI extends BaseAPI
@Autowired
private UserService userService;
+ @Autowired
+ private DataUserAIS dataUser;
/**
* Get all the configured RM roles.
*
@@ -192,14 +195,12 @@ public class RMRolesAndActionsAPI extends BaseAPI
String adminPassword,
String userName,
String password,
- String email,
- String role,
- String firstName,
- String lastName)
+ String role)
{
if (!userService.userExists(adminUser, adminPassword, userName))
{
- userService.create(adminUser, adminPassword, userName, password, email, firstName, lastName);
+ dataUser.createUser(userName, password);
+
}
assignRoleToUser(adminUser, adminPassword, userName, role);
}
diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/DispositionScheduleService.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/DispositionScheduleService.java
index 930e8811e8..9fa6db0860 100644
--- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/DispositionScheduleService.java
+++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/DispositionScheduleService.java
@@ -31,7 +31,7 @@ import java.util.HashMap;
import org.alfresco.rest.core.v0.BaseAPI;
import org.alfresco.rest.v0.RecordCategoriesAPI;
-import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.data.DataUserAIS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -48,7 +48,7 @@ public class DispositionScheduleService extends BaseAPI
private RecordCategoriesAPI recordCategoriesAPI;
@Autowired
- private DataUser dataUser;
+ private DataUserAIS dataUser;
/**
* Helper method for adding a retain after period step
diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/RMAuditService.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/RMAuditService.java
index 3a8d4f4fc2..8a4e1fefe4 100644
--- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/RMAuditService.java
+++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/RMAuditService.java
@@ -35,7 +35,7 @@ import java.util.List;
import org.alfresco.rest.rm.community.model.audit.AuditEntry;
import org.alfresco.rest.rm.community.model.audit.AuditEvents;
import org.alfresco.rest.v0.RMAuditAPI;
-import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.data.DataUserAIS;
import org.alfresco.utility.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -54,7 +54,7 @@ public class RMAuditService
private RMAuditAPI rmAuditAPI;
@Autowired
- private DataUser dataUser;
+ private DataUserAIS dataUser;
/**
* Clear the list of audit entries as admin user.
diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/RoleService.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/RoleService.java
index a62b24ccf8..afecd9c92b 100644
--- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/RoleService.java
+++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/RoleService.java
@@ -40,6 +40,7 @@ import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.v0.RMRolesAndActionsAPI;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.data.DataUserAIS;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
@@ -60,7 +61,7 @@ public class RoleService
@Autowired
@Getter (value = PROTECTED)
- private DataUser dataUser;
+ private DataUserAIS dataUser;
@Autowired
@Getter (value = PROTECTED)
diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java
index 720a6fc662..1b57359633 100644
--- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java
+++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java
@@ -75,7 +75,6 @@ import org.alfresco.rest.rm.community.model.transfercontainer.TransferContainer;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainer;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildEntry;
-import org.alfresco.rest.rm.community.model.user.UserPermissions;
import org.alfresco.rest.rm.community.requests.gscore.api.RMSiteAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
@@ -85,7 +84,7 @@ import org.alfresco.rest.search.SearchNodeModel;
import org.alfresco.rest.search.SearchRequest;
import org.alfresco.rest.v0.SearchAPI;
import org.alfresco.utility.Utility;
-import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.data.DataUserAIS;
import org.alfresco.utility.model.ContentModel;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FolderModel;
@@ -111,7 +110,7 @@ public class BaseRMRestTest extends RestTest
@Autowired
@Getter (value = PROTECTED)
- private DataUser dataUser;
+ protected DataUserAIS dataUser;
@Autowired
@Getter(value = PROTECTED)
diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-v35-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-v35-context.xml
new file mode 100644
index 0000000000..63ccdb75e8
--- /dev/null
+++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-v35-context.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/version.properties b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/version.properties
index 6830ad62fe..a8d3e2c6b3 100644
--- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/version.properties
+++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/version.properties
@@ -1,3 +1,3 @@
# RM Schema number
-version.rm.schema=3300
+version.rm.schema=3500
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v35/RMv35HoldNewChildAssocPatch.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v35/RMv35HoldNewChildAssocPatch.java
new file mode 100644
index 0000000000..0b620d07df
--- /dev/null
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v35/RMv35HoldNewChildAssocPatch.java
@@ -0,0 +1,127 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2021 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.patch.v35;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
+import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
+import org.alfresco.module.org_alfresco_module_rm.patch.AbstractModulePatch;
+import org.alfresco.repo.policy.BehaviourFilter;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+
+/**
+ * Patch to create new hold child association to link the record to the hold
+ *
+ * See: https://alfresco.atlassian.net/browse/APPS-659
+ *
+ *
+ * @since 3.5
+ */
+public class RMv35HoldNewChildAssocPatch extends AbstractModulePatch
+{
+ /**
+ * File plan service interface
+ */
+ private FilePlanService filePlanService;
+
+ /**
+ * Hold service interface.
+ */
+ private HoldService holdService;
+
+ /**
+ * Interface for public and internal node and store operations.
+ */
+ private NodeService nodeService;
+
+ private BehaviourFilter behaviourFilter;
+
+ /**
+ * Setter for fileplanservice
+ * @param filePlanService File plan service interface
+ */
+ public void setFilePlanService(FilePlanService filePlanService)
+ {
+ this.filePlanService = filePlanService;
+ }
+
+ /**
+ * Setter for hold service
+ * @param holdService Hold service interface.
+ */
+ public void setHoldService(HoldService holdService)
+ {
+ this.holdService = holdService;
+ }
+
+ /**
+ * Setter for node service
+ * @param nodeService Interface for public and internal node and store operations.
+ */
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ public BehaviourFilter getBehaviourFilter()
+ {
+ return behaviourFilter;
+ }
+
+ public void setBehaviourFilter(BehaviourFilter behaviourFilter)
+ {
+ this.behaviourFilter = behaviourFilter;
+ }
+
+ @Override
+ public void applyInternal()
+ {
+ behaviourFilter.disableBehaviour(ContentModel.ASPECT_AUDITABLE);
+ behaviourFilter.disableBehaviour(ContentModel.ASPECT_VERSIONABLE);
+ try
+ {
+ for (NodeRef filePlan : filePlanService.getFilePlans())
+ {
+ for (NodeRef hold : holdService.getHolds(filePlan))
+ {
+ for (ChildAssociationRef ref : nodeService.getChildAssocs(hold))
+ {
+ holdService.removeFromHold(hold, ref.getChildRef());
+ holdService.addToHold(hold, ref.getChildRef());
+ }
+ }
+ }
+ }
+ finally
+ {
+ behaviourFilter.enableBehaviour(ContentModel.ASPECT_AUDITABLE);
+ behaviourFilter.enableBehaviour(ContentModel.ASPECT_VERSIONABLE);
+ }
+ }
+}
diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/patch/v35/RMv35HoldNewChildAssocPatchUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/patch/v35/RMv35HoldNewChildAssocPatchUnitTest.java
new file mode 100644
index 0000000000..01b04de73d
--- /dev/null
+++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/patch/v35/RMv35HoldNewChildAssocPatchUnitTest.java
@@ -0,0 +1,158 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2021 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.patch.v35;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyMap;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
+import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
+import org.alfresco.repo.policy.BehaviourFilter;
+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 org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * RM V3.5 Create new hold child association to link the record to the hold
+ *
+ * @since 3.5
+ */
+public class RMv35HoldNewChildAssocPatchUnitTest
+{
+ @Mock
+ private FilePlanService mockFilePlanService;
+
+ @Mock
+ private HoldService mockHoldService;
+
+ @Mock
+ private NodeService mockNodeService;
+
+ @Mock
+ private BehaviourFilter mockBehaviourFilter;
+
+ @InjectMocks
+ private RMv35HoldNewChildAssocPatch patch;
+
+ private NodeRef filePlanRef, holdRef, heldItemRef;
+ private Set fileplans;
+ private List holds;
+
+ @Mock
+ private ChildAssociationRef childAssociationRef;
+
+ private List childAssocs;
+
+ @Before
+ public void setUp()
+ {
+ MockitoAnnotations.initMocks(this);
+ filePlanRef = new NodeRef("workspace://SpacesStore/filePlan");
+ holdRef = new NodeRef("workspace://SpacesStore/hold");
+ heldItemRef = new NodeRef("workspace://SpacesStore/heldItem");
+ fileplans = new HashSet<>();
+ fileplans.add(filePlanRef);
+ holds = new ArrayList<>();
+ holds.add(holdRef);
+ childAssocs = new ArrayList<>();
+ childAssocs.add(childAssociationRef);
+ }
+
+ /**
+ * Test held items are removed from a hold and re-add to make sure the association is correct
+ */
+ @Test
+ public void testAHoldIsRemovedAndReplacedDuringUpgrade()
+ {
+ when(mockFilePlanService.getFilePlans()).thenReturn(fileplans);
+ when(mockHoldService.getHolds(filePlanRef)).thenReturn(holds);
+ when(childAssociationRef.getChildRef()).thenReturn(heldItemRef);
+ when(mockNodeService.getChildAssocs(holdRef)).thenReturn(childAssocs);
+ patch.applyInternal();
+ verify(mockHoldService, times(1)).removeFromHold(holdRef, heldItemRef);
+ verify(mockHoldService, times(1)).addToHold(holdRef, heldItemRef);
+ }
+
+ @Test
+ public void patchRunWithSuccessWhenNoHoldChilds()
+ {
+ List holdList = new ArrayList<>();
+ holdList.add(holdRef);
+ when(childAssociationRef.getChildRef()).thenReturn(heldItemRef);
+ when(mockNodeService.getChildAssocs(holdRef)).thenReturn(new ArrayList<>());
+ patch.applyInternal();
+
+ verify(mockHoldService, times(0)).removeFromHold(holdRef, heldItemRef);
+ verify(mockHoldService, times(0)).addToHold(holdRef, heldItemRef);
+
+ }
+
+ @Test
+ public void patchRunWithSuccessWhenNoHolds()
+ {
+ //no holds
+ List holdList = new ArrayList<>();
+ when(mockFilePlanService.getFilePlans()).thenReturn(fileplans);
+ when(mockHoldService.getHolds(filePlanRef)).thenReturn(holdList);
+ patch.applyInternal();
+
+ verify(mockHoldService, times(0)).removeFromHold(holdRef, heldItemRef);
+ verify(mockHoldService, times(0)).addToHold(holdRef, heldItemRef);
+ }
+
+ @Test
+ public void patchRunWithSuccessWhenNoFilePlan()
+ {
+ // given
+ doReturn(Collections.EMPTY_SET).when(mockFilePlanService).getFilePlans();
+
+ // when
+ patch.applyInternal();
+
+ // then
+ verifyZeroInteractions(mockHoldService);
+ verify(mockNodeService, times(0)).addAspect(any(NodeRef.class), any(QName.class), anyMap());
+ }
+}