Search in sources :

Example 16 with StatefulKnowledgeSession

use of org.drools.runtime.StatefulKnowledgeSession in project jBPM5-Developer-Guide by Salaboy.

the class AdvancedProcessAndRulesIntegrationTest method processEventsTest.

@Test
public void processEventsTest() throws InterruptedException {
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add(new ClassPathResource("evolution/mapping.drl"), ResourceType.DRL);
    kbuilder.add(new ClassPathResource("evolution/scoring_processVariables_wider.drl"), ResourceType.DRL);
    kbuilder.add(new ClassPathResource("evolution/process-events-decision.bpmn"), ResourceType.BPMN2);
    if (kbuilder.hasErrors()) {
        for (KnowledgeBuilderError error : kbuilder.getErrors()) {
            System.out.println(">>> Error:" + error.getMessage());
        }
        fail(">>> Knowledge couldn't be parsed! ");
    }
    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
    final StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
    ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new WorkItemHandler() {

        public void executeWorkItem(WorkItem wi, WorkItemManager wim) {
            System.out.println(" >>> Completing Task! -> " + wi.getName() + " - id: " + wi.getId());
            wim.completeWorkItem(wi.getId(), null);
        }

        public void abortWorkItem(WorkItem wi, WorkItemManager wim) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    });
    KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);
    ksession.addEventListener(new DefaultAgendaEventListener() {

        @Override
        public void activationCreated(ActivationCreatedEvent event) {
            ((StatefulKnowledgeSession) event.getKnowledgeRuntime()).fireAllRules();
        }

        @Override
        public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event) {
            ((StatefulKnowledgeSession) event.getKnowledgeRuntime()).fireAllRules();
        }
    });
    Person person = new Person("Salaboy", 28);
    RatesToday ratesToday = new RatesToday(1, 100);
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("person", person);
    params.put("ratesToday", ratesToday);
    ProcessInstance processInstance = ksession.createProcessInstance("com.salaboy.process.SimpleDecision", params);
    System.out.println("Variables: " + ((WorkflowProcessInstanceImpl) processInstance).getVariables());
    assertEquals(processInstance.getState(), ProcessInstance.STATE_PENDING);
    final FactHandle processHandle = ksession.insert(processInstance);
    ((StatefulKnowledgeSessionImpl) ksession).addEventListener(new DefaultProcessEventListener() {

        @Override
        public void beforeProcessStarted(ProcessStartedEvent event) {
            ((StatefulKnowledgeSession) event.getKnowledgeRuntime()).fireAllRules();
        }

        @Override
        public void afterProcessStarted(ProcessStartedEvent event) {
            ((StatefulKnowledgeSession) event.getKnowledgeRuntime()).fireAllRules();
        }

        @Override
        public void afterProcessCompleted(ProcessCompletedEvent event) {
            ((StatefulKnowledgeSession) event.getKnowledgeRuntime()).retract(processHandle);
        }
    });
    ksession.startProcessInstance(processInstance.getId());
    Thread.sleep(1000);
    //        // If you want to query the process variables while the process Instance is running you can do: 
    //        QueryResults queryResults = ksession.getQueryResults("allProcessVariables", new Object[]{});
    //        Iterator<QueryResultsRow> iterator = queryResults.iterator();
    //
    //        QueryResultsRow ratesRow = iterator.next();
    //        assertEquals(ratesToday, ((ProcessVariable) ratesRow.get("$pv")).getValue());
    //
    //        QueryResultsRow personRow = iterator.next();
    //        assertEquals(person, ((ProcessVariable) personRow.get("$pv")).getValue());
    assertEquals(processInstance.getState(), ProcessInstance.STATE_COMPLETED);
    QueryResults queryResults = ksession.getQueryResults("allProcessVariables", new Object[] {});
    // The Process Variables are automatically retracted when the Process Instance is Completed
    assertEquals(0, queryResults.size());
}
Also used : HashMap(java.util.HashMap) FactHandle(org.drools.runtime.rule.FactHandle) WorkflowProcessInstanceImpl(org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl) DefaultAgendaEventListener(org.drools.event.rule.DefaultAgendaEventListener) WorkItem(org.drools.runtime.process.WorkItem) KnowledgeBuilder(org.drools.builder.KnowledgeBuilder) KnowledgeBase(org.drools.KnowledgeBase) ActivationCreatedEvent(org.drools.event.rule.ActivationCreatedEvent) WorkItemManager(org.drools.runtime.process.WorkItemManager) KnowledgeBuilderError(org.drools.builder.KnowledgeBuilderError) StatefulKnowledgeSession(org.drools.runtime.StatefulKnowledgeSession) ProcessStartedEvent(org.drools.event.process.ProcessStartedEvent) RatesToday(com.salaboy.model.RatesToday) ProcessCompletedEvent(org.drools.event.process.ProcessCompletedEvent) ClassPathResource(org.drools.io.impl.ClassPathResource) QueryResults(org.drools.runtime.rule.QueryResults) WorkItemHandler(org.drools.process.instance.WorkItemHandler) RuleFlowGroupActivatedEvent(org.drools.event.rule.RuleFlowGroupActivatedEvent) StatefulKnowledgeSessionImpl(org.drools.impl.StatefulKnowledgeSessionImpl) DefaultProcessEventListener(org.drools.event.process.DefaultProcessEventListener) ProcessInstance(org.drools.runtime.process.ProcessInstance) Person(com.salaboy.model.Person)

Example 17 with StatefulKnowledgeSession

use of org.drools.runtime.StatefulKnowledgeSession in project jBPM5-Developer-Guide by Salaboy.

the class ProcessAndEventIntegrationTest method createEventsSession.

private StatefulKnowledgeSession createEventsSession() {
    KnowledgeBuilder eventsKbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    eventsKbuilder.add(new ClassPathResource("analyze-process-events.drl"), ResourceType.DRL);
    if (eventsKbuilder.hasErrors()) {
        for (KnowledgeBuilderError error : eventsKbuilder.getErrors()) {
            System.out.println(">>> Error:" + error.getMessage());
        }
        fail(">>> Knowledge couldn't be parsed! ");
    }
    KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
    config.setOption(EventProcessingOption.STREAM);
    KnowledgeBase eventsKbase = KnowledgeBaseFactory.newKnowledgeBase(config);
    eventsKbase.addKnowledgePackages(eventsKbuilder.getKnowledgePackages());
    StatefulKnowledgeSession eventsKsession = eventsKbase.newStatefulKnowledgeSession();
    ((StatefulKnowledgeSessionImpl) eventsKsession).getInternalWorkingMemory().addEventListener(new DefaultWorkingMemoryEventListener() {

        @Override
        public void objectInserted(ObjectInsertedEvent event) {
            event.getWorkingMemory().fireAllRules();
        }

        @Override
        public void objectUpdated(ObjectUpdatedEvent event) {
            event.getWorkingMemory().fireAllRules();
        }

        @Override
        public void objectRetracted(ObjectRetractedEvent event) {
            event.getWorkingMemory().fireAllRules();
        }
    });
    ((StatefulKnowledgeSessionImpl) eventsKsession).getInternalWorkingMemory().addEventListener(new DefaultAgendaEventListener() {

        @Override
        public void activationCreated(ActivationCreatedEvent event, WorkingMemory workingMemory) {
            workingMemory.fireAllRules();
        }
    });
    return eventsKsession;
}
Also used : KnowledgeBuilderError(org.drools.builder.KnowledgeBuilderError) WorkingMemory(org.drools.WorkingMemory) StatefulKnowledgeSession(org.drools.runtime.StatefulKnowledgeSession) ClassPathResource(org.drools.io.impl.ClassPathResource) KnowledgeBuilder(org.drools.builder.KnowledgeBuilder) KnowledgeBase(org.drools.KnowledgeBase) KnowledgeBaseConfiguration(org.drools.KnowledgeBaseConfiguration)

Example 18 with StatefulKnowledgeSession

use of org.drools.runtime.StatefulKnowledgeSession in project jBPM5-Developer-Guide by Salaboy.

the class ProcessAndEventMultiThreadIntegrationTest method createEventsSession.

private StatefulKnowledgeSession createEventsSession() {
    KnowledgeBuilder eventsKbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    eventsKbuilder.add(new ClassPathResource("analyze-process-events.drl"), ResourceType.DRL);
    if (eventsKbuilder.hasErrors()) {
        for (KnowledgeBuilderError error : eventsKbuilder.getErrors()) {
            System.out.println(">>> Error:" + error.getMessage());
        }
        fail(">>> Knowledge couldn't be parsed! ");
    }
    KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
    config.setOption(EventProcessingOption.STREAM);
    KnowledgeBase eventsKbase = KnowledgeBaseFactory.newKnowledgeBase(config);
    eventsKbase.addKnowledgePackages(eventsKbuilder.getKnowledgePackages());
    StatefulKnowledgeSession eventsKsession = eventsKbase.newStatefulKnowledgeSession();
    ((StatefulKnowledgeSessionImpl) eventsKsession).getInternalWorkingMemory().addEventListener(new DefaultWorkingMemoryEventListener() {

        @Override
        public void objectInserted(ObjectInsertedEvent event) {
            event.getWorkingMemory().fireAllRules();
        }

        @Override
        public void objectUpdated(ObjectUpdatedEvent event) {
            event.getWorkingMemory().fireAllRules();
        }

        @Override
        public void objectRetracted(ObjectRetractedEvent event) {
            event.getWorkingMemory().fireAllRules();
        }
    });
    ((StatefulKnowledgeSessionImpl) eventsKsession).getInternalWorkingMemory().addEventListener(new DefaultAgendaEventListener() {

        @Override
        public void activationCreated(ActivationCreatedEvent event, WorkingMemory workingMemory) {
            workingMemory.fireAllRules();
        }
    });
    return eventsKsession;
}
Also used : KnowledgeBuilderError(org.drools.builder.KnowledgeBuilderError) WorkingMemory(org.drools.WorkingMemory) StatefulKnowledgeSession(org.drools.runtime.StatefulKnowledgeSession) ClassPathResource(org.drools.io.impl.ClassPathResource) KnowledgeBuilder(org.drools.builder.KnowledgeBuilder) KnowledgeBase(org.drools.KnowledgeBase) KnowledgeBaseConfiguration(org.drools.KnowledgeBaseConfiguration)

Example 19 with StatefulKnowledgeSession

use of org.drools.runtime.StatefulKnowledgeSession in project jBPM5-Developer-Guide by Salaboy.

the class SingleSessionPatternsTest method singleSessionPerProcessDefinitionWithRules.

/**
     * This test uses a single session to start all the instances of a process 
     * definition. The singularity of the test is that it never starts a process
     * instance directly. Instead of that the session uses a rule to determine
     * when a process instance must be started.
     * @throws Exception 
     */
@Test
public void singleSessionPerProcessDefinitionWithRules() throws Exception {
    //Creates an entity manager and get the user transaction. We are going
    //to need them later to interact with the business entities persisted
    //by the work item handlers we have configured in our session.
    EntityManager em = getEmf().createEntityManager();
    UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
    //Creates the ksession. In this case the ksession
    //will not only contains the process definition but it is also going to
    //have a rule that is going to start a process instance for each
    //Person object we insert in the session.
    StatefulKnowledgeSession ksession = createProcessWithRulesKnowledgeSession("myProcessDefinitionSession");
    registerWorkItemHandlers(ksession, "myProcessDefinitionSession", em);
    //Instead of manually starting a new process instance we will let the
    //rules to start it when they consider it is necessary.
    //In this case we are going to instantiate a Person object and insert it
    //into the session. After this we will call ksession.fireAllRules() to
    //execute any activated rule.
    Person person = new Person("Salaboy", 29);
    ksession.insert(person);
    ksession.fireAllRules();
    //Dispose the session since we are no longer interested in it.
    ksession.dispose();
    //At this point, a process instance must be started and we should have
    //a business entity persisted in the database. Remember that this entity
    //was persisted by the work item hanlder we have configured for our tasks.
    BusinessEntity businessEntity = getBusinessEntity("myProcessDefinitionSession", em);
    Assert.assertNotNull(businessEntity);
    //Let's restore the session now to insert a new instance of Person and
    //see what happens. In order to restore the session we are using the
    //sessionId present in the business entity we have retrieved from the 
    //database.
    ksession = loadKnowldgeSession(businessEntity.getSessionId(), "myProcessDefinitionSession", em);
    assertNotNull(ksession);
    //Let's create a new Person and insert it in the sesssion. This will
    //cause a new process instance to be launched.
    Person person2 = new Person("Salaboy", 29);
    ksession.insert(person2);
    ksession.fireAllRules();
    //Dispose the session since we are no longer interested in it.
    ksession.dispose();
    //Getting the correct work item to finish:
    //If we don't know which workItem do we want to complete we can create 
    //a query to see which are pending work items for a process or for a 
    //more complex business key.
    //If the thread that wants to notify the engine about the completion of 
    //the external interaction is the one which has created the token inside 
    //the WorkItemHandler it can use that unique value to get the related 
    //workItemId.
    BusinessEntity businessEntityByWorkItemId = getBusinessEntityByWorkItemId(1L, em);
    //Before completing the work item we need to reload the session once again.
    ksession = loadKnowldgeSession(businessEntityByWorkItemId.getSessionId(), "myProcessDefinitionSession", em);
    assertNotNull(ksession);
    try {
        // This needs to happen in the same transaction in order to be consistent
        ut.begin();
        //complete the pending work item handler
        ksession.getWorkItemManager().completeWorkItem(businessEntityByWorkItemId.getWorkItemId(), null);
        //mark the BusinessEntity as completed
        markBusinessEntityAsCompleted(businessEntityByWorkItemId.getId(), em);
        ut.commit();
    } catch (Exception e) {
        System.out.println("Rolling back because of: " + e.getMessage());
        ut.rollback();
    }
    //Dispose the session since we are no longer interested in it.
    ksession.dispose();
    //The only pending workItem related to the processId 2 should be 2
    //We can create queries to find out the pending workItems for a process 
    //instance or to find a process instance related to a business scenario 
    //using this approach.
    List<BusinessEntity> businessEntitiesProcessId = getBusinessEntitiesProcessId(2L, em);
    assertEquals(1, businessEntitiesProcessId.size());
    assertEquals(2, businessEntitiesProcessId.get(0).getWorkItemId());
    assertEquals(2, businessEntitiesProcessId.get(0).getProcessId());
}
Also used : UserTransaction(javax.transaction.UserTransaction) EntityManager(javax.persistence.EntityManager) StatefulKnowledgeSession(org.drools.runtime.StatefulKnowledgeSession) BusinessEntity(com.salaboy.sessions.patterns.BusinessEntity) Person(com.salaboy.model.Person) InitialContext(javax.naming.InitialContext) Test(org.junit.Test)

Example 20 with StatefulKnowledgeSession

use of org.drools.runtime.StatefulKnowledgeSession in project jBPM5-Developer-Guide by Salaboy.

the class SingleSessionPatternsTest method singleSessionPerProcessInstance.

/**
     * This test starts 2 process instances of the same process definition
     * in independent sessions.
     * @throws Exception 
     */
@Test
public void singleSessionPerProcessInstance() throws Exception {
    //Creates an entity manager and get the user transaction. We are going
    //to need them later to interact with the business entities persisted
    //by the work item handlers we have configured in our session.
    EntityManager em = getEmf().createEntityManager();
    UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
    //Initial parameters for process instance #1
    Person person = new Person("Salaboy", 29);
    Map<String, Object> params1 = new HashMap<String, Object>();
    params1.put("person", person);
    //Creates the ksession for process instance #1
    StatefulKnowledgeSession ksession1 = createProcessKnowledgeSession(person.getId());
    registerWorkItemHandlers(ksession1, person.getId(), em);
    int ksession1Id = ksession1.getId();
    //Starts process instance #1
    ksession1.startProcess("com.salaboy.process.AsyncInteractions", params1);
    //We don't want to use the ksession anymore so we will dispose it.
    //At this point MockAsyncExternalServiceWorkItemHandler has persisted
    //a business key that we can use later to retireve the session from
    //the database and continue with the execution of the process.
    ksession1.dispose();
    //Initial parameters for process instance #2
    Person person2 = new Person("Salaboy2", 29);
    Map<String, Object> params2 = new HashMap<String, Object>();
    params2.put("person", person2);
    //Creates a new ksession for process instance #2
    StatefulKnowledgeSession ksession2 = createProcessKnowledgeSession(person2.getId());
    registerWorkItemHandlers(ksession2, person2.getId(), em);
    int ksession2Id = ksession2.getId();
    //Starts process instance #2
    ksession2.startProcess("com.salaboy.process.AsyncInteractions", params2);
    //Dispose ksession2 as we don't want to use it anymore. Just like with
    //process instance #1, the work item handler associated to the task nodes
    //of the process has persisted a business key that we can use to continue
    //with the execution of this session later.
    ksession2.dispose();
    //Let's find the BusinessEntity persisted by process instance #2.
    //The key of the BusinessEntity is the the persnon's id.
    BusinessEntity businessEntity = getBusinessEntity(person2.getId(), em);
    assertNotNull(businessEntity);
    //the BusinessEntity must be of session #2
    assertEquals(businessEntity.getSessionId(), ksession2Id);
    //We shouldn't have more active business entities in the database.
    List<BusinessEntity> activeBusinessEntities = getActiveBusinessEntities(em);
    assertTrue(activeBusinessEntities.size() == 2);
    //Let' restore the session #2 using the information present in the BusinessEntity
    //Since we keep one kbase per ksession we also need to get it using
    //the information present in the BusinessEntity.
    ksession2 = loadKnowldgeSession(businessEntity.getSessionId(), businessEntity.getBusinessKey(), em);
    registerWorkItemHandlers(ksession2, businessEntity.getBusinessKey(), em);
    assertNotNull(ksession2);
    try {
        ut.begin();
        //Now that we have session #2 back we can complete the pending work item 
        //handler with the information present in BusinessEntity we can 
        ksession2.getWorkItemManager().completeWorkItem(businessEntity.getWorkItemId(), null);
        //The BusinessEntity is no longer needed so we can marked as completed
        //in the database.
        markBusinessEntityAsCompleted(businessEntity.getId(), em);
        ut.commit();
    } catch (Exception e) {
        System.out.println("Rolling back because of: " + e.getMessage());
        ut.rollback();
    }
    //We are done with ksession #2
    ksession2.dispose();
    //Now we are going to complete the pending work item handler of 
    //the process instance #1, but first we need to restore the session from
    //the database.
    businessEntity = getBusinessEntity(person.getId(), em);
    assertNotNull(businessEntity);
    //the BusinessEntity must be of session #1
    assertEquals(businessEntity.getSessionId(), ksession1Id);
    //load the ksession using the information present in BusinessEntity
    ksession1 = loadKnowldgeSession(businessEntity.getSessionId(), businessEntity.getBusinessKey(), em);
    assertNotNull(ksession1);
    try {
        // This needs to happen in the same transaction in order to be consistent
        ut.begin();
        //complete the pending work item handler
        ksession1.getWorkItemManager().completeWorkItem(businessEntity.getWorkItemId(), null);
        //mark the BusinessEntity as completed
        markBusinessEntityAsCompleted(businessEntity.getId(), em);
        ut.commit();
    } catch (Exception e) {
        System.out.println("Rolling back because of: " + e.getMessage());
        ut.rollback();
    }
    //dispose ksession #1
    ksession1.dispose();
    //We should have two active business entities in the database. Because the processes have two workitems each.
    activeBusinessEntities = getActiveBusinessEntities(em);
    assertEquals(2, activeBusinessEntities.size());
    //We should have two inactive business entities in the database.
    List<BusinessEntity> inActiveBusinessEntities = getInactiveBusinessEntities(em);
    assertEquals(2, inActiveBusinessEntities.size());
}
Also used : UserTransaction(javax.transaction.UserTransaction) HashMap(java.util.HashMap) StatefulKnowledgeSession(org.drools.runtime.StatefulKnowledgeSession) BusinessEntity(com.salaboy.sessions.patterns.BusinessEntity) InitialContext(javax.naming.InitialContext) EntityManager(javax.persistence.EntityManager) Person(com.salaboy.model.Person) Test(org.junit.Test)

Aggregations

StatefulKnowledgeSession (org.drools.runtime.StatefulKnowledgeSession)42 KnowledgeBase (org.drools.KnowledgeBase)28 KnowledgeBuilder (org.drools.builder.KnowledgeBuilder)26 KnowledgeBuilderError (org.drools.builder.KnowledgeBuilderError)26 ClassPathResource (org.drools.io.impl.ClassPathResource)25 HashMap (java.util.HashMap)24 Test (org.junit.Test)21 Person (com.salaboy.model.Person)17 ProcessInstance (org.drools.runtime.process.ProcessInstance)17 DefaultProcessEventListener (org.drools.event.process.DefaultProcessEventListener)12 QueryResults (org.drools.runtime.rule.QueryResults)9 FactHandle (org.drools.runtime.rule.FactHandle)7 Resources (com.salaboy.model.Resources)6 ProcessNodeLeftEvent (org.drools.event.process.ProcessNodeLeftEvent)6 Customer (com.salaboy.model.Customer)5 RatesToday (com.salaboy.model.RatesToday)5 BusinessEntity (com.salaboy.sessions.patterns.BusinessEntity)5 InitialContext (javax.naming.InitialContext)5 EntityManager (javax.persistence.EntityManager)5 UserTransaction (javax.transaction.UserTransaction)5