Package org.drools.integrationtests

Source Code of org.drools.integrationtests.FusionIncrementalKbaseTest

package org.drools.integrationtests;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.agent.KnowledgeAgent;
import org.drools.agent.KnowledgeAgentConfiguration;
import org.drools.agent.KnowledgeAgentFactory;
import org.drools.conf.EventProcessingOption;
import org.drools.core.util.FileManager;
import org.drools.event.knowledgeagent.AfterChangeSetAppliedEvent;
import org.drools.event.knowledgeagent.AfterChangeSetProcessedEvent;
import org.drools.event.knowledgeagent.AfterResourceProcessedEvent;
import org.drools.event.knowledgeagent.BeforeChangeSetAppliedEvent;
import org.drools.event.knowledgeagent.BeforeChangeSetProcessedEvent;
import org.drools.event.knowledgeagent.BeforeResourceProcessedEvent;
import org.drools.event.knowledgeagent.KnowledgeAgentEventListener;
import org.drools.event.knowledgeagent.KnowledgeBaseUpdatedEvent;
import org.drools.event.knowledgeagent.ResourceCompilationFailedEvent;
import org.drools.event.rule.DebugAgendaEventListener;
import org.drools.event.rule.DebugKnowledgeAgentEventListener;
import org.drools.io.ResourceChangeScannerConfiguration;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import org.junit.Before;
import org.junit.Test;

/**
* Test case for BZ-813547 / JBRULES-3467
*/
public class FusionIncrementalKbaseTest {

  FileManager fileManager;
  KnowledgeBase kbase;
    private KnowledgeAgent kagent;

  @Before
  @SuppressWarnings("restriction")
  public void setUp() throws Exception {
    fileManager = new FileManager();
    fileManager.setUp();

    // creating initial rule
    fileManager.write("rule1.drl", createRule("initialRHSPrintMessage"));

    prepareKagent(createChangeSet());

    // scanning changes each 2 seconds
    ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
    sconf.setProperty("drools.resource.scanner.interval", "2");
    ResourceFactory.getResourceChangeScannerService().configure(sconf);

    ResourceFactory.getResourceChangeNotifierService().start();
    ResourceFactory.getResourceChangeScannerService().start();
  }

  @Test
  @SuppressWarnings("restriction")
  public void testIncrementalKbaseChangesWithTemporalRules() throws Exception {
    StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
    KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");

    List<String> list = new ArrayList<String>();
    ksession.setGlobal("list", list);

    Event firtEvent = new Event();
    ksession.insert(firtEvent);
    ksession.fireAllRules();
    assertEquals( 1, list.size() );
        assertTrue(list.contains("initialRHSPrintMessage"));

        // make sure the first event expired
        Thread.sleep( 3000 );

    // now changing the rule resource
    fileManager.write("rule1.drl", createRule("changedRHSPrintMessage"));
   
    // wait for the agent to reload the resource
    scan( kagent );

    // the first event should be expired (2 seconds defined by the rule) but
    // I still should be able to add others
    Event secondEvent = new Event();
    ksession.insert(secondEvent);

    // NPE
    ksession.fireAllRules();

    assertEquals(2, list.size());
    assertTrue(list.contains("initialRHSPrintMessage"));
    assertTrue(list.contains("changedRHSPrintMessage"));

    logger.close();

  }
 
    public void scan(KnowledgeAgent kagent) {
        // Calls the Resource Scanner and sets up a listener and a latch so we can wait until it's finished processing, instead of using timers
        final CountDownLatch latch = new CountDownLatch( 1 );
        final List<ResourceCompilationFailedEvent> resourceCompilationFailedEvents = new ArrayList<ResourceCompilationFailedEvent>();
        KnowledgeAgentEventListener l = new KnowledgeAgentEventListener() {
            public void resourceCompilationFailed(ResourceCompilationFailedEvent event) {
                //It is not correct to throw an exception from a listener becuase
                //it will interfere with the agent's logic.
                //throw new RuntimeException("Unable to compile Knowledge"+ event );
               
                //It is better to use a list and then check if it is empty.
                resourceCompilationFailedEvents.add(event);
            }
           
            public void knowledgeBaseUpdated(KnowledgeBaseUpdatedEvent event) {
            }
            public void beforeResourceProcessed(BeforeResourceProcessedEvent event) {
            }
            public void beforeChangeSetProcessed(BeforeChangeSetProcessedEvent event) {
            }
            public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent event) {
            }
            public void afterResourceProcessed(AfterResourceProcessedEvent event) {
            }
            public void afterChangeSetProcessed(AfterChangeSetProcessedEvent event) {
            }
            public void afterChangeSetApplied(AfterChangeSetAppliedEvent event) {
                latch.countDown();
            }
        };
       
        kagent.addEventListener( l );
       
        try {
            latch.await( 10, TimeUnit.SECONDS );
        } catch ( InterruptedException e ) {
            throw new RuntimeException( "Unable to wait for latch countdown", e);
        }
       
        if ( latch.getCount() > 0 ) {
            throw new RuntimeException( "Event for KnowlegeBase update, due to scan, was never received" );
        }
       
        kagent.removeEventListener( l );
        if (!resourceCompilationFailedEvents.isEmpty()){
            //A compilation error occured
            throw new RuntimeException("Unable to compile Knowledge"+ resourceCompilationFailedEvents.get(0).getKnowledgeBuilder().getErrors() );
        }
    }
 

  @SuppressWarnings("restriction")
  public File createChangeSet() throws Exception {
    String xml = "";
    xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'";
    xml += "    xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'";
    xml += "    xs:schemaLocation='http://drools.org/drools-5.0/change-set http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' >";
    xml += "    <add> ";
    xml += "        <resource source='file:"+ fileManager.getRootDirectory().getPath()+ "/rule1.drl' type='DRL' />";
    xml += "    </add> ";
    xml += "</change-set>";

    return fileManager.write("changeset.xml", xml);
  }

  public void prepareKagent(File changeset) throws Exception {
    KnowledgeBaseConfiguration kbconf = KnowledgeBaseFactory
        .newKnowledgeBaseConfiguration();
    kbconf.setOption(EventProcessingOption.STREAM);
    kbase = KnowledgeBaseFactory.newKnowledgeBase(kbconf);

    // Defining incremental resources to kbase
    KnowledgeAgentConfiguration kaconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
    kaconf.setProperty("drools.agent.newInstance", "false");

    kagent = KnowledgeAgentFactory.newKnowledgeAgent("theAgent", kbase, kaconf);
    kagent.applyChangeSet(ResourceFactory.newUrlResource(changeset.toURI().toURL()));
    kbase = kagent.getKnowledgeBase();
  }

  public String createRule(String rhsMessage) {
    StringBuilder sb = new StringBuilder();

    sb.append("\n\npackage com.sample\n");
    sb.append("import "+Event.class.getCanonicalName()+"\n");
    sb.append("global java.util.ArrayList<String> list\n\n");

    sb.append("declare Event\n");
    sb.append("   @role( event )\n");
    sb.append(" end\n\n");

    sb.append("rule x");
    sb.append("\n");
    sb.append("when\n");
    sb.append("Event() over window:time (2s)\n");
    sb.append("then\n");
    sb.append("   list.add(\"");
    sb.append(rhsMessage);
    sb.append("\");\n");
    sb.append("end\n\n");
    //System.out.println(sb.toString());

    return sb.toString();
  }

  public static class Event {

  }
}
TOP

Related Classes of org.drools.integrationtests.FusionIncrementalKbaseTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.