3 Replies Latest reply on Jan 15, 2014 6:32 AM by mdegan

    How to restore human task workflow when server restarts

    wailwinmoe

      I have a human task workflow

      Start -> human task 1 -> human task 2 -> human task 3 -> end.

       

      My workflow will completely finish when human task 3 completed the task.

      In normal case, I can create and start the workflow successfully.

       

      But when server restarts, workflow can not successfully complete.

       

      The complete process must be as follows.

      1.Start the process.

      2.Complete human task 1 and reserve human task 2.

      3. Restart jboss server.

      4. Complete human task 2 and reserve human task 3.

      5. Complete human task 3.

      6.End the process.

       

      The incomplete process that I faced is as follows.

      1.Start the process.

      2.Complete human task 1 and reserve human task 2.

      3. Restart jboss server.

      4. Complete human task 2 and end the process.

       

      Jbpm cannot create and reserve the human task 3 when server restarts. It can only complete the current reserved task.

       

      I would like to know how to complete human task workflow when jboss server restarts.

       

      Best regards

      Wai Lwin Moe.

        • 1. Re: How to restore human task workflow when server restarts
          mdegan

          Hi,

           

          A few things that you need to ensure if you want process instances to be restored:

          1) Persistence should be enabled for jbpm run time and the tasks

          2) On server restart, you need to re-load the last saved knowledge session for all the information availability on running process instances. If new session is created each time, the available data for running instances will not be available.

           

          Regards,

          Manny

          • 2. Re: How to restore human task workflow when server restarts
            wailwinmoe

            I enabled and reload the last saved knowledge session on server restarts. But i Can't complete the workflow.

             

            Here is the spring-beans.xml configuration file.

            <?xml version="1.0" encoding="UTF-8"?>

            <beans xmlns="http://www.springframework.org/schema/beans"

              xmlns:context="http://www.springframework.org/schema/context"

              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"

              xmlns:faces="http://www.springframework.org/schema/faces"

              xmlns:int-security="http://www.springframework.org/schema/integration/security"

              xmlns:jbpm="http://drools.org/schema/drools-spring"

              xmlns:tx="http://www.springframework.org/schema/tx" xmlns:sec="http://www.springframework.org/schema/security"

              xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee"

              xsi:schemaLocation="http://www.springframework.org/schema/integration/security http://www.springframework.org/schema/integration/security/spring-integration-security-2.0.xsd

              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

              http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd

              http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd

              http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

              http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces-2.0.xsd

              http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd

              http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd

              http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd

              http://drools.org/schema/drools-spring http://drools.org/schema/drools-spring-1.7.0.xsd">

             

             

              <context:annotation-config />

              <context:component-scan base-package="org.jbpm.task" />

              <tx:annotation-driven transaction-manager="transactionManager" />

             

             

              <jee:jndi-lookup id="dataSource" jndi-name="java:jboss/datasources/workflowDS"

              resource-ref="false" />

             

             

              <bean

              class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

             

             

              <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">

              <property name="entityManagerFactory" ref="entityManagerFactory" />

              <property name="dataSource" ref="dataSource" />

              </bean>

             

             

              <util:properties id="sqlErrorCodeproperties"

              location="classpath:SQL_ERROR_CODE.properties" />

              <bean id="entityManagerFactory"

              class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

              <property name="persistenceUnitName" value="JPA" />

              <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />

              <property name="jpaDialect">

              <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> <!-- EclipseLinkJpaDialect -->

              </property>

              <property name="dataSource" ref="dataSource" />

              </bean>

             

             

              <bean id="jpaVendorAdapter"

              class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">

              <!-- <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> -->

              <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />

              <!-- <property name="databasePlatform" value="org.eclipse.persistence.platform.database.MySQLPlatform"/> -->

              <!-- property name="databasePlatform" value="org.eclipse.persistence.platform.database.OraclePlatform"

              / -->

              <property name="generateDdl" value="false" />

              <property name="showSql" value="false" />

              </bean>

             

             

              <!-- persistence & transactions-->

             

              <jbpm:kbase id="kbase"> 

                <jbpm:resources> 

                    <jbpm:resource source="classpath:workflow.bpmn" type="BPMN2"></jbpm:resource>

                    <jbpm:resource source="classpath:workflow_new.bpmn" type="BPMN2"></jbpm:resource>

                    </jbpm:resources> 

                </jbpm:kbase> 

               

              <jbpm:ksession id="ksession" type="stateful" kbase="kbase"> 

                <jbpm:configuration>

                    <jbpm:jpa-persistence> 

                        <jbpm:transaction-manager ref="transactionManager" /> 

                            <jbpm:entity-manager-factory ref="entityManagerFactory" /> 

              </jbpm:jpa-persistence> 

              </jbpm:configuration> 

              </jbpm:ksession>

             

              <bean id="systemEventListener" class="org.drools.SystemEventListenerFactory" factory-method="getSystemEventListener" /> 

                 

                <bean id="taskService" class="org.jbpm.task.service.TaskService" > 

                <constructor-arg name="emf" ref="entityManagerFactory" />

                    <constructor-arg name="systemEventListener" ref="systemEventListener" />

              </bean> 

             

              <bean id="taskSession" class="org.jbpm.task.service.TaskServiceSession"

                    factory-bean="taskService" factory-method="createSession"

              scope="singleton" >

                </bean>

               

                <bean id="honetQTaskServer" class="org.jbpm.task.service.hornetq.HornetQTaskServer">

                    <constructor-arg ref="taskService" />

                    <constructor-arg>

                    <value>5153</value>

                    </constructor-arg>

                </bean>

             

                <bean id="taskServerThread" class="java.lang.Thread" init-method="start">

                <constructor-arg ref="honetQTaskServer"/>

              </bean>

             

              <bean id="humanTaskHandler" class="org.jbpm.process.workitem.wsht.AsyncHornetQHTWorkItemHandler">

              <constructor-arg ref="ksession"/>

              <constructor-arg>

                    <value>true</value>

                    </constructor-arg>

              </bean>

              

                <bean id="workItemManager" factory-bean="ksession" factory-method="getWorkItemManager"/>

             

              <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">

              <property name="targetObject" ref="workItemManager"/>

                 <property name="targetMethod" value="registerWorkItemHandler"/>

                 <property name="arguments">

                   <list>

                     <value>Human Task</value>

                     <ref bean="humanTaskHandler"/>

                   </list>

                 </property>

              </bean>

             

                <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">

                 <property name="targetObject" ref="humanTaskHandler"/>

                 <property name="targetMethod" value="connect"/>

              </bean> 

                   

                <bean id="taskClientConnector" class="org.jbpm.task.service.hornetq.HornetQTaskClientConnector">

                 <constructor-arg>

                    <value>Task Client</value>

                    </constructor-arg>

                 <constructor-arg>

                   <bean class="org.jbpm.task.service.hornetq.HornetQTaskClientHandler">

                     <constructor-arg>

                       <bean class="org.drools.SystemEventListenerFactory" factory-method="getSystemEventListener"/>

                     </constructor-arg>

                   </bean>

                 </constructor-arg>

              </bean>

             

             

              <bean id="taskClient" class="org.jbpm.task.service.TaskClient">

                <constructor-arg ref="taskClientConnector"/>

              </bean>

             

              <bean id="logger" class="org.jbpm.process.audit.JPAWorkingMemoryDbLogger">

                <constructor-arg ref="ksession"/>

              </bean>

            </beans>

             

            And i reload the knowledge session like that in my java class.

             

            private KnowledgeBase kBase;

              private EntityManagerFactory emf;

              private JpaTransactionManager txM;

             

              @Autowired

              public void setKnowledgeBase(KnowledgeBase kBase) {

              this.kBase = kBase;

              }

             

              @Autowired

              public void setEntityManagerFactory(EntityManagerFactory emf) {

              this.emf = emf;

              }

             

              @Autowired

              public void setJpaTransactionManager(JpaTransactionManager txM) {

              this.txM = txM;

              }

             

            public void startWorkflow() {

             

              //Load the knowledge session.

               Environment env = KnowledgeBaseFactory.newEnvironment();

              env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );

              env.set( EnvironmentName.TRANSACTION_MANAGER, txM );

             

            // Let assume 1 is the last saved knowledge session.

            StatefulKnowledgeSession loadedKSession = JPAKnowledgeService.loadStatefulKnowledgeSession(1,

              kBase,null, env);

              AsyncHornetQHTWorkItemHandler taskHandler = new AsyncHornetQHTWorkItemHandler(loadedKSession, true);

              taskHandler.connect();

              loadedKSession.getWorkItemManager().registerWorkItemHandler("Human Task", taskHandler);

              loadedKSession.signalEvent("Trigger", null);

             

            }

             

            If you have any idea or suggestion, let me know.

             

            Best regards,

            Wai lwin Moe

            • 3. Re: How to restore human task workflow when server restarts
              mdegan

              Please check the DB for the following tables:

              1) SessionInfo - This gives you the details of the session. If you are using a single session for your application, you should see a single session here. However, if there are different sessions for different processInstances, the handling will be much different and you will see loads of sessions here. That would also mean that you need to load the sessions for all active processInstances.

              2) Task - Check the processSessionId column to ensure that the task is linked to the session that you are loading. If the linked session is right, the task should proceed.

               

               

              Also, I do not know much about Spring, however, the Task persistence should also be available for this.

               

               

              Regards,

              Manny