drewry / fdns-rules-engine

This the repository with the Java Library for the Business Rules Engine, will also need to publish to Maven.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Build Status

FDNS Rules Engine

This is the repository with the Java Library for the Business Rules Engine.

Usage

Add this into your pom.xml to start using the rules engine:

<!-- add the dependency to your project -->
<dependency>
  <groupId>gov.cdc</groupId>
  <artifactId>fdns-rules-engine</artifactId>
  <version>1.0.2</version>
</dependency>

<!-- add GitHub CDCgov to repositories -->
<repositories>
  <repository>
    <id>github-cdcgov</id>
    <url>https://github.com/CDCgov/maven-repository/raw/master/</url>
  </repository>
</repositories>

$all

The $all operator validates the objects where the value of a field is an array that contains all the specified elements.

Syntax:

{ "$all": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A JSON array containing the required values
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$all": {
        "$.contacts[*]": {
            "hobbies": [
                "Cinema",
                "Ski"
            ]
        }
    }
}

$and

The $and operator performs a logical AND operation on an array of two or more <rules> and validates objects that satisfy all business rules.

Syntax:

{ "$and": [ <rule1>, <rule2>, ... { <ruleN> } ] } 

$dateFormat

The $dateFormat command validates objects where string values match a date format.

Syntax:

{ "$dateFormat": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> must be a String value acceptable by Java (reference: https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html).

Example:

{
    "$dateFormat": {
        "$.contacts": {
            "$.dob": "yyyyMMdd"
        }
    }
}

$eq

The $eq operator validates objects where the value of a field equals the specified value.

Syntax:

{ "$eq": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A basic object such as an integer, a double, a float, a string, a boolean or the null value.
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$eq": {
        "$.contacts[*]": {
            "age": 33,
            "score": 0.6,
            "enabled": true,
            "ip": null
        }
    }
}

$emptyOrNull

The $emptyOrNull command validates objects where the value of the field doesn't exist, is null or is an empty string.

Syntax:

{ "$emptyOrNull": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A boolean value such as true or false
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$emptyOrNull": {
        "$.items[*]": {
            "$.val-1": false,
            "$.val-2": true,
            "$.val-3": true,
            "$.val-4": false
        }
    }
}

$exists

The $exists command validates object that contain the field, including object where the field value is null.

Syntax:

{ "$exists": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A boolean
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$exists": {
        "$.contacts": true,
        "$.contacts[*]": {
            "name": true,
            "age": false
        }
    }
}

$gt

$gt validates those objects where the value of the field is greater than (i.e. >) the specified value.

Syntax:

{ "$gt": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A basic object such as an integer, a double, a float, a string, a boolean.
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$gt": {
        "$.contacts[*]": {
            "age": 18,
            "score": 0.5,
            "enabled": false
        }
    }
}

$gte

$gte validates those objects where the value of the field is greater than or equal to (i.e. >=) the specified value.

Syntax:

{ "$gte": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A basic object such as an integer, a double, a float, a string, a boolean.
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$gte": {
        "$.contacts[*]": {
            "age": 18,
            "score": 0.5,
            "enabled": false
        }
    }
}

$in

The $in operator validates the objects where the value of a field equals any value in the specified array.

Syntax:

{ "$in": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A JSON array containing basic objects such as an integer, a double, a float, a string, a boolean or the null value.
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$in": {
        "$.contact.name": [
            "Ben",
            "John",
            "Harry"
        ],
        "$.contact.age": [
            30,
            31,
            32,
            33,
            "N/a"
        ],
        "$.contact.score": [
            0,
            0.6
        ],
        "$.contact.enabled": [
            true,
            false
        ],
        "$.contact.ip": [
            null,
            "0.0.0.0"
        ]
    }
}

$lt

$lt validates the objects where the value of the field is less than (i.e. <) the specified value.

Syntax:

{ "$lt": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A basic object such as an integer, a double, a float, a string, a boolean.
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$lt": {
        "$.contacts[*]": {
            "age": 18,
            "score": 0.5,
            "enabled": false
        }
    }
}

$lte

$lte validates the objects where the value of the field is less than or equal (i.e. <=) the specified value.

Syntax:

{ "$lte": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A basic object such as an integer, a double, a float, a string, a boolean.
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$lte": {
        "$.contacts[*]": {
            "age": 18,
            "score": 0.5,
            "enabled": true
        }
    }
}

$mod

Validate objects where the value of a field divided by a divisor has the specified remainder (i.e. perform a modulo operation to validate objects).

Syntax:

{ "$mod": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A JSON array containing two integer values. The first value is the modulo, and the second value is the remainder
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$mod": {
        "$.contact.age": [3, 0]
    }
}

$ne

$ne validates the objects where the value of the field is not equal (i.e. !=) to the specified value. This validates objects that do not contain the field.

Syntax:

{ "$ne": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A basic object such as an integer, a double, a float, a string, a boolean or the null value
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$ne": {
        "$.contact.name": "System",
        "$.contact.age": 18,
        "$.contact.score": 0.5,
        "$.contact.enabled": false,
        "$.contact.ip": null
    }
}

$nin

$nin validates the objects where: (a) the field value is not in the specified array or (b) the field does not exist.

Syntax:

{ "$nin": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A JSON array containing basic objects such as an integer, a double, a float, a string, a boolean or the null value
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$nin": {
        "$.contact.name": [
            "System",
            "Admin",
            "N/a"
        ],
        "$.contact.age": [
            18,
            19,
            20,
            "N/a"
        ],
        "$.contact.score": [
            0,
            0.5
        ],
        "$.contact.enabled": [
            false
        ],
        "$.contact.ip": [
            null,
            "0.0.0.0"
        ]
    }
}

$nor

$nor performs a logical NOR operation on an array of one or more business rules and validates objects that fail all the rules in the array.

Syntax:

{ "$nor": [ <rule1>, <rule2>, ... { <ruleN> } ] } 

$not

$not performs a logical NOT operation on the specified <rule> and validates the objects that do not match the <rule>.

Syntax:

{ "$not": <rule> } 

$or

The $or operator performs a logical OR operation on an array of two or more <rules> and validates the object if at least one rule is satisfied.

Syntax:

{ "$or": [ <rule1>, <rule2>, ... { <ruleN> } ] } 

$regex

Provides regular expression capabilities for pattern matching strings in object validations. If you need help to write your regex pattern, consult this page: https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html.

Syntax:

{ "$regex": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • A string value representing the regex pattern
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$regex": {
        "$.contacts[*]": {
            "name": "[A-Z][a-z]+"
        }
    }
}

$size

The $size operator validates any array with the number of elements specified by the argument.

Syntax:

{ "$size": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } } 

The <expression> can be:

  • An integer representing the required size
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$size": {
        "$.contacts[*]": {
            "hobbies": 3
        }
    }
}

$type

The $type command validate objects where the value of the field is an instance of the specified type.

Syntax:

{ "$type": { "<jsonPath1>" : <expression1>, "<jsonPath2>" : <expression2>, ... } }

The <expression> can be:

  • A string value representing the type. This is the allowed list of type to test:
  • Number
  • String
  • Boolean
  • Array
  • Object
  • Null
  • A JSON object containing the rule that will be applied on each element returned by <jsonPath>

Example:

{
    "$type": {
        "$.contacts[*]": {
            "name": "String",
            "age": "Number",
            "score": "Number",
            "hobbies": "Array"
        }
    }
}

Custom command

It's possible as well to create your own custom command in Java. If you want to create a command that checks if an array don't contain duplicates. Just create a Java class like this one that implements the abstract class AbstractCommand :

package gov.cdc.engine.commands;

import java.util.HashSet;
import java.util.Set;

import org.json.JSONObject;

import gov.cdc.engine.ValidatorException;
import gov.cdc.engine.result.CompoundValidationResult;
import gov.cdc.engine.result.ValidationResult;

/**
 * The $noDuplicate operator validates any array that contains only unique
 * values.
 * 
 * @author Ben Chevallereau
 *
 */
public class NoDuplicateCommand extends SingleCommand {

  public String getKeyword() {
    return "$noDuplicate";
  }

  @Override
  protected void isValid(JSONObject rule, String jsonPath, Object value, boolean found, CompoundValidationResult result) throws ValidatorException {
    // If the field doesn't exist in the object
    if (!found) {
      result.addResult(ValidationResult.create(false, rule.toString(), getKeyword()));
    } else if (rule.get(jsonPath) instanceof Boolean) {
      Boolean parameter = (Boolean) rule.get(jsonPath);

      boolean valid = false;
      if (value instanceof net.minidev.json.JSONArray) {
        net.minidev.json.JSONArray v = (net.minidev.json.JSONArray) value;
        Set<Object> foundValues = new HashSet<Object>();
        for (int i = 0; i < v.size(); i++)
          foundValues.add(v.get(i));
        valid = foundValues.size() == v.size();
      } else
        throw new ValidatorException("The retrieved value is not a JSON array: " + value);

      if (!parameter)
        valid = !valid;

      result.addResult(ValidationResult.create(valid, rule.toString(), getKeyword()));
    } else if (rule.get(jsonPath) instanceof JSONObject) {
      // If the parameter is a sub-rule
      JSONObject subrule = rule.getJSONObject(jsonPath);
      // Recurse
      result.addAllResults(recurse(subrule, value));
    } else
      throw new ValidatorException("Don't understand the following parameter: " + rule.get(jsonPath));
  }

}

Then, you can use your new rule keyword in your JSON configuration:

{
    "$noDuplicate": {
        "$.contacts[*]": {
            "hobbies": true
        }
    }
}

Public Domain

This repository constitutes a work of the United States Government and is not subject to domestic copyright protection under 17 USC § 105. This repository is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the CC0 1.0 Universal public domain dedication. All contributions to this repository will be released under the CC0 dedication. By submitting a pull request you are agreeing to comply with this waiver of copyright interest.

License

The repository utilizes code licensed under the terms of the Apache Software License and therefore is licensed under ASL v2 or later.

The source code in this repository is free: you can redistribute it and/or modify it under the terms of the Apache Software License version 2, or (at your option) any later version.

The source code in this repository 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 Apache Software License for more details.

You should have received a copy of the Apache Software License along with this program. If not, see http://www.apache.org/licenses/LICENSE-2.0.html

The source code forked from other open source projects will inherit its license.

Privacy

This repository contains only non-sensitive, publicly available data and information. All material and community participation is covered by the Surveillance Platform Disclaimer and Code of Conduct. For more information about CDC's privacy policy, please visit http://www.cdc.gov/privacy.html.

Contributing

Anyone is encouraged to contribute to the repository by forking and submitting a pull request. (If you are new to GitHub, you might start with a basic tutorial.) By contributing to this project, you grant a world-wide, royalty-free, perpetual, irrevocable, non-exclusive, transferable license to all users under the terms of the Apache Software License v2 or later.

All comments, messages, pull requests, and other submissions received through CDC including this GitHub page are subject to the Presidential Records Act and may be archived. Learn more at https://www.cdc.gov/other/privacy.html.

Records

This repository is not a source of government records, but is a copy to increase collaboration and collaborative potential. All government records will be published through the CDC web site.

Notices

Please refer to CDC's Template Repository for more information about contributing to this repository, public domain notices and disclaimers, and code of conduct.

About

This the repository with the Java Library for the Business Rules Engine, will also need to publish to Maven.

License:Apache License 2.0


Languages

Language:Java 100.0%