javagroovyeasy-rules

How do I write a rule in easy-rules which takes an array of string and checks a fact string using contains?


I am using expression-language-support to write rules in json format using easy-rules.

MVELRuleFactory ruleFactory = new MVELRuleFactory(new JsonRuleDefinitionReader())
Rules rules = ruleFactory.createRules(new FileReader("user-role-rule.json"))

2 Rules

  1. dept contains "gas" && (title contains "director" || title contains "manager")

  2. dept contains any of ["gas","ges","ips","csa","sales - cloud renewal"] values

Note: dept = "SALES - CLOUD RENEWAL" or "SALES US CLOUD RENEWAL"

user-role-rule.json

[
    {
        "name": "account",
        "description": "User in gas department having either Director or Manager title",
        "priority": 1,
        "condition": "user.getDept().toLowerCase().contains(\"gas\") && (user.getTitle().toLowerCase().contains(\"director\") || user.getTitle().toLowerCase().contains(\"manager\"))",
        "actions": [
          "user.setRole(\"account\");"
        ]
  },
  {
    "name": "account_common",
    "description": "User in CSM, IPS, CSA, SALES - CLOUD ENTERPRISE or GES department irrespective of any title",
    "priority": 1,
    "condition": "for (String dep in [\"gas\",\"ges\",\"ips\",\"csa\",\"sales - cloud renewal\"]) {user.getDept().toLowerCase().contains(dep)}",
    "actions": [
      "user.setRole(\"account\");"
    ]
  }
]

User pojo class

class User {
    String userId
    String dept
    String title
    List<String> role

    User(String userId, String dept, String title) {
        this.userId = userId
        this.dept = dept
        this.title = title
        this.role = new ArrayList<String>()
    }
    //..ommitting getter setters
}

Here 1st rule with name "account" works fine, but in the 2nd rule I want to use a list of string check dept falls under any of ["gas","ges","ips","csa","sales - cloud renewal"] values.

Example dept value is "SALES - CLOUD RENEWAL" or "SALES US CLOUD RENEWAL"

Exception in 2nd rule

Exception in thread "main" [Error: expected : in foreach]
[Near : {... es - cloud renewal"]) {user.getDept().toLowerCase( ....}]
                                 ^

Solution

  • As the error states, you should use a colon character : in foreach instead of in. Just write the second rule's condition as follows:

    "condition": "for (String dep : [\"gcs\", ..., \"sales - cloud renewal\"]) {user.getDept().toLowerCase().contains(dep)}"
    

    You can also check the MVEL foreach documentation