Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
[enter image description here][1]I am facing some issue in Drools I want to pass date as a date type but currently we don't have any method in JSONObject to handle dates .My JSONObject looks like this.
{"id":600,"city":"Gotham","age":25,"startDate":"29-DEC-2017","endDate":"2014-08-31"}
My Drool condition looks like this.
package com.rules
import org.drools.core.spi.KnowledgeHelper;
import org.json.JSONObject;
rule "ComplexRule1"
salience 100
dialect "mvel"
date-effective "16-Jan-2018 00:00"
no-loop
$cdr : JSONObject( $cdr.optString("startDate") >= '28-Dec-2017')
$cdr.put("Action_1" , new JSONObject().put("actionName","Complex_Rule1_Action1").put("actionTypeName","SEND OFFER").put("channelName","SMS").put("messageTemplateName","SMSTemplate").put("@timestamp",(new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new java.util.Date())).put("ruleFileName","ComplexRule1.drl").put("ruleName","ComplexRule1"));
I am currently using .optString Because we dont have any methods like optString/optInt/optBoolean for date. So how can I handle date in Drools?
Any help will be appreciated.
Regards Puneet
My new DRL looks like this :
package com.rules
import com.aravind.drools.SuperJSONObject;
import org.drools.core.spi.KnowledgeHelper;
import org.json.JSONObject;
rule "Convert to SuperJSONObject"
$cdr: JSONObject()
insert(new SuperJSONObject($cdr));
rule "ComplexRule1"
salience 100
dialect "mvel"
date-effective "16-Jan-2018 00:00"
no-loop
$cdr : SuperJSONObject( $cdr.getAsDate("startDate") == '28-Dec-2017')
$cdr.getObject().put("Action_1" , new JSONObject().put("actionName","Complex_Rule1_Action1").put("actionTypeName","SEND OFFER").put("channelName","SMS").put("messageTemplateName","SMSTemplate").put("@timestamp",(new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new java.util.Date())).put("ruleFileName","ComplexRule1.drl").put("ruleName","ComplexRule1"));
Class look like this :
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.json.*;
public class SuperJSONObject {
public final JSONObject obj;
SimpleDateFormat sdfmt2= new SimpleDateFormat("yyyy/MM/dd");
public SuperJSONObject(JSONObject obj){
this.obj = obj;
public Date getAsDate(String field) throws ParseException{
return sdfmt2.parse(this.obj.optString(field));
public JSONObject getObject(){
return this.obj;
Another Class is like this
import java.io.File
import java.io.FileReader
import org.drools.KnowledgeBase
import org.drools.KnowledgeBaseFactory
import org.drools.builder.KnowledgeBuilder
import org.drools.builder.KnowledgeBuilderFactory
import org.drools.builder.ResourceType
import org.drools.io.ResourceFactory
import org.drools.runtime.StatefulKnowledgeSession
import org.json.JSONObject
object RunStandAloneDrools {
def main(args: Array[String]): Unit = {
var jsonObjectArray: Array[JSONObject] = new Array(1)
jsonObjectArray(0) = new JSONObject("{\"id\":600,\"city\":\"Gotham\",\"age\":25,\"startDate\":\"28-Dec-2017\",\"endDate\":\"2014-08-01\"}")
var file: String = "/home/puneet/Downloads/ComplexRule1.drl"
var kbuilder: KnowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder()
kbuilder.add(ResourceFactory.newReaderResource(new FileReader(new File(file))), ResourceType.DRL)
println("Errors? " + kbuilder.getErrors.size())
var iter = kbuilder.getErrors.iterator()
while(iter.hasNext()){
println(iter.next().getMessage)
var kbase: KnowledgeBase = KnowledgeBaseFactory.newKnowledgeBase()
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages)
var session: StatefulKnowledgeSession = kbase.newStatefulKnowledgeSession()
callRulesEngine(jsonObjectArray,session)
println("Done")
def callRulesEngine(data: Array[JSONObject], knowledgeSession: StatefulKnowledgeSession): Unit = {
data.map ( x => callRulesEngine(x,knowledgeSession) )
def callRulesEngine(data: JSONObject, knowledgeSession: StatefulKnowledgeSession): Unit = {
try {
println("Input data " + data.toString())
knowledgeSession.insert(data)
knowledgeSession.fireAllRules()
println("Facts details " + knowledgeSession.getFactCount)
println("Enriched data " + data.toString())
} catch {
case (e: Exception) => println("Exception", e);
Output is not coming as per expectations
There are multiple ways to deal with this, but the fundamental thing is for you to understand that this is NOT a Drools issue at all. Your question is more on how do get a Date
from a JSONObject
.
One way this could be achieved is by using a function in Drools to make the conversion.
But I don't like functions, so I'll give you another, more elaborated, way to deal with this situation (and many others where a type conversion is required).
The idea is to create a wrapper class for your JSONObject
- a SuperJSONObject
- that will expose all the functionality you need. For the implementation of this class I will be using composition, but you can use inheritance (or a proxy) if you want.
public class SuperJSONObject {
public final JSONObject obj;
public SuperJSONObject(JSONObject obj){
this.obj = obj;
//expose all the methods from JSONObject you want/need
public Date getAsDate(String field){
return someDateParser.parse(this.obj.optString(field));
public JSONObject getObject(){
return this.obj;
So now we have a getAsDate()
method that we can use in our rules. But we first need to convert a JSONObject
into a SuperJSONObject
before we can even use that method. You can do this in multiple ways and places. I'll be showing how to do it in DRL.
rule "Convert to SuperJSONObject"
$jo: JSONObject() //you may want to filter which objects are converted by adding constraints to this pattern
insert(new SuperJSONObject($jo));
And now we are good to go. We can now write a rule using this new class as follows:
rule "ComplexRule1"
salience 100
dialect "mvel"
date-effective "16-Jan-2018 00:00"
no-loop
$cdr : SuperJSONObject( getAsDate("startDate") >= '28-Dec-2017')
$cdr.getObject().put("Action_1" , ...);
After I have written all this code, I might reconsider the option of a simple function in DRL... :P
Hope it helps,
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.