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:
Dave Ward
2012-10-18 12:03:53 +00:00
parent 18e20933e5
commit 502bb3d954
6 changed files with 77 additions and 41 deletions

View File

@@ -2376,13 +2376,23 @@ public class CMISConnector implements ApplicationContextAware, ApplicationListen
for (String aspect : aspectsToRemove) for (String aspect : aspectsToRemove)
{ {
aspectType = aspect; 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) for (String aspect : aspectsToAdd)
{ {
aspectType = aspect; 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()); Collections.<QName, Serializable> emptyMap());
} }
} }

View File

@@ -18,6 +18,8 @@
*/ */
package org.alfresco.repo.admin; package org.alfresco.repo.admin;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/** /**
* @author Andy * @author Andy
* *
@@ -25,16 +27,32 @@ package org.alfresco.repo.admin;
public class RepositoryState public class RepositoryState
{ {
private boolean bootstrapping; private boolean bootstrapping;
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public boolean isBootstrapping() public boolean isBootstrapping()
{
this.lock.readLock().lock();
try
{ {
return bootstrapping; return bootstrapping;
} }
finally
{
this.lock.readLock().unlock();
}
}
public void setBootstrapping(boolean bootstrapping) public void setBootstrapping(boolean bootstrapping)
{
this.lock.writeLock().lock();
try
{ {
this.bootstrapping = bootstrapping; this.bootstrapping = bootstrapping;
} }
finally
{
this.lock.writeLock().unlock();
}
}
} }

View File

@@ -3867,30 +3867,6 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
completedPaths.add(pathToSave); 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 // walk up each parent association
for (Map.Entry<Long, ChildAssocEntity> entry : parentAssocInfo.getParentAssocs().entrySet()) for (Map.Entry<Long, ChildAssocEntity> entry : parentAssocInfo.getParentAssocs().entrySet())
{ {
@@ -4113,6 +4089,19 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
value = loadParentAssocs(node.getNodeVersionKey()); value = loadParentAssocs(node.getNodeVersionKey());
parentAssocsCache.put(cacheKey, value); 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; return value;
} }
@@ -4185,7 +4174,7 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
// and the lack of parent associations will be cached, anyway. // 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 // But to match earlier fixes of ALF-12393, we do a double-check of the node's details
NodeEntity nodeCheckFromDb = selectNodeById(nodeId); 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 // The node is gone or has moved on in version
invalidateNodeCaches(nodeId); invalidateNodeCaches(nodeId);

View File

@@ -1367,9 +1367,14 @@ public class FileFolderServiceImpl implements FileFolderService
NodeRef folderNodeRef = searchSimple(parentNodeRef, pathElement); NodeRef folderNodeRef = searchSimple(parentNodeRef, pathElement);
if (folderNodeRef == null) if (folderNodeRef == null)
{ {
StringBuilder sb = new StringBuilder(128); if (mustExist)
sb.append("Folder not found: " + currentPath); {
throw new FileNotFoundException(sb.toString()); throw new FileNotFoundException("Folder not found: " + currentPath);
}
else
{
return null;
}
} }
parentNodeRef = folderNodeRef; parentNodeRef = folderNodeRef;
} }

View File

@@ -53,6 +53,7 @@ import org.alfresco.repo.node.NodeServicePolicies.OnUpdateNodePolicy;
import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy; import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy;
import org.alfresco.repo.node.db.NodeHierarchyWalker; import org.alfresco.repo.node.db.NodeHierarchyWalker;
import org.alfresco.repo.node.db.NodeHierarchyWalker.VisitedNode; 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.BehaviourFilter;
import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.Policy; import org.alfresco.repo.policy.Policy;
@@ -101,6 +102,7 @@ public class NodeServiceTest extends TestCase
protected ServiceRegistry serviceRegistry; protected ServiceRegistry serviceRegistry;
protected NodeService nodeService; protected NodeService nodeService;
protected NodeIndexer nodeIndexer;
protected NodeDAO nodeDAO; protected NodeDAO nodeDAO;
private TransactionService txnService; private TransactionService txnService;
private PolicyComponent policyComponent; private PolicyComponent policyComponent;
@@ -120,6 +122,7 @@ public class NodeServiceTest extends TestCase
serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
nodeService = serviceRegistry.getNodeService(); nodeService = serviceRegistry.getNodeService();
nodeIndexer = (NodeIndexer) ctx.getBean("nodeIndexer");
nodeDAO = (NodeDAO) ctx.getBean("nodeDAO"); nodeDAO = (NodeDAO) ctx.getBean("nodeDAO");
txnService = serviceRegistry.getTransactionService(); txnService = serviceRegistry.getTransactionService();
policyComponent = (PolicyComponent) ctx.getBean("policyComponent"); policyComponent = (PolicyComponent) ctx.getBean("policyComponent");
@@ -1245,6 +1248,10 @@ public class NodeServiceTest extends TestCase
// forcefully remove the primary parent assoc // forcefully remove the primary parent assoc
final Long childNodeId = (Long)nodeService.getProperty(childNodeRef, ContentModel.PROP_NODE_DBID); 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>() txnService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
{ {
@Override @Override
@@ -1256,6 +1263,11 @@ public class NodeServiceTest extends TestCase
} }
}); });
} }
finally
{
nodeIndexer.setDisabled(false);
}
}
// Now need to identify the problem nodes // Now need to identify the problem nodes
final List<Long> childNodeIds = getChildNodesWithNoParentNode(params, idsToSkip); final List<Long> childNodeIds = getChildNodesWithNoParentNode(params, idsToSkip);

View File

@@ -449,6 +449,8 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
{ {
final String tenantDomain = getTenantDomain(tenantDomainIn); final String tenantDomain = getTenantDomain(tenantDomainIn);
AuthenticationUtil.setMtEnabled(true); // in case this is the 1st tenant
initTenant(tenantDomain, contentRoot); initTenant(tenantDomain, contentRoot);
try try