Search code examples
javadroolsdrools-kie-server

how to insert facts in drools at runtime to share between rules?


I have a simple that checks whether a user id is present in db

rule "check if user is already present"
agenda-group "dbcheck"
    when
        $blackListUserDto : BlackListUserDto(  )
        eval( BlackListServiceImpl.isUserBlacklisted($blackListUserDto) )

    then
        System.out.println("to be executed first");
        System.out.println($blackListUserDto.isUserAlreadyBlacklisted());
end

The method isUserBlacklisted is as follows

public static boolean isUserBlacklisted(BlackListUserDto blackListUserDto)
    {
        try {
            BlackListEntity blackListEntity = blackListRepository.findByUserId(blackListUserDto.getUserId());
            if(blackListEntity!=null)
                {
                blackListUserDto.setUserAlreadyBlacklisted(true);
                }
            else
            //do something else
        } catch (Exception e) {

            e.printStackTrace();
            return false;
        }

        return true;
    }

As it can be seen that I am modifying the fact(dto) blackListUserDto by setUserAlreadyBlacklisted(true).

But in the "then" part of rule when I am printing the value

System.out.println($blackListUserDto.isUserAlreadyBlacklisted()); The output is still false.

also I need to share this data in another rule which is as follows

rule "blacklist user"
agenda-group "blacklist"
    when
        (BlackListUserDto( userAlreadyBlacklisted == false ))
    then
        //do something else
end

so far my understanding is that when I edit facts then do we need to re insert them again? if yes then how do I insert it in the same session as there is another method in which I am creating this session as follows :-

public void blacklistUser(String userId) throws IOException
    {
            BlackListUserDto blackListUserDto=new BlackListUserDto();
        blackListUserDto.setUserId(userId);

        KieSession kieSession = kContainer.newKieSession();

        Agenda agenda = kieSession.getAgenda();
        agenda.getAgendaGroup( "blacklist" ).setFocus();
        agenda.getAgendaGroup( "dbcheck" ).setFocus();

        kieSession.insert(blackListUserDto);
        kieSession.insert(queryTypeDto);

        kieSession.fireAllRules();
        kieSession.dispose();
    }

what all changes to be done to make sure that the fact gets updated and the updated value gets reflected in the next rule.


Solution

  • I found a solution to the above and I am sharing the rule that solved the above use case

    rule "check if user is already blacklisted 1"
    agenda-group "dbcheck"
        when
            (QueryTypeDto( queryType == "blacklist" ))
            $blackListUser : BlackListUserDto(  )
            not ControlFact( blackListUserDto == $blackListUser )
            $blackListUserDto : BlackListUserDto(  )
            eval( BlackListServiceImpl.isUserBlacklisted($blackListUser) == false )
            $queryTypeDto : QueryTypeDto()
        then
            System.out.println("to be executed first");
            System.out.println($blackListUser.isBlackListFraudUser());
            modify($blackListUser){
            setBlackListFraudUser(true)
            }
            insert (new ControlFact($blackListUser));
            //$queryTypeDto.setUserBlackListed(false);
    end
    

    This blog will help more in understanding the use of modify in drools : https://ilesteban.wordpress.com/2012/11/16/about-drools-and-infinite-execution-loops/