mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-29 15:21:53 +00:00
Compare commits
60 Commits
20.19
...
dev-swapni
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01d907a3e5 | ||
|
|
9ec4323b76 | ||
|
|
c954f87706 | ||
|
|
6572baf8e1 | ||
|
|
f295838c66 | ||
|
|
1be88222e1 | ||
|
|
ba7be5999b | ||
|
|
8503b2c96c | ||
|
|
f43806b9f4 | ||
|
|
1eebb8ec12 | ||
|
|
008b340851 | ||
|
|
6d3e249149 | ||
|
|
bf276c60d6 | ||
|
|
54be23513a | ||
|
|
fa0fdff8d4 | ||
|
|
c37b26e678 | ||
|
|
b5e13e253a | ||
|
|
5b5164420f | ||
|
|
17c09efb93 | ||
|
|
f96304bd28 | ||
|
|
499f679c8c | ||
|
|
80c6a0127d | ||
|
|
74e44acb1c | ||
|
|
f4d66debea | ||
|
|
af838043c9 | ||
|
|
1245647a9f | ||
|
|
fe35f312bb | ||
|
|
a5f16f1b11 | ||
|
|
38a9f6d3e1 | ||
|
|
dc512e5ab0 | ||
|
|
5c8db99231 | ||
|
|
e39a97ed8d | ||
|
|
ad0ad081c6 | ||
|
|
8b9513ca8f | ||
|
|
5b3582c051 | ||
|
|
ccba1768bd | ||
|
|
f03790e278 | ||
|
|
2c979ea71e | ||
|
|
227c74a8bd | ||
|
|
24aa64c165 | ||
|
|
183873166c | ||
|
|
1c9419d635 | ||
|
|
17b04d7321 | ||
|
|
fe5faa3263 | ||
|
|
63b0ff8cf4 | ||
|
|
15c99b0c10 | ||
|
|
0f24f453c8 | ||
|
|
03ce7e37d4 | ||
|
|
1a5740eec1 | ||
|
|
f55602842d | ||
|
|
7819e29bcc | ||
|
|
91031ca72a | ||
|
|
32314480a1 | ||
|
|
f49b7a393f | ||
|
|
d32ba12405 | ||
|
|
7430c80a41 | ||
|
|
af2c11063b | ||
|
|
0d74540b2b | ||
|
|
d68ceb1a4b | ||
|
|
379f65db0d |
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.rest.rm.community.rules;
|
||||
|
||||
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
|
||||
import org.alfresco.rest.rm.community.model.record.Record;
|
||||
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
|
||||
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
|
||||
import org.alfresco.rest.rm.community.model.rules.ActionsOnRule;
|
||||
import org.alfresco.rest.rm.community.model.rules.RuleDefinition;
|
||||
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
|
||||
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
|
||||
import org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI;
|
||||
import org.alfresco.rest.rm.community.smoke.CreateCategoriesTests;
|
||||
import org.alfresco.rest.v0.RulesAPI;
|
||||
import org.alfresco.test.AlfrescoTest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
|
||||
import static org.alfresco.rest.rm.community.base.TestData.ELECTRONIC_RECORD_NAME;
|
||||
import static org.alfresco.rest.rm.community.base.TestData.NONELECTRONIC_RECORD_NAME;
|
||||
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
|
||||
import static org.alfresco.rest.rm.community.utils.CoreUtil.createBodyForMoveCopy;
|
||||
import static org.alfresco.rest.rm.community.utils.CoreUtil.toContentModel;
|
||||
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.*;
|
||||
import static org.alfresco.utility.data.RandomData.getRandomName;
|
||||
import static org.alfresco.utility.report.log.Step.STEP;
|
||||
import static org.springframework.http.HttpStatus.*;
|
||||
|
||||
public class CopyToRuleOnFoldersTest extends BaseRMRestTest {
|
||||
|
||||
private RecordCategory category;
|
||||
private RecordCategoryChild folder1,folder2;
|
||||
private final static String title = "Run in background";
|
||||
private final String TEST_PREFIX = generateTestPrefix(CopyToRuleOnFoldersTest.class);
|
||||
private final String RM_ADMIN = TEST_PREFIX + "rm_admin";
|
||||
private final String electronicRecord = TEST_PREFIX + "record_electronic_for_copyTo";
|
||||
private final String nonElectronicRecord = TEST_PREFIX + "record_non_electronic_for_copyTo";
|
||||
|
||||
@Autowired
|
||||
private RulesAPI rulesAPI;
|
||||
|
||||
@Test
|
||||
@AlfrescoTest(jira = "RM-2994")
|
||||
public void copyToRuleOnFoldersTest()
|
||||
{
|
||||
|
||||
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description1")
|
||||
.runInBackground(true).title(title)
|
||||
.actions(Collections.singletonList(ActionsOnRule.COPY_TO.getActionValue()));
|
||||
|
||||
|
||||
STEP("Create the RM site if doesn't exist");
|
||||
createRMSiteIfNotExists();
|
||||
|
||||
STEP("Create record categories and record folders");
|
||||
category= createRootCategory(getRandomName("recordCategory"));
|
||||
String folder1 = createCategoryFolderInFilePlan().getId();
|
||||
String folder2 = createCategoryFolderInFilePlan().getId();
|
||||
|
||||
// create a rule on folder
|
||||
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + folder1, ruleDefinition);
|
||||
|
||||
// create electronic record in record folder
|
||||
String electronicRecordId = createElectronicRecord(folder1, ELECTRONIC_RECORD_NAME).getId();
|
||||
assertStatusCode(CREATED);
|
||||
|
||||
// create non-electronic record in record folder
|
||||
String nonElectronicRecord = createElectronicRecord(folder1, NONELECTRONIC_RECORD_NAME).getId();
|
||||
assertStatusCode(CREATED);
|
||||
|
||||
// Move the electronic and non-electronic records from "Category with records"> "Folder with rule"
|
||||
// to "Copy Category with records" > "Folder with rule"
|
||||
getRestAPIFactory().getNodeAPI(toContentModel(folder1)).copy(createBodyForMoveCopy(category.getId()));
|
||||
getRestAPIFactory().getNodeAPI(toContentModel( electronicRecord)).move(createBodyForMoveCopy(folder2));
|
||||
getRestAPIFactory().getNodeAPI(toContentModel( nonElectronicRecord)).move(createBodyForMoveCopy(folder2));
|
||||
|
||||
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
|
||||
// Delete the record category
|
||||
RecordCategoryAPI recordCategoryAPI = getRestAPIFactory().getRecordCategoryAPI();
|
||||
String recordCategoryId = category.getId();
|
||||
recordCategoryAPI.deleteRecordCategory(recordCategoryId);
|
||||
recordsAPI.deleteRecord(electronicRecord);
|
||||
recordsAPI.deleteRecord(nonElectronicRecord);
|
||||
assertStatusCode(NO_CONTENT);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.rest.rm.community.rules;
|
||||
|
||||
import org.alfresco.dataprep.CMISUtil;
|
||||
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
|
||||
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
|
||||
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
|
||||
import org.alfresco.rest.rm.community.model.rules.ActionsOnRule;
|
||||
import org.alfresco.rest.rm.community.model.rules.RuleDefinition;
|
||||
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildEntry;
|
||||
import org.alfresco.rest.rm.community.model.user.UserRoles;
|
||||
|
||||
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
|
||||
import org.alfresco.rest.rm.community.smoke.FileAsRecordTests;
|
||||
import org.alfresco.rest.v0.RulesAPI;
|
||||
import org.alfresco.rest.v0.service.RoleService;
|
||||
import org.alfresco.test.AlfrescoTest;
|
||||
import org.alfresco.utility.model.FileModel;
|
||||
import org.alfresco.utility.model.FolderModel;
|
||||
import org.alfresco.utility.model.UserModel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
|
||||
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
|
||||
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
|
||||
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
|
||||
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
|
||||
import static org.alfresco.utility.data.RandomData.getRandomName;
|
||||
import static org.alfresco.utility.report.log.Step.STEP;
|
||||
import static org.springframework.http.HttpStatus.CREATED;
|
||||
|
||||
@AlfrescoTest (jira = "APPS-36")
|
||||
public class FileAsRecordRuleTests extends BaseRMRestTest
|
||||
{
|
||||
private UserModel nonRMUser, rmManager;
|
||||
private RecordCategory category_manager, category_admin;
|
||||
private RecordCategoryChild folder_admin, folder_manager ;
|
||||
private static final String CATEGORY_MANAGER = "catManager" + generateTestPrefix(FileAsRecordTests.class);
|
||||
private static final String CATEGORY_ADMIN = "catAdmin" + generateTestPrefix(FileAsRecordTests.class);
|
||||
private static final String FOLDER_MANAGER = "recordFolder" + generateTestPrefix(FileAsRecordTests.class);
|
||||
private static final String FOLDER_ADMIN = "recordFolder" + generateTestPrefix(FileAsRecordTests.class);
|
||||
private FolderModel testFolder;
|
||||
private FileModel document,inPlaceRecord;
|
||||
|
||||
|
||||
@Autowired
|
||||
private RoleService roleService;
|
||||
@Autowired
|
||||
private RulesAPI rulesAPI;
|
||||
|
||||
/**
|
||||
* Create preconditions:
|
||||
* 1. RM site is created
|
||||
* 2. Two users: user without RM role and a user with RM manager role
|
||||
* 3. Two Record categories with one folder each
|
||||
* 4. User with RM MANAGER role has Filling permission over one category
|
||||
* 5. A collaboration folder with rule set to declare and file as record to a record folder
|
||||
**/
|
||||
@BeforeClass(alwaysRun = true)
|
||||
public void preconditionForDeclareFileAsRecordRuleTests()
|
||||
{
|
||||
STEP("Create the RM site if doesn't exist");
|
||||
createRMSiteIfNotExists();
|
||||
|
||||
STEP("Create a user");
|
||||
nonRMUser = dataUser.createRandomTestUser("testUser");
|
||||
|
||||
STEP("Create a collaboration site");
|
||||
testSite = dataSite.usingUser(nonRMUser).createPublicRandomSite();
|
||||
|
||||
STEP("Create two categories with two folders");
|
||||
category_manager = createRootCategory(CATEGORY_MANAGER);
|
||||
category_admin = createRootCategory(CATEGORY_ADMIN);
|
||||
folder_admin = createFolder(category_admin.getId(),FOLDER_ADMIN);
|
||||
folder_manager = createFolder(category_manager.getId(),FOLDER_MANAGER);
|
||||
|
||||
STEP("Create an rm user and give filling permission over CATEGORY_MANAGER record category");
|
||||
RecordCategory recordCategory = new RecordCategory().builder()
|
||||
.id(category_manager.getId()).build();
|
||||
|
||||
rmManager = roleService.createCollaboratorWithRMRoleAndPermission(testSite, recordCategory,
|
||||
UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
|
||||
|
||||
STEP("Create a collaboration folder with a rule set to declare and file as record to a record folder");
|
||||
RecordCategoryChild folderWithRule = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
|
||||
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
|
||||
.applyToChildren(true)
|
||||
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
|
||||
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + folderWithRule.getId(), ruleDefinition);
|
||||
|
||||
assertStatusCode(CREATED);
|
||||
}
|
||||
/**
|
||||
* Given I am a user that can create a rule on a folder in a collaboration site
|
||||
* When I am creating the rule
|
||||
* Then I have the option of adding a "Declare and File as Record" action to the rule
|
||||
* <p>
|
||||
* Given I am creating a rule
|
||||
* When I add the "Declare and File as Record" action to the rule
|
||||
* Then I am able to select the record folder I want the declared record to be filed to
|
||||
* <p>
|
||||
* Given I am configuring a "Declare and File as Record" action within a rule
|
||||
* And I have at least one records management role (eg RM User)
|
||||
* When I am selecting the record folder location to file the declared record to
|
||||
* Then I see the record folders in the file plan that I have file access to as the creator of the record
|
||||
**/
|
||||
@Test
|
||||
public void declareAsRecordRuleAsRMUserWithFilingPermissions() {
|
||||
STEP("Create a collaboration folder");
|
||||
testFolder = dataContent.usingSite(testSite)
|
||||
.usingUser(rmManager)
|
||||
.createFolder();
|
||||
|
||||
STEP("Create a rule with Declare as Record action and check that user can select a record folder.");
|
||||
RecordCategory recordCategory = new RecordCategory().builder()
|
||||
.id(category_manager.getId()).build();
|
||||
RecordCategoryChild folderWithRule = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
|
||||
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
|
||||
.applyToChildren(true)
|
||||
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
|
||||
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + folderWithRule.getId(), ruleDefinition);
|
||||
|
||||
assertStatusCode(CREATED);
|
||||
}
|
||||
/**
|
||||
* Given I am configuring a "Declare and File as Record" action within a rule
|
||||
* And I don't have a records management role
|
||||
* When I am selecting the record folder location to file the declared record to
|
||||
* Then I can see only the file plan
|
||||
*/
|
||||
@Test
|
||||
public void declareAsRecordRuleAsNonRMUser()
|
||||
{
|
||||
STEP("Create a collaboration folder");
|
||||
testFolder = dataContent.usingSite(testSite)
|
||||
.usingUser(nonRMUser)
|
||||
.createFolder();
|
||||
|
||||
STEP("Create a rule with Declare as Record action and check that user can select a record folder.");
|
||||
RecordCategory recordCategory = new RecordCategory().builder()
|
||||
.id(category_manager.getId()).build();
|
||||
|
||||
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
|
||||
.applyToChildren(true)
|
||||
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
|
||||
rulesAPI.createRule(nonRMUser.getUsername(), nonRMUser.getPassword(), NODE_PREFIX + testFolder.getNodeRef(), ruleDefinition);
|
||||
|
||||
assertStatusCode(CREATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given I have not selected a record folder location
|
||||
* When the rule is triggered
|
||||
* Then the file is declared as record to the UnFiled Records folder
|
||||
*/
|
||||
@Test
|
||||
public void triggerDeclareToUnfiledRuleAsNonRMUser()
|
||||
{
|
||||
STEP("Create a collaboration folder with a rule set to declare and file as record without a record folder location");
|
||||
|
||||
RecordCategory recordCategory = new RecordCategory().builder()
|
||||
.id(category_manager.getId()).build();
|
||||
|
||||
RecordCategoryChild folderWithRule = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
|
||||
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
|
||||
.applyToChildren(true)
|
||||
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
|
||||
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + folderWithRule.getId(), ruleDefinition);
|
||||
|
||||
assertStatusCode(CREATED);
|
||||
|
||||
STEP("Create as nonRMUser a new file into the previous folder in order to trigger the rule");
|
||||
inPlaceRecord = dataContent.usingUser(nonRMUser).usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
|
||||
// Verify that declared record is in Unfilled Records Folder
|
||||
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
|
||||
List<UnfiledContainerChildEntry> matchingRecords = unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
|
||||
.getEntries()
|
||||
.stream()
|
||||
.filter(e -> e.getEntry().getId().equals(inPlaceRecord.getNodeRefWithoutVersion()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@AfterClass(alwaysRun = true)
|
||||
public void cleanupDeclareAsRecordRuleTests()
|
||||
{
|
||||
STEP("Delete the collaboration site");
|
||||
dataSite.usingUser(nonRMUser).deleteSite(testSite);
|
||||
|
||||
STEP("Delete Users");
|
||||
dataUser.deleteUser(nonRMUser);
|
||||
dataUser.deleteUser(rmManager);
|
||||
|
||||
STEP("Delete categories");
|
||||
getRestAPIFactory().getFilePlansAPI().getRootRecordCategories(FILE_PLAN_ALIAS).getEntries().forEach(recordCategoryEntry ->
|
||||
deleteRecordCategory(recordCategoryEntry.getEntry().getId()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.rest.rm.community.rules;
|
||||
|
||||
import org.alfresco.dataprep.CMISUtil;
|
||||
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
|
||||
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
|
||||
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
|
||||
import org.alfresco.rest.rm.community.model.rules.ActionsOnRule;
|
||||
import org.alfresco.rest.rm.community.model.rules.RuleDefinition;
|
||||
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildEntry;
|
||||
import org.alfresco.rest.rm.community.model.user.UserRoles;
|
||||
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
|
||||
import org.alfresco.rest.rm.community.smoke.FileAsRecordTests;
|
||||
import org.alfresco.rest.v0.RulesAPI;
|
||||
import org.alfresco.rest.v0.service.RoleService;
|
||||
import org.alfresco.utility.model.FileModel;
|
||||
import org.alfresco.utility.model.FileType;
|
||||
import org.alfresco.utility.model.FolderModel;
|
||||
import org.alfresco.utility.model.UserModel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
|
||||
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
|
||||
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
|
||||
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
|
||||
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
|
||||
import static org.alfresco.utility.data.RandomData.getRandomName;
|
||||
import static org.alfresco.utility.report.log.Step.STEP;
|
||||
import static org.springframework.http.HttpStatus.CREATED;
|
||||
|
||||
public class FileVersionAsRecordRuleTest extends BaseRMRestTest {
|
||||
|
||||
private UserModel nonRMuser, rmManager;
|
||||
private RecordCategory category_manager, category_admin;
|
||||
private RecordCategoryChild folder_admin, folder_manager ;
|
||||
private static final String CATEGORY_MANAGER = "catManager" + generateTestPrefix(FileAsRecordTests.class);
|
||||
private static final String CATEGORY_ADMIN = "catAdmin" + generateTestPrefix(FileAsRecordTests.class);
|
||||
private static final String FOLDER_MANAGER = "recordFolder" + generateTestPrefix(FileAsRecordTests.class);
|
||||
private static final String FOLDER_ADMIN = "recordFolder" + generateTestPrefix(FileAsRecordTests.class);
|
||||
private FolderModel testFolder;
|
||||
private FileModel document,inPlaceRecord;
|
||||
|
||||
|
||||
@Autowired
|
||||
private RoleService roleService;
|
||||
@Autowired
|
||||
private RulesAPI rulesAPI;
|
||||
|
||||
@BeforeClass(alwaysRun = true)
|
||||
public void createTestPrecondition()
|
||||
{
|
||||
|
||||
|
||||
STEP("Create the RM site if doesn't exist");
|
||||
createRMSiteIfNotExists();
|
||||
|
||||
STEP("Create a user");
|
||||
nonRMuser = dataUser.createRandomTestUser("testUser");
|
||||
|
||||
STEP("Create a collaboration site");
|
||||
testSite = dataSite.usingUser(nonRMuser).createPublicRandomSite();
|
||||
|
||||
STEP("Create a document with the user without RM role");
|
||||
document = dataContent.usingSite(testSite)
|
||||
.usingUser(nonRMuser)
|
||||
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
|
||||
STEP("Create two categories with two folders");
|
||||
category_manager = createRootCategory(CATEGORY_MANAGER);
|
||||
category_admin = createRootCategory(CATEGORY_ADMIN);
|
||||
folder_admin = createFolder(category_admin.getId(),FOLDER_ADMIN);
|
||||
folder_manager = createFolder(category_manager.getId(),FOLDER_MANAGER);
|
||||
|
||||
|
||||
STEP("Create an rm user and give filling permission over CATEGORY_MANAGER record category");
|
||||
RecordCategory recordCategory = new RecordCategory().builder()
|
||||
.id(category_manager.getId())
|
||||
.build();
|
||||
rmManager = roleService.createCollaboratorWithRMRoleAndPermission(testSite, recordCategory,
|
||||
UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING);
|
||||
|
||||
|
||||
|
||||
STEP("Create a collaboration folder with a rule set to declare and file version as record to a record folder");
|
||||
RecordCategoryChild folderWithRule = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
|
||||
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
|
||||
.applyToChildren(true)
|
||||
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
|
||||
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX + folderWithRule.getId(), ruleDefinition);
|
||||
|
||||
assertStatusCode(CREATED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void declareVersionAsRecordRuleAsRMUserWithFilingPermissions()
|
||||
{
|
||||
|
||||
STEP("Create a collaboration folder");
|
||||
testFolder = dataContent.usingSite(testSite)
|
||||
.usingUser(rmManager)
|
||||
.createFolder();
|
||||
|
||||
STEP("Create a rule with Declare as Record action and check that user can select a record folder.");
|
||||
RecordCategory recordCategory = new RecordCategory().builder()
|
||||
.id(category_manager.getId()).build();
|
||||
RecordCategoryChild folderWithRule = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
|
||||
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
|
||||
.applyToChildren(true)
|
||||
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
|
||||
rulesAPI.createRule(rmManager.getUsername(), rmManager.getPassword(), NODE_PREFIX + testFolder.getNodeRef(), ruleDefinition);
|
||||
|
||||
assertStatusCode(CREATED);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void declareVersionAsRecordRuleAsNonRMUser()
|
||||
{
|
||||
|
||||
STEP("Create a collaboration folder");
|
||||
testFolder = dataContent.usingSite(testSite)
|
||||
.usingUser(nonRMuser)
|
||||
.createFolder();
|
||||
|
||||
STEP("Create a rule with Declare as Record action and check that user can select a record folder.");
|
||||
RecordCategory recordCategory = new RecordCategory().builder()
|
||||
.id(category_manager.getId()).build();
|
||||
|
||||
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
|
||||
.applyToChildren(true)
|
||||
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
|
||||
rulesAPI.createRule(nonRMuser.getUsername(), nonRMuser.getPassword(), NODE_PREFIX + testFolder.getNodeRef(), ruleDefinition);
|
||||
|
||||
assertStatusCode(CREATED);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void triggerDeclareToUnfiledRuleAsNonRMUser() throws Exception {
|
||||
|
||||
STEP("Create a collaboration folder with a rule set to declare and file as record without a record folder location");
|
||||
|
||||
|
||||
FileModel inplaceRecord = dataContent.usingSite(testSite).usingUser(nonRMuser)
|
||||
.createContent(new FileModel("declareAndFileToIntoUnfiledRecordFolder",
|
||||
FileType.TEXT_PLAIN));
|
||||
|
||||
RecordCategory recordCategory = new RecordCategory().builder()
|
||||
.id(category_manager.getId()).build();
|
||||
|
||||
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description")
|
||||
.applyToChildren(true)
|
||||
.actions(Collections.singletonList(ActionsOnRule.DECLARE_AS_RECORD.getActionValue()));
|
||||
rulesAPI.createRule(nonRMuser.getUsername(), nonRMuser.getPassword(), NODE_PREFIX + inplaceRecord.getNodeRef(), ruleDefinition);
|
||||
|
||||
assertStatusCode(CREATED);
|
||||
|
||||
STEP("Create as nonRMuser a new file into the previous folder in order to trigger the rule");
|
||||
inPlaceRecord = dataContent.usingUser(nonRMuser).usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
|
||||
// verify the declared record is in Unfilled Records folder
|
||||
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
|
||||
List<UnfiledContainerChildEntry> matchingRecords = unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
|
||||
.getEntries()
|
||||
.stream()
|
||||
.filter(e -> e.getEntry().getId().equals(inplaceRecord.getNodeRefWithoutVersion()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@AfterClass(alwaysRun = true)
|
||||
public void cleanupDeclareVersionAsRecordRuleTests()
|
||||
{
|
||||
|
||||
STEP("Delete the collaboration site");
|
||||
dataSite.usingUser(nonRMuser).deleteSite(testSite);
|
||||
|
||||
STEP("Delete Users");
|
||||
dataUser.deleteUser(nonRMuser);
|
||||
dataUser.deleteUser(rmManager);
|
||||
|
||||
|
||||
STEP("Delete categories");
|
||||
getRestAPIFactory().getFilePlansAPI().getRootRecordCategories(FILE_PLAN_ALIAS).getEntries().forEach(recordCategoryEntry ->
|
||||
deleteRecordCategory(recordCategoryEntry.getEntry().getId()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.rest.rm.community.rules;
|
||||
|
||||
import org.alfresco.rest.model.RestNodeModel;
|
||||
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
|
||||
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
|
||||
import org.alfresco.rest.rm.community.model.record.Record;
|
||||
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
|
||||
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
|
||||
import org.alfresco.rest.rm.community.model.rules.ActionsOnRule;
|
||||
import org.alfresco.rest.rm.community.model.rules.ConditionsOnRule;
|
||||
import org.alfresco.rest.rm.community.model.rules.RuleDefinition;
|
||||
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainer;
|
||||
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildEntry;
|
||||
import org.alfresco.rest.rm.community.model.user.UserRoles;
|
||||
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
|
||||
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
|
||||
import org.alfresco.rest.search.RestRequestQueryModel;
|
||||
import org.alfresco.rest.v0.HoldsAPI;
|
||||
import org.alfresco.rest.v0.RecordsAPI;
|
||||
import org.alfresco.rest.v0.RulesAPI;
|
||||
import org.alfresco.rest.v0.service.RoleService;
|
||||
import org.alfresco.utility.model.UserModel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.lang.Integer.MAX_VALUE;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX;
|
||||
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
|
||||
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
|
||||
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
|
||||
import static org.alfresco.rest.rm.community.utils.CoreUtil.createBodyForMoveCopy;
|
||||
import static org.alfresco.rest.rm.community.utils.CoreUtil.toContentModel;
|
||||
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.*;
|
||||
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
|
||||
import static org.alfresco.utility.data.RandomData.getRandomName;
|
||||
import static org.alfresco.utility.report.log.Step.STEP;
|
||||
import static org.springframework.http.HttpStatus.*;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
|
||||
public class MoveToRuleOnFoldersTest extends BaseRMRestTest{
|
||||
|
||||
|
||||
private RecordCategoryChild recordFolder2;
|
||||
private RecordCategoryChild recordFolder1;
|
||||
private String nonElectronicId;
|
||||
|
||||
public Record electronicRecord;
|
||||
|
||||
private String ruleType = ConditionsOnRule.UPDATE.getWhenConditionValue();
|
||||
private UserModel rmAdmin;
|
||||
public RecordCategory RecordCategoryOne;
|
||||
private RecordCategoryChild recordFolder;
|
||||
public static final String RECORD_FOLDER_ONE = "record-folder-one";
|
||||
private final String TEST_PREFIX = generateTestPrefix(MoveToRuleOnFoldersTest.class);
|
||||
|
||||
private final String RECORD_CATEGORY_ONE = TEST_PREFIX + "category";
|
||||
|
||||
private final String recordName = "Test record";
|
||||
private final String recordTitle = recordName + " title";
|
||||
private final String recordDescription = recordName + " description";
|
||||
private Record nonElectrinicRecordModel;
|
||||
private RecordFolderAPI recordFolderAPI;
|
||||
public String title,description,box,file,shelf,storageLocation,name;
|
||||
@Autowired
|
||||
private RulesAPI rulesAPI;
|
||||
@Autowired
|
||||
private HoldsAPI holdsAPI;
|
||||
|
||||
@Autowired
|
||||
private RoleService roleService;
|
||||
|
||||
@Autowired
|
||||
public RecordsAPI recordsAPI;
|
||||
|
||||
|
||||
@BeforeClass(alwaysRun = true)
|
||||
public void precondition()
|
||||
{
|
||||
//create RM site
|
||||
createRMSiteIfNotExists();
|
||||
rmAdmin = roleService.createUserWithRMRole(UserRoles.ROLE_RM_ADMIN.roleId);
|
||||
//create root category, create folders , add electronic and non electronic records
|
||||
RecordCategoryOne = createRootCategory(RECORD_CATEGORY_ONE);
|
||||
recordFolder1=createRecordFolder(RecordCategoryOne.getId(), getRandomName("recFolder"));
|
||||
// recordFolder1_id = createRecordFolder(RecordCategoryOne.getId(), getRandomName("recFolder")).getId();
|
||||
recordFolder2 = createFolder(getAdminUser(),RecordCategoryOne.getId(),getRandomName("recFolder"));
|
||||
|
||||
|
||||
STEP("CREATE ELECTRONIC RECORD");
|
||||
recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
|
||||
electronicRecord = recordFolderAPI.createRecord(createElectronicRecordModel(), recordFolder1.getId(), getFile(IMAGE_FILE));
|
||||
STEP("Check the electronic record has been created");
|
||||
assertStatusCode(CREATED);
|
||||
|
||||
|
||||
STEP("Create a non-electronic record by completing some of the fields");
|
||||
// Use these properties for non-electronic record to be created
|
||||
title = "Title " + getRandomAlphanumeric();
|
||||
description = "Description " + getRandomAlphanumeric();
|
||||
box = "Box "+ getRandomAlphanumeric();
|
||||
file = "File " + getRandomAlphanumeric();
|
||||
shelf = "Shelf " + getRandomAlphanumeric();
|
||||
storageLocation = "Storage Location " + getRandomAlphanumeric();
|
||||
name = "Record " + getRandomAlphanumeric();
|
||||
Random random = new Random();
|
||||
Integer numberOfCopies = random.nextInt(MAX_VALUE);
|
||||
Integer physicalSize = random.nextInt(MAX_VALUE);
|
||||
|
||||
// Set values of all available properties for the non electronic records
|
||||
nonElectrinicRecordModel = createFullNonElectronicRecordModel(name, title, description, box, file, shelf, storageLocation, numberOfCopies, physicalSize);
|
||||
// Create non-electronic record
|
||||
nonElectronicId = recordFolderAPI.createRecord(nonElectrinicRecordModel, recordFolder1.getId()).getId();
|
||||
STEP("Check the non-electronic record has been created");
|
||||
assertStatusCode(CREATED);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void MoveToRuleFoldersTest()
|
||||
{
|
||||
|
||||
String CatName=RecordCategoryOne.getName();
|
||||
String folder2name=recordFolder2.getName();
|
||||
String recfolder2_path="/"+CatName+"/"+folder2name;
|
||||
|
||||
STEP("create a rule MOVE_TO for folder 1");
|
||||
RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title("name").description("description1")
|
||||
.runInBackground(true).title(title)
|
||||
.actions(Collections.singletonList(ActionsOnRule.MOVE_TO.getActionValue())).ruleType(ruleType).path(recfolder2_path);
|
||||
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX +recordFolder1.getId() , ruleDefinition);
|
||||
|
||||
|
||||
|
||||
STEP("Update metadata for Non-Electronic Record");
|
||||
updateRecordMetadata();
|
||||
|
||||
STEP("Delete ELECTRONIC AND NON-ELECTRONIC RECORDS IN FOLDER 2");
|
||||
org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
|
||||
recordsAPI.deleteRecord(electronicRecord.getId());
|
||||
assertStatusCode(NO_CONTENT);
|
||||
recordsAPI.deleteRecord(nonElectronicId);
|
||||
assertStatusCode(NO_CONTENT);
|
||||
|
||||
STEP("RULE CREATION FOR FOLDER 1 WITHOUT RUNNING IN BACKGROUND");
|
||||
|
||||
RuleDefinition ruleDefinition_notinbackground = RuleDefinition.createNewRule().title("name").description("description1")
|
||||
.runInBackground(false).title(title)
|
||||
.actions(Collections.singletonList(ActionsOnRule.MOVE_TO.getActionValue())).ruleType(ruleType).path(recfolder2_path);
|
||||
rulesAPI.createRule(getAdminUser().getUsername(), getAdminUser().getPassword(), NODE_PREFIX +recordFolder1.getId() , ruleDefinition);
|
||||
|
||||
STEP("CREATE ELECTRONIC AND NON-ELECTRONIC RECORDS");
|
||||
electronicRecord = recordFolderAPI.createRecord(createElectronicRecordModel(), recordFolder1.getId(), getFile(IMAGE_FILE));
|
||||
STEP("Check the electronic record has been created");
|
||||
assertStatusCode(CREATED);
|
||||
nonElectronicId = recordFolderAPI.createRecord(nonElectrinicRecordModel, recordFolder1.getId()).getId();
|
||||
STEP("Check the non-electronic record has been created");
|
||||
assertStatusCode(CREATED);
|
||||
|
||||
STEP("UPDATE METADATA");
|
||||
updateRecordMetadata();
|
||||
|
||||
STEP("CHECK IF ELECTRONIC AND NON-ELECTRONIC RECORDS MOVED TO FOLDER2");
|
||||
updateRecordMetadata();
|
||||
}
|
||||
|
||||
@AfterClass(alwaysRun = true)
|
||||
public void cleanMoveToRuleOnFoldersTest()
|
||||
{
|
||||
deleteRecordCategory(RecordCategoryOne.getId());
|
||||
|
||||
getDataUser().deleteUser(rmAdmin);
|
||||
}
|
||||
|
||||
private String getModifiedPropertyValue(String originalValue) {
|
||||
/* to be used to append to modifications */
|
||||
String MODIFIED_PREFIX = "modified_";
|
||||
return MODIFIED_PREFIX + originalValue;
|
||||
}
|
||||
private void updateRecordMetadata(){
|
||||
STEP("Update metadata for Non-Electronic Record");
|
||||
org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
|
||||
Record nonelecrecord = recordsAPI.getRecord(nonElectronicId);
|
||||
String nonelecnewName = getModifiedPropertyValue(nonElectrinicRecordModel.getName());
|
||||
String nonelecnewTitle = getModifiedPropertyValue(nonElectrinicRecordModel.getProperties().getTitle());
|
||||
String nonelecnewDescription = getModifiedPropertyValue(nonElectrinicRecordModel.getProperties().getDescription());
|
||||
recordsAPI.updateRecord(createRecordModel(nonelecnewName, nonelecnewDescription, nonelecnewTitle),nonelecrecord.getId());
|
||||
assertStatusCode(OK);
|
||||
|
||||
STEP("Update metadata for Electronic Record");
|
||||
Record elecrecord = recordsAPI.getRecord(electronicRecord.getId());
|
||||
String elecnewName = getModifiedPropertyValue(electronicRecord.getName());
|
||||
String elecnewTitle = getModifiedPropertyValue(electronicRecord.getProperties().getTitle());
|
||||
String elecnewDescription = getModifiedPropertyValue(electronicRecord.getProperties().getDescription());
|
||||
recordsAPI.updateRecord(createRecordModel(elecnewName, elecnewDescription, elecnewTitle),elecrecord.getId());
|
||||
assertStatusCode(OK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
SOLR6_TAG=2.0.5
|
||||
SOLR6_TAG=2.0.5.1
|
||||
POSTGRES_TAG=14.4
|
||||
ACTIVEMQ_TAG=5.17.1-jre11-rockylinux8
|
||||
|
||||
@@ -175,6 +175,10 @@
|
||||
<property name="nodesModelFactory" ref="nodesModelFactory" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.alfresco.rm.rest.api.events.EventEntityResource">
|
||||
<property name="recordsManagementEventService" ref="RecordsManagementEventService" />
|
||||
</bean>
|
||||
|
||||
<!-- extended sites bean definition -->
|
||||
<bean id="rm.sites" class="org.alfresco.rm.rest.api.impl.RMSitesImpl" parent="sites">
|
||||
<property name="siteSurfConfig" ref="rm.siteSurfConfig" />
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.rm.rest.api.events;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEventService;
|
||||
import org.alfresco.rest.framework.WebApiDescription;
|
||||
import org.alfresco.rest.framework.resource.EntityResource;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Paging;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.rm.rest.api.model.EventInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Event entity resource
|
||||
*/
|
||||
@EntityResource(name = "events", title = "Events")
|
||||
public class EventEntityResource implements EntityResourceAction.Read<EventInfo> {
|
||||
private RecordsManagementEventService recordsManagementEventService;
|
||||
|
||||
/**
|
||||
* Set the records management event service
|
||||
*
|
||||
* @param rmEventService Records management event service
|
||||
*/
|
||||
public void setRecordsManagementEventService(RecordsManagementEventService rmEventService)
|
||||
{
|
||||
this.recordsManagementEventService = rmEventService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@WebApiDescription(title = "Return a list of events")
|
||||
public CollectionWithPagingInfo<EventInfo> readAll(Parameters params)
|
||||
{
|
||||
Paging paging = params.getPaging();
|
||||
|
||||
List<EventInfo> eventInfoList = recordsManagementEventService.getEvents().stream()
|
||||
.map(EventInfo::fromRecordsManagementEvent)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
int totalCount = eventInfoList.size();
|
||||
boolean hasMoreItems = paging.getSkipCount() + paging.getMaxItems() < totalCount;
|
||||
return CollectionWithPagingInfo.asPaged(paging, eventInfoList.stream()
|
||||
.skip(paging.getSkipCount())
|
||||
.limit(paging.getMaxItems())
|
||||
.collect(Collectors.toList()), hasMoreItems, totalCount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
/**
|
||||
* Package info that defines the Information Governance Events REST API
|
||||
*/
|
||||
@WebApi(name="gs", scope=Api.SCOPE.PUBLIC, version=1)
|
||||
package org.alfresco.rm.rest.api.events;
|
||||
import org.alfresco.rest.framework.Api;
|
||||
import org.alfresco.rest.framework.WebApi;
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.rm.rest.api.model;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
|
||||
|
||||
/**
|
||||
* The EventInfo model to be exposed through REST API.
|
||||
*/
|
||||
public class EventInfo {
|
||||
private String id;
|
||||
private String name;
|
||||
private String type;
|
||||
|
||||
public static EventInfo fromRecordsManagementEvent(RecordsManagementEvent event)
|
||||
{
|
||||
EventInfo eventInfo = new EventInfo();
|
||||
if (event != null) {
|
||||
eventInfo.setName(event.getDisplayLabel());
|
||||
eventInfo.setId(event.getName());
|
||||
eventInfo.setType(event.getType());
|
||||
}
|
||||
return eventInfo;
|
||||
}
|
||||
|
||||
public EventInfo() {}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -38,6 +38,9 @@ tags:
|
||||
description: Retrieve and manage unfiled records containers
|
||||
- name: unfiled-record-folders
|
||||
description: Retrieve and manage unfiled record folders
|
||||
- name: events
|
||||
description: Retrieve and manage retention events
|
||||
|
||||
paths:
|
||||
## GS sites
|
||||
'/gs-sites':
|
||||
@@ -2091,7 +2094,172 @@ paths:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
'/events':
|
||||
get:
|
||||
tags:
|
||||
- events
|
||||
summary: List all available retention events
|
||||
description: |
|
||||
Gets the list of events that can be used by retention steps
|
||||
operationId: getAllEvents
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- $ref: '#/parameters/skipCountParam'
|
||||
- $ref: '#/parameters/maxItemsParam'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
schema:
|
||||
$ref: '#/definitions/EventPaging'
|
||||
'400':
|
||||
description: |
|
||||
Invalid parameter: value of **maxItems** or **skipCount** is invalid
|
||||
'401':
|
||||
description: Authentication failed
|
||||
default:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
|
||||
post:
|
||||
tags:
|
||||
- events
|
||||
summary: Create a new retention event
|
||||
description: |
|
||||
Creates a new event that can be used by retention schedules.
|
||||
operationId: createEvent
|
||||
parameters:
|
||||
- in: body
|
||||
name: eventBodyCreate
|
||||
description: The new event.
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/EventBody'
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
'201':
|
||||
description: Successful response
|
||||
schema:
|
||||
$ref: '#/definitions/EventEntry'
|
||||
'400':
|
||||
description: |
|
||||
Invalid parameter: **name** or **type** is invalid
|
||||
'401':
|
||||
description: Authentication failed
|
||||
'403':
|
||||
description: Current user does not have permission to create event
|
||||
'409':
|
||||
description: Cannot create event. An event with the name **name** already exists
|
||||
default:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
|
||||
'/events/{eventId}':
|
||||
get:
|
||||
tags:
|
||||
- events
|
||||
summary: Return event for given eventId
|
||||
description: |
|
||||
Gets information about the retention event with id **eventId**.
|
||||
operationId: getEvent
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- $ref: '#/parameters/eventIdParam'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
schema:
|
||||
$ref: '#/definitions/EventEntry'
|
||||
'400':
|
||||
description: |
|
||||
Invalid parameter: **eventId** is invalid
|
||||
'401':
|
||||
description: Authentication failed
|
||||
'404':
|
||||
description: "**eventId** does not exist"
|
||||
default:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
put:
|
||||
tags:
|
||||
- events
|
||||
summary: Update event for given eventId
|
||||
operationId: updateEvent
|
||||
description: |
|
||||
Updates retention event with id **eventId**.
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- $ref: '#/parameters/eventIdParam'
|
||||
- in: body
|
||||
name: eventBodyUpdate
|
||||
description: The event information to update.
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/EventBody'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
schema:
|
||||
$ref: '#/definitions/EventEntry'
|
||||
'400':
|
||||
description: |
|
||||
Invalid parameter: The update request is invalid or **eventId** is not a valid format or **eventBodyUpdate** is invalid
|
||||
'401':
|
||||
description: Authentication failed
|
||||
'403':
|
||||
description: Current user does not have permission to update events
|
||||
'404':
|
||||
description: "**eventId** does not exist"
|
||||
'409':
|
||||
description: Cannot update event. An event with the name **name** already exists
|
||||
default:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
|
||||
'/event-types':
|
||||
get:
|
||||
tags:
|
||||
- events
|
||||
summary: List all the retention event types
|
||||
description: |
|
||||
Gets a list of all the retention event types.
|
||||
operationId: getAllEventTypes
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- $ref: '#/parameters/skipCountParam'
|
||||
- $ref: '#/parameters/maxItemsParam'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
schema:
|
||||
$ref: '#/definitions/EventTypePaging'
|
||||
'400':
|
||||
description: |
|
||||
Invalid parameter: value of **maxItems** or **skipCount** is invalid
|
||||
'401':
|
||||
description: Authentication failed
|
||||
default:
|
||||
description: Unexpected error
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
parameters:
|
||||
## event
|
||||
eventIdParam:
|
||||
name: eventId
|
||||
in: path
|
||||
description: The identifier of an event.
|
||||
required: true
|
||||
type: string
|
||||
## File plans
|
||||
filePlanEntryIncludeParam:
|
||||
name: include
|
||||
@@ -3760,3 +3928,91 @@ definitions:
|
||||
- SiteCollaborator
|
||||
- SiteContributor
|
||||
- SiteManager
|
||||
EventPaging:
|
||||
type: object
|
||||
properties:
|
||||
list:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
$ref: '#/definitions/Pagination'
|
||||
entries:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/EventEntry'
|
||||
EventEntry:
|
||||
type: object
|
||||
required:
|
||||
- entry
|
||||
properties:
|
||||
entry:
|
||||
$ref: '#/definitions/Event'
|
||||
Event:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
- type
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: this is the id of the event
|
||||
name:
|
||||
type: string
|
||||
description: This is the unique display label of the event
|
||||
type:
|
||||
type: string
|
||||
description: this is event type
|
||||
EventBody:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: This is the unique display label of the event
|
||||
type:
|
||||
type: string
|
||||
description: this is event type
|
||||
default: Simple
|
||||
EventTypePaging:
|
||||
type: object
|
||||
properties:
|
||||
list:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
$ref: '#/definitions/Pagination'
|
||||
entries:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/EventTypeEntry'
|
||||
EventTypeEntry:
|
||||
type: object
|
||||
required:
|
||||
- entry
|
||||
properties:
|
||||
entry:
|
||||
$ref: '#/definitions/EventType'
|
||||
EventType:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: this is the event type id
|
||||
name:
|
||||
type: string
|
||||
description: this is event type name
|
||||
isAutomatic:
|
||||
type: boolean
|
||||
description: Whether events of this type need completing manually or can be completed automatically
|
||||
default: true
|
||||
associationName:
|
||||
type: string
|
||||
description: The association used to determine whether automatic events of this type are complete
|
||||
actionOnAssociatedNode:
|
||||
type: string
|
||||
description: If an association name is set for this event type then it is possible to require an action to be completed on the associated node
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
</project>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
SOLR6_TAG=2.0.5
|
||||
SOLR6_TAG=2.0.5.1
|
||||
POSTGRES_TAG=14.4
|
||||
ACTIVEMQ_TAG=5.17.1-jre11-rockylinux8
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<organization>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
package org.alfresco.rest.actions.email;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.json.JsonObject;
|
||||
|
||||
import org.alfresco.rest.RestTest;
|
||||
import org.alfresco.rest.core.JsonBodyGenerator;
|
||||
import org.alfresco.utility.model.FileModel;
|
||||
import org.alfresco.utility.model.FileType;
|
||||
import org.alfresco.utility.model.FolderModel;
|
||||
import org.alfresco.utility.model.UserModel;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class EmailTemplateTest extends RestTest {
|
||||
|
||||
public static final String MAIL_ACTION = "mail";
|
||||
|
||||
private UserModel adminUser;
|
||||
private UserModel testUser;
|
||||
private FolderModel testFolder;
|
||||
|
||||
@BeforeClass(alwaysRun = true)
|
||||
public void dataPreparation() throws Exception {
|
||||
adminUser = dataUser.getAdminUser();
|
||||
|
||||
testUser = dataUser.createRandomTestUser();
|
||||
testSite = dataSite.usingUser(testUser)
|
||||
.createPublicRandomSite();
|
||||
testFolder = dataContent.usingUser(testUser)
|
||||
.usingSite(testSite)
|
||||
.createFolder();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void adminCanSendEmailUsingTemplateWithModelAsString() throws Exception
|
||||
{
|
||||
String templateId = uploadEmailTemplate("simpleEmailTemplate.ftl");
|
||||
|
||||
// Create the model for use with email template
|
||||
JsonObject args = JsonBodyGenerator.defineJSON()
|
||||
.add("args", JsonBodyGenerator.defineJSON()
|
||||
.add("name", "testname")
|
||||
.build())
|
||||
.build();
|
||||
String emailModel = args.toString();
|
||||
|
||||
// Send an email using the template
|
||||
restClient.authenticateUser(adminUser)
|
||||
.withCoreAPI()
|
||||
.usingActions()
|
||||
.executeAction(MAIL_ACTION, testFolder, createMailWithTemplateParameters(adminUser, testUser, templateId, emailModel));
|
||||
|
||||
restClient.onResponse()
|
||||
.assertThat().statusCode(HttpStatus.ACCEPTED.value())
|
||||
.assertThat().body("entry.id", notNullValue());
|
||||
}
|
||||
|
||||
private String uploadEmailTemplate(String templateName) throws IOException
|
||||
{
|
||||
final String templateContent = getTemplateContent(templateName);
|
||||
final FileModel templateToCreate = new FileModel(templateName, FileType.TEXT_PLAIN, templateContent);
|
||||
|
||||
final FileModel createdTemplate = dataContent.usingAdmin()
|
||||
.usingResource(testFolder)
|
||||
.createContent(templateToCreate);
|
||||
|
||||
return createdTemplate.getNodeRef();
|
||||
}
|
||||
|
||||
private String getTemplateContent(String templateName) throws IOException
|
||||
{
|
||||
final String templateClasspathLocation = "/shared-resources/testdata/" + templateName;
|
||||
try (InputStream templateStream = getClass().getResourceAsStream(templateClasspathLocation))
|
||||
{
|
||||
requireNonNull(templateStream, "Couldn't locate `" + templateClasspathLocation + "`");
|
||||
return new String(templateStream.readAllBytes());
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, Serializable> createMailWithTemplateParameters(UserModel sender, UserModel recipient, String templateId, Serializable model)
|
||||
{
|
||||
Map<String, Serializable> parameterValues = new HashMap<>();
|
||||
|
||||
parameterValues.put("from", sender.getEmailAddress());
|
||||
parameterValues.put("to", recipient.getEmailAddress());
|
||||
parameterValues.put("subject", "Test");
|
||||
parameterValues.put("template", "workspace://SpacesStore/" + templateId);
|
||||
parameterValues.put("template_model", model);
|
||||
|
||||
return parameterValues;
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
package org.alfresco.rest.rules;
|
||||
|
||||
import static org.alfresco.rest.requests.RuleSettings.IS_INHERITANCE_ENABLED;
|
||||
import static org.alfresco.utility.report.log.Step.STEP;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
@@ -38,10 +39,12 @@ import org.alfresco.rest.model.RestRuleModelsCollection;
|
||||
import org.alfresco.rest.model.RestRuleSetLinkModel;
|
||||
import org.alfresco.rest.model.RestRuleSetModel;
|
||||
import org.alfresco.rest.model.RestRuleSetModelsCollection;
|
||||
import org.alfresco.rest.model.RestRuleSettingsModel;
|
||||
import org.alfresco.utility.model.FolderModel;
|
||||
import org.alfresco.utility.model.SiteModel;
|
||||
import org.alfresco.utility.model.TestGroup;
|
||||
import org.alfresco.utility.model.UserModel;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -71,26 +74,96 @@ public class GetInheritedRulesTests extends RestTest
|
||||
STEP("Create a parent and child folder, each with inheriting rules");
|
||||
FolderModel parent = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||
FolderModel child = dataContent.usingUser(user).usingResource(parent).createFolder();
|
||||
RestRuleModel parentRule = rulesUtils.createRuleModelWithDefaultValues();
|
||||
RestRuleModel parentRule = rulesUtils.createInheritableRuleModel();
|
||||
parentRule = restClient.authenticateUser(user).withPrivateAPI().usingNode(parent).usingDefaultRuleSet().createSingleRule(parentRule);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
|
||||
RestRuleSettingsModel enabled = new RestRuleSettingsModel();
|
||||
enabled.setValue(true);
|
||||
restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingRuleSetting(IS_INHERITANCE_ENABLED).updateSetting(enabled);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
RestRuleModel childRule = rulesUtils.createRuleModelWithDefaultValues();
|
||||
childRule = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingDefaultRuleSet().createSingleRule(childRule);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
|
||||
STEP("Get the rules in the default rule set for the child folder");
|
||||
RestRuleModelsCollection rules = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingDefaultRuleSet().getListOfRules();
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
rules.assertThat().entriesListContains("id", childRule.getId())
|
||||
.and().entriesListCountIs(1);
|
||||
|
||||
STEP("Get the rules in the inherited rule set for the child folder");
|
||||
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).include("inclusionType").getListOfRuleSets();
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
String inheritedRuleSetId = ruleSets.getEntries().stream()
|
||||
.filter(ruleSet -> ruleSet.onModel().getInclusionType().equals("inherited"))
|
||||
.findFirst().get().onModel().getId();
|
||||
|
||||
RestRuleModelsCollection inheritedRules = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingRuleSet(inheritedRuleSetId).getListOfRules();
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
inheritedRules.assertThat().entriesListContains("id", parentRule.getId())
|
||||
.and().entriesListCountIs(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check we get no (inherited) rules when inheritance is disabled in the child folder.
|
||||
*/
|
||||
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
|
||||
public void getInheritedRules_childFolderInheritanceDisabled()
|
||||
{
|
||||
STEP("Create a parent and child folder, with inheritable parent rule");
|
||||
FolderModel parent = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||
FolderModel child = dataContent.usingUser(user).usingResource(parent).createFolder();
|
||||
RestRuleModel parentRule = rulesUtils.createInheritableRuleModel();
|
||||
restClient.authenticateUser(user).withPrivateAPI().usingNode(parent).usingDefaultRuleSet().createSingleRule(parentRule);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
|
||||
STEP("Disable inheritance in the child folder");
|
||||
RestRuleSettingsModel enabledInheritance = new RestRuleSettingsModel();
|
||||
enabledInheritance.setValue(false);
|
||||
restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingRuleSetting(IS_INHERITANCE_ENABLED).updateSetting(enabledInheritance);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
STEP("The child folder should have no rule sets");
|
||||
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).getListOfRuleSets();
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
ruleSets.assertThat().entriesListIsEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that non-inheritable rules owned by the parent folder are not found inside the child folder.
|
||||
*/
|
||||
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
|
||||
public void inheritance_test()
|
||||
{
|
||||
STEP("Create a parent and child folder, with an inheritable and a non-inheritable parent rule");
|
||||
FolderModel parent = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||
FolderModel child = dataContent.usingUser(user).usingResource(parent).createFolder();
|
||||
|
||||
RestRuleModel inheritableRule = rulesUtils.createInheritableRuleModel();
|
||||
inheritableRule = restClient.authenticateUser(user).withPrivateAPI().usingNode(parent).usingDefaultRuleSet().createSingleRule(inheritableRule);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
|
||||
RestRuleModel nonInheritableRule = rulesUtils.createRuleModelWithDefaultValues();
|
||||
nonInheritableRule = restClient.authenticateUser(user).withPrivateAPI().usingNode(parent).usingDefaultRuleSet().createSingleRule(nonInheritableRule);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
|
||||
STEP("The inherited rule set for the child folder should only return the inheritable rule");
|
||||
RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).include("inclusionType").getListOfRuleSets();
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
|
||||
String inheritedRuleSetId = ruleSets.getEntries().stream()
|
||||
.filter(ruleSet -> ruleSet.onModel().getInclusionType().equals("inherited"))
|
||||
.findFirst().get().onModel().getId();
|
||||
|
||||
RestRuleModelsCollection inheritedRules = restClient.authenticateUser(user).withPrivateAPI().usingNode(child).usingRuleSet(inheritedRuleSetId).getListOfRules();
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
inheritedRules.assertThat().entriesListContains("id", inheritableRule.getId())
|
||||
.and().entriesListDoesNotContain("id",nonInheritableRule.getId())
|
||||
.and().entriesListCountIs(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that we only get each rule once with linking and inheritance, and the order is correct.
|
||||
* <p>
|
||||
@@ -110,9 +183,14 @@ public class GetInheritedRulesTests extends RestTest
|
||||
FolderModel folderB = dataContent.usingUser(user).usingResource(folderA).createFolder();
|
||||
FolderModel folderC = dataContent.usingUser(user).usingResource(folderB).createFolder();
|
||||
FolderModel folderD = dataContent.usingUser(user).usingResource(folderC).createFolder();
|
||||
RestRuleModel ruleB = restClient.authenticateUser(user).withPrivateAPI().usingNode(folderB).usingDefaultRuleSet().createSingleRule(rulesUtils.createRuleModelWithDefaultValues());
|
||||
RestRuleModel ruleC = restClient.authenticateUser(user).withPrivateAPI().usingNode(folderC).usingDefaultRuleSet().createSingleRule(rulesUtils.createRuleModelWithDefaultValues());
|
||||
RestRuleModel ruleB = restClient.authenticateUser(user).withPrivateAPI().usingNode(folderB).usingDefaultRuleSet().createSingleRule(rulesUtils.createInheritableRuleModel());
|
||||
RestRuleModel ruleC = restClient.authenticateUser(user).withPrivateAPI().usingNode(folderC).usingDefaultRuleSet().createSingleRule(rulesUtils.createInheritableRuleModel());
|
||||
RestRuleModel ruleD = restClient.authenticateUser(user).withPrivateAPI().usingNode(folderD).usingDefaultRuleSet().createSingleRule(rulesUtils.createRuleModelWithDefaultValues());
|
||||
RestRuleSettingsModel enabled = new RestRuleSettingsModel();
|
||||
enabled.setValue(true);
|
||||
restClient.authenticateUser(user).withPrivateAPI().usingNode(folderC).usingRuleSetting(IS_INHERITANCE_ENABLED).updateSetting(enabled);
|
||||
restClient.authenticateUser(user).withPrivateAPI().usingNode(folderD).usingRuleSetting(IS_INHERITANCE_ENABLED).updateSetting(enabled);
|
||||
|
||||
STEP("Link folderA to ruleSetD");
|
||||
RestRuleSetLinkModel linkModel = new RestRuleSetLinkModel();
|
||||
linkModel.setId(folderD.getNodeRef());
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.alfresco.utility.model.FolderModel;
|
||||
import org.alfresco.utility.model.SiteModel;
|
||||
import org.alfresco.utility.model.TestGroup;
|
||||
import org.alfresco.utility.model.UserModel;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -172,6 +173,56 @@ public class RuleSetLinksTests extends RestTest
|
||||
.get(0).onModel().assertThat().isEqualTo(expectedRuleSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check we can link to a rule set when linking from a folder which has inherited rules.
|
||||
*/
|
||||
@Test(groups = {TestGroup.REST_API, TestGroup.RULES})
|
||||
public void linkFromFolderWithInheritedRules()
|
||||
{
|
||||
STEP("Create folders");
|
||||
final FolderModel parentFolder = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||
final FolderModel childFolder = dataContent.usingUser(user).usingResource(parentFolder).createFolder();
|
||||
final FolderModel linkedToFolder = dataContent.usingUser(user).usingSite(site).createFolder();
|
||||
|
||||
STEP("Create rules in the parent folder and the linking folder");
|
||||
RestRuleModel parentRule = rulesUtils.createInheritableRuleModel();
|
||||
parentRule = restClient.authenticateUser(user).withPrivateAPI().usingNode(parentFolder).usingDefaultRuleSet().createSingleRule(parentRule);
|
||||
restClient.assertStatusCodeIs(CREATED);
|
||||
|
||||
RestRuleModel linkingFolderRule = rulesUtils.createRuleModelWithDefaultValues();
|
||||
restClient.authenticateUser(user).withPrivateAPI().usingNode(linkedToFolder).usingDefaultRuleSet().createSingleRule(linkingFolderRule);
|
||||
restClient.assertStatusCodeIs(CREATED);
|
||||
|
||||
STEP("Get the rule sets for the linking folder and find the rule set id");
|
||||
final RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withPrivateAPI().usingNode(linkedToFolder).getListOfRuleSets();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
ruleSets.assertThat().entriesListCountIs(1);
|
||||
final String ruleSetId = ruleSets.getEntries().get(0).onModel().getId();
|
||||
|
||||
STEP("Link the child folder to the target folder");
|
||||
final RestRuleSetLinkModel request = new RestRuleSetLinkModel();
|
||||
request.setId(linkedToFolder.getNodeRef());
|
||||
final RestRuleSetLinkModel ruleLink = restClient.authenticateUser(user).withPrivateAPI().usingNode(childFolder).createRuleLink(request);
|
||||
restClient.assertStatusCodeIs(CREATED);
|
||||
|
||||
STEP("Assert link result");
|
||||
final RestRuleSetLinkModel expectedLink = new RestRuleSetLinkModel();
|
||||
expectedLink.setId(ruleSetId);
|
||||
ruleLink.assertThat().isEqualTo(expectedLink);
|
||||
|
||||
STEP("Assert that the child folder has also inherited the parent rule");
|
||||
RestRuleSetModelsCollection ruleSetsInh = restClient.authenticateUser(user).withPrivateAPI().usingNode(childFolder).include("inclusionType").getListOfRuleSets();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
String inheritedRuleSetId = ruleSetsInh.getEntries().stream()
|
||||
.filter(ruleSet -> ruleSet.onModel().getInclusionType().equals("inherited"))
|
||||
.findFirst().get().onModel().getId();
|
||||
|
||||
RestRuleModelsCollection inheritedRules = restClient.authenticateUser(user).withPrivateAPI().usingNode(childFolder).usingRuleSet(inheritedRuleSetId).getListOfRules();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
inheritedRules.assertThat().entriesListContains("id", parentRule.getId())
|
||||
.and().entriesListCountIs(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check we get 404 when linking to a non-existing rule set/folder.
|
||||
*/
|
||||
|
||||
@@ -213,6 +213,13 @@ public class RulesTestsUtils
|
||||
return createRuleModel(RULE_NAME_DEFAULT);
|
||||
}
|
||||
|
||||
public RestRuleModel createInheritableRuleModel()
|
||||
{
|
||||
RestRuleModel ruleModel = createRuleModel(RULE_NAME_DEFAULT);
|
||||
ruleModel.setIsInheritable(true);
|
||||
return ruleModel;
|
||||
}
|
||||
|
||||
public RestRuleModel createRuleModel(String name)
|
||||
{
|
||||
return createRuleModel(name, List.of(createAddAudioAspectAction()));
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
Hello ${args.name}!
|
||||
</body>
|
||||
</html>
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
6
pom.xml
6
pom.xml
@@ -2,7 +2,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Alfresco Community Repo Parent</name>
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
<dependency.jakarta-json-path.version>2.7.0</dependency.jakarta-json-path.version>
|
||||
<dependency.jakarta-rpc-api.version>1.1.4</dependency.jakarta-rpc-api.version>
|
||||
|
||||
<alfresco.googledrive.version>3.3.1-A2</alfresco.googledrive.version>
|
||||
<alfresco.googledrive.version>3.3.1-A3</alfresco.googledrive.version>
|
||||
<alfresco.aos-module.version>1.5.0</alfresco.aos-module.version>
|
||||
<alfresco.api-explorer.version>7.3.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
|
||||
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
|
||||
<url>https://github.com/Alfresco/alfresco-community-repo</url>
|
||||
<tag>20.19</tag>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -363,13 +363,13 @@ public class ActionsImpl implements Actions
|
||||
Map.Entry::getValue));
|
||||
}
|
||||
|
||||
private Map<String, Serializable> extractActionParams(org.alfresco.service.cmr.action.ActionDefinition actionDefinition, Map<String, String> params)
|
||||
private Map<String, Serializable> extractActionParams(org.alfresco.service.cmr.action.ActionDefinition actionDefinition, Map<String, ?> params)
|
||||
{
|
||||
Map<String, Serializable> parameterValues = new HashMap<>();
|
||||
|
||||
try
|
||||
{
|
||||
for (Map.Entry<String, String> entry : params.entrySet())
|
||||
for (Map.Entry<String, ?> entry : params.entrySet())
|
||||
{
|
||||
String propertyName = entry.getKey();
|
||||
Object propertyValue = entry.getValue();
|
||||
|
||||
@@ -170,7 +170,7 @@ public class RuleSetsImpl implements RuleSets
|
||||
}
|
||||
|
||||
//The folder shouldn't have any pre-existing rules
|
||||
if (ruleService.hasRules(folderNodeRef)) {
|
||||
if (ruleService.hasNonInheritedRules(folderNodeRef)) {
|
||||
throw new InvalidArgumentException("Unable to link to a rule set because the folder has pre-existing rules or is already linked to a rule set.");
|
||||
}
|
||||
|
||||
|
||||
@@ -26,17 +26,12 @@
|
||||
|
||||
package org.alfresco.rest.api.impl.rules;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.alfresco.repo.action.ActionImpl;
|
||||
import org.alfresco.repo.action.access.ActionAccessRestriction;
|
||||
import org.alfresco.repo.action.executer.ExecuteAllRulesActionExecuter;
|
||||
import org.alfresco.rest.api.Rules;
|
||||
import org.alfresco.rest.api.model.mapper.RestModelMapper;
|
||||
import org.alfresco.rest.api.model.rules.InclusionType;
|
||||
import org.alfresco.rest.api.model.rules.Rule;
|
||||
import org.alfresco.rest.api.model.rules.RuleExecution;
|
||||
import org.alfresco.rest.api.model.rules.RuleSet;
|
||||
@@ -53,6 +48,14 @@ import org.apache.commons.collections.CollectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.INCLUSION_TYPE;
|
||||
|
||||
@Experimental
|
||||
public class RulesImpl implements Rules
|
||||
{
|
||||
@@ -63,6 +66,7 @@ public class RulesImpl implements Rules
|
||||
private RuleService ruleService;
|
||||
private NodeValidator validator;
|
||||
private RuleLoader ruleLoader;
|
||||
private RuleSetLoader ruleSetLoader;
|
||||
private ActionPermissionValidator actionPermissionValidator;
|
||||
private RestModelMapper<Rule, org.alfresco.service.cmr.rule.Rule> ruleMapper;
|
||||
|
||||
@@ -75,8 +79,10 @@ public class RulesImpl implements Rules
|
||||
final NodeRef folderNodeRef = validator.validateFolderNode(folderNodeId, false);
|
||||
NodeRef ruleSetNode = validator.validateRuleSetNode(ruleSetId, folderNodeRef);
|
||||
NodeRef owningFolder = ruleService.getOwningNodeRef(ruleSetNode);
|
||||
RuleSet ruleSet = ruleSetLoader.loadRuleSet(ruleSetNode, folderNodeRef, List.of(INCLUSION_TYPE));
|
||||
|
||||
final List<Rule> rules = ruleService.getRules(owningFolder, false).stream()
|
||||
.filter(ruleModel -> ruleSet.getInclusionType() != InclusionType.INHERITED || ruleModel.isAppliedToChildren())
|
||||
.map(ruleModel -> ruleLoader.loadRule(ruleModel, includes))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -182,6 +188,11 @@ public class RulesImpl implements Rules
|
||||
this.ruleLoader = ruleLoader;
|
||||
}
|
||||
|
||||
public void setRuleSetLoader(RuleSetLoader ruleSetLoader)
|
||||
{
|
||||
this.ruleSetLoader = ruleSetLoader;
|
||||
}
|
||||
|
||||
public void setActionPermissionValidator(ActionPermissionValidator actionPermissionValidator)
|
||||
{
|
||||
this.actionPermissionValidator = actionPermissionValidator;
|
||||
|
||||
@@ -32,7 +32,7 @@ public class Action
|
||||
private String id;
|
||||
private String actionDefinitionId;
|
||||
private String targetId;
|
||||
Map<String, String> params;
|
||||
private Map<String, ?> params;
|
||||
|
||||
public String getId()
|
||||
{
|
||||
@@ -64,12 +64,12 @@ public class Action
|
||||
this.targetId = targetId;
|
||||
}
|
||||
|
||||
public Map<String, String> getParams()
|
||||
public Map<String, ?> getParams()
|
||||
{
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(Map<String, String> params)
|
||||
public void setParams(Map<String, ? extends Object> params)
|
||||
{
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@@ -929,6 +929,7 @@
|
||||
<property name="validator" ref="nodeValidator"/>
|
||||
<property name="ruleService" ref="RuleService" />
|
||||
<property name="ruleLoader" ref="ruleLoader"/>
|
||||
<property name="ruleSetLoader" ref="ruleSetLoader"/>
|
||||
<property name="actionPermissionValidator" ref="actionPermissionValidator"/>
|
||||
<property name="ruleMapper" ref="ruleMapper"/>
|
||||
</bean>
|
||||
|
||||
@@ -257,7 +257,7 @@ public class RuleSetsImplTest extends TestCase
|
||||
String actual = ruleSets.linkToRuleSet(FOLDER_ID,LINK_TO_NODE_ID).getId();
|
||||
|
||||
then(ruleServiceMock).should().hasRules(LINK_TO_NODE);
|
||||
then(ruleServiceMock).should().hasRules(FOLDER_NODE);
|
||||
then(ruleServiceMock).should().hasNonInheritedRules(FOLDER_NODE);
|
||||
then(runtimeRuleServiceMock).should().getSavedRuleFolderAssoc(LINK_TO_NODE);
|
||||
then(runtimeRuleServiceMock).shouldHaveNoMoreInteractions();
|
||||
then(nodeServiceMock).should().addChild(FOLDER_NODE, childNodeRef, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER);
|
||||
@@ -284,7 +284,7 @@ public class RuleSetsImplTest extends TestCase
|
||||
then(nodeValidatorMock).should().validateRuleSetNode(LINK_TO_NODE_ID,false);
|
||||
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleServiceMock).should().hasRules(LINK_TO_NODE);
|
||||
then(ruleServiceMock).should().hasRules(FOLDER_NODE);
|
||||
then(ruleServiceMock).should().hasNonInheritedRules(FOLDER_NODE);
|
||||
then(runtimeRuleServiceMock).should().getSavedRuleFolderAssoc(LINK_TO_NODE);
|
||||
then(runtimeRuleServiceMock).shouldHaveNoMoreInteractions();
|
||||
then(nodeServiceMock).should().addChild(FOLDER_NODE, childNodeRef, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER);
|
||||
@@ -312,7 +312,8 @@ public class RuleSetsImplTest extends TestCase
|
||||
@Test
|
||||
public void testLinkToRuleSet_folderShouldntHavePreExistingRules()
|
||||
{
|
||||
given(ruleServiceMock.hasRules(any(NodeRef.class))).willReturn(true, true);
|
||||
given(ruleServiceMock.hasRules(any(NodeRef.class))).willReturn(true);
|
||||
given(ruleServiceMock.hasNonInheritedRules(any(NodeRef.class))).willReturn(true);
|
||||
|
||||
//when
|
||||
assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy(
|
||||
@@ -320,7 +321,7 @@ public class RuleSetsImplTest extends TestCase
|
||||
|
||||
then(nodeServiceMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleServiceMock).should().hasRules(LINK_TO_NODE);
|
||||
then(ruleServiceMock).should().hasRules(FOLDER_NODE);
|
||||
then(ruleServiceMock).should().hasNonInheritedRules(FOLDER_NODE);
|
||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||
then(runtimeRuleServiceMock).shouldHaveNoInteractions();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ package org.alfresco.rest.api.impl.rules;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
import static org.alfresco.rest.api.impl.rules.RuleSetLoader.INCLUSION_TYPE;
|
||||
import static org.alfresco.rest.api.model.rules.RuleSet.DEFAULT_ID;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
@@ -51,8 +52,10 @@ import org.alfresco.repo.action.executer.ExecuteAllRulesActionExecuter;
|
||||
import org.alfresco.rest.api.Nodes;
|
||||
import org.alfresco.rest.api.model.mapper.RestModelMapper;
|
||||
import org.alfresco.rest.api.model.rules.Action;
|
||||
import org.alfresco.rest.api.model.rules.InclusionType;
|
||||
import org.alfresco.rest.api.model.rules.Rule;
|
||||
import org.alfresco.rest.api.model.rules.RuleExecution;
|
||||
import org.alfresco.rest.api.model.rules.RuleSet;
|
||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
||||
@@ -80,6 +83,7 @@ public class RulesImplTest extends TestCase
|
||||
private static final String FOLDER_NODE_ID = "dummy-folder-node-id";
|
||||
private static final String RULE_SET_ID = "dummy-rule-set-id";
|
||||
private static final String RULE_ID = "dummy-rule-id";
|
||||
private static final String RULE_ID_INHERITED = "dummy-rule-id-inherited";
|
||||
private static final NodeRef FOLDER_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, FOLDER_NODE_ID);
|
||||
private static final NodeRef RULE_SET_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
|
||||
private static final NodeRef RULE_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID);
|
||||
@@ -101,15 +105,20 @@ public class RulesImplTest extends TestCase
|
||||
@Mock
|
||||
private RuleLoader ruleLoaderMock;
|
||||
@Mock
|
||||
private RuleSetLoader ruleSetLoaderMock;
|
||||
@Mock
|
||||
private ActionPermissionValidator actionPermissionValidatorMock;
|
||||
@Mock
|
||||
private org.alfresco.service.cmr.rule.Rule serviceRuleMock;
|
||||
@Mock
|
||||
private Rule ruleMock;
|
||||
@Mock
|
||||
private RuleSet ruleSetMock;
|
||||
@Mock
|
||||
private Action actionMock;
|
||||
|
||||
private org.alfresco.service.cmr.rule.Rule ruleModel = createRule(RULE_ID);
|
||||
private org.alfresco.service.cmr.rule.Rule ruleModelInherited = createRule(RULE_ID_INHERITED);
|
||||
|
||||
@InjectMocks
|
||||
private RulesImpl rules;
|
||||
@@ -118,6 +127,9 @@ public class RulesImplTest extends TestCase
|
||||
@Override
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
ruleModel.applyToChildren(true);
|
||||
ruleModelInherited.applyToChildren(true);
|
||||
|
||||
given(nodeValidatorMock.validateFolderNode(any(), anyBoolean())).willReturn(FOLDER_NODE_REF);
|
||||
given(nodeValidatorMock.validateRuleSetNode(any(), any())).willReturn(RULE_SET_NODE_REF);
|
||||
given(nodeValidatorMock.validateRuleNode(any(), any())).willReturn(RULE_NODE_REF);
|
||||
@@ -126,13 +138,15 @@ public class RulesImplTest extends TestCase
|
||||
given(ruleServiceMock.getRules(FOLDER_NODE_REF, false)).willReturn(List.of(ruleModel));
|
||||
given(ruleServiceMock.getOwningNodeRef(RULE_SET_NODE_REF)).willReturn(FOLDER_NODE_REF);
|
||||
|
||||
given(ruleSetMock.getInclusionType()).willReturn(InclusionType.INHERITED);
|
||||
|
||||
given(ruleLoaderMock.loadRule(ruleModel, INCLUDE)).willReturn(ruleMock);
|
||||
given(ruleSetLoaderMock.loadRuleSet(RULE_SET_NODE_REF, FOLDER_NODE_REF, List.of(INCLUSION_TYPE))).willReturn(ruleSetMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRules()
|
||||
{
|
||||
given(ruleLoaderMock.loadRule(ruleModel, emptyList())).willReturn(ruleMock);
|
||||
|
||||
// when
|
||||
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING);
|
||||
@@ -141,6 +155,66 @@ public class RulesImplTest extends TestCase
|
||||
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF);
|
||||
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleServiceMock).should().getOwningNodeRef(RULE_SET_NODE_REF);
|
||||
then(ruleSetLoaderMock).should().loadRuleSet(RULE_SET_NODE_REF, FOLDER_NODE_REF, List.of(INCLUSION_TYPE));
|
||||
then(ruleSetLoaderMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF, false);
|
||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleLoaderMock).should().loadRule(ruleModel, emptyList());
|
||||
then(ruleLoaderMock).shouldHaveNoMoreInteractions();
|
||||
assertThat(rulesPage)
|
||||
.isNotNull()
|
||||
.extracting(CollectionWithPagingInfo::getCollection)
|
||||
.isNotNull()
|
||||
.extracting(Collection::size)
|
||||
.isEqualTo(1);
|
||||
assertThat(rulesPage.getCollection().stream().findFirst().get()).isEqualTo(ruleMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRules_ruleNotAppliedToChildren()
|
||||
{
|
||||
given(ruleSetMock.getInclusionType()).willReturn(InclusionType.INHERITED);
|
||||
given(ruleServiceMock.getRules(FOLDER_NODE_REF, false)).willReturn(List.of(ruleModel, ruleModelInherited));
|
||||
ruleModelInherited.applyToChildren(false);
|
||||
|
||||
// when
|
||||
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING);
|
||||
|
||||
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
|
||||
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF);
|
||||
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleServiceMock).should().getOwningNodeRef(RULE_SET_NODE_REF);
|
||||
then(ruleSetLoaderMock).should().loadRuleSet(RULE_SET_NODE_REF, FOLDER_NODE_REF, List.of(INCLUSION_TYPE));
|
||||
then(ruleSetLoaderMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF, false);
|
||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleLoaderMock).should().loadRule(ruleModel, emptyList());
|
||||
then(ruleLoaderMock).shouldHaveNoMoreInteractions();
|
||||
assertThat(rulesPage)
|
||||
.isNotNull()
|
||||
.extracting(CollectionWithPagingInfo::getCollection)
|
||||
.isNotNull()
|
||||
.extracting(Collection::size)
|
||||
.isEqualTo(1);
|
||||
assertThat(rulesPage.getCollection().stream().findFirst().get()).isEqualTo(ruleMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRules_inheritedRuleSet()
|
||||
{
|
||||
given(ruleSetMock.getInclusionType()).willReturn(InclusionType.INHERITED);
|
||||
ruleModelInherited.applyToChildren(false);
|
||||
given(ruleServiceMock.getRules(FOLDER_NODE_REF, false)).willReturn(List.of(ruleModel, ruleModelInherited));
|
||||
|
||||
// when
|
||||
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING);
|
||||
|
||||
then(nodeValidatorMock).should().validateFolderNode(FOLDER_NODE_ID, false);
|
||||
then(nodeValidatorMock).should().validateRuleSetNode(RULE_SET_ID, FOLDER_NODE_REF);
|
||||
then(nodeValidatorMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleServiceMock).should().getOwningNodeRef(RULE_SET_NODE_REF);
|
||||
then(ruleSetLoaderMock).should().loadRuleSet(RULE_SET_NODE_REF, FOLDER_NODE_REF, List.of(INCLUSION_TYPE));
|
||||
then(ruleSetLoaderMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF, false);
|
||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleLoaderMock).should().loadRule(ruleModel, emptyList());
|
||||
@@ -163,6 +237,8 @@ public class RulesImplTest extends TestCase
|
||||
final CollectionWithPagingInfo<Rule> rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, INCLUDE, PAGING);
|
||||
|
||||
then(ruleServiceMock).should().getOwningNodeRef(RULE_SET_NODE_REF);
|
||||
then(ruleSetLoaderMock).should().loadRuleSet(RULE_SET_NODE_REF, FOLDER_NODE_REF, List.of(INCLUSION_TYPE));
|
||||
then(ruleSetLoaderMock).shouldHaveNoMoreInteractions();
|
||||
then(ruleServiceMock).should().getRules(FOLDER_NODE_REF, false);
|
||||
then(ruleServiceMock).shouldHaveNoMoreInteractions();
|
||||
assertThat(rulesPage)
|
||||
|
||||
@@ -78,7 +78,7 @@ public class Action extends org.alfresco.rest.api.model.Action implements Serial
|
||||
String id = (String) jsonObject.get("id");
|
||||
String actionDefinitionId = (String) jsonObject.get("actionDefinitionId");
|
||||
String targetId = (String) jsonObject.get("targetId");
|
||||
Map<String, String> params = (Map<String, String>) jsonObject.get("params");
|
||||
Map<String, Object> params = (Map<String, Object>) jsonObject.get("params");
|
||||
|
||||
Action action = new Action();
|
||||
action.setId(id);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.19</version>
|
||||
<version>20.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -461,6 +461,12 @@ public class RuleServiceImpl
|
||||
return getRules(nodeRef).size() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNonInheritedRules(NodeRef nodeRef)
|
||||
{
|
||||
return getRules(nodeRef, false).size() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Rule> getRules(NodeRef nodeRef)
|
||||
{
|
||||
|
||||
@@ -165,6 +165,15 @@ public interface RuleService
|
||||
@Auditable(parameters = {"nodeRef"})
|
||||
public boolean hasRules(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* Indicates whether the node in question has any non-inherited rules associated with it.
|
||||
*
|
||||
* @param nodeRef the node reference
|
||||
* @return true if the node has rules associated, false otherwise
|
||||
*/
|
||||
@Auditable(parameters = {"nodeRef"})
|
||||
public boolean hasNonInheritedRules(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* Get all the rules associated with an actionable node, including those
|
||||
* inherited from parents.
|
||||
|
||||
Reference in New Issue
Block a user