Rules v1 REST API - Get rule definition - mapping of "other fields" (#1244)

ACS-3229: Rules v1 REST API - Get rule definition
- adding mapping of so-called "other fields"
This commit is contained in:
krdabrowski
2022-07-27 14:02:08 +02:00
committed by GitHub
parent 71080c9c7d
commit ac9151ed86
11 changed files with 587 additions and 77 deletions

View File

@@ -65,10 +65,11 @@ public class RulesImpl implements Rules
public CollectionWithPagingInfo<Rule> getRules(final String folderNodeId, final String ruleSetId, final Paging paging)
{
final NodeRef folderNodeRef = validateFolderNode(folderNodeId, false);
validateRuleSetNode(ruleSetId, folderNodeRef);
final NodeRef ruleSetNodeRef = validateRuleSetNode(ruleSetId, folderNodeRef);
final boolean isShared = isRuleSetNotNullAndShared(ruleSetNodeRef);
final List<Rule> rules = ruleService.getRules(folderNodeRef).stream()
.map(Rule::from)
.map(ruleModel -> Rule.from(ruleModel, isShared))
.collect(Collectors.toList());
return ListPage.of(rules, paging);
@@ -81,7 +82,7 @@ public class RulesImpl implements Rules
final NodeRef ruleSetNodeRef = validateRuleSetNode(ruleSetId, folderNodeRef);
final NodeRef ruleNodeRef = validateRuleNode(ruleId, ruleSetNodeRef);
return Rule.from(ruleService.getRule(ruleNodeRef));
return Rule.from(ruleService.getRule(ruleNodeRef), isRuleSetNotNullAndShared(ruleSetNodeRef));
}
@Override
@@ -89,15 +90,12 @@ public class RulesImpl implements Rules
{
final NodeRef folderNodeRef = validateFolderNode(folderNodeId, true);
// Don't validate the ruleset node if -default- is passed since we may need to create it.
if (RuleSet.isNotDefaultId(ruleSetId))
{
validateRuleSetNode(ruleSetId, folderNodeRef);
}
final NodeRef ruleSetNodeRef = (RuleSet.isNotDefaultId(ruleSetId)) ? validateRuleSetNode(ruleSetId, folderNodeRef) : null;
return rules.stream()
.map(rule -> rule.toServiceModel(nodes))
.map(rule -> ruleService.saveRule(folderNodeRef, rule))
.map(Rule::from)
.map(rule -> Rule.from(rule, isRuleSetNotNullAndShared(ruleSetNodeRef, folderNodeRef)))
.collect(Collectors.toList());
}
@@ -207,11 +205,30 @@ public class RulesImpl implements Rules
return nodeRef;
}
private void verifyNodeType(final NodeRef nodeRef, final QName expectedType, final String expectedTypeName) {
private void verifyNodeType(final NodeRef nodeRef, final QName expectedType, final String expectedTypeName)
{
final Set<QName> expectedTypes = Set.of(expectedType);
if (!nodes.nodeMatches(nodeRef, expectedTypes, null)) {
final String expectedTypeLocalName = (expectedTypeName != null)? expectedTypeName : expectedType.getLocalName();
throw new InvalidArgumentException(String.format("NodeId of a %s is expected!", expectedTypeLocalName));
}
}
private boolean isRuleSetNotNullAndShared(final NodeRef ruleSetNodeRef, final NodeRef folderNodeRef)
{
if (ruleSetNodeRef == null && folderNodeRef != null)
{
final NodeRef ruleSetNode = ruleService.getRuleSetNode(folderNodeRef);
return ruleSetNode != null && ruleService.isRuleSetShared(ruleSetNode);
}
else
{
return isRuleSetNotNullAndShared(ruleSetNodeRef);
}
}
private boolean isRuleSetNotNullAndShared(final NodeRef ruleSetNodeRef)
{
return ruleSetNodeRef != null && ruleService.isRuleSetShared(ruleSetNodeRef);
}
}

View File

@@ -31,14 +31,15 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.action.executer.ScriptActionExecuter;
import org.alfresco.repo.action.executer.SetPropertyValueActionExecuter;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.framework.resource.UniqueId;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.GUID;
@@ -47,16 +48,48 @@ public class Rule
{
private String id;
private String name;
private String description;
private boolean enabled;
private boolean cascade;
private boolean asynchronous;
private boolean shared;
private String errorScript;
private List<RuleTrigger> triggers;
public static Rule from(final org.alfresco.service.cmr.rule.Rule ruleModel) {
if (ruleModel == null) {
/**
* Converts service POJO rule to REST model rule.
*
* @param ruleModel - {@link org.alfresco.service.cmr.rule.Rule} service POJO
* @return {@link Rule} REST model
*/
public static Rule from(final org.alfresco.service.cmr.rule.Rule ruleModel, final boolean shared)
{
if (ruleModel == null)
{
return null;
}
return builder()
.setId(ruleModel.getNodeRef().getId())
.setName(ruleModel.getTitle())
.createRule();
final Rule.Builder builder = builder()
.name(ruleModel.getTitle())
.description(ruleModel.getDescription())
.enabled(!ruleModel.getRuleDisabled())
.cascade(ruleModel.isAppliedToChildren())
.asynchronous(ruleModel.getExecuteAsynchronously())
.shared(shared);
if (ruleModel.getNodeRef() != null) {
builder.id(ruleModel.getNodeRef().getId());
}
if (ruleModel.getRuleTypes() != null)
{
builder.triggers(ruleModel.getRuleTypes().stream().map(RuleTrigger::of).collect(Collectors.toList()));
}
if (ruleModel.getAction() != null && ruleModel.getAction().getCompensatingAction() != null && ruleModel.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF) != null)
{
builder.errorScript(ruleModel.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF).toString());
}
return builder.create();
}
/**
@@ -79,7 +112,7 @@ public class Rule
Map<String, Serializable> parameters = Map.of(
SetPropertyValueActionExecuter.PARAM_PROPERTY, ContentModel.PROP_TITLE,
SetPropertyValueActionExecuter.PARAM_VALUE, "UPDATED:" + GUID.generate());
Action action = new ActionImpl(null, GUID.generate(), SetPropertyValueActionExecuter.NAME, parameters);
org.alfresco.service.cmr.action.Action action = new ActionImpl(null, GUID.generate(), SetPropertyValueActionExecuter.NAME, parameters);
ruleModel.setAction(action);
return ruleModel;
@@ -106,68 +139,190 @@ public class Rule
this.name = name;
}
// TODO: Added stub for actions as it's a required field. Replace this implementation when we implement support for actions.
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public boolean isEnabled()
{
return enabled;
}
public void setEnabled(boolean enabled)
{
this.enabled = enabled;
}
public boolean isCascade()
{
return cascade;
}
public void setCascade(boolean cascade)
{
this.cascade = cascade;
}
public boolean isAsynchronous()
{
return asynchronous;
}
public void setAsynchronous(boolean asynchronous)
{
this.asynchronous = asynchronous;
}
public String getErrorScript()
{
return errorScript;
}
public void setErrorScript(String errorScript)
{
this.errorScript = errorScript;
}
public boolean isShared()
{
return shared;
}
public void setShared(boolean shared)
{
this.shared = shared;
}
public List<RuleTrigger> getTriggers()
{
return triggers;
}
public void setTriggers(List<RuleTrigger> triggers)
{
this.triggers = triggers;
}
public List<Void> getActions()
{
return Collections.emptyList();
}
@Override
public String toString()
{
return "Rule{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", description='" + description + '\'' + ", enabled=" + enabled + ", cascade=" + cascade
+ ", asynchronous=" + asynchronous + ", shared=" + shared + ", errorScript='" + errorScript + '\'' + ", triggers=" + triggers + '}';
}
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof Rule))
{
if (o == null || getClass() != o.getClass())
return false;
}
Rule rule = (Rule) o;
return Objects.equals(id, rule.id) &&
Objects.equals(name, rule.name);
return enabled == rule.enabled && cascade == rule.cascade && asynchronous == rule.asynchronous && shared == rule.shared && Objects.equals(id, rule.id) && Objects.equals(
name, rule.name) && Objects.equals(description, rule.description) && Objects.equals(errorScript, rule.errorScript) && Objects.equals(triggers, rule.triggers);
}
@Override
public int hashCode()
{
return Objects.hash(id, name);
return Objects.hash(id, name, description, enabled, cascade, asynchronous, shared, errorScript, triggers);
}
@Override
public String toString()
public static Builder builder()
{
return "Rule{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}';
}
public static RuleBuilder builder()
{
return new RuleBuilder();
return new Builder();
}
/** Builder class. */
public static class RuleBuilder
public static class Builder
{
private String id;
private String name;
private String description;
private boolean enabled;
private boolean cascade;
private boolean asynchronous;
private boolean shared;
private String errorScript;
private List<RuleTrigger> triggers;
public RuleBuilder setId(String id)
public Builder id(String id)
{
this.id = id;
return this;
}
public RuleBuilder setName(String name)
public Builder name(String name)
{
this.name = name;
return this;
}
public Rule createRule()
public Builder description(String description)
{
this.description = description;
return this;
}
public Builder enabled(boolean enabled)
{
this.enabled = enabled;
return this;
}
public Builder cascade(boolean cascade)
{
this.cascade = cascade;
return this;
}
public Builder asynchronous(boolean asynchronous)
{
this.asynchronous = asynchronous;
return this;
}
public Builder shared(boolean shared)
{
this.shared = shared;
return this;
}
public Builder errorScript(String errorScript)
{
this.errorScript = errorScript;
return this;
}
public Builder triggers(List<RuleTrigger> triggers)
{
this.triggers = triggers;
return this;
}
public Rule create()
{
Rule rule = new Rule();
rule.setId(id);
rule.setName(name);
rule.setDescription(description);
rule.setEnabled(enabled);
rule.setCascade(cascade);
rule.setAsynchronous(asynchronous);
rule.setShared(shared);
rule.setErrorScript(errorScript);
rule.setTriggers(triggers);
return rule;
}
}

View File

@@ -26,6 +26,8 @@
package org.alfresco.rest.api.model.rules;
import java.util.Objects;
import org.alfresco.service.Experimental;
@Experimental
@@ -37,10 +39,9 @@ public class RuleSet
public static RuleSet of(String id)
{
final RuleSet ruleSet = new RuleSet();
ruleSet.id = id;
return ruleSet;
return builder()
.id(id)
.create();
}
public boolean isNotDefaultId() {
@@ -74,4 +75,44 @@ public class RuleSet
{
return "RuleSet{" + "id='" + id + '\'' + '}';
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
RuleSet ruleSet = (RuleSet) o;
return Objects.equals(id, ruleSet.id);
}
@Override
public int hashCode()
{
return Objects.hash(id);
}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
private String id;
public Builder id(String id)
{
this.id = id;
return this;
}
public RuleSet create()
{
final RuleSet ruleSet = new RuleSet();
ruleSet.setId(id);
return ruleSet;
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.model.rules;
import org.alfresco.service.Experimental;
@Experimental
public enum RuleTrigger
{
INBOUND("inbound"),
UPDATE("update"),
OUTBOUND("outbound");
RuleTrigger(String value)
{
this.value = value;
}
private final String value;
public String getValue()
{
return value;
}
public static RuleTrigger of(final String value)
{
for (RuleTrigger ruleTrigger : values())
{
if (ruleTrigger.value.equals(value)) {
return ruleTrigger;
}
}
return null;
}
}

View File

@@ -48,9 +48,8 @@ import org.junit.runners.Suite;
org.alfresco.repo.webdav.RenameShuffleDetectionTest.class,
org.alfresco.repo.webdav.WebDAVHelperTest.class,
org.alfresco.repo.webdav.WebDAVLockServiceImplTest.class,
org.alfresco.rest.api.RulesUnitTests.class,
org.alfresco.rest.api.impl.ContentStorageInformationImplTest.class,
org.alfresco.rest.api.impl.RulesImplTest.class,
org.alfresco.rest.api.nodes.NodeRulesRelationTest.class,
org.alfresco.rest.api.nodes.NodeStorageInfoRelationTest.class,
org.alfresco.rest.api.search.ResultMapperTests.class,
org.alfresco.rest.api.search.SearchApiWebscriptTests.class,

View File

@@ -0,0 +1,45 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api;
import org.alfresco.rest.api.impl.RulesImplTest;
import org.alfresco.rest.api.model.rules.RuleTest;
import org.alfresco.rest.api.nodes.NodeRulesRelationTest;
import org.alfresco.service.Experimental;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@Experimental
@RunWith(Suite.class)
@Suite.SuiteClasses({
NodeRulesRelationTest.class,
RulesImplTest.class,
RuleTest.class
})
public class RulesUnitTests
{
}

View File

@@ -40,12 +40,14 @@ import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import junit.framework.TestCase;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
@@ -54,6 +56,7 @@ import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.rule.RuleService;
@@ -77,6 +80,7 @@ public class RulesImplTest extends TestCase
private static final NodeRef ruleSetNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
private static final NodeRef ruleNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID);
private static final Paging paging = Paging.DEFAULT;
private static final Action action = new ActionImpl(folderNodeRef, "actionId", "actionDefinitionName");
private static final String RULE_NAME = "Rule name";
@Mock
@@ -121,6 +125,7 @@ public class RulesImplTest extends TestCase
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
then(permissionServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
then(ruleServiceMock).should().isRuleSetShared(ruleSetNodeRef);
then(ruleServiceMock).should().getRules(folderNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(rulesPage)
@@ -138,6 +143,7 @@ public class RulesImplTest extends TestCase
@Test
public void testGetRulesForDefaultRuleSet()
{
given(ruleServiceMock.getRuleSetNode(any())).willReturn(ruleSetNodeRef);
given(ruleServiceMock.getRules(any())).willReturn(List.of(createRule(RULE_ID)));
// when
@@ -149,6 +155,7 @@ public class RulesImplTest extends TestCase
then(permissionServiceMock).should().hasReadPermission(folderNodeRef);
then(permissionServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getRuleSetNode(folderNodeRef);
then(ruleServiceMock).should().isRuleSetShared(ruleSetNodeRef);
then(ruleServiceMock).should().getRules(folderNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(rulesPage)
@@ -235,6 +242,7 @@ public class RulesImplTest extends TestCase
then(permissionServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(ruleNodeRef, ruleSetNodeRef);
then(ruleServiceMock).should().isRuleSetShared(ruleSetNodeRef);
then(ruleServiceMock).should().getRule(ruleNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(rule)
@@ -264,7 +272,8 @@ public class RulesImplTest extends TestCase
then(permissionServiceMock).shouldHaveNoMoreInteractions();
then(ruleServiceMock).should().getRuleSetNode(folderNodeRef);
then(ruleServiceMock).should().isRuleAssociatedWithRuleSet(ruleNodeRef, ruleSetNodeRef);
then(ruleServiceMock).should().getRule(eq(ruleNodeRef));
then(ruleServiceMock).should().isRuleSetShared(ruleSetNodeRef);
then(ruleServiceMock).should().getRule(ruleNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(rule)
.isNotNull()
@@ -301,14 +310,16 @@ public class RulesImplTest extends TestCase
org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class);
given(ruleServiceMock.saveRule(folderNodeRef, serviceRuleBody)).willReturn(serviceRule);
given(serviceRule.getNodeRef()).willReturn(ruleNodeRef);
given(serviceRule.getAction()).willReturn(action);
// when
List<Rule> actual = rules.createRules(folderNodeRef.getId(), ruleSetNodeRef.getId(), ruleList);
then(ruleServiceMock).should().isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef);
then(ruleServiceMock).should().isRuleSetShared(ruleSetNodeRef);
then(ruleServiceMock).should().saveRule(folderNodeRef, ruleBody.toServiceModel(nodesMock));
then(ruleServiceMock).shouldHaveNoMoreInteractions();
List<Rule> expected = List.of(Rule.from(serviceRule));
List<Rule> expected = List.of(Rule.from(serviceRule, false));
assertThat(actual).isEqualTo(expected);
}
@@ -320,24 +331,27 @@ public class RulesImplTest extends TestCase
List<Rule> ruleList = List.of(ruleBody);
org.alfresco.service.cmr.rule.Rule serviceRuleBody = mock(org.alfresco.service.cmr.rule.Rule.class);
given(ruleBody.toServiceModel(nodesMock)).willReturn(serviceRuleBody);
given(ruleServiceMock.getRuleSetNode(any())).willReturn(ruleSetNodeRef);
org.alfresco.service.cmr.rule.Rule serviceRule = mock(org.alfresco.service.cmr.rule.Rule.class);
given(ruleServiceMock.saveRule(folderNodeRef, serviceRuleBody)).willReturn(serviceRule);
given(serviceRule.getNodeRef()).willReturn(ruleNodeRef);
given(serviceRule.getAction()).willReturn(action);
// when
List<Rule> actual = rules.createRules(folderNodeRef.getId(), DEFAULT_ID, ruleList);
then(ruleServiceMock).should().getRuleSetNode(folderNodeRef);
then(ruleServiceMock).should().isRuleSetShared(ruleSetNodeRef);
then(ruleServiceMock).should().saveRule(folderNodeRef, ruleBody.toServiceModel(nodesMock));
then(ruleServiceMock).shouldHaveNoMoreInteractions();
List<Rule> expected = List.of(Rule.from(serviceRule));
List<Rule> expected = List.of(Rule.from(serviceRule, false));
assertThat(actual).isEqualTo(expected);
}
@Test
public void testSaveRules_ruleSetNotAssociatedWithFolder()
{
Rule rule = Rule.builder().setName(RULE_NAME)
.createRule();
Rule rule = Rule.builder().name(RULE_NAME).create();
List<Rule> ruleList = List.of(rule);
given(ruleServiceMock.isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef)).willReturn(false);
@@ -380,7 +394,8 @@ public class RulesImplTest extends TestCase
given(ruleServiceMock.saveRule(folderNodeRef, serviceRuleBody)).willReturn(serviceRule);
NodeRef ruleNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, ruleId);
given(serviceRule.getNodeRef()).willReturn(ruleNodeRef);
expected.add(Rule.from(serviceRule));
given(serviceRule.getAction()).willReturn(action);
expected.add(Rule.from(serviceRule, false));
}
// when
@@ -391,6 +406,7 @@ public class RulesImplTest extends TestCase
{
then(ruleServiceMock).should().saveRule(folderNodeRef, ruleBody.toServiceModel(nodesMock));
}
then(ruleServiceMock).should(times(ruleBodyList.size())).isRuleSetShared(ruleSetNodeRef);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
assertThat(actual).isEqualTo(expected);
}
@@ -552,8 +568,11 @@ public class RulesImplTest extends TestCase
private static org.alfresco.service.cmr.rule.Rule createRule(final String id) {
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id);
final org.alfresco.service.cmr.rule.Rule rule = new org.alfresco.service.cmr.rule.Rule();
rule.setNodeRef(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, id));
rule.setNodeRef(nodeRef);
rule.setRuleType("ruleType");
rule.setAction(action);
return rule;
}

View File

@@ -0,0 +1,116 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.model.rules;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import org.alfresco.repo.action.ActionConditionImpl;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.action.executer.ScriptActionExecuter;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionCondition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.rule.RuleType;
import org.assertj.core.api.Condition;
import org.junit.Test;
@Experimental
public class RuleTest
{
private static final String RULE_ID = "fake-rule-id";
private static final String RULE_NAME = "rule name";
private static final String RULE_DESCRIPTION = "rule description";
private static final boolean RULE_ENABLED = true;
private static final boolean RULE_CASCADE = true;
private static final boolean RULE_ASYNC = false;
private static final boolean RULE_SHARED = true;
private static final String ERROR_SCRIPT = "error-script-ref";
@Test
public void testFrom()
{
final org.alfresco.service.cmr.rule.Rule ruleModel = createRuleModel();
final Rule expectedRule = createRuleWithDefaultValues();
// when
final Rule actualRule = Rule.from(ruleModel, RULE_SHARED);
assertThat(actualRule).isNotNull().usingRecursiveComparison().isEqualTo(expectedRule);
}
@Test
public void testFromRuleModelWithNullValues()
{
final org.alfresco.service.cmr.rule.Rule ruleModel = new org.alfresco.service.cmr.rule.Rule();
final Rule expectedRule = Rule.builder().enabled(true).create();
// when
final Rule actualRule = Rule.from(ruleModel, false);
assertThat(actualRule).isNotNull().usingRecursiveComparison().isEqualTo(expectedRule);
}
private static org.alfresco.service.cmr.rule.Rule createRuleModel() {
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_ID);
final org.alfresco.service.cmr.rule.Rule ruleModel = new org.alfresco.service.cmr.rule.Rule(nodeRef);
ruleModel.setTitle(RULE_NAME);
ruleModel.setDescription(RULE_DESCRIPTION);
ruleModel.setRuleDisabled(!RULE_ENABLED);
ruleModel.applyToChildren(RULE_CASCADE);
ruleModel.setExecuteAsynchronously(RULE_ASYNC);
ruleModel.setRuleTypes(List.of(RuleType.INBOUND, RuleType.UPDATE));
final Action compensatingAction = new ActionImpl(nodeRef, "compensatingActionId", "compensatingActionDefName");
compensatingAction.setParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF, ERROR_SCRIPT);
final ActionCondition actionCondition = new ActionConditionImpl("actionConditionId", "actionConditionDefName");
final Action action = new ActionImpl(nodeRef, "actionId", "actionDefName");
action.setCompensatingAction(compensatingAction);
action.addActionCondition(actionCondition);
ruleModel.setAction(action);
return ruleModel;
}
private static Rule createRuleWithDefaultValues() {
return Rule.builder()
.id(RULE_ID)
.name(RULE_NAME)
.description(RULE_DESCRIPTION)
.enabled(RULE_ENABLED)
.cascade(RULE_CASCADE)
.asynchronous(RULE_ASYNC)
.shared(RULE_SHARED)
.triggers(List.of(RuleTrigger.INBOUND, RuleTrigger.UPDATE))
.errorScript(ERROR_SCRIPT)
.create();
}
}

View File

@@ -25,6 +25,15 @@
*/
package org.alfresco.repo.rule;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.action.ActionModel;
@@ -65,15 +74,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.ParameterCheck;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Rule service implementation.
* <p>
@@ -1616,13 +1616,9 @@ public class RuleServiceImpl
@Override
@Experimental
public NodeRef getRuleSetNode(final NodeRef folderNodeRef) {
return getPrimaryChildNode(folderNodeRef, RuleModel.ASSOC_RULE_FOLDER);
}
private NodeRef getPrimaryChildNode(final NodeRef nodeRef, final QNamePattern associationType) {
return runtimeNodeService.getChildAssocs(nodeRef, associationType, associationType).stream()
.filter(ChildAssociationRef::isPrimary)
public NodeRef getRuleSetNode(final NodeRef folderNodeRef)
{
return runtimeNodeService.getChildAssocs(folderNodeRef, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER).stream()
.map(ChildAssociationRef::getChildRef)
.findFirst()
.orElse(null);
@@ -1630,17 +1626,20 @@ public class RuleServiceImpl
@Override
@Experimental
public boolean isRuleSetAssociatedWithFolder(final NodeRef ruleSetNodeRef, final NodeRef folderNodeRef) {
public boolean isRuleSetAssociatedWithFolder(final NodeRef ruleSetNodeRef, final NodeRef folderNodeRef)
{
return isChildOf(ruleSetNodeRef, RuleModel.ASSOC_RULE_FOLDER, folderNodeRef);
}
@Override
@Experimental
public boolean isRuleAssociatedWithRuleSet(final NodeRef ruleNodeRef, final NodeRef ruleSetNodeRef) {
public boolean isRuleAssociatedWithRuleSet(final NodeRef ruleNodeRef, final NodeRef ruleSetNodeRef)
{
return isChildOf(ruleNodeRef, null, ruleSetNodeRef);
}
private boolean isChildOf(final NodeRef childNodeRef, final QNamePattern associationType, final NodeRef parentNodeRef) {
private boolean isChildOf(final NodeRef childNodeRef, final QNamePattern associationType, final NodeRef parentNodeRef)
{
final List<ChildAssociationRef> associations;
if (associationType == null) {
associations = runtimeNodeService.getParentAssocs(childNodeRef);
@@ -1652,4 +1651,12 @@ public class RuleServiceImpl
.map(ChildAssociationRef::getParentRef)
.anyMatch(parentNodeRef::equals);
}
@Override
@Experimental
public boolean isRuleSetShared(final NodeRef ruleSetNodeRef)
{
return runtimeNodeService.getParentAssocs(ruleSetNodeRef).stream()
.anyMatch(association -> !association.isPrimary());
}
}

View File

@@ -362,4 +362,14 @@ public interface RuleService
@Auditable(parameters = {"ruleNodeRef", "ruleSetNodeRef"})
@Experimental
boolean isRuleAssociatedWithRuleSet(final NodeRef ruleNodeRef, final NodeRef ruleSetNodeRef);
/**
* Check if others folders are linked to rule set.
*
* @param ruleSetNodeRef - node reference of a rule set
* @return true if others folders are linked to rule set
*/
@Auditable(parameters = {"ruleSetNodeRef"})
@Experimental
boolean isRuleSetShared(final NodeRef ruleSetNodeRef);
}

View File

@@ -25,6 +25,12 @@
*/
package org.alfresco.repo.rule;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
@@ -51,12 +57,6 @@ import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Parameter definition implementation unit test.
*
@@ -364,6 +364,19 @@ public class RuleLinkTest extends BaseSpringTest
assertEquals(expectedRuleSetNodeRef, ruleSetNodeRef);
}
@Test
public void testGetRuleSetNodeForLinkedFolder() {
final Rule rule = createTestRule(false, "luke");
this.ruleService.saveRule(folderOne, rule);
link(folderOne, folderTwo);
final NodeRef expectedRuleSetNodeRef = getRuleSetNode(folderOne);
final NodeRef ruleSetNodeRef = ruleService.getRuleSetNode(folderTwo);
assertNotNull(ruleSetNodeRef);
assertEquals(expectedRuleSetNodeRef, ruleSetNodeRef);
}
@Test
public void testIsRuleSetAssociatedWithFolder()
{
@@ -425,6 +438,33 @@ public class RuleLinkTest extends BaseSpringTest
assertFalse(associated);
}
@Test
public void testIsRuleSetShared()
{
final Rule rule = createTestRule(false, "luke");
this.ruleService.saveRule(folderOne, rule);
link(folderOne, folderTwo);
final NodeRef ruleSetNodeRef = ruleService.getRuleSetNode(folderOne);
// when
final boolean shared = ruleService.isRuleSetShared(ruleSetNodeRef);
assertTrue(shared);
}
@Test
public void testIsRuleSetNotShared()
{
final Rule rule = createTestRule(false, "luke");
this.ruleService.saveRule(folderOne, rule);
final NodeRef ruleSetNodeRef = ruleService.getRuleSetNode(folderOne);
// when
final boolean shared = ruleService.isRuleSetShared(ruleSetNodeRef);
assertFalse(shared);
}
protected Rule createTestRule(boolean isAppliedToChildren, String title)
{
// Rule properties