[jbpm-commits] JBoss JBPM SVN: r1703 - in jbpm3/branches/tdiesler/modules/jpdl: core/src/main/java/org/jbpm/db and 9 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Thu Jul 24 07:31:32 EDT 2008


Author: thomas.diesler at jboss.com
Date: 2008-07-24 07:31:32 -0400 (Thu, 24 Jul 2008)
New Revision: 1703

Added:
   jbpm3/branches/tdiesler/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java
   jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/org/jbpm/job/executor/timerOnTimer.jpdl.xml
Removed:
   jbpm3/branches/tdiesler/modules/jpdl/integration/
Modified:
   jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java
   jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteActionJob.java
   jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteNodeJob.java
   jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java
   jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java
   jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/msg/db/DbMessageService.java
   jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/scheduler/db/DbSchedulerService.java
   jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/svc/Services.java
   jbpm3/branches/tdiesler/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml
   jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/log4j.xml
   jbpm3/branches/tdiesler/modules/jpdl/pom.xml
Log:
Rollback to -r1492. Merge -r1552:1558

Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java	2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java	2008-07-24 11:31:32 UTC (rev 1703)
@@ -15,7 +15,6 @@
 import org.jbpm.graph.def.Action;
 import org.jbpm.graph.exe.ProcessInstance;
 import org.jbpm.graph.exe.Token;
-import org.jbpm.job.ExecuteNodeJob;
 import org.jbpm.job.Job;
 import org.jbpm.job.Timer;
 import org.jbpm.svc.save.SaveOperation;
@@ -194,30 +193,18 @@
         return;
       }
 
-      // the bulk delete was replaced with a query and session.deletes on 
-      // the retrieved elements to prevent stale object exceptions.  
-      // With a bulk delete, the hibernate session is not aware and gives a problem 
-      // if a later session.delete doesn't return 1.
       log.debug("deleting timers for process instance "+processInstance);
       Session session = jbpmContext.getSession();
-      Query query = session.getNamedQuery("JobSession.getTimersForProcessInstance");
+      Query query = session.getNamedQuery("JobSession.deleteTimersForProcessInstance");
       query.setParameter("processInstance", processInstance);
-      List timers = query.list();
-      for (Iterator i = timers.iterator(); i.hasNext();) {
-        Timer timer = (Timer) i.next();
-        session.delete(timer);
-      }
-      log.debug(timers.size()+" remaining timers for '"+processInstance+"' were deleted");
+      int entityCount = query.executeUpdate();
+      log.debug(entityCount+" remaining timers for '"+processInstance+"' were deleted");
 
       log.debug("deleting execute-node-jobs for process instance "+processInstance);
-      query = session.getNamedQuery("JobSession.getExecuteNodeJobsForProcessInstance");
+      query = session.getNamedQuery("JobSession.deleteExecuteNodeJobsForProcessInstance");
       query.setParameter("processInstance", processInstance);
-      List jobs = query.list();
-      for (Iterator i = jobs.iterator(); i.hasNext();) {
-        ExecuteNodeJob job = (ExecuteNodeJob) i.next();
-        session.delete(job);
-      }
-      log.debug(jobs.size()+" remaining execute-node-jobs for '"+processInstance+"' are deleted");
+      entityCount = query.executeUpdate();
+      log.debug(entityCount+" remaining execute-node-jobs for '"+processInstance+"' are deleted");
     }
     
   }

Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteActionJob.java
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteActionJob.java	2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteActionJob.java	2008-07-24 11:31:32 UTC (rev 1703)
@@ -34,7 +34,7 @@
       action.execute(executionContext);
     }
 
-    jbpmContext.save(token);
+    jbpmContext.save(processInstance);
 
     return true;
   }

Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteNodeJob.java
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteNodeJob.java	2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteNodeJob.java	2008-07-24 11:31:32 UTC (rev 1703)
@@ -25,7 +25,7 @@
     token.unlock(this.toString());
     ExecutionContext executionContext = new ExecutionContext(token);
     node.execute(executionContext);
-    jbpmContext.save(token);
+    jbpmContext.save(processInstance);
     return true;
   }
   

Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java	2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java	2008-07-24 11:31:32 UTC (rev 1703)
@@ -35,7 +35,10 @@
   }
 
   public boolean execute(JbpmContext jbpmContext) throws Exception {
-    boolean deleteThisJob = true;
+    if (processInstance.hasEnded()) {
+      // happens when a repeating timer is blocked at the time the process instance ends
+      return true;
+    }
 
     ExecutionContext executionContext = new ExecutionContext(token);
     executionContext.setTimer(this);
@@ -52,7 +55,7 @@
     // then execute the action if there is one
     if (action!=null) {
       try {
-        log.debug("executing timer '"+this+"'");
+        log.debug("executing '"+this+"'");
         if (graphElement!=null) {
           graphElement.executeAction(action, executionContext);
         } else {
@@ -61,28 +64,19 @@
       } catch (Exception actionException) {
         // NOTE that Error's are not caught because that might halt the JVM and mask the original Error.
         log.warn("timer action threw exception", actionException);
-
-        // we put the exception in t
-        Exception t = actionException;
-        try {
-          // if there is a graphElement connected to this timer...
-          if (graphElement != null) {
+        // if there is a graphElement connected to this timer...
+        if (graphElement != null) {
+          try {
             // we give that graphElement a chance to catch the exception
             graphElement.raiseException(actionException, executionContext);
             log.debug("timer exception got handled by '"+graphElement+"'");
-            t = null;
+          } catch (Exception handlerException) {
+            // if the exception handler rethrows or the original exception results in a DelegationException...
+            throw handlerException;
           }
-        } catch (Exception rethrowOrDelegationException) {
-          // NOTE that Error's are not caught because that might halt the JVM and mask the original Error.
-          // if the exception handler rethrows or the original exception results in a DelegationException...
-          t = rethrowOrDelegationException;
+        } else {
+          throw actionException;
         }
-        
-        if (t!=null) {
-          // This is either the original exception wrapped as a delegation exception
-          // or an exception that was throws from an exception handler
-          throw t;
-        }
       }
     }
 
@@ -100,20 +94,17 @@
     
     // if repeat is specified, reschedule the job
     if (repeat!=null) {
-      deleteThisJob = false;
-
       // suppose that it took the timer runner thread a 
       // very long time to execute the timers.
       // then the repeat action dueDate could already have passed.
       while (dueDate.getTime()<=System.currentTimeMillis()) {
-        dueDate = businessCalendar
-              .add(dueDate, 
-                new Duration(repeat));
+        dueDate = businessCalendar.add(dueDate, new Duration(repeat));
       }
-      log.debug("updated timer for repetition '"+this+"' in '"+(dueDate.getTime()-System.currentTimeMillis())+"' millis");
-    } 
+      log.debug("updated '"+this+"' for repetition on '"+formatDueDate(dueDate)+"'");
+      return false;
+    }
     
-    return deleteThisJob;
+    return true;
   }
   
   public String toString() {

Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java	2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java	2008-07-24 11:31:32 UTC (rev 1703)
@@ -2,7 +2,6 @@
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
@@ -19,6 +18,7 @@
 import org.jbpm.job.Timer;
 import org.jbpm.persistence.JbpmPersistenceException;
 import org.jbpm.persistence.db.StaleObjectLogConfigurer;
+import org.jbpm.svc.Services;
 
 public class JobExecutorThread extends Thread {
 
@@ -48,65 +48,59 @@
   volatile boolean isActive = true;
 
   public void run() {
-    try {
-      currentIdleInterval = idleInterval;
-      while (isActive) {
-        try {
-          Collection acquiredJobs = acquireJobs();
+    currentIdleInterval = idleInterval;
+    while (isActive) {
+      try {
+        Collection acquiredJobs = acquireJobs();
 
-          if (! acquiredJobs.isEmpty()) {
-            Iterator iter = acquiredJobs.iterator();
-            while (iter.hasNext() && isActive) {
-              Job job = (Job) iter.next();
-              executeJob(job);
-            }
+        if (! acquiredJobs.isEmpty()) {
+          Iterator iter = acquiredJobs.iterator();
+          while (iter.hasNext() && isActive) {
+            Job job = (Job) iter.next();
+            executeJob(job);
+          }
 
-          } else { // no jobs acquired
-            if (isActive) {
-              long waitPeriod = getWaitPeriod();
-              if (waitPeriod>0) {
-                synchronized(jobExecutor) {
-                  jobExecutor.wait(waitPeriod);
-                }
+        } else { // no jobs acquired
+          if (isActive) {
+            long waitPeriod = getWaitPeriod();
+            if (waitPeriod>0) {
+              synchronized(jobExecutor) {
+                jobExecutor.wait(waitPeriod);
               }
             }
           }
-          
-          // no exception so resetting the currentIdleInterval
-          currentIdleInterval = idleInterval;
+        }
+        
+        // no exception so resetting the currentIdleInterval
+        currentIdleInterval = idleInterval;
 
-        } catch (InterruptedException e) {
-          log.info((isActive? "active" : "inactive")+" job executor thread '"+getName()+"' got interrupted");
-        } catch (Exception e) {
-          log.error("exception in job executor thread. waiting "+currentIdleInterval+" milliseconds", e);
-          try {
-            synchronized(jobExecutor) {
-              jobExecutor.wait(currentIdleInterval);
-            }
-          } catch (InterruptedException e2) {
-            log.debug("delay after exception got interrupted", e2);
+      } catch (InterruptedException e) {
+        log.info((isActive? "active" : "inactive")+" job executor thread '"+getName()+"' got interrupted");
+      } catch (Exception e) {
+        log.error("exception in job executor thread. waiting "+currentIdleInterval+" milliseconds", e);
+        try {
+          synchronized(jobExecutor) {
+            jobExecutor.wait(currentIdleInterval);
           }
-          // after an exception, the current idle interval is doubled to prevent 
-          // continuous exception generation when e.g. the db is unreachable
-          currentIdleInterval <<= 1;
-          if (currentIdleInterval > maxIdleInterval || currentIdleInterval < 0) {
-            currentIdleInterval = maxIdleInterval;
-          }
+        } catch (InterruptedException e2) {
+          log.debug("delay after exception got interrupted", e2);
         }
+        // after an exception, the current idle interval is doubled to prevent 
+        // continuous exception generation when e.g. the db is unreachable
+        currentIdleInterval <<= 1;
+        if (currentIdleInterval > maxIdleInterval || currentIdleInterval < 0) {
+          currentIdleInterval = maxIdleInterval;
+        }
       }
-    } catch (Exception e) {
-      // NOTE that Error's are not caught because that might halt the JVM and mask the original Error.
-      log.error("exception in job executor thread", e);
-    } finally {
-      log.info(getName()+" leaves cyberspace");
     }
+    log.info(getName()+" leaves cyberspace");
   }
 
   protected Collection acquireJobs() {
     Collection acquiredJobs;
     synchronized (jobExecutor) {
-      Collection jobsToLock = new ArrayList();
       log.debug("acquiring jobs for execution...");
+      Collection jobsToLock = Collections.EMPTY_LIST;
       JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
       try {
         JobSession jobSession = jbpmContext.getJobSession();
@@ -116,11 +110,11 @@
           if (job.isExclusive()) {
             log.debug("exclusive acquirable job found ("+job+"). querying for other exclusive jobs to lock them all in one tx...");
             List otherExclusiveJobs = jobSession.findExclusiveJobs(getName(), job.getProcessInstance());
-            jobsToLock.addAll(otherExclusiveJobs);
+            jobsToLock = otherExclusiveJobs;
             log.debug("trying to obtain a process-instance exclusive locks for '"+otherExclusiveJobs+"'");
           } else {
             log.debug("trying to obtain a lock for '"+job+"'");
-            jobsToLock.add(job);
+            jobsToLock = Collections.singletonList(job);
           }
           
           Iterator iter = jobsToLock.iterator();
@@ -145,17 +139,13 @@
           log.debug("obtained lock on jobs: "+acquiredJobs);
         }
         catch (JbpmPersistenceException e) {
-          // if this is a stale object exception, the jbpm configuration has control over the logging
-          if ("org.hibernate.StaleObjectStateException".equals(e.getCause().getClass().getName())) {
-            log.info("problem committing job acquisition transaction: optimistic locking failed");
-            StaleObjectLogConfigurer.staleObjectExceptionsLog.error("problem committing job acquisition transaction: optimistic locking failed", e);
+          // if this is a stale object exception, keep it quiet
+          if (Services.isCausedByStaleState(e)) {
+            log.debug("optimistic locking failed, couldn't obtain lock on jobs: "+jobsToLock);
+            acquiredJobs = Collections.EMPTY_LIST;
           } else {
-            // TODO run() will log this exception, log it here too?
-            log.error("problem committing job acquisition transaction", e);
             throw e;
           }
-          acquiredJobs = Collections.EMPTY_LIST;
-          log.debug("couldn't obtain lock on jobs: "+jobsToLock); 
         }
       }
     }
@@ -173,7 +163,6 @@
         if (job.execute(jbpmContext)) {
           jobSession.deleteJob(job);
         }
-
       } catch (Exception e) {
         log.debug("exception while executing '"+job+"'", e);
         StringWriter sw = new StringWriter();
@@ -187,7 +176,6 @@
       if (totalLockTimeInMillis>maxLockTime) {
         jbpmContext.setRollbackOnly();
       }
-
     } finally {
       try {
         jbpmContext.close();

Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/msg/db/DbMessageService.java
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/msg/db/DbMessageService.java	2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/msg/db/DbMessageService.java	2008-07-24 11:31:32 UTC (rev 1703)
@@ -37,9 +37,8 @@
   
   private static final long serialVersionUID = 1L;
 
-  JbpmConfiguration jbpmConfiguration;
   JobSession jobSession = null;
-  Collection destinations = null;
+  JobExecutor jobExecutor = null;
   boolean hasProducedJobs = false;
   
   public DbMessageService() {
@@ -47,8 +46,8 @@
     if (jbpmContext==null) {
       throw new JbpmException("instantiation of the DbMessageService requires a current JbpmContext");
     }
-    this.jbpmConfiguration = jbpmContext.getJbpmConfiguration();
-    this.jobSession = jbpmContext.getJobSession();
+    jobSession = jbpmContext.getJobSession();
+    jobExecutor = jbpmContext.getJbpmConfiguration().getJobExecutor();
   }
 
   public void send(Job job) {
@@ -58,11 +57,10 @@
   }
 
   public void close() {
-    JobExecutor jobExecutor = jbpmConfiguration.getJobExecutor();
     if ( (hasProducedJobs)
          && (jobExecutor!=null)
        ) {
-      log.debug("messages were produced the jobExecutor will be signalled");
+      log.debug("messages were produced, job executor will be signalled");
       synchronized(jobExecutor) {
         jobExecutor.notify();
       }

Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/scheduler/db/DbSchedulerService.java
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/scheduler/db/DbSchedulerService.java	2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/scheduler/db/DbSchedulerService.java	2008-07-24 11:31:32 UTC (rev 1703)
@@ -21,26 +21,39 @@
  */
 package org.jbpm.scheduler.db;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.jbpm.JbpmContext;
 import org.jbpm.JbpmException;
 import org.jbpm.db.JobSession;
 import org.jbpm.graph.exe.ProcessInstance;
 import org.jbpm.graph.exe.Token;
 import org.jbpm.job.Timer;
+import org.jbpm.job.executor.JobExecutor;
 import org.jbpm.scheduler.SchedulerService;
 
 public class DbSchedulerService implements SchedulerService {
 
   private static final long serialVersionUID = 1L;
+
+  private static final Log log = LogFactory.getLog(DbSchedulerService.class);
   
   JobSession jobSession = null;
-  
+  JobExecutor jobExecutor = null;
+  boolean hasProducedJobs = false;
+
   public DbSchedulerService() {
-    this.jobSession = JbpmContext.getCurrentJbpmContext().getJobSession();
+    JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
+    if (jbpmContext==null) {
+      throw new JbpmException("instantiation of the DbSchedulerService requires a current JbpmContext");
+    }
+    this.jobSession = jbpmContext.getJobSession();
+    this.jobExecutor = jbpmContext.getJbpmConfiguration().getJobExecutor();
   }
   
   public void createTimer(Timer timerJob) {
     jobSession.saveJob(timerJob);
+    hasProducedJobs = true;
   }
 
   public void deleteTimersByName(String timerName, Token token) {
@@ -55,5 +68,11 @@
   }
 
   public void close() {
+    if (hasProducedJobs && jobExecutor != null) {
+      log.debug("timers were produced, job executor will be signalled");
+      synchronized (jobExecutor) {
+        jobExecutor.notify();
+      }
+    }
   }
 }

Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/svc/Services.java
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/svc/Services.java	2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/svc/Services.java	2008-07-24 11:31:32 UTC (rev 1703)
@@ -31,6 +31,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.hibernate.StaleStateException;
 import org.jbpm.JbpmContext;
 import org.jbpm.JbpmException;
 import org.jbpm.graph.exe.ProcessInstance;
@@ -234,8 +235,8 @@
             log.debug("closing service '"+serviceName+"': "+service);
             service.close();
           } catch (JbpmPersistenceException e) {
-            // if this is a stale object exception, the jbpm configuration has control over the logging
-            if ("org.hibernate.StaleObjectStateException".equals(e.getCause().getClass().getName())) {
+            // if this is a stale state exception, the jbpm configuration has control over the logging
+            if (isCausedByStaleState(e)) {
               log.info("problem closing service '"+serviceName+"': optimistic locking failed");
               StaleObjectLogConfigurer.staleObjectExceptionsLog.error("problem closing service '"+serviceName+"': optimistic locking failed", e);
             } else {
@@ -263,6 +264,14 @@
     }
   }
 
+  public static boolean isCausedByStaleState(JbpmPersistenceException persistenceException) {
+    for (Throwable cause = persistenceException.getCause(); cause != null; cause = cause.getCause()) {
+      if (cause instanceof StaleStateException)
+        return true;
+    }
+    return false;
+  }
+
   public static void assignId(Object object) {
     JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
     if (jbpmContext!=null) {

Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml	2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml	2008-07-24 11:31:32 UTC (rev 1703)
@@ -314,19 +314,19 @@
     ]]>
   </query>
 
-  <query name="JobSession.getTimersForProcessInstance">
+  <query name="JobSession.deleteTimersForProcessInstance">
     <![CDATA[
-      select timer
-      from org.jbpm.job.Timer timer
+      delete from org.jbpm.job.Timer timer
       where timer.processInstance = :processInstance
+        and timer.lockOwner is null
     ]]>
   </query>
 
-  <query name="JobSession.getExecuteNodeJobsForProcessInstance">
+  <query name="JobSession.deleteExecuteNodeJobsForProcessInstance">
     <![CDATA[
-      select job
-      from org.jbpm.job.ExecuteNodeJob job
+      delete from org.jbpm.job.ExecuteNodeJob job
       where job.processInstance = :processInstance
+        and job.lockOwner is null
     ]]>
   </query>
 

Copied: jbpm3/branches/tdiesler/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java (from rev 1558, jbpm3/trunk/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java)
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java	                        (rev 0)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java	2008-07-24 11:31:32 UTC (rev 1703)
@@ -0,0 +1,105 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.job.executor;
+
+import java.io.Serializable;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jbpm.db.AbstractDbTestCase;
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.graph.exe.ProcessInstance;
+
+/**
+ * Test case for JBPM-1135
+ * @author Alejandro Guizar
+ */
+public class TimerOnTimerDbTest extends AbstractDbTestCase {
+
+  private static final Log log = LogFactory.getLog(TimerOnTimerDbTest.class);
+
+  public void testTimerOnTimer() {
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("org/jbpm/job/executor/timerOnTimer.jpdl.xml");
+    jbpmContext.deployProcessDefinition(processDefinition);
+
+    ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("timerTest");
+    processInstance.getContextInstance().setVariable("timerTestWorkflow", new WorkflowLogger());
+    processInstance.signal();
+    commitAndCloseSession();
+    long tokenId = processInstance.getRootToken().getId();
+
+    startJobExecutor();
+    try {
+      sleep(500);
+      beginSessionTransaction();
+      assertEquals("timerTest", jbpmContext.loadToken(tokenId).getNode().getName());
+      commitAndCloseSession();
+
+      sleep(1000);
+      beginSessionTransaction();
+      assertEquals("secondTimerTest", jbpmContext.loadToken(tokenId).getNode().getName());
+      commitAndCloseSession();
+
+      sleep(1000);
+      beginSessionTransaction();
+      assertTrue(jbpmContext.loadToken(tokenId).getProcessInstance().hasEnded());
+    }
+    finally {
+      stopJobExecutor();
+    }
+  }
+
+  private void sleep(long millis) {
+    try {
+      Thread.sleep(millis);
+    }
+    catch (InterruptedException e) {
+      // reassert interruption
+      Thread.currentThread().interrupt();
+    }    
+  }
+
+  public static final class WorkflowLogger implements Serializable {
+  
+    private static final long serialVersionUID = 1L;
+  
+    public void logNodeEnter() {
+      log.info("entered node");
+    }
+  
+    public void logNodeLeave() {
+      log.info("left node");
+    }
+  
+    public void logTaskCreate() {
+      log.info("created task");
+    }
+  
+    public void logTimerCreate() {
+      log.info("created timer");
+    }
+  
+    public void logTimerFired() {
+      log.info("fired timer");
+    }
+  }
+}

Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/log4j.xml
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/log4j.xml	2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/log4j.xml	2008-07-24 11:31:32 UTC (rev 1703)
@@ -12,7 +12,7 @@
     <param name="Append" value="false"/>
     <layout class="org.apache.log4j.PatternLayout">
       <!-- The default pattern: Date Priority [Category] Message\n -->
-      <param name="ConversionPattern" value="%d %-5p [%c:%L] %m%n"/>
+      <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
     </layout>
   </appender>
   
@@ -24,7 +24,7 @@
     <param name="Target" value="System.out" />
     <param name="Threshold" value="INFO" />
     <layout class="org.apache.log4j.PatternLayout">
-      <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} [%t] %-5p %C{1} : %m%n" />
+      <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %-5p [%c{1}] %m%n" />
     </layout>
   </appender>
 
@@ -40,11 +40,17 @@
     <priority value="INFO" />
   </category>
 
-  <!-- hide optimistic locking failures -->
+  <!-- hide optimistic locking failures
   <category name="org.hibernate.event.def.AbstractFlushingEventListener">
     <priority value="FATAL" />
   </category>
+  -->
 
+  <!-- hide proxy narrowing warns -->
+  <category name="org.hibernate.engine.StatefulPersistenceContext.ProxyWarnLog">
+    <priority value="ERROR" />
+  </category>
+
   <!-- show SQL DML statements as they are executed -->
   <category name="org.hibernate.SQL">
     <priority value="DEBUG" />

Copied: jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/org/jbpm/job/executor/timerOnTimer.jpdl.xml (from rev 1558, jbpm3/trunk/modules/jpdl/core/src/test/resources/org/jbpm/job/executor/timerOnTimer.jpdl.xml)
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/org/jbpm/job/executor/timerOnTimer.jpdl.xml	                        (rev 0)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/org/jbpm/job/executor/timerOnTimer.jpdl.xml	2008-07-24 11:31:32 UTC (rev 1703)
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<process-definition name="timerTest" xmlns="urn:jbpm.org:jpdl-3.2"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="urn:jbpm.org:jpdl-3.2 http://jbpm.org/xsd/jpdl-3.2.xsd">
+
+  <start-state name="start">
+    <transition name="" to="timerTest" />
+  </start-state>
+
+  <task-node name="timerTest" end-tasks="true">
+    <event type="node-enter">
+      <action expression="#{timerTestWorkflow.logNodeEnter}" />
+    </event>
+    <event type="node-leave">
+      <action expression="#{timerTestWorkflow.logNodeLeave}" />
+    </event>
+    <transition name="doneFirst" to="secondTimerTest" />
+    <task name="timerTestTask" description="TimerTestTask">
+      <assignment actor-id="admin" />
+      <event type="task-create">
+        <action expression="#{timerTestWorkflow.logTaskCreate}" />
+      </event>
+      <event type="timer-create">
+        <action expression="#{timerTestWorkflow.logTimerCreate}" />
+      </event>
+      <timer duedate="1 second" transition="doneFirst">
+        <action expression="#{timerTestWorkflow.logTimerFired}" />
+      </timer>
+    </task>
+  </task-node>
+
+  <task-node name="secondTimerTest">
+    <task name="secondTimerTestTask" description="SecondTimerTestTask">
+      <assignment actor-id="admin" />
+      <event type="task-create">
+        <action expression="#{timerTestWorkflow.logTaskCreate}" />
+      </event>
+      <event type="timer-create">
+        <action expression="#{timerTestWorkflow.logTimerCreate}" />
+      </event>
+      <timer duedate="1 second" transition="doneSecond">
+        <action expression="#{timerTestWorkflow.logTimerFired}" />
+      </timer>
+    </task>
+    <transition name="doneSecond" to="end" />
+  </task-node>
+
+  <end-state name="end" />
+
+</process-definition>
\ No newline at end of file

Modified: jbpm3/branches/tdiesler/modules/jpdl/pom.xml
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/pom.xml	2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/pom.xml	2008-07-24 11:31:32 UTC (rev 1703)
@@ -34,7 +34,6 @@
     <module>db</module>
     <module>examples</module>
     <module>identity</module>
-    <module>integration</module>
     <module>simulation</module>
     <module>userguide</module>
     <module>ws</module>




More information about the jbpm-commits mailing list