Search code examples
spring-bootdroolskie

How to fire DRL rules deployed on KIE Server using spring boot?


I created a simple project in Drools work bench. The project has 1 data object and 2 DRL files. I build and deployed the project to the KIE server. And I have created a simple spring boot application which loads data into the data object using a rest service and fires the rules. Below is the code:

public class Main {

    private static String containerId = "ImportProducts_1.0.1-LATEST";
    private static String user = "kieserver";
    private static String password = "kieserver1!";
    private static String url = "http://localhost:8180/kieserver/services/rest/server";


    private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
    private static final MarshallingFormat FORMAT = MarshallingFormat.JSON;
    private static String CLASS_NAME = "ImportProduct";

    public static void main(String[] args) {
        List<ImportProduct> prods = new ArrayList<>();
        prods.add(new ImportProduct("1", "Grocery - Milk", "OK", 25.0));
        prods.add(new ImportProduct("2", "Fashion - Trouser", "NOT_OK", 1300.0));
        prods.add(new ImportProduct("3", "Grocery - Wheat", "OK", 425.0));
        prods.add(new ImportProduct("4", "Grocery - Dairy Milk Chocolate", "OK", 100.0));

        KieServicesConfiguration config = KieServicesFactory.newRestConfiguration(url, user, password, 60000);
        config.setMarshallingFormat(MarshallingFormat.JSON);
        RuleServicesClient client = KieServicesFactory.newKieServicesClient(config).getServicesClient(RuleServicesClient.class);

        List<Command<?>> cmds = new ArrayList<>();
        KieCommands commands = KieServices.Factory.get().getCommands();
        cmds.add(commands.newInsert(prods, CLASS_NAME));
        cmds.add(commands.newFireAllRules());

        BatchExecutionCommand myCommands = CommandFactory.newBatchExecution(cmds);
        ServiceResponse<ExecutionResults> response = client.executeCommandsWithResults(containerId, myCommands);

        if (response.getType() == ServiceResponse.ResponseType.SUCCESS) {
            LOGGER.info("Commands executed with success! Response: ");
            LOGGER.info("{}", response.getResult());
            List<ImportProduct> prodUpdated = (List<ImportProduct>) response.getResult().getValue(CLASS_NAME);
            //sale.setDiscount(saleUpdated.getDiscount());
            LOGGER.info("Response is: {}", response.getMsg());
            LOGGER.info("Output is: {}", prodUpdated.toString());
        } else {
            LOGGER.error("Error executing rules. Message: {}", response.getMsg());
        }

        //KieServices kieServices = KieServices.Factory.get();
        //ReleaseId releaseId = (ReleaseId) kieServices.newReleaseId( "com.test", "ImportProducts", "1.0.1-LATEST" );

    }
}

The application runs without errors but the there is no impact of the rules on the data fed in the KIE container. The rule deletes the data object if the status != 'OK'. I am getting all the data back I sent in the request body of the POST request service. I think DRL capability is enabled as shown in the stack trace below:

22:11:40.139 [main] DEBUG org.kie.server.client.impl.AbstractKieServicesClientImpl - About to deserialize content:

 '{
  "type" : "SUCCESS",
  "msg" : "Kie Server info",
  "result" : {
    "kie-server-info" : {
      "id" : "kie-server-a017ffcb29dc",
      "version" : "7.55.0.Final",
      "name" : "kie-server-a017ffcb29dc",
      "location" : "http://172.17.0.3:8080/kie-server/services/rest/server",
      **"capabilities" : [ "KieServer", "BRM", "BPM", "CaseMgmt", "BPM-UI", "BRP", "DMN", "Swagger" ],**
      "messages" : [ {
        "severity" : "INFO",
        "timestamp" : {
  "java.util.Date" : 1623926563857
},
        "content" : [ "Server KieServerInfo{serverId='kie-server-a017ffcb29dc', version='7.55.0.Final', name='kie-server-a017ffcb29dc', location='http://172.17.0.3:8080/kie-server/services/rest/server', capabilities=[KieServer, BRM, BPM, CaseMgmt, BPM-UI, BRP, DMN, Swagger]', messages=null', mode=DEVELOPMENT}started successfully at Thu Jun 17 10:42:43 UTC 2021" ]
      } ],
      "mode" : "DEVELOPMENT"
    }
  }
}'

Below is the response I got back:

22:11:41.515 [main] DEBUG org.kie.server.client.impl.AbstractKieServicesClientImpl - About to deserialize content:

 '{
  "type" : "SUCCESS",
  "msg" : "Container ImportProducts_1.0.1-LATEST successfully called.",
  "result" : {
    "execution-results" : {
      "results" : [ {
        "value" : [{"com.test.importproducts.ImportProduct":{
  "id" : "1",
  "category" : "Grocery - Milk",
  "status" : "OK",
  "price" : 25.0
}},{"com.test.importproducts.ImportProduct":{
  "id" : "2",
  "category" : "Fashion - Trouser",
  "status" : "NOT_OK",
  "price" : 1300.0
}},{"com.test.importproducts.ImportProduct":{
  "id" : "3",
  "category" : "Grocery - Wheat",
  "status" : "OK",
  "price" : 425.0
}},{"com.test.importproducts.ImportProduct":{
  "id" : "4",
  "category" : "Grocery - Dairy Milk Chocolate",
  "status" : "OK",
  "price" : 100.0
}}],
        "key" : "ImportProduct"
      } ],
      "facts" : [ {
        "value" : {"org.drools.core.common.DefaultFactHandle":{
  "external-form" : "0:3:459769708:-992461270:3:DEFAULT:NON_TRAIT:java.util.ArrayList"
}},
        "key" : "ImportProduct"
      } ]
    }
  }
}' 

Please help.


Solution

  • I fixed the issue. Below is the working code:

    private Command<?> prepareCommands(List<ImportProduct> facts, String sessionName, String outIdentifier) {
        KieCommands commandsFactory = KieServices.Factory.get().getCommands();
        List<Command> commands = facts.stream().map(commandsFactory::newInsert).collect(Collectors.toList());
        commands.add(commandsFactory.newFireAllRules());
        ObjectFilter factsFilter = new ClassObjectFilter(ImportProduct.class);
        //System.out.println("Check1: "+commandsFactory.newGetObjects(factsFilter, CLASS_NAME));
        //System.out.println("Check2: "+commands.toString());
        commands.add(commandsFactory.newGetObjects(factsFilter, CLASS_NAME));
        return commandsFactory.newBatchExecution(commands, sessionName);
    }