Compare commits

..

13 Commits

Author SHA1 Message Date
cezary-witkowski
0e5b66c637 [ACS-9167] Clear more caches 2025-03-21 17:11:38 +01:00
cezary-witkowski
0c17a1c617 [ACS-9167] Improved integration test 2025-03-21 16:01:10 +01:00
cezary-witkowski
87ecfc9290 [ACS-9167] Header years 2025-03-21 14:50:45 +01:00
cezary-witkowski
520e06dd49 [ACS-9167] Added integration tests 2025-03-21 14:50:07 +01:00
cezary-witkowski
f271697a8e [ACS-9167] Fix bugs found in testing 2025-03-21 14:49:16 +01:00
cezary-witkowski
e106502363 [ACS-9167] PMD fix 2025-03-20 12:08:12 +01:00
cezary-witkowski
8811a73a8d [ACS-9167] Updated header year 2025-03-20 11:53:59 +01:00
cezary-witkowski
44bca1d416 [ACS-9167] Adding missing mappings 2025-03-19 16:34:02 +01:00
cezary-witkowski
3b476670e0 [ACS-9167] Added second query to count all nodes matching the query to fix pagination having incorrect totalItems which in turn breaks pagination on frontend when using smart folders. 2025-03-19 15:01:05 +01:00
alfresco-build
f630da7cce [maven-release-plugin][skip ci] prepare for next development iteration 2025-03-19 08:22:48 +00:00
alfresco-build
48ad5adc84 [maven-release-plugin][skip ci] prepare release 25.2.0.2 2025-03-19 08:22:46 +00:00
mohit-singh4
2b372ec381 [APPS-3242] Fix for facet query for elasticsearch (#3260)
Co-authored-by: mohit-singh4 <mohit.singh@contractors.hyland.com>
2025-03-19 13:06:44 +05:30
alfresco-build
30c40ee6e0 [maven-release-plugin][skip ci] prepare for next development iteration 2025-03-17 16:01:07 +00:00
33 changed files with 352 additions and 48 deletions

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<build>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<build>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -9,6 +9,6 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
</project>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<organization>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -96,6 +96,45 @@ public class NodeSizeDetailsTests extends RestTest
});
}
/**
* calculateNodeSizeForEmptyFolder testcase
*/
@TestRail(section = {TestGroup.REST_API, TestGroup.NODES}, executionType = ExecutionType.SANITY)
@Test(groups = {TestGroup.REST_API, TestGroup.NODES, TestGroup.SANITY})
public void calculateNodeSizeForEmptyFolder() throws Exception
{
STEP("1. Create a folder in the test site.");
folder = dataContent.usingUser(user1).usingSite(siteModel).createFolder(FolderModel.getRandomFolderModel());
RestSizeDetailsModel restSizeDetailsModel = restClient.authenticateUser(user1).withCoreAPI().usingNode(folder).executeSizeDetails();
restClient.assertStatusCodeIs(HttpStatus.ACCEPTED);
restSizeDetailsModel.assertThat().field("jobId").isNotEmpty();
jobId = restSizeDetailsModel.getJobId();
STEP("2. Wait for 5 seconds for the processing to complete.");
Awaitility
.await()
.atMost(Duration.ofSeconds(5))
.pollInterval(Durations.ONE_SECOND)
.ignoreExceptions()
.untilAsserted(() -> {
RestSizeDetailsModel sizeDetailsModel = restClient.authenticateUser(user1)
.withCoreAPI()
.usingNode(folder)
.getSizeDetails(jobId);
restClient.assertStatusCodeIs(HttpStatus.OK);
sizeDetailsModel.assertThat()
.field("sizeInBytes")
.isNotEmpty();
Assert.assertEquals(sizeDetailsModel.getSizeInBytes(), 0,
"Value of sizeInBytes should be 0 " + sizeDetailsModel.getSizeInBytes());
Assert.assertEquals(sizeDetailsModel.getStatus().name(), "COMPLETED",
"Status should be - COMPLETED" + sizeDetailsModel.getStatus().name());
});
}
/**
* checkJobIdPresentInCache testcase
*/

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -153,7 +153,7 @@
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
<url>https://github.com/Alfresco/alfresco-community-repo</url>
<tag>25.2.0.1</tag>
<tag>HEAD</tag>
</scm>
<distributionManagement>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.2.0.1</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -58,6 +58,7 @@ public class NodeSizeDetailsServiceImpl implements NodeSizeDetailsService, Initi
private static final Logger LOG = LoggerFactory.getLogger(NodeSizeDetailsServiceImpl.class);
private static final String FIELD_FACET = "content.size";
private static final String FACET_QUERY = "{!afts}content.size:[0 TO " + Integer.MAX_VALUE + "]";
private static final int DEFAULT_FACET_LIMIT = 100;
private SearchService searchService;
private SimpleCache<Serializable, NodeSizeDetails> simpleCache;
private TransactionService transactionService;
@@ -214,7 +215,11 @@ public class NodeSizeDetailsServiceImpl implements NodeSizeDetailsService, Initi
}
searchParameters.addFacetQuery(FACET_QUERY);
FieldFacet fieldFacet = new FieldFacet(FIELD_FACET);
fieldFacet.setLimitOrNull((int) resultsWithoutFacet.getNumberFound());
int numberFound = Optional.ofNullable(resultsWithoutFacet.getNumberFound())
.map(Long::intValue)
.filter(n -> n > 0)
.orElse(DEFAULT_FACET_LIMIT);
fieldFacet.setLimitOrNull(numberFound);
searchParameters.addFieldFacet(fieldFacet);
resultsWithoutFacet.close();
return searchService.query(searchParameters);

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -90,6 +90,8 @@ public class DBQueryEngine implements QueryEngine
protected static final Log logger = LogFactory.getLog(DBQueryEngine.class);
protected static final String SELECT_BY_DYNAMIC_QUERY = "alfresco.metadata.query.select_byDynamicQuery";
protected static final String COUNT_BY_DYNAMIC_QUERY = "alfresco.metadata.query.count_byDynamicQuery";
protected static final QueryTemplate QUERY_TEMPLATE = new QueryTemplate(SELECT_BY_DYNAMIC_QUERY, COUNT_BY_DYNAMIC_QUERY);
private static final int DEFAULT_MIN_PAGING_BATCH_SIZE = 2500;
@@ -252,7 +254,7 @@ public class DBQueryEngine implements QueryEngine
}
/* (non-Javadoc)
*
*
* @see org.alfresco.repo.search.impl.querymodel.QueryEngine#executeQuery(org.alfresco.repo.search.impl.querymodel.Query, org.alfresco.repo.search.impl.querymodel.QueryOptions, org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext) */
@Override
public QueryEngineResults executeQuery(Query query, QueryOptions options, FunctionEvaluationContext functionContext)
@@ -331,10 +333,10 @@ public class DBQueryEngine implements QueryEngine
return asQueryEngineResults(resultSet);
}
protected String pickQueryTemplate(QueryOptions options, DBQuery dbQuery)
protected QueryTemplate pickQueryTemplate(QueryOptions options, DBQuery dbQuery)
{
logger.debug("- using standard table for the query");
return SELECT_BY_DYNAMIC_QUERY;
return QUERY_TEMPLATE;
}
private ResultSet selectNodesWithPermissions(QueryOptions options, DBQuery dbQuery)
@@ -370,7 +372,8 @@ public class DBQueryEngine implements QueryEngine
int requiredNodes = computeRequiredNodesCount(options);
logger.debug("- query sent to the database");
performTmdqSelect(pickQueryTemplate(options, dbQuery), dbQuery, requiredNodes, new ResultHandler<Node>() {
QueryTemplate queryTemplate = pickQueryTemplate(options, dbQuery);
performTmdqSelect(queryTemplate, dbQuery, requiredNodes, new ResultHandler<Node>() {
@Override
public void handleResult(ResultContext<? extends Node> context)
{
@@ -425,8 +428,7 @@ public class DBQueryEngine implements QueryEngine
}
}
});
int numberFound = nodes.size();
int numberFound = countSelectedNodes(queryTemplate, dbQuery);
nodes.removeAll(Collections.singleton(null));
DBResultSet rs = createResultSet(options, nodes, numberFound);
@@ -437,8 +439,17 @@ public class DBQueryEngine implements QueryEngine
return frs;
}
private void performTmdqSelect(String statement, DBQuery dbQuery, int requiredNodes, ResultHandler<Node> handler)
protected int countSelectedNodes(QueryTemplate queryTemplate, DBQuery dbQuery)
{
dbQuery.setLimit(0);
dbQuery.setOffset(0);
String countQuery = queryTemplate.count();
return template.selectOne(countQuery, dbQuery);
}
private void performTmdqSelect(QueryTemplate queryTemplate, DBQuery dbQuery, int requiredNodes, ResultHandler<Node> handler)
{
String statement = queryTemplate.select();
if (usePagingQuery)
{
performTmdqSelectPaging(statement, dbQuery, requiredNodes, handler);
@@ -457,8 +468,7 @@ public class DBQueryEngine implements QueryEngine
private void performTmdqSelectPaging(String statement, DBQuery dbQuery, int requiredNodes, ResultHandler<Node> handler)
{
int batchStart = 0;
int batchSize = requiredNodes * 2;
batchSize = Math.min(Math.max(batchSize, minPagingBatchSize), maxPagingBatchSize);
int batchSize = calculateBatchSize(requiredNodes);
DefaultResultContext<Node> resultCtx = new DefaultResultContext<>();
while (!resultCtx.isStopped())
{
@@ -485,6 +495,21 @@ public class DBQueryEngine implements QueryEngine
}
}
private int calculateBatchSize(int requiredNodes)
{
int batchSize;
if (requiredNodes > Integer.MAX_VALUE / 2)
{
// preventing overflow
batchSize = Integer.MAX_VALUE;
}
else
{
batchSize = requiredNodes * 2;
}
return Math.min(Math.max(batchSize, minPagingBatchSize), maxPagingBatchSize);
}
private DBResultSet createResultSet(QueryOptions options, List<Node> nodes, int numberFound)
{
DBResultSet dbResultSet = new DBResultSet(options.getAsSearchParmeters(), nodes, nodeDAO, nodeService, tenantService, Integer.MAX_VALUE);
@@ -524,7 +549,7 @@ public class DBQueryEngine implements QueryEngine
}
/* (non-Javadoc)
*
*
* @see org.alfresco.repo.search.impl.querymodel.QueryEngine#getQueryModelFactory() */
@Override
public QueryModelFactory getQueryModelFactory()
@@ -534,7 +559,7 @@ public class DBQueryEngine implements QueryEngine
/**
* Injection of nodes cache for clean-up and warm up when required
*
*
* @param cache
* The node cache to set
*/
@@ -588,4 +613,7 @@ public class DBQueryEngine implements QueryEngine
}
}
}
protected record QueryTemplate(String select, String count)
{}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -203,9 +203,8 @@ public class VirtualQueryImpl implements VirtualQuery
start = 0;
}
}
final int totlaSecond = !hasMore ? (int) result.getNumberFound() : (int) (start + result.getNumberFound() + 1);
final Pair<Integer, Integer> total = new Pair<Integer, Integer>(totalFirst,
totlaSecond);
final int totalSecond = !hasMore ? (int) result.getNumberFound() : (int) (start + result.getNumberFound());
final Pair<Integer, Integer> total = new Pair<>(totalFirst, totalSecond);
return new PagingResults<Reference>() {
@Override

View File

@@ -8,4 +8,10 @@
<include refid="sql_select_byDynamicQuery"/>
</select>
</mapper>
<select id="count_byDynamicQuery" parameterType="org.alfresco.repo.search.impl.querymodel.impl.db.DBQuery" resultType="int">
SELECT COUNT(DISTINCT nodes.id)
FROM (
<include refid="sql_select_byDynamicQuery"/>
) nodes
</select>
</mapper>

View File

@@ -8,4 +8,10 @@
<include refid="sql_select_byDynamicQuery"/>
</select>
</mapper>
<select id="count_byDynamicQuery" parameterType="org.alfresco.repo.search.impl.querymodel.impl.db.DBQuery" resultType="int">
SELECT COUNT(DISTINCT nodes.id)
FROM (
<include refid="sql_select_byDynamicQuery"/>
) nodes
</select>
</mapper>

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -80,6 +80,7 @@ import org.alfresco.util.testing.category.NonBuildTests;
// ACS-1907
org.alfresco.repo.search.impl.querymodel.impl.db.ACS1907Test.class,
org.alfresco.repo.search.impl.querymodel.impl.db.ACS9167Test.class,
// REPO-2963 : Tests causing a cascade of failures in AllDBTestsTestSuite on PostgreSQL/MySQL
// Moved at the bottom of the suite because DbNodeServiceImplTest.testNodeCleanupRegistry() takes a long time on a clean DB.

View File

@@ -0,0 +1,216 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.search.impl.querymodel.impl.db;
import static org.junit.Assert.assertEquals;
import java.io.Serializable;
import java.time.Duration;
import java.util.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.context.ApplicationContext;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cache.TransactionalCache;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.QueryConsistency;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.test_category.OwnJVMTestsCategory;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.testing.category.DBTests;
@Category({OwnJVMTestsCategory.class, DBTests.class})
@SuppressWarnings({"PMD.JUnitTestsShouldIncludeAssert"})
public class ACS9167Test
{
private NodeService nodeService;
private AuthenticationComponent authenticationComponent;
private SearchService pubSearchService;
private TransactionService transactionService;
private RetryingTransactionHelper txnHelper;
@Before
public void setUp() throws Exception
{
setupServices();
txnHelper = new RetryingTransactionHelper();
txnHelper.setTransactionService(transactionService);
txnHelper.setReadOnly(false);
txnHelper.setMaxRetries(1);
authenticationComponent.setSystemUserAsCurrentUser();
}
private void setupServices()
{
ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
nodeService = (NodeService) ctx.getBean("dbNodeService");
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
pubSearchService = (SearchService) ctx.getBean("SearchService");
transactionService = (TransactionService) ctx.getBean("TransactionService");
List<TransactionalCache<?, ?>> cachesToClear = new ArrayList<>();
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("propertyValueCache"));
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("node.nodesCache"));
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("node.propertiesCache"));
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("aclCache"));
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("aclEntityCache"));
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("permissionEntityCache"));
cachesToClear.add((TransactionalCache<?, ?>) ctx.getBean("nodeOwnerCache"));
for (TransactionalCache<?, ?> transactionalCache : cachesToClear)
{
transactionalCache.clear();
}
}
@After
public void tearDown() throws Exception
{
authenticationComponent.clearCurrentSecurityContext();
}
@Test
public void testPagination()
{
String searchMarker = UUID.randomUUID().toString();
int contentFilesCount = 185;
createFolderWithContentNodes(searchMarker, contentFilesCount);
prepareParametersQueryAndAssertResult(searchMarker, 0, 50, 50, contentFilesCount);
prepareParametersQueryAndAssertResult(searchMarker, 50, 50, 50, contentFilesCount);
prepareParametersQueryAndAssertResult(searchMarker, 150, 50, 35, contentFilesCount);
prepareParametersQueryAndAssertResult(searchMarker, 200, 50, 0, contentFilesCount);
prepareParametersQueryAndAssertResult(searchMarker, 0, 100, 100, contentFilesCount);
prepareParametersQueryAndAssertResult(searchMarker, 100, 100, 85, contentFilesCount);
prepareParametersQueryAndAssertResult(searchMarker, 200, 100, 0, contentFilesCount);
prepareParametersQueryAndAssertResult(searchMarker, 0, 200, contentFilesCount, contentFilesCount);
}
@Test
public void testLargeFilesCount()
{
String searchMarker = UUID.randomUUID().toString();
int contentFilesCount = 10_000;
createFolderWithContentNodes(searchMarker, contentFilesCount);
prepareParametersQueryAndAssertResult(searchMarker, 0, Integer.MAX_VALUE, contentFilesCount, contentFilesCount);
}
private void createFolderWithContentNodes(String searchMarker, int contentFilesCount)
{
NodeRef testFolder = txnHelper.doInTransaction(this::createFolderNode, false, false);
int batchSize = 1000;
int fullBatches = contentFilesCount / batchSize;
int remainingItems = contentFilesCount % batchSize;
for (int i = 0; i < fullBatches; i++)
{
txnHelper.doInTransaction(() -> {
for (int j = 0; j < batchSize; j++)
{
createContentNode(searchMarker, testFolder);
}
return null;
}, false, false);
}
if (remainingItems > 0)
{
txnHelper.doInTransaction(() -> {
for (int j = 0; j < remainingItems; j++)
{
createContentNode(searchMarker, testFolder);
}
return null;
}, false, false);
}
}
private void prepareParametersQueryAndAssertResult(String searchMarker, int parameterSkipCount, int parameterMaxItems, int expectedLength, int expectedNumberFound)
{
txnHelper.doInTransaction(() -> {
// given
SearchParameters sp = new SearchParameters();
sp.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
sp.setQueryConsistency(QueryConsistency.TRANSACTIONAL);
sp.setQuery("(+TYPE:'cm:content') and !ASPECT:'cm:checkedOut' and !TYPE:'fm:forum' and !TYPE:'fm:topic' and !TYPE:'cm:systemfolder' and !TYPE:'fm:post' and !TYPE:'fm:forums' and =cm:description:'" + searchMarker + "'");
sp.setSkipCount(parameterSkipCount);
sp.setMaxItems(parameterMaxItems);
sp.setMaxPermissionChecks(Integer.MAX_VALUE);
sp.setMaxPermissionCheckTimeMillis(Duration.ofMinutes(10).toMillis());
// when
ResultSet resultSet = pubSearchService.query(sp);
// then
assertEquals(expectedLength, resultSet.length());
assertEquals(expectedNumberFound, resultSet.getNumberFound());
return null;
}, false, false);
}
private NodeRef createFolderNode()
{
NodeRef rootNodeRef = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
Map<QName, Serializable> testFolderProps = new HashMap<>();
String folderName = "folder" + UUID.randomUUID();
testFolderProps.put(ContentModel.PROP_NAME, folderName);
return nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, folderName),
ContentModel.TYPE_FOLDER,
testFolderProps).getChildRef();
}
private void createContentNode(String searchMarker, NodeRef testFolder)
{
Map<QName, Serializable> testContentProps = new HashMap<>();
String fileName = "content" + UUID.randomUUID();
testContentProps.put(ContentModel.PROP_NAME, fileName);
testContentProps.put(ContentModel.PROP_DESCRIPTION, searchMarker);
nodeService.createNode(
testFolder,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, fileName),
ContentModel.TYPE_CONTENT,
testContentProps);
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -60,7 +60,8 @@ import org.alfresco.util.Pair;
public class DBQueryEngineTest
{
private static final String SQL_TEMPLATE_PATH = "alfresco.metadata.query.select_byDynamicQuery";
private static final String SQL_SELECT_TEMPLATE_PATH = "alfresco.metadata.query.select_byDynamicQuery";
private static final String SQL_COUNT_TEMPLATE_PATH = "alfresco.metadata.query.count_byDynamicQuery";
private DBQueryEngine engine;
private SqlSessionTemplate template;
@@ -94,6 +95,7 @@ public class DBQueryEngineTest
public void shouldGetAFilteringResultSetFromAcceleratedNodeSelection()
{
withMaxItems(10);
when(template.selectOne(any(), eq(dbQuery))).thenReturn(10);
ResultSet result = engine.acceleratedNodeSelection(options, dbQuery, assessor);
@@ -226,7 +228,9 @@ public class DBQueryEngineTest
}
return null;
}).when(template).select(eq(SQL_TEMPLATE_PATH), eq(dbQuery), any());
}).when(template).select(eq(SQL_SELECT_TEMPLATE_PATH), eq(dbQuery), any());
when(template.selectOne(eq(SQL_COUNT_TEMPLATE_PATH), eq(dbQuery))).thenReturn(nodes.size());
}
private QueryOptions createQueryOptions()