Request from java application gives me problems

344 views
Skip to first unread message

Marius Lazar

unread,
Mar 29, 2016, 2:31:26 PM3/29/16
to Drools Usage
Hi there,

I have used KIE Workbench 6.3.0 and KIE Server 6.3.0. Inside the workbench I have built a data object "demo.firstattempt.Person" with name, age and valid properties and a guided rule that set the valid property of the person to "valid" in case age > 18. I have deployed the object and the rule to the server. If I make the POST from POSTMAN I get the expected result:

{
   
"commands":[
     
{
         
"insert":{
           
"out-identifier":"jonny",
           
"object":{
               
"demo.firstattempt.Person":{
                 
"name":"John",
                 
"age":26,
                 
"valid":"invalid"
               
}
           
}
         
}
     
},
     
{
         
"fire-all-rules":""
     
}
   
]
}

I get:

{
   
"type":"SUCCESS",
   
"msg":"Container ruleContainer successfully called.",
   
"result":"{\r\n  \"results\" : [ {\r\n    \"key\" : \"\",\r\n    \"value\" : 1\r\n  }, {\r\n    \"key\" : \"jonny\",\r\n    \"value\" : {\"demo.firstattempt.Person\":{\"name\":\"John\",\"age\":26,\"valid\":\"valid\"}}\r\n  } ],\r\n  \"facts\" : [ {\r\n    \"key\" : \"jonny\",\r\n    \"value\" : {\r\n      \"external-form\" : \"0:8:910483374:910483374:8:DEFAULT:NON_TRAIT:demo.firstattempt.Person\"\r\n    }\r\n  } ]\r\n}"
}

But when I try to access the server from my application through the REST API nothing change:

{
   
"results":[
     
{
         
"key":"john",
         
"value":{
           
"type":"MAP",
           
"element":[
               
{
                 
"key":"name",
                 
"value":"John"
               
},
               
{
                 
"key":"age",
                 
"value":20
               
},
               
{
                 
"key":"valid",
                  "value":"invalid"
               
}
           
]
         
}
     
}
   
],
   
"facts":[
     
{
         
"key":"john",
         
"value":{
           
"external-form":"0:7:1436937083:1920279190:7:DEFAULT:NON_TRAIT:java.util.LinkedHashMap"
         
}
     
}
   
]
}

My application code is like this:

        String serverUrl = "http://localhost:8080/kie-server/services/rest/server";
       
String user = "kieserver";
       
String password = "-------";
       
String containerId = "ruleContainer";
       
       
KieServicesConfiguration configuration = KieServicesFactory.newRestConfiguration(serverUrl, user, password);
        configuration
.setMarshallingFormat(MarshallingFormat.JSON);
       
KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(configuration);
       
           
List<GenericCommand<?>> cmds = new ArrayList<GenericCommand<?>>();
           
BatchExecutionCommandImpl executionCommand = new BatchExecutionCommandImpl(cmds);
            executionCommand
.setLookup("defaultKieSession");
                       
           
InsertObjectCommand insertObjectCommand1 = new InsertObjectCommand();
            insertObjectCommand1
.setOutIdentifier("john");
            insertObjectCommand1
.setObject(new Person("John",20,"invalid"));

           
FireAllRulesCommand fireAllRulesCommand = new FireAllRulesCommand();

            cmds
.add(insertObjectCommand1);
            cmds
.add(fireAllRulesCommand);
           
           
RuleServicesClient ruleClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
           
ServiceResponse<String> response = ruleClient.executeCommands(containerId, executionCommand);
           
System.out.println("\n\n\n######### Rules executed");
           
System.out.println("\n\n " + response.getResult());


I believe the problem is that on the server I have deployed a "demo.firstattempt.Person" class but on my application I use "com.sample.Person" class when I insert an object.

If that's the problem, can somebody tell me how to create objects from the class that I have deployed on my server not that I have in my application ? Or can I use the one I have in my application ? What's the best approach and how should be done?

And another question, why I get the  "external-form" : "0:7:1436937083:1920279190:7:DEFAULT:NON_TRAIT:java.util.LinkedHashMap" ? What's this?

Thank you very much!

Maciej Swiderski

unread,
Mar 29, 2016, 3:29:56 PM3/29/16
to drools...@googlegroups.com
You can either include kjar as dependency of your application. It as simple as adding it in your pom if you use maven. Workbench is a maven repo so make sure you emdefine it too

Another way is to duplicate (as you already do) class definition. Just make sure they have same signature and fully qualified class name - package and class name

Maciej
--
You received this message because you are subscribed to the Google Groups "Drools Usage" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-usage...@googlegroups.com.
To post to this group, send email to drools...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/drools-usage/70937d61-c010-42fe-9d8e-2258b0047419%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Marius Lazar

unread,
Mar 30, 2016, 4:34:42 PM3/30/16
to Drools Usage
Thank you Maciej! I tried both options, but the same problem happens. The rule only apply when I POST using the RESTClient firefox extension. From my application, still doesn't work.

When I post with RESTClient, I use this code + JSON content type:

{
     
"commands":[
       
{
         
"insert":{
             
"out-identifier":"jony",
             
"return-object":"true",
             
"object":{
                 
"demo.firstattempt.Person":{
                     
"name":"john",
                     
"age":25,
                     
"valid":"invalid"
                 
}
             
}
           
}
       
},
       
{
         
"fire-all-rules":""
       
}
     
]
 
}

And as response I got:

{
"type" : "SUCCESS",
"msg" : "Container rulesContainer successfully called.",
"result" : "{\r\n \"results\" : [ {\r\n \"key\" : \"\",\r\n \"value\" : 1\r\n }, {\r\n \"key\" : \"jony\",\r\n \"value\" : {\"demo.firstattempt.Person\":{\"name\":\"john\",\"age\":25,\"valid\":\"true\"}}\r\n } ],\r\n \"facts\" : [ {\r\n \"key\" : \"jony\",\r\n \"value\" : {\r\n \"external-form\" : \"0:1:1129868577:1129868577:1:DEFAULT:NON_TRAIT:demo.firstattempt.Person\"\r\n }\r\n } ]\r\n}"}

When I post from my app wrote in my first post, I got this:

 {
 
"results" : [ {
 
"key" : "marius",

 
"value" : {
 
"type" : "MAP",
 
"element" : [ {
 
"key" : "name",

 
"value" : "Marius"

 
}, {
 
"key" : "age",
 
"value" : 20
 
}, {
 "key" : "valid",
 
"value" : "invalid"
 
} ]
 
}
 
} ],
 
"facts" : [ {

 
"key" : "marius",
 
"value" : {
 
"external-form" : "0:2:272566824:-81332424:2:DEFAULT:NON_TRAIT:java.util.LinkedHashMap"
 
}
 
} ]
}


My rule deployed on the server:

package demo.firstattempt;

import java.lang.Number;

rule
"Valid age"
 dialect
"mvel"
 
when
 person
: Person( age >= 18 )
 
then
 person
.setValid( "true" );
end



I don't understand what's the problem... Can you check my code please? Or give me some suggestions...

Maciej Swiderski

unread,
Mar 31, 2016, 5:05:51 AM3/31/16
to drools...@googlegroups.com
Could you post your complete code how you use the api so we can take a look at what’s possible causing issue.

Maciej
--
You received this message because you are subscribed to the Google Groups "Drools Usage" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-usage...@googlegroups.com.
To post to this group, send email to drools...@googlegroups.com.

Marius Lazar

unread,
Mar 31, 2016, 11:01:58 AM3/31/16
to Drools Usage
Yes, of course.

This is my DroolsTest class:

package com.sample;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.drools.core.command.impl.GenericCommand;
import org.drools.core.command.runtime.BatchExecutionCommandImpl;
import org.drools.core.command.runtime.rule.FireAllRulesCommand;
import org.drools.core.command.runtime.rule.InsertObjectCommand;
import org.kie.server.api.marshalling.Marshaller;
import org.kie.server.api.marshalling.MarshallerFactory;
import org.kie.server.api.marshalling.MarshallingFormat;
import org.kie.server.api.model.KieContainerResource;
import org.kie.server.api.model.KieContainerResourceList;
import org.kie.server.api.model.ReleaseId;
import org.kie.server.api.model.ServiceResponse;
import org.kie.server.client.KieServicesClient;
import org.kie.server.client.KieServicesConfiguration;
import org.kie.server.client.KieServicesFactory;
import org.kie.server.client.RuleServicesClient;
import demo.firstattempt.Person;

/**
 * This is a sample class to launch a rule.
 */

public class DroolsTest {
   
   
public static final void main(String[] args) {

       
String serverUrl = "http://localhost:8080/kie-server/services/rest/server";
       
String user = "kieserver";

       
String password = "kieserver1!";
       
String containerId = "rulesContainer";

       
       
KieServicesConfiguration configuration = KieServicesFactory.newRestConfiguration(serverUrl, user, password);
        configuration
.setMarshallingFormat(MarshallingFormat.JSON);
       
KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(configuration);

       
KieContainerResource myContainer = null;
       
       
boolean deployContainer = true;
       
KieContainerResourceList containers = kieServicesClient.listContainers().getResult();
       
// check if the container is not yet deployed, if not deploy it
       
if (containers != null) {
           
for (KieContainerResource kieContainerResource : containers.getContainers()) {
               
if (kieContainerResource.getContainerId().equals(containerId)) {
                   
System.out.println("\t######### Found container " + containerId + " skipping deployment...");
                    deployContainer
= false;
                    myContainer
= kieContainerResource;
                   
break;
               
}
           
}
       
}
       
// deploy container if not there yet        
       
if (deployContainer) {
           
System.out.println("\n\n\n######### Deploying container " + containerId);
           
KieContainerResource resource = new KieContainerResource(containerId, new ReleaseId("demo", "firstattempt", "1.0.8"));
            kieServicesClient
.createContainer(containerId, resource);
            myContainer
= resource;

       
}
       
           
List<GenericCommand<?>> cmds = new ArrayList<GenericCommand<?>>();
           
BatchExecutionCommandImpl executionCommand = new BatchExecutionCommandImpl(cmds);
            executionCommand
.setLookup("defaultKieSession");
                       
           
InsertObjectCommand insertObjectCommand1 = new InsertObjectCommand();

            insertObjectCommand1
.setOutIdentifier("marius");
            insertObjectCommand1
.setReturnObject(true);
           
Person p = new Person("Marius",20,"invalid");
            insertObjectCommand1
.setObject(p);


           
FireAllRulesCommand fireAllRulesCommand = new FireAllRulesCommand();

            cmds
.add(insertObjectCommand1);
            cmds
.add(fireAllRulesCommand);
           
           
RuleServicesClient ruleClient = kieServicesClient.getServicesClient(RuleServicesClient.class);
           
ServiceResponse<String> response = ruleClient.executeCommands(containerId, executionCommand);
           
System.out.println("\n\n\n######### Rules executed");
           
System.out.println("\n\n " + response.getResult());
           
   
}

}



And this is my Person class(same as in workbench):

package demo.firstattempt;

/**
 * This class was automatically generated by the data modeler tool.
 */


public class Person implements java.io.Serializable
{

   
static final long serialVersionUID = 1L;

       
@org.kie.api.definition.type.Label("Name")
       
private java.lang.String name;
       
@org.kie.api.definition.type.Label("Age")
       
private int age;
       
@org.kie.api.definition.type.Label(value = "Over 18")
       
private java.lang.String valid;

       
public Person()
       
{
       
}

       
public java.lang.String getName()
       
{
         
return this.name;
       
}

       
public void setName(java.lang.String name)
       
{
         
this.name = name;
       
}

       
public int getAge()
       
{
         
return this.age;
       
}

       
public void setAge(int age)
       
{
         
this.age = age;
       
}

       
public java.lang.String getValid()
       
{
         
return this.valid;
       
}

       
public void setValid(java.lang.String valid)
       
{
         
this.valid = valid;
       
}

       
public Person(java.lang.String name, int age, java.lang.String valid)
       
{
         
this.name = name;
         
this.age = age;
         
this.valid = valid;
       
}

}

And this is my rule:

package demo.firstattempt;

import java.lang.Number;

rule
"Valid age"
 dialect
"mvel"
 
when
 person
: Person( age >= 18 )
 
then
 person
.setValid( "true" );
end

Thank you!

Maciej Swiderski

unread,
Mar 31, 2016, 11:39:53 AM3/31/16
to drools...@googlegroups.com
you need to add your class(es) to the marhsaller of kie server client - see this example on how to do it. 

don’t be misled by the name JaxbClasses as both jaxb and json rely on it.

Once you have this in place marshaller will produce properly the wrapper of the JSON object for that given class so server can properly unmarshal it and process.

Maciej
--
You received this message because you are subscribed to the Google Groups "Drools Usage" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-usage...@googlegroups.com.
To post to this group, send email to drools...@googlegroups.com.

Marius Lazar

unread,
Mar 31, 2016, 2:15:03 PM3/31/16
to Drools Usage
Thank you. It worked after adding the class to the configuration!

       
KieServicesConfiguration configuration = KieServicesFactory.newRestConfiguration(serverUrl, user, password);
        configuration
.setMarshallingFormat(MarshallingFormat.JSON);

       
Set<Class<?>> classes = new HashSet<Class<?>>();
        classes
.add(Person.class);
        configuration
.addJaxbClasses(classes);        
       
KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(configuration);





Is there an example on how to extract the result from the response? I tried with            

ServiceResponse<ExecutionResults> response = ruleClient.executeCommandsWithResults(containerId, executionCommand);

but the "executeCommandsWithResults(string,commands)" it's not recognized (undefined for type RuleServicesClient)

I saw you posted this on another thread pointing to the links below, but that repository was updated one day after you provided the links:

- first you create marshaller:
https://github.com/droolsjbpm/droolsjbpm-integration/blob/master/kie-server-parent/kie-server-tests/kie-server-integ-tests-drools/src/test/java/org/kie/server/integrationtests/drools/StatefulSessionUsageIntegrationTest.java#L97

- next you take the data and unmarshal it:
https://github.com/droolsjbpm/droolsjbpm-integration/blob/master/kie-server-parent/kie-server-tests/kie-server-integ-tests-drools/src/test/java/org/kie/server/integrationtests/drools/StatefulSessionUsageIntegrationTest.java#L110-L111



I have to update my kie.server.client jar? Or what should I do ?

Maciej Swiderski

unread,
Apr 1, 2016, 1:17:49 AM4/1/16
to Drools Usage
2016-03-31 20:15 GMT+02:00 Marius Lazar <marius...@gmail.com>:
Thank you. It worked after adding the class to the configuration!

       
KieServicesConfiguration configuration = KieServicesFactory.newRestConfiguration(serverUrl, user, password);
        configuration
.setMarshallingFormat(MarshallingFormat.JSON);

       
Set<Class<?>> classes = new HashSet<Class<?>>();
        classes
.add(Person.class);
        configuration
.addJaxbClasses(classes);        
       
KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(configuration);


 glad to hear it worked fine



Is there an example on how to extract the result from the response? I tried with            

ServiceResponse<ExecutionResults> response = ruleClient.executeCommandsWithResults(containerId, executionCommand);

but the "executeCommandsWithResults(string,commands)" it's not recognized (undefined for type RuleServicesClient)

executeCommandsWithResults is only available in 6.4 so if you run on previous version it's not there.

--
You received this message because you are subscribed to the Google Groups "Drools Usage" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-usage...@googlegroups.com.
To post to this group, send email to drools...@googlegroups.com.

Marius Lazar

unread,
Apr 2, 2016, 6:25:37 AM4/2/16
to Drools Usage
Thank you, it worked:d ! This what I have done:

Marshaller marshaller = MarshallerFactory.getMarshaller(classes, configuration.getMarshallingFormat(), Person.class.getClassLoader());            
ExecutionResults actualData = marshaller.unmarshall(response.getResult(), ExecutionResultImpl.class);
Person responsePerson = (Person) actualData.getValue("Marius");
System.out.println(responsePerson.getName()+" "+responsePerson.getAge()+" "+responsePerson.getValid());



vijayalakshmi s

unread,
Sep 14, 2017, 1:36:21 AM9/14/17
to Drools Usage
Hi Marius Lazar,

You have mentioned like you made POST call from POSTMAN and you got the result. What is the url and how did you call it from POSTMAN? I'm not getting the exact url to make the call.
Reply all
Reply to author
Forward
0 new messages