1 2 Previous Next 15 Replies Latest reply: Oct 17, 2012 4:39 AM by Mai A. S RSS

Human task API, how to move forward in the workflow ?

John Augusto Charnet Newbie

I'm finishing my human task, with the taskClient API, calling start and complete on the human task. But my next task, (after the human task) never gets called.

 

Do I need to do something else in my code ?

 

 

Thanks a lot.

 

John

  • 1. Re: Human task API, how to move forward in the workflow ?
    Demian Calcaprina Master

    I have made something similar in a test, it may help you:

     

    https://github.com/calcacuervo/JBPM5-Samples/blob/master/human-tasks/src/test/java/com/test/HumanTaskTest.java

     

    How are you checking that your next task in not getting called?

     

    Demian

  • 3. Re: Human task API, how to move forward in the workflow ?
    John Augusto Charnet Newbie

    Thansk for your reply.

    I took a look at your example Demian, and also I've already had looked at jbpm examples like Tihomir had suggested. Apparently there is not any difference in the way I'm using the Task Client API.

     

    The way I'm checking if the next task is getting called is by debug. Mas next task has a task handler, and I have a breakpoint in this task handler.

    If I create a custom task handler for the human task, and call the completeWorkItem method, my next task does get called. So I know that there is nothing wrong with this next task.

     

    My environment is:

    Spring for the model and transactions ( I do not configure any jbpm in spring )

    JPA - Hibernate for persistence.

     

    I'm also persisting the workflow in the database with JPAKnowledgeService and CommandBasedWSHumanTaskHandler.

     

    Any other ideas I could try ?

     

    Thanks,

     

    John

  • 4. Re: Human task API, how to move forward in the workflow ?
    Demian Calcaprina Master

    Hi John.

     

    Are you using the Console Logger? What is it logging after you call complete?

     

    If possible, could you please provide a test that shows this error with you configurations?

     

    Thanks,

     

    Demian

  • 5. Re: Human task API, how to move forward in the workflow ?
    John Augusto Charnet Newbie

    Here is the complete log.

    It has hibernate statements and the jbpm console logger.

    I can't see through the jbpm console logger, anything related to the complete task. But if you see the hibernate statemens, you will find some updates to the task table, the last update sets the status to Completed.

     

    Thanks

    Hibernate:

        select

            task0_.id as col_0_0_,

            deadline1_.id as col_1_0_,

            deadline1_.deadline_date as col_2_0_

        from

            Task task0_,

            Deadline deadline1_

        where

            (

                deadline1_.id in (

                    select

                        startdeadl2_.id

                    from

                        Deadline startdeadl2_

                    where

                        task0_.id=startdeadl2_.Deadlines_StartDeadLine_Id

                )

                or deadline1_.id in (

                    select

                        enddeadlin3_.id

                    from

                        Deadline enddeadlin3_

                    where

                        task0_.id=enddeadlin3_.Deadlines_EndDeadLine_Id

                )

            )

            and deadline1_.escalated=0

        order by

            deadline1_.deadline_date

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    BEFORE RULEFLOW VARIABLE CHANGED ator=Joao process:test.b[id=test.bpmn]

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    AFTER RULEFLOW VARIABLE CHANGED ator=Joao process:test.b[id=test.bpmn]

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    BEFORE RULEFLOW STARTED process:test.b[id=test.bpmn]

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    BEFORE PROCESS NODE TRIGGERED node:Start[id=1] process:test.b[id=test.bpmn]

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    BEFORE PROCESS NODE EXITED node:Start[id=1] process:test.b[id=test.bpmn]

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    BEFORE PROCESS NODE TRIGGERED node:Hello World[id=2] process:test.b[id=test.bpmn]

    Hello world!

    Date: Wed Jul 13 11:31:50 BRT 2011

    BEFORE RULEFLOW VARIABLE CHANGED action=Hello process:test.b[id=test.bpmn]

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    AFTER RULEFLOW VARIABLE CHANGED action=Hello process:test.b[id=test.bpmn]

    Context: org.drools.spi.ProcessContext@d68b39

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    BEFORE PROCESS NODE EXITED node:Hello World[id=2] process:test.b[id=test.bpmn]

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    BEFORE PROCESS NODE TRIGGERED node:User Task[id=9] process:test.b[id=test.bpmn]

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    AFTER PROCESS NODE TRIGGERED node:User Task[id=9] process:test.b[id=test.bpmn]

    AFTER PROCESS NODE TRIGGERED node:Hello World[id=2] process:test.b[id=test.bpmn]

    AFTER PROCESS NODE TRIGGERED node:Hello World[id=2] process:test.b[id=test.bpmn]

    AFTER PROCESS NODE TRIGGERED node:Start[id=1] process:test.b[id=test.bpmn]

    AFTER PROCESS NODE TRIGGERED node:Start[id=1] process:test.b[id=test.bpmn]

    AFTER RULEFLOW STARTED process:test.b[id=test.bpmn]

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    Hibernate:

        select

            user_.id

        from

            OrganizationalEntity user_

        where

            user_.id=?

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    Hibernate:

        select

            hibernate_sequence.nextval

        from

            dual

    Hibernate:

        insert

        into

            Task

            (allowedToDelegate, taskInitiator_id, priority, activationTime, actualOwner_id, createdBy_id, createdOn, documentAccessType, documentContentId, documentType, expirationTime, faultAccessType, faultContentId, faultName, faultType, outputAccessType, outputContentId, outputType, parentId, previousStatus, processInstanceId, skipable, status, workItemId, id)

        values

            (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

    Hibernate:

        insert

        into

            I18NText

            (language, text, id)

        values

            (?, ?, ?)

    Hibernate:

        insert

        into

            I18NText

            (language, text, id)

        values

            (?, ?, ?)

    Hibernate:

        insert

        into

            I18NText

            (language, text, id)

        values

            (?, ?, ?)

    Hibernate:

        insert

        into

            Content

            (content, id)

        values

            (?, ?)

    Hibernate:

        update

            Task

        set

            allowedToDelegate=?,

            taskInitiator_id=?,

            priority=?,

            activationTime=?,

            actualOwner_id=?,

            createdBy_id=?,

            createdOn=?,

            documentAccessType=?,

            documentContentId=?,

            documentType=?,

            expirationTime=?,

            faultAccessType=?,

            faultContentId=?,

            faultName=?,

            faultType=?,

            outputAccessType=?,

            outputContentId=?,

            outputType=?,

            parentId=?,

            previousStatus=?,

            processInstanceId=?,

            skipable=?,

            status=?,

            workItemId=?

        where

            id=?

    Hibernate:

        update

            I18NText

        set

            Task_Descriptions_Id=?

        where

            id=?

    Hibernate:

        update

            I18NText

        set

            Task_Names_Id=?

        where

            id=?

    Hibernate:

        insert

        into

            PeopleAssignments_BAs

            (task_id, entity_id)

        values

            (?, ?)

    Hibernate:

        insert

        into

            PeopleAssignments_PotOwners

            (task_id, entity_id)

        values

            (?, ?)

    Hibernate:

        update

            I18NText

        set

            Task_Subjects_Id=?

        where

            id=?

    Hibernate:

        select

            task0_.id as col_0_0_,

            task0_.processInstanceId as col_1_0_,

            i18ntext4_.text as col_2_0_,

            subjects3_.text as col_3_0_,

            i18ntext5_.text as col_4_0_,

            task0_.status as col_5_0_,

            task0_.priority as col_6_0_,

            task0_.skipable as col_7_0_,

            task0_.actualOwner_id as col_8_0_,

            task0_.createdBy_id as col_9_0_,

            task0_.createdOn as col_10_0_,

            task0_.activationTime as col_11_0_,

            task0_.expirationTime as col_12_0_

        from

            Task task0_

        left outer join

            OrganizationalEntity user1_

                on task0_.createdBy_id=user1_.id

        left outer join

            OrganizationalEntity user2_

                on task0_.actualOwner_id=user2_.id

        left outer join

            I18NText subjects3_

                on task0_.id=subjects3_.Task_Subjects_Id,

            I18NText i18ntext4_,

            I18NText i18ntext5_,

            OrganizationalEntity organizati6_

        where

            organizati6_.id=?

            and (

                organizati6_.id in (

                    select

                        potentialo9_.entity_id

                    from

                        PeopleAssignments_PotOwners potentialo9_

                    where

                        task0_.id=potentialo9_.task_id

                )

            )

            and i18ntext4_.language=?

            and (

                i18ntext4_.id in (

                    select

                        names10_.id

                    from

                        I18NText names10_

                    where

                        task0_.id=names10_.Task_Names_Id

                )

            )

            and (

                subjects3_.language=?

                or (

                    select

                        count(subjects11_.Task_Subjects_Id)

                    from

                        I18NText subjects11_

                    where

                        task0_.id=subjects11_.Task_Subjects_Id

                )=0

            )

            and (

                i18ntext5_.language=?

                and (

                    i18ntext5_.id in (

                        select

                            descriptio12_.id

                        from

                            I18NText descriptio12_

                        where

                            task0_.id=descriptio12_.Task_Descriptions_Id

                    )

                )

                or (

                    select

                        count(descriptio13_.Task_Descriptions_Id)

                    from

                        I18NText descriptio13_

                    where

                        task0_.id=descriptio13_.Task_Descriptions_Id

                )=0

            )

            and (

                task0_.status in (

                    'Created' , 'Ready' , 'Reserved' , 'InProgress' , 'Suspended'

                )

            )

            and (

                task0_.expirationTime is null

            )

    Hibernate:

        select

            user0_.id as id10_0_

        from

            OrganizationalEntity user0_

        where

            user0_.id=?

            and user0_.DTYPE='User'

    Hibernate:

        select

            task0_.id as id15_3_,

            task0_.allowedToDelegate as allowedT2_15_3_,

            task0_.taskInitiator_id as taskIni23_15_3_,

            task0_.priority as priority15_3_,

            task0_.activationTime as activati4_15_3_,

            task0_.actualOwner_id as actualO24_15_3_,

            task0_.createdBy_id as createdBy25_15_3_,

            task0_.createdOn as createdOn15_3_,

            task0_.documentAccessType as document6_15_3_,

            task0_.documentContentId as document7_15_3_,

            task0_.documentType as document8_15_3_,

            task0_.expirationTime as expirati9_15_3_,

            task0_.faultAccessType as faultAc10_15_3_,

            task0_.faultContentId as faultCo11_15_3_,

            task0_.faultName as faultName15_3_,

            task0_.faultType as faultType15_3_,

            task0_.outputAccessType as outputA14_15_3_,

            task0_.outputContentId as outputC15_15_3_,

            task0_.outputType as outputType15_3_,

            task0_.parentId as parentId15_3_,

            task0_.previousStatus as previou18_15_3_,

            task0_.processInstanceId as process19_15_3_,

            task0_.skipable as skipable15_3_,

            task0_.status as status15_3_,

            task0_.workItemId as workItemId15_3_,

            user1_.id as id10_0_,

            user2_.id as id10_1_,

            user3_.id as id10_2_

        from

            Task task0_

        left outer join

            OrganizationalEntity user1_

                on task0_.taskInitiator_id=user1_.id

        left outer join

            OrganizationalEntity user2_

                on task0_.actualOwner_id=user2_.id

        left outer join

            OrganizationalEntity user3_

                on task0_.createdBy_id=user3_.id

        where

            task0_.id=?

    Hibernate:

        update

            Task

        set

            allowedToDelegate=?,

            taskInitiator_id=?,

            priority=?,

            activationTime=?,

            actualOwner_id=?,

            createdBy_id=?,

            createdOn=?,

            documentAccessType=?,

            documentContentId=?,

            documentType=?,

            expirationTime=?,

            faultAccessType=?,

            faultContentId=?,

            faultName=?,

            faultType=?,

            outputAccessType=?,

            outputContentId=?,

            outputType=?,

            parentId=?,

            previousStatus=?,

            processInstanceId=?,

            skipable=?,

            status=?,

            workItemId=?

        where

            id=?

    Hibernate:

        select

            task0_.id as id15_3_,

            task0_.allowedToDelegate as allowedT2_15_3_,

            task0_.taskInitiator_id as taskIni23_15_3_,

            task0_.priority as priority15_3_,

            task0_.activationTime as activati4_15_3_,

            task0_.actualOwner_id as actualO24_15_3_,

            task0_.createdBy_id as createdBy25_15_3_,

            task0_.createdOn as createdOn15_3_,

            task0_.documentAccessType as document6_15_3_,

            task0_.documentContentId as document7_15_3_,

            task0_.documentType as document8_15_3_,

            task0_.expirationTime as expirati9_15_3_,

            task0_.faultAccessType as faultAc10_15_3_,

            task0_.faultContentId as faultCo11_15_3_,

            task0_.faultName as faultName15_3_,

            task0_.faultType as faultType15_3_,

            task0_.outputAccessType as outputA14_15_3_,

            task0_.outputContentId as outputC15_15_3_,

            task0_.outputType as outputType15_3_,

            task0_.parentId as parentId15_3_,

            task0_.previousStatus as previou18_15_3_,

            task0_.processInstanceId as process19_15_3_,

            task0_.skipable as skipable15_3_,

            task0_.status as status15_3_,

            task0_.workItemId as workItemId15_3_,

            user1_.id as id10_0_,

            user2_.id as id10_1_,

            user3_.id as id10_2_

        from

            Task task0_

        left outer join

            OrganizationalEntity user1_

                on task0_.taskInitiator_id=user1_.id

        left outer join

            OrganizationalEntity user2_

                on task0_.actualOwner_id=user2_.id

        left outer join

            OrganizationalEntity user3_

                on task0_.createdBy_id=user3_.id

        where

            task0_.id=?

    Hibernate:

        select

            subtaskstr0_.Task_Id as Task4_1_,

            subtaskstr0_.id as id1_,

            subtaskstr0_.id as id16_0_,

            subtaskstr0_.name as name16_0_,

            subtaskstr0_.DTYPE as DTYPE16_0_

        from

            SubTasksStrategy subtaskstr0_

        where

            subtaskstr0_.Task_Id=?

    Hibernate:

        update

            Task

        set

            allowedToDelegate=?,

            taskInitiator_id=?,

            priority=?,

            activationTime=?,

            actualOwner_id=?,

            createdBy_id=?,

            createdOn=?,

            documentAccessType=?,

            documentContentId=?,

            documentType=?,

            expirationTime=?,

            faultAccessType=?,

            faultContentId=?,

            faultName=?,

            faultType=?,

            outputAccessType=?,

            outputContentId=?,

            outputType=?,

            parentId=?,

            previousStatus=?,

            processInstanceId=?,

            skipable=?,

            status=?,

            workItemId=?

        where

            id=?

    Hibernate:

        select

            task0_.id as id15_3_,

            task0_.allowedToDelegate as allowedT2_15_3_,

            task0_.taskInitiator_id as taskIni23_15_3_,

            task0_.priority as priority15_3_,

            task0_.activationTime as activati4_15_3_,

            task0_.actualOwner_id as actualO24_15_3_,

            task0_.createdBy_id as createdBy25_15_3_,

            task0_.createdOn as createdOn15_3_,

            task0_.documentAccessType as document6_15_3_,

            task0_.documentContentId as document7_15_3_,

            task0_.documentType as document8_15_3_,

            task0_.expirationTime as expirati9_15_3_,

            task0_.faultAccessType as faultAc10_15_3_,

            task0_.faultContentId as faultCo11_15_3_,

            task0_.faultName as faultName15_3_,

            task0_.faultType as faultType15_3_,

            task0_.outputAccessType as outputA14_15_3_,

            task0_.outputContentId as outputC15_15_3_,

            task0_.outputType as outputType15_3_,

            task0_.parentId as parentId15_3_,

            task0_.previousStatus as previou18_15_3_,

            task0_.processInstanceId as process19_15_3_,

            task0_.skipable as skipable15_3_,

            task0_.status as status15_3_,

            task0_.workItemId as workItemId15_3_,

            user1_.id as id10_0_,

            user2_.id as id10_1_,

            user3_.id as id10_2_

        from

            Task task0_

        left outer join

            OrganizationalEntity user1_

                on task0_.taskInitiator_id=user1_.id

        left outer join

            OrganizationalEntity user2_

                on task0_.actualOwner_id=user2_.id

        left outer join

            OrganizationalEntity user3_

                on task0_.createdBy_id=user3_.id

        where

            task0_.id=?

    Hibernate:

        select

            workitemin0_.workItemId as workItemId3_0_,

            workitemin0_.creationDate as creation2_3_0_,

            workitemin0_.name as name3_0_,

            workitemin0_.processInstanceId as processI4_3_0_,

            workitemin0_.state as state3_0_,

            workitemin0_.OPTLOCK as OPTLOCK3_0_,

            workitemin0_.workItemByteArray as workItem7_3_0_

        from

            WorkItemInfo workitemin0_

        where

            workitemin0_.workItemId=?

    Hibernate:

        select

            names0_.Task_Names_Id as Task5_1_,

            names0_.id as id1_,

            names0_.id as id11_0_,

            names0_.language as language11_0_,

            names0_.text as text11_0_

        from

            I18NText names0_

        where

            names0_.Task_Names_Id=?

  • 6. Re: Human task API, how to move forward in the workflow ?
    James Williams Newbie

    I've had similar problems where I thought tasks were not being created, but they were. Have you checked in the database to see if the next task has been created?

     

    Is the next task assigned to a user or a group?

  • 7. Re: Human task API, how to move forward in the workflow ?
    John Augusto Charnet Newbie

    Hi James.

    My next task is not a Human Task, it is a <task> ...</task>, that I have attached a Task Handler to it. If I change this task to a script task, and make my script task write a simple System.out, nothing get's printed to the console.

    So I still presume that my next task is not getting called.

     

     

    thanks

  • 8. Re: Human task API, how to move forward in the workflow ?
    James Williams Newbie

    Hi John,

     

    Have you tried making it a human task and see if it get to that point? At least then you would know that your code moving the process forward is work so there must be something wrong with the script task or configuration.

     

    Just a thought.

  • 9. Re: Human task API, how to move forward in the workflow ?
    John Augusto Charnet Newbie

    Just tried your idea James, but my next task (modified to be a human task), did not get called.

    It looks like I'm missing some configuration or something.

  • 10. Re: Human task API, how to move forward in the workflow ?
    John Augusto Charnet Newbie

    I've made some massive debug, and what I found out was that after the task client api complete method is executed, I get to a point where the method completeWorkItem is executing. This method tries to join an existing transaction, and I'm getting the following error:

     

    javax.persistence.TransactionRequiredException: No local transaction to join

              at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.doJoinTransaction(ExtendedEntityManagerCreator.java:407)

              at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350)

              at $Proxy56.joinTransaction(Unknown Source)

              at org.drools.persistence.jpa.JpaPersistenceContextManager.beginCommandScopedEntityManager(JpaPersistenceContextManager.java:66)

              at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:287)

              at org.drools.command.impl.CommandBasedStatefulKnowledgeSession$1.completeWorkItem(CommandBasedStatefulKnowledgeSession.java:149)

              at org.jbpm.process.workitem.wsht.CommandBasedWSHumanTaskHandler$GetCompletedTaskResponseHandler.execute(CommandBasedWSHumanTaskHandler.java:259)

     

     

    Is there any configuration problems with my environment ?

    Spring is in control of my EntityManagerFactory and in my test unit I'm using bitronix.tm.TransactionManagerServices.getTransactionManager().

     

    Any ideas ?

     

    Thanks

  • 11. Re: Human task API, how to move forward in the workflow ?
    RuiHua Tang Newbie

    I've had similar problems .

    I am looking forward to someone can solve this problem.

  • 12. Re: Human task API, how to move forward in the workflow ?
    Demian Calcaprina Master

    Hi John,

     

    could you please share your configuration, and if possible your test case?

     

    Thanks,

     

    Demian

  • 13. Re: Human task API, how to move forward in the workflow ?
    John Augusto Charnet Newbie

    Hi Demian,

    not sure what type of configuration you want me to share.

    If you need any other information, please let me know.

     

    Spring 3.0.1

    Jbpm 5.1.0-Final

    JPA 1.2

    Hibernate 3.3.2.GA

    /**
     * Todos os direitos reservados para Softway.
     *
     * Data de criacao: 27/06/2011 16:12:28
     */
    package br.com.softcomex.components.workflow.service.impl;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    
    import javax.persistence.EntityManagerFactory;
    import javax.transaction.TransactionManager;
    
    import org.drools.KnowledgeBase;
    import org.drools.KnowledgeBaseFactory;
    import org.drools.SystemEventListener;
    import org.drools.SystemEventListenerFactory;
    import org.drools.builder.KnowledgeBuilder;
    import org.drools.builder.KnowledgeBuilderFactory;
    import org.drools.builder.ResourceType;
    import org.drools.io.ResourceFactory;
    import org.drools.logger.KnowledgeRuntimeLogger;
    import org.drools.logger.KnowledgeRuntimeLoggerFactory;
    import org.drools.persistence.jpa.JPAKnowledgeService;
    import org.drools.runtime.Environment;
    import org.drools.runtime.EnvironmentName;
    import org.drools.runtime.KnowledgeSessionConfiguration;
    import org.drools.runtime.StatefulKnowledgeSession;
    import org.drools.runtime.process.ProcessInstance;
    import org.drools.spi.ProcessContext;
    import org.jbpm.process.audit.JPAProcessInstanceDbLog;
    import org.jbpm.process.audit.JPAWorkingMemoryDbLogger;
    import org.jbpm.process.workitem.wsht.CommandBasedWSHumanTaskHandler;
    import org.jbpm.task.Status;
    import org.jbpm.task.query.TaskSummary;
    import org.jbpm.task.service.TaskClient;
    import org.jbpm.task.service.TaskServer;
    import org.jbpm.task.service.TaskService;
    import org.jbpm.task.service.mina.MinaTaskClientConnector;
    import org.jbpm.task.service.mina.MinaTaskClientHandler;
    import org.jbpm.task.service.mina.MinaTaskServer;
    import org.jbpm.task.service.responsehandlers.BlockingTaskOperationResponseHandler;
    import org.jbpm.task.service.responsehandlers.BlockingTaskSummaryResponseHandler;
    
    import br.com.softcomex.components.log.SfwLogger;
    import br.com.softcomex.components.log.SfwLoggerFactory;
    import br.com.softcomex.components.workflow.service.SfwJbpmWorkFlow;
    
    
    /**
     * 

    * Implementação da classe responsável por criar o ambiente do JBPM. *

    * @author João Augusto Charnet * */ public class SfwJbpmWorkFlowImpl implements SfwJbpmWorkFlow {     /**      * Log.      */     private SfwLogger sfwLogger = SfwLoggerFactory.getLogger(getClass());         /**      * Entity Manager Factory injetado.      */     private EntityManagerFactory emf;         /**      * Transação.      */     private TransactionManager transactionManager;         /**      * Sessão da base de conhecimento do JBPM.      */     private StatefulKnowledgeSession kSession;         /**      * Thread do servidor de tarefa humana.      */     private TaskServer humanTaskServerThread;         /**      * Porta do sevidor de tarefa humana.      */     private int humanTaskServerPort = -1;         /**      * Endereço do Servidor de tarefa humana.      */     private String humanTaskServerLocalAddress = "127.0.0.1";         /**      * Lista com os jbpm que precisa ser carregado.      */     private List workFlowResourcesList;         /**      * Responsável por se comunicar com o servidor de tarefas humanas.      */     private TaskClient taskClient;         /**      * Contexto do processo.      */         /**      * Construtor padrão.      */     public SfwJbpmWorkFlowImpl() {     }     @Override     public void prepareSession() {         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();                 for (String resource : this.workFlowResourcesList) {             kbuilder.add(ResourceFactory.newClassPathResource(resource), ResourceType.BPMN2);         }                 KnowledgeBase kbase = kbuilder.newKnowledgeBase();                 Environment env = KnowledgeBaseFactory.newEnvironment();         env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, this.emf);         env.set(EnvironmentName.TRANSACTION_MANAGER,             this.transactionManager);                 // Human Task         SystemEventListener systemEventListener = SystemEventListenerFactory.getSystemEventListener();                 TaskService taskService = new TaskService(this.emf, systemEventListener);                this.startHumanTaskServer(taskService);                 Properties properties = new Properties();         properties.put("drools.processInstanceManagerFactory", "org.jbpm.persistence.processinstance.JPAProcessInstanceManagerFactory");         properties.put("drools.processSignalManagerFactory", "org.jbpm.persistence.processinstance.JPASignalManagerFactory");         KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(properties);                 StatefulKnowledgeSession ksession =             JPAKnowledgeService.newStatefulKnowledgeSession(kbase, config, env);               //this will log in audit tables         JPAWorkingMemoryDbLogger jpaWorkingMemoryLog = new JPAWorkingMemoryDbLogger(ksession);         JPAProcessInstanceDbLog processLog = new JPAProcessInstanceDbLog(ksession.getEnvironment());         KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);                         CommandBasedWSHumanTaskHandler humanTask = new CommandBasedWSHumanTaskHandler(ksession);         humanTask.setConnection(this.humanTaskServerLocalAddress, this.humanTaskServerPort);         ksession.getWorkItemManager().registerWorkItemHandler("Human Task", humanTask);               this.setkSession(ksession);     }     /**      * Inicia o servidor para a tarefa humana.      *      * @param taskService Serviço da tarefa.      */     private void startHumanTaskServer(TaskService taskService) {         if (this.humanTaskServerPort <= 0) {             this.humanTaskServerPort = SfwJbpmWorkFlow.DEFAULT_HUMAN_TASK_SERVER_PORT;         }         this.sfwLogger.debug("Iniciando Human Task Server! ip [ " + this.humanTaskServerLocalAddress + "] port [" + this.humanTaskServerPort +"]");         this.humanTaskServerThread = new MinaTaskServer(taskService, this.humanTaskServerPort);         Thread thread = new Thread(this.humanTaskServerThread);         thread.start();     }     @Override     public void stopHumanTaskServer() throws Exception {        if (this.humanTaskServerThread != null &&            this.humanTaskServerThread.isRunning()) {                       this.taskClient.disconnect();            this.humanTaskServerThread.stop();                       this.sfwLogger.debug("Encerrando Human Task Server!");        }     }     @Override     public void setHumanTaskServerPort(int humanTaskServerPort) {         this.humanTaskServerPort = humanTaskServerPort;     }     @Override     public int getHumanTaskServerPort() {         return humanTaskServerPort;     }         @Override     public EntityManagerFactory getEmf() {             return emf;     }         @Override     public void setEmf(EntityManagerFactory emf) {             this.emf = emf;     }     @Override     public void setkSession(StatefulKnowledgeSession kSession) {         this.kSession = kSession;     }     @Override     public StatefulKnowledgeSession getkSession() {         return kSession;     }     @Override     public void setTransactionManager(TransactionManager transactionManager) {         this.transactionManager = transactionManager;     }     @Override     public TransactionManager getTransactionManager() {         return transactionManager;     }     @Override     public ProcessInstance startProcess(String processId, Map params) {         return this.kSession.startProcess(processId, params);             }     @Override     public void setWorkFlowResourcesList(List workFlowResourcesList) {         this.workFlowResourcesList = workFlowResourcesList;     }     @Override     public List getWorkFlowResourcesList() {         return workFlowResourcesList;     }     @Override     public void addWorkFlowResource(String workFlowResource) {         if (this.workFlowResourcesList == null) {             this.workFlowResourcesList = new ArrayList();         }                 this.workFlowResourcesList.add(workFlowResource);             }     @Override     public String getHumanTaskServerLocalAddress() {             return humanTaskServerLocalAddress;     }         @Override     public void setHumanTaskServerLocalAddress(String humanTaskServerLocalAddress) {             this.humanTaskServerLocalAddress = humanTaskServerLocalAddress;     }     @Override     public ProcessContext getProcessContext() {         ProcessContext procContext = new ProcessContext(this.kSession);         return procContext;     }         /**      * Cria um TaskClient conectando no servido de tarefa humana.      * @return TaskClient TaskClient.      */     private TaskClient createTaskClient() {                 if (this.taskClient == null) {             this.taskClient = new TaskClient(new MinaTaskClientConnector("SfwTaskClient",                                                     new MinaTaskClientHandler(SystemEventListenerFactory.getSystemEventListener())));                         boolean connected = this.taskClient.connect(this.humanTaskServerLocalAddress, this.humanTaskServerPort);             if (!connected) {                 this.sfwLogger.error("Não foi possível conectar no servidor de tarefa humana. Server [" + this.humanTaskServerLocalAddress + "] - Port [" + this.humanTaskServerPort + "]");             }         }         return this.taskClient;     }         @Override     public TaskClient getTaskClient() {             return taskClient;     }         @Override     public void setTaskClient(TaskClient taskClient) {             this.taskClient = taskClient;     }     @Override     public List getTasksByUser(String user) {         this.createTaskClient();                 BlockingTaskSummaryResponseHandler taskSummaryResponseHandler =             new BlockingTaskSummaryResponseHandler();         this.taskClient.getTasksAssignedAsPotentialOwner(user, "en-UK", taskSummaryResponseHandler);         final int oneSec = 1000;         taskSummaryResponseHandler.waitTillDone(oneSec);                 List tasks = taskSummaryResponseHandler.getResults();                 return tasks;     }         /**      * Cria uma TaskClient, caso necessário e retorna um taskResponseHandler      * para se comunicar com o servidor de tarefa humana.      *      * @return BlockingTaskOperationResponseHandler      */     private BlockingTaskOperationResponseHandler createTaskClientAndReturnTaskOperationResponseHandler() {         this.createTaskClient();                 BlockingTaskOperationResponseHandler taskResponseHandler =             new BlockingTaskOperationResponseHandler();         return taskResponseHandler;     }     @Override     public void completeTask(List tasks, String user) {         for (TaskSummary task : tasks) {             this.sfwLogger.debug("Completando tarefa [" + task.getName() + "] do usuário [" + user + "]");             this.completeTask(task, user);         }             }     @Override     public void completeTask(TaskSummary task, String user) {                 BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         this.taskClient.complete(task.getId(), user, null, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);     }     @Override     public void failTask(TaskSummary task, String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();                 this.taskClient.fail(task.getId(), user, null, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);     }     @Override     public void suspendTask(TaskSummary task, String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();                 this.taskClient.suspend(task.getId(), user, taskResponseHandler);     }     @Override     public void startTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         if (!task.getStatus().equals(Status.InProgress)) {                     this.taskClient.start(task.getId(), user, taskResponseHandler);             final int oneSec = 1000;             taskResponseHandler.waitTillDone(oneSec);         }                     }     @Override     public void stopTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         this.taskClient.stop(task.getId(), user, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);     }     @Override     public void releaseTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         this.taskClient.release(task.getId(), user, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);     }     @Override     public void resumeTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         this.taskClient.resume(task.getId(), user, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);     }     @Override     public void skipTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         this.taskClient.skip(task.getId(), user, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);             }     @Override     public void claimTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();                 this.taskClient.claim(task.getId(), user, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);             } }

     


    Unit Test case

    /**
     * Todos os direitos reservados para Softway.
     *
     * Data de criacao: 28/06/2011 15:18:56
     */
    package br.com.softcomex.components.workflow.service.impl;
    
    import java.net.ConnectException;
    import java.net.Socket;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.ResourceBundle;
    
    import javax.inject.Inject;
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Query;
    
    import junit.framework.Assert;
    
    import org.drools.runtime.process.ProcessInstance;
    import org.drools.runtime.process.WorkItem;
    import org.drools.runtime.process.WorkItemHandler;
    import org.drools.runtime.process.WorkItemManager;
    import org.drools.spi.ProcessContext;
    import org.jbpm.task.query.TaskSummary;
    import org.junit.BeforeClass;
    import org.junit.Test;
    
    import bitronix.tm.TransactionManagerServices;
    import bitronix.tm.resource.jdbc.PoolingDataSource;
    import br.com.softcomex.components.workflow.service.SfwJbpmWorkFlow;
    import br.com.softcomex.test.serviceeao.SfwBaseServiceTestCase;
    
    
    /**
     * Classe de teste do serviço SfwJbmWorkFlowImpl.
     * 
     * @author João Augusto Charnet *
     */
    public class SfwJbpmWorkFlowImplTest extends SfwBaseServiceTestCase {
    
        /**
         * Serviço.
         */
        @Inject
        private SfwJbpmWorkFlow sfwWorkFlow;
    
        
        /**
         * Prepara o datasource.
         */
        @BeforeClass
        public static void prepareDatasource() {
            PoolingDataSource ds = new PoolingDataSource();
            ds.setUniqueName("localDataSource");
            ds.setClassName("oracle.jdbc.xa.client.OracleXADataSource");
            ds.setMaxPoolSize(3);
            ds.setAllowLocalTransactions(true);
            
            ResourceBundle rb = ResourceBundle.getBundle("jdbc");
            
            ds.getDriverProperties().put("user", rb.getString("jdbc.username"));
            ds.getDriverProperties().put("password", rb.getString("jdbc.password"));
            ds.getDriverProperties().put("URL", rb.getString("jdbc.url"));
            ds.init();
        }
        
        /**
         * Teste.
         * @throws Exception Exceção.
         */
        @Test
        public void testJbpmWorkFlow() throws Exception {
            
            this.sfwWorkFlow.setTransactionManager(TransactionManagerServices.getTransactionManager());
            this.sfwWorkFlow.getTransactionManager().begin();
            this.sfwWorkFlow.addWorkFlowResource("test.bpmn");
            this.sfwWorkFlow.addWorkFlowResource("testHumanTask.bpmn");
            this.sfwWorkFlow.prepareSession();
            
            MyAutomaticHumanSimulatorWorkItemHandler workHandler = new MyAutomaticHumanSimulatorWorkItemHandler();
            TestWorkItemHandler workItemHandler = new TestWorkItemHandler();
    
            
            Socket socket = new Socket("127.0.0.1", this.sfwWorkFlow.getHumanTaskServerPort());
            Assert.assertNotNull(socket);
            Map params = new HashMap();
            params.put("responsible", "John");
            ProcessInstance processInstance = this.sfwWorkFlow.startProcess("testHumanTask", params);
            
            Thread.currentThread().sleep(3000);
            
            List tasks = this.sfwWorkFlow.getTasksByUser("John");
            
            this.sfwWorkFlow.startTask(tasks.get(0), "John");
            
            this.sfwWorkFlow.completeTask(tasks.get(0), "John");
            
            Thread.currentThread().sleep(5000);
            
            Assert.assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
            
            this.sfwWorkFlow.stopHumanTaskServer();
            
            try {
                socket = new Socket("127.0.0.1", this.sfwWorkFlow.getHumanTaskServerPort());
                Assert.fail("Esperando exceção, por não ter ninguém escutando na porta do sevidor " + this.sfwWorkFlow.getHumanTaskServerPort());
            } catch (ConnectException excep) {
                Assert.assertTrue(true);
            } finally {
                this.sfwWorkFlow.getTransactionManager().rollback();
            }
        }
        
        
    }
    
    

     

    testHumanTask.JPG

    jbpm xml

             <?xml version="1.0" encoding="UTF-8"?>  
    <definitions id="Definition"
                 targetNamespace="http://www.jboss.org/drools"
                 typeLanguage="http://www.java.com/javaTypes"
                 expressionLanguage="http://www.mvel.org/2.0"
                 xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
                 xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
                 xs:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
                 xmlns:g="http://www.jboss.org/drools/flow/gpd"
                 xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
                 xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
                 xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
                 xmlns:tns="http://www.jboss.org/drools"> 
    
      <itemDefinition id="_responsibleItem" structureRef="String" /> 
    
      <process processType="Private" isExecutable="true" id="testHumanTask" name="testHumanTask" > 
    
        <!-- process variables --> 
        <property id="responsible" itemSubjectRef="_responsibleItem"/> 
    
        <!-- nodes --> 
        <startEvent id="_1" name="Start" /> 
        <userTask id="_2" name="User Task" > 
          <ioSpecification> 
            <dataInput id="_2_TaskNameInput" name="TaskName" /> 
            <inputSet> 
              <dataInputRefs> _2_TaskNameInput</dataInputRefs> 
            </inputSet> 
            <outputSet> 
            </outputSet> 
          </ioSpecification> 
          <dataInputAssociation> 
            <targetRef> _2_TaskNameInput</targetRef> 
            <assignment> 
              <from xs:type="tFormalExpression"> Test Human Task</from> 
              <to xs:type="tFormalExpression"> _2_TaskNameInput</to> 
            </assignment> 
          </dataInputAssociation> 
          <potentialOwner> 
            <resourceAssignmentExpression> 
              <formalExpression> #{responsible}</formalExpression> 
            </resourceAssignmentExpression> 
          </potentialOwner> 
        </userTask> 
        <scriptTask id="_3" name="Script" scriptFormat="http://www.java.com/java" > 
          <script> System.out.println("Script task :" + new java.util.Date());</script> 
        </scriptTask> 
        <endEvent id="_4" name="End" > 
            <terminateEventDefinition/> 
        </endEvent> 
    
        <!-- connections --> 
        <sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" /> 
        <sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3" /> 
        <sequenceFlow id="_3-_4" sourceRef="_3" targetRef="_4" /> 
    
      </process> 
    
      <bpmndi:BPMNDiagram> 
        <bpmndi:BPMNPlane bpmnElement="testHumanTask" > 
          <bpmndi:BPMNShape bpmnElement="_1" > 
            <dc:Bounds x="51" y="34" width="48" height="48" /> 
          </bpmndi:BPMNShape> 
          <bpmndi:BPMNShape bpmnElement="_2" > 
            <dc:Bounds x="165" y="35" width="100" height="48" /> 
          </bpmndi:BPMNShape> 
          <bpmndi:BPMNShape bpmnElement="_3" > 
            <dc:Bounds x="176" y="158" width="80" height="48" /> 
          </bpmndi:BPMNShape> 
          <bpmndi:BPMNShape bpmnElement="_4" > 
            <dc:Bounds x="191" y="301" width="48" height="48" /> 
          </bpmndi:BPMNShape> 
          <bpmndi:BPMNEdge bpmnElement="_1-_2" > 
            <di:waypoint x="75" y="58" /> 
            <di:waypoint x="215" y="59" /> 
          </bpmndi:BPMNEdge> 
          <bpmndi:BPMNEdge bpmnElement="_2-_3" > 
            <di:waypoint x="215" y="59" /> 
            <di:waypoint x="216" y="182" /> 
          </bpmndi:BPMNEdge> 
          <bpmndi:BPMNEdge bpmnElement="_3-_4" > 
            <di:waypoint x="216" y="182" /> 
            <di:waypoint x="215" y="325" /> 
          </bpmndi:BPMNEdge> 
        </bpmndi:BPMNPlane> 
      </bpmndi:BPMNDiagram> 
    
    </definitions>                                                                                                                                  
    
  • 14. Re: Human task API, how to move forward in the workflow ?
    John Augusto Charnet Newbie

    I got it to work. Not the ideal way though.

     

    I had to create my EntityManagerFactory in my JUnit test with Persistence.createEntityManagerFactory.

    I cannot use my spring configuration to create the entity manager, and to handle the transaction.

     

    Now this brings me to a new question. When I run my web application, will I get this same error ?

     

     

    Thanks for all the help !

     

     

    John

1 2 Previous Next