[jbpm-commits] JBoss JBPM SVN: r6137 - in jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main: java/org/jbpm and 3 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Jan 27 02:59:50 EST 2010


Author: alex.guizar at jboss.com
Date: 2010-01-27 02:59:50 -0500 (Wed, 27 Jan 2010)
New Revision: 6137

Added:
   jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/
   jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/
   jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandService.java
   jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandServiceFactory.java
   jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/SaveJobExceptionCommand.java
Modified:
   jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/etc/jbpm.cfg.xml
   jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/CommandServiceBean.java
   jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/ExecuteJobCommand.java
Log:
JBPM-2691: save job exception in separate transaction - enterprise module

Modified: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/etc/jbpm.cfg.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/etc/jbpm.cfg.xml	2010-01-26 18:45:01 UTC (rev 6136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/etc/jbpm.cfg.xml	2010-01-27 07:59:50 UTC (rev 6137)
@@ -7,6 +7,7 @@
     <service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
     <service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
     <service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
+    <service name="command" factory="org.jbpm.command.jms.JmsCommandServiceFactory" />
   </jbpm-context>
 
   <!-- use the context class loader -->

Added: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandService.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandService.java	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandService.java	2010-01-27 07:59:50 UTC (rev 6137)
@@ -0,0 +1,94 @@
+/*
+ * 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.command.jms;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.jbpm.JbpmException;
+import org.jbpm.command.Command;
+import org.jbpm.command.CommandService;
+import org.jbpm.msg.jms.JmsMessageService;
+import org.jbpm.svc.Service;
+
+/**
+ * @author Alejandro Guizar
+ */
+public class JmsCommandService implements Service, CommandService {
+
+  private Connection connection;
+  private Session session;
+  private MessageProducer messageProducer;
+
+  public static final String SERVICE_NAME = "command";
+  
+  private static final long serialVersionUID = 1L;
+
+  private static final Log log = LogFactory.getLog(JmsMessageService.class);
+
+  public JmsCommandService(JmsCommandServiceFactory serviceFactory) throws JMSException {
+    connection = serviceFactory.getConnectionFactory().createConnection();
+    session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+    messageProducer = session.createProducer(serviceFactory.getDestination());
+  }
+
+  public Object execute(Command command) {
+    try {
+      Message message = session.createObjectMessage(command);
+      messageProducer.send(message);
+      return null;
+    }
+    catch (JMSException e) {
+      throw new JbpmException("could not send jms message", e);
+    }
+  }
+
+  public void close() {
+    try {
+      messageProducer.close();
+    }
+    catch (JMSException e) {
+      log.warn("could not close message producer", e);
+    }
+
+    try {
+      session.close();
+    }
+    catch (JMSException e) {
+      log.warn("could not close jms session", e);
+    }
+
+    try {
+      connection.close();
+    }
+    catch (JMSException e) {
+      log.warn("could not close jms connection", e);
+    }  
+  }
+
+}


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandService.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandServiceFactory.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandServiceFactory.java	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandServiceFactory.java	2010-01-27 07:59:50 UTC (rev 6137)
@@ -0,0 +1,111 @@
+/*
+ * 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.command.jms;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.jbpm.JbpmException;
+import org.jbpm.ejb.impl.CommandListenerBean;
+import org.jbpm.svc.Service;
+import org.jbpm.svc.ServiceFactory;
+
+/**
+ * The JMS command service leverages the reliable communication infrastructure
+ * available through JMS to deliver commands to the {@link CommandListenerBean}
+ * for asynchronous execution.
+ * 
+ * <h3>Configuration</h3>
+ * 
+ * The JMS command service factory provides the following configurable fields.
+ * <ul>
+ * <li><code>connectionFactoryJndiName</code></li>
+ * <li><code>destinationJndiName</code></li>
+ * </ul>
+ * 
+ * @author Alejandro Guizar
+ */
+public class JmsCommandServiceFactory implements ServiceFactory {
+
+  String connectionFactoryJndiName = "java:comp/env/jms/JbpmConnectionFactory";
+  String destinationJndiName = "java:comp/env/jms/CommandQueue";
+
+  private ConnectionFactory connectionFactory;
+  private Destination destination;
+
+  private static final long serialVersionUID = 1L;
+
+  public ConnectionFactory getConnectionFactory() {
+    if (connectionFactory == null) {
+      try {
+        connectionFactory =
+            (ConnectionFactory) lookup(connectionFactoryJndiName);
+      }
+      catch (NamingException e) {
+        throw new JbpmException(
+            "could not retrieve command connection factory", e);
+      }
+    }
+    return connectionFactory;
+  }
+
+  public Destination getDestination() {
+    if (destination == null) {
+      try {
+        destination = (Destination) lookup(destinationJndiName);
+      }
+      catch (NamingException e) {
+        throw new JbpmException("could not retrieve command destination", e);
+      }
+    }
+    return destination;
+  }
+
+  private static Object lookup(String name) throws NamingException {
+    Context initial = new InitialContext();
+    try {
+      return initial.lookup(name);
+    }
+    finally {
+      initial.close();
+    }
+  }
+
+  public Service openService() {
+    try {
+      return new JmsCommandService(this);
+    }
+    catch (JMSException e) {
+      throw new JbpmException("could not open command service", e);
+    }
+  }
+
+  public void close() {
+    connectionFactory = null;
+    destination = null;
+  }
+
+}


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandServiceFactory.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Modified: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/CommandServiceBean.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/CommandServiceBean.java	2010-01-26 18:45:01 UTC (rev 6136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/CommandServiceBean.java	2010-01-27 07:59:50 UTC (rev 6137)
@@ -40,14 +40,16 @@
 import org.jbpm.tx.TxService;
 
 /**
- * Stateless session bean that executes {@linkplain Command commands} by
- * calling their {@link Command#execute(JbpmContext) execute} method on
- * a separate {@link JbpmContext jBPM context}.
+ * Stateless session bean that executes {@linkplain Command commands} by calling
+ * their {@link Command#execute(JbpmContext) execute} method on a separate
+ * {@link JbpmContext jBPM context}.
  * 
  * <h3>Environment</h3>
  * 
- * <p>The environment entries and resources available for customization are
- * summarized in the table below.</p>
+ * <p>
+ * The environment entries and resources available for customization are
+ * summarized in the table below.
+ * </p>
  * 
  * <table border="1">
  * <tr>
@@ -58,17 +60,16 @@
  * <tr>
  * <td><code>JbpmCfgResource</code></td>
  * <td>Environment Entry</td>
- * <td>The classpath resource from which to read the {@linkplain 
- * JbpmConfiguration jBPM configuration}. Optional, defaults to <code>
- * jbpm.cfg.xml</code>.
- * </td>
+ * <td>The classpath resource from which to read the
+ * {@linkplain JbpmConfiguration jBPM configuration}. Optional, defaults to
+ * <code>
+ * jbpm.cfg.xml</code>.</td>
  * </tr>
  * <tr>
  * <td><code>ejb/TimerEntityBean</code></td>
  * <td>EJB Reference</td>
  * <td>Link to the local {@linkplain TimerEntityBean entity bean} that
- * implements the scheduler service. Required for processes that contain
- * timers.
+ * implements the scheduler service. Required for processes that contain timers.
  * </td>
  * </tr>
  * <tr>
@@ -76,26 +77,23 @@
  * <td>Resource Manager Reference</td>
  * <td>Logical name of the data source that provides JDBC connections to the
  * {@linkplain JtaDbPersistenceServiceFactory persistence service}. Must match
- * the <code>hibernate.connection.datasource</code> property in the Hibernate 
- * configuration file.
- * </td>
+ * the <code>hibernate.connection.datasource</code> property in the Hibernate
+ * configuration file.</td>
  * </tr>
  * <tr>
  * <td><code>jms/JbpmConnectionFactory</code></td>
  * <td>Resource Manager Reference</td>
- * <td>Logical name of the factory that provides JMS connections to the 
- * {@linkplain JmsMessageServiceFactory message service}. Required for 
- * processes that contain asynchronous continuations.
- * </td>
+ * <td>Logical name of the factory that provides JMS connections to the
+ * {@linkplain JmsMessageServiceFactory message service}. Required for processes
+ * that contain asynchronous continuations.</td>
  * </tr>
  * <tr>
  * <td><code>jms/JobQueue</code></td>
  * <td>Message Destination Reference</td>
- * <td>The message service sends job messages to the queue referenced here.
- * To ensure this is the same queue from which the {@linkplain JobListenerBean
- * job listener bean} receives messages, the <code>message-destination-link
- * </code> points to a common logical destination, <code>JobQueue</code>.
- * </td>
+ * <td>The message service sends job messages to the queue referenced here. To
+ * ensure this is the same queue from which the {@linkplain JobListenerBean job
+ * listener bean} receives messages, the <code>message-destination-link
+ * </code> points to a common logical destination, <code>JobQueue</code>.</td>
  * </tr>
  * </table>
  * 
@@ -111,29 +109,32 @@
   SessionContext sessionContext = null;
 
   /**
-   * creates a command service that will be used to execute the commands that 
-   * are passed in the execute method.  The command service will be build by 
-   * creating a jbpm configuration.  In case the environment key JbpmCfgResource
-   * is specified for this bean, that value will be used to resolve the jbpm 
-   * configuration file as a resource.  If that key is not configured, the default 
-   * jbpm configuration file will be used (jbpm.cfg.xml).
+   * creates a command service that will be used to execute the commands that
+   * are passed in the execute method. The command service will be build by
+   * creating a jbpm configuration. In case the environment key JbpmCfgResource
+   * is specified for this bean, that value will be used to resolve the jbpm
+   * configuration file as a resource. If that key is not configured, the
+   * default jbpm configuration file will be used (jbpm.cfg.xml).
    */
   public void ejbCreate() throws CreateException {
-    String jbpmCfgResource = null; 
+    String jbpmCfgResource = null;
     try {
       log.debug("getting jbpm configuration resource from the environment properties");
       Context initial = new InitialContext();
-      jbpmCfgResource = (String) initial.lookup("java:comp/env/JbpmCfgResource");
-    } catch (NamingException e) {
+      jbpmCfgResource =
+          (String) initial.lookup("java:comp/env/JbpmCfgResource");
+    }
+    catch (NamingException e) {
       log.debug("couldn't find configuration property JbpmCfgResource through JNDI");
     }
 
     if (log.isDebugEnabled()) {
-      if (jbpmCfgResource==null) {
+      if (jbpmCfgResource == null) {
         log.debug("getting default jbpm configuration resource (jbpm.cfg.xml)");
-      } else {
-        log.debug("getting jbpm configuration from resource "+jbpmCfgResource);
       }
+      else {
+        log.debug("getting jbpm configuration from resource " + jbpmCfgResource);
+      }
     }
 
     jbpmConfiguration = JbpmConfiguration.getInstance(jbpmCfgResource);
@@ -150,11 +151,14 @@
       if (txService.isRollbackOnly()) {
         sessionContext.setRollbackOnly();
       }
-    } catch (RuntimeException e) {
+    }
+    catch (RuntimeException e) {
       throw e;
-    } catch (Exception e) {
+    }
+    catch (Exception e) {
       throw new JbpmException("failed to execute " + command, e);
-    } finally {
+    }
+    finally {
       jbpmContext.close();
     }
     return result;
@@ -169,9 +173,11 @@
     jbpmConfiguration = null;
   }
 
-  public void ejbActivate() {}
+  public void ejbActivate() {
+  }
 
-  public void ejbPassivate() {}
+  public void ejbPassivate() {
+  }
 
   private static final Log log = LogFactory.getLog(CommandServiceBean.class);
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/ExecuteJobCommand.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/ExecuteJobCommand.java	2010-01-26 18:45:01 UTC (rev 6136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/ExecuteJobCommand.java	2010-01-27 07:59:50 UTC (rev 6137)
@@ -21,17 +21,11 @@
  */
 package org.jbpm.ejb.impl;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.jbpm.JbpmContext;
-import org.jbpm.JbpmException;
 import org.jbpm.command.Command;
+import org.jbpm.command.CommandService;
 import org.jbpm.graph.exe.ProcessInstance;
 import org.jbpm.job.Job;
-import org.jbpm.persistence.db.DbPersistenceService;
 
 /**
  * Individual job processing command.
@@ -72,27 +66,24 @@
     return job;
   }
 
-  static void executeJob(Job job, JbpmContext jbpmContext) {
-    log.debug("executing " + job);
+  private static void executeJob(Job job, JbpmContext jbpmContext)
+      throws Exception {
     try {
       if (job.execute(jbpmContext)) {
         jbpmContext.getJobSession().deleteJob(job);
       }
     }
     catch (Exception e) {
-      log.debug("exception while executing " + job, e);
-      if (!DbPersistenceService.isPersistenceException(e)) {
-        StringWriter memoryWriter = new StringWriter();
-        e.printStackTrace(new PrintWriter(memoryWriter));
-        job.setException(memoryWriter.toString());
-      }
-      else {
-        // prevent unsafe use of the session after an exception occurs
-        throw e instanceof RuntimeException ? (RuntimeException) e :
-        	new JbpmException("failed to execute " + job, e);
-      }
+      jbpmContext.setRollbackOnly();
+      saveJobException(job, jbpmContext, e);
     }
   }
 
-  private static Log log = LogFactory.getLog(ExecuteJobCommand.class);
+  private static void saveJobException(Job job, JbpmContext jbpmContext,
+      Exception exception) {
+    CommandService commandService =
+        (CommandService) jbpmContext.getServices().getService("command");
+    commandService.execute(new SaveJobExceptionCommand(job.getId(), exception));
+  }
+
 }

Added: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/SaveJobExceptionCommand.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/SaveJobExceptionCommand.java	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/SaveJobExceptionCommand.java	2010-01-27 07:59:50 UTC (rev 6137)
@@ -0,0 +1,66 @@
+/*
+ * 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.ejb.impl;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.jbpm.JbpmContext;
+import org.jbpm.command.Command;
+import org.jbpm.command.CommandService;
+import org.jbpm.db.JobSession;
+import org.jbpm.job.Job;
+
+/**
+ * @author Alejandro Guizar
+ */
+public class SaveJobExceptionCommand implements Command {
+  
+  private final long jobId;
+  private final Exception exception;
+
+  private static final long serialVersionUID = 1L;
+
+  public SaveJobExceptionCommand(long jobId, Exception exception) {
+    this.jobId = jobId;
+    this.exception = exception;
+  }
+
+  public Object execute(JbpmContext jbpmContext) throws Exception {
+    JobSession jobSession = jbpmContext.getJobSession();
+    Job job = jobSession.loadJob(jobId);
+
+    StringWriter out = new StringWriter();
+    exception.printStackTrace(new PrintWriter(out));
+    job.setException(out.toString());
+
+    int retries = job.getRetries();
+    if (retries > 0) {
+      job.setRetries(retries - 1);
+      CommandService commandService = (CommandService) jbpmContext.getServices()
+          .getService("command");
+      commandService.execute(new ExecuteJobCommand(jobId));
+    }
+    return job;
+  }
+
+}


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/SaveJobExceptionCommand.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native



More information about the jbpm-commits mailing list