8 Replies Latest reply on Jul 24, 2013 7:01 AM by srinipatha

    How Can a Drools Rule call another Drools Rule?

    balazska

      Hy!


      I'd like to invoke a rule from another rule based on a condition.


      When MainRule is firing and the conditions are good, I'd like to invoke an another drools rule.


      Is It possible?
      thx.


        • 1. Re: How Can a Drools Rule call another Drools Rule?
          serkan.s.eskici.online.nl

          I don't know if that's possible with Drools (you should check the manual), but what you certainly can do is making use of Events and Observers.


          Let's say your MainRule looks something like this:



          rule MainRule
          when
            yourComponent: MyComponent()
            //other conditions
          do
            yourComponent.foo();
          end
          



          @Name("myComponent")
          public class MyComponent {
          
              @RaiseEvent("mainrule.fired")
              public void foo() {
                  //do some stuff
              }
          }
          



          @Name("myOtherComponent")
          public class OtherComponent {
          
            @In WorkingMemory subMemory;
          
            @Observer("mainrule.fired")
            public void bar() {
               this.subMemory.insert(yourObject);
               this.subMemory.fireAllRules();
            }
          }
          


          • 2. Re: How Can a Drools Rule call another Drools Rule?
            balazska

            Thanks for yor reply!
            I don't want to use java components, only drools rules.


            Is It possible to change yourComponent.foo(); to {s:hasPermission($myobject,'rule')} ?

            • 3. Re: How Can a Drools Rule call another Drools Rule?
              serkan.s.eskici.online.nl

              I don't understand exactly what you mean, but instead changing foo(), you can add s:hasPermission just inside your rule condition, like this:



              rule MainRule
              when
                myComponent: MyComponent()
                c: PermissionCheck(target == myComponent, action == "theMethodThatNeedsProtection")
                r: Role(name == "admin")
              do
                c.grant();
              end
              



              And ! for that the case that you forgot, if you have many rules in 1 .drl file ALL of them will be iterated IF their conditions are met. So if you place that other rule just inside the same file, it will be fired.


              But don't expect it to be fired in the order you want.

              • 4. Re: How Can a Drools Rule call another Drools Rule?
                balazska
                Thanks.

                This is my scenario:

                I invoke the MainRule from a seam page, then I'd like to invoke an other rule if some conditions are good.

                rule MainRule1
                      no-loop
                      activation-group "ag"
                when
                    $c: PermissionCheck(action == "viewGeneral", granted == false)
                    MyEntity($myEntity : this)
                    //some conditions1
                then
                    //pass $myEntity and invoke viewSpecializedRule1
                end


                rule MainRule1
                      no-loop
                      activation-group "ag"
                when
                    $c: PermissionCheck(action == "viewGeneral", granted == false)
                    MyEntity($myEntity : this)
                    //some conditions2
                then
                    //pass $myEntity and invoke viewSpecializedRule2
                end


                rule viewSpecializedRule1...

                rule viewSpecializedRule2...
                • 5. Re: How Can a Drools Rule call another Drools Rule?
                  balazska
                  so:

                  rule MainRule1
                        no-loop
                        activation-group "ag"
                  when
                      $c: PermissionCheck(action == "viewGeneral", granted == false)
                      MyEntity($myEntity : this)
                      //some conditions1
                  then
                      //pass $myEntity and invoke viewSpecializedRule1
                  end


                  rule MainRule2
                        no-loop
                        activation-group "ag"
                  when
                      $c: PermissionCheck(action == "viewGeneral", granted == false)
                      MyEntity($myEntity : this)
                      //some conditions2
                  then
                      //pass $myEntity and invoke viewSpecializedRule2
                  end


                  rule viewSpecializedRule1...

                  rule viewSpecializedRule2...
                  • 6. Re: How Can a Drools Rule call another Drools Rule?
                    balazska

                    Is it possible?

                    • 7. Re: How Can a Drools Rule call another Drools Rule?
                      finalspy

                      Isn't it the purpose of the agenda-group ?
                      Recently seen in a book on drools :





                      rule "MrFlow"
                           when
                                person : Person ( gender == 'M');
                           then
                                System.out.println("Mr flow activated");
                                drools.setFocus("MrGroup");
                      end
                      
                      rule "MrsFlow"
                           when
                                person : Person ( gender == 'F');
                           then
                                System.out.println("Mr flow activated");
                                drools.setFocus("MrsGroup");
                      end
                      
                      rule "HelloMr"
                           agenda-group "MrGroup"
                           when
                                person : Person ();
                           then
                                System.out.println("Hello Mr. " + person.getName());
                                retract (person);
                      end
                      
                      rule "HelloMrs"
                           agenda-group "MrsGroup"
                           when
                                person : Person ();
                           then
                                System.out.println("Hello Mrs. " + person.getName());
                                retract (person);
                      end
                      


                      Here MrFlow rule calls HelloMr and MrsFlow rule calls HelloMrs one.



                      Hope this helps ...


                      Yann

                      • 8. Re: How Can a Drools Rule call another Drools Rule?
                        srinipatha

                        Is any possible way to call rule with in rule... please give some more information...