Giter Club home page Giter Club logo

dhis2-rule-engine's Introduction

RuleEngine (WIP)

Initialization

RuleEngine is initialized in two steps.

  • Metadata configuration within RuleEngineContext
  • Setting background / contextual data for RuleEngine
RuleEngineContext ruleEngineContext = RuleEngineContext.builder(ruleExpressionEvaluator)
                .ruleVariables(ruleVariables)    // optional
                .rules(rules)                    // at least one rule must be supplied
                .build();

.builder factory method accepts instance of RuleExpressionEvaluator - something what knows how to evaluate program rule statements. RuleExpressionEvaluator implementation might be specific to certain platform. For example, on JVM it can be backed by JEXL, while on android it can be something like duktape-android.

RuleEngineContext instance is immutable. It means it can be safely shared and reused across multiple threads. Next step will be setting some contextual data to the rule engine, which will be used as a source of data for most variables.

RuleEngine ruleEngine = ruleEngineContext.toEngineBuilder()
        .enrollment(enrollment)    // contextual enrollment
        .events(events)            // contextual events
        .build();

RuleEngine is immutable as well. In example above, toEngineBuilder() method returns and instance of RuleEngine.Builder class. All parameters are optional, it means that one can simply call ruleEngineContext.toEngineBuilder().build() to get an instance of engine back.

Evaluation

Now we can send target event or enrollment to the engine in order to get some RuleEffects back. Before showing code, there are certain quirks which one should be aware of. You are not allowed to send duplicate events or enrollments to the engine as evaluation targets. In other words, if you have already supplied enrollment or event as a part of the contextual data, you won't be allowed to send it again as evaluation target. For example:

RuleEngine ruleEngine = ruleEngineContext.toEngineBuilder()
        .enrollment(enrollment)    // contextual enrollment        
        .build();

ruleEngine.evaluate(enrollment);   // not allowed!        

In general, there are a few scenarios in which rule engine can be used. Let's use next notation to declare possible options.

<metadata>(contextual_data)[evaluation_target]

  • <rules, variables>(single_events - target_event)[target_event]: applicable for programs without registration.
  • <rules, variables>(enrollment, enrollment_events - target_event)[target_event]: applicable for programs with registration. In this case, event is under evaluation.
  • <rules, variables>(enrollment_events)[target_enrollment]: evaluating enrollment. In this case, events which are a part of enrollment, can be used as source of values for program rule variables.

There are two methods for evaluation at the moment:

List<RuleEffect> enrollmentEffects = ruleEngine.evaluate(enrollment);
List<RuleEffect> eventEffects = ruleEngine.evaluate(event);

List of supported environment (contextual) variables:

  • current_date
  • event_date
  • event_count
  • due_date
  • event_id
  • enrollment_date
  • enrollment_id
  • enrollment_count
  • incident_date
  • tei_count

Development

Version

Library version is defined in the file build.gradle.kts. The version must be manually increased and include the -SNAPSHOT suffix. Please make sure the version is updated before opening the PR.

Publications

On merged pull request to main:

  • Production release to Maven.
  • Production release to NPMJS.

On pull request creation/update:

  • Snapshot release to Maven.

On demand:

  • Beta releases to NPMJS can be triggered on demand by using the action "Publish NPM beta". Please make sure you select the right branch in the selector.

Publication can be skipped by adding [skip publish] to the pull request title.


WIP

dhis2-rule-engine's People

Contributors

andresmr avatar balcan avatar bekkalizer avatar dependabot[bot] avatar enricocolasante avatar ferdyrod avatar jbee avatar jimgrace avatar stian-sandvold avatar superskip avatar vgarciabnz avatar zubaira avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dhis2-rule-engine's Issues

Catch exceptions raised by the RuleEngineExecution in different evaluations so it is easier to trace the problem with the Program Rules

In the code:

Could be better to have something like:

            try
            {
                if ( Boolean.valueOf( process( rule.condition() ) ) )
                {

                    for ( RuleAction action : rule.actions() )
                    {

                        //Check if action is assigning value to calculated variable
                        if ( isAssignToCalculatedValue( action ) )
                        {
                            try {
                                RuleActionAssign ruleActionAssign = (RuleActionAssign) action;
                                updateValueMap(ruleActionAssign.content(), RuleVariableValue.create(process(ruleActionAssign.data()), RuleValueType.TEXT));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error( "Exception while assigning value for PR in " + rule.name() + ": " + e.getMessage() );
                            }
                        }
                        else
                        {
                            try {
                                ruleEffects.add(create(action));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error( "Exception while applying action for PR in " + rule.name() + ": " + e.getMessage() );
                            }
                        }
                    }
                }
            }
            catch ( Exception e )
            {
                e.printStackTrace();
                log.error( "Exception in " + rule.name() + ": " + e.getMessage() );
            }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.