From bba1664fef5bd9230c2cb49572078f76b22990cf Mon Sep 17 00:00:00 2001 From: Tom Page Date: Wed, 10 Aug 2022 10:58:15 +0100 Subject: [PATCH] ACS-3361 Support for inclusionType. (#1286) * ACS-3361 Support for inclusionType. * ACS-3361 Update to released version of TAS Rest API. [tas] * ACS-3361 Better coverage of different inclusion types. [tas] --- .../alfresco/rest/rules/GetRuleSetsTests.java | 17 ++++++ pom.xml | 2 +- .../rest/api/impl/rules/RuleSetLoader.java | 31 +++++++++- .../rest/api/impl/rules/RuleSetsImpl.java | 5 +- .../rest/api/model/rules/InclusionType.java | 59 +++++++++++++++++++ .../rest/api/model/rules/RuleSet.java | 34 ++++++++++- .../api/impl/rules/RuleSetLoaderTest.java | 54 +++++++++++++++-- .../rest/api/impl/rules/RuleSetsImplTest.java | 2 +- 8 files changed, 188 insertions(+), 16 deletions(-) create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/model/rules/InclusionType.java diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java index 79257be1f5..29eb3bc8a2 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java @@ -132,6 +132,23 @@ public class GetRuleSetsTests extends RestTest ruleSets.assertThat().entriesListCountIs(1); } + /** Check we can get the reason that a rule set is included in the list. */ + @Test (groups = { TestGroup.REST_API, TestGroup.RULES }) + public void getRuleSetsAndInclusionType() + { + STEP("Get the rule sets and inclusion type"); + RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withCoreAPI() + .usingNode(ruleFolder) + .usingParams("include=inclusionType") + .getListOfRuleSets(); + + restClient.assertStatusCodeIs(OK); + ruleSets.getEntries().get(0).onModel() + .assertThat().field("inclusionType").is("owned") + .assertThat().field("id").is(ruleSetId); + ruleSets.assertThat().entriesListCountIs(1); + } + /** Check we can get a rule set by its id. */ @Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY }) public void getRuleSetById() diff --git a/pom.xml b/pom.xml index c933c9132a..3c63bab9f8 100644 --- a/pom.xml +++ b/pom.xml @@ -120,7 +120,7 @@ 2.7.4 3.0.49 5.1.1 - 1.103 + 1.104 1.31 1.8 1.6 diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java index 32296098ff..3e7d10bf38 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java @@ -25,10 +25,15 @@ */ package org.alfresco.rest.api.impl.rules; +import static org.alfresco.rest.api.model.rules.InclusionType.INHERITED; +import static org.alfresco.rest.api.model.rules.InclusionType.LINKED; +import static org.alfresco.rest.api.model.rules.InclusionType.OWNED; + import java.util.List; import org.alfresco.rest.api.model.rules.RuleSet; import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; @@ -36,6 +41,8 @@ import org.alfresco.service.cmr.repository.NodeService; @Experimental public class RuleSetLoader { + protected static final String OWNING_FOLDER = "owningFolder"; + protected static final String INCLUSION_TYPE = "inclusionType"; private NodeService nodeService; /** @@ -45,15 +52,33 @@ public class RuleSetLoader * @param includes A list of fields to include. * @return The rule set object. */ - protected RuleSet loadRuleSet(NodeRef ruleSetNodeRef, List includes) + protected RuleSet loadRuleSet(NodeRef ruleSetNodeRef, NodeRef folderNodeRef, List includes) { String ruleSetId = ruleSetNodeRef.getId(); RuleSet ruleSet = RuleSet.of(ruleSetId); - if (includes != null && includes.contains("owningFolder")) + if (includes != null) { NodeRef parentRef = nodeService.getPrimaryParent(ruleSetNodeRef).getParentRef(); - ruleSet.setOwningFolder(parentRef); + if (includes.contains(OWNING_FOLDER)) + { + ruleSet.setOwningFolder(parentRef); + } + if (includes.contains(INCLUSION_TYPE)) + { + // In the case that a rule set applies to the given folder for multiple reasons then priority is given to owned, then linked, then inherited. + if (parentRef.equals(folderNodeRef)) + { + ruleSet.setInclusionType(OWNED); + } + else + { + boolean linked = nodeService.getParentAssocs(ruleSetNodeRef) + .stream().map(ChildAssociationRef::getParentRef) + .anyMatch(folderNodeRef::equals); + ruleSet.setInclusionType(linked ? LINKED : INHERITED); + } + } } return ruleSet; } diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetsImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetsImpl.java index 89dfcb57e6..e8b181e3e2 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetsImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetsImpl.java @@ -54,7 +54,8 @@ public class RuleSetsImpl implements RuleSets NodeRef ruleSetNode = ruleService.getRuleSetNode(folderNode); List ruleSets = Optional.ofNullable(ruleSetNode) - .map(nodeRef -> ruleSetLoader.loadRuleSet(nodeRef, includes)).stream().collect(toList()); + .map(nodeRef -> ruleSetLoader.loadRuleSet(nodeRef, folderNode, includes)) + .stream().collect(toList()); return ListPage.of(ruleSets, paging); } @@ -65,7 +66,7 @@ public class RuleSetsImpl implements RuleSets NodeRef folderNode = validator.validateFolderNode(folderNodeId, false); NodeRef ruleSetNode = validator.validateRuleSetNode(ruleSetId, folderNode); - return ruleSetLoader.loadRuleSet(ruleSetNode, includes); + return ruleSetLoader.loadRuleSet(ruleSetNode, folderNode, includes); } public void setRuleSetLoader(RuleSetLoader ruleSetLoader) diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/InclusionType.java b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/InclusionType.java new file mode 100644 index 0000000000..687cde0f4d --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/InclusionType.java @@ -0,0 +1,59 @@ +/* + * #%L + * Alfresco Remote API + * %% + * 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 . + * #L% + */ +package org.alfresco.rest.api.model.rules; + +import com.fasterxml.jackson.annotation.JsonValue; + +import org.alfresco.service.Experimental; + +/** The reason why a rule set applies to a folder. */ +@Experimental +public enum InclusionType +{ + OWNED, INHERITED, LINKED; + + /** + * Load an InclusionType from a given string (case insensitively). + * + * @param inclusionType The given string. + * @return The inclusion type. + */ + public static InclusionType from(String inclusionType) + { + return InclusionType.valueOf(inclusionType.toUpperCase()); + } + + /** + * The lower case version of the inclusion type. + * + * @return A lowercase string. + */ + @JsonValue + public String toString() + { + return super.toString().toLowerCase(); + } +} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java index 343c2bc13e..df1984673f 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java @@ -27,7 +27,9 @@ package org.alfresco.rest.api.model.rules; import java.util.Objects; +import java.util.StringJoiner; +import org.alfresco.rest.api.People; import org.alfresco.service.Experimental; import org.alfresco.service.cmr.repository.NodeRef; @@ -38,6 +40,7 @@ public class RuleSet private String id; private NodeRef owningFolder; + private InclusionType inclusionType; public static RuleSet of(String id) { @@ -74,10 +77,26 @@ public class RuleSet this.owningFolder = owningFolder; } + public InclusionType getInclusionType() + { + return inclusionType; + } + + public void setInclusionType(InclusionType inclusionType) + { + this.inclusionType = inclusionType; + } + @Override public String toString() { - return "RuleSet{" + "id='" + id + '\'' + '}'; + return "RuleSet{" + + new StringJoiner(", ") + .add("id='" + id + "'") + .add("owningFolder='" + owningFolder + "'") + .add("inclusionType='" + inclusionType + "'") + .toString() + + '}'; } @Override @@ -89,13 +108,14 @@ public class RuleSet return false; RuleSet ruleSet = (RuleSet) o; return Objects.equals(id, ruleSet.id) - && Objects.equals(owningFolder, ruleSet.owningFolder); + && Objects.equals(owningFolder, ruleSet.owningFolder) + && inclusionType == ruleSet.inclusionType; } @Override public int hashCode() { - return Objects.hash(id, owningFolder); + return Objects.hash(id, owningFolder, inclusionType); } public static Builder builder() @@ -107,6 +127,7 @@ public class RuleSet { private String id; private NodeRef owningFolder; + private InclusionType inclusionType; public Builder id(String id) { @@ -120,11 +141,18 @@ public class RuleSet return this; } + public Builder inclusionType(InclusionType inclusionType) + { + this.inclusionType = inclusionType; + return this; + } + public RuleSet create() { final RuleSet ruleSet = new RuleSet(); ruleSet.setId(id); ruleSet.setOwningFolder(owningFolder); + ruleSet.setInclusionType(inclusionType); return ruleSet; } } diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java index 54299b261e..29a0fd92c5 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java @@ -25,18 +25,22 @@ */ package org.alfresco.rest.api.impl.rules; +import static org.alfresco.rest.api.impl.rules.RuleSetLoader.INCLUSION_TYPE; +import static org.alfresco.rest.api.impl.rules.RuleSetLoader.OWNING_FOLDER; +import static org.alfresco.rest.api.model.rules.InclusionType.INHERITED; +import static org.alfresco.rest.api.model.rules.InclusionType.LINKED; +import static org.alfresco.rest.api.model.rules.InclusionType.OWNED; +import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE; import static org.mockito.BDDMockito.given; import java.util.List; import junit.framework.TestCase; import org.alfresco.rest.api.model.rules.RuleSet; -import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.service.Experimental; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -51,8 +55,11 @@ public class RuleSetLoaderTest extends TestCase { private static final String FOLDER_ID = "dummy-folder-id"; private static final String RULE_SET_ID = "dummy-rule-set-id"; - private static final NodeRef FOLDER_NODE = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, FOLDER_ID); - private static final NodeRef RULE_SET_NODE = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID); + private static final NodeRef FOLDER_NODE = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, FOLDER_ID); + private static final NodeRef RULE_SET_NODE = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID); + private static final String LINKING_FOLDER_ID = "linking-folder"; + private static final NodeRef LINKING_FOLDER = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, LINKING_FOLDER_ID); + private static final NodeRef INHERITING_FOLDER = new NodeRef("inheriting://folder/"); @InjectMocks private RuleSetLoader ruleSetLoader; @@ -60,6 +67,8 @@ public class RuleSetLoaderTest extends TestCase private NodeService nodeServiceMock; @Mock private ChildAssociationRef ruleSetAssociationMock; + @Mock + private ChildAssociationRef linkAssociationMock; @Before @Override @@ -67,13 +76,16 @@ public class RuleSetLoaderTest extends TestCase { given(ruleSetAssociationMock.getParentRef()).willReturn(FOLDER_NODE); given(nodeServiceMock.getPrimaryParent(RULE_SET_NODE)).willReturn(ruleSetAssociationMock); + + given(linkAssociationMock.getParentRef()).willReturn(LINKING_FOLDER); + given(nodeServiceMock.getParentAssocs(RULE_SET_NODE)).willReturn(List.of(ruleSetAssociationMock, linkAssociationMock)); } @Test public void testLoadRuleSet_noIncludes() { // Call the method under test. - RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, null); + RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, null); RuleSet expected = RuleSet.builder().id(RULE_SET_ID).create(); assertEquals(expected, actual); @@ -83,9 +95,39 @@ public class RuleSetLoaderTest extends TestCase public void testLoadRuleSet_includeOwningFolder() { // Call the method under test. - RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, List.of("owningFolder")); + RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, List.of(OWNING_FOLDER)); RuleSet expected = RuleSet.builder().id(RULE_SET_ID).owningFolder(FOLDER_NODE).create(); assertEquals(expected, actual); } + + @Test + public void testLoadRuleSet_includeInclusionType() + { + // Call the method under test. + RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, List.of(INCLUSION_TYPE)); + + RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inclusionType(OWNED).create(); + assertEquals(expected, actual); + } + + @Test + public void testLoadRuleSet_linkedInclusionType() + { + // Call the method under test. + RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, LINKING_FOLDER, List.of(INCLUSION_TYPE)); + + RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inclusionType(LINKED).create(); + assertEquals(expected, actual); + } + + @Test + public void testLoadRuleSet_inheritedInclusionType() + { + // Call the method under test. + RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, INHERITING_FOLDER, List.of(INCLUSION_TYPE)); + + RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inclusionType(INHERITED).create(); + assertEquals(expected, actual); + } } diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetsImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetsImplTest.java index bb2fba99a4..1ef53083ec 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetsImplTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetsImplTest.java @@ -87,7 +87,7 @@ public class RuleSetsImplTest extends TestCase given(nodeValidatorMock.validateRuleSetNode(RULE_SET_ID, FOLDER_NODE)).willReturn(RULE_SET_NODE); given(ruleServiceMock.getRuleSetNode(FOLDER_NODE)).willReturn(RULE_SET_NODE); - given(ruleSetLoaderMock.loadRuleSet(RULE_SET_NODE, INCLUDES)).willReturn(ruleSetMock); + given(ruleSetLoaderMock.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, INCLUDES)).willReturn(ruleSetMock); } @Test