APPS-832: prevent multiple nodes from initializing the custom properties

This commit is contained in:
ehardon
2021-03-03 15:10:33 +02:00
parent 87625c3592
commit e191018231
2 changed files with 108 additions and 22 deletions

View File

@@ -806,6 +806,7 @@
<bean id="recordsManagementAdminService" class="org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminServiceImpl" parent="recordsManagementAdminBase"> <bean id="recordsManagementAdminService" class="org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminServiceImpl" parent="recordsManagementAdminBase">
<property name="relationshipService" ref="RelationshipService" /> <property name="relationshipService" ref="RelationshipService" />
<property name="transactionService" ref="transactionService"/> <property name="transactionService" ref="transactionService"/>
<property name="jobLockService" ref="jobLockService"/>
<property name="customisableTypes"> <property name="customisableTypes">
<list> <list>
<value>rma:recordCategory</value> <value>rma:recordCategory</value>

View File

@@ -37,6 +37,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
@@ -53,6 +54,9 @@ import org.alfresco.repo.dictionary.M2Aspect;
import org.alfresco.repo.dictionary.M2Constraint; import org.alfresco.repo.dictionary.M2Constraint;
import org.alfresco.repo.dictionary.M2Model; import org.alfresco.repo.dictionary.M2Model;
import org.alfresco.repo.dictionary.M2Property; import org.alfresco.repo.dictionary.M2Property;
import org.alfresco.repo.lock.JobLockService;
import org.alfresco.repo.lock.JobLockService.JobLockRefreshCallback;
import org.alfresco.repo.lock.LockAcquisitionException;
import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.policy.annotation.Behaviour; import org.alfresco.repo.policy.annotation.Behaviour;
@@ -71,6 +75,7 @@ import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
@@ -112,6 +117,7 @@ public class RecordsManagementAdminServiceImpl extends RecordsManagementAdminBas
private static final String PARAM_ALLOWED_VALUES = "allowedValues"; private static final String PARAM_ALLOWED_VALUES = "allowedValues";
private static final String PARAM_CASE_SENSITIVE = "caseSensitive"; private static final String PARAM_CASE_SENSITIVE = "caseSensitive";
private static final String PARAM_MATCH_LOGIC = "matchLogic"; private static final String PARAM_MATCH_LOGIC = "matchLogic";
private static final long DEFAULT_TIME = 30000L;
/** Relationship service */ /** Relationship service */
private RelationshipService relationshipService; private RelationshipService relationshipService;
@@ -119,6 +125,9 @@ public class RecordsManagementAdminServiceImpl extends RecordsManagementAdminBas
/** Transaction service */ /** Transaction service */
private TransactionService transactionService; private TransactionService transactionService;
/** Job Lock service */
private JobLockService jobLockService;
/** List of types that can be customisable */ /** List of types that can be customisable */
private List<QName> pendingCustomisableTypes; private List<QName> pendingCustomisableTypes;
private Map<QName, QName> customisableTypes; private Map<QName, QName> customisableTypes;
@@ -152,6 +161,14 @@ public class RecordsManagementAdminServiceImpl extends RecordsManagementAdminBas
return this.relationshipService; return this.relationshipService;
} }
/**
* @param jobLockService The Job Lock service
*/
public void setJobLockService(JobLockService jobLockService)
{
this.jobLockService = jobLockService;
}
/** /**
* Indicate that this application content listener must be executed with the lowest * Indicate that this application content listener must be executed with the lowest
* precedence. (ie last) * precedence. (ie last)
@@ -172,6 +189,16 @@ public class RecordsManagementAdminServiceImpl extends RecordsManagementAdminBas
@Override @Override
public void onApplicationEvent(ContextRefreshedEvent event) public void onApplicationEvent(ContextRefreshedEvent event)
{ {
final LockCallback lockCallback = new LockCallback();
// try and get the lock
String lockToken = getLock();
if (lockToken != null)
{
try
{
jobLockService.refreshLock(lockToken, getLockQName(), DEFAULT_TIME, lockCallback);
if (!isCustomMapInit && getDictionaryService().getAllModels().contains(RM_CUSTOM_MODEL)) if (!isCustomMapInit && getDictionaryService().getAllModels().contains(RM_CUSTOM_MODEL))
{ {
// run as System on bootstrap // run as System on bootstrap
@@ -195,6 +222,64 @@ public class RecordsManagementAdminServiceImpl extends RecordsManagementAdminBas
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());
} }
} }
finally
{
try
{
lockCallback.running.set(false);
jobLockService.releaseLock(lockToken, getLockQName());
}
catch (LockAcquisitionException e)
{
// Ignore
if (logger.isDebugEnabled())
{
logger.debug("Lock release failed: " + getLockQName() + ": " + lockToken + "("
+ e.getMessage() + ")");
}
}
}
}
}
private QName getLockQName()
{
return QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, this.getClass().getName());
}
/**
* Attempts to get the lock. If the lock couldn't be taken, then <tt>null</tt> is returned.
*
* @return Returns the lock token or <tt>null</tt>
*/
private String getLock()
{
try
{
return jobLockService.getLock(getLockQName(), DEFAULT_TIME);
}
catch (LockAcquisitionException e)
{
return null;
}
}
private class LockCallback implements JobLockRefreshCallback
{
final AtomicBoolean running = new AtomicBoolean(true);
@Override
public boolean isActive()
{
return running.get();
}
@Override
public void lockReleased()
{
running.set(false);
}
}
/** /**
* Helper method to indicate whether the custom map is initialised or not. * Helper method to indicate whether the custom map is initialised or not.