diff --git a/e2e-test/pom.xml b/e2e-test/pom.xml index 586b8f9ae..27ea7c0e0 100644 --- a/e2e-test/pom.xml +++ b/e2e-test/pom.xml @@ -13,7 +13,7 @@ 1.35 1.13 - 3.0.19 + 3.0.20 3.3.0.1 src/test/resources/SearchSuite.xml diff --git a/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/SearchPermissionsTest.java b/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/SearchPermissionsTest.java index 763322842..f2b79e547 100644 --- a/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/SearchPermissionsTest.java +++ b/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/SearchPermissionsTest.java @@ -113,32 +113,40 @@ public class SearchPermissionsTest extends AbstractE2EFunctionalTest @Test(priority = 1) public void searchResultsRespectInheritedPermissions() { + /** + * Private Site Folder Structure available for this test + * |- permGrandParent + * |-- permChild1 + * |------ permFile1 (inheritance disabled, deny permission to testUser1) + * |-- permChild2 + * |------ permFile2 (inheritance disabled, allow permission to testUser2) + */ // Search as testUser: expect all: 5 results: When user is a Site Manager SearchResponse response = queryAsUser(testUser, "cm:name:perm*"); int resultCount = response.getPagination().getCount(); - Assert.assertTrue(resultCount == 5, "Unexpected Result count for testUser: Expected 5, received: " + resultCount); + Assert.assertEquals(resultCount, 5, "Unexpected Result count for testUser: Expected 5, received: " + resultCount); // Search as testUser1: expect 3 results: when user is a site member but without permission to a content response = queryAsUser(testUser1, "cm:name:perm*"); resultCount = response.getPagination().getCount(); - Assert.assertTrue(resultCount == 3, "Unexpected Result count for testUser1: Expected 3, received: " + resultCount); + Assert.assertEquals(resultCount, 3, "Unexpected Result count for testUser1: Expected 3, received: " + resultCount); // Search as testUser2: expect 1 result: When user isn't a site member but has granular permissions to a content response = queryAsUser(testUser2, "cm:name:perm*"); resultCount = response.getPagination().getCount(); - Assert.assertTrue(resultCount == 1, "Unexpected Result count for testUser2: Expected 1, received: " + resultCount); + Assert.assertEquals(resultCount, 1, "Unexpected Result count for testUser2: Expected 1, received: " + resultCount); // Search as testUser3: expect none: 0 results: When user isn't a site member / does not have granular permissions to the content response = queryAsUser(testUser3, "cm:name:perm*"); resultCount = response.getPagination().getCount(); - Assert.assertTrue(resultCount == 0, "Unexpected Result count for testUser3: Expected 0, received: " + resultCount); + Assert.assertEquals(resultCount, 0, "Unexpected Result count for testUser3: Expected 0, received: " + resultCount); } @Test(priority = 2) public void searchResultsRespectInheritedPermissionsDisabled() throws Exception { // Create folder - FolderModel folder3 = dataContent.usingUser(testUser).usingSite(testSite).usingResource(parentFolder).createFolderCmisApi("permChild32"); + FolderModel folder3 = dataContent.usingUser(testUser).usingSite(testSite).usingResource(parentFolder).createFolderCmisApi("permChild3"); // Turn off inherited permissions for folder3 JsonObject userPermission = Json.createObjectBuilder().add("permissions", Json.createObjectBuilder().add("isInheritanceEnabled", false)).build(); @@ -148,25 +156,35 @@ public class SearchPermissionsTest extends AbstractE2EFunctionalTest // Wait for indexing waitForIndexing(folder3.getName(), true); - // Search as testUser: expect all: 5 results: When user is a Site Manager + /** + * Private Site Folder Structure available now for this test + * |- permGrandParent + * |-- permChild1 + * |------ permFile1 (inheritance disabled, deny permission to testUser1) + * |-- permChild2 + * |------ permFile2 (inheritance disabled, allow permission to testUser2) + * |-- permChild3 (inheritance disabled) + */ + + // Search as testUser: expect all: 6 results: When user is a Site Manager SearchResponse response = queryAsUser(testUser, "cm:name:perm*"); int resultCount = response.getPagination().getCount(); - Assert.assertTrue(resultCount == 6, "Unexpected Result count for testUser: Expected 5, received: " + resultCount); + Assert.assertEquals(resultCount, 6, "Unexpected Result count for testUser: Expected 6, received: " + resultCount); // Search as testUser1: expect 3 results: when user is a site member but without permission to a content response = queryAsUser(testUser1, "cm:name:perm*"); resultCount = response.getPagination().getCount(); - Assert.assertTrue(resultCount == 3, "Unexpected Result count for testUser1: Expected 3, received: " + resultCount); + Assert.assertEquals(resultCount, 3, "Unexpected Result count for testUser1: Expected 3, received: " + resultCount); // Search as testUser2: expect 1 result: When user isn't a site member but has granular permissions to a content response = queryAsUser(testUser2, "cm:name:perm*"); resultCount = response.getPagination().getCount(); - Assert.assertTrue(resultCount == 1, "Unexpected Result count for testUser2: Expected 1, received: " + resultCount); + Assert.assertEquals(resultCount, 1, "Unexpected Result count for testUser2: Expected 1, received: " + resultCount); // Search as testUser3: expect none: 0 results: When user isn't a site member / does not have granular permissions to the content response = queryAsUser(testUser3, "cm:name:perm*"); resultCount = response.getPagination().getCount(); - Assert.assertTrue(resultCount == 0, "Unexpected Result count for testUser3: Expected 0, received: " + resultCount); + Assert.assertEquals(resultCount, 0, "Unexpected Result count for testUser3: Expected 0, received: " + resultCount); } @Test(priority = 3) @@ -199,6 +217,6 @@ public class SearchPermissionsTest extends AbstractE2EFunctionalTest // Query SearchResponse response = queryAsUser(testUser, folderName); int resultCount = response.getPagination().getCount(); - Assert.assertTrue(resultCount == 1, "Unexpected Result count for testUser: Expected 1, received: " + resultCount); + Assert.assertEquals(resultCount, 1, "Unexpected Result count for testUser: Expected 1, received: " + resultCount); } } diff --git a/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/ShardInfoTest.java b/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/ShardInfoTest.java index 573af0ae3..fe8dd1f9c 100644 --- a/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/ShardInfoTest.java +++ b/e2e-test/src/test/java/org/alfresco/test/search/functional/searchServices/search/ShardInfoTest.java @@ -189,21 +189,21 @@ public class ShardInfoTest extends AbstractE2EFunctionalTest case "DB_ID": break; case "DB_ID_RANGE": - // TODO: Uncomment the following assert when fixed: https://issues.alfresco.com/jira/browse/SEARCH-2110 - //assertEquals(shardParams.contains("shard.range="), "Unexpected shard params defined for DB_ID_RANGE"); + assertTrue(shardParams.contains("shard.range="), "Shard Parameters Not as expected for the Shard Method: DB_ID_RANGE"); break; case "DATE": - assertTrue(shardParams.contains("shard.key="), "Unexpected shard params defined for DATE"); - assertTrue(shardParams.contains("shard.grouping="), "Unexpected shard grouping defined for DATE"); + assertTrue(shardParams.contains("shard.key="), "Shard Parameters Not as expected for the Shard Method: DATE"); + assertTrue(shardParams.contains("shard.date.grouping="), "Shard Parameters Not as expected for the Shard Method: DATE"); break; case "PROPERTY": - assertTrue(shardParams.contains("shard.key="), "Unexpected shard params defined for PROPERTY"); + assertTrue(shardParams.contains("shard.key="), "Shard Parameters Not as expected for the Shard Method: PROPERTY"); + assertTrue(shardParams.contains("shard.regex="), "Shard Parameters Not as expected for the Shard Method: PROPERTY"); break; case "EXPLICIT_ID": - assertTrue(shardParams.contains("shard.key="), "Unexpected shard params defined for EXPLICIT_ID"); + assertTrue(shardParams.contains("shard.key="), "Shard Parameters Not as expected for the Shard Method: EXPLICIT_ID"); break; default: - throw new AssertionError("Not as expected: " + shardParams.toString()); + throw new AssertionError("Shard Method Not expected: " + model.getShardMethod()); } } } diff --git a/search-services/alfresco-search/pom.xml b/search-services/alfresco-search/pom.xml index fa8b7d7b8..ab8c550b9 100644 --- a/search-services/alfresco-search/pom.xml +++ b/search-services/alfresco-search/pom.xml @@ -181,7 +181,7 @@ com.carrotsearch.randomizedtesting randomizedtesting-runner - 2.7.6 + 2.7.7 test diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CoreStatePublisher.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CoreStatePublisher.java index 6c38fb47a..591863964 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CoreStatePublisher.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CoreStatePublisher.java @@ -40,6 +40,7 @@ import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.namespace.QName; import org.alfresco.solr.AlfrescoCoreAdminHandler; import org.alfresco.solr.AlfrescoSolrDataModel; +import org.alfresco.solr.BoundedDeque; import org.alfresco.solr.InformationServer; import org.alfresco.solr.NodeReport; import org.alfresco.solr.TrackerState; @@ -52,8 +53,8 @@ import java.util.Properties; /** * Superclass for all components which are able to inform Alfresco about the hosting node state. - * This has been introduced in SEARCH-1752 for splitting the dual responsibility of the {@link MetadataTracker}. - * As consequence of that, this class contains all the members needed for obtaining a valid + * This has been introduced in SEARCH-1752 for splitting the dual responsibility of the {@link org.alfresco.solr.tracker.MetadataTracker}. + * As consequence of that, this class contains only the members needed for obtaining a valid * {@link org.alfresco.repo.index.shard.ShardState} that can be periodically communicated to Alfresco. * * @author Andrea Gazzarini @@ -176,15 +177,15 @@ public abstract class CoreStatePublisher extends AbstractTracker * The {@link ShardState} is primarily used in two places: * * * * @return the {@link ShardState} instance which stores the current state of the hosting shard. + * @see SlaveCoreStatePublisher */ ShardState getShardState() { @@ -198,10 +199,11 @@ public abstract class CoreStatePublisher extends AbstractTracker HashMap propertyBag = new HashMap<>(); propertyBag.put("coreName", coreName); + HashMap extendedPropertyBag = new HashMap<>(propertyBag); updateShardProperty(); - shardProperty.ifPresent(p -> extendedPropertyBag.putAll(docRouter.getProperties(p))); + extendedPropertyBag.putAll(docRouter.getProperties(shardProperty)); return ShardStateBuilder.shardState() .withMaster(isMaster) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DBIDRangeRouter.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DBIDRangeRouter.java index bbbcca37d..b405b479a 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DBIDRangeRouter.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DBIDRangeRouter.java @@ -19,6 +19,7 @@ package org.alfresco.solr.tracker; import java.util.Map; +import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; @@ -108,9 +109,8 @@ public class DBIDRangeRouter implements DocRouter } @Override - public Map getProperties(QName shardProperty) + public Map getProperties(Optional shardProperty) { return Map.of(DocRouterFactory.SHARD_RANGE_KEY, startRange + "-" + expandableRange); } - } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DateMonthRouter.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DateMonthRouter.java index 8870f02e6..20282e8d9 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DateMonthRouter.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DateMonthRouter.java @@ -26,10 +26,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Calendar; -import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.Map; +import java.util.Optional; + +import static java.util.Collections.emptyMap; /** * The date-based sharding assigns dates sequentially through shards based on the month. @@ -121,14 +123,13 @@ public class DateMonthRouter implements DocRouter } @Override - public Map getProperties(QName shardProperty) + public Map getProperties(Optional shardProperty) { - - return (shardProperty == null ? - Collections.emptyMap() : - Map.of(DocRouterFactory.SHARD_KEY_KEY, shardProperty.getPrefixString(), - DocRouterFactory.SHARD_DATE_GROUPING_KEY, String.valueOf(grouping))); - + return shardProperty + .map(QName::getPrefixString) + .map(prefix -> Map.of( + DocRouterFactory.SHARD_KEY_KEY, prefix, + DocRouterFactory.SHARD_DATE_GROUPING_KEY, String.valueOf(grouping))) + .orElse(emptyMap()); } - } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DocRouter.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DocRouter.java index 694780c4b..d146acc98 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DocRouter.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DocRouter.java @@ -22,6 +22,7 @@ import org.alfresco.solr.client.Node; import java.util.Collections; import java.util.Map; +import java.util.Optional; import org.alfresco.service.namespace.QName; import org.alfresco.solr.client.Acl; @@ -65,13 +66,13 @@ public interface DocRouter Boolean routeNode(int shardCount, int shardInstance, Node node); /** - * Get additional properties to "shardProperty" depending on the Shard Method - * @param shardProperty custom property used to configure the Router + * Get additional properties to "shardProperty" depending on the Shard Method. + * + * @param shardProperty custom property used to configure the Router. Note not all routers need that. * @return pair of key, value */ - default public Map getProperties(QName shardProperty) { + default Map getProperties(Optional shardProperty) { return Collections.emptyMap(); } - } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DocRouterWithFallback.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DocRouterWithFallback.java index d809b330f..08462a801 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DocRouterWithFallback.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/DocRouterWithFallback.java @@ -9,6 +9,7 @@ import java.util.Objects; import static java.util.Optional.ofNullable; import java.util.Map; +import java.util.Optional; /** * A composable {@link DocRouter} which consists of @@ -47,9 +48,8 @@ public class DocRouterWithFallback implements DocRouter } @Override - public Map getProperties(QName shardProperty) + public Map getProperties(Optional shardProperty) { return primaryStrategy.getProperties(shardProperty); } - } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ExplicitShardIdWithDynamicPropertyRouter.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ExplicitShardIdWithDynamicPropertyRouter.java index 383414bcc..67a6e6c85 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ExplicitShardIdWithDynamicPropertyRouter.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ExplicitShardIdWithDynamicPropertyRouter.java @@ -18,13 +18,15 @@ */ package org.alfresco.solr.tracker; -import java.util.Collections; import java.util.Map; +import java.util.Optional; import org.alfresco.service.namespace.QName; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.Node; +import static java.util.Collections.emptyMap; + /** * Routes a document only if the shardInstance matches the provided shardId. * The access control information is duplicated in each shard. @@ -78,11 +80,11 @@ public class ExplicitShardIdWithDynamicPropertyRouter extends ComposableDocRoute } @Override - public Map getProperties(QName shardProperty) + public Map getProperties(Optional shardProperty) { - return (shardProperty == null ? - Collections.emptyMap() : - Map.of(DocRouterFactory.SHARD_KEY_KEY, shardProperty.getPrefixString())); + return shardProperty + .map(QName::getPrefixString) + .map(prefix -> Map.of(DocRouterFactory.SHARD_KEY_KEY, prefix)) + .orElse(emptyMap()); } - } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/PropertyRouter.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/PropertyRouter.java index c64c59ab0..d1b4d620d 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/PropertyRouter.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/PropertyRouter.java @@ -26,11 +26,13 @@ import org.apache.solr.common.util.Hash; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Collections; import java.util.Map; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static java.util.Collections.emptyMap; + /** * Routes based on a text property field. * In this method, the value of some property is hashed and this hash is used to assign the node to a random shard. @@ -126,12 +128,13 @@ public class PropertyRouter implements DocRouter } @Override - public Map getProperties(QName shardProperty) + public Map getProperties(Optional shardProperty) { - return (shardProperty == null ? - Collections.emptyMap() : - Map.of(DocRouterFactory.SHARD_KEY_KEY, shardProperty.getPrefixString(), - DocRouterFactory.SHARD_REGEX_KEY, propertyRegEx)); + return shardProperty + .map(QName::getPrefixString) + .map(prefix -> Map.of( + DocRouterFactory.SHARD_KEY_KEY, prefix, + DocRouterFactory.SHARD_REGEX_KEY, propertyRegEx)) + .orElse(emptyMap()); } - } diff --git a/search-services/alfresco-solrclient-lib/pom.xml b/search-services/alfresco-solrclient-lib/pom.xml index b0a866644..9a0b643a7 100644 --- a/search-services/alfresco-solrclient-lib/pom.xml +++ b/search-services/alfresco-solrclient-lib/pom.xml @@ -23,7 +23,7 @@ 8.87 - 2.10.2 + 2.10.3 diff --git a/search-services/packaging/src/main/resources/licenses/notice.txt b/search-services/packaging/src/main/resources/licenses/notice.txt index b3eb46870..9b216f7cc 100644 --- a/search-services/packaging/src/main/resources/licenses/notice.txt +++ b/search-services/packaging/src/main/resources/licenses/notice.txt @@ -52,9 +52,9 @@ cxf-rt-wsdl-3.2.12.jar https://cxf.apache.org/ chemistry-opencmis-server-support-1.0.0.jar http://chemistry.apache.org/ chemistry-opencmis-server-bindings-1.0.0.jar http://chemistry.apache.org/ quartz-2.3.2.jar http://quartz-scheduler.org/ -jackson-core-2.10.2.jar https://github.com/FasterXML/jackson -jackson-annotations-2.10.2.jar https://github.com/FasterXML/jackson -jackson-databind-2.10.2.jar https://github.com/FasterXML/jackson +jackson-core-2.10.3.jar https://github.com/FasterXML/jackson +jackson-annotations-2.10.3.jar https://github.com/FasterXML/jackson +jackson-databind-2.10.3.jar https://github.com/FasterXML/jackson commons-httpclient-3.1-HTTPCLIENT-1265.jar http://jakarta.apache.org/commons/ spring-aop-5.2.3.RELEASE.jar http://projects.spring.io/spring-framework/ spring-beans-5.2.3.RELEASE.jar http://projects.spring.io/spring-framework/