You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by sh...@apache.org on 2021/06/24 16:39:50 UTC

[unomi] branch UNOMI-492-fix-rule-null-actions created (now 23017ec)

This is an automated email from the ASF dual-hosted git repository.

shuber pushed a change to branch UNOMI-492-fix-rule-null-actions
in repository https://gitbox.apache.org/repos/asf/unomi.git.


      at 23017ec  UNOMI-492 Make rules engine more robust when some rules are invalid (null actions) - Make sure we handle null actions gracefully instead of generating a NPE and blocking loading of further rules - Add an integration test to test the case of null actions in rule - Improve logging when rules have null or empty conditions and actions

This branch includes the following new commits:

     new 23017ec  UNOMI-492 Make rules engine more robust when some rules are invalid (null actions) - Make sure we handle null actions gracefully instead of generating a NPE and blocking loading of further rules - Add an integration test to test the case of null actions in rule - Improve logging when rules have null or empty conditions and actions

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[unomi] 01/01: UNOMI-492 Make rules engine more robust when some rules are invalid (null actions) - Make sure we handle null actions gracefully instead of generating a NPE and blocking loading of further rules - Add an integration test to test the case of null actions in rule - Improve logging when rules have null or empty conditions and actions

Posted by sh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

shuber pushed a commit to branch UNOMI-492-fix-rule-null-actions
in repository https://gitbox.apache.org/repos/asf/unomi.git

commit 23017eca2f19808bab6ebd4ec7669dc6b82fad9c
Author: Serge Huber <sh...@jahia.com>
AuthorDate: Thu Jun 24 18:39:24 2021 +0200

    UNOMI-492 Make rules engine more robust when some rules are invalid (null actions)
    - Make sure we handle null actions gracefully instead of generating a NPE and blocking loading of further rules
    - Add an integration test to test the case of null actions in rule
    - Improve logging when rules have null or empty conditions and actions
---
 .../org/apache/unomi/itests/RuleServiceIT.java     | 85 ++++++++++++++++++++++
 .../apache/unomi/services/impl/ParserHelper.java   | 21 +++++-
 .../impl/definitions/DefinitionsServiceImpl.java   |  8 +-
 .../services/impl/events/EventServiceImpl.java     |  2 +-
 .../services/impl/goals/GoalsServiceImpl.java      | 18 +++--
 .../services/impl/profiles/ProfileServiceImpl.java |  4 +-
 .../services/impl/queries/QueryServiceImpl.java    |  8 +-
 .../services/impl/rules/RulesServiceImpl.java      | 16 ++--
 .../services/impl/segments/SegmentServiceImpl.java | 12 +--
 9 files changed, 135 insertions(+), 39 deletions(-)

diff --git a/itests/src/test/java/org/apache/unomi/itests/RuleServiceIT.java b/itests/src/test/java/org/apache/unomi/itests/RuleServiceIT.java
new file mode 100644
index 0000000..2dfc21b
--- /dev/null
+++ b/itests/src/test/java/org/apache/unomi/itests/RuleServiceIT.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package org.apache.unomi.itests;
+
+import org.apache.unomi.api.Metadata;
+import org.apache.unomi.api.rules.Rule;
+import org.apache.unomi.api.services.DefinitionsService;
+import org.apache.unomi.api.services.RulesService;
+import org.apache.unomi.persistence.spi.PersistenceService;
+import org.junit.Before;
+import org.junit.Test;
+import org.ops4j.pax.exam.util.Filter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Integration tests for the Unomi rule service.
+ */
+public class RuleServiceIT extends BaseIT {
+
+    private final static Logger LOGGER = LoggerFactory.getLogger(RuleServiceIT.class);
+
+    private final static String TEST_RULE_ID = "test-rule-id";
+    public static final String TEST_SCOPE = "test-scope";
+
+    @Inject
+    @Filter(timeout = 600000)
+    protected RulesService rulesService;
+
+    @Inject
+    @Filter(timeout = 600000)
+    protected PersistenceService persistenceService;
+
+    @Inject
+    @Filter(timeout = 600000)
+    protected DefinitionsService definitionsService;
+
+    @Before
+    public void setUp() {
+        TestUtils.removeAllProfiles(definitionsService, persistenceService);
+    }
+
+    @Test
+    public void testRuleWithNullActions() throws InterruptedException {
+        Set<Metadata> ruleMetadatas = rulesService.getRuleMetadatas();
+        int initialRuleCount = ruleMetadatas.size();
+        Metadata metadata = new Metadata(TEST_RULE_ID);
+        metadata.setName(TEST_RULE_ID + "_name");
+        metadata.setDescription(TEST_RULE_ID + "_description");
+        metadata.setScope(TEST_SCOPE);
+        Rule nullRule = new Rule(metadata);
+        nullRule.setCondition(null);
+        nullRule.setActions(null);
+        rulesService.setRule(nullRule);
+        LOGGER.info("Waiting for rules to refresh from persistence...");
+        int loopCount = 0;
+        int lastRuleCount = initialRuleCount;
+        while (loopCount < 20 && lastRuleCount == initialRuleCount) {
+            Thread.sleep(1000);
+            ruleMetadatas = rulesService.getRuleMetadatas();
+            lastRuleCount = ruleMetadatas.size();
+            loopCount++;
+        }
+        assertEquals("Rule not properly saved", initialRuleCount + 1, lastRuleCount);
+    }
+}
diff --git a/services/src/main/java/org/apache/unomi/services/impl/ParserHelper.java b/services/src/main/java/org/apache/unomi/services/impl/ParserHelper.java
index a861f6c..ef9b9de 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/ParserHelper.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/ParserHelper.java
@@ -23,6 +23,7 @@ import org.apache.unomi.api.actions.Action;
 import org.apache.unomi.api.actions.ActionType;
 import org.apache.unomi.api.conditions.Condition;
 import org.apache.unomi.api.conditions.ConditionType;
+import org.apache.unomi.api.rules.Rule;
 import org.apache.unomi.api.services.DefinitionsService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -39,8 +40,9 @@ public class ParserHelper {
     private static final Set<String> unresolvedActionTypes = new HashSet<>();
     private static final Set<String> unresolvedConditionTypes = new HashSet<>();
 
-    public static boolean resolveConditionType(final DefinitionsService definitionsService, Condition rootCondition) {
+    public static boolean resolveConditionType(final DefinitionsService definitionsService, Condition rootCondition, String contextObjectName) {
         if (rootCondition == null) {
+            logger.warn("Couldn't resolve null condition for {}", contextObjectName);
             return false;
         }
         final List<String> result = new ArrayList<String>();
@@ -56,7 +58,7 @@ public class ParserHelper {
                         result.add(condition.getConditionTypeId());
                         if (!unresolvedConditionTypes.contains(condition.getConditionTypeId())) {
                             unresolvedConditionTypes.add(condition.getConditionTypeId());
-                            logger.warn("Couldn't resolve condition type: " + condition.getConditionTypeId());
+                            logger.warn("Couldn't resolve condition type: {} for {}", condition.getConditionTypeId(), contextObjectName);
                         }
                     }
                 }
@@ -96,15 +98,26 @@ public class ParserHelper {
         }
     }
 
-    public static boolean resolveActionTypes(DefinitionsService definitionsService, List<Action> actions) {
+    public static boolean resolveActionTypes(DefinitionsService definitionsService, Rule rule) {
         boolean result = true;
-        for (Action action : actions) {
+        if (rule.getActions() == null) {
+            logger.warn("Rule {}:{} has null actions", rule.getItemId(), rule.getMetadata().getName());
+            return false;
+        }
+        if (rule.getActions().isEmpty()) {
+            logger.warn("Rule {}:{} has empty actions", rule.getItemId(), rule.getMetadata().getName());
+            return result;
+        }
+        for (Action action : rule.getActions()) {
             result &= ParserHelper.resolveActionType(definitionsService, action);
         }
         return result;
     }
 
     public static boolean resolveActionType(DefinitionsService definitionsService, Action action) {
+        if (definitionsService == null) {
+            return false;
+        }
         if (action.getActionType() == null) {
             ActionType actionType = definitionsService.getActionType(action.getActionTypeId());
             if (actionType != null) {
diff --git a/services/src/main/java/org/apache/unomi/services/impl/definitions/DefinitionsServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/definitions/DefinitionsServiceImpl.java
index 04a7674..8cb4e8f 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/definitions/DefinitionsServiceImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/definitions/DefinitionsServiceImpl.java
@@ -276,7 +276,7 @@ public class DefinitionsServiceImpl implements DefinitionsService, SynchronousBu
         Collection<ConditionType> all = persistenceService.getAllItems(ConditionType.class);
         for (ConditionType type : all) {
             if (type != null && type.getParentCondition() != null) {
-                ParserHelper.resolveConditionType(this, type.getParentCondition());
+                ParserHelper.resolveConditionType(this, type.getParentCondition(), "condition type " + type.getItemId());
             }
         }
         return all;
@@ -295,7 +295,7 @@ public class DefinitionsServiceImpl implements DefinitionsService, SynchronousBu
         List<ConditionType> directConditionTypes = persistenceService.query(fieldName, fieldValue,null, ConditionType.class);
         for (ConditionType type : directConditionTypes) {
             if (type.getParentCondition() != null) {
-                ParserHelper.resolveConditionType(this, type.getParentCondition());
+                ParserHelper.resolveConditionType(this, type.getParentCondition(), "condition type " + type.getItemId());
             }
         }
         conditionTypes.addAll(directConditionTypes);
@@ -315,7 +315,7 @@ public class DefinitionsServiceImpl implements DefinitionsService, SynchronousBu
             }
         }
         if (type != null && type.getParentCondition() != null) {
-            ParserHelper.resolveConditionType(this, type.getParentCondition());
+            ParserHelper.resolveConditionType(this, type.getParentCondition(), "condition type " + type.getItemId());
         }
         return type;
     }
@@ -515,7 +515,7 @@ public class DefinitionsServiceImpl implements DefinitionsService, SynchronousBu
 
     @Override
     public boolean resolveConditionType(Condition rootCondition) {
-        return ParserHelper.resolveConditionType(this, rootCondition);
+        return ParserHelper.resolveConditionType(this, rootCondition, (rootCondition != null ? "condition type " + rootCondition.getConditionTypeId() : "unknown"));
     }
 
     @Override
diff --git a/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java
index a163d32..ced1351 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java
@@ -312,7 +312,7 @@ public class EventServiceImpl implements EventService {
 
     @Override
     public PartialList<Event> searchEvents(Condition condition, int offset, int size) {
-        ParserHelper.resolveConditionType(definitionsService, condition);
+        ParserHelper.resolveConditionType(definitionsService, condition, "event search");
         return persistenceService.query(condition, "timeStamp", Event.class, offset, size);
     }
 
diff --git a/services/src/main/java/org/apache/unomi/services/impl/goals/GoalsServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/goals/GoalsServiceImpl.java
index 4a802ba..fcf3afc 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/goals/GoalsServiceImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/goals/GoalsServiceImpl.java
@@ -215,8 +215,8 @@ public class GoalsServiceImpl implements GoalsService, SynchronousBundleListener
     public Goal getGoal(String goalId) {
         Goal goal = persistenceService.load(goalId, Goal.class);
         if (goal != null) {
-            ParserHelper.resolveConditionType(definitionsService, goal.getStartEvent());
-            ParserHelper.resolveConditionType(definitionsService, goal.getTargetEvent());
+            ParserHelper.resolveConditionType(definitionsService, goal.getStartEvent(), "goal "+goalId+" start event");
+            ParserHelper.resolveConditionType(definitionsService, goal.getTargetEvent(), "goal "+goalId+" target event");
         }
         return goal;
     }
@@ -230,8 +230,12 @@ public class GoalsServiceImpl implements GoalsService, SynchronousBundleListener
 
     @Override
     public void setGoal(Goal goal) {
-        ParserHelper.resolveConditionType(definitionsService, goal.getStartEvent());
-        ParserHelper.resolveConditionType(definitionsService, goal.getTargetEvent());
+        if (goal == null) {
+            logger.warn("Trying to save null goal, aborting...");
+            return;
+        }
+        ParserHelper.resolveConditionType(definitionsService, goal.getStartEvent(), "goal "+goal.getItemId()+" start event");
+        ParserHelper.resolveConditionType(definitionsService, goal.getTargetEvent(), "goal "+goal.getItemId()+" start event");
 
         if (goal.getMetadata().isEnabled()) {
             if (goal.getStartEvent() != null) {
@@ -398,7 +402,7 @@ public class GoalsServiceImpl implements GoalsService, SynchronousBundleListener
     public Campaign getCampaign(String id) {
         Campaign campaign = persistenceService.load(id, Campaign.class);
         if (campaign != null) {
-            ParserHelper.resolveConditionType(definitionsService, campaign.getEntryCondition());
+            ParserHelper.resolveConditionType(definitionsService, campaign.getEntryCondition(), "campaign " + id);
         }
         return campaign;
     }
@@ -412,7 +416,7 @@ public class GoalsServiceImpl implements GoalsService, SynchronousBundleListener
     }
 
     public void setCampaign(Campaign campaign) {
-        ParserHelper.resolveConditionType(definitionsService, campaign.getEntryCondition());
+        ParserHelper.resolveConditionType(definitionsService, campaign.getEntryCondition(), "campaign " + campaign.getItemId());
 
         if(rulesService.getRule(campaign.getMetadata().getId() + "EntryEvent") != null) {
             rulesService.removeRule(campaign.getMetadata().getId() + "EntryEvent");
@@ -457,7 +461,7 @@ public class GoalsServiceImpl implements GoalsService, SynchronousBundleListener
         }
 
         if (query != null && query.getCondition() != null) {
-            ParserHelper.resolveConditionType(definitionsService, query.getCondition());
+            ParserHelper.resolveConditionType(definitionsService, query.getCondition(), "goal " + goalId + " report");
             list.add(query.getCondition());
         }
 
diff --git a/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java
index 38356cf..90c0c86 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java
@@ -796,7 +796,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList
 
     @Override
     public boolean matchCondition(Condition condition, Profile profile, Session session) {
-        ParserHelper.resolveConditionType(definitionsService, condition);
+        ParserHelper.resolveConditionType(definitionsService, condition, "profile " + profile.getItemId() + " matching");
 
         if (condition.getConditionTypeId().equals("booleanCondition")) {
             List<Condition> subConditions = (List<Condition>) condition.getParameter("subConditions");
@@ -821,7 +821,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList
     }
 
     public void batchProfilesUpdate(BatchUpdate update) {
-        ParserHelper.resolveConditionType(definitionsService, update.getCondition());
+        ParserHelper.resolveConditionType(definitionsService, update.getCondition(), "batch update on property " + update.getPropertyName());
         List<Profile> profiles = persistenceService.query(update.getCondition(), null, Profile.class);
 
         for (Profile profile : profiles) {
diff --git a/services/src/main/java/org/apache/unomi/services/impl/queries/QueryServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/queries/QueryServiceImpl.java
index ca278eb..c9317ee 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/queries/QueryServiceImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/queries/QueryServiceImpl.java
@@ -74,7 +74,7 @@ public class QueryServiceImpl implements QueryService {
     @Override
     public Map<String, Double> getMetric(String type, String property, String slashConcatenatedMetrics, Condition condition) {
         if (condition.getConditionType() == null) {
-            ParserHelper.resolveConditionType(definitionsService, condition);
+            ParserHelper.resolveConditionType(definitionsService, condition, "metric " + type + " on property " + property);
         }
         return persistenceService.getSingleValuesMetrics(condition, slashConcatenatedMetrics.split("/"), property, type);
     }
@@ -82,7 +82,7 @@ public class QueryServiceImpl implements QueryService {
     @Override
     public long getQueryCount(String itemType, Condition condition) {
         if (condition.getConditionType() == null) {
-            ParserHelper.resolveConditionType(definitionsService, condition);
+            ParserHelper.resolveConditionType(definitionsService, condition, "query count on " +itemType);
         }
         return persistenceService.queryCount(condition, itemType);
     }
@@ -90,9 +90,7 @@ public class QueryServiceImpl implements QueryService {
     private Map<String, Long> getAggregate(String itemType, String property, AggregateQuery query, boolean optimizedQuery) {
         if (query != null) {
             // resolve condition
-            if (query.getCondition() != null) {
-                ParserHelper.resolveConditionType(definitionsService, query.getCondition());
-            }
+            ParserHelper.resolveConditionType(definitionsService, query.getCondition(), "aggregate on property " + property + " for type " + itemType);
 
             // resolve aggregate
             BaseAggregate baseAggregate = null;
diff --git a/services/src/main/java/org/apache/unomi/services/impl/rules/RulesServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/rules/RulesServiceImpl.java
index 8ccc767..4c601d2 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/rules/RulesServiceImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/rules/RulesServiceImpl.java
@@ -243,8 +243,8 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn
     private List<Rule> getAllRules() {
         List<Rule> allItems = persistenceService.getAllItems(Rule.class, 0, -1, "priority").getList();
         for (Rule rule : allItems) {
-            ParserHelper.resolveConditionType(definitionsService, rule.getCondition());
-            ParserHelper.resolveActionTypes(definitionsService, rule.getActions());
+            ParserHelper.resolveConditionType(definitionsService, rule.getCondition(), "rule " + rule.getItemId());
+            ParserHelper.resolveActionTypes(definitionsService, rule);
         }
         return allItems;
     }
@@ -334,12 +334,8 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn
     public Rule getRule(String ruleId) {
         Rule rule = persistenceService.load(ruleId, Rule.class);
         if (rule != null) {
-            if (rule.getCondition() != null) {
-                ParserHelper.resolveConditionType(definitionsService, rule.getCondition());
-            }
-            if (rule.getActions() != null) {
-                ParserHelper.resolveActionTypes(definitionsService, rule.getActions());
-            }
+            ParserHelper.resolveConditionType(definitionsService, rule.getCondition(), "rule " + rule.getItemId());
+            ParserHelper.resolveActionTypes(definitionsService, rule);
         }
         return rule;
     }
@@ -351,7 +347,7 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn
         Condition condition = rule.getCondition();
         if (condition != null) {
             if (rule.getMetadata().isEnabled() && !rule.getMetadata().isMissingPlugins()) {
-                ParserHelper.resolveConditionType(definitionsService, condition);
+                ParserHelper.resolveConditionType(definitionsService, condition, "rule " + rule.getItemId());
                 definitionsService.extractConditionBySystemTag(condition, "eventCondition");
             }
         }
@@ -368,7 +364,7 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn
             if(trackedCondition != null){
                 Condition sourceEventPropertyCondition = definitionsService.extractConditionBySystemTag(r.getCondition(), "sourceEventCondition");
                 if(source != null && sourceEventPropertyCondition != null) {
-                    ParserHelper.resolveConditionType(definitionsService, sourceEventPropertyCondition);
+                    ParserHelper.resolveConditionType(definitionsService, sourceEventPropertyCondition, "rule " + r.getItemId() + " source event condition");
                     if(persistenceService.testMatch(sourceEventPropertyCondition, source)){
                         trackedConditions.add(trackedCondition);
                     }
diff --git a/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java
index 385ab08..fba8e16 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java
@@ -243,7 +243,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe
     private List<Segment> getAllSegmentDefinitions() {
         List<Segment> allItems = persistenceService.getAllItems(Segment.class);
         for (Segment segment : allItems) {
-            ParserHelper.resolveConditionType(definitionsService, segment.getCondition());
+            ParserHelper.resolveConditionType(definitionsService, segment.getCondition(), "segment " + segment.getItemId());
         }
         return allItems;
     }
@@ -251,13 +251,13 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe
     public Segment getSegmentDefinition(String segmentId) {
         Segment definition = persistenceService.load(segmentId, Segment.class);
         if (definition != null) {
-            ParserHelper.resolveConditionType(definitionsService, definition.getCondition());
+            ParserHelper.resolveConditionType(definitionsService, definition.getCondition(), "segment " + segmentId);
         }
         return definition;
     }
 
     public void setSegmentDefinition(Segment segment) {
-        ParserHelper.resolveConditionType(definitionsService, segment.getCondition());
+        ParserHelper.resolveConditionType(definitionsService, segment.getCondition(), "segment " + segment.getItemId());
         if (!persistenceService.isValidCondition(segment.getCondition(), new Profile())) {
             throw new BadSegmentConditionException();
         }
@@ -533,7 +533,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe
         List<Scoring> allItems = persistenceService.getAllItems(Scoring.class);
         for (Scoring scoring : allItems) {
             for (ScoringElement element : scoring.getElements()) {
-                ParserHelper.resolveConditionType(definitionsService, element.getCondition());
+                ParserHelper.resolveConditionType(definitionsService, element.getCondition(), "scoring " + scoring.getItemId());
             }
         }
         return allItems;
@@ -543,7 +543,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe
         Scoring definition = persistenceService.load(scoringId, Scoring.class);
         if (definition != null) {
             for (ScoringElement element : definition.getElements()) {
-                ParserHelper.resolveConditionType(definitionsService, element.getCondition());
+                ParserHelper.resolveConditionType(definitionsService, element.getCondition(), "scoring " + scoringId);
             }
         }
         return definition;
@@ -551,7 +551,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe
 
     public void setScoringDefinition(Scoring scoring) {
         for (ScoringElement element : scoring.getElements()) {
-            ParserHelper.resolveConditionType(definitionsService, element.getCondition());
+            ParserHelper.resolveConditionType(definitionsService, element.getCondition(), "scoring " + scoring.getItemId() + " element ");
         }
         for (ScoringElement element : scoring.getElements()) {
             if (scoring.getMetadata().isEnabled() && !scoring.getMetadata().isMissingPlugins()) {