From d785b100df430408d441e3a6c8d5e200f292219e Mon Sep 17 00:00:00 2001 From: Antonio Felix Date: Thu, 22 Dec 2022 11:48:55 +0000 Subject: [PATCH] Fix/mnt 23290 slow group membership (#1637) * MNT-23290 - Change query to get the root groups --- .../security/rm-method-security.properties | 1 + .../service/cmr/repository/NodeService.java | 14 +++- .../alfresco/repo/domain/node/NodeDAO.java | 4 +- .../repo/domain/node/ibatis/NodeDAOImpl.java | 18 ++++- .../repo/node/db/DbNodeServiceImpl.java | 11 ++- .../security/authority/AuthorityDAOImpl.java | 9 +-- .../repo/version/NodeServiceImpl.java | 74 ++++++++++--------- .../bundle/VirtualNodeServiceExtension.java | 7 +- .../node-common-SqlMap.xml | 14 ++++ .../public-services-security-context.xml | 1 + 10 files changed, 109 insertions(+), 44 deletions(-) diff --git a/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/security/rm-method-security.properties b/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/security/rm-method-security.properties index 8c9bd9a7e8..60fe652775 100644 --- a/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/security/rm-method-security.properties +++ b/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/security/rm-method-security.properties @@ -47,6 +47,7 @@ rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getPaths=RM.Re rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getStoreArchiveNode=RM_ABSTAIN rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.restoreNode=RM_ABSTAIN rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildAssocsWithoutParentAssocsOfType=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.findAssocsNotLinkedByTwoOtherAssocs=RM_ABSTAIN rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getNodeRef=RM.Read.0 rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildAssocsByPropertyValue=RM.Read.0,AFTER_RM.FilterNode rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.countChildAssocs=RM.Read.0 diff --git a/data-model/src/main/java/org/alfresco/service/cmr/repository/NodeService.java b/data-model/src/main/java/org/alfresco/service/cmr/repository/NodeService.java index 449b4dad9c..b2d59e4935 100644 --- a/data-model/src/main/java/org/alfresco/service/cmr/repository/NodeService.java +++ b/data-model/src/main/java/org/alfresco/service/cmr/repository/NodeService.java @@ -2,7 +2,7 @@ * #%L * Alfresco Data model classes * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited + * Copyright (C) 2005 - 2022 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of @@ -714,6 +714,18 @@ public interface NodeService final NodeRef parent, final QName assocTypeQName); + /** + * Gets the list of the localnames of the child associations without parent node + * + * @param parent + * the parent node reference + * @return a list of the local names of the child associations + */ + @Auditable(parameters = {"parent"}) + public List findAssocsNotLinkedByTwoOtherAssocs( + final NodeRef parent); + + /** * Create a peer association between two nodes. *

diff --git a/repository/src/main/java/org/alfresco/repo/domain/node/NodeDAO.java b/repository/src/main/java/org/alfresco/repo/domain/node/NodeDAO.java index 787587761e..3c1bb2675d 100644 --- a/repository/src/main/java/org/alfresco/repo/domain/node/NodeDAO.java +++ b/repository/src/main/java/org/alfresco/repo/domain/node/NodeDAO.java @@ -2,7 +2,7 @@ * #%L * Alfresco Repository * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited + * Copyright (C) 2005 - 2022 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of @@ -894,6 +894,8 @@ public interface NodeDAO extends NodeBulkLoader Serializable nodeValue, ChildAssocRefQueryCallback resultsCallback); + public abstract List selectAssocsNotLinkedByTwoOtherAssocs( + Long parentNodeId); /** * Used by the re-encryptor to re-encrypt encryptable properties with a new encryption key. */ diff --git a/repository/src/main/java/org/alfresco/repo/domain/node/ibatis/NodeDAOImpl.java b/repository/src/main/java/org/alfresco/repo/domain/node/ibatis/NodeDAOImpl.java index e1e9e546f9..a387385de0 100644 --- a/repository/src/main/java/org/alfresco/repo/domain/node/ibatis/NodeDAOImpl.java +++ b/repository/src/main/java/org/alfresco/repo/domain/node/ibatis/NodeDAOImpl.java @@ -2,7 +2,7 @@ * #%L * Alfresco Repository * %% - * Copyright (C) 2005 - 2021 Alfresco Software Limited + * Copyright (C) 2005 - 2022 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of @@ -139,6 +139,8 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl private static final String SELECT_CHILD_ASSOC_OF_PARENT_BY_NAME = "alfresco.node.select_ChildAssocOfParentByName"; private static final String SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_PARENT_ASSOCS_OF_TYPE = "alfresco.node.select_ChildAssocsOfParentWithoutParentAssocsOfType"; + + private static final String SELECT_ASSOCS_NOT_LINKED_BY_TWO_OTHER_ASSOCS = "alfresco.node.select_AssocsNotLinkedByTwoOtherAssocs"; private static final String SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_NODE_ASSOCS_OF_TYPE = "alfresco.node.select_ChildAssocsOfParentWithoutNodeAssocsOfType"; private static final String SELECT_PARENT_ASSOCS_OF_CHILD = "alfresco.node.select_ParentAssocsOfChild"; @@ -1415,11 +1417,23 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl assoc.setOrdered(resultsCallback.orderResults()); ChildAssocResultHandler resultHandler = new ChildAssocResultHandler(resultsCallback); - + template.select(SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_PARENT_ASSOCS_OF_TYPE, assoc, resultHandler); resultsCallback.done(); } + public List selectAssocsNotLinkedByTwoOtherAssocs( + Long parentNodeId) + { + ChildAssocEntity assoc = new ChildAssocEntity(); + // Parent + NodeEntity parentNode = new NodeEntity(); + parentNode.setId(parentNodeId); + assoc.setParentNode(parentNode); + // Type QName + return template.selectList(SELECT_ASSOCS_NOT_LINKED_BY_TWO_OTHER_ASSOCS, assoc); + } + @Override public List selectChildAssocsWithoutNodeAssocsOfTypes(Long parentNodeId, Long minNodeId, Long maxNodeId, Set assocTypeQNames) { diff --git a/repository/src/main/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java b/repository/src/main/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java index cd6e33f032..e0c19856b9 100644 --- a/repository/src/main/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java +++ b/repository/src/main/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java @@ -2133,7 +2133,16 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl implements Extens // done return results; } - + + @Extend(traitAPI=NodeServiceTrait.class,extensionAPI=NodeServiceExtension.class) + public List findAssocsNotLinkedByTwoOtherAssocs(NodeRef parent) + { + // Get the parent node + Pair nodePair = getNodePairNotNull(parent); + Long parentNodeId = nodePair.getFirst(); + + return nodeDAO.selectAssocsNotLinkedByTwoOtherAssocs(parentNodeId); + } /** * Specific properties not supported by {@link #getChildAssocsByPropertyValue(NodeRef, QName, Serializable)} */ diff --git a/repository/src/main/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java b/repository/src/main/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java index 8e930b3497..f72f4b5177 100644 --- a/repository/src/main/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java +++ b/repository/src/main/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java @@ -2,7 +2,7 @@ * #%L * Alfresco Repository * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited + * Copyright (C) 2005 - 2022 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of @@ -48,7 +48,6 @@ import org.alfresco.query.CannedQueryFactory; import org.alfresco.query.CannedQueryResults; import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingResults; -import org.alfresco.repo.cache.AsynchronouslyRefreshedCache; import org.alfresco.util.cache.RefreshableCacheEvent; import org.alfresco.util.cache.RefreshableCacheListener; import org.alfresco.repo.cache.SimpleCache; @@ -1566,11 +1565,11 @@ public class AuthorityDAOImpl implements AuthorityDAO, NodeServicePolicies.Befor { return Collections. emptySet(); } - Collection childRefs = nodeService.getChildAssocsWithoutParentAssocsOfType(container, ContentModel.ASSOC_MEMBER); + List rootGroupsNames = nodeService.findAssocsNotLinkedByTwoOtherAssocs(container); Set authorities = new TreeSet(); - for (ChildAssociationRef childRef : childRefs) + for (String rootGroupName : rootGroupsNames) { - addAuthorityNameIfMatches(authorities, childRef.getQName().getLocalName(), type); + addAuthorityNameIfMatches(authorities, rootGroupName, type); } return authorities; } diff --git a/repository/src/main/java/org/alfresco/repo/version/NodeServiceImpl.java b/repository/src/main/java/org/alfresco/repo/version/NodeServiceImpl.java index aa3d2514f8..b8c40cc21b 100644 --- a/repository/src/main/java/org/alfresco/repo/version/NodeServiceImpl.java +++ b/repository/src/main/java/org/alfresco/repo/version/NodeServiceImpl.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - * #L% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2022 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ package org.alfresco.repo.version; import java.io.Serializable; @@ -656,13 +656,13 @@ public class NodeServiceImpl implements NodeService, VersionModel throw new UnsupportedOperationException(MSG_UNSUPPORTED); } - /** - * Gets an association by ID. - * - * @param id - * the association id - * @return the association, or null if it does not exist - */ + /** + * Gets an association by ID. + * + * @param id + * the association id + * @return the association, or null if it does not exist + */ public AssociationRef getAssoc(Long id) { return null; @@ -762,7 +762,15 @@ public class NodeServiceImpl implements NodeService, VersionModel public Collection getChildAssocsWithoutParentAssocsOfType(NodeRef parent, QName assocTypeQName) { throw new UnsupportedOperationException(MSG_UNSUPPORTED); - } + } + + /** + * @throws UnsupportedOperationException always + */ + public List findAssocsNotLinkedByTwoOtherAssocs(NodeRef parent) + { + throw new UnsupportedOperationException(MSG_UNSUPPORTED); + } /** * Gets, converts and adds the intrinsic properties to the current node's properties diff --git a/repository/src/main/java/org/alfresco/repo/virtual/bundle/VirtualNodeServiceExtension.java b/repository/src/main/java/org/alfresco/repo/virtual/bundle/VirtualNodeServiceExtension.java index 7c752236e8..1cf368d1f1 100644 --- a/repository/src/main/java/org/alfresco/repo/virtual/bundle/VirtualNodeServiceExtension.java +++ b/repository/src/main/java/org/alfresco/repo/virtual/bundle/VirtualNodeServiceExtension.java @@ -2,7 +2,7 @@ * #%L * Alfresco Repository * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited + * Copyright (C) 2005 - 2022 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of @@ -1467,6 +1467,11 @@ public class VirtualNodeServiceExtension extends VirtualSpringBeanExtension findAssocsNotLinkedByTwoOtherAssocs(NodeRef nodeRef){ + return getTrait().findAssocsNotLinkedByTwoOtherAssocs(nodeRef); + } + @Override public void removeAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) throws InvalidNodeRefException diff --git a/repository/src/main/resources/alfresco/ibatis/org.alfresco.repo.domain.dialect.Dialect/node-common-SqlMap.xml b/repository/src/main/resources/alfresco/ibatis/org.alfresco.repo.domain.dialect.Dialect/node-common-SqlMap.xml index 2c1ba5bf32..f208f3d222 100644 --- a/repository/src/main/resources/alfresco/ibatis/org.alfresco.repo.domain.dialect.Dialect/node-common-SqlMap.xml +++ b/repository/src/main/resources/alfresco/ibatis/org.alfresco.repo.domain.dialect.Dialect/node-common-SqlMap.xml @@ -1147,6 +1147,20 @@ parentNode.id = #{parentNode.id} and a.child_node_id IS NULL + +