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)
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user