Merged V3.2 to HEAD

17163: org.alfresco.repo.domain.hibernate.AclDaoComponentImpl.updateAuthority() needs to flush/dirty the session in order to work
   17160: Fix HeartBeat
      - Lazy initialization in scheduled job needed its own transaction
   17146: Fix failing unit tests
      - HibernateNodeDaoServiceImpl.moveNodeToStore() must invalidate parentAssocsCache now that it contains NodeRefs
   17145: Fixes to patches for new CRC schema changes
      - Sequenced patch.fixNameCrcValues-2 before all other patches
      - Fixed typos in schema upgrade script and added CRCs for the repository descriptor nodes, so that the descriptor service and patch service can boot up
      - HeartBeat initializes lazily so that it doesn't try to load information before the patch service has bootstrapped
      - Made FixNameCrcValuesPatch industrial strength by using BatchProcessor to handle multi threading, progress reporting and transaction delineation
   17097: Removal of spurious logs directory accidentally introduced in 17096
   17096: Performance tuning for improved throughput during high volume import from LDAP directory
      - Lucene indexer will now no longer index and then reindex the same node in the same transaction
      - lucene.indexer.mergerTargetOverlaysBlockingFactor reduced to 1 (improves indexing performance and no excessive throttling observed during 10 hour test)
      - HomeFolderManager fixed so that it pays attention to the eager home folder creation flag
      - HibernateNodeDaoServiceImpl.parentAssocsCache 'upgraded' to hold information about root nodes and node refs so that recursive methods such as prependPaths can run entirely out of the cache
      - Boolean argument added to getChildAssocs() so that preloading of all child nodes is optional
      - qname_crc column added to alf_child_assoc to allow efficient lookup and indexing of child associations by QName. CRC of (qname_namespace, qname_localname).
      - idx_alf_cass_qnln on qname_localname replaced with idx_alf_cass_qncrc (qname_crc, type_qname_id, parent_node_id)
      - All node service lookup queries involving qname_localname modified to include qname_crc in WHERE clause
      - schema patch provided
      - existing org.alfresco.repo.admin.patch.impl.FixNameCrcValuesPatch extended to also fill in qname_crc column and forced to run on newer schemas
      - Optimized ChainingUserRegistrySynchronizer so that it doesn't have to look up the entire set of authorities during  an 'empty' incremental sync
      - ChainingUserRegistrySynchronizer no longer starts an outer transaction around all its smaller transactions (used to die due to timeout)
      - rule service disabled for LDAP batch processing threads
      - org.alfresco.cache.parentAssocsCache and org.alfresco.cache.storeAndNodeIdCache size increased to 80,000
      - Fixed case sensitivity issue with person caching in PersonServiceImpl
      - Cache the people container in PersonServiceImpl for faster person lookups
      - PersonDAO removed and replaced with now more efficient node service child assoc lookup methods


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@17168 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2009-10-26 15:52:59 +00:00
parent 104d6258a5
commit b8aaa9c372
33 changed files with 1123 additions and 627 deletions

View File

@@ -41,6 +41,7 @@ import java.util.concurrent.TimeUnit;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.rule.RuleService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEventPublisher;
@@ -65,6 +66,9 @@ public class BatchProcessor<T> implements BatchMonitor
/** The retrying transaction helper. */
private RetryingTransactionHelper retryingTransactionHelper;
/** The rule service. */
private RuleService ruleService;
/** The collection. */
private Collection<T> collection;
@@ -106,6 +110,8 @@ public class BatchProcessor<T> implements BatchMonitor
*
* @param retryingTransactionHelper
* the retrying transaction helper
* @param ruleService
* the rule service
* @param collection
* the collection
* @param processName
@@ -119,11 +125,12 @@ public class BatchProcessor<T> implements BatchMonitor
* @param batchSize
* the number of entries we process at a time in a transaction
*/
public BatchProcessor(RetryingTransactionHelper retryingTransactionHelper,
public BatchProcessor(RetryingTransactionHelper retryingTransactionHelper, RuleService ruleService,
ApplicationEventPublisher applicationEventPublisher, Collection<T> collection, String processName,
int loggingInterval, int workerThreads, int batchSize)
{
this.retryingTransactionHelper = retryingTransactionHelper;
this.ruleService = ruleService;
this.collection = collection;
this.processName = processName;
this.loggingInterval = loggingInterval;
@@ -272,7 +279,7 @@ public class BatchProcessor<T> implements BatchMonitor
// Create a thread pool executor with the specified number of threads and a finite blocking queue of jobs
ExecutorService executorService = splitTxns && this.workerThreads > 1 ? new ThreadPoolExecutor(
this.workerThreads, this.workerThreads, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(
this.workerThreads * 10)
this.workerThreads * batchSize * 10)
{
// Add blocking behaviour to work queue
@Override
@@ -378,10 +385,10 @@ public class BatchProcessor<T> implements BatchMonitor
NumberFormat.getPercentInstance().format(
totalResults == 0 ? 1.0F : (float) processed / totalResults)).append(" complete");
}
long duration = System.currentTimeMillis() - startTime.getTime();
long duration = System.currentTimeMillis() - this.startTime.getTime();
if (duration > 0)
{
message.append(". Rate: ").append(processed * 1000 / duration).append(" per second");
message.append(". Rate: ").append(processed * 1000L / duration).append(" per second");
}
message.append(". " + this.totalErrors + " failures detected.");
BatchProcessor.logger.info(message);
@@ -454,13 +461,13 @@ public class BatchProcessor<T> implements BatchMonitor
/** The current entry being processed in the transaction */
private String txnEntryId;
/** The last error. */
private Throwable txnLastError;
/** The last error entry id. */
private String txnLastErrorEntryId;
/*
* (non-Javadoc)
* @see org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback#execute ()
@@ -473,7 +480,7 @@ public class BatchProcessor<T> implements BatchMonitor
this.txnEntryId = this.worker.getIdentifier(entry);
synchronized (BatchProcessor.this)
{
BatchProcessor.this.currentEntryId = txnEntryId;
BatchProcessor.this.currentEntryId = this.txnEntryId;
}
try
{
@@ -486,11 +493,11 @@ public class BatchProcessor<T> implements BatchMonitor
{
if (BatchProcessor.logger.isWarnEnabled())
{
BatchProcessor.logger.warn(getProcessName() + ": Failed to process entry \"" + txnEntryId
+ "\".", t);
BatchProcessor.logger.warn(getProcessName() + ": Failed to process entry \""
+ this.txnEntryId + "\".", t);
}
this.txnLastError = t;
this.txnLastErrorEntryId = txnEntryId;
this.txnLastErrorEntryId = this.txnEntryId;
this.txnErrors++;
}
else
@@ -508,6 +515,8 @@ public class BatchProcessor<T> implements BatchMonitor
*/
public void run()
{
// Disable rules for this thread
BatchProcessor.this.ruleService.disableRules();
try
{
BatchProcessor.this.retryingTransactionHelper.doInTransaction(this, false, this.splitTxns);
@@ -540,6 +549,12 @@ public class BatchProcessor<T> implements BatchMonitor
throw new AlfrescoRuntimeException("Transactional error during " + getProcessName(), t);
}
}
finally
{
// Re-enable rules
BatchProcessor.this.ruleService.enableRules();
}
commitProgress();
}
@@ -606,6 +621,7 @@ public class BatchProcessor<T> implements BatchMonitor
BatchProcessor.this.lastError = this.txnLastError;
BatchProcessor.this.lastErrorEntryId = this.txnLastErrorEntryId;
}
reset();
}
}

View File

@@ -53,6 +53,7 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.attributes.AttributeService;
import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PersonService;
@@ -134,6 +135,9 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
/** The retrying transaction helper. */
private RetryingTransactionHelper retryingTransactionHelper;
/** The rule service. */
private RuleService ruleService;
/** The job lock service. */
private JobLockService jobLockService;
@@ -221,6 +225,17 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
this.retryingTransactionHelper = retryingTransactionHelper;
}
/**
* Sets the rule service.
*
* @param ruleService
* the new rule service
*/
public void setRuleService(RuleService ruleService)
{
this.ruleService = ruleService;
}
/**
* Sets the job lock service.
*
@@ -304,6 +319,8 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
*/
public void synchronize(boolean force, boolean splitTxns)
{
String lockToken = null;
// Let's ensure all exceptions get logged
try
{
@@ -314,8 +331,16 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
{
// 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);
lockToken = this.retryingTransactionHelper.doInTransaction(
new RetryingTransactionCallback<String>()
{
public String execute() throws Throwable
{
return ChainingUserRegistrySynchronizer.this.jobLockService.getLock(
ChainingUserRegistrySynchronizer.LOCK_QNAME,
ChainingUserRegistrySynchronizer.LOCK_TTL, 0, 1);
}
}, false, splitTxns);
}
else
{
@@ -382,6 +407,23 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
ChainingUserRegistrySynchronizer.logger.error("Synchronization aborted due to error", e);
throw e;
}
// Release the lock if necessary
finally
{
if (lockToken != null)
{
final String token = lockToken;
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
ChainingUserRegistrySynchronizer.this.jobLockService.releaseLock(token,
ChainingUserRegistrySynchronizer.LOCK_QNAME);
return null;
}
}, false, splitTxns);
}
}
}
/*
@@ -458,7 +500,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
final Set<String> zoneSet = getZones(zoneId);
long lastModifiedMillis = getMostRecentUpdateTime(
ChainingUserRegistrySynchronizer.GROUP_LAST_MODIFIED_ATTRIBUTE, zoneId);
ChainingUserRegistrySynchronizer.GROUP_LAST_MODIFIED_ATTRIBUTE, zoneId, splitTxns);
Date lastModified = lastModifiedMillis == -1 ? null : new Date(lastModifiedMillis);
if (ChainingUserRegistrySynchronizer.logger.isInfoEnabled())
@@ -474,33 +516,22 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
}
}
// Get current set of known authorities
Set<String> allZoneAuthorities = this.retryingTransactionHelper.doInTransaction(
new RetryingTransactionCallback<Set<String>>()
{
public Set<String> execute() throws Throwable
{
return ChainingUserRegistrySynchronizer.this.authorityService.getAllAuthoritiesInZone(zoneId,
null);
}
}, false, splitTxns);
// First, analyze the group structure. Create maps of authorities to their parents for associations to create
// and delete. Also deal with 'overlaps' with other zones in the authentication chain.
final BatchProcessor<NodeDescription> groupProcessor = new BatchProcessor<NodeDescription>(
this.retryingTransactionHelper, this.applicationEventPublisher, userRegistry.getGroups(lastModified),
zone + " Group Analysis", this.loggingInterval, this.workerThreads, 20);
this.retryingTransactionHelper, this.ruleService, this.applicationEventPublisher, userRegistry
.getGroups(lastModified), zone + " Group Analysis", this.loggingInterval, this.workerThreads,
20);
class Analyzer implements Worker<NodeDescription>
{
private final Set<String> allZoneAuthorities;
private final Set<String> allZoneAuthorities = new TreeSet<String>();
private final Set<String> groupsToCreate = new TreeSet<String>();
private final Map<String, Set<String>> groupAssocsToCreate = new TreeMap<String, Set<String>>();
private final Map<String, Set<String>> groupAssocsToDelete = new TreeMap<String, Set<String>>();
private long latestTime;
public Analyzer(final Set<String> allZoneAuthorities, final long latestTime)
public Analyzer(final long latestTime)
{
this.allZoneAuthorities = allZoneAuthorities;
this.latestTime = latestTime;
}
@@ -509,6 +540,11 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
return this.latestTime;
}
public Set<String> getAllZoneAuthorities()
{
return this.allZoneAuthorities;
}
public Set<String> getGroupsToCreate()
{
return this.groupsToCreate;
@@ -665,105 +701,129 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
}
}
Analyzer groupAnalyzer = new Analyzer(allZoneAuthorities, lastModifiedMillis);
Analyzer groupAnalyzer = new Analyzer(lastModifiedMillis);
int groupProcessedCount = groupProcessor.process(groupAnalyzer, splitTxns);
final Map<String, Set<String>> groupAssocsToCreate = groupAnalyzer.getGroupAssocsToCreate();
final Map<String, Set<String>> groupAssocsToDelete = groupAnalyzer.getGroupAssocsToDelete();
// Prune our set of authorities according to deletions
Set<String> deletionCandidates = null;
if (force)
// If we got back some groups, we have to cross reference them with the set of known authorities
if (force || !groupAssocsToCreate.isEmpty())
{
deletionCandidates = new TreeSet<String>(allZoneAuthorities);
userRegistry.processDeletions(deletionCandidates);
allZoneAuthorities.removeAll(deletionCandidates);
groupAssocsToCreate.keySet().removeAll(deletionCandidates);
groupAssocsToDelete.keySet().removeAll(deletionCandidates);
}
// Sort the group associations in depth-first order (root groups first)
Map<String, Set<String>> sortedGroupAssociations = new LinkedHashMap<String, Set<String>>(groupAssocsToCreate
.size() * 2);
List<String> authorityPath = new ArrayList<String>(5);
for (String authority : groupAssocsToCreate.keySet())
{
if (allZoneAuthorities.contains(authority))
{
authorityPath.add(authority);
visitGroupAssociations(authorityPath, allZoneAuthorities, groupAssocsToCreate, sortedGroupAssociations);
authorityPath.clear();
}
}
// Add the groups and their parent associations in depth-first order
final Set<String> groupsToCreate = groupAnalyzer.getGroupsToCreate();
BatchProcessor<Map.Entry<String, Set<String>>> groupCreator = new BatchProcessor<Map.Entry<String, Set<String>>>(
this.retryingTransactionHelper, this.applicationEventPublisher, sortedGroupAssociations.entrySet(),
zone + " Group Creation and Association", this.loggingInterval, 1, 20);
groupCreator.process(new Worker<Map.Entry<String, Set<String>>>()
{
public String getIdentifier(Map.Entry<String, Set<String>> entry)
{
return entry.getKey() + " " + entry.getValue();
}
public void process(Map.Entry<String, Set<String>> entry) throws Throwable
{
Set<String> parents = entry.getValue();
String child = entry.getKey();
if (groupsToCreate.contains(child))
{
String groupShortName = ChainingUserRegistrySynchronizer.this.authorityService.getShortName(child);
if (ChainingUserRegistrySynchronizer.logger.isDebugEnabled())
// Get current set of known authorities
Set<String> allZoneAuthorities = this.retryingTransactionHelper.doInTransaction(
new RetryingTransactionCallback<Set<String>>()
{
ChainingUserRegistrySynchronizer.logger.debug("Creating group '" + groupShortName + "'");
}
// create the group
ChainingUserRegistrySynchronizer.this.authorityService.createAuthority(AuthorityType
.getAuthorityType(child), groupShortName, groupShortName, zoneSet);
}
if (!parents.isEmpty())
{
if (ChainingUserRegistrySynchronizer.logger.isDebugEnabled())
{
for (String groupName : parents)
public Set<String> execute() throws Throwable
{
ChainingUserRegistrySynchronizer.logger.debug("Adding '"
+ ChainingUserRegistrySynchronizer.this.authorityService.getShortName(child)
+ "' to group '"
+ ChainingUserRegistrySynchronizer.this.authorityService.getShortName(groupName)
+ "'");
return ChainingUserRegistrySynchronizer.this.authorityService.getAllAuthoritiesInZone(
zoneId, null);
}
}
ChainingUserRegistrySynchronizer.this.authorityService.addAuthority(parents, child);
}
Set<String> parentsToDelete = groupAssocsToDelete.get(child);
if (parentsToDelete != null && !parentsToDelete.isEmpty())
}, true, splitTxns);
// Add in those that will be created or moved
allZoneAuthorities.addAll(groupAnalyzer.getAllZoneAuthorities());
// Prune our set of authorities according to deletions
if (force)
{
deletionCandidates = new TreeSet<String>(allZoneAuthorities);
userRegistry.processDeletions(deletionCandidates);
allZoneAuthorities.removeAll(deletionCandidates);
groupAssocsToCreate.keySet().removeAll(deletionCandidates);
groupAssocsToDelete.keySet().removeAll(deletionCandidates);
}
if (!groupAssocsToCreate.isEmpty())
{
// Sort the group associations in depth-first order (root groups first)
Map<String, Set<String>> sortedGroupAssociations = new LinkedHashMap<String, Set<String>>(
groupAssocsToCreate.size() * 2);
List<String> authorityPath = new ArrayList<String>(5);
for (String authority : groupAssocsToCreate.keySet())
{
for (String parent : parentsToDelete)
if (allZoneAuthorities.contains(authority))
{
if (ChainingUserRegistrySynchronizer.logger.isDebugEnabled())
authorityPath.add(authority);
visitGroupAssociations(authorityPath, allZoneAuthorities, groupAssocsToCreate,
sortedGroupAssociations);
authorityPath.clear();
}
}
// Add the groups and their parent associations in depth-first order
final Set<String> groupsToCreate = groupAnalyzer.getGroupsToCreate();
BatchProcessor<Map.Entry<String, Set<String>>> groupCreator = new BatchProcessor<Map.Entry<String, Set<String>>>(
this.retryingTransactionHelper, this.ruleService, this.applicationEventPublisher,
sortedGroupAssociations.entrySet(), zone + " Group Creation and Association",
this.loggingInterval, this.workerThreads, 20);
groupCreator.process(new Worker<Map.Entry<String, Set<String>>>()
{
public String getIdentifier(Map.Entry<String, Set<String>> entry)
{
return entry.getKey() + " " + entry.getValue();
}
public void process(Map.Entry<String, Set<String>> entry) throws Throwable
{
Set<String> parents = entry.getValue();
String child = entry.getKey();
if (groupsToCreate.contains(child))
{
ChainingUserRegistrySynchronizer.logger
.debug("Removing '"
String groupShortName = ChainingUserRegistrySynchronizer.this.authorityService
.getShortName(child);
if (ChainingUserRegistrySynchronizer.logger.isDebugEnabled())
{
ChainingUserRegistrySynchronizer.logger
.debug("Creating group '" + groupShortName + "'");
}
// create the group
ChainingUserRegistrySynchronizer.this.authorityService.createAuthority(AuthorityType
.getAuthorityType(child), groupShortName, groupShortName, zoneSet);
}
if (!parents.isEmpty())
{
if (ChainingUserRegistrySynchronizer.logger.isDebugEnabled())
{
for (String groupName : parents)
{
ChainingUserRegistrySynchronizer.logger.debug("Adding '"
+ ChainingUserRegistrySynchronizer.this.authorityService
.getShortName(child)
+ "' to group '"
+ ChainingUserRegistrySynchronizer.this.authorityService
.getShortName(groupName) + "'");
}
}
ChainingUserRegistrySynchronizer.this.authorityService.addAuthority(parents, child);
}
Set<String> parentsToDelete = groupAssocsToDelete.get(child);
if (parentsToDelete != null && !parentsToDelete.isEmpty())
{
for (String parent : parentsToDelete)
{
if (ChainingUserRegistrySynchronizer.logger.isDebugEnabled())
{
ChainingUserRegistrySynchronizer.logger.debug("Removing '"
+ ChainingUserRegistrySynchronizer.this.authorityService
.getShortName(child)
+ "' from group '"
+ ChainingUserRegistrySynchronizer.this.authorityService
.getShortName(parent) + "'");
}
ChainingUserRegistrySynchronizer.this.authorityService.removeAuthority(parent, child);
}
}
ChainingUserRegistrySynchronizer.this.authorityService.removeAuthority(parent, child);
}
}
}, splitTxns);
}
}, splitTxns);
}
// Process persons and their parent associations
lastModifiedMillis = getMostRecentUpdateTime(ChainingUserRegistrySynchronizer.PERSON_LAST_MODIFIED_ATTRIBUTE,
zoneId);
zoneId, splitTxns);
lastModified = lastModifiedMillis == -1 ? null : new Date(lastModifiedMillis);
if (ChainingUserRegistrySynchronizer.logger.isInfoEnabled())
{
@@ -778,8 +838,9 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
}
}
final BatchProcessor<NodeDescription> personProcessor = new BatchProcessor<NodeDescription>(
this.retryingTransactionHelper, this.applicationEventPublisher, userRegistry.getPersons(lastModified),
zone + " User Creation and Association", this.loggingInterval, this.workerThreads, 10);
this.retryingTransactionHelper, this.ruleService, this.applicationEventPublisher, userRegistry
.getPersons(lastModified), zone + " User Creation and Association", this.loggingInterval,
this.workerThreads, 10);
class PersonWorker implements Worker<NodeDescription>
{
private long latestTime;
@@ -822,7 +883,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
ChainingUserRegistrySynchronizer.logger.debug("Updating user '" + personName + "'");
}
ChainingUserRegistrySynchronizer.this.personService.setPersonProperties(personName,
personProperties);
personProperties, false);
}
else
{
@@ -936,8 +997,8 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
if (force)
{
BatchProcessor<String> authorityDeletionProcessor = new BatchProcessor<String>(
this.retryingTransactionHelper, this.applicationEventPublisher, deletionCandidates, zone
+ " Authority Deletion", this.loggingInterval, this.workerThreads, 10);
this.retryingTransactionHelper, this.ruleService, this.applicationEventPublisher,
deletionCandidates, zone + " Authority Deletion", this.loggingInterval, this.workerThreads, 10);
class AuthorityDeleter implements Worker<String>
{
private int personProcessedCount;
@@ -1062,11 +1123,18 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
* the zone id
* @return the most recent update time in milliseconds
*/
private long getMostRecentUpdateTime(String label, String zoneId)
private long getMostRecentUpdateTime(final String label, final String zoneId, boolean splitTxns)
{
Attribute attribute = this.attributeService.getAttribute(ChainingUserRegistrySynchronizer.ROOT_ATTRIBUTE_PATH
+ '/' + label + '/' + zoneId);
return attribute == null ? -1 : attribute.getLongValue();
return this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Long>()
{
public Long execute() throws Throwable
{
Attribute attribute = ChainingUserRegistrySynchronizer.this.attributeService
.getAttribute(ChainingUserRegistrySynchronizer.ROOT_ATTRIBUTE_PATH + '/' + label + '/' + zoneId);
return attribute == null ? -1 : attribute.getLongValue();
}
}, true, splitTxns);
}
/**
@@ -1144,24 +1212,16 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl
{
public Object doWork() throws Exception
{
return ChainingUserRegistrySynchronizer.this.retryingTransactionHelper
.doInTransaction(new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
try
{
synchronize(false, true);
}
catch (Exception e)
{
ChainingUserRegistrySynchronizer.logger.warn(
"Failed initial synchronize with user registries", e);
}
return null;
}
});
try
{
synchronize(false, true);
}
catch (Exception e)
{
ChainingUserRegistrySynchronizer.logger.warn("Failed initial synchronize with user registries",
e);
}
return null;
}
}, AuthenticationUtil.getSystemUserName());
}

View File

@@ -171,15 +171,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
{
newGroup("G2", "U1", "U3", "U4"), newGroup("G6", "U3", "U4", "G7"), newGroup("G7", "U5")
}));
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
ChainingUserRegistrySynchronizerTest.this.synchronizer.synchronize(true, true);
return null;
}
});
this.synchronizer.synchronize(true, true);
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
{
@@ -200,7 +192,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
assertExists("Z2", "G7", "U5");
return null;
}
});
}, false, true);
}
/**
@@ -209,22 +201,14 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
* @throws Exception
* the exception
*/
private void tearDownTestUsersAndGroups() throws Exception
public void tearDownTestUsersAndGroups() throws Exception
{
// Wipe out everything that was in Z1 and Z2
this.applicationContextManager.setUserRegistries(new MockUserRegistry("Z0", new NodeDescription[] {},
new NodeDescription[] {}), new MockUserRegistry("Z1", new NodeDescription[] {},
new NodeDescription[] {}), new MockUserRegistry("Z2", new NodeDescription[] {},
new NodeDescription[] {}));
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
ChainingUserRegistrySynchronizerTest.this.synchronizer.synchronize(true, true);
return null;
}
});
this.synchronizer.synchronize(true, true);
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
{
@@ -245,7 +229,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
assertNotExists("G7");
return null;
}
});
}, false, true);
}
/**
@@ -348,15 +332,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
{
newGroup("G2", "U1", "U3", "U4", "U6"), newGroup("G6", "U3", "U4", "G7"), newGroup("G7", "U4", "U5")
}));
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
ChainingUserRegistrySynchronizerTest.this.synchronizer.synchronize(true, true);
return null;
}
});
this.synchronizer.synchronize(true, true);
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
{
@@ -378,7 +354,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
assertExists("Z2", "G7");
return null;
}
});
}, false, true);
tearDownTestUsersAndGroups();
}
@@ -393,15 +369,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
List<NodeDescription> persons = new ArrayList<NodeDescription>(new RandomPersonCollection(100));
List<NodeDescription> groups = new ArrayList<NodeDescription>(new RandomGroupCollection(100, persons));
this.applicationContextManager.setUserRegistries(new MockUserRegistry("Z0", persons, groups));
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
ChainingUserRegistrySynchronizerTest.this.synchronizer.synchronize(true, true);
return null;
}
});
this.synchronizer.synchronize(true, true);
tearDownTestUsersAndGroups();
}
@@ -413,20 +381,20 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
*/
public void dontTestAssocs() throws Exception
{
this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
List<NodeDescription> groups = new ArrayList<NodeDescription>(new RandomGroupCollection(1000,
ChainingUserRegistrySynchronizerTest.this.authorityService.getAllAuthoritiesInZone(
AuthorityService.ZONE_AUTH_EXT_PREFIX + "Z0", null)));
ChainingUserRegistrySynchronizerTest.this.applicationContextManager
.setUserRegistries(new MockUserRegistry("Z0", Collections.<NodeDescription> emptyList(), groups));
;
ChainingUserRegistrySynchronizerTest.this.synchronizer.synchronize(true, true);
return null;
}
});
List<NodeDescription> groups = this.retryingTransactionHelper.doInTransaction(
new RetryingTransactionCallback<List<NodeDescription>>()
{
public List<NodeDescription> execute() throws Throwable
{
return new ArrayList<NodeDescription>(new RandomGroupCollection(1000,
ChainingUserRegistrySynchronizerTest.this.authorityService.getAllAuthoritiesInZone(
AuthorityService.ZONE_AUTH_EXT_PREFIX + "Z0", null)));
}
}, true, true);
ChainingUserRegistrySynchronizerTest.this.applicationContextManager.setUserRegistries(new MockUserRegistry(
"Z0", Collections.<NodeDescription> emptyList(), groups));
ChainingUserRegistrySynchronizerTest.this.synchronizer.synchronize(true, true);
tearDownTestUsersAndGroups();
}
@@ -631,10 +599,9 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
{
return this.zoneId;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.alfresco.repo.security.sync.UserRegistry#processDeletions(java.util.Set)
*/
public void processDeletions(Set<String> candidateAuthoritiesForDeletion)
@@ -649,7 +616,8 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase
}
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.alfresco.repo.security.sync.UserRegistry#getGroups(java.util.Date)
*/
public Collection<NodeDescription> getGroups(Date modifiedSince)