Hi Team,
Need help on an urgent issue. I have tried a lot but no way out. Any help is appreciated.
I am running JBoss and drools in a container hosted in azure vm(32GB RAM, 18GB Heap space). And I am executing rules using the below code in an microservice:
I am facing two problem:
1. I am sending more than 100000 objects in batches of 1000
after a certain time I am getting heap space issue.
2. Execution of rules are very slow
Here is java options which is already set :
-Xmx18G -Xms18G -XX:MetaspaceSize=4G -XX:MaxMetaspaceSize=4G -XX:+UseG1GC -Ddrools.multithreadEvaluation=true -Ddrools.shadowproxy=false -Ddrools.maintainTms=false
-Ddrools.sequential=true -Ddrools.maxThreads=500 -XX:+UseStringDeduplication -XX:MaxDirectMemorySize=5G
==================Client code in Microservice to call and execute rules==========
private KieServicesConfiguration buildKieServicesClient(){
KieServicesConfiguration connectionConfig = KieServicesFactory.newRestConfiguration(
this.serverUrl,
this.user,
this.password,KIESERVER_CONNECTION_TIMEOUT);
connectionConfig.setMarshallingFormat(KIESERVER_MARSHALLING);
addExtraClasses(connectionConfig);
return connectionConfig;
}
private void addExtraClasses(KieServicesConfiguration connectionConfig) {
Set<Class<?>> extraClassList = new HashSet<Class<?>>();
extraClassList.add(SourceData.class);
connectionConfig.addExtraClasses(extraClassList);
}
public static KieServicesClient getKieServicesClient() {
return kieServicesClient;
}
private void setKieServicesClient(final KieServicesClient _kieServicesClient){
kieServicesClient = _kieServicesClient;
}
private List<SourceData> subBatchprocess(List<SourceData> input) {
KieServicesClient kieClient=KieServicesFactory.newKieServicesClient(connectionConfig);
RuleServicesClient client=kieClient.getServicesClient(RuleServicesClient.class);
List<Command<?>> cmds = new ArrayList<Command<?>>();
KieCommands commands= KieServices.Factory.get().getCommands();
for(SourceData sd:input)
{
cmds.add(commands.newInsert(sd));
}
GetObjectsCommand getObjectsCommand = new GetObjectsCommand();
getObjectsCommand.setOutIdentifier("objects");
cmds.add(getObjectsCommand);
BatchExecutionCommand myCommands=commands.newBatchExecution(cmds,ksessionName);
log.info("Calling kie server for this batch ");
ServiceResponse<ExecutionResults> response=null;
List<SourceData> responseList=new ArrayList<SourceData>();
try {
response = client.executeCommandsWithResults(ContainerId, myCommands);
}catch(Exception ex)
{
System.out.println("### exception:executeCommandsWithResults calling got exception -"+ex.getMessage());
}
log.info("Received response from kie server Response:"+response.getMsg());
responseList=(List<SourceData>)response.getResult().getValue("objects");
return responseList;
}
=================================================
using Kie work bench I have create a project with
1. SourceData Class--same SourceData model class which is microservice
2. Functions Class - where all java functions are present which I am calling from ddrl file
3. DRL file- Here all drool rules are present total 40 rules present
========DRL file one sample rule=============
package com.att.hcmlink.hcmlinkruleengine;
import com.att.hcmlink.hcmlinkruleengine.SourceData.*;
import com.att.hcmlink.hcmlinkruleengine.Functions;
import java.text.ParseException;
import java.util.List;
dialect "java"
rule "ConditionMatcher"
@ConditionLHS()
@ConditionRHS()
@ConditionResult()
@DefaultColumnName()
@Hints(This rule will be used for matching condition like if ConditionLHS==ConditionRHS then use value ConditionResult else use default column value)
when
sourceDataInstance:SourceData(ruleName=="ConditionMatcher" && status!="Processed" && status!="Exception")
then
SourceData sd=new SourceData();
sd=sourceDataInstance;
try{
sd.setStatus("Processed");
sd.setDestColumnValue(Functions.ConditionMatcherFunction(Functions.mapLookup(sourceDataInstance.getRuleParam().get("ConditionLHS"),sourceDataInstance.getRow()),sourceDataInstance.getRuleParam().get("ConditionRHS"),sourceDataInstance.getRuleParam().get("ConditionResult"),Functions.mapLookup(sourceDataInstance.getRuleParam().get("DefaultColumnName"),sourceDataInstance.getRow())));
insertLogical(sd);
retract(sourceDataInstance);
}catch(Exception e)
{
sd.setExMsg(e.toString());
sd.setStatus("Exception");
insertLogical(sd);
retract(sourceDataInstance);
}
end
==============Sample function in Functions class============
package com.att.hcmlink.hcmlinkruleengine;
//import java.lang.Integer.parseInt;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Calendar;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import java.text.ParseException;
import java.sql.Timestamp;
import java.time.Instant;
/**
* This class was automatically generated by the data modeler tool.
*/
@org.kie.api.definition.type.Expires("10ms")
public class Functions implements java.io.Serializable {
static final long serialVersionUID = 1L;
public Functions() {
}
public static String ConditionMatcherFunction(String lhs, String rhs,
String result, String originalVal) {
if (lhs.equals(rhs))
return result;
else
return originalVal;
}
public static String splitString(String str, String startPos, String endPos) {
return str.substring(Integer.parseInt(startPos),
Integer.parseInt(endPos));
}
public static String changeDateFormat(String sourceFormat,
String destinationFormat, String dateVal) throws ParseException {
DateFormat inputDateFormat = new SimpleDateFormat(sourceFormat);
inputDateFormat.setLenient(false);
DateFormat outputDateFormat = new SimpleDateFormat(destinationFormat);
Date date = null;
String returnDate = dateVal;
date = inputDateFormat.parse(dateVal);
returnDate = outputDateFormat.format(date);
return returnDate;
}
}
=================SourceData.java===========================
package com.att.hcmlink.hcmlinkruleengine;
/**
* This class was automatically generated by the data modeler tool.
*/
@org.kie.api.definition.type.Expires("10ms")
public class SourceData implements java.io.Serializable {
static final long serialVersionUID = 1L;
@org.kie.api.definition.type.Label("columnName")
private java.lang.String columnName;
@org.kie.api.definition.type.Label("columnValue")
private java.lang.String columnValue;
@org.kie.api.definition.type.Label("ruleName")
private java.lang.String ruleName;
@org.kie.api.definition.type.Label(value = "ruleParam")
private java.util.Map<java.lang.String, java.lang.String> ruleParam;
@org.kie.api.definition.type.Label(value = "row")
private java.util.Map<java.lang.String, java.lang.String> row;
@org.kie.api.definition.type.Label(value = "output")
private java.util.Map<java.lang.String, java.lang.String> output;
@org.kie.api.definition.type.Label("destColumnName")
private java.lang.String destColumnName;
@org.kie.api.definition.type.Label("destColumnPosition")
private java.lang.Integer destColumnPosition;
@org.kie.api.definition.type.Label("destColumnValue")
private java.lang.String destColumnValue;
@org.kie.api.definition.type.Label("rownum")
private java.lang.Integer rownum;
@org.kie.api.definition.type.Label("executionPhase")
private java.lang.Integer executionPhase;
@org.kie.api.definition.type.Label("status")
private java.lang.String status;
@org.kie.api.definition.type.Label("exMsg")
private java.lang.String exMsg;
}
with all getters, setters, constructor, equals, hashcode, and tostring method