mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
MNT-22385 Cmis query GetTotalNumItems is returning wrong value (#504)
* Changes made to correct the value of totalItems when performing a TMDQ * Fixes after review - Slight change was made to NodePermissionAssessor to log when permission limits are exceeded * Now pre-computing maxPermissionChecks value as per review suggestion
This commit is contained in:
@@ -112,6 +112,8 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
|
|
||||||
private long maxPermissionCheckTimeMillis;
|
private long maxPermissionCheckTimeMillis;
|
||||||
|
|
||||||
|
private boolean maxPermissionCheckEnabled;
|
||||||
|
|
||||||
protected EntityLookupCache<Long, Node, NodeRef> nodesCache;
|
protected EntityLookupCache<Long, Node, NodeRef> nodesCache;
|
||||||
|
|
||||||
private List<Pair<Long, StoreRef>> stores;
|
private List<Pair<Long, StoreRef>> stores;
|
||||||
@@ -122,7 +124,7 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
{
|
{
|
||||||
this.aclCrudDAO = aclCrudDAO;
|
this.aclCrudDAO = aclCrudDAO;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaxPermissionChecks(int maxPermissionChecks)
|
public void setMaxPermissionChecks(int maxPermissionChecks)
|
||||||
{
|
{
|
||||||
this.maxPermissionChecks = maxPermissionChecks;
|
this.maxPermissionChecks = maxPermissionChecks;
|
||||||
@@ -132,6 +134,11 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
{
|
{
|
||||||
this.maxPermissionCheckTimeMillis = maxPermissionCheckTimeMillis;
|
this.maxPermissionCheckTimeMillis = maxPermissionCheckTimeMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMaxPermissionCheckEnabled(boolean maxPermissionCheckEnabled)
|
||||||
|
{
|
||||||
|
this.maxPermissionCheckEnabled = maxPermissionCheckEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTemplate(SqlSessionTemplate template)
|
public void setTemplate(SqlSessionTemplate template)
|
||||||
{
|
{
|
||||||
@@ -329,13 +336,7 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
@Override
|
@Override
|
||||||
public void handleResult(ResultContext<? extends Node> context)
|
public void handleResult(ResultContext<? extends Node> context)
|
||||||
{
|
{
|
||||||
doHandleResult(permissionAssessor, nodes, requiredNodes, context);
|
if (!maxPermissionCheckEnabled && nodes.size() >= requiredNodes)
|
||||||
}
|
|
||||||
|
|
||||||
private void doHandleResult(NodePermissionAssessor permissionAssessor, List<Node> nodes,
|
|
||||||
int requiredNodes, ResultContext<? extends Node> context)
|
|
||||||
{
|
|
||||||
if (nodes.size() >= requiredNodes)
|
|
||||||
{
|
{
|
||||||
context.stop();
|
context.stop();
|
||||||
return;
|
return;
|
||||||
@@ -344,7 +345,7 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
Node node = context.getResultObject();
|
Node node = context.getResultObject();
|
||||||
addStoreInfo(node);
|
addStoreInfo(node);
|
||||||
|
|
||||||
boolean shouldCache = nodes.size() >= options.getSkipCount();
|
boolean shouldCache = shouldCache(options, nodes, requiredNodes);
|
||||||
if(shouldCache)
|
if(shouldCache)
|
||||||
{
|
{
|
||||||
logger.debug("- selected node "+nodes.size()+": "+node.getUuid()+" "+node.getId());
|
logger.debug("- selected node "+nodes.size()+": "+node.getUuid()+" "+node.getId());
|
||||||
@@ -357,7 +358,14 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
|
|
||||||
if (permissionAssessor.isIncluded(node))
|
if (permissionAssessor.isIncluded(node))
|
||||||
{
|
{
|
||||||
nodes.add(shouldCache ? node : null);
|
if (nodes.size() > requiredNodes)
|
||||||
|
{
|
||||||
|
nodes.add(node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nodes.add(shouldCache ? node : null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (permissionAssessor.shouldQuitChecks())
|
if (permissionAssessor.shouldQuitChecks())
|
||||||
@@ -366,6 +374,18 @@ public class DBQueryEngine implements QueryEngine
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean shouldCache(QueryOptions options, List<Node> nodes, int requiredNodes)
|
||||||
|
{
|
||||||
|
if (nodes.size() > requiredNodes)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nodes.size() >= options.getSkipCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
int numberFound = nodes.size();
|
int numberFound = nodes.size();
|
||||||
|
@@ -41,9 +41,13 @@ import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
|||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.EqualsHelper;
|
import org.alfresco.util.EqualsHelper;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
public class NodePermissionAssessor
|
public class NodePermissionAssessor
|
||||||
{
|
{
|
||||||
|
protected static final Log logger = LogFactory.getLog(NodePermissionAssessor.class);
|
||||||
|
|
||||||
private final boolean isSystemReading;
|
private final boolean isSystemReading;
|
||||||
private final boolean isAdminReading;
|
private final boolean isAdminReading;
|
||||||
private final boolean isNullReading;
|
private final boolean isNullReading;
|
||||||
@@ -138,24 +142,31 @@ public class NodePermissionAssessor
|
|||||||
|
|
||||||
public void setMaxPermissionChecks(int maxPermissionChecks)
|
public void setMaxPermissionChecks(int maxPermissionChecks)
|
||||||
{
|
{
|
||||||
this.maxPermissionChecks = maxPermissionChecks;
|
if (maxPermissionChecks == Integer.MAX_VALUE)
|
||||||
|
{
|
||||||
|
this.maxPermissionChecks = maxPermissionChecks;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.maxPermissionChecks = maxPermissionChecks + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldQuitChecks()
|
public boolean shouldQuitChecks()
|
||||||
{
|
{
|
||||||
boolean result = false;
|
|
||||||
|
|
||||||
if (checksPerformed >= maxPermissionChecks)
|
if (checksPerformed >= maxPermissionChecks)
|
||||||
{
|
{
|
||||||
result = true;
|
logger.warn("Maximum permission checks exceeded (" + maxPermissionChecks + ")");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((System.currentTimeMillis() - startTime) >= maxPermissionCheckTimeMillis)
|
if ((System.currentTimeMillis() - startTime) >= maxPermissionCheckTimeMillis)
|
||||||
{
|
{
|
||||||
result = true;
|
logger.warn("Maximum permission checks time exceeded (" + maxPermissionCheckTimeMillis + ")");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaxPermissionCheckTimeMillis(long maxPermissionCheckTimeMillis)
|
public void setMaxPermissionCheckTimeMillis(long maxPermissionCheckTimeMillis)
|
||||||
|
@@ -153,6 +153,7 @@ system.cache.parentAssocs.limitFactor=8
|
|||||||
system.acl.maxPermissionCheckTimeMillis=10000
|
system.acl.maxPermissionCheckTimeMillis=10000
|
||||||
# The maximum number of search results to perform permission checks against
|
# The maximum number of search results to perform permission checks against
|
||||||
system.acl.maxPermissionChecks=1000
|
system.acl.maxPermissionChecks=1000
|
||||||
|
system.acl.maxPermissionCheckEnabled=false
|
||||||
|
|
||||||
# The maximum number of filefolder list results
|
# The maximum number of filefolder list results
|
||||||
system.filefolderservice.defaultListMaxResults=5000
|
system.filefolderservice.defaultListMaxResults=5000
|
||||||
|
@@ -126,6 +126,9 @@
|
|||||||
<property name="maxPermissionCheckTimeMillis">
|
<property name="maxPermissionCheckTimeMillis">
|
||||||
<value>${system.acl.maxPermissionCheckTimeMillis}</value>
|
<value>${system.acl.maxPermissionCheckTimeMillis}</value>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="maxPermissionCheckEnabled">
|
||||||
|
<value>${system.acl.maxPermissionCheckEnabled}</value>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="search.dbQueryEngine" class="org.springframework.aop.framework.ProxyFactoryBean">
|
<bean id="search.dbQueryEngine" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||||
|
@@ -167,7 +167,20 @@ public class DBQueryEngineTest
|
|||||||
assertNodePresent(6, result);
|
assertNodePresent(6, result);
|
||||||
assertNodePresent(7, result);
|
assertNodePresent(7, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldResultSetLengthMatchTheAmountOfAllAccessibleNodesWhenMaxPermissionCheckEnabled()
|
||||||
|
{
|
||||||
|
withMaxItems(5);
|
||||||
|
prepareTemplate(dbQuery, createNodes(10));
|
||||||
|
when(assessor.isIncluded(any(Node.class))).thenReturn(true);
|
||||||
|
|
||||||
|
engine.setMaxPermissionCheckEnabled(true);
|
||||||
|
FilteringResultSet result = engine.acceleratedNodeSelection(options, dbQuery, assessor);
|
||||||
|
|
||||||
|
assertEquals(10, result.length());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldNotConsiderInaccessibleNodesInResultSetWhenSkippingNodes()
|
public void shouldNotConsiderInaccessibleNodesInResultSetWhenSkippingNodes()
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user