14 Replies Latest reply on Nov 13, 2005 6:38 AM by Koen Aers

    how to execute timer actions

    Abhikal Jaiswal Newbie

      hi

      i am trying to build an applicatoion which have certain interval hold time and process control is supposed to get transitied to other state implicitly after performing certain task .i have implemented the schedular for this purspose however there is no action when the token goes to state which have timer nither the transaction is happening. please suggest

      the code is like this

      TaskTimer()
      {
      ProcessDefinition pd = ProcessDefinition.parseXmlString(
       "<process-definition>" +
       " <start-state>" +
       " <transition to='state1' />" +
       " </start-state>" +
       " <state name='state1'>" +
       " <timer name='timer1'" +
       " duedate='1 minutes'" +
      
       " transition='end' >" +
       " <action class='abcd' />" +
       " </timer>" +
       " </state>" +
       " <end-state name='end'/>" +
       "</process-definition>"
       );
       JbpmSession js = jsf.openJbpmSession();
       js.beginTransaction();
      
       ProcessInstance pi = new ProcessInstance(pd);
       pi.signal();
       js.getGraphSession().saveProcessInstance(pi);
      
       System.out.println("====="+pi.getRootToken().getNode().getName());
      
      } }
       public static void main(String[] args)
       {
      
       TaskTimer tt=new TaskTimer();
      
      
       }
      
      }
      


        • 1. Re: how to execute timer actions
          Koen Aers Master

          I don't really understand what you want to achieve. Could you detail your example code? Besides this, I have the impression that you don't commit your transaction and thus, nothing gets persisted in the database...

          Regards,
          Koen

          • 2. Re: how to execute timer actions
            Abhikal Jaiswal Newbie

            hi koen

            thanks for replying
            i am building an customer support service application which have a hold state for 20 minutes.
            eg a customer call in to support dept and encounters the wait state for 30 seconds.
            i am trying trying to implement a schedular which should execute as soon the token enters into the state which have timer event and timer should elapse after 40 seconds, then some action should be performed and the transition should happen automatically to the next stage.

            now i am trying to get the result through simple eg which have 3 states
            1 start state
            2 state1 --------: which have a timer which would elapse after 40 seconds
            and some action should be performed which is declared
            inside timer class and then transition should be made
            implicitly to the next state that is end-state;
            3 end state

            • 3. Re: how to execute timer actions
              Koen Aers Master

              AFAIK there are no problems in achieving this. Why do you think this does not work? Do you have a failing JUnit test to show it?

              Regards,
              Koen

              • 4. Re: how to execute timer actions
                Abhikal Jaiswal Newbie

                hi koen

                the junit runs fine.
                there is no exception while i run this on jboss, hoever i am not able to get the action handler results and nither the timer is transacting to next stage, for your information if i specify the execute function on Timer class instance, i am able to get the action hanler results however the transaction to the next state still never happens. please suggest

                • 5. Re: how to execute timer actions
                  Abhikal Jaiswal Newbie

                  i had made changes in my code as you said to commit the transaction, still i am not able to get the desired results as according to the documentations.
                  can you please give me a simple code that i can run on jboss or on eclipse
                  in jboss i am running this code wrapped in servlets

                  • 6. Re: how to execute timer actions
                    Koen Aers Master

                    If you want me to understand what you are trying to achieve and what is going wrong, you should provide a failing JUnit test.

                    Regards,
                    Koen

                    • 7. Re: how to execute timer actions
                      Abhikal Jaiswal Newbie

                      Hi koen

                      thank you for for giving your efforts on this issue
                      my junit test code is

                      import org.jbpm.db.JbpmSession;
                      import org.jbpm.db.JbpmSessionFactory;
                      import org.jbpm.db.SchedulerSession;
                      import org.jbpm.graph.def.ProcessDefinition;
                      import org.jbpm.graph.exe.ProcessInstance;
                      import org.jbpm.scheduler.exe.Timer;
                      
                      import junit.framework.TestCase;
                      
                      public class Schedule1 extends TestCase
                      {
                       static JbpmSessionFactory jsf=null;
                       static
                       {
                       jsf=JbpmSessionFactory.buildJbpmSessionFactory();
                       jsf.getJbpmSchema().createSchema();
                       }
                      
                       public void testProcess()throws Exception
                       {
                       ProcessDefinition pd = ProcessDefinition.parseXmlString(
                       "<process-definition>" +
                       " <start-state>" +
                       " <transition to='state1' />" +
                       " </start-state>" +
                       " <state name='state1'>" +
                       " <timer name='timer1'" +
                       " duedate='1 minutes'" +
                      
                       " transition='end' >" +
                       " <action class='abcd' />" +
                       " </timer>" +
                       " </state>" +
                       " <end-state name='end'/>" +
                       "</process-definition>"
                       );
                      
                       JbpmSession js = jsf.openJbpmSession();
                       SchedulerSession ss=new SchedulerSession(js);
                       js.beginTransaction();
                      
                       ProcessInstance pi = new ProcessInstance(pd);
                       pi.signal();
                       assertEquals("state1",pi.getRootToken().getNode().getName());
                       assertEquals(1, pi.getSchedulerInstance().getScheduledTimers().size());
                       Timer timer = (Timer) pi.getSchedulerInstance().getScheduledTimers().get(0);
                       assertEquals("timer1", timer.getName());
                       assertEquals(pd.getNode("state1"), timer.getGraphElement());
                       System.out.println(timer.getDueDate());
                       assertNotNull(timer.getDueDate());
                       assertEquals("abcd",timer.getAction().getActionDelegation().getClassName());
                       assertSame(pi.getRootToken(), timer.getToken());
                       assertEquals("end", timer.getTransitionName());
                       js.getSchedulerSession().saveTimer(timer);
                       js.getGraphSession().saveProcessDefinition(pd);
                       js.getGraphSession().saveProcessInstance(pi);
                      
                       js.commitTransaction();
                      
                       js=jsf.openJbpmSession();
                       pi=js.getGraphSession().loadProcessInstance(pi.getId());
                       assertEquals("end",pi.getRootToken().getNode().getName());
                      
                       System.out.println("====="+pi.getRootToken().getNode().getName());
                      
                       }
                      
                      
                       }
                      
                      
                      
                      
                      


                      and its gives the runtime error


                      junit.framework.ComparisonFailure: expected:<end> but was:<state1>
                      at junit.framework.Assert.assertEquals(Assert.java:81)
                      at junit.framework.Assert.assertEquals(Assert.java:87)
                      at Schedule1.testProcess(Schedule1.java:62)
                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                      at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                      at java.lang.reflect.Method.invoke(Unknown Source)
                      at junit.framework.TestCase.runTest(TestCase.java:154)
                      at junit.framework.TestCase.runBare(TestCase.java:127)
                      at junit.framework.TestResult$1.protect(TestResult.java:106)
                      at junit.framework.TestResult.runProtected(TestResult.java:124)
                      at junit.framework.TestResult.run(TestResult.java:109)
                      at junit.framework.TestCase.run(TestCase.java:118)
                      at junit.framework.TestSuite.runTest(TestSuite.java:208)
                      at junit.framework.TestSuite.run(TestSuite.java:203)
                      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
                      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
                      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)








                      • 8. Re: how to execute timer actions
                        Abhikal Jaiswal Newbie

                        this is what i am getting
                        nither the action 'abcd' happens nither the state transiction takes place from 'state1' to 'end'

                        regards
                        abhikal

                        • 9. Re: how to execute timer actions
                          Koen Aers Master

                          Okay now I understand it. What happens is perfectly normal. The process is not yet in the end state, it is in the state1. The last transition was not taken because it was not signalled. The timer is scheduled successfully but the action 'abcd' never happens. For the action to execute you have to have a scheduler thread running, which is a separate process and not really testable in a JUnit test scenario. This scheduler thread is running for instance when you start the jBPM webapp in the starter's kit.
                          If you would deploy this process to the jBPM engine of the starter's kit and then provoke the first transition, you would see the scheduler thread picking up the scheduled action. Thus 'abcd' would execute, the transition would be taken and the process would end.
                          Download and fire up the jbpm server in the starter's kit and have a try!

                          Regards,
                          Koen

                          • 10. Re: how to execute timer actions
                            Abhikal Jaiswal Newbie

                            Thanks koen
                            i appreciate your help
                            i have tried that in jboss using servlets where the schedular instance is running, however you have given me new and good information that would help me to proceed, i would try it and would let you know. thanks again

                            regards
                            abhikal

                            • 11. Re: how to execute timer actions
                              Abhikal Jaiswal Newbie

                              Hi koen

                              i have tried the code wrapped in servlet and deployed in jbpm jboss server. the issue is not resolved. the timer action is not executing nither the transaction takes place from 'state1' to 'end' state. Please suggest

                              package cs;
                              import java.io.IOException;
                              import java.io.IOException;
                              import java.io.PrintWriter;
                              
                              import javax.servlet.http.HttpServlet;
                              import javax.servlet.http.HttpServletRequest;
                              import javax.servlet.http.HttpServletResponse;
                              
                              import org.jbpm.db.JbpmSession;
                              import org.jbpm.db.JbpmSessionFactory;
                              import org.jbpm.db.SchedulerSession;
                              import org.jbpm.graph.def.ProcessDefinition;
                              import org.jbpm.graph.exe.ProcessInstance;
                              import org.jbpm.scheduler.exe.Timer;
                              import org.jbpm.scheduler.impl.Scheduler;
                              
                              import javax.servlet.http.HttpServlet;
                              
                              public class schedule extends HttpServlet
                              {
                               JbpmSessionFactory jsf=null;
                              
                               public void doGet(HttpServletRequest rq,HttpServletResponse res)
                               {
                               ProcessDefinition pd = ProcessDefinition.parseXmlString(
                               "<process-definition>" +
                               " <start-state>" +
                               " <transition to='state1' />" +
                               " </start-state>" +
                               " <state name='state1'>" +
                               " <timer name='timer1'" +
                               " duedate='30 seconds'" +
                               " transition='end' >" +
                               " <action class='cs.abcd' />" +
                               " </timer>" +
                               " </state>" +
                               " <end-state name='end'/>" +
                               "</process-definition>"
                               );
                               if(jsf==null)
                               {
                               jsf=JbpmSessionFactory.buildJbpmSessionFactory();
                               jsf.getJbpmSchema().createSchema();
                               }
                               JbpmSession js = jsf.openJbpmSession();
                               SchedulerSession ss=new SchedulerSession(js);
                               js.beginTransaction();
                              
                               ProcessInstance pi = new ProcessInstance(pd);
                               pi.signal();
                              
                              
                               Timer timer = (Timer) pi.getSchedulerInstance().getScheduledTimers().get(0);
                               js.getSchedulerSession().saveTimer(timer);
                               js.getGraphSession().saveProcessDefinition(pd);
                               js.getGraphSession().saveProcessInstance(pi);
                               js.commitTransaction();
                              
                              
                               js=jsf.openJbpmSession();
                               pi=js.getGraphSession().loadProcessInstance(pi.getId());
                              
                              
                              
                              
                              
                               PrintWriter pw;
                               res.setContentType("text/html");
                              
                              
                              
                               try
                               {
                               pw = res.getWriter();
                               pw.println("hello how r u");
                               if(pi.getRootToken().getNode().getName().equals("state1"));
                               {
                               pw.println(pi.getRootToken().getNode().getName());
                               pw.println("<META HTTP-EQUIV=Refresh CONTENT=\"1; URL=http://localhost:8080/service/sh\">");
                               pw.println("in");
                               }
                               pw.println("out");
                               }
                               catch (IOException e)
                               {
                               e.printStackTrace();
                               }
                              
                              
                               }
                              
                               }
                              
                              
                              
                              


                              regards
                              abhikal

                              • 12. Re: how to execute timer actions
                                Koen Aers Master

                                You should deploy your process to the jbpm server. Your client code should lookup the processdefinition of the deployed process, create an instance of it and signal the root token.
                                This client code does not have to be a servlet, it can easily be done from a normal standalone program or a JUnit test.

                                Regards,
                                Koen

                                • 13. Re: how to execute timer actions
                                  Abhikal Jaiswal Newbie

                                  Hi koen

                                  i have run the test using servlet client and process definition deployed in jbpm server. Please know that the action handler class could not be loaded because it has to deployed in special directory, i did that in /tmp in linux.
                                  if you have any simple code that could help to avoid putting the action class file in special folder and specifing a FileDefinitionEntry in some file, i cannot recall right now, to make action happen.


                                  regards
                                  abhikal

                                  • 14. Re: how to execute timer actions
                                    Koen Aers Master

                                    The action handler class files should be on the classpath of the jBPM webapp if you want it to be run by the scheduler thread. The easiest way to achieve this is deploy your action classes along with your process definition. Another possibility is rebuild the jBPM webapp and add your custom classes in a jar file in the lib folder of the webapp archive.

                                    Regards,
                                    Koen