Fix/mnt 23290 slow group membership (#1637)

* MNT-23290 - Change query to get the root groups
This commit is contained in:
Antonio Felix
2022-12-22 11:48:55 +00:00
committed by GitHub
parent 3b25edefd1
commit d785b100df
10 changed files with 109 additions and 44 deletions

View File

@@ -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.getStoreArchiveNode=RM_ABSTAIN
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.restoreNode=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.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.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.getChildAssocsByPropertyValue=RM.Read.0,AFTER_RM.FilterNode
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.countChildAssocs=RM.Read.0 rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.countChildAssocs=RM.Read.0

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Data model classes * 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. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -714,6 +714,18 @@ public interface NodeService
final NodeRef parent, final NodeRef parent,
final QName assocTypeQName); 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<String> findAssocsNotLinkedByTwoOtherAssocs(
final NodeRef parent);
/** /**
* Create a peer association between two nodes. * Create a peer association between two nodes.
* <p/> * <p/>

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2022 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -894,6 +894,8 @@ public interface NodeDAO extends NodeBulkLoader
Serializable nodeValue, Serializable nodeValue,
ChildAssocRefQueryCallback resultsCallback); ChildAssocRefQueryCallback resultsCallback);
public abstract List<String> selectAssocsNotLinkedByTwoOtherAssocs(
Long parentNodeId);
/** /**
* Used by the re-encryptor to re-encrypt encryptable properties with a new encryption key. * Used by the re-encryptor to re-encrypt encryptable properties with a new encryption key.
*/ */

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited * Copyright (C) 2005 - 2022 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * 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_ASSOC_OF_PARENT_BY_NAME = "alfresco.node.select_ChildAssocOfParentByName";
private static final String SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_PARENT_ASSOCS_OF_TYPE = private static final String SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_PARENT_ASSOCS_OF_TYPE =
"alfresco.node.select_ChildAssocsOfParentWithoutParentAssocsOfType"; "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 = private static final String SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_NODE_ASSOCS_OF_TYPE =
"alfresco.node.select_ChildAssocsOfParentWithoutNodeAssocsOfType"; "alfresco.node.select_ChildAssocsOfParentWithoutNodeAssocsOfType";
private static final String SELECT_PARENT_ASSOCS_OF_CHILD = "alfresco.node.select_ParentAssocsOfChild"; 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()); assoc.setOrdered(resultsCallback.orderResults());
ChildAssocResultHandler resultHandler = new ChildAssocResultHandler(resultsCallback); ChildAssocResultHandler resultHandler = new ChildAssocResultHandler(resultsCallback);
template.select(SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_PARENT_ASSOCS_OF_TYPE, assoc, resultHandler); template.select(SELECT_CHILD_ASSOCS_OF_PARENT_WITHOUT_PARENT_ASSOCS_OF_TYPE, assoc, resultHandler);
resultsCallback.done(); resultsCallback.done();
} }
public List<String> 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 @Override
public List<Node> selectChildAssocsWithoutNodeAssocsOfTypes(Long parentNodeId, Long minNodeId, Long maxNodeId, Set<QName> assocTypeQNames) public List<Node> selectChildAssocsWithoutNodeAssocsOfTypes(Long parentNodeId, Long minNodeId, Long maxNodeId, Set<QName> assocTypeQNames)
{ {

View File

@@ -2133,7 +2133,16 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl implements Extens
// done // done
return results; return results;
} }
@Extend(traitAPI=NodeServiceTrait.class,extensionAPI=NodeServiceExtension.class)
public List<String> findAssocsNotLinkedByTwoOtherAssocs(NodeRef parent)
{
// Get the parent node
Pair<Long, NodeRef> nodePair = getNodePairNotNull(parent);
Long parentNodeId = nodePair.getFirst();
return nodeDAO.selectAssocsNotLinkedByTwoOtherAssocs(parentNodeId);
}
/** /**
* Specific properties <b>not</b> supported by {@link #getChildAssocsByPropertyValue(NodeRef, QName, Serializable)} * Specific properties <b>not</b> supported by {@link #getChildAssocsByPropertyValue(NodeRef, QName, Serializable)}
*/ */

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2022 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * 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.CannedQueryResults;
import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults; import org.alfresco.query.PagingResults;
import org.alfresco.repo.cache.AsynchronouslyRefreshedCache;
import org.alfresco.util.cache.RefreshableCacheEvent; import org.alfresco.util.cache.RefreshableCacheEvent;
import org.alfresco.util.cache.RefreshableCacheListener; import org.alfresco.util.cache.RefreshableCacheListener;
import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.cache.SimpleCache;
@@ -1566,11 +1565,11 @@ public class AuthorityDAOImpl implements AuthorityDAO, NodeServicePolicies.Befor
{ {
return Collections.<String> emptySet(); return Collections.<String> emptySet();
} }
Collection<ChildAssociationRef> childRefs = nodeService.getChildAssocsWithoutParentAssocsOfType(container, ContentModel.ASSOC_MEMBER); List<String> rootGroupsNames = nodeService.findAssocsNotLinkedByTwoOtherAssocs(container);
Set<String> authorities = new TreeSet<String>(); Set<String> authorities = new TreeSet<String>();
for (ChildAssociationRef childRef : childRefs) for (String rootGroupName : rootGroupsNames)
{ {
addAuthorityNameIfMatches(authorities, childRef.getQName().getLocalName(), type); addAuthorityNameIfMatches(authorities, rootGroupName, type);
} }
return authorities; return authorities;
} }

View File

@@ -1,28 +1,28 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2022 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * 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 * 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 * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.version; package org.alfresco.repo.version;
import java.io.Serializable; import java.io.Serializable;
@@ -656,13 +656,13 @@ public class NodeServiceImpl implements NodeService, VersionModel
throw new UnsupportedOperationException(MSG_UNSUPPORTED); throw new UnsupportedOperationException(MSG_UNSUPPORTED);
} }
/** /**
* Gets an association by ID. * Gets an association by ID.
* *
* @param id * @param id
* the association id * the association id
* @return the association, or <code>null</code> if it does not exist * @return the association, or <code>null</code> if it does not exist
*/ */
public AssociationRef getAssoc(Long id) public AssociationRef getAssoc(Long id)
{ {
return null; return null;
@@ -762,7 +762,15 @@ public class NodeServiceImpl implements NodeService, VersionModel
public Collection<ChildAssociationRef> getChildAssocsWithoutParentAssocsOfType(NodeRef parent, QName assocTypeQName) public Collection<ChildAssociationRef> getChildAssocsWithoutParentAssocsOfType(NodeRef parent, QName assocTypeQName)
{ {
throw new UnsupportedOperationException(MSG_UNSUPPORTED); throw new UnsupportedOperationException(MSG_UNSUPPORTED);
} }
/**
* @throws UnsupportedOperationException always
*/
public List<String> findAssocsNotLinkedByTwoOtherAssocs(NodeRef parent)
{
throw new UnsupportedOperationException(MSG_UNSUPPORTED);
}
/** /**
* Gets, converts and adds the intrinsic properties to the current node's properties * Gets, converts and adds the intrinsic properties to the current node's properties

View File

@@ -2,7 +2,7 @@
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited * Copyright (C) 2005 - 2022 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
@@ -1467,6 +1467,11 @@ public class VirtualNodeServiceExtension extends VirtualSpringBeanExtension<Node
} }
} }
@Override
public List<String> findAssocsNotLinkedByTwoOtherAssocs(NodeRef nodeRef){
return getTrait().findAssocsNotLinkedByTwoOtherAssocs(nodeRef);
}
@Override @Override
public void removeAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) public void removeAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName)
throws InvalidNodeRefException throws InvalidNodeRefException

View File

@@ -1147,6 +1147,20 @@
parentNode.id = #{parentNode.id} and parentNode.id = #{parentNode.id} and
a.child_node_id IS NULL a.child_node_id IS NULL
</select> </select>
<select id="select_AssocsNotLinkedByTwoOtherAssocs" parameterType="ChildAssoc" resultType="java.lang.String">
select distinct c.qname_localname
from alf_child_assoc c
where c.parent_node_id = #{parentNode.id}
and not exists (
select 1
from alf_child_assoc a
join alf_child_assoc z
on z.parent_node_id = #{parentNode.id}
and z.child_node_id = a.parent_node_id
where c.child_node_id = a.child_node_id
);
</select>
<select id="select_ChildAssocsByPropertyValue" parameterType="ChildProperty" resultMap="result_ChildAssoc"> <select id="select_ChildAssocsByPropertyValue" parameterType="ChildProperty" resultMap="result_ChildAssoc">
<include refid="alfresco.node.select_ChildAssoc_Results"/> <include refid="alfresco.node.select_ChildAssoc_Results"/>

View File

@@ -425,6 +425,7 @@
org.alfresco.service.cmr.repository.NodeService.getStoreArchiveNode=ACL_NODE.0.sys:base.Read org.alfresco.service.cmr.repository.NodeService.getStoreArchiveNode=ACL_NODE.0.sys:base.Read
org.alfresco.service.cmr.repository.NodeService.restoreNode=ACL_NODE.0.sys:base.DeleteNode,ACL_NODE.1.sys:base.CreateChildren org.alfresco.service.cmr.repository.NodeService.restoreNode=ACL_NODE.0.sys:base.DeleteNode,ACL_NODE.1.sys:base.CreateChildren
org.alfresco.service.cmr.repository.NodeService.getChildAssocsWithoutParentAssocsOfType=ACL_NODE.0.sys:base.ReadProperties,AFTER_ACL_NODE.sys:base.ReadProperties org.alfresco.service.cmr.repository.NodeService.getChildAssocsWithoutParentAssocsOfType=ACL_NODE.0.sys:base.ReadProperties,AFTER_ACL_NODE.sys:base.ReadProperties
org.alfresco.service.cmr.repository.NodeService.findAssocsNotLinkedByTwoOtherAssocs=ACL_NODE.0.sys:base.ReadProperties,AFTER_ACL_NODE.sys:base.ReadProperties
org.alfresco.service.cmr.repository.NodeService.countChildAssocs=ACL_NODE.0.sys:base.ReadChildren org.alfresco.service.cmr.repository.NodeService.countChildAssocs=ACL_NODE.0.sys:base.ReadChildren
org.alfresco.service.cmr.repository.NodeService.*=ACL_DENY org.alfresco.service.cmr.repository.NodeService.*=ACL_DENY
</value> </value>