mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged BRANCHES/V3.4 to HEAD:
24356: It's possible for a persisted action to be removed during the transaction, so have the ActionTrackingService ensure the node still exists before doing the async update of the details (ALF-5745) 24374: ALF-5744 - Retry the add aspect to avoid failures due to concurrent node updates git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@24931 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -114,6 +114,9 @@
|
|||||||
<property name="transactionService">
|
<property name="transactionService">
|
||||||
<ref bean="TransactionService" />
|
<ref bean="TransactionService" />
|
||||||
</property>
|
</property>
|
||||||
|
<property name="nodeService">
|
||||||
|
<ref bean="NodeService" />
|
||||||
|
</property>
|
||||||
<property name="runtimeActionService">
|
<property name="runtimeActionService">
|
||||||
<ref bean="actionService" />
|
<ref bean="actionService" />
|
||||||
</property>
|
</property>
|
||||||
@@ -330,6 +333,12 @@
|
|||||||
<property name="nodeService">
|
<property name="nodeService">
|
||||||
<ref bean="NodeService" />
|
<ref bean="NodeService" />
|
||||||
</property>
|
</property>
|
||||||
|
<property name="transactionService">
|
||||||
|
<ref bean="TransactionService" />
|
||||||
|
</property>
|
||||||
|
<property name="ignoreLock">
|
||||||
|
<value>false</value>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="remove-features" class="org.alfresco.repo.action.executer.RemoveFeaturesActionExecuter" parent="action-executer">
|
<bean id="remove-features" class="org.alfresco.repo.action.executer.RemoveFeaturesActionExecuter" parent="action-executer">
|
||||||
|
@@ -39,6 +39,7 @@ import org.alfresco.service.cmr.action.CancellableAction;
|
|||||||
import org.alfresco.service.cmr.action.ExecutionDetails;
|
import org.alfresco.service.cmr.action.ExecutionDetails;
|
||||||
import org.alfresco.service.cmr.action.ExecutionSummary;
|
import org.alfresco.service.cmr.action.ExecutionSummary;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
@@ -56,6 +57,7 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
|
|||||||
private static Log logger = LogFactory.getLog(ActionTrackingServiceImpl.class);
|
private static Log logger = LogFactory.getLog(ActionTrackingServiceImpl.class);
|
||||||
|
|
||||||
private SimpleCache<String, ExecutionDetails> executingActionsCache;
|
private SimpleCache<String, ExecutionDetails> executingActionsCache;
|
||||||
|
private NodeService nodeService;
|
||||||
private TransactionService transactionService;
|
private TransactionService transactionService;
|
||||||
private RuntimeActionService runtimeActionService;
|
private RuntimeActionService runtimeActionService;
|
||||||
|
|
||||||
@@ -78,6 +80,16 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
|
|||||||
this.transactionService = transactionService;
|
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
|
* Set the runtime action service
|
||||||
*
|
*
|
||||||
@@ -139,7 +151,7 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
|
|||||||
action.setExecutionFailureMessage(null);
|
action.setExecutionFailureMessage(null);
|
||||||
|
|
||||||
// Do we need to update the persisted details?
|
// 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
|
// Make sure we re-fetch the latest action details and save
|
||||||
// this version back into the repository
|
// this version back into the repository
|
||||||
@@ -164,8 +176,15 @@ public class ActionTrackingServiceImpl implements ActionTrackingService
|
|||||||
{
|
{
|
||||||
public Action doWork() throws Exception
|
public Action doWork() throws Exception
|
||||||
{
|
{
|
||||||
// Grab the latest version of the
|
// Ensure the action persisted node still exists, and wasn't deleted
|
||||||
// action
|
// 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
|
ActionImpl action = (ActionImpl) runtimeActionService
|
||||||
.createAction(actionNode);
|
.createAction(actionNode);
|
||||||
|
|
||||||
|
@@ -24,12 +24,14 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.repo.action.ParameterDefinitionImpl;
|
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.Action;
|
||||||
import org.alfresco.service.cmr.action.ParameterDefinition;
|
import org.alfresco.service.cmr.action.ParameterDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add features action executor implementation.
|
* Add features action executor implementation.
|
||||||
@@ -49,16 +51,29 @@ public class AddFeaturesActionExecuter extends ActionExecuterAbstractBase
|
|||||||
*/
|
*/
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
|
|
||||||
|
/** Transaction Service, used for retrying operations */
|
||||||
|
private TransactionService transactionService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the node service
|
* Set the node service
|
||||||
*
|
*
|
||||||
* @param nodeService the node service
|
* @param nodeService the node service
|
||||||
*/
|
*/
|
||||||
public void setNodeService(NodeService nodeService)
|
public void setNodeService(NodeService nodeService)
|
||||||
{
|
{
|
||||||
this.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
|
* 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)
|
* @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)
|
if (this.nodeService.exists(actionedUponNodeRef))
|
||||||
{
|
{
|
||||||
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
|
transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||||
QName aspectQName = null;
|
new RetryingTransactionCallback<Void>() {
|
||||||
|
public Void execute() throws Throwable {
|
||||||
Map<String, Serializable> paramValues = ruleAction.getParameterValues();
|
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
|
||||||
for (Map.Entry<String, Serializable> entry : paramValues.entrySet())
|
QName aspectQName = null;
|
||||||
{
|
|
||||||
if (entry.getKey().equals(PARAM_ASPECT_NAME) == true)
|
if(! nodeService.exists(actionedUponNodeRef))
|
||||||
{
|
{
|
||||||
aspectQName = (QName)entry.getValue();
|
// Node has gone away, skip
|
||||||
}
|
return null;
|
||||||
else
|
}
|
||||||
{
|
|
||||||
// Must be an adhoc property
|
// Build the aspect details
|
||||||
QName propertyQName = QName.createQName(entry.getKey());
|
Map<String, Serializable> paramValues = ruleAction.getParameterValues();
|
||||||
Serializable propertyValue = entry.getValue();
|
for (Map.Entry<String, Serializable> entry : paramValues.entrySet())
|
||||||
properties.put(propertyQName, propertyValue);
|
{
|
||||||
}
|
if (entry.getKey().equals(PARAM_ASPECT_NAME) == true)
|
||||||
}
|
{
|
||||||
|
aspectQName = (QName)entry.getValue();
|
||||||
// Add the aspect
|
}
|
||||||
this.nodeService.addAspect(actionedUponNodeRef, aspectQName, properties);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user