6 Replies Latest reply on Sep 19, 2011 9:56 PM by Tobias Wittur

    How to access a processInstance within a work item

    Tobias Wittur Newbie

      Hello,

       

      I know usually a signal is invoked upon the knowledgeSession, and all processInstances that are registered on this session and listen to the messageType, will be notified. E.g.

      ksession.signalEvent("Message-StartProcessMessage", params);
      

       

      However, how can I signal a specific process instance from within a work Item?

       

      I know how to get to the ProcessInstanceId, but how would I have to go on?

       

      public class CustomerServiceTaskHandler implements WorkItemHandler {

       

          public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {

             System.out.println(workItem.getProcessInstanceId());

       

                try{

      ...

                }catch(Exception ex){

                    myProcessInstance.signal('AbortTheCurrentInstance');

                }

            

          }

       

          public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {

          }

      }

       

       

      Best regards,

       

      Tobias

        • 1. Re: How to access a processInstance within a work item
          Tihomir Surdilovic Master

          Hi, you can pass the session to the handler and register it. For example:

           

          CustomerServiceTaskHandler handler = new CustomerServiceTaskHandler(ksession, ......);

          ksession.getWorkItemManager().registerWorkItemHandler("myServiceTaskHandler", handler);

           

          In the handler then you can invoke methods on the ksession, like in your example the signalEvent() method.

          Hope this helps.

          • 2. Re: How to access a processInstance within a work item
            Tobias Wittur Newbie

            Thanks Tihomir.

             

            Here some example code.

             

            processTest.java

             

            package TestingBPMN;

             

            import java.util.HashMap;

            import java.util.Map;

             

            import org.drools.KnowledgeBase;

            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.runtime.StatefulKnowledgeSession;

            import org.drools.runtime.process.WorkflowProcessInstance;

            import org.jbpm.process.workitem.wsht.WSHumanTaskHandler;

            import org.jbpm.bpmn2.handler.SendTaskHandler;

            import org.jbpm.bpmn2.handler.ServiceTaskHandler;

            /**

            * This is a sample file to launch a process.

            */

            public class ProcessTest {

             

                public static final void main(String[] args) {

                    try {

             

                        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

                        kbuilder.add(ResourceFactory.newClassPathResource("TestingBPMN/TestingBPMN2.bpmn2"), ResourceType.BPMN2);

                        KnowledgeBase kbase = kbuilder.newKnowledgeBase();

             

                        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

             

                        /*

                         * Register work item handlers

                         *

                         */

                        ksession.getWorkItemManager().registerWorkItemHandler(

                                 "Service Task",

                                 //Pass session into work item handler

                                 new CustomerServiceTaskHandler(ksession)

                        );

                        ksession.getWorkItemManager().registerWorkItemHandler(

                                "Send Task",

                                new CustomSendTaskHandler()

                        );

             

                        /*

                         * Create parameters

                         */

                        HashMap<String, String> m = new HashMap<String, String>();

                        m.put("name", "Karsten");

                        m.put("request", "test");

             

                        /*

                         * Message based process start passing values

                         */

             

                        ksession.signalEvent("Message-StartProcessMessage", m);

                        ksession.signalEvent("Message-StartProcessMessage", m);

                        ksession.signalEvent("Message-StartProcessMessage", m);

                        ksession.signalEvent("Message-StartProcessMessage", m);

                        ksession.signalEvent("Message-StartProcessMessage", m);

             

             

                    } catch (Throwable t) {

                        t.printStackTrace();

                    }

                }

            }

             

            CustomerServiceTaskHandler.java

            package TestingBPMN;

             

            import java.lang.reflect.InvocationTargetException;

            import java.lang.reflect.Method;

            import java.util.HashMap;

            import java.util.Map;

             

            import org.drools.runtime.StatefulKnowledgeSession;

            import org.drools.runtime.process.WorkItem;

            import org.drools.runtime.process.WorkItemHandler;

            import org.drools.runtime.process.WorkItemManager;

            import org.drools.runtime.process.ProcessInstance;

            /*

            * https://github.com/droolsjbpm/jbpm/blob/master/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/ServiceTaskHandler.java

            *

            */

            public class CustomerServiceTaskHandler implements WorkItemHandler {

                private StatefulKnowledgeSession ksession = null;

                public CustomerServiceTaskHandler(StatefulKnowledgeSession ksession) {

                    this.ksession = ksession;

                }

             

                public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {

             

                    //Print Process Instance Id

                    System.out.println(workItem.getProcessInstanceId());

             

                    //Get Current process Instance

                    ProcessInstance p = this.ksession.getProcessInstance(workItem.getProcessInstanceId());

             

                    //Abort the current process if it has an id of 3

                    if(workItem.getProcessInstanceId()==3){

                        this.ksession.abortProcessInstance(workItem.getProcessInstanceId());

                    }

             

                    //if the current state is 3, the process has been aborted!

                    if(p.getState()==3){

                        System.out.println("aborted!");

                    }

             

                    System.out.println("");

                }

             

                public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {}

             

            }

            • 3. Re: How to access a processInstance within a work item
              Tobias Wittur Newbie

              Hi,

               

              I think I ve to reopen this discussion.

               

              I tried the given recommendation for a service and a send task, while for my service task everything works out fine, the send task does not.

              Shouldnt it have the same behaviour in any of those function handlers??

               

              This is in my processTest.java, before the process is instantiated:

              StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

               

              /*

              * Register work item handlers

              */

              ksession.getWorkItemManager().registerWorkItemHandler(

                       "Service Task",

                       //Pass session into work item handler

                       new CustomServiceTaskHandler(ksession)

              );

              ksession.getWorkItemManager().registerWorkItemHandler(

                      "Send Task",

                      new CustomSendTaskHandler(ksession)

              );

               

              //This is the handler:

              public class CustomSendTaskHandler implements WorkItemHandler {

               

                  private StatefulKnowledgeSession ksession = null;

               

                  public CustomSendTaskHandler(StatefulKnowledgeSession ksession) {

                      this.ksession = ksession;

                  }

               

                  public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {

               

                      //Print Process Instance Id , prints 0 (which should be correct as I get the same id in my service task)

                      System.out.println(workItem.getProcessInstanceId());

               

                     //Get Current process Instance (p turns out null)

                      ProcessInstance p = this.ksession.getProcessInstance(workItem.getProcessInstanceId());

                      System.out.println(p.getState());

                  }

               

              @Override

              public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {

                  // Do nothing, cannot be aborted

              }

               

              If I execute

              Object o = this.ksession.getProcessInstances();

               

              I get:

               

              [WorkflowProcessInstance1 [processId=myProcessDiagramId,state=1]]

               

              So there is obviously a ProcessInstanceId alive, but the processInstanceId in the session and in the workItem do not match?

               

              This is the serviceTaskHandler:

               

              public class CustomServiceTaskHandler implements WorkItemHandler {

                  private StatefulKnowledgeSession ksession = null;

                  public CustomServiceTaskHandler(StatefulKnowledgeSession ksession) {

                      this.ksession = ksession;

                  }

               

                  @Override

                  public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {

               

                      //Prints 0

                      System.out.println(workItem.getProcessInstanceId());

               

                      //getState prints 1 for active

                      ProcessInstance p = this.ksession.getProcessInstance(workItem.getProcessInstanceId());

                      System.out.println(p.getState());

              • 4. Re: How to access a processInstance within a work item
                Mauricio Salatino Master

                Hi Tobias, do you mention that the "Send Task" don't work, can you please share the BPMN process XML? Are you sure that you have a task with the tns:name="Send Task"?

                Cheers

                • 5. Re: How to access a processInstance within a work item
                  Tobias Wittur Newbie

                  Well, it is actually an intermediate message throw event as well as a message throw end event, my xml is at the bottom.

                   

                  I had a look at the examples and for the intermediate throw event, a send task handler was defined:

                   

                  KnowledgeBase kbase = createKnowledgeBase("BPMN2-IntermediateThrowEventMessage.bpmn2");

                          StatefulKnowledgeSession ksession = createKnowledgeSession(kbase);

                          ksession.getWorkItemManager().registerWorkItemHandler("Send Task", new SendTaskHandler());

                   

                  I then looked at the xml for the send task example as well as the intermediate message throw example, neither has any attribute like tns:name="Send Task" and oryx is also not producing one ?

                   

                  Intermediate message throw event:

                  <intermediateThrowEvent id="_2" name="MessageEvent" >

                    <dataInput id="_2_Input" />

                    <dataInputAssociation>

                      <sourceRef>x</sourceRef>

                      <targetRef>_2_Input</targetRef>

                    </dataInputAssociation>

                    <inputSet>

                      <dataInputRefs>_2_Input</dataInputRefs>

                    </inputSet>

                    <messageEventDefinition messageRef="_2_Message"/>

                  </intermediateThrowEvent>

                  <endEvent id="_3" name="EndEvent" />

                   

                  //send task

                  <sendTask id="_2" name="Hello" messageRef="_2_Message" implementation="Other" >

                    <ioSpecification>

                      <dataInput id="_2_param" name="Message" />

                      <inputSet>

                        <dataInputRefs>_2_param</dataInputRefs>

                      </inputSet>

                      <outputSet/>

                    </ioSpecification>

                    <dataInputAssociation>

                      <sourceRef>s</sourceRef>

                      <targetRef>_2_param</targetRef>

                    </dataInputAssociation>

                  </sendTask>

                  My process xml:

                  <bpmn2:intermediateThrowEvent id="_1246A3A8-08AE-4FEC-AEDB-731A233E28CE" name="Update Twitter Status (throw message)">

                    <bpmn2:incoming>_BC5261CD-860C-4979-A045-AE209C41780D</bpmn2:incoming>

                    <bpmn2:outgoing>_3E572AF9-62AA-4D13-B0E7-BD1A3B893C80</bpmn2:outgoing>

                    <bpmn2:dataInput id="_1246A3A8-08AE-4FEC-AEDB-731A233E28CE_Parameter" name="Parameter"/>

                    <bpmn2:dataInputAssociation id="_amcjQ-J1EeC2tu7nt8W9eg">

                      <bpmn2:sourceRef>x</bpmn2:sourceRef>

                      <bpmn2:targetRef>_1246A3A8-08AE-4FEC-AEDB-731A233E28CE_Parameter</bpmn2:targetRef>

                    </bpmn2:dataInputAssociation>

                    <bpmn2:inputSet id="_amcjQuJ1EeC2tu7nt8W9eg">

                      <bpmn2:dataInputRefs>_1246A3A8-08AE-4FEC-AEDB-731A233E28CE_Parameter</bpmn2:dataInputRefs>

                    </bpmn2:inputSet>

                    <bpmn2:messageEventDefinition id="_amcjROJ1EeC2tu7nt8W9eg" drools:msgref="twitterProductLink" messageRef="twitterProductLink"/>

                  </bpmn2:intermediateThrowEvent>

                  • 6. Re: How to access a processInstance within a work item
                    Tobias Wittur Newbie

                    In addition to the above, I just tried:

                     

                    I added this to the process definition:

                    xmlns:tns="http://eclipse.org/bpel/correlwait"

                     

                    I changed my xml to this:

                    <bpmn2:intermediateThrowEvent tns:name="twitterTaskHandler" id="_1246A3A8-08AE-4FEC-AEDB-731A233E28CE" name="Update Twitter Status (throw message)">

                      <bpmn2:incoming>_BC5261CD-860C-4979-A045-AE209C41780D</bpmn2:incoming>

                      <bpmn2:outgoing>_3E572AF9-62AA-4D13-B0E7-BD1A3B893C80</bpmn2:outgoing>

                      <bpmn2:dataInput id="_1246A3A8-08AE-4FEC-AEDB-731A233E28CE_Parameter" name="Parameter"/>

                      <bpmn2:dataInputAssociation id="_amcjQ-J1EeC2tu7nt8W9eg">

                        <bpmn2:sourceRef>x</bpmn2:sourceRef>

                        <bpmn2:targetRef>_1246A3A8-08AE-4FEC-AEDB-731A233E28CE_Parameter</bpmn2:targetRef>

                      </bpmn2:dataInputAssociation>

                      <bpmn2:inputSet id="_amcjQuJ1EeC2tu7nt8W9eg">

                        <bpmn2:dataInputRefs>_1246A3A8-08AE-4FEC-AEDB-731A233E28CE_Parameter</bpmn2:dataInputRefs>

                      </bpmn2:inputSet>

                      <bpmn2:messageEventDefinition id="_amcjROJ1EeC2tu7nt8W9eg" drools:msgref="twitterProductLink" messageRef="twitterProductLink"/>

                    </bpmn2:intermediateThrowEvent>

                     

                    However, it still executes the standard send task.