Search in sources :

Example 1 with Rule

use of com.peterphi.rules.types.Rule in project stdlib by petergeneric.

the class RulesEngineImpl method run.

@Override
public void run(final Rules rules, boolean ignoreMethodErrors) throws OgnlException {
    Map<String, Object> vars = prepare(rules);
    for (RuleSet rs : rules.ruleSets) {
        try {
            log.debug("Assessing input for ruleset : " + rs.id);
            OgnlContext rsContext = createContext(vars);
            rs.runInput(rsContext);
            for (Rule rule : rs.rules) {
                if (StringUtils.isEmpty(rule.id)) {
                    throw new IllegalArgumentException("Rule with condition " + rule.condition + " has no id!");
                }
                final RuleProcessTask task = new RuleProcessTask(this, rs, rule, rsContext);
                synchronized (activeTasks) {
                    // if not currently being processed
                    if (!activeTasks.containsKey(rule.id)) {
                        try {
                            activeTasks.put(rule.id, task);
                            task.submit(executorService);
                        } catch (Exception e) {
                            log.error("Error submitting rule for execution ", e);
                            activeTasks.remove(rule.id);
                        }
                    }
                }
            }
        } catch (MethodFailedException mfe) {
            if (!ignoreMethodErrors) {
                throw mfe;
            }
            log.warn("Method failed for ruleset " + rs.id, mfe);
        }
    }
}
Also used : RuleSet(com.peterphi.rules.types.RuleSet) Rule(com.peterphi.rules.types.Rule) MethodFailedException(ognl.MethodFailedException) MethodFailedException(ognl.MethodFailedException) OgnlException(ognl.OgnlException) OgnlContext(ognl.OgnlContext)

Example 2 with Rule

use of com.peterphi.rules.types.Rule in project stdlib by petergeneric.

the class RulesEngineImpl method matching.

/**
 * returns a list of the rules that match from the supplied Rules document
 *
 * @param rules
 *
 * @return
 */
@Override
public Map<RuleSet, List<Rule>> matching(Rules rules, Map<String, Object> vars, boolean ignoreMethodErrors) throws OgnlException {
    Map<RuleSet, List<Rule>> ret = new HashMap<>();
    for (RuleSet ruleSet : rules.ruleSets) {
        try {
            OgnlContext context = createContext(vars);
            List<Rule> matching = match(ruleSet, context);
            if (!matching.isEmpty()) {
                ret.put(ruleSet, matching);
            }
        } catch (MethodFailedException mfe) {
            if (!ignoreMethodErrors) {
                throw mfe;
            }
            log.warn("Method failed for ruleset " + ruleSet.id, mfe);
        }
    }
    return ret;
}
Also used : RuleSet(com.peterphi.rules.types.RuleSet) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ArrayList(java.util.ArrayList) List(java.util.List) Rule(com.peterphi.rules.types.Rule) MethodFailedException(ognl.MethodFailedException) OgnlContext(ognl.OgnlContext)

Example 3 with Rule

use of com.peterphi.rules.types.Rule in project stdlib by petergeneric.

the class RulesEngineImpl method execute.

@Override
public void execute(Map<RuleSet, List<Rule>> matchingrulesMap, Map<String, Object> vars) throws OgnlException {
    for (Map.Entry<RuleSet, List<Rule>> ruleSetListEntry : matchingrulesMap.entrySet()) {
        RuleSet rs = ruleSetListEntry.getKey();
        List<Rule> rules = ruleSetListEntry.getValue();
        for (Rule rule : rules) {
            OgnlContext context = createContext(vars);
            rs.runInput(context);
            if (rule.matches(context)) {
                rule.runCommands(context);
            } else {
                log.warn("Rule " + rule.id + " previously matched but doesn't any more");
            }
        }
    }
}
Also used : RuleSet(com.peterphi.rules.types.RuleSet) ArrayList(java.util.ArrayList) List(java.util.List) Rule(com.peterphi.rules.types.Rule) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) OgnlContext(ognl.OgnlContext)

Example 4 with Rule

use of com.peterphi.rules.types.Rule in project stdlib by petergeneric.

the class RulesEngineImpl method match.

/**
 * returns a list of rules that match in the given rule set
 *
 * @param ruleSet
 * @param ognlContext
 *
 * @return
 */
private List<Rule> match(final RuleSet ruleSet, final OgnlContext ognlContext) throws OgnlException {
    log.debug("Assessing input for ruleset : " + ruleSet.id);
    // run the input commands
    ruleSet.runInput(ognlContext);
    final List<Rule> ret = new ArrayList<>();
    // assess each rule against the input, return any that match
    for (Rule rule : ruleSet.rules) {
        Boolean bresult = rule.assessMatch(ognlContext);
        if (bresult) {
            log.debug(rule.condition.getOriginalExpression() + " matches");
            ret.add(rule);
        }
    }
    return ret;
}
Also used : ArrayList(java.util.ArrayList) Rule(com.peterphi.rules.types.Rule)

Example 5 with Rule

use of com.peterphi.rules.types.Rule in project stdlib by petergeneric.

the class RulesEngineImpl method validateSyntax.

@Override
public Map<String, String> validateSyntax(final Rules rules) {
    Map<String, String> results = new HashMap<>();
    Set<String> knownIds = new HashSet<>();
    for (RuleSet ruleSet : rules.ruleSets) {
        if (knownIds.contains(ruleSet.id)) {
            throw new IllegalArgumentException("Duplicate id " + ruleSet.id);
        }
        for (OgnlCommand command : ruleSet.input.commands) {
            validate(ruleSet.id + " - input", command, results);
        }
        for (Rule rule : ruleSet.rules) {
            if (StringUtils.isEmpty(rule.id)) {
                throw new IllegalArgumentException("Rule with condition " + rule.condition + " has no id!");
            }
            if (knownIds.contains(rule.id)) {
                throw new IllegalArgumentException("Duplicate id " + rule.id);
            }
            validate(rule.id + " condition", rule.condition, results);
            for (OgnlCommand command : rule.commands) {
                validate(rule.id, command, results);
            }
        }
    }
    return results;
}
Also used : RuleSet(com.peterphi.rules.types.RuleSet) OgnlCommand(com.peterphi.rules.types.OgnlCommand) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Rule(com.peterphi.rules.types.Rule) HashSet(java.util.HashSet)

Aggregations

Rule (com.peterphi.rules.types.Rule)5 RuleSet (com.peterphi.rules.types.RuleSet)4 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 OgnlContext (ognl.OgnlContext)3 List (java.util.List)2 MethodFailedException (ognl.MethodFailedException)2 OgnlCommand (com.peterphi.rules.types.OgnlCommand)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 OgnlException (ognl.OgnlException)1