mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V2.9 to HEAD
9845: Merged V2.2 to V2.9 9733: Merged V2.1 to V2.2 9281: Improvements to index AUTO recovery 9316: Fixed ETWOONE-193: Transactional caches not being cleaned up after rollback (2.1.4 regression) 9317: Fixed ETWOONE-194: Faster void handling during index tracking 9365: Improved performance for finding which snapshots have been indexed 9413: Support to retrieve read/write state of the transaction and ensure Lucene commits are handled last 9414: ACT-3245: Updating node properties and aspects don't bump the alf_node.version value 9415: Code cleanup: Removed unnecessary empty methods 9416: Fixed creation of multiple thread pools 9417: Full index recovery absorbs indexing exceptions by default 9418: Added AUTO index recovery option to sample in line with Wiki docs 9419: ETWOONE-194: Index tracking is too slow 9420: Fixed ETWOONE-201: Better logging and configurability for RetryingTransactionHelper 9421: Fixed ETWOONE-202: SPlit person cleanup doesn't break read-only transactions 9422: Follow up on CHK-3317: Removed use of JDK 1.6 NavigableMap interface 9423: Fixed unit test after CHK-3317 9424: More test fixes after CHK-3317 9425: Ensure that index tracking tests don't run too long. 9426: Made concurrent reindexing optional. It is on by default. 9509: ACT-3539: Mid-transaction locking on Lucene resources 9547: Multithreaded index tracking startup: Handle previously lagging single-threaded rebuilds git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10592 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -41,6 +41,10 @@ import org.alfresco.repo.policy.JavaBehaviour;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
import org.alfresco.repo.security.permissions.PermissionServiceSPI;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.TransactionListenerAdapter;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -57,12 +61,15 @@ import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class PersonServiceImpl implements PersonService,
|
||||
NodeServicePolicies.OnCreateNodePolicy, NodeServicePolicies.BeforeDeleteNodePolicy
|
||||
public class PersonServiceImpl
|
||||
extends TransactionListenerAdapter
|
||||
implements PersonService, NodeServicePolicies.OnCreateNodePolicy, NodeServicePolicies.BeforeDeleteNodePolicy
|
||||
{
|
||||
private static Log s_logger = LogFactory.getLog(PersonServiceImpl.class);
|
||||
|
||||
@@ -80,6 +87,8 @@ public class PersonServiceImpl implements PersonService,
|
||||
|
||||
private StoreRef storeRef;
|
||||
|
||||
private TransactionService transactionService;
|
||||
|
||||
private NodeService nodeService;
|
||||
|
||||
private TenantService tenantService;
|
||||
@@ -126,12 +135,33 @@ public class PersonServiceImpl implements PersonService,
|
||||
props.add(ContentModel.PROP_ORGID);
|
||||
mutableProperties = Collections.unmodifiableSet(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
return this == obj;
|
||||
}
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spring bean init method
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
PropertyCheck.mandatory(this, "storeUrl", storeRef);
|
||||
PropertyCheck.mandatory(this, "transactionService", transactionService);
|
||||
PropertyCheck.mandatory(this, "nodeService", nodeService);
|
||||
PropertyCheck.mandatory(this, "searchService", searchService);
|
||||
PropertyCheck.mandatory(this, "permissionServiceSPI", permissionServiceSPI);
|
||||
PropertyCheck.mandatory(this, "authorityService", authorityService);
|
||||
PropertyCheck.mandatory(this, "namespacePrefixResolver", namespacePrefixResolver);
|
||||
PropertyCheck.mandatory(this, "policyComponent", policyComponent);
|
||||
PropertyCheck.mandatory(this, "personCache", personCache);
|
||||
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
|
||||
ContentModel.TYPE_PERSON,
|
||||
@@ -202,8 +232,10 @@ public class PersonServiceImpl implements PersonService,
|
||||
NodeRef personNode = getPersonOrNull(userName);
|
||||
if (personNode == null)
|
||||
{
|
||||
if (createMissingPeople())
|
||||
TxnReadState txnReadState = AlfrescoTransactionSupport.getTransactionReadState();
|
||||
if (createMissingPeople() && txnReadState == TxnReadState.TXN_READ_WRITE)
|
||||
{
|
||||
// We create missing people AND are in a read-write txn
|
||||
return createMissingPerson(userName);
|
||||
}
|
||||
else
|
||||
@@ -289,11 +321,7 @@ public class PersonServiceImpl implements PersonService,
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
if (singleton)
|
||||
{
|
||||
returnRef = returnRef;
|
||||
}
|
||||
else
|
||||
if (!singleton)
|
||||
{
|
||||
returnRef = handleDuplicates(searchUserName);
|
||||
}
|
||||
@@ -303,29 +331,12 @@ public class PersonServiceImpl implements PersonService,
|
||||
}
|
||||
return returnRef;
|
||||
}
|
||||
|
||||
private NodeRef handleDuplicates(String searchUserName)
|
||||
{
|
||||
if (processDuplicates)
|
||||
{
|
||||
NodeRef best = findBest(searchUserName);
|
||||
if (duplicateMode.equalsIgnoreCase(SPLIT))
|
||||
{
|
||||
split(searchUserName, best);
|
||||
s_logger.info("Split duplicate person objects for uid " + searchUserName);
|
||||
}
|
||||
else if (duplicateMode.equalsIgnoreCase(DELETE))
|
||||
{
|
||||
delete(searchUserName, best);
|
||||
s_logger.info("Deleted duplicate person objects for uid " + searchUserName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_logger.isDebugEnabled())
|
||||
{
|
||||
s_logger.debug("Duplicate person objects exist for uid " + searchUserName);
|
||||
}
|
||||
}
|
||||
addDuplicateUserNameToHandle(searchUserName, best);
|
||||
return best;
|
||||
}
|
||||
else
|
||||
@@ -343,6 +354,74 @@ public class PersonServiceImpl implements PersonService,
|
||||
}
|
||||
}
|
||||
|
||||
private static final String KEY_POST_TXN_DUPLICATES = "PersonServiceImpl.KEY_POST_TXN_DUPLICATES";
|
||||
/**
|
||||
* Get the txn-bound usernames that need cleaning up
|
||||
*/
|
||||
private Map<String, NodeRef> getPostTxnDuplicates()
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, NodeRef> postTxnDuplicates = (Map<String, NodeRef>) AlfrescoTransactionSupport.getResource(KEY_POST_TXN_DUPLICATES);
|
||||
if (postTxnDuplicates == null)
|
||||
{
|
||||
postTxnDuplicates = new HashMap<String, NodeRef>(7);
|
||||
AlfrescoTransactionSupport.bindResource(KEY_POST_TXN_DUPLICATES, postTxnDuplicates);
|
||||
}
|
||||
return postTxnDuplicates;
|
||||
}
|
||||
/**
|
||||
* Flag a username for cleanup after the transaction.
|
||||
*/
|
||||
private void addDuplicateUserNameToHandle(String searchUserName, NodeRef best)
|
||||
{
|
||||
// Firstly, bind this service to the transaction
|
||||
AlfrescoTransactionSupport.bindListener(this);
|
||||
// Now get the post txn duplicate list
|
||||
Map<String, NodeRef> postTxnDuplicates = getPostTxnDuplicates();
|
||||
postTxnDuplicates.put(searchUserName, best);
|
||||
}
|
||||
/**
|
||||
* Process clean up any duplicates that were flagged during the transaction.
|
||||
*/
|
||||
@Override
|
||||
public void afterCommit()
|
||||
{
|
||||
// Get the duplicates in a form that can be read by the transaction work anonymous instance
|
||||
final Map<String, NodeRef> postTxnDuplicates = getPostTxnDuplicates();
|
||||
|
||||
RetryingTransactionCallback<Object> processDuplicateWork = new RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute() throws Throwable
|
||||
{
|
||||
for (Map.Entry<String, NodeRef> entry : postTxnDuplicates.entrySet())
|
||||
{
|
||||
String username = entry.getKey();
|
||||
NodeRef best = entry.getValue();
|
||||
if (duplicateMode.equalsIgnoreCase(SPLIT))
|
||||
{
|
||||
split(username, best);
|
||||
s_logger.info("Split duplicate person objects for uid " + username);
|
||||
}
|
||||
else if (duplicateMode.equalsIgnoreCase(DELETE))
|
||||
{
|
||||
delete(username, best);
|
||||
s_logger.info("Deleted duplicate person objects for uid " + username);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_logger.isDebugEnabled())
|
||||
{
|
||||
s_logger.debug("Duplicate person objects exist for uid " + username);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Done
|
||||
return null;
|
||||
}
|
||||
};
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(processDuplicateWork, false, true);
|
||||
}
|
||||
|
||||
private void delete(String searchUserName, NodeRef best)
|
||||
{
|
||||
SearchParameters sp = new SearchParameters();
|
||||
@@ -799,6 +878,11 @@ public class PersonServiceImpl implements PersonService,
|
||||
this.permissionServiceSPI = permissionServiceSPI;
|
||||
}
|
||||
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
|
Reference in New Issue
Block a user