0

i'm working at a little drools project and i have following problem:

- when i read the knowledgepackages from drools via the knowledgeAgent it takes a long time to load
((now i know that building the knowledgeBase in general and especially when loading packages from guvnor is very intense ))

  • so I'm trying to serialize the KnowledgeBase to a file which is located locally on the system
    - on the one hand because loading the kBase from a local file is much much faster
    - and for the other so that i can use the KnowledgeBase for other applications
    The Problem with this is, that while using the KnowledgeAgent to load the KnowledgeBase the first time, the base will be updated by the Agent automatically

    BUT: whilst the Base is updated, my local file will not be updated too
    So I'm wondering how to handle/get the changeNotification from my KnowledgeAgent so i can call a method to serialize my KnowledgeBase ?


    Is this somehow possible? basically i just want to update my local knowledgeBase file, everytime someone edits a rule in governor, so that my local file is always up to date.


    If it isn't possible, or a really bad solution to begin with, what is the recommended / best way to go about it?


    Please endure my english and the question itself, if you cant really make out what i want to accomplish or if my request is actually not a good solution or the question itself is redundant, im rather new to java and a total noob when it comes to drools.

Down below is the code:

public class DroolsConnection {

private static KnowledgeAgent kAgent;
private static KnowledgeBase  kAgentBase;

public DroolsConnection(){
     ResourceFactory.getResourceChangeNotifierService().start();
     ResourceFactory.getResourceChangeScannerService() .start();

} 

public KnowledgeBase readKnowledgeBase( ) throws Exception {

     kAgent     = KnowledgeAgentFactory.newKnowledgeAgent("guvnorAgent");
     kAgent      .applyChangeSet( ResourceFactory.newFileResource(CHANGESET_PATH));
     kAgent.monitorResourceChangeEvents(true);

     kAgentBase = kAgent.getKnowledgeBase();
     serializeKnowledgeBase(kAgentBase);
     return kAgentBase;

   }


 public List<EvaluationObject> runAgainstRules( List<EvaluationObject> objectsToEvaluate,
                                                KnowledgeBase kBase ) throws Exception{

    StatefulKnowledgeSession knowSession = kBase.newStatefulKnowledgeSession();
    KnowledgeRuntimeLogger knowLogger    = KnowledgeRuntimeLoggerFactory.newFileLogger(knowSession, "logger");

    for ( EvaluationObject o : objectsToEvaluate ){
        knowSession.insert( o );
    }

    knowSession.fireAllRules();
    knowLogger .close();
    knowSession.dispose();
    return objectsToEvaluate;
 }


 public KnowledgeBase serializeKnowledgeBase(KnowledgeBase kBase) throws IOException{

        OutputStream outStream = new FileOutputStream( SERIALIZE_BASE_PATH );
        ObjectOutputStream oos = new ObjectOutputStream( outStream );
        oos.writeObject        ( kBase );
        oos.close();
        return kBase;
 }


 public KnowledgeBase loadFromSerializedKnowledgeBase() throws Exception {

        KnowledgeBase kBase   = KnowledgeBaseFactory.newKnowledgeBase(); 
        InputStream is        = new FileInputStream( SERIALIZE_BASE_PATH );
        ObjectInputStream ois = new ObjectInputStream( is );
        kBase                 = (KnowledgeBase) ois.readObject();
        ois.close();
        return kBase;
 }

}


thanks for your help in advance!
best regards,
Marenko

Marenko
  • 3
  • 2

1 Answers1

0

In order to keep your local kbase updated you could use a KnowledgeAgentEventListener to know when its internal kbase gets updated:

    kagent.addEventListener( new KnowledgeAgentEventListener() {

        public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent event) {
        }

        public synchronized void afterChangeSetApplied(AfterChangeSetAppliedEvent event) {
        }

        public void beforeChangeSetProcessed(BeforeChangeSetProcessedEvent event) {
        }

        public void afterChangeSetProcessed(AfterChangeSetProcessedEvent event) {
        }

        public void beforeResourceProcessed(BeforeResourceProcessedEvent event) {
        }

        public void afterResourceProcessed(AfterResourceProcessedEvent event) {
        }

        public void knowledgeBaseUpdated(KnowledgeBaseUpdatedEvent event) {
            //THIS IS THE EVENT YOU ARE INTERESTED IN 
        }

        public void resourceCompilationFailed(ResourceCompilationFailedEvent event) {               
        }
    } );

You still need to handle concurrently accesses on your local kbase though.

By the way, since you are not using 'newInstance' configuration option, the agent will create a new instance of a kbase each time a change-set is applied. So, make sure you serialize the kagent's internal kbase (kagent.getKnowledgeBase()) instead of the reference you have in your app.

Hope it helps,

Esteban Aliverti
  • 6,259
  • 2
  • 19
  • 31
  • thank you very much for your answer, i hope that is what i was looking for, too. when i run into an issue, ill come back to you, thanks much for the quick reply :) – Marenko Feb 11 '13 at 07:48
  • when i try to serialize the event.getKnowledgeBase int the konwledgeBaseUpdated function, i get an io.EOFException when trying to read from the serialized knowledgebase ("at java.io.ObjectInputStream.something (Unknown Source)". when i remove the eventlistener it works just fine, do you have any idea for me? – Marenko Feb 11 '13 at 09:51
  • Do you have the complete stacktrace? – Esteban Aliverti Feb 11 '13 at 10:30
  • Sry Esteban, but i already changed my code and the way i go about it (still doesnt work though). Thanks really much for your help though, gave me some pushs in a good direction. could you maybe redirect me to a really good documentation about the knowledgeAgent? i cant seem to get it into my head and i need it for hotdeployment using guvnor, so that we will be able to change rules on the fly. if not, really appreciating your help so far :) – Marenko Feb 11 '13 at 14:50
  • Unfortunately there is no other documentation other than the one present in drools.org: http://docs.jboss.org/drools/release/5.5.0.Final/drools-expert-docs/html_single/index.html#d0e2239 – Esteban Aliverti Feb 11 '13 at 15:44
  • I also have some old posts that may give you some more information: http://ilesteban.wordpress.com/2010/03/25/knowledge-agent-incremental-change-set-processing-and-binary-diff/ and http://ilesteban.wordpress.com/2010/05/26/knowledge-agent-incremental-change-set-build-implementation/ – Esteban Aliverti Feb 11 '13 at 15:45