Home > Back-end >  How to compare nested JsonNode field values with Java object parameter values in DROOLS?
How to compare nested JsonNode field values with Java object parameter values in DROOLS?

Time:05-21

I've been trying to execute a set of rules on a request object on the basis of some set of configuration value. Below is the example on what I am trying to do:

Configuration: config.json

{
  "company1": {
    "site1": {
      "maxWeeklyWorkingHours": 40,
      "rule2": [1, 3, 4],
    },
    "site2": {
      "maxWeeklyWorkingHours": 40,
      "rule2": [1, 3, 4],
    }
  },
  "company2": {
    "site1": {
      "maxWeeklyWorkingHours": 40,
      "rule2": [1, 3, 4],
    },
    "site2": {
      "maxWeeklyWorkingHours": 40,
      "rule2": [1, 3, 4],
    }
  }
}

Request Class Object: policyDataToBeVerified

PolicyDataToBeVerified(company=company1, site=site1, workerWeeklyWorkingHours=39, isRequestValid=0)

I converted the config.json into a JsonNode object:configJson and passed both policyDataToBeVerified and configJson to drools working memory. Below are the approaches I tried to take to frame the rule but failed anyways:

APPROACH 1: drools.drl

rule "maxWorkingHours"
when
    $configJson: JsonNode()
    $policyData: PolicyDataToBeVerified(maximumWeeklyWorkingHours <= $configJson.get(company).get(site).get("workerWeeklyWorkingHours"))
then
    $policyData.setIsRequestValid(true)
 end

Issue: I am getting null pointer exception at $configJson.get(company).get(site).get("workerWeeklyWorkingHours")

APPROACH 2: I even tried to use configJSON as a global variable but, then drools didn't allow me to use get methods of JsonNode to get the nested fields from JSON


I've been trying to find a solution to my problem for past few days, but nothing worked. I'd be happy to learn even if we can view this problem from a different perspective and solve it in a different way, or if we can debug this, whatever works.

Thank you

CodePudding user response:

is there a way for you to map your Json as a simple Java POJO Like

class Config
private List<Company> companies
class Company
private List<site> sites
class Site
private int maxWeeklyWorkingHours
private int[] rule2

Then you would be able to serialize your json as the company POJO and reuse the POJO in your rules.

rule "maxWorkingHours"
when
    $config: Config()
    $policyData: PolicyDataToBeVerified(maximumWeeklyWorkingHours <= 
    $config.getCompany().getSite().getWorkerWeeklyWorkingHours())
then
    $policyData.setIsRequestValid(true)

CodePudding user response:

NOTE: IntellijIDEA has inaccurate linting for .drl files, so request you to not rely on it.

I created a validateSlotsResponse as following for better handling of response:

package com.example.demo;
import lombok.Builder;
import lombok.Data;
import java.util.List;

@Data
@Builder
public class ValidateSlotsResponse {
    boolean isRequestValid;
    List<String> comments;
}

I'll pass this class's object into the working memory of DROOLS, and will update it inside the drools program, which will then be used as the respose for validation.

Below are the rules inside my drools file, please make sure you have made the right imports:

rule "fetchMaximumAllowedWeeklyWorkingHours"
when
     $validateSlotsResponse: ValidateSlotsResponse()
     $policyDataToBeVerified: PolicyDataToBeVerified()
     $configJson: JsonNode()
     $workingHoursAllowed:Integer() from $configJson.get($policyDataToBeVerified.getCompany()).get($policyDataToBeVerified.getSite()).get("maxWeeklyWorkingHours").intValue()
then
 end


 rule "maxWorkingHoursAccept" extends "fetchMaximumAllowedWeeklyWorkingHours"
 when
     eval($policyDataToBeVerified.workerWeeklyWorkingHours() <= $workingHoursAllowed)
 then
     $policyDataToBeVerified.setIsRequestValid(true);
     $validateSlotsResponse.setRequestValid(true);
     $validateSlotsResponse.setComments(new ArrayList<>(Arrays.asList("Worker allowed to work for " $policyDataToBeVerified.getMaximumWeeklyWorkingHours()   " hours")));
  end


  rule "maxWorkingHoursReject" extends "fetchMaximumAllowedWeeklyWorkingHours"
  when
       eval($policyDataToBeVerified.workerWeeklyWorkingHours() > Integer.parseInt($workingHoursAllowed.toString()))
  then
       $policyDataToBeVerified.setIsRequestValid(false);
       $validateSlotsResponse.setRequestValid(false);
       $validateSlotsResponse.setComments(new ArrayList<>(Arrays.asList("Worker not allowed to work more than "  $workingHoursAllowed   " hours")));
  end
  • Related