Skip to content
Advertisement

How to compare nested JsonNode field values with Java object parameter values in DROOLS?

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

Advertisement

Answer

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
Advertisement