[jbpm-commits] JBoss JBPM SVN: r5183 - in jbpm3/branches/jbpm-3.2-soa/modules: core/src/test/java/org/jbpm/seam and 1 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Jul 1 21:05:31 EDT 2009


Author: alex.guizar at jboss.com
Date: 2009-07-01 21:05:31 -0400 (Wed, 01 Jul 2009)
New Revision: 5183

Modified:
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/JobSession.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/CustomJobExecutor.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/CustomJobExecutorThread.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/JobExecutorCustomizationTest.java
   jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/TimerEntityBean.java
Log:
make JobExecutorCustomizationTest resistant to stale state exceptions

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/JobSession.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/JobSession.java	2009-07-01 20:20:45 UTC (rev 5182)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/JobSession.java	2009-07-02 01:05:31 UTC (rev 5183)
@@ -29,6 +29,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
 import org.hibernate.Query;
 import org.hibernate.Session;
 
@@ -68,10 +69,10 @@
           .list();
     }
     catch (HibernateException e) {
-      throw new JbpmPersistenceException("could not find exclusive jobs owned by '"
-          + lockOwner
-          + "' for "
-          + processInstance, e);
+      throw new JbpmPersistenceException("could not find exclusive jobs owned by '" +
+          lockOwner +
+          "' for " +
+          processInstance, e);
     }
   }
 
@@ -99,10 +100,10 @@
       return (Job) query.setString("lockOwner", lockOwner).setMaxResults(1).uniqueResult();
     }
     catch (HibernateException e) {
-      throw new JbpmPersistenceException("could not get first due job owned by '"
-          + lockOwner
-          + "' ignoring jobs "
-          + monitoredJobs, e);
+      throw new JbpmPersistenceException("could not get first due job owned by '" +
+          lockOwner +
+          "' ignoring jobs " +
+          monitoredJobs, e);
     }
   }
 
@@ -134,6 +135,21 @@
     }
   }
 
+  /**
+   * Reattach job originally loaded in a previous session.
+   * 
+   * @param job a detached job
+   * @see <a href="http://tinyurl.com/kjss69">Detached objects and automatic versioning</a>
+   */
+  public void reattachJob(Job job) {
+    try {
+      session.lock(job, LockMode.NONE);
+    }
+    catch (HibernateException e) {
+      throw new JbpmPersistenceException("could not reattach " + job, e);
+    }
+  }
+
   public Timer loadTimer(long timerId) {
     try {
       return (Timer) session.load(Timer.class, new Long(timerId));
@@ -173,46 +189,51 @@
   public void deleteTimersByName(String name, Token token) {
     try {
       // delete unowned timers
-      int entityCount = session.getNamedQuery("JobSession.deleteTimersByName")
-          .setString("name", name)
-          .setParameter("token", token)
-          .executeUpdate();
+      int entityCount =
+          session.getNamedQuery("JobSession.deleteTimersByName")
+              .setString("name", name)
+              .setParameter("token", token)
+              .executeUpdate();
       log.debug("deleted " + entityCount + " timers by name '" + name + "' for " + token);
 
       // prevent further repetitions
-      List timers = session.getNamedQuery("JobSession.findRepeatingTimersByName")
-          .setString("name", name)
-          .setParameter("token", token)
-          .list();
+      List timers =
+          session.getNamedQuery("JobSession.findRepeatingTimersByName")
+              .setString("name", name)
+              .setParameter("token", token)
+              .list();
       preventFurtherRepetitions(timers);
     }
     catch (HibernateException e) {
-      throw new JbpmPersistenceException("could not delete timers by name '"
-          + name
-          + "' for "
-          + token, e);
+      throw new JbpmPersistenceException("could not delete timers by name '" +
+          name +
+          "' for " +
+          token, e);
     }
   }
 
   public int countDeletableJobsForProcessInstance(ProcessInstance processInstance) {
-    Number jobCount = (Number) session.getNamedQuery("JobSession.countDeletableJobsForProcessInstance")
-        .setParameter("processInstance", processInstance)
-        .uniqueResult();
+    Number jobCount =
+        (Number) session.getNamedQuery("JobSession.countDeletableJobsForProcessInstance")
+            .setParameter("processInstance", processInstance)
+            .uniqueResult();
     return jobCount.intValue();
   }
 
   public void deleteJobsForProcessInstance(ProcessInstance processInstance) {
     try {
       // delete unowned node-execute-jobs and timers
-      int entityCount = session.getNamedQuery("JobSession.deleteJobsForProcessInstance")
-          .setParameter("processInstance", processInstance)
-          .executeUpdate();
+      int entityCount =
+          session.getNamedQuery("JobSession.deleteJobsForProcessInstance")
+              .setParameter("processInstance", processInstance)
+              .executeUpdate();
       log.debug("deleted " + entityCount + " jobs for " + processInstance);
 
       // prevent further repetitions
-      List timers = session.getNamedQuery("JobSession.findRepeatingTimersForProcessInstance")
-          .setParameter("processInstance", processInstance)
-          .list();
+      List timers =
+          session.getNamedQuery("JobSession.findRepeatingTimersForProcessInstance")
+              .setParameter("processInstance", processInstance)
+              .list();
       preventFurtherRepetitions(timers);
     }
     catch (HibernateException e) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/CustomJobExecutor.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/CustomJobExecutor.java	2009-07-01 20:20:45 UTC (rev 5182)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/CustomJobExecutor.java	2009-07-02 01:05:31 UTC (rev 5183)
@@ -6,6 +6,6 @@
   private static final long serialVersionUID = 1L;
 
   protected Thread createThread(String threadName) {
-    return new CustomJobExecutorThread(threadName, this, jbpmConfiguration, idleInterval, maxIdleInterval, maxLockTime, historyMaxSize);
+    return new CustomJobExecutorThread(threadName, this);
   }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/CustomJobExecutorThread.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/CustomJobExecutorThread.java	2009-07-01 20:20:45 UTC (rev 5182)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/CustomJobExecutorThread.java	2009-07-02 01:05:31 UTC (rev 5183)
@@ -1,24 +1,37 @@
 package org.jbpm.seam;
 
-import org.jbpm.JbpmConfiguration;
+import org.jbpm.JbpmContext;
+import org.jbpm.db.JobSession;
 import org.jbpm.job.Job;
 import org.jbpm.job.executor.JobExecutor;
 import org.jbpm.job.executor.JobExecutorThread;
 
 public class CustomJobExecutorThread extends JobExecutorThread {
 
-  public CustomJobExecutorThread(String name, JobExecutor jobExecutor, JbpmConfiguration jbpmConfiguration, int idleInterval, int maxIdleInterval, long maxLockTime, int maxHistory) {
-    super(name, jobExecutor, jbpmConfiguration, idleInterval, maxIdleInterval, maxLockTime, maxHistory);
+  private JobExecutor jobExecutor;
+
+  public CustomJobExecutorThread(String name, JobExecutor jobExecutor) {
+    super(name, jobExecutor);
+    this.jobExecutor = jobExecutor;
   }
 
   protected void executeJob(Job job) {
-    // intercept before
-    JobExecutorCustomizationTest.jobEvents.add("before");
+    JbpmContext jbpmContext = jobExecutor.getJbpmConfiguration().createJbpmContext();
     try {
-      super.executeJob(job);
-    } finally {
-      // intercept after
-      JobExecutorCustomizationTest.jobEvents.add("after");
+      JobSession jobSession = jbpmContext.getJobSession();
+      jobSession.reattachJob(job);
+
+      // custom stuff
+      job.getProcessInstance().getContextInstance().setVariable("custom", Boolean.TRUE);
+
+      if (job.execute(jbpmContext)) jobSession.deleteJob(job);
     }
+    catch (Exception e) {
+      e.printStackTrace();
+      jbpmContext.setRollbackOnly();
+    }
+    finally {
+      jbpmContext.close();
+    }
   }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/JobExecutorCustomizationTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/JobExecutorCustomizationTest.java	2009-07-01 20:20:45 UTC (rev 5182)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/seam/JobExecutorCustomizationTest.java	2009-07-02 01:05:31 UTC (rev 5183)
@@ -1,19 +1,12 @@
 package org.jbpm.seam;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import org.jbpm.db.AbstractDbTestCase;
-import org.jbpm.graph.def.ActionHandler;
 import org.jbpm.graph.def.ProcessDefinition;
-import org.jbpm.graph.exe.ExecutionContext;
+import org.jbpm.graph.exe.ProcessInstance;
 import org.jbpm.job.executor.JobExecutor;
 
 public class JobExecutorCustomizationTest extends AbstractDbTestCase {
 
-  static List jobEvents = new ArrayList();
-
   protected String getJbpmTestConfig() {
     return "org/jbpm/seam/custom.job.executor.jbpm.cfg.xml";
   }
@@ -27,36 +20,28 @@
     JobExecutor jobExecutor = getJbpmConfiguration().getJobExecutor();
     assertEquals(CustomJobExecutor.class, jobExecutor.getClass());
 
-    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition name='customjobexecution' initial='start'>" +
-        "  <node name='start'>" +
-        "    <transition to='end'>" +
-        "      <action async='true' class='" +
-        AsyncAction.class.getName() +
-        "' />" +
-        "    </transition>" +
-        "  </node>" +
-        "  <state name='end' />" +
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
+        "<process-definition name='custom job exec'>" +
+        "  <start-state name='start'>" +
+        "    <transition to='end'/>" +
+        "  </start-state>" +
+        "  <end-state name='end' async='true' />" +
         "</process-definition>");
     jbpmContext.deployProcessDefinition(processDefinition);
 
     newTransaction();
     try {
-      jbpmContext.newProcessInstanceForUpdate("customjobexecution");
+      ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("custom job exec");
+      processInstance.signal();
 
-      processJobs(20 * 1000);
-      List expectedJobEvents = Arrays.asList(new String[] { "before", "execute action", "after" });
-      assertEquals(expectedJobEvents, jobEvents);
+      processJobs(60 * 1000);
+      
+      processInstance = jbpmContext.loadProcessInstance(processInstance.getId());
+      assertEquals(Boolean.TRUE, processInstance.getContextInstance().getVariable("custom"));
     }
     finally {
       graphSession.deleteProcessDefinition(processDefinition.getId());
     }
   }
 
-  public static class AsyncAction implements ActionHandler {
-    private static final long serialVersionUID = 1L;
-
-    public void execute(ExecutionContext executionContext) throws Exception {
-      jobEvents.add("execute action");
-    }
-  }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/TimerEntityBean.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/TimerEntityBean.java	2009-07-01 20:20:45 UTC (rev 5182)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/TimerEntityBean.java	2009-07-02 01:05:31 UTC (rev 5183)
@@ -29,7 +29,8 @@
  * <h3>Environment</h3>
  * 
  * <p>
- * The environment entries and resources available for customization are summarized in the table below.
+ * The environment entries and resources available for customization are summarized in the table
+ * below.
  * </p>
  * 
  * <table border="1">
@@ -41,7 +42,8 @@
  * <tr>
  * <td><code>ejb/LocalCommandServiceBean</code></td>
  * <td>EJB Reference</td>
- * <td>Link to the local {@linkplain CommandServiceBean session bean} that executes timers on a separate jBPM context.</td>
+ * <td>Link to the local {@linkplain CommandServiceBean session bean} that executes timers on a
+ * separate jBPM context.</td>
  * </tr>
  * </table>
  * 
@@ -49,11 +51,11 @@
  * @author Alejandro Guizar
  * @author Fady Matar
  */
-public abstract class TimerEntityBean implements EntityBean, TimedObject
-{
+public abstract class TimerEntityBean implements EntityBean, TimedObject {
   private EntityContext entityContext;
   private LocalCommandService commandService;
 
+  private static final long serialVersionUID = 1L;
   private static final Log log = LogFactory.getLog(TimerEntityBean.class);
 
   public abstract Long getTimerId();
@@ -76,100 +78,83 @@
 
   public abstract void setDiscriminator(String discriminator);
 
-  public void ejbActivate()
-  {
-    try
-    {
+  public void ejbActivate() {
+    try {
       Context initial = new InitialContext();
-      LocalCommandServiceHome commandServiceHome = (LocalCommandServiceHome)initial.lookup("java:comp/env/ejb/LocalCommandServiceBean");
+      LocalCommandServiceHome commandServiceHome =
+          (LocalCommandServiceHome) initial.lookup("java:comp/env/ejb/LocalCommandServiceBean");
       commandService = commandServiceHome.create();
     }
-    catch (NamingException e)
-    {
+    catch (NamingException e) {
       throw new EJBException("failed to retrieve command service home", e);
     }
-    catch (CreateException e)
-    {
+    catch (CreateException e) {
       throw new EJBException("command service creation failed", e);
     }
   }
 
-  public void ejbPassivate()
-  {
+  public void ejbPassivate() {
     commandService = null;
   }
 
-  public void ejbRemove()
-  {
+  public void ejbRemove() {
     commandService = null;
   }
 
-  public void ejbLoad()
-  {
+  public void ejbLoad() {
   }
 
-  public void ejbStore()
-  {
+  public void ejbStore() {
   }
 
-  public void setEntityContext(EntityContext entityContext)
-  {
+  public void setEntityContext(EntityContext entityContext) {
     this.entityContext = entityContext;
   }
 
-  public void unsetEntityContext()
-  {
+  public void unsetEntityContext() {
     entityContext = null;
   }
 
   /**
-   * No ejbCreate operation is allowed. One approach of ensuring that an EJB is set as read-only.
+   * No ejbCreate operation is allowed, ensuring that this bean is set as read-only.
    * 
-   * @throws CreateException
+   * @throws CreateException if invoked
    */
-  public Long ejbCreate() throws CreateException
-  {
+  public Long ejbCreate() throws CreateException {
     throw new CreateException("direct creation of timer entities is prohibited");
   }
 
-  public void ejbPostCreate()
-  {
+  public void ejbPostCreate() {
   }
 
-  public void ejbTimeout(javax.ejb.Timer ejbTimer)
-  {
+  public void ejbTimeout(javax.ejb.Timer ejbTimer) {
     log.debug(ejbTimer + " fired");
-    TimerInfo timerInfo = (TimerInfo)ejbTimer.getInfo();
-    Timer timer = (Timer)commandService.execute(new ExecuteTimerCommand(timerInfo.getTimerId()));
+    TimerInfo timerInfo = (TimerInfo) ejbTimer.getInfo();
+    Timer timer = (Timer) commandService.execute(new ExecuteTimerCommand(timerInfo.getTimerId()));
     // if the timer has repeat
-    if (timer.getRepeat() != null)
-    {
+    if (timer.getRepeat() != null) {
       // create a new timer
       log.debug("scheduling timer for repeat on " + timer.getDueDate());
       createTimer(timer);
     }
   }
 
-  public void createTimer(org.jbpm.job.Timer timer)
-  {
+  public void createTimer(org.jbpm.job.Timer timer) {
     TimerService timerService = entityContext.getTimerService();
     javax.ejb.Timer ejbTimer = timerService.createTimer(timer.getDueDate(), new TimerInfo(timer));
     log.debug("created " + ejbTimer);
   }
 
-  public void cancelTimer(org.jbpm.job.Timer timer)
-  {
+  public void cancelTimer(org.jbpm.job.Timer timer) {
     long timerId = timer.getId();
     Collection timers = entityContext.getTimerService().getTimers();
     log.debug("retrieved " + timers.size() + " ejb timer(s) by id " + timerId);
 
     int count = 0;
-    for (Iterator i = timers.iterator(); i.hasNext();)
-    {
-      javax.ejb.Timer ejbTimer = (javax.ejb.Timer)i.next();
-      TimerInfo timerInfo = (TimerInfo)ejbTimer.getInfo();
-      if (timerInfo.getTimerId() == timerId)
-      {
+    for (Iterator i = timers.iterator(); i.hasNext();) {
+      javax.ejb.Timer ejbTimer = (javax.ejb.Timer) i.next();
+      TimerInfo timerInfo = (TimerInfo) ejbTimer.getInfo();
+      if (timerInfo.getTimerId() == timerId) {
         ejbTimer.cancel();
         ++count;
       }
@@ -177,18 +162,20 @@
     log.debug("canceled " + count + " ejb timer(s) by id " + timerId);
   }
 
-  public void cancelTimersByName(String timerName, Token token)
-  {
+  public void cancelTimersByName(String timerName, Token token) {
     Collection timers = entityContext.getTimerService().getTimers();
-    log.debug("retrieved " + timers.size() + " ejb timer(s) by name '" + timerName + "' for " + token);
+    log.debug("retrieved " +
+        timers.size() +
+        " ejb timer(s) by name '" +
+        timerName +
+        "' for " +
+        token);
 
     int count = 0;
-    for (Iterator i = timers.iterator(); i.hasNext();)
-    {
-      javax.ejb.Timer ejbTimer = (javax.ejb.Timer)i.next();
-      TimerInfo timerInfo = (TimerInfo)ejbTimer.getInfo();
-      if (timerInfo.matchesName(timerName, token))
-      {
+    for (Iterator i = timers.iterator(); i.hasNext();) {
+      javax.ejb.Timer ejbTimer = (javax.ejb.Timer) i.next();
+      TimerInfo timerInfo = (TimerInfo) ejbTimer.getInfo();
+      if (timerInfo.matchesName(timerName, token)) {
         ejbTimer.cancel();
         ++count;
       }
@@ -196,18 +183,15 @@
     log.debug("canceled " + count + " ejb timer(s) by name '" + timerName + "' for " + token);
   }
 
-  public void cancelTimersForProcessInstance(ProcessInstance processInstance)
-  {
+  public void cancelTimersForProcessInstance(ProcessInstance processInstance) {
     Collection timers = entityContext.getTimerService().getTimers();
     log.debug("retrieved " + timers.size() + " timer(s) for " + processInstance);
 
     int count = 0;
-    for (Iterator i = timers.iterator(); i.hasNext();)
-    {
-      javax.ejb.Timer ejbTimer = (javax.ejb.Timer)i.next();
-      TimerInfo timerInfo = (TimerInfo)ejbTimer.getInfo();
-      if (timerInfo.matchesProcessInstance(processInstance))
-      {
+    for (Iterator i = timers.iterator(); i.hasNext();) {
+      javax.ejb.Timer ejbTimer = (javax.ejb.Timer) i.next();
+      TimerInfo timerInfo = (TimerInfo) ejbTimer.getInfo();
+      if (timerInfo.matchesProcessInstance(processInstance)) {
         ejbTimer.cancel();
         ++count;
       }




More information about the jbpm-commits mailing list