diff --git a/config/alfresco/action-services-context.xml b/config/alfresco/action-services-context.xml
index 86b822260a..8807738d60 100644
--- a/config/alfresco/action-services-context.xml
+++ b/config/alfresco/action-services-context.xml
@@ -114,6 +114,9 @@
+
+
+
@@ -330,6 +333,12 @@
+
+
+
+
+ false
+
diff --git a/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java b/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java
index 9e10f96733..4b619126d5 100644
--- a/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java
+++ b/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java
@@ -39,6 +39,7 @@ import org.alfresco.service.cmr.action.CancellableAction;
import org.alfresco.service.cmr.action.ExecutionDetails;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -56,6 +57,7 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
private static Log logger = LogFactory.getLog(ActionTrackingServiceImpl.class);
private SimpleCache executingActionsCache;
+ private NodeService nodeService;
private TransactionService transactionService;
private RuntimeActionService runtimeActionService;
@@ -78,6 +80,16 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
this.transactionService = transactionService;
}
+ /**
+ * Set the node service
+ *
+ * @param nodeService the node service
+ */
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
/**
* Set the runtime action service
*
@@ -139,7 +151,7 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
action.setExecutionFailureMessage(null);
// Do we need to update the persisted details?
- if (action.getNodeRef() != null)
+ if (action.getNodeRef() != null && nodeService.exists(action.getNodeRef()))
{
// Make sure we re-fetch the latest action details and save
// this version back into the repository
@@ -164,8 +176,15 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
{
public Action doWork() throws Exception
{
- // Grab the latest version of the
- // action
+ // Ensure the action persisted node still exists, and wasn't deleted
+ // between when it loaded running and now
+ if( !nodeService.exists(actionNode) )
+ {
+ // Persisted node has gone, nothing to update
+ return null;
+ }
+
+ // Grab the latest version of the action
ActionImpl action = (ActionImpl) runtimeActionService
.createAction(actionNode);
diff --git a/source/java/org/alfresco/repo/action/executer/AddFeaturesActionExecuter.java b/source/java/org/alfresco/repo/action/executer/AddFeaturesActionExecuter.java
index 066054b426..352332bbae 100644
--- a/source/java/org/alfresco/repo/action/executer/AddFeaturesActionExecuter.java
+++ b/source/java/org/alfresco/repo/action/executer/AddFeaturesActionExecuter.java
@@ -24,12 +24,14 @@ import java.util.List;
import java.util.Map;
import org.alfresco.repo.action.ParameterDefinitionImpl;
+import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
+import org.alfresco.service.transaction.TransactionService;
/**
* Add features action executor implementation.
@@ -49,16 +51,29 @@ public class AddFeaturesActionExecuter extends ActionExecuterAbstractBase
*/
private NodeService nodeService;
+ /** Transaction Service, used for retrying operations */
+ private TransactionService transactionService;
+
/**
* Set the node service
*
- * @param nodeService the node service
+ * @param nodeService the node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
+ /**
+ * Set the transaction service
+ *
+ * @param transactionService the transaction service
+ */
+ public void setTransactionService(TransactionService transactionService)
+ {
+ this.transactionService = transactionService;
+ }
+
/**
* Adhoc properties are allowed for this executor
*/
@@ -71,32 +86,46 @@ public class AddFeaturesActionExecuter extends ActionExecuterAbstractBase
/**
* @see org.alfresco.repo.action.executer.ActionExecuter#execute(org.alfresco.service.cmr.repository.NodeRef, NodeRef)
*/
- public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef)
+ public void executeImpl(final Action ruleAction, final NodeRef actionedUponNodeRef)
{
- if (this.nodeService.exists(actionedUponNodeRef) == true)
- {
- Map properties = new HashMap();
- QName aspectQName = null;
-
- Map paramValues = ruleAction.getParameterValues();
- for (Map.Entry entry : paramValues.entrySet())
- {
- if (entry.getKey().equals(PARAM_ASPECT_NAME) == true)
- {
- aspectQName = (QName)entry.getValue();
- }
- else
- {
- // Must be an adhoc property
- QName propertyQName = QName.createQName(entry.getKey());
- Serializable propertyValue = entry.getValue();
- properties.put(propertyQName, propertyValue);
- }
- }
-
- // Add the aspect
- this.nodeService.addAspect(actionedUponNodeRef, aspectQName, properties);
- }
+ if (this.nodeService.exists(actionedUponNodeRef))
+ {
+ transactionService.getRetryingTransactionHelper().doInTransaction(
+ new RetryingTransactionCallback() {
+ public Void execute() throws Throwable {
+ Map properties = new HashMap();
+ QName aspectQName = null;
+
+ if(! nodeService.exists(actionedUponNodeRef))
+ {
+ // Node has gone away, skip
+ return null;
+ }
+
+ // Build the aspect details
+ Map paramValues = ruleAction.getParameterValues();
+ for (Map.Entry entry : paramValues.entrySet())
+ {
+ if (entry.getKey().equals(PARAM_ASPECT_NAME) == true)
+ {
+ aspectQName = (QName)entry.getValue();
+ }
+ else
+ {
+ // Must be an adhoc property
+ QName propertyQName = QName.createQName(entry.getKey());
+ Serializable propertyValue = entry.getValue();
+ properties.put(propertyQName, propertyValue);
+ }
+ }
+
+ // Add the aspect
+ nodeService.addAspect(actionedUponNodeRef, aspectQName, properties);
+ return null;
+ }
+ }
+ );
+ }
}
/**