[rules-users] Drools in a web application

Stephen Masters stephen.masters at me.com
Sat Nov 9 08:16:36 EST 2013


That’s a balancing act I’m struggling with. I’m trying to make it a reasonably full-featued web application, but at the same time, I’m trying to keep it simple enough to use for demonstrating things. Unfortunately, those aims often feel mutually exclusive. But I certainly need to add more explanatory comments. There are some areas of the application where I haven’t done much commenting.

This is the controller class with the @Controller and @RequestMapping annotations in it:

https://github.com/gratiartis/sctrcd-payment-validation-web/blob/master/src/main/java/com/sctrcd/payments/validation/web/PaymentValidationControllerImpl.java

You should see in there that there is a mapping for an IBAN validation request:

    @Override
    @RequestMapping(value = "/iban/validate/{iban}", method = RequestMethod.GET, produces = "application/json")
    public @ResponseBody
    IbanValidationResult validateIban(@PathVariable String iban) {
        IbanValidationResult result = ibanValidator.validateIban(iban);
        log.debug("Validated IBAN: " + result.toString());
        return result;
    }

That invokes an IbanValidator, which in this case has been injected with the “ruleBasedIbanValidator”:

https://github.com/gratiartis/sctrcd-payment-validation-web/blob/master/src/main/java/com/sctrcd/payments/validation/iban/RuleBasedIbanValidator.java

That particular validator is a Spring @Service. It constructs a knowledge base in its constructor, because Spring will instantiate it on start-up, and ensure that there is only one instance.

The validateIban(iban) method in the RuleBasedIbanValidator creates a new stateless session for the knowledge base. It creates an IbanValidationRequest fact, which it inserts into the session and causes rules to fire.

As you might see in the constructor for the IBAN validator, the rules are in here:
https://github.com/gratiartis/sctrcd-payment-validation-web/blob/master/src/main/resources/rules/payments/validation/IbanRules.drl

That contains rules such as this:

rule "IBAN failed the Mod-97 checksum test."
    salience 100
when
    $req: IbanValidationRequest($iban:iban)
    not PaymentValidationAnnotation(
        attribute == PaymentAttribute.iban,
        level == AnnotationLevel.REJECT, 
        ruleName == "IBAN failed the Mod-97 checksum test."
    )
    eval(!IbanMod97Check.isValid($iban))
then
    insert(
        new PaymentValidationAnnotation(
            drools.getRule().getName(),
            AnnotationLevel.REJECT, 
            "The IBAN is not valid.", 
            PaymentAttribute.iban
        )
    );
end

That rule will activate if the IBAN is not valid according to a standard "Mod-97" check. In the case of it activating, it will insert a PaymentValidationAnnotation fact. This is a simple object to note that the request has been rejected, and indicates why.

Whenever an annotation is inserted, the “Derive most severe IBAN annotation” rule might fire. This will update the “mostSevereAnnotation” property of the original IbanValidationRequest. Similarly, the “RejectIBAN request if there is an IBAN rejection annotation” rule will set the “isValid” property to false if the request has has a rejection raised against it.

Going back to the RuleBasedIbanValidator, once the rules have executed, all I do is look at the IbanValdiationRequest that was inserted into the session. I use the contents of that to create an IbanValidationResult which just has a flag to indicate whether it is valid and contains a list of annotations. That gets returned to the controller.

Finally the controller, returns the IbanValidationResult. Because it has a @ResponseBody annotation and the project includes a dependency on Jackson, that result will be converted to JSON automatically. Hence, firing a valid IBAN at the service, I’ll get:

{"annotations":[],"iban":"GB29NWBK60161331926819","valid":true}

… and firing an invalid IBAN gives me:

{"annotations":[],"iban":"GB29NWBK6016133192681","valid”:false}

… which shows that it’s not working right! It’s working out that the IBAN is incorrect, but the response is not including the annotations. Time for me to do a little bit of debugging. :)

Anyway, I hope that’s a useful walkthrough. Feel free to fire more questions at me.

Steve 



On 9 Nov 2013, at 11:28, forsakendoll <forsakendoll at hotmail.com> wrote:

> I'm already reading your code while waiting for response here. Actually Its a
> bit big project for me to start and I'm also new to Spring MVC so its really
> hard for me to read this code too. I'm using annotation for controllers and
> I don't see one in yours. Correct me if I'm wrong what I'm expecting is:
> 
> 1. From the user interaction through the page it will send a request to the
> controller.
> 2. From the controller a bean will be send to the .drl file which have
> rules.
> 3. Update or send back some data to the controller ( this one is I don't
> really have the idea of how can I do this )
> 4. Add to the model attribute the data that has been send by .drl file.
> 
> Please correct me if I'm wrong. And please guide me a bit more to this.
> 
> 
> Stephen Masters wrote
>> Given that you’re using Spring MVC, this might be a reasonable example:
>> 
>> 	https://github.com/gratiartis/sctrcd-payment-validation-web
>> 
>> It has examples of doing this for a simple validation, with a stateless
>> session.
>> 
>> i.e.
>> Request goes to Spring MVC controller.
>> Controller invokes a service bean, which wraps a knowledge base.
>> Rule based validator inserts a fact and executes rules.
>> Rules may or may not set an ‘isValid’ flag on the request. They may (or
>> may not) also annotate that request fact to indicate which rules are
>> rejecting it and why.
>> The rule based validator returns a result object to the service.
>> The service returns a result object to the controller.
>> The controller returns a JSON object to the client.
>> 
>> Hopefully it’s not too difficult to find your way around the project.
>> 
>> To try it out:
>> git clone https://github.com/gratiartis/sctrcd-payment-validation-web
>> cd sctrcd-payment-validation-web
>> mvn clean install tomcat7:run
>> curl http://localhost:9090/iban/validate/GB29NWBK60161331926819
>> Change a couple of characters in the IBAN on another curl to see a
>> rejection.
>> 
>> btw - If anybody else fancies taking a look at it, please feel free to
>> send criticism back to me. Either directly or to discuss on the mailing
>> list. There’s so little out there in the way of documented good practice
>> for using Drools, that I get the impression that everyone just finds their
>> own way. So I would be happy to hear what others feel could be done to
>> improve my little Spring MVC/Drools demo project.
>> 
>> Steve
>> 
>> 
>> On 9 Nov 2013, at 09:24, forsakendoll &lt;
> 
>> forsakendoll@
> 
>> &gt; wrote:
>> 
>>> I'm very new to drools. I know this question is really a noob question
>>> but
>>> please bear with me. I'm using Spring MVC and I want to integrate drools
>>> expert to my project. What I've done so far is to integrate the hello
>>> world
>>> sample of drools expert. But now what I want to do is:
>>> 
>>> 1. Send a bean to the rules for it to evaluate.
>>> 2. Modify the bean depending on the rules
>>> 3. Send it back to the controller to make a response to the user.
>>> 
>>> I was able to do the number 1. But for number 2 and 3. I don't know how
>>> to
>>> do it. I want to have a nested rule. But now I'm only capable of doing
>>> this
>>> rule:
>>> 
>>> global String $test;
>>> 
>>> rule "Excellent"
>>> 
>>>   when
>>>       $m: FLTBean ( listeningScore > 85 )
>>>       $p: FLTBean ( listeningScore < 101 )
>>>   then
>>>       $test = "Excellent";
>>>       System.out.println( $test );
>>> 
>>> end
>>> 
>>> I don't know yet how can I make a nested rule. Please give me a simple
>>> example that a newbie like me can understand.
>>> 
>>> 
>>> 
>>> 
>>> --
>>> View this message in context:
>>> http://drools.46999.n3.nabble.com/Drools-in-a-web-application-tp4026704.html
>>> Sent from the Drools: User forum mailing list archive at Nabble.com.
>>> _______________________________________________
>>> rules-users mailing list
>>> 
> 
>> rules-users at .jboss
> 
>>> https://lists.jboss.org/mailman/listinfo/rules-users
>> 
>> 
>> _______________________________________________
>> rules-users mailing list
> 
>> rules-users at .jboss
> 
>> https://lists.jboss.org/mailman/listinfo/rules-users
> 
> 
> 
> 
> 
> --
> View this message in context: http://drools.46999.n3.nabble.com/Drools-in-a-web-application-tp4026704p4026707.html
> Sent from the Drools: User forum mailing list archive at Nabble.com.
> 
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20131109/e83953d2/attachment-0001.html 


More information about the rules-users mailing list