mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V4.1-BUG-FIX to HEAD
42774: ALF-16367: MT fix for "Exporting a tenant from one instance A and importing it to another Alfresco instance B does not work" 42775: Merged DEV to V4.1-BUG-FIX 42274: First part of ALF-14341: WQS: SOLR Request failed wit error 500: DTENANT_FILTER_FROM_JSON WQS jobs don't execute if repository is in the bootstrapping state. RepositoryState class was made thread safe. 42781: ALF-15135: Apple Mail always fails when copying folders with nested folders - Because FileFolderService.resolveNamePath was not properly honouring mustExist==false for parent folders 42798: ALF-16384 - checkLicenseForSyncMode exposed via properties files code comments changed. 42799: ALF-16384 - checkLicenseForSyncMode exposed via properties files properties comments changed. 42801: Merged BRANCHES/DEV/BELARUS/V4.1-BUG-FIX-2012_10_17 to BRANCHES/DEV/V4.1-BUG-FIX: 42748: ALF-14200: Adding Invalid Aspects Via CMIS ATOM API Results in NullPointerException 42802: Fix failing NodeServiceTest - Moved parentless node validation to correct location to avoid NPEs in indexing - Fixed unit test to temporarily disable indexing in order to be able to create a corrupt parentless node git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@42803 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -2376,13 +2376,23 @@ public class CMISConnector implements ApplicationContextAware, ApplicationListen
|
||||
for (String aspect : aspectsToRemove)
|
||||
{
|
||||
aspectType = aspect;
|
||||
nodeService.removeAspect(nodeRef, getType(aspect).getAlfrescoName());
|
||||
TypeDefinitionWrapper type = getType(aspect);
|
||||
if (type == null)
|
||||
{
|
||||
throw new CmisInvalidArgumentException("Invalid aspect: " + aspectType);
|
||||
}
|
||||
nodeService.removeAspect(nodeRef, type.getAlfrescoName());
|
||||
}
|
||||
|
||||
for (String aspect : aspectsToAdd)
|
||||
{
|
||||
aspectType = aspect;
|
||||
nodeService.addAspect(nodeRef, getType(aspect).getAlfrescoName(),
|
||||
TypeDefinitionWrapper type = getType(aspect);
|
||||
if (type == null)
|
||||
{
|
||||
throw new CmisInvalidArgumentException("Invalid aspect: " + aspectType);
|
||||
}
|
||||
nodeService.addAspect(nodeRef, type.getAlfrescoName(),
|
||||
Collections.<QName, Serializable> emptyMap());
|
||||
}
|
||||
}
|
||||
|
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.alfresco.repo.admin;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* @author Andy
|
||||
*
|
||||
@@ -25,16 +27,32 @@ package org.alfresco.repo.admin;
|
||||
public class RepositoryState
|
||||
{
|
||||
private boolean bootstrapping;
|
||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
public boolean isBootstrapping()
|
||||
{
|
||||
this.lock.readLock().lock();
|
||||
try
|
||||
{
|
||||
return bootstrapping;
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setBootstrapping(boolean bootstrapping)
|
||||
{
|
||||
this.lock.writeLock().lock();
|
||||
try
|
||||
{
|
||||
this.bootstrapping = bootstrapping;
|
||||
}
|
||||
|
||||
finally
|
||||
{
|
||||
this.lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -3867,30 +3867,6 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
|
||||
completedPaths.add(pathToSave);
|
||||
}
|
||||
|
||||
if (!hasParents && !parentAssocInfo.isStoreRoot())
|
||||
{
|
||||
// We appear to have an orphaned node. But we may just have a temporarily out of sync clustered cache or a
|
||||
// transaction that started ages before the one that committed the cache content!. So double check the node
|
||||
// isn't actually deleted.
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Stale cache detected for Node #" + currentNodeId + ": removing from cache.");
|
||||
}
|
||||
invalidateNodeCaches(currentNodeId);
|
||||
|
||||
Status currentNodeStatus = getNodeRefStatus(currentNodeRef);
|
||||
if (currentNodeStatus == null || currentNodeStatus.isDeleted())
|
||||
{
|
||||
// Force a retry. The cached node was stale
|
||||
throw new DataIntegrityViolationException("Stale cache detected for Node #" + currentNodeId);
|
||||
}
|
||||
|
||||
// We have a corrupt repository - non-root node has a missing parent ?!
|
||||
bindFixAssocAndCollectLostAndFound(currentNodePair, "nonRootNodeWithoutParents", null, false);
|
||||
|
||||
// throw - error will be logged and then bound txn listener (afterRollback) will be called
|
||||
throw new NonRootNodeWithoutParentsException(currentNodePair);
|
||||
}
|
||||
// walk up each parent association
|
||||
for (Map.Entry<Long, ChildAssocEntity> entry : parentAssocInfo.getParentAssocs().entrySet())
|
||||
{
|
||||
@@ -4113,6 +4089,19 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
|
||||
value = loadParentAssocs(node.getNodeVersionKey());
|
||||
parentAssocsCache.put(cacheKey, value);
|
||||
}
|
||||
|
||||
// We have already validated on loading that we have a list in sync with the child node, so if the list is still
|
||||
// empty we have an integrity problem
|
||||
if (value.getPrimaryParentAssoc() == null && !value.isStoreRoot())
|
||||
{
|
||||
Pair<Long, NodeRef> currentNodePair = node.getNodePair();
|
||||
// We have a corrupt repository - non-root node has a missing parent ?!
|
||||
bindFixAssocAndCollectLostAndFound(currentNodePair, "nonRootNodeWithoutParents", null, false);
|
||||
|
||||
// throw - error will be logged and then bound txn listener (afterRollback) will be called
|
||||
throw new NonRootNodeWithoutParentsException(currentNodePair);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -4185,7 +4174,7 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
|
||||
// and the lack of parent associations will be cached, anyway.
|
||||
// But to match earlier fixes of ALF-12393, we do a double-check of the node's details
|
||||
NodeEntity nodeCheckFromDb = selectNodeById(nodeId);
|
||||
if (nodeCheckFromDb == null || !nodeCheckFromDb.getNodeVersionKey().equals(nodeVersionKey))
|
||||
if (nodeCheckFromDb == null || nodeCheckFromDb.getDeleted(qnameDAO) || !nodeCheckFromDb.getNodeVersionKey().equals(nodeVersionKey))
|
||||
{
|
||||
// The node is gone or has moved on in version
|
||||
invalidateNodeCaches(nodeId);
|
||||
|
@@ -1367,9 +1367,14 @@ public class FileFolderServiceImpl implements FileFolderService
|
||||
NodeRef folderNodeRef = searchSimple(parentNodeRef, pathElement);
|
||||
if (folderNodeRef == null)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
sb.append("Folder not found: " + currentPath);
|
||||
throw new FileNotFoundException(sb.toString());
|
||||
if (mustExist)
|
||||
{
|
||||
throw new FileNotFoundException("Folder not found: " + currentPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
parentNodeRef = folderNodeRef;
|
||||
}
|
||||
|
@@ -53,6 +53,7 @@ import org.alfresco.repo.node.NodeServicePolicies.OnUpdateNodePolicy;
|
||||
import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy;
|
||||
import org.alfresco.repo.node.db.NodeHierarchyWalker;
|
||||
import org.alfresco.repo.node.db.NodeHierarchyWalker.VisitedNode;
|
||||
import org.alfresco.repo.node.index.NodeIndexer;
|
||||
import org.alfresco.repo.policy.BehaviourFilter;
|
||||
import org.alfresco.repo.policy.JavaBehaviour;
|
||||
import org.alfresco.repo.policy.Policy;
|
||||
@@ -101,6 +102,7 @@ public class NodeServiceTest extends TestCase
|
||||
|
||||
protected ServiceRegistry serviceRegistry;
|
||||
protected NodeService nodeService;
|
||||
protected NodeIndexer nodeIndexer;
|
||||
protected NodeDAO nodeDAO;
|
||||
private TransactionService txnService;
|
||||
private PolicyComponent policyComponent;
|
||||
@@ -120,6 +122,7 @@ public class NodeServiceTest extends TestCase
|
||||
|
||||
serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
nodeService = serviceRegistry.getNodeService();
|
||||
nodeIndexer = (NodeIndexer) ctx.getBean("nodeIndexer");
|
||||
nodeDAO = (NodeDAO) ctx.getBean("nodeDAO");
|
||||
txnService = serviceRegistry.getTransactionService();
|
||||
policyComponent = (PolicyComponent) ctx.getBean("policyComponent");
|
||||
@@ -1245,6 +1248,10 @@ public class NodeServiceTest extends TestCase
|
||||
|
||||
// forcefully remove the primary parent assoc
|
||||
final Long childNodeId = (Long)nodeService.getProperty(childNodeRef, ContentModel.PROP_NODE_DBID);
|
||||
// We'll need to disable indexing to do this or the transaction will be thrown out
|
||||
nodeIndexer.setDisabled(true);
|
||||
try
|
||||
{
|
||||
txnService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
@Override
|
||||
@@ -1256,6 +1263,11 @@ public class NodeServiceTest extends TestCase
|
||||
}
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
nodeIndexer.setDisabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Now need to identify the problem nodes
|
||||
final List<Long> childNodeIds = getChildNodesWithNoParentNode(params, idsToSkip);
|
||||
|
@@ -449,6 +449,8 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
|
||||
{
|
||||
final String tenantDomain = getTenantDomain(tenantDomainIn);
|
||||
|
||||
AuthenticationUtil.setMtEnabled(true); // in case this is the 1st tenant
|
||||
|
||||
initTenant(tenantDomain, contentRoot);
|
||||
|
||||
try
|
||||
|
Reference in New Issue
Block a user