mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-15 15:02:20 +00:00
Merged 5.0.N (5.0.4) to 5.1.N (5.1.2)
124888 jvonka: Merged 50N-NDB (5.0.4) to 5.0.N (5.0.4)
124735: MNT-15211: Follow-on (note: only affects NDB) - tweaks for further repo tests, including:
- FileFolderServiceImplTest.testMoveCopyLotsOfFiles
- DbNodeServiceImplTest.testDuplicateCatch
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.1.N/root@124938 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -3143,6 +3143,28 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
|
|||||||
// Index
|
// Index
|
||||||
assoc.setAssocIndex(-1);
|
assoc.setAssocIndex(-1);
|
||||||
|
|
||||||
|
Long assocId = newChildAssocImplInsert(assoc, assocTypeQName, childNodeName);
|
||||||
|
|
||||||
|
// Persist it
|
||||||
|
assoc.setId(assocId);
|
||||||
|
|
||||||
|
// Primary associations accompany new nodes, so we only have to bring the
|
||||||
|
// node into the current transaction for secondary associations
|
||||||
|
if (!isPrimary)
|
||||||
|
{
|
||||||
|
updateNode(childNodeId, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done
|
||||||
|
if (isDebugEnabled)
|
||||||
|
{
|
||||||
|
logger.debug("Created child association: " + assoc);
|
||||||
|
}
|
||||||
|
return assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Long newChildAssocImplInsert(final ChildAssocEntity assoc, final QName assocTypeQName, final String childNodeName)
|
||||||
|
{
|
||||||
RetryingCallback<Long> callback = new RetryingCallback<Long>()
|
RetryingCallback<Long> callback = new RetryingCallback<Long>()
|
||||||
{
|
{
|
||||||
public Long execute() throws Throwable
|
public Long execute() throws Throwable
|
||||||
@@ -3175,7 +3197,7 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
|
|||||||
|
|
||||||
// We assume that this is from the child cm:name constraint violation
|
// We assume that this is from the child cm:name constraint violation
|
||||||
throw new DuplicateChildNodeNameException(
|
throw new DuplicateChildNodeNameException(
|
||||||
parentNode.getNodeRef(),
|
assoc.getParentNode().getNodeRef(),
|
||||||
assocTypeQName,
|
assocTypeQName,
|
||||||
childNodeName,
|
childNodeName,
|
||||||
e);
|
e);
|
||||||
@@ -3183,22 +3205,7 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
Long assocId = childAssocRetryingHelper.doWithRetry(callback);
|
Long assocId = childAssocRetryingHelper.doWithRetry(callback);
|
||||||
// Persist it
|
return assocId;
|
||||||
assoc.setId(assocId);
|
|
||||||
|
|
||||||
// Primary associations accompany new nodes, so we only have to bring the
|
|
||||||
// node into the current transaction for secondary associations
|
|
||||||
if (!isPrimary)
|
|
||||||
{
|
|
||||||
updateNode(childNodeId, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done
|
|
||||||
if (isDebugEnabled)
|
|
||||||
{
|
|
||||||
logger.debug("Created child association: " + assoc);
|
|
||||||
}
|
|
||||||
return assoc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import org.alfresco.repo.domain.node.TransactionQueryEntity;
|
|||||||
import org.alfresco.repo.domain.qname.QNameDAO;
|
import org.alfresco.repo.domain.qname.QNameDAO;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
@@ -63,6 +64,7 @@ import org.apache.ibatis.session.ResultContext;
|
|||||||
import org.apache.ibatis.session.ResultHandler;
|
import org.apache.ibatis.session.ResultHandler;
|
||||||
import org.apache.ibatis.session.RowBounds;
|
import org.apache.ibatis.session.RowBounds;
|
||||||
import org.mybatis.spring.SqlSessionTemplate;
|
import org.mybatis.spring.SqlSessionTemplate;
|
||||||
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
|
||||||
@@ -1755,6 +1757,12 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
|
|||||||
*/
|
*/
|
||||||
public static class MySQLClusterNDB extends MySQL
|
public static class MySQLClusterNDB extends MySQL
|
||||||
{
|
{
|
||||||
|
// eg. see
|
||||||
|
// ArchiveAndRestoreTest.*,
|
||||||
|
// LargeArchiveAndRestoreTest.testCreateAndRestore (also bumped MaxNoOfFiredTriggers from 4000 to 12000)
|
||||||
|
// DbNodeServiceImplTest.testNodeStatus
|
||||||
|
// MultilingualDocumentAspectTest.testDeleteNode
|
||||||
|
// ...
|
||||||
@Override
|
@Override
|
||||||
protected Long newNodeImplInsert(NodeEntity node)
|
protected Long newNodeImplInsert(NodeEntity node)
|
||||||
{
|
{
|
||||||
@@ -1796,6 +1804,42 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
|
|||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eg. see DbNodeServiceImplTest.testDuplicateCatch
|
||||||
|
@Override
|
||||||
|
protected Long newChildAssocImplInsert(final ChildAssocEntity assoc, final QName assocTypeQName, final String childNodeName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Long id = insertChildAssoc(assoc);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
// DuplicateChildNodeNameException implements DoNotRetryException.
|
||||||
|
|
||||||
|
// Allow real DB concurrency issues (e.g. DeadlockLoserDataAccessException) straight through for a retry
|
||||||
|
if (e instanceof ConcurrencyFailureException)
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There are some cases - FK violations, specifically - where we DO actually want to retry.
|
||||||
|
// Detecting this is done by looking for the related FK names, 'fk_alf_cass_*' in the error message
|
||||||
|
String lowerMsg = e.getMessage().toLowerCase();
|
||||||
|
if (lowerMsg.contains("fk_alf_cass_"))
|
||||||
|
{
|
||||||
|
throw new ConcurrencyFailureException("FK violation updating primary parent association:" + assoc, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We assume that this is from the child cm:name constraint violation
|
||||||
|
throw new DuplicateChildNodeNameException(
|
||||||
|
assoc.getParentNode().getNodeRef(),
|
||||||
|
assocTypeQName,
|
||||||
|
childNodeName,
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
* Copyright (C) 2005-2016 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This file is part of Alfresco
|
* This file is part of Alfresco
|
||||||
*
|
*
|
||||||
@@ -46,6 +46,7 @@ import org.alfresco.repo.dictionary.DictionaryBootstrap;
|
|||||||
import org.alfresco.repo.dictionary.DictionaryDAO;
|
import org.alfresco.repo.dictionary.DictionaryDAO;
|
||||||
import org.alfresco.repo.dictionary.M2Model;
|
import org.alfresco.repo.dictionary.M2Model;
|
||||||
import org.alfresco.repo.dictionary.M2Type;
|
import org.alfresco.repo.dictionary.M2Type;
|
||||||
|
import org.alfresco.repo.domain.hibernate.dialect.AlfrescoMySQLClusterNDBDialect;
|
||||||
import org.alfresco.repo.model.filefolder.FileFolderServiceImpl.InvalidTypeException;
|
import org.alfresco.repo.model.filefolder.FileFolderServiceImpl.InvalidTypeException;
|
||||||
import org.alfresco.repo.node.integrity.IntegrityChecker;
|
import org.alfresco.repo.node.integrity.IntegrityChecker;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
@@ -80,6 +81,7 @@ import org.alfresco.util.FileFilterMode;
|
|||||||
import org.alfresco.util.FileFilterMode.Client;
|
import org.alfresco.util.FileFilterMode.Client;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.junit.experimental.categories.Category;
|
import org.junit.experimental.categories.Category;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.extensions.surf.util.I18NUtil;
|
import org.springframework.extensions.surf.util.I18NUtil;
|
||||||
@@ -1736,7 +1738,7 @@ public class FileFolderServiceImplTest extends TestCase
|
|||||||
checkFileList(pageRes, 6, 0, expectedNames);
|
checkFileList(pageRes, 6, 0, expectedNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMoveCopy3000Files() throws FileNotFoundException
|
public void testMoveCopyLotsOfFiles() throws FileNotFoundException
|
||||||
{
|
{
|
||||||
final String CONTAINING_FOLDER = "CONTAINING FOLDER " + GUID.generate(),
|
final String CONTAINING_FOLDER = "CONTAINING FOLDER " + GUID.generate(),
|
||||||
FOLDER_1 = "FOLDER 1 " + GUID.generate(),
|
FOLDER_1 = "FOLDER 1 " + GUID.generate(),
|
||||||
@@ -1746,8 +1748,18 @@ public class FileFolderServiceImplTest extends TestCase
|
|||||||
folder1 = fileFolderService.create(containingFolder.getNodeRef(), FOLDER_1, ContentModel.TYPE_FOLDER),
|
folder1 = fileFolderService.create(containingFolder.getNodeRef(), FOLDER_1, ContentModel.TYPE_FOLDER),
|
||||||
folder2 = fileFolderService.create(containingFolder.getNodeRef(), FOLDER_2, ContentModel.TYPE_FOLDER);
|
folder2 = fileFolderService.create(containingFolder.getNodeRef(), FOLDER_2, ContentModel.TYPE_FOLDER);
|
||||||
|
|
||||||
// create 3000 files within the folder
|
// create thousand(s) of files within the folder
|
||||||
final int COUNT = 3000;
|
int COUNT = 3000;
|
||||||
|
|
||||||
|
Dialect dialect = (Dialect) ctx.getBean("dialect");
|
||||||
|
if (dialect instanceof AlfrescoMySQLClusterNDBDialect)
|
||||||
|
{
|
||||||
|
// note: to increase the file count on NDB, may need to further bump-up NDB cluster config
|
||||||
|
// eg. DataMemory, IndexMemory, MaxNoOfConcurrentOperations, ...
|
||||||
|
// also consider splitting into separate txns (eg. after each bulk create, move, delete, copy, ...)
|
||||||
|
COUNT = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
for (int index = 0; index < COUNT; index++)
|
for (int index = 0; index < COUNT; index++)
|
||||||
{
|
{
|
||||||
fileFolderService.create(folder1.getNodeRef(), "Name " + index, ContentModel.TYPE_CONTENT);
|
fileFolderService.create(folder1.getNodeRef(), "Name " + index, ContentModel.TYPE_CONTENT);
|
||||||
@@ -1778,11 +1790,13 @@ public class FileFolderServiceImplTest extends TestCase
|
|||||||
assertEquals(COUNT, fileFolderService.listFiles(folders.get(0).getNodeRef()).size());
|
assertEquals(COUNT, fileFolderService.listFiles(folders.get(0).getNodeRef()).size());
|
||||||
|
|
||||||
fileFolderService.delete(folder1.getNodeRef());
|
fileFolderService.delete(folder1.getNodeRef());
|
||||||
|
|
||||||
assertEquals(1, fileFolderService.list(containingFolder.getNodeRef()).size());
|
assertEquals(1, fileFolderService.list(containingFolder.getNodeRef()).size());
|
||||||
|
|
||||||
folder1 = folders.get(0);
|
folder1 = folders.get(0);
|
||||||
// copy back
|
// copy back
|
||||||
FileInfo newFolder = fileFolderService.copy(folder1.getNodeRef(), containingFolder.getNodeRef(), null);
|
FileInfo newFolder = fileFolderService.copy(folder1.getNodeRef(), containingFolder.getNodeRef(), null);
|
||||||
|
|
||||||
assertEquals(2, fileFolderService.list(containingFolder.getNodeRef()).size());
|
assertEquals(2, fileFolderService.list(containingFolder.getNodeRef()).size());
|
||||||
assertEquals(COUNT, fileFolderService.list(newFolder.getNodeRef()).size());
|
assertEquals(COUNT, fileFolderService.list(newFolder.getNodeRef()).size());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user