Giter Site home page Giter Site logo

deliveredtechnologies / rulebook Goto Github PK

View Code? Open in Web Editor NEW
711.0 711.0 125.0 1.53 MB

100% Java, Lambda Enabled, Lightweight Rules Engine with a Simple and Intuitive DSL

Home Page: http://www.deliveredtechnologies.com

License: Apache License 2.0

Java 98.21% XSLT 1.79%
dsl java lambda rules rules-engine

rulebook's People

Contributors

awattez avatar azell avatar bradegler avatar briandeacon avatar clayton7510 avatar harshavs avatar jabhijeet avatar jimmymain avatar mikelear avatar mill5james avatar nicolaslambert avatar rizjoj avatar tomekbielaszewski avatar vidi42 avatar xplutox avatar

Stargazers

 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  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  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

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  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

rulebook's Issues

Rules Auditing

It comes to mind that it might be useful to have an audit of rules available. Say, for example, I have a RuleBook that contains many different rules. When I run that RuleBook, some rules might fire, some rules might not. It might be nice to know which rules executed.

I'm thinking rules could be audited by name. That means, each rule should have a name. By default, it could be the classname of the Rule. But if a String name is specified, then it would be the name specified.

Is it possible to stop RuleBook evaluations when exceptions are thrown?

Hi. This is an awesome library!

Suppose the following:

  • I have a service call with side effects that can throw checked or unchecked exceptions at runtime (e.g. a database read/write call).
  • The method call is embedded as a then method on a rule evaluation.
  • If the service method fails (i.e. throws an Exception), the rule book evaluation continues to execute.

In my use case, is it possible to configure RuleBook or each individual rule in such a way that any unhandled Exceptions stop the rule book evaluation and have the Exception bubble up back to the caller? Is there a better way to handle this scenario?

Thanks again!

Support for Groovy

Defining rules in Java using Lambda is awesome. But Groovy doesn't currently support Lambda; it uses Groovy closures.

Given how much I personally love Groovy and that Groovy scripting could be used to externalize (and version) RuleBooks, I think RuleBook needs to be Groovy too!

Stopping the chain if a Rule returns false

Hi

If I want to add a bunch of rules, where I want the result to contain success ONLY if all rules are successful, is this possible currently. So, lets say that I have two rules, the first one checks if a user is Male, the second checks whether the users age is less than 40. If the user happens to be female, then the first rule will return false, but the second rule will still process. If the second rule returns true (the user is less than 40), then the rulebook result is true, even though I actually want it to be false. Essentially I'd like to be able to stop the chain should a rule fail, but this doesn't look possible. Is there another way of doing this possibly ?

Thanks

Darrell

Re-using RuleBook instance

Hi Clayton, I have a question. Is it possible to re-use a RuleBook instance? So, is it possible to call run method in a cycle for example ? Thanks.

More Robust Application Examples

I think the time has come to include complete working project examples in the GitHub source. Suggestions are welcome. Contributions are encouraged.

Facts of different actual types

Is it possible to use a Java interface and/or a general class (instead of the concrete type) as the generic type passed to Facts and FactMap and the @given List? I replaced references to ApplicantBean with an interface (IApplicant which declares the expected methods) e.g. FactMap and in the rule:
@given private List applicants
I end up with no objects in the applicants list. I've tried this with a generalized class as well (where concrete classes are specializations of ApplicantBean).

Springify RuleBook

RuleBook can already be used easily with Spring. But there are a few things the developer has to be aware of: the Rules, Decisions and Books must be prototypes because they persist state which may be interrupted and changed if they were singletons.

There might be some other useful stuff that can be streamlined for Spring support, too.

Externalized Rules Using a BDSL

I'm thinking that it would be cool to be able to have rules stored outside of the application (and the JVM) and have RuleBook be able to point to those rules and use them.

Supported languages and format is currently TBD. Maybe Groovy?

Rules cannot iterate through facts?

I understand one can apply multiple rules to any value on the facts map.

But what if I have a List of objects that I want to have evaluated by the same rule pipeline?

Imagine I have something like:

List<Person> people = new ArrayList<Person>();
people.add(new Person("Steve", 30));
people.add(new Person("Eddie", 42));
people.add(new Person("Mary", 32));

RuleBook ruleBook = ruleBookBuilder.addRule(RuleBuilder.create().withFactType(JsonObject.class)
                .when(person -> person.age < 40)
                .then(person -> person.getName())
                .build()).build();

        ruleBook.run(people);

-------OUTPUT------

Steve
Mary

It seems that if I want to put a List/Set of objects through a rule pipeline at the moment I always need to recreate a new Rulebook, is this right?

Run several rules each returning a result

Hi,

I have several rules, each having to be triggered (when is true) and so each one should return the name of the winner (some String value). I have been wondering if you have an advice to give me to achieve that. I thought about creating a RuleBook instance per rule, but this is quite tedious and messy. Also, I am using Spring and the Rule logic is quite long, so either I'd have to create a package per Rule (quite messy!) or I'd have to use addRule() on each Rule instance and instanciate them manually.

Thanks!

Valentin

When condition seems not working. A very easy question regarding with going through the example on the toturial

Hi, I tried to do the simple Hello World example to see how the library generally work, but the result is a little bit funky.
Here is the code I wrote:
import com.deliveredtechnologies.rulebook.FactMap;
import com.deliveredtechnologies.rulebook.NameValueReferableMap;
import com.deliveredtechnologies.rulebook.Result;
import com.deliveredtechnologies.rulebook.lang.RuleBookBuilder;
import com.deliveredtechnologies.rulebook.model.RuleBook;
import com.deliveredtechnologies.rulebook.lang.RuleBuilder;
import com.deliveredtechnologies.rulebook.Rule;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.lang.String;

class ruletest{
public static void main(String [] arg){
NameValueReferableMap factMap = new FactMap();
factMap.setValue("hello", "Hello");
factMap.setValue("world", " World");
RuleBook ruleBook = RuleBookBuilder.create().withResultType(Integer.class)
.addRule(rule -> rule.withFactType(FactMap.class)
.when(f -> f.containsKey("hello") )
.using("hello").then(t -> System.out.println(1) ))
.addRule(rule -> rule.withFactType(FactMap.class)
.when(f -> !f.containsKey("hello_2"))
.then(t -> System.out.println(2) ))
.build();

    ruleBook.run(factMap); //return 2. However it should be 1
    System.out.println(factMap.containsKey("hello")); //Return true
}

}

When I run the code, it seems that it is not working. the expected result should be 1 instead of 2.
Thank you for the help.
Wish you have a good day

Is it possible to have an "else" for a rule?

Hi, is there some way to have like an "else" for a rule? I have to run a set of rules, but I need to know which one "passed" and which ones not, so I was thinking about having a Result consisting on a list of "states" for each rule ran.
The problem is, I have no access to the "result" in the "when" rule part, and the "then" is never ran if the rule result is false. Is there any way to achieve this with Rulebook? Thanks in advance!.

Cleanup old & unneeded RuleBook code

Specialized Spring support for RuleBook isn't really needed anymore. RuleBook can now be easily used with Spring.

Also, there's some old RuleBook code left over from the early days of RuleBook that's only kept there for backwards compatibility purposes. v1.0 should see that old code removed.

When-condition of rule is not accessed

Hi,

I'm trying to use RuleBook version 0.5 in my Spring-application. It seems like the when-part will never be evaluated, so I access for each rule the then-part.
First there comes my code, then the issue is explained with a little bit more details.

The Code:

My Pom contains:

<dependency>
    <groupId>com.deliveredtechnologies</groupId>
    <artifactId>rulebook-core</artifactId>
    <version>0.5</version>
</dependency>
<dependency>
    <groupId>com.deliveredtechnologies</groupId>
    <artifactId>rulebook-spring</artifactId>
    <version>0.5</version>
</dependency>

Like in the wiki/readme told I created a @Configuration-bean:

@Configuration
public class RuleBookSpringConfig {
  @Bean
  public RuleBookFactoryBean ruleBook() throws InvalidClassException {
	return new RuleBookFactoryBean("my.package.rulebook.myRules"); 
  }
}

I defined one rule in the package:

@Rule(order =1)
public class MyRule {
  public MyRule() {}

  @Given("field")
  private myClass field;
  
  @When
  public boolean when() {
	System.out.println("Evaluate condition");
	return field.isPropertySet(); 
  }
  
  @Then
  public RuleState then() {
	System.out.println("Rule is correct");
	return RuleState.NEXT;
  }
}

This rule is used here:

NameValueReferableMap<FieldMetaElement> facts = new FactMap<>();
facts.setValue("field", instanceOfMyClass);
this.ruleBook.run(facts);

The issue:

If I run the code, my output is every time Rule is correct, wether the property is set or not. The output Evaluate condition is never displayed. So I changed the when-part to:

@When
public boolean when() {
    return false;
}

The output is every time Rule is correct again. If I set a breakpoint to when() it does not stop there. So the when-part is not executed at every time.
If I set a breakpoint at com.deliveredtechnologies.rulebook.model.runner.RuleAdapter.class line 126 - public Predicate<NameValueReferableMap> getCondition() the application does not stop there. Same at com.deliveredtechnologies.rulebook.runner.RuleAdapter.class line 121 - public Predicate getWhen().
I tried to use a manually instance of RuleBook without spring and have exactly the same situation.
Same situation comes if I use a rule with a Result or more rules.

Additional information:

The imports at the rule-class are:

  • import com.deliveredtechnologies.rulebook.RuleState;
  • import com.deliveredtechnologies.rulebook.annotation.Given;
  • import com.deliveredtechnologies.rulebook.annotation.Rule;
  • import com.deliveredtechnologies.rulebook.annotation.Then;
  • import com.deliveredtechnologies.rulebook.annotation.When;

The imports at the rule-usage-class are:

  • import com.deliveredtechnologies.rulebook.FactMap;
  • import com.deliveredtechnologies.rulebook.NameValueReferableMap;
  • import com.deliveredtechnologies.rulebook.model.RuleBook;
  • import com.deliveredtechnologies.rulebook.Result;

The import at Spring-configuration is:

  • import com.deliveredtechnologies.rulebook.spring.RuleBookFactoryBean;

HomeLoanRateRuleBook example not working

Hello,

Was trying to run through your HomeLoan example and it doesn't appear to be returning any result. I have the ApplicantBean and the Main classes copied verbatim. However instantiating the HomeLoanRateRuleBook object gives me a compile error because the following is incompatible:

HomeLoanRateRuleBook homeLoanRateRuleBook = RuleBookBuilder.create(HomeLoanRateRuleBook).withResultType(Double.class) .build();

Results in "Incompatible types". Required HomeLoanRateRuleBook, found RuleBook

If I try casting as HomeLoanRateRuleBook or even setting the variable as:

RuleBook<Double> homeLoanRateRuleBook = RuleBookBuilder.create(HomeLoanRateRuleBook).withResultType(Double.class) .build();

It does not work. Any time I run through the steps the RuleBook result (_result) is coming back null. Only when I specify a defaultResult does it return a value back. Any ideas?

Different Fact types in one FactMap

Hello again.

Is it possible to include multiple object types in one FactMap, after setting the FactType in the ruleBuilder? Example:

I'm first building the rule with a FactType of Deduction.class:

private RuleBuilder<Deduction,Boolean> getDeductionRuleBuilder(){ return RuleBuilder.create().withFactType(Deduction.class).withResultType(Boolean.class); }

When I setup my FactMap, I have a Deduction and String object I want to pass in:
private NameValueReferableMap getFactMap(Deduction deduction, String state) { NameValueReferableMap facts = new FactMap<>(); facts.setValue("deduction", deduction); facts.setValue("state", state); return facts; }

Here's an example rule I have defined:
addRule(getDeductionRuleBuilder() .when(facts -> facts.getOne().getType().equals(SOME_EQUALITY_CHECK)) .then((factMap, booleanResult) -> { System.out.println(factMap.getStrVal("state")); booleanResult.setValue(Constants.SOME_OTHER_CHECK.contains(factMap.getStrVal("state"))); }).stop().build());
So, when I execute the Rule, obviously the Deduction fact is retained, however the String object seems to get cut out of the factmap, and it returns false because it can't evaluate the "state" Fact. I realize I could easily create a container object to hold the Deduction and String object. However, I wanted to make sure there was no other way to create a FactMap of various object types to be used in a RuleBook.

Verify execution order with POJO rules

Execution order was included in POJO rules, but it was not verified. It should be verified to ensure that facts and/or results are used & modified in the order specified.

Additional Algorithms for Rules Evaluation

Rules Engine uses CoR for sequential rules evaluation. It works! And for many situations, it's serves the need. However, for more ambitious applications, it would be nice to have other algorithms for rules evaluation available. The catch is that other algorithms should have a sequential dependency component to provide predictable execution between dependent rules. In addition, rules evaluation algorithms should be pluggable - the library certainly allows for it.

This is not pressing. On the 1. Make it work 2. Make it good 3. Make it fast hierarchy, it's definitely in the 3rd category. And there are other things (like versioning and BDSL) that should take precedence. But this is something that will be needed at some point down the line.

Multiple invocations of RuleBook.run() could define rules more than once

Practically, this shouldn't be a huge issue since RuleBooks are likely instantiated each time they are to be used (Spring does this with prototype) and therefore run() would likely only be called once per RuleBook instance. However, if a developer wanted to create a single instantiation of a RuleBook class and re-run it then there could be an issue with rules running multiple times unintentionally. This should be corrected in a minor release.

Passing a Collection (Map,List) as Given shows up as null in rule?

You can tell me if I'm just not using it correctly, but --

If I pass a single POJO as Given, I retrieve the List in my rule and process it as normal, as your documentation states. However, trying to pass a collection seems to result in the object either being swallowed up and spit out as null, or as an empty List. I can provide an example if needed.

Make it easier to use the DSL with Facts of different types in a RuleBook

If you are using POJO Rules, this is a non-issue. But if you are using the Java DSL, then mixing types of Facts is cumbersome since generics suppose all Facts are of the same type.

This should be an easier thing to do. I'm thinking that a RuleBook can be of an unspecified type and then Rules of any type can be added. Facts of all types would be chained across Rules. But only Facts of the type of the Rule would be available in the When and Predicate, still keeping the lambda syntax pretty streamlined.

Rules Versioning

Rules should be able to be versioned independently of the application code. When a new version of rules is published, the application should load the newly published rules and start running the new rules version in place of the old one.

A couple of things to consider:

  • in-flight rules should not break during a rules version update
  • version updates should have various modes of scheduling (it could use quartz or EJB timer, perhaps)

Initially, repositories for rules could be Maven. Maybe later, Git could be supported.

FileSystemNotFoundException on standalone Spring Boot app

I like where this library is going so I am giving it a shot. The main problem I've encountered that I don't seem to find a workaround for is this FileSystemNotFoundException that occurs when I run the RuleBook standalone (I am using the annotated classes not the Java DSL). Everything works fine in IntelliJ but if I try to just java -jar target/long-jar-name.jar from the command line it fails. I am running this in a standard Spring Boot app.

It appears that the problem could be how the Paths are created using NIO: https://stackoverflow.com/questions/22605666/java-access-files-in-jar-causes-java-nio-file-filesystemnotfoundexception

I am using version 0.8 pulled from Maven Central. Here is what the exception looks like:

2017-09-12 23:18:22 [http-nio-8080-exec-3] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.nio.file.FileSystemNotFoundException] with root cause
java.nio.file.FileSystemNotFoundException: null
        at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
        at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
        at java.nio.file.Paths.get(Paths.java:143)
        at com.deliveredtechnologies.rulebook.model.runner.RuleBookRunner.findRuleClassesInPackage(RuleBookRunner.java:120)
        at com.deliveredtechnologies.rulebook.model.runner.RuleBookRunner.run(RuleBookRunner.java:68)

More Sugar

There are a couple of things in the new DSL that are a bit cumbersome. Retrieving results is one of those things. Maybe it could be cleaned up a bit.

Thread safety?

Is RuleBook thread safe for multithreading environment?
Should I create an instance for each thread for rule evaluation?

RuleBook first run unexpected result

Hi,

I'm trying to integrate RuleBook in an enterprise project, because it seems to be really interesting.

I'm using version 0.5 and found that first run returns a default value because headRule is not correctly valued in CoRRuleBook.run method. These are the steps I did:

  1. First I created a new RuleBook extending CoRRuleBook:
public class AutoEvaluationRuleBook extends CoRRuleBook<MyBean> {

	@Override
	public void defineRules() {
           // here I define all my business rules
	}

}
  1. Then I instantiate a new RuleBook:
RuleBook<AutoEvaluationResult> autoEvaluationRuleBook = RuleBookBuilder.create(AutoEvaluationRuleBook.class)
				.withResultType(AutoEvaluationResult.class)
				.withDefaultResult(new AutoEvaluationResult(null, false, false, null))
				.build();
  1. Then I create some test cases:
List<NameValueReferableMap<MyBean>> factsList = testCases();

factsList.forEach(x -> {
	count++;
	autoEvaluationRuleBook.run(x);
	autoEvaluationRuleBook.getResult().ifPresent(result -> {
	MyBean ref = result.getValue().getRef();
	System.out.println(String.format("%s. Item: %s, Autoevaluated: %s, Suspect: %s, Reason: %s", count,
		null != ref ? "item" : "NULL", result.getValue().isAutoEvaluated(),
		result.getValue().isSuspect(), null != result.getValue().getReason() ? result.getValue().getReason().name() : "NULL"));
	});
});

In this way, the first run returns an unexpected result because I noticed in the run method inside the CoRRuleBook class the object headRule is not valued.

The original code:

  @Override
  @SuppressWarnings("unchecked")
  public void run(NameValueReferableMap facts) {
   // here an Optional obj wraps the class property _headRule
    Optional<Handler<Rule>> headRule = Optional.ofNullable(_headRule);
    if (!headRule.isPresent()) {
      // if not present (first run), you call defineRules()
      defineRules();
    }
   // here headRule Optional value is still null, is it wanted ?
    headRule.ifPresent(ruleHandler -> {
        ruleHandler.getDelegate().setFacts(facts);
        getResult().ifPresent(result -> ruleHandler.getDelegate().setResult(result));
      });
    headRule.ifPresent(Handler::handleRequest);
  }

In the original code if the headRule is not present, it calls the defineRules, defining the book rules, but after that the method isPresent is called on the Optional<Handler> headRule object which will return false. Is this wanted ?

I modified this code in this way:

@Override
@SuppressWarnings("unchecked")
public void run(NameValueReferableMap facts) {
	Optional<Handler<Rule>> headRule = Optional.ofNullable(_headRule);
	if (!headRule.isPresent()) {
		defineRules();
                // new added line below, rules are defined but object is still not present
		headRule = Optional.ofNullable(_headRule);
	}		
	headRule.ifPresent(ruleHandler -> {
		ruleHandler.getDelegate().setFacts(facts);
		getResult().ifPresent(result -> ruleHandler.getDelegate().setResult(result));
	});
	headRule.ifPresent(Handler::handleRequest);
}

In this way I have all the objects valued correctly (also the first one).

Let me know.

Thanks and best regards,
Alessandro Torrisi.

Unable to create an instance of the specified Rule class <> with fact and result type specified.

Hello, just moved to 0.8 from 0.7. Prior to and after the update, I'm getting these debug statements in my output when trying to build rules. However, the rules are being loaded and executed properly as all my testing is passing successfully. I've tried different variations of below and still end up with the log statements. Any ideas?

14:30:59.143 [main] DEBUG c.d.rulebook.lang.RuleBuilder - Unable to create an instance of the specified Rule class 'class com.deliveredtechnologies.rulebook.model.GoldenRule' with fact and result types specified

`public class CanadaRules extends CoRRuleBook{

Override
protected void defineRules() {
addRule(getCalculatorRuleBuilder()
.when(fact -> isRequestTypeDonation(fact.getOne()))
.then((fact, result) -> {
Map<Item,List> appliedItemRateMap = getAppliedItemRateMap(fact.getOne());
result.setValue(createResult(appliedItemRateMap));
}).stop().build());

private RuleBuilder<CalculatorFact, BusinessRulesResult> getCalculatorRuleBuilder() {
return RuleBuilder.create().withFactType(CalculatorFact.class).withResultType(BusinessRulesResult.class);
}
}`

Megabank example - bug or feature?

As I understand it, the ApplicantNumberRule only allows loan applications with 3 or fewer applicants to be processed, i.e. if greater than three applicants then processing is halted. In my main method I supplied 4 applicants:

 RuleBookRunner ruleBook = new RuleBookRunner("rules");
    NameValueReferableMap<ApplicantBean> facts = new FactMap<ApplicantBean>();
    ApplicantBean applicant1 = new ApplicantBean(650, 20000, true);
    ApplicantBean applicant2 = new ApplicantBean(620, 30000, true);
       ApplicantBean applicant3 = new ApplicantBean(620, 30000, true);//same as applicant2
       ApplicantBean applicant4 = new ApplicantBean(900, 30000, true);
       facts.put(new Fact<>(applicant1));
       facts.put(new Fact<>(applicant2));
       facts.put(new Fact<>(applicant3));
       facts.put(new Fact<>(applicant4));
    
       ruleBook.setDefaultResult(4.5);
       ruleBook.run(facts);
       ruleBook.getResult().ifPresent(result -> System.out.println("Applicant qualified for the following rate: " + result));

output:

  Applicants count:3
  Applicant qualified for the following rate: 3.3

Because two of the applicants have the same facts.
If I change one of the repeated applicants so that all the applicants are unique the rule fires as expected (4 applicants).

Is this a bug or a feature?
P.S. also the code copied and pasted from the readme did not compile with some missing ")"s

addRule() method for RuleBookFactoryBean

Is there any way we can get the addRule functionality added to the RulebookFactoryBean? Had a setup like below where we created rulebookbeans (at prototype scope) and were able to use the same rules from the same package within different rulebooks. After updating the version I noticed the RuleBookBean is deprecated and you now only have package scanning available for spring created rulebooks.

`@Configuration
public class RulesEngines {

@bean(name="defaultRule")
@scope("prototype")
public RuleBookBean inRuleBook(FilterItemRateMapRule filterItemRateMapRule, InterstateRule interstateRule, IntrastateRule intrastateRule, CountryRule countryRule) throws InvalidClassException {
return getRuleBook(filterItemRateMapRule, interstateRule, intrastateRule,countryRule);
}

@bean(name="indiaRuleMTR")
@scope("prototype")
public RuleBookBean inRuleBookMTR(FilterItemRateMapRule filterItemRateMapRule, InterstateRule interstateRule, IntrastateRuleMTR intrastateRule,CountryRule countryRule) throws InvalidClassException {
return getRuleBook(filterItemRateMapRule, interstateRule, intrastateRule,countryRule);
}

private RuleBookBean getRuleBook(FilterItemRateMapRule filterItemRateMapRule, InterstateRule interstateRule, ApplicableTaxRule intrastateRule, CountryRule countryRule) throws InvalidClassException {

RuleBookBean inRuleBook = new RuleBookBean();
inRuleBook.addRule(filterItemRateMapRule);
inRuleBook.addRule(countryRule);
inRuleBook.addRule(interstateRule);
inRuleBook.addRule(intrastateRule);
return inRuleBook;

}

}
`

MegaBank Example With POJO Rules not working

I don't think the MegaBank Example With POJO Rules are documented properly and even its working ?

I tried to simulated MegaBank Example With POJO Rules but the rules are not getting invoked.
Result is simply coming null.
Applicant qualified for the following rate: null null

Using method not working as expected

In the below example where using is used(highlighted in bold):

RuleBook ruleBook = RuleBookBuilder.create().withResultType(String.class)
.withDefaultResult("Unknown!")
.addRule(rule->rule.withFactType(String.class)
.when(f->f.containsKey("hello") && f.containsKey("world"))
.using("hello").then(System.out::print)
.using("world").then(System.out::println))

.build();

The outcome is actually object reference like:
com.deliveredtechnologies.rulebook.TypeConvertibleFactMap@5f4da5c3com.deliveredtechnologies.rulebook.TypeConvertibleFactMap@443b7951

Instead of "Hello World"

Add Support for Defining Rules Without Lambda and the DSL

Rules and Decisions can be very nicely wired up with lambda. But [eventually] there should be support for wiring rules up without lambda and without the DSL (even though, this is very cool :).

What if given(), when() and then() methods could take in Facts, Predicates and Functions, respectively, but also be defined in a Rule class (by the developer)? That might be pretty cool. So, it could be an either/or situation. And thenRules or Decisions could then be added to a Book or mixed with other Rule types.

POJO Rules don't support injection of multiple facts based on the type

The MegaBank example won't work correctly with POJOs since POJOs cannot currently be injected with a grouping of objects stored in different facts. Right now, it only injects based on the name. However, in the MegaBank example, the name might not be known ahead of time, nor would the number of Facts.

This should probably be fixed before the next minor release.

Add Some More Syntactic Sugar to the DSL

  • Add a Consumer then() method option that continues by default.
  • Add the ability to chain multiple then() statements.
  • Add a stop() method that breaks on then()
  • Add a given() method that accepts a String and an Object of some type T for adding a single Fact
    • Do this for Rules and RuleBooks

Make POJO Rules Stateless

Thread safety in POJO RuleBooks requires different instances of RuleBooks per thread since state is stored in the Rules. This allows the interface to very intuitive. But unfortunately, it also means that each thread needs its own POJO RuleBook. I think the solution is to have Facts injected as parameters instead of instance variables.

Unexpected results in 4.1 A Hello World Example?

hellowordrule.txt
example4.1.txt
Hi Clayton,

Running the Hello World example using bogus facts the rulebook.getResults().isPresent() is true. Should the results be false? I was expecting a Null value.

Running the Hello World example using RuleBookBuilder using bogus facts the rulebook.getResults().isPresent() is false. Which is what I expected.

Love the RuleBook. Keep up the good work.

cheers,
Kent

RuleState vs RuleChainActionType

Can you explain what the expected behavior would be for setting RuleState to next/break vs setting the RuleChainActionType to continue/stop on failure? I noticed setting STOP_ON_FAILURE automatically sets the rule to RuleState.NEXT. Just looking for some clarity on these values.

stop() in POJO-Rules with Spring

When using POJO-Rules with Spring, is there any way to configure a Rule as last Rule, like in the DSL-examples: addRule(RuleBuilder.create().....stop().build());? Im looking for a way to create a rulebook with different rules that can be executed exclusively (like "only execute the first matching rule"), so i could have a default rule with low order to be executed if there has been no more specific matching rule before.

Don't know if i just haven't found the correct way or there's no way to do this at the moment. And if there's no way to do this at the moment, would it make sense to add this feature or is this a strange use case?

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.