mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.2 to HEAD
17462: ETHREEOH-3346: New meaning to synchronization.synchronizeChangesOnly property - In the LDAP sync performance optimizations we always used the differential queries to determine the users and groups to be updated. Deletions were determined by a separate query. - This meant that if you ever did want to force the update of all users it wasn't possible. - So now when the flag is false it means don't use differential queries in the scheduled sync job. - The scheduled job now processes deletions regardless. - The default value for the property is now true. 17431: ETHREEOH-3274: Refix NTLM support for share - Fixed NPE introduced by ETHREEOH-2767 - Made web.xml validate against schema for JBoss - Reintroduced missing open comment in webscript-framework-config-custom.xml.sample 17426: ETHREEOH-2997: Fix ticket parameter passing into NTLM/Kerberos WebDAV authentication filters - A NPE was stopping it from working 17425: ETHREEOH-3282: Fixed NPE preventing upload from working with NTLM SSO enabled 17368: ETHREEOH-3197: Use utf8_bin collation in MySQL out of the box to avoid problems with comparison of accented characters 17361: ETHREEOH-3276: Don't attempt to start an LDAP sync when the repository is read only 17347: ETHREEOH-3206: Fix LocalFeedTaskProcessor to work with JBoss 5 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@17464 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -56,8 +56,8 @@
|
|||||||
<property name="applicationContextManager">
|
<property name="applicationContextManager">
|
||||||
<ref bean="Authentication" />
|
<ref bean="Authentication" />
|
||||||
</property>
|
</property>
|
||||||
<property name="retryingTransactionHelper">
|
<property name="transactionService">
|
||||||
<ref bean="retryingTransactionHelper" />
|
<ref bean="transactionService" />
|
||||||
</property>
|
</property>
|
||||||
<property name="ruleService">
|
<property name="ruleService">
|
||||||
<ref bean="ruleService" />
|
<ref bean="ruleService" />
|
||||||
|
@@ -2,12 +2,14 @@
|
|||||||
# This properties file is used to configure user registry syncronisation (e.g. LDAP)
|
# This properties file is used to configure user registry syncronisation (e.g. LDAP)
|
||||||
#
|
#
|
||||||
|
|
||||||
# Should the scheduled sync job only query users and groups changed since the
|
# Should the scheduled sync job use differential or full queries on the user
|
||||||
# last sync? Note that when true, the sync job will not be able to detect which
|
# registries to determine the set of local users to be updated? When true,
|
||||||
# users or groups have been removed from the directory (but obviously group
|
# each user registry is only queried for those users and groups modified since
|
||||||
# membership changes would still be reflected). When false, a more regular
|
# the most recent modification date of all the objects last queried from that
|
||||||
# differential sync on login can still be enabled.
|
# same source. When <code>false</code> then <i>all</i> users and groups are
|
||||||
synchronization.synchronizeChangesOnly=false
|
# queried from the user registry and updated locally. Nevertheless, a separate
|
||||||
|
# query will be run by the scheduled sync job to determine deletions.
|
||||||
|
synchronization.synchronizeChangesOnly=true
|
||||||
|
|
||||||
# The cron expression defining when imports should take place
|
# The cron expression defining when imports should take place
|
||||||
synchronization.import.cron=0 0 0 * * ?
|
synchronization.import.cron=0 0 0 * * ?
|
||||||
|
@@ -47,6 +47,9 @@ import org.alfresco.service.cmr.repository.NodeService;
|
|||||||
import org.alfresco.service.cmr.site.SiteService;
|
import org.alfresco.service.cmr.site.SiteService;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||||
@@ -59,7 +62,7 @@ import freemarker.template.DefaultObjectWrapper;
|
|||||||
/**
|
/**
|
||||||
* The local (ie. not grid) feed task processor is responsible for processing the individual feed job
|
* The local (ie. not grid) feed task processor is responsible for processing the individual feed job
|
||||||
*/
|
*/
|
||||||
public class LocalFeedTaskProcessor extends FeedTaskProcessor
|
public class LocalFeedTaskProcessor extends FeedTaskProcessor implements ApplicationContextAware
|
||||||
{
|
{
|
||||||
private static final Log logger = LogFactory.getLog(LocalFeedTaskProcessor.class);
|
private static final Log logger = LogFactory.getLog(LocalFeedTaskProcessor.class);
|
||||||
|
|
||||||
@@ -74,6 +77,7 @@ public class LocalFeedTaskProcessor extends FeedTaskProcessor
|
|||||||
private String defaultEncoding;
|
private String defaultEncoding;
|
||||||
private List<String> templateSearchPaths;
|
private List<String> templateSearchPaths;
|
||||||
private boolean useRemoteCallbacks;
|
private boolean useRemoteCallbacks;
|
||||||
|
private ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
||||||
|
|
||||||
// used to start/end/commit transaction
|
// used to start/end/commit transaction
|
||||||
// note: currently assumes that all dao services are configured with this mapper / data source
|
// note: currently assumes that all dao services are configured with this mapper / data source
|
||||||
@@ -129,6 +133,11 @@ public class LocalFeedTaskProcessor extends FeedTaskProcessor
|
|||||||
this.sqlMapper = sqlMapper;
|
this.sqlMapper = sqlMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
||||||
|
{
|
||||||
|
this.resolver = applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
public void startTransaction() throws SQLException
|
public void startTransaction() throws SQLException
|
||||||
{
|
{
|
||||||
sqlMapper.startTransaction();
|
sqlMapper.startTransaction();
|
||||||
@@ -307,7 +316,6 @@ public class LocalFeedTaskProcessor extends FeedTaskProcessor
|
|||||||
// Helper to return a list of resource document paths based on a search pattern.
|
// Helper to return a list of resource document paths based on a search pattern.
|
||||||
private List<String> getPaths(String pattern, String classPath) throws IOException
|
private List<String> getPaths(String pattern, String classPath) throws IOException
|
||||||
{
|
{
|
||||||
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
|
||||||
Resource[] resources = resolver.getResources(pattern);
|
Resource[] resources = resolver.getResources(pattern);
|
||||||
List<String> documentPaths = new ArrayList<String>(resources.length);
|
List<String> documentPaths = new ArrayList<String>(resources.length);
|
||||||
for (Resource resource : resources)
|
for (Resource resource : resources)
|
||||||
|
@@ -59,6 +59,7 @@ import org.alfresco.service.cmr.security.AuthorityType;
|
|||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.util.AbstractLifecycleBean;
|
import org.alfresco.util.AbstractLifecycleBean;
|
||||||
import org.alfresco.util.PropertyMap;
|
import org.alfresco.util.PropertyMap;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@@ -132,6 +133,9 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
/** The attribute service. */
|
/** The attribute service. */
|
||||||
private AttributeService attributeService;
|
private AttributeService attributeService;
|
||||||
|
|
||||||
|
/** The transaction service. */
|
||||||
|
private TransactionService transactionService;
|
||||||
|
|
||||||
/** The retrying transaction helper. */
|
/** The retrying transaction helper. */
|
||||||
private RetryingTransactionHelper retryingTransactionHelper;
|
private RetryingTransactionHelper retryingTransactionHelper;
|
||||||
|
|
||||||
@@ -215,14 +219,15 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the retrying transaction helper.
|
* Sets the transaction service.
|
||||||
*
|
*
|
||||||
* @param retryingTransactionHelper
|
* @param transactionService
|
||||||
* the new retrying transaction helper
|
* the transaction service
|
||||||
*/
|
*/
|
||||||
public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
|
public void setTransactionService(TransactionService transactionService)
|
||||||
{
|
{
|
||||||
this.retryingTransactionHelper = retryingTransactionHelper;
|
this.transactionService = transactionService;
|
||||||
|
this.retryingTransactionHelper = transactionService.getRetryingTransactionHelper();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -315,10 +320,18 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.security.sync.UserRegistrySynchronizer#synchronize(boolean, boolean)
|
* @see org.alfresco.repo.security.sync.UserRegistrySynchronizer#synchronize(boolean, boolean, boolean)
|
||||||
*/
|
*/
|
||||||
public void synchronize(boolean force, boolean splitTxns)
|
public void synchronize(boolean forceUpdate, boolean allowDeletions, boolean splitTxns)
|
||||||
{
|
{
|
||||||
|
// Don't proceed with the sync if the repository is read only
|
||||||
|
if (this.transactionService.isReadOnly())
|
||||||
|
{
|
||||||
|
ChainingUserRegistrySynchronizer.logger
|
||||||
|
.warn("Unable to proceed with user registry synchronization. Repository is read only.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String lockToken = null;
|
String lockToken = null;
|
||||||
|
|
||||||
// Let's ensure all exceptions get logged
|
// Let's ensure all exceptions get logged
|
||||||
@@ -380,10 +393,10 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
ChainingUserRegistrySynchronizer.logger
|
ChainingUserRegistrySynchronizer.logger
|
||||||
.info("Synchronizing users and groups with user registry '" + id + "'");
|
.info("Synchronizing users and groups with user registry '" + id + "'");
|
||||||
}
|
}
|
||||||
if (force && ChainingUserRegistrySynchronizer.logger.isWarnEnabled())
|
if (allowDeletions && ChainingUserRegistrySynchronizer.logger.isWarnEnabled())
|
||||||
{
|
{
|
||||||
ChainingUserRegistrySynchronizer.logger
|
ChainingUserRegistrySynchronizer.logger
|
||||||
.warn("Forced synchronization with user registry '"
|
.warn("Full synchronization with user registry '"
|
||||||
+ id
|
+ id
|
||||||
+ "'; some users and groups previously created by synchronization with this user registry may be removed.");
|
+ "'; some users and groups previously created by synchronization with this user registry may be removed.");
|
||||||
}
|
}
|
||||||
@@ -393,7 +406,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
boolean requiresNew = splitTxns
|
boolean requiresNew = splitTxns
|
||||||
|| AlfrescoTransactionSupport.getTransactionReadState() == TxnReadState.TXN_READ_ONLY;
|
|| AlfrescoTransactionSupport.getTransactionReadState() == TxnReadState.TXN_READ_ONLY;
|
||||||
|
|
||||||
syncWithPlugin(id, plugin, force, requiresNew, visitedZoneIds, allZoneIds);
|
syncWithPlugin(id, plugin, forceUpdate, allowDeletions, requiresNew, visitedZoneIds, allZoneIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (NoSuchBeanDefinitionException e)
|
catch (NoSuchBeanDefinitionException e)
|
||||||
@@ -439,7 +452,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
synchronize(false, false);
|
synchronize(false, false, false);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -474,8 +487,16 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
* tell those that have been deleted from the registry.
|
* tell those that have been deleted from the registry.
|
||||||
* @param userRegistry
|
* @param userRegistry
|
||||||
* the user registry for the zone.
|
* the user registry for the zone.
|
||||||
* @param force
|
* @param forceUpdate
|
||||||
* <code>true</code> if user and group deletions are to be processed.
|
* Should the complete set of users and groups be updated / created locally or just those known to have
|
||||||
|
* changed since the last sync? When <code>true</code> then <i>all</i> users and groups are queried from
|
||||||
|
* the user registry and updated locally. When <code>false</code> then each source is only queried for
|
||||||
|
* those users and groups modified since the most recent modification date of all the objects last
|
||||||
|
* queried from that same source.
|
||||||
|
* @param allowDeletions
|
||||||
|
* Should a complete set of user and group IDs be queried from the user registries in order to determine
|
||||||
|
* deletions? This parameter is independent of <code>force</code> as a separate query is run to process
|
||||||
|
* updates.
|
||||||
* @param splitTxns
|
* @param splitTxns
|
||||||
* Can the modifications to Alfresco be split across multiple transactions for maximum performance? If
|
* Can the modifications to Alfresco be split across multiple transactions for maximum performance? If
|
||||||
* <code>true</code>, users and groups are created/updated in batches for increased performance. If
|
* <code>true</code>, users and groups are created/updated in batches for increased performance. If
|
||||||
@@ -490,8 +511,8 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
* recorded against a user or group is invalid for the current authentication chain and whether the user
|
* recorded against a user or group is invalid for the current authentication chain and whether the user
|
||||||
* or group needs to be 're-zoned'.
|
* or group needs to be 're-zoned'.
|
||||||
*/
|
*/
|
||||||
private void syncWithPlugin(final String zone, UserRegistry userRegistry, boolean force, boolean splitTxns,
|
private void syncWithPlugin(final String zone, UserRegistry userRegistry, boolean forceUpdate,
|
||||||
final Set<String> visitedZoneIds, final Set<String> allZoneIds)
|
boolean allowDeletions, boolean splitTxns, final Set<String> visitedZoneIds, final Set<String> allZoneIds)
|
||||||
{
|
{
|
||||||
// Create a prefixed zone ID for use with the authority service
|
// Create a prefixed zone ID for use with the authority service
|
||||||
final String zoneId = AuthorityService.ZONE_AUTH_EXT_PREFIX + zone;
|
final String zoneId = AuthorityService.ZONE_AUTH_EXT_PREFIX + zone;
|
||||||
@@ -499,7 +520,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
// The set of zones we associate with new objects (default plus registry specific)
|
// The set of zones we associate with new objects (default plus registry specific)
|
||||||
final Set<String> zoneSet = getZones(zoneId);
|
final Set<String> zoneSet = getZones(zoneId);
|
||||||
|
|
||||||
long lastModifiedMillis = getMostRecentUpdateTime(
|
long lastModifiedMillis = forceUpdate ? -1 : getMostRecentUpdateTime(
|
||||||
ChainingUserRegistrySynchronizer.GROUP_LAST_MODIFIED_ATTRIBUTE, zoneId, splitTxns);
|
ChainingUserRegistrySynchronizer.GROUP_LAST_MODIFIED_ATTRIBUTE, zoneId, splitTxns);
|
||||||
Date lastModified = lastModifiedMillis == -1 ? null : new Date(lastModifiedMillis);
|
Date lastModified = lastModifiedMillis == -1 ? null : new Date(lastModifiedMillis);
|
||||||
|
|
||||||
@@ -708,7 +729,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
Set<String> deletionCandidates = null;
|
Set<String> deletionCandidates = null;
|
||||||
|
|
||||||
// If we got back some groups, we have to cross reference them with the set of known authorities
|
// If we got back some groups, we have to cross reference them with the set of known authorities
|
||||||
if (force || !groupAssocsToCreate.isEmpty())
|
if (allowDeletions || !groupAssocsToCreate.isEmpty())
|
||||||
{
|
{
|
||||||
// Get current set of known authorities
|
// Get current set of known authorities
|
||||||
Set<String> allZoneAuthorities = this.retryingTransactionHelper.doInTransaction(
|
Set<String> allZoneAuthorities = this.retryingTransactionHelper.doInTransaction(
|
||||||
@@ -724,7 +745,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
allZoneAuthorities.addAll(groupAnalyzer.getAllZoneAuthorities());
|
allZoneAuthorities.addAll(groupAnalyzer.getAllZoneAuthorities());
|
||||||
|
|
||||||
// Prune our set of authorities according to deletions
|
// Prune our set of authorities according to deletions
|
||||||
if (force)
|
if (allowDeletions)
|
||||||
{
|
{
|
||||||
deletionCandidates = new TreeSet<String>(allZoneAuthorities);
|
deletionCandidates = new TreeSet<String>(allZoneAuthorities);
|
||||||
userRegistry.processDeletions(deletionCandidates);
|
userRegistry.processDeletions(deletionCandidates);
|
||||||
@@ -822,8 +843,8 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
|
|
||||||
// Process persons and their parent associations
|
// Process persons and their parent associations
|
||||||
|
|
||||||
lastModifiedMillis = getMostRecentUpdateTime(ChainingUserRegistrySynchronizer.PERSON_LAST_MODIFIED_ATTRIBUTE,
|
lastModifiedMillis = forceUpdate ? -1 : getMostRecentUpdateTime(
|
||||||
zoneId, splitTxns);
|
ChainingUserRegistrySynchronizer.PERSON_LAST_MODIFIED_ATTRIBUTE, zoneId, splitTxns);
|
||||||
lastModified = lastModifiedMillis == -1 ? null : new Date(lastModifiedMillis);
|
lastModified = lastModifiedMillis == -1 ? null : new Date(lastModifiedMillis);
|
||||||
if (ChainingUserRegistrySynchronizer.logger.isInfoEnabled())
|
if (ChainingUserRegistrySynchronizer.logger.isInfoEnabled())
|
||||||
{
|
{
|
||||||
@@ -994,7 +1015,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete authorities if we have complete information for the zone
|
// Delete authorities if we have complete information for the zone
|
||||||
if (force)
|
if (allowDeletions)
|
||||||
{
|
{
|
||||||
BatchProcessor<String> authorityDeletionProcessor = new BatchProcessor<String>(
|
BatchProcessor<String> authorityDeletionProcessor = new BatchProcessor<String>(
|
||||||
this.retryingTransactionHelper, this.ruleService, this.applicationEventPublisher,
|
this.retryingTransactionHelper, this.ruleService, this.applicationEventPublisher,
|
||||||
@@ -1214,7 +1235,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
synchronize(false, true);
|
synchronize(false, false, true);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@@ -171,7 +171,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
|
|||||||
{
|
{
|
||||||
newGroup("G2", "U1", "U3", "U4"), newGroup("G6", "U3", "U4", "G7"), newGroup("G7", "U5")
|
newGroup("G2", "U1", "U3", "U4"), newGroup("G6", "U3", "U4", "G7"), newGroup("G7", "U5")
|
||||||
}));
|
}));
|
||||||
this.synchronizer.synchronize(true, true);
|
this.synchronizer.synchronize(true, true, true);
|
||||||
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
|
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
|
|||||||
new NodeDescription[] {}), new MockUserRegistry("Z1", new NodeDescription[] {},
|
new NodeDescription[] {}), new MockUserRegistry("Z1", new NodeDescription[] {},
|
||||||
new NodeDescription[] {}), new MockUserRegistry("Z2", new NodeDescription[] {},
|
new NodeDescription[] {}), new MockUserRegistry("Z2", new NodeDescription[] {},
|
||||||
new NodeDescription[] {}));
|
new NodeDescription[] {}));
|
||||||
this.synchronizer.synchronize(true, true);
|
this.synchronizer.synchronize(true, true, true);
|
||||||
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
|
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
|
|||||||
public Object execute() throws Throwable
|
public Object execute() throws Throwable
|
||||||
{
|
{
|
||||||
|
|
||||||
ChainingUserRegistrySynchronizerTest.this.synchronizer.synchronize(false, false);
|
ChainingUserRegistrySynchronizerTest.this.synchronizer.synchronize(false, false, false);
|
||||||
// Stay in the same transaction
|
// Stay in the same transaction
|
||||||
assertExists("Z1", "U1");
|
assertExists("Z1", "U1");
|
||||||
assertEmailEquals("U1", "changeofemail@alfresco.com");
|
assertEmailEquals("U1", "changeofemail@alfresco.com");
|
||||||
@@ -332,7 +332,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
|
|||||||
{
|
{
|
||||||
newGroup("G2", "U1", "U3", "U4", "U6"), newGroup("G6", "U3", "U4", "G7"), newGroup("G7", "U4", "U5")
|
newGroup("G2", "U1", "U3", "U4", "U6"), newGroup("G6", "U3", "U4", "G7"), newGroup("G7", "U4", "U5")
|
||||||
}));
|
}));
|
||||||
this.synchronizer.synchronize(true, true);
|
this.synchronizer.synchronize(true, true, true);
|
||||||
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
|
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -369,7 +369,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
|
|||||||
List<NodeDescription> persons = new ArrayList<NodeDescription>(new RandomPersonCollection(100));
|
List<NodeDescription> persons = new ArrayList<NodeDescription>(new RandomPersonCollection(100));
|
||||||
List<NodeDescription> groups = new ArrayList<NodeDescription>(new RandomGroupCollection(100, persons));
|
List<NodeDescription> groups = new ArrayList<NodeDescription>(new RandomGroupCollection(100, persons));
|
||||||
this.applicationContextManager.setUserRegistries(new MockUserRegistry("Z0", persons, groups));
|
this.applicationContextManager.setUserRegistries(new MockUserRegistry("Z0", persons, groups));
|
||||||
this.synchronizer.synchronize(true, true);
|
this.synchronizer.synchronize(true, true, true);
|
||||||
tearDownTestUsersAndGroups();
|
tearDownTestUsersAndGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,7 +394,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
|
|||||||
}, true, true);
|
}, true, true);
|
||||||
ChainingUserRegistrySynchronizerTest.this.applicationContextManager.setUserRegistries(new MockUserRegistry(
|
ChainingUserRegistrySynchronizerTest.this.applicationContextManager.setUserRegistries(new MockUserRegistry(
|
||||||
"Z0", Collections.<NodeDescription> emptyList(), groups));
|
"Z0", Collections.<NodeDescription> emptyList(), groups));
|
||||||
ChainingUserRegistrySynchronizerTest.this.synchronizer.synchronize(true, true);
|
ChainingUserRegistrySynchronizerTest.this.synchronizer.synchronize(true, true, true);
|
||||||
tearDownTestUsersAndGroups();
|
tearDownTestUsersAndGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -48,19 +48,21 @@ public interface UserRegistrySynchronizer
|
|||||||
* users and groups last retrieved from the same sources. Any updates and additions made to those users and groups
|
* users and groups last retrieved from the same sources. Any updates and additions made to those users and groups
|
||||||
* are applied to the local Alfresco copies.
|
* are applied to the local Alfresco copies.
|
||||||
*
|
*
|
||||||
* @param force
|
* @param forceUpdate
|
||||||
* Should a complete or partial set of information be queried from the external sources? When
|
* Should the complete set of users and groups be updated / created locally or just those known to have
|
||||||
* <code>true</code> then <i>all</i> users and groups are queried. With this complete set of information,
|
* changed since the last sync? When <code>true</code> then <i>all</i> users and groups are queried from
|
||||||
* the implementation is able to identify which users and groups have been deleted, so it will delete
|
* the user registry and updated locally. When <code>false</code> then each source is only queried for
|
||||||
* users and groups as well as update and create them. When <code>false</code> then each source is only
|
* those users and groups modified since the most recent modification date of all the objects last
|
||||||
* queried for those users and groups modified since the most recent modification date of all the objects
|
* queried from that same source.
|
||||||
* last queried from that same source. In this mode, local users and groups are created and updated, but
|
* @param allowDeletions
|
||||||
* not deleted.
|
* Should a complete set of user and group IDs be queried from the user registries in order to determine
|
||||||
|
* deletions? This parameter is independent of <code>force</code> as a separate query is run to process
|
||||||
|
* updates.
|
||||||
* @param splitTxns
|
* @param splitTxns
|
||||||
* Can the modifications to Alfresco be split across multiple transactions for maximum performance? If
|
* Can the modifications to Alfresco be split across multiple transactions for maximum performance? If
|
||||||
* <code>true</code>, users and groups are created/updated in batches of 10 for increased performance. If
|
* <code>true</code>, users and groups are created/updated in batches of 10 for increased performance. If
|
||||||
* <code>false</code>, all users and groups are processed in the current transaction. This is required if
|
* <code>false</code>, all users and groups are processed in the current transaction. This is required if
|
||||||
* calling synchronously (e.g. in response to an authentication event in the same transaction).
|
* calling synchronously (e.g. in response to an authentication event in the same transaction).
|
||||||
*/
|
*/
|
||||||
public void synchronize(boolean force, boolean splitTxns);
|
public void synchronize(boolean forceUpdate, boolean allowDeletions, boolean splitTxns);
|
||||||
}
|
}
|
@@ -32,9 +32,9 @@ import org.quartz.JobExecutionException;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A scheduled job that regularly invokes a {@link UserRegistrySynchronizer}. Supports a
|
* A scheduled job that regularly invokes a {@link UserRegistrySynchronizer}. Supports a
|
||||||
* <code>synchronizeChangesOnly</code> string parameter. When <code>"true"</code> means that the
|
* <code>synchronizeChangesOnly</code> string parameter. When <code>"false"</code> means that the
|
||||||
* {@link UserRegistrySynchronizer#synchronize(boolean)} method will be called with a <code>false</code> argument rather
|
* {@link UserRegistrySynchronizer#synchronize(boolean)} method will be called with a <code>true</code> forceUpdate
|
||||||
* than the default <code>true</code>.
|
* argument rather than the default <code>false</code>.
|
||||||
*
|
*
|
||||||
* @author dward
|
* @author dward
|
||||||
*/
|
*/
|
||||||
@@ -55,7 +55,7 @@ public class UserRegistrySynchronizerJob implements Job
|
|||||||
public Object doWork() throws Exception
|
public Object doWork() throws Exception
|
||||||
{
|
{
|
||||||
userRegistrySynchronizer.synchronize(synchronizeChangesOnly == null
|
userRegistrySynchronizer.synchronize(synchronizeChangesOnly == null
|
||||||
|| !Boolean.parseBoolean(synchronizeChangesOnly), true);
|
|| !Boolean.parseBoolean(synchronizeChangesOnly), true, true);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}, AuthenticationUtil.getSystemUserName());
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
@@ -15,8 +15,8 @@
|
|||||||
<property name="applicationContextManager">
|
<property name="applicationContextManager">
|
||||||
<ref bean="testApplicationContextManager" />
|
<ref bean="testApplicationContextManager" />
|
||||||
</property>
|
</property>
|
||||||
<property name="retryingTransactionHelper">
|
<property name="transactionService">
|
||||||
<ref bean="retryingTransactionHelper" />
|
<ref bean="transactionService" />
|
||||||
</property>
|
</property>
|
||||||
<property name="ruleService">
|
<property name="ruleService">
|
||||||
<ref bean="ruleService" />
|
<ref bean="ruleService" />
|
||||||
|
Reference in New Issue
Block a user