context.verifyForActivation();
List<ActiveRuleChange> changes = Lists.newArrayList();
ActiveRuleChange change;
+ boolean stopPropagation = false;
+
if (context.activeRule() == null) {
+ // new activation
change = new ActiveRuleChange(ActiveRuleChange.Type.ACTIVATED, activation.getKey());
-
- //Rules crated by default Inheritance
if (activation.isCascade() || context.isSameAsParent(activation)) {
change.setInheritance(ActiveRule.Inheritance.INHERITED);
}
+ applySeverityAndParamToChange(activation, context, change);
+
} else {
- change = new ActiveRuleChange(ActiveRuleChange.Type.UPDATED, activation.getKey());
- // Stop propagation on overriding profiles
+ // already activated
+
if (activation.isCascade() && context.activeRule().doesOverride()) {
+ // propagating to descendants, but child profile already overrides rule -> stop propagation
return changes;
}
-
- //Updates on rule that exists with a valid parent switch them to OVERRIDE
- if (!activation.isCascade() && context.parentProfile() != null) {
- change.setInheritance(context.isSameAsParent(activation) ? ActiveRule.Inheritance.INHERITED : ActiveRule.Inheritance.OVERRIDES);
+ change = new ActiveRuleChange(ActiveRuleChange.Type.UPDATED, activation.getKey());
+ if (activation.isCascade() && context.activeRule().getInheritance() == null) {
+ // activate on child, then on parent -> mark child as overriding parent
+ change.setInheritance(ActiveRule.Inheritance.OVERRIDES);
+ change.setSeverity(context.activeRule().getSeverityString());
+ change.setParameters(context.activeRuleParamsAsStringMap());
+ stopPropagation = true;
+ } else {
+ applySeverityAndParamToChange(activation, context, change);
+ if (!activation.isCascade() && context.parentProfile() != null) {
+ // override rule which is already declared on parents
+ change.setInheritance(context.isSameAsParent(activation) ? ActiveRule.Inheritance.INHERITED : ActiveRule.Inheritance.OVERRIDES);
+ }
}
}
- // Severity and parameter values are :
- // 1. defined by end-user
- // 2. else inherited from parent profile
- // 3. else defined by rule defaults
- change.setSeverity(StringUtils.defaultIfEmpty(activation.getSeverity(), context.defaultSeverity()));
- for (RuleParamDto ruleParamDto : context.ruleParams()) {
- String value = StringUtils.defaultIfEmpty(
- activation.getParameters().get(ruleParamDto.getName()),
- context.defaultParam(ruleParamDto.getName()));
- verifyParam(ruleParamDto, value);
- change.setParameter(ruleParamDto.getName(), StringUtils.defaultIfEmpty(value, ruleParamDto.getDefaultValue()));
- }
-
changes.add(change);
- // TODO filter changes without any differences
-
persist(change, context, dbSession);
- // Execute the cascade on the child if NOT overrides
- changes.addAll(cascadeActivation(dbSession, activation));
+ if (!stopPropagation) {
+ changes.addAll(cascadeActivation(dbSession, activation));
+ }
if (!changes.isEmpty()) {
log.write(dbSession, Log.Type.ACTIVE_RULE, changes);
return changes;
}
+ /**
+ * Severity and parameter values are :
+ * 1. defined by end-user
+ * 2. else inherited from parent profile
+ * 3. else defined by rule defaults
+ */
+ private void applySeverityAndParamToChange(RuleActivation activation, RuleActivatorContext context, ActiveRuleChange change) {
+ change.setSeverity(StringUtils.defaultIfEmpty(activation.getSeverity(), context.defaultSeverity()));
+ for (RuleParamDto ruleParamDto : context.ruleParams()) {
+ String value = StringUtils.defaultIfEmpty(
+ activation.getParameters().get(ruleParamDto.getName()),
+ context.defaultParam(ruleParamDto.getName()));
+ verifyParam(ruleParamDto, value);
+ change.setParameter(ruleParamDto.getName(), StringUtils.defaultIfEmpty(value, ruleParamDto.getDefaultValue()));
+ }
+ }
+
private List<ActiveRuleChange> cascadeActivation(DbSession session, RuleActivation activation) {
List<ActiveRuleChange> changes = Lists.newArrayList();
// change on parent -> do not propagate on children because they're overriding values
activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
activation.setSeverity(Severity.CRITICAL);
- activation.setParameter("max", "10");
+ activation.setParameter("max", "9");
+ ruleActivator.activate(activation);
+ dbSession.clearCache();
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.CRITICAL, null, ImmutableMap.of("max", "9"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "8"));
+
+ // reset on parent (use default severity and params) -> do not propagate on children because they're overriding values
+ activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.CRITICAL, null, ImmutableMap.of("max", "10"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.MINOR, null, ImmutableMap.of("max", "10"));
verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "8"));
verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "8"));
}
+ @Test
+ public void active_on_parent_a_rule_already_activated_on_child() throws Exception {
+ createChildProfiles();
+
+ // activate on child profile
+ RuleActivation activation = new RuleActivation(ActiveRuleKey.of(XOO_CHILD_PROFILE_KEY, XOO_RULE_1));
+ activation.setSeverity(Severity.INFO);
+ activation.setParameter("max", "7");
+ ruleActivator.activate(activation);
+ verifyZeroActiveRules(XOO_PROFILE_KEY);
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+
+ // active the same rule on root profile -> mark the child profile as OVERRIDES
+ activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ activation.setSeverity(Severity.MAJOR);
+ activation.setParameter("max", "8");
+ ruleActivator.activate(activation);
+ dbSession.clearCache();
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.MAJOR, null, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ }
+
+
@Test
public void do_not_override_on_child_if_same_values() throws Exception {
createChildProfiles();
verifyZeroActiveRules(XOO_GRAND_CHILD_PROFILE_KEY);
}
+ @Test
+ public void propagate_deactivation_even_on_child_overrides() throws Exception {
+ createChildProfiles();
+
+ // activate on root profile
+ RuleActivation activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ activation.setSeverity(Severity.INFO);
+ activation.setParameter("max", "7");
+ ruleActivator.activate(activation);
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.INFO, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+
+ // override on child
+ activation = new RuleActivation(ActiveRuleKey.of(XOO_CHILD_PROFILE_KEY, XOO_RULE_1));
+ activation.setSeverity(Severity.BLOCKER);
+ activation.setParameter("max", "8");
+ ruleActivator.activate(activation);
+ dbSession.clearCache();
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.INFO, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "8"));
+
+ // deactivate on parent -> do not propagate on children because they're overriding values
+ ruleActivator.deactivate(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ dbSession.clearCache();
+ verifyZeroActiveRules(XOO_PROFILE_KEY);
+ verifyZeroActiveRules(XOO_CHILD_PROFILE_KEY);
+ verifyZeroActiveRules(XOO_GRAND_CHILD_PROFILE_KEY);
+ }
+
@Test
public void do_not_deactivate_inherited_or_overridden_rule() throws Exception {
createChildProfiles();
}
@Test
- public void bulk_activate_lot_of_rules() {
+ public void mass_activation() {
// Generate more rules than the search's max limit
int bulkSize = QueryOptions.MAX_LIMIT + 10;
for (int i = 0; i < bulkSize; i++) {