Search code examples
javadroolsjbpm

How do I return the loanApplication object from a rule to the bpm process?


I am using drools(kie-wb web interface) and I have a bpm process which takes a loanApplication and returns that loanApplication with updated data(is the goal). But when I try to do that I get returned.

"Unable to create response: [LoanApplicationReviewer.LoanApplicationReview:21 - Age Knockout:1] -- [LoanApplicationReviewer.LoanApplicationReview:21 - Age Knockout:1] -- null"

My data model:

public class LoanApplication implements java.io.Serializable {

    static final long serialVersionUID = 1L;

    private java.lang.Integer id;
    private java.lang.Integer age;
    private boolean accepted = true;
    private java.util.List<java.lang.String> knockoutReasons = new java.util.ArrayList<java.lang.String>();


    public LoanApplication() {
    }

    public java.lang.Integer getId() {
        return this.id;
    }

    public void setId(java.lang.Integer id) {
        this.id = id;
    }

    public java.lang.Integer getAge() {
        return this.age;
    }

    public void setAge(java.lang.Integer age) {
        this.age = age;
    }

    public boolean isAccepted() {
        return this.accepted;
    }

    public void setAccepted(boolean accepted) {
        this.accepted = accepted;
    }

    public java.util.List<java.lang.String> getKnockoutReasons() {
        return this.knockoutReasons;
    }

    public void setKnockoutReasons(
            java.util.List<java.lang.String> knockoutReasons) {
        this.knockoutReasons = knockoutReasons;
    }

    public void addKnockoutReason(String knockoutReason) {
        if (this.knockoutReasons == null) {
            this.knockoutReasons = new java.util.ArrayList<java.lang.String>();
        }
        this.knockoutReasons.add(knockoutReason);
    }



    public String toString() {
        return "loanApplicationResponse::[accepted=" + this.accepted 
        + ",knockoutReasons="
        + this.knockoutReasons.toString() + "]";
    }

    public LoanApplication(java.lang.Integer id, java.lang.Integer age,
                           boolean accepted, java.util.List 
                           knockoutReasons) {
        this.id = id;
        this.age = age;
        this.accepted = accepted;
        this.knockoutReasons = knockoutReasons;
    }
}

and my rule is:

package com.xyz.loanapplicationreviewer;

import com.xyz.loanapplicationreviewer.LoanApplication;
import org.kie.api.runtime.process.WorkflowProcessInstance;

rule 'age less than 30 do not accept'
ruleflow-group 'ageKnockoutGroup'
  dialect "mvel"
  when
    $process : WorkflowProcessInstance();
    $loanApp : LoanApplication() from (LoanApplication)$process.getVariable("loanApplication");
    eval ($loanApp.getAge() < 30);
  then
    $loanApp.setAccepted(false);
    $loanApp.addKnockoutReason("age under 30");
    ((WorkflowProcessInstance)kcontext.getKnowledgeRuntime().getProcessInstance($process.getId())).setVariable("loanApplication", $loanApp);
    System.out.println("Age less than 30 knockout");
end

I have added the an entry script on the business rule step to fill in the process instance like so:

kcontext.getKnowledgeRuntime().insert(kcontext.getProcessInstance()); 

I also have filled in what I expect to be my data assignments as well. It appears to get the data because when I create a new instance and run it from the form it has the data and executes the rule, just from the rest interface using swagger I get the above error.


Solution

  • After looking at this for much to long;

    It seems I had to have modify my request slightly to become:

    {
      "loanApplication" : {
        "com.xyz.abc.LoanApplication" : {
          "id" : 1,
          "age": 1,
          "accepted" : true
        }
      }
    }
    

    Further I had to change the rule to look like:

    rule 'age less than 30 do not accept'
      ruleflow-group 'ageKnockoutGroup'
      dialect "mvel"
      when
        loanApplication : LoanApplication(age < 30);
        //process : WorkflowProcessInstance();
        //loanApp : LoanApplication() from (LoanApplication)process.getVariable("loanApplication");
        //eval (loanApp.getAge() < 30);
      then
        loanApplication.setAccepted(false);
        loanApplication.addKnockoutReason("age under 30");
        System.out.println("in then less than 30 with loanApp:" + loanApplication.toString());
        String knockoutReasonFact = "age under 30";
        boolean acceptedFact = false;
        insert(knockoutReasonFact);
        insert(acceptedFact);
        update(loanApplication);
    end
    

    Using all the same endpoints I ultimately got the response back that I had expected. I just ended up tracing through how business central was calling into my drools/jbpm process and just mirrored that.