deliveredtechnologies / rulebook

100% Java, Lambda Enabled, Lightweight Rules Engine with a Simple and Intuitive DSL
http://www.deliveredtechnologies.com
Apache License 2.0
717 stars 124 forks source link

Unable to update field in rule object when using Custom Java Object in @Given #117

Closed manishsangani closed 6 years ago

manishsangani commented 6 years ago

Hi, I have followed megabank example to create a rule which uses custom java object, but I keep getting error that RuleAdapter - Unable to update field 'tags' in rule object 'class com.bofa.sa.rulebook.TwoWeekDestroyRule'

Here is my Rule class.

@Rule
public class TwoWeekDestroyRule {
    @Given("crDate")
    private ResourceTags tags;

    @Result
    private Boolean result;

    @When
    public boolean when() {
        return tags.getTest1().equals("Test1");
    }
    @Then
    public void then() {result = true; }
}
 ResourceTags tags = new ResourceTags( "Test1",  "Test2", "Test3", "Test4",  "Test5", "Test6" );
RuleBook<Boolean> ruleBook = new RuleBookRunner("com.rulebook");
NameValueReferableMap<ResourceTags> facts = new FactMap<>();
facts.put(new Fact<>("crDate",tags));
ruleBook.setDefaultResult(false);
ruleBook.run(facts);
ruleBook.getResult().ifPresent(result -> System.out::println);

Any help is appreciated. Thanks

Clayton7510 commented 6 years ago

Sorry about the delayed response. My full-time gig has been a little unforgiving in terms of workload over the past few months. But I have a breather this weekend. I'll check it out. Thanks.

Clayton7510 commented 6 years ago

I checked this out and the only thing that stood out was the last line of your code is not valid syntax. You combine the reference syntax with lambda syntax and in Java 8+, it's one or the other. So, ruleBook.getResult().ifPresent(System.out::println); or ruleBook.getResult().ifPresent(result -> System.out.println(result));

Now, I did have to infer the internals of ResourceTags based on your code. So, this is what I implemented to test and it seemed to work out as expected.

package com.example.rulebook.pojo;

import java.util.ArrayList;
import java.util.List;

public class ResourceTags {
  private List<String> _tags = new ArrayList();

  public ResourceTags(String... tags) {
    for (String tag: tags) {
      _tags.add(tag);
    }
  }

  public String getTest1() {
    return _tags.get(0);
  }

}
package com.example.rulebook.pojo;

import com.deliveredtechnologies.rulebook.annotation.*;

@Rule
public class TwoWeekDestroyRule {
  @Given("crDate")
  private ResourceTags tags;

  @Result
  private Boolean result;

  @When
  public boolean when() {
    return tags.getTest1().equals("Test1");
  }
  @Then
  public void then() {result = true; }
}
package com.example.rulebook.pojo;

import com.deliveredtechnologies.rulebook.Fact;
import com.deliveredtechnologies.rulebook.FactMap;
import com.deliveredtechnologies.rulebook.NameValueReferableMap;
import com.deliveredtechnologies.rulebook.model.RuleBook;
import com.deliveredtechnologies.rulebook.model.runner.RuleBookRunner;

public class Application {
  public static void main(String args[]) {
    ResourceTags tags = new ResourceTags( "Test1",  "Test2", "Test3", "Test4",  "Test5", "Test6" );
    RuleBook<Boolean> ruleBook = new RuleBookRunner("com.example.rulebook.pojo");
    NameValueReferableMap<ResourceTags> facts = new FactMap<>();
    facts.put(new Fact<>("crDate",tags));
    ruleBook.setDefaultResult(false);
    ruleBook.run(facts);
    ruleBook.getResult().ifPresent(System.out::println);
  }
}

I hope that helps. If not, please post the code for your ResourceTags class. Perhaps there is something in the makeup of that class that is unaccounted for.

Thanks,

Clayton

manishsangani commented 6 years ago

Thanks Clayton. I will take a look at it.

Any future plans on adding a feature to externalize rules?

Thanks Manish

Regards, Manish


From: Clayton Long notifications@github.com Sent: Sunday, March 18, 2018 5:10:44 PM To: rulebook-rules/rulebook Cc: Manish Sangani; Author Subject: Re: [rulebook-rules/rulebook] Unable to update field in rule object when using Custom Java Object in @Given (#117)

I checked this out and the only thing that stood out was the last line of your code is not valid syntax. You combine the reference syntax with lambda syntax and in Java 8+, it's one or the other. So, ruleBook.getResult().ifPresent(System.out::println); or ruleBook.getResult().ifPresent(result -> System.out.println(result));

Now, I did have to infer the internals of ResourceTags based on your code. So, this is what I implemented to test and it seemed to work out as expected.

package com.example.rulebook.pojo;

import java.util.ArrayList; import java.util.List;

public class ResourceTags { private List _tags = new ArrayList();

public ResourceTags(String... tags) { for (String tag: tags) { _tags.add(tag); } }

public String getTest1() { return _tags.get(0); }

}

package com.example.rulebook.pojo;

import com.deliveredtechnologies.rulebook.annotation.*;

@Rule public class TwoWeekDestroyRule { @Given("crDate") private ResourceTags tags;

@Result private Boolean result;

@When public boolean when() { return tags.getTest1().equals("Test1"); } @Then public void then() {result = true; } }

package com.example.rulebook.pojo;

import com.deliveredtechnologies.rulebook.Fact; import com.deliveredtechnologies.rulebook.FactMap; import com.deliveredtechnologies.rulebook.NameValueReferableMap; import com.deliveredtechnologies.rulebook.model.RuleBook; import com.deliveredtechnologies.rulebook.model.runner.RuleBookRunner;

public class Application { public static void main(String args[]) { ResourceTags tags = new ResourceTags( "Test1", "Test2", "Test3", "Test4", "Test5", "Test6" ); RuleBook ruleBook = new RuleBookRunner("com.example.rulebook.pojo"); NameValueReferableMap facts = new FactMap<>(); facts.put(new Fact<>("crDate",tags)); ruleBook.setDefaultResult(false); ruleBook.run(facts); ruleBook.getResult().ifPresent(result -> System.out.println(result)); } }

I hope that helps. If not, please post the code for your ResourceTags class. Perhaps there is something in the makeup of that class that is unaccounted for.

Thanks,

Clayton

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/rulebook-rules/rulebook/issues/117#issuecomment-374047459, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AD3MlmT_N9oTP3iKECvmJiD_YUX6F4fmks5tfs1UgaJpZM4SMc0e.

Clayton7510 commented 6 years ago

@manishsagani There are plans to externalize rules using Groovy scripts. I just need to time to make it happen ;) But, it will happen.