mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.2 to HEAD
15888: ETHREEOH-2617: CIFS Authenticators should not try to initialize when disabled - removed init-method declaration from cifsAuthenticatorBase 15731: ENH-524: Use JobLockService to ensure that it is only possible for LDAP sync to run on one node at a time in a cluster - Ensures that if schedule is identical on all nodes, the LDAP sync will only be run on one 15694: Fix TransactionServiceImplTest broken by 15685 15685: ETHREEOH-983: Move RepoServerMgmt JMX editable capabilities into a sysAdmin subsystem for more consistent control and cluster support - New SysAdminParams interface exported by sysAdmin subsystem through which AuthenticationService and TransactionService get at the configured parameters - The repository read only flag does not apply to the system user so that we can still persist changes to that flag through JMX! - Removed sysAdminCache and supporting configuration. 15684: Improvements to cluster support for subsystems - When a subsystem is stopped on a node for editing it is completely destroyed and deregistered from JMX on other nodes - Should the subsystem be reactivated on those other nodes (e.g. called into by code) it will be reinitialized from persisted properties and thus stay in sync with the node being edited! 15683: Fixed potential concurrency issues in HeartBeat and LicenseComponent - Discovered during cluster testing - Because these components schedule triggers in a retrying transaction, they need to unschedule the triggers beforehand, just in case a retry has happened 15617: MOB-646: JMX edits now synchronized across cluster via JGroups - When you stop a component or subsystem, it is stopped across the entire cluster - When you restart it after editing properties, the component is reinitialized from the persisted properties across the cluster git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@16873 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -38,6 +38,8 @@ import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.attributes.Attribute;
|
||||
import org.alfresco.repo.attributes.LongAttributeValue;
|
||||
import org.alfresco.repo.attributes.MapAttributeValue;
|
||||
import org.alfresco.repo.lock.JobLockService;
|
||||
import org.alfresco.repo.lock.LockAcquisitionException;
|
||||
import org.alfresco.repo.management.subsystems.ActivateableBean;
|
||||
import org.alfresco.repo.management.subsystems.ChildApplicationContextManager;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
@@ -50,6 +52,8 @@ import org.alfresco.service.cmr.attributes.AttributeService;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.AbstractLifecycleBean;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -65,7 +69,8 @@ import org.springframework.context.ApplicationEvent;
|
||||
* the 'chain' of application contexts, managed by a {@link ChildApplicationContextManager}, and compares its
|
||||
* timestamped user and group information with the local users and groups last retrieved from the same source. Any
|
||||
* updates and additions made to those users and groups are applied to the local copies. The ordering of each
|
||||
* {@link UserRegistry} in the chain determines its precedence when it comes to user and group name collisions.
|
||||
* {@link UserRegistry} in the chain determines its precedence when it comes to user and group name collisions. The
|
||||
* {@link JobLockService} is used to ensure that in a cluster, no two nodes actually run a synchronize at the same time.
|
||||
* <p>
|
||||
* The <code>force</code> argument determines whether a complete or partial set of information is queried from the
|
||||
* {@link UserRegistry}. When <code>true</code> then <i>all</i> users and groups are queried. With this complete set of
|
||||
@@ -84,12 +89,20 @@ import org.springframework.context.ApplicationEvent;
|
||||
*/
|
||||
public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean implements UserRegistrySynchronizer
|
||||
{
|
||||
/** The number of users / groups we add at a time in a transaction **/
|
||||
|
||||
/** The number of users / groups we add at a time in a transaction *. */
|
||||
private static final int BATCH_SIZE = 10;
|
||||
|
||||
/** The logger. */
|
||||
private static final Log logger = LogFactory.getLog(ChainingUserRegistrySynchronizer.class);
|
||||
|
||||
/** The name of the lock used to ensure that a synchronize does not run on more than one node at the same time. */
|
||||
private static final QName LOCK_QNAME = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI,
|
||||
"ChainingUserRegistrySynchronizer");
|
||||
|
||||
/** The maximum time this lock will be held for (1 day). */
|
||||
private static final long LOCK_TTL = 1000 * 60 * 60 * 24;
|
||||
|
||||
/** The path in the attribute service below which we persist attributes. */
|
||||
private static final String ROOT_ATTRIBUTE_PATH = ".ChainingUserRegistrySynchronizer";
|
||||
|
||||
@@ -117,13 +130,16 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
||||
/** The retrying transaction helper. */
|
||||
private RetryingTransactionHelper retryingTransactionHelper;
|
||||
|
||||
/** Should we trigger a differential sync when missing people log in? */
|
||||
/** The job lock service. */
|
||||
private JobLockService jobLockService;
|
||||
|
||||
/** Should we trigger a differential sync when missing people log in?. */
|
||||
private boolean syncWhenMissingPeopleLogIn = true;
|
||||
|
||||
/** Should we trigger a differential sync on startup? */
|
||||
/** Should we trigger a differential sync on startup?. */
|
||||
private boolean syncOnStartup = true;
|
||||
|
||||
/** Should we auto create a missing person on log in? */
|
||||
/** Should we auto create a missing person on log in?. */
|
||||
private boolean autoCreatePeopleOnLogin = true;
|
||||
|
||||
/**
|
||||
@@ -193,7 +209,18 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls whether we auto create a missing person on log in
|
||||
* Sets the job lock service.
|
||||
*
|
||||
* @param jobLockService
|
||||
* the job lock service
|
||||
*/
|
||||
public void setJobLockService(JobLockService jobLockService)
|
||||
{
|
||||
this.jobLockService = jobLockService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls whether we auto create a missing person on log in.
|
||||
*
|
||||
* @param autoCreatePeopleOnLogin
|
||||
* <code>true</code> if we should auto create a missing person on log in
|
||||
@@ -204,7 +231,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls whether we trigger a differential sync when missing people log in
|
||||
* Controls whether we trigger a differential sync when missing people log in.
|
||||
*
|
||||
* @param syncWhenMissingPeopleLogIn
|
||||
* <codetrue</code> if we should trigger a sync when missing people log in
|
||||
@@ -215,7 +242,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls whether we trigger a differential sync when the subsystem starts up
|
||||
* Controls whether we trigger a differential sync when the subsystem starts up.
|
||||
*
|
||||
* @param syncOnStartup
|
||||
* <codetrue</code> if we should trigger a sync on startup
|
||||
@@ -231,10 +258,36 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
||||
*/
|
||||
public void synchronize(boolean force, boolean splitTxns)
|
||||
{
|
||||
// First, try to obtain a lock to ensure we are the only node trying to run this job
|
||||
try
|
||||
{
|
||||
if (splitTxns)
|
||||
{
|
||||
// If this is an automated sync on startup or scheduled sync, don't even wait around for the lock.
|
||||
// Assume the sync will be completed on another node.
|
||||
this.jobLockService.getTransactionalLock(ChainingUserRegistrySynchronizer.LOCK_QNAME,
|
||||
ChainingUserRegistrySynchronizer.LOCK_TTL, 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this is a login-triggered sync, give it a few retries before giving up
|
||||
this.jobLockService.getTransactionalLock(ChainingUserRegistrySynchronizer.LOCK_QNAME,
|
||||
ChainingUserRegistrySynchronizer.LOCK_TTL, 3000, 10);
|
||||
}
|
||||
}
|
||||
catch (LockAcquisitionException e)
|
||||
{
|
||||
// Don't proceed with the sync if it is running on another node
|
||||
ChainingUserRegistrySynchronizer.logger
|
||||
.warn("User registry synchronization already running in another thread. Synchronize aborted");
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> visitedZoneIds = new TreeSet<String>();
|
||||
Collection<String> instanceIds = this.applicationContextManager.getInstanceIds();
|
||||
|
||||
// Work out the set of all zone IDs in the authentication chain so that we can decide which users / groups need
|
||||
// Work out the set of all zone IDs in the authentication chain so that we can decide which users / groups
|
||||
// need
|
||||
// 're-zoning'
|
||||
Set<String> allZoneIds = new TreeSet<String>();
|
||||
for (String id : instanceIds)
|
||||
@@ -894,6 +947,10 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
||||
return zones;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.util.AbstractLifecycleBean#onBootstrap(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event)
|
||||
{
|
||||
@@ -928,6 +985,10 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.util.AbstractLifecycleBean#onShutdown(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event)
|
||||
{
|
||||
|
Reference in New Issue
Block a user