mirror of
https://github.com/Alfresco/SearchServices.git
synced 2026-09-16 18:12:56 +00:00
Synced branch with master
This commit is contained in:
+51
-60
@@ -3,8 +3,8 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-super-pom</artifactId>
|
||||
<version>10</version>
|
||||
<artifactId>alfresco-search-and-insight-parent</artifactId>
|
||||
<version>1.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>search-analytics-e2e-test</groupId>
|
||||
<artifactId>search-analytics-e2e-test</artifactId>
|
||||
@@ -20,24 +20,10 @@
|
||||
<suiteXmlFile>src/test/resources/SearchSuite.xml</suiteXmlFile>
|
||||
<test.exclude></test.exclude>
|
||||
<test.include></test.include>
|
||||
<java.version>11</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
||||
<jackson.databind.version>2.7.7</jackson.databind.version>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<release>${java.version}</release>
|
||||
<showWarnings>true</showWarnings>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
@@ -53,29 +39,34 @@
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-insight-jdbc</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco.tas</groupId>
|
||||
<artifactId>restapi-test</artifactId>
|
||||
<version>${tas.rest.api.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco.tas</groupId>
|
||||
<artifactId>cmis-test</artifactId>
|
||||
<version>${tas.cmis.api.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
@@ -83,50 +74,50 @@
|
||||
<version>${rm.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.databind.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.databind.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-automation-community-rest-api</artifactId>
|
||||
<version>${rm.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- alfresco tester settings -->
|
||||
<dependency>
|
||||
<groupId>org.alfresco.tas</groupId>
|
||||
<artifactId>utility</artifactId>
|
||||
<version>${tas.utility.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<groupId>org.slf4j</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- alfresco tester settings -->
|
||||
<dependency>
|
||||
<groupId>org.alfresco.tas</groupId>
|
||||
<artifactId>utility</artifactId>
|
||||
<version>${tas.utility.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<groupId>org.slf4j</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.8</version>
|
||||
<version>1.18.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>12-ea+10</version>
|
||||
</dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>12-ea+10</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<model name="shard:contentModel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
|
||||
|
||||
<description>Explicit Routing for Sharding Sample Model</description>
|
||||
|
||||
<imports>
|
||||
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
|
||||
</imports>
|
||||
|
||||
<namespaces>
|
||||
<namespace uri="http://www.alfresco.org/model/sharding/1.0" prefix="shard"/>
|
||||
</namespaces>
|
||||
|
||||
<aspects>
|
||||
<aspect name="shard:sharding">
|
||||
<title>Sharding</title>
|
||||
<properties>
|
||||
<!-- Shard number to index this content -->
|
||||
<property name="shard:shardId">
|
||||
<title>Shard Id</title>
|
||||
<type>d:text</type>
|
||||
</property>
|
||||
</properties>
|
||||
</aspect>
|
||||
</aspects>
|
||||
|
||||
</model>
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package org.alfresco.test.search.functional.searchServices.search;
|
||||
|
||||
import org.alfresco.search.TestGroup;
|
||||
import org.alfresco.test.search.functional.AbstractE2EFunctionalTest;
|
||||
import org.alfresco.utility.model.FileModel;
|
||||
import org.alfresco.utility.model.FileType;
|
||||
import org.apache.chemistry.opencmis.commons.PropertyIds;
|
||||
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
public class ExplicitRoutingTest extends AbstractE2EFunctionalTest {
|
||||
|
||||
|
||||
/**
|
||||
* Checks indexing still works after sharding model used for explicit routing has been disabled
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test(priority = 1, groups = {TestGroup.NOT_BAMBOO, TestGroup.EXPLICIT_SHARDING, TestGroup.ACS_62n})
|
||||
public void testIndexingStillWorkingAfterShardModelIsDeactivated() throws Exception
|
||||
{
|
||||
|
||||
// Deploy sharding model
|
||||
assertTrue(deployCustomModel("model/sharding-content-model.xml"),
|
||||
"failing while deploying sharding model");
|
||||
|
||||
// Create a first child in parent folder. It will be indexed in the parent shard (shard 0)
|
||||
FileModel file = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
|
||||
Map<String, Object> propertiesFirstChild = Map.of(PropertyIds.NAME, file.getName(),
|
||||
PropertyIds.OBJECT_TYPE_ID, "cmis:document",
|
||||
"cmis:secondaryObjectTypeIds", List.of("P:shard:sharding"),
|
||||
"shard:shardId", "0");
|
||||
|
||||
// Create file using shard:shardId
|
||||
cmisApi.authenticateUser(testUser).usingSite(testSite)
|
||||
.createFile(file,
|
||||
Map.of(PropertyIds.NAME, file.getName(),
|
||||
PropertyIds.OBJECT_TYPE_ID, "cmis:document"),
|
||||
VersioningState.MAJOR)
|
||||
.assertThat().existsInRepo();
|
||||
|
||||
// Wait for file to be indexed
|
||||
assertTrue(isContentInSearchResults(file.getName(), file.getName(), true),
|
||||
"A file using sharding model has not been indexed");
|
||||
|
||||
|
||||
// Deleting file
|
||||
dataContent.usingSite(testSite).usingUser(testUser).usingResource(file).deleteContent();
|
||||
restClient.withCoreAPI().usingTrashcan().deleteNodeFromTrashcan(file);
|
||||
|
||||
// Deleting sharding model
|
||||
assertTrue(deactivateCustomModel("sharding-content-model.xml"),
|
||||
"failing while deactivating sharding model");
|
||||
assertTrue(deleteCustomModel("sharding-content-model.xml"),
|
||||
"failing while removing sharding model");
|
||||
|
||||
assertTrue(waitForIndexing("TYPE:'" + "shard:shardId" + "'", false),
|
||||
"Indexes are not updated after deactivating a model");
|
||||
|
||||
// Create a file in the parent folder
|
||||
file = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
|
||||
|
||||
cmisApi.authenticateUser(testUser).usingSite(testSite)
|
||||
.createFile(file,
|
||||
Map.of(PropertyIds.NAME, file.getName(),
|
||||
PropertyIds.OBJECT_TYPE_ID, "cmis:document"),
|
||||
VersioningState.MAJOR)
|
||||
.assertThat().existsInRepo();
|
||||
|
||||
|
||||
assertTrue(isContentInSearchResults(file.getName(), file.getName(), true),
|
||||
"Indexing is not working after the sharding model has been removed");
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -90,7 +90,7 @@ public class FacetFieldsSearchTest extends AbstractE2EFunctionalTest
|
||||
restClient.authenticateUser(testUser).withCoreAPI().usingNode(textFile).updateNode(putBody);
|
||||
|
||||
// Wait for the file to be indexed
|
||||
waitForIndexing(htmlFile.getName(), true);
|
||||
waitForContentIndexing(htmlFile.getContent(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+4
-3
@@ -109,9 +109,10 @@ public class SearchHighLightTest extends AbstractSearchServicesE2ETest
|
||||
nodes.getEntries().stream()
|
||||
.map(SearchNodeModel::getModel)
|
||||
.map(SearchNodeModel::getSearch)
|
||||
.map(SearchScoreModel::getHighlight).forEach(( hl ->
|
||||
assertEquals(expectedHighlight, hl.get(0).getSnippets().get(0))
|
||||
)
|
||||
.map(SearchScoreModel::getHighlight).forEach(( hl -> {
|
||||
assertEquals(1, hl.size());
|
||||
assertEquals(expectedHighlight, hl.get(0).getSnippets().get(0));
|
||||
})
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
+64
-19
@@ -19,8 +19,12 @@ import org.apache.chemistry.opencmis.commons.PropertyIds;
|
||||
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test class tests cascading updates for a child node when parent node is updated
|
||||
*
|
||||
@@ -31,6 +35,46 @@ public class CascadingTrackerIntegrationTest extends AbstractE2EFunctionalTest
|
||||
{
|
||||
@Autowired
|
||||
protected DataContent dataContent;
|
||||
private FolderModel parentFolderSharded;
|
||||
private FileModel firstChildFileSharded;
|
||||
private FileModel secondChildFileSharded;
|
||||
|
||||
|
||||
@BeforeClass(alwaysRun = true)
|
||||
public void setupEnvironment()
|
||||
{
|
||||
assertTrue(deployCustomModel("model/sharding-content-model.xml"),
|
||||
"failing while deploying sharding model");
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public void cleanUpEnvironment()
|
||||
{
|
||||
if (firstChildFileSharded != null)
|
||||
{
|
||||
dataContent.usingSite(testSite).usingUser(testUser).usingResource(firstChildFileSharded).deleteContent();
|
||||
restClient.withCoreAPI().usingTrashcan().deleteNodeFromTrashcan(firstChildFileSharded);
|
||||
}
|
||||
|
||||
if (secondChildFileSharded != null)
|
||||
{
|
||||
dataContent.usingSite(testSite).usingUser(testUser).usingResource(secondChildFileSharded).deleteContent();
|
||||
restClient.withCoreAPI().usingTrashcan().deleteNodeFromTrashcan(secondChildFileSharded);
|
||||
}
|
||||
|
||||
if (parentFolderSharded != null)
|
||||
{
|
||||
dataContent.usingSite(testSite).usingUser(testUser).usingResource(parentFolderSharded).deleteContent();
|
||||
restClient.withCoreAPI().usingTrashcan().deleteNodeFromTrashcan(parentFolderSharded);
|
||||
}
|
||||
|
||||
dataContent.deleteSite(testSite);
|
||||
assertTrue(deactivateCustomModel("sharding-content-model.xml"),
|
||||
"failing while deactivating sharding model");
|
||||
assertTrue(deleteCustomModel("sharding-content-model.xml"),
|
||||
"failing while removing sharding model");
|
||||
}
|
||||
|
||||
@Test(priority = 1)
|
||||
public void testChildPathWhenParentRenamed() throws Exception
|
||||
@@ -143,53 +187,53 @@ public class CascadingTrackerIntegrationTest extends AbstractE2EFunctionalTest
|
||||
* Check that, after parent renaming, both the children are searchable in the new path
|
||||
* (computed accordingly with the new parent folder name)
|
||||
*/
|
||||
@Test(priority = 1, groups = {TestGroup.NOT_BAMBOO, TestGroup.EXPLICIT_SHARDING })
|
||||
@Test(priority = 3, groups = {TestGroup.NOT_BAMBOO, TestGroup.EXPLICIT_SHARDING })
|
||||
public void testChildrenPathOnParentRenamedWithChildrenInDifferentShards() throws Exception
|
||||
{
|
||||
|
||||
// Create Parent folder. It will be indexed in shard 0
|
||||
FolderModel parentFolder = FolderModel.getRandomFolderModel();
|
||||
parentFolderSharded = FolderModel.getRandomFolderModel();
|
||||
|
||||
List<String> secondaryTypes = List.of("P:shard:sharding");
|
||||
Map<String, Object> parentProperties = Map.of(PropertyIds.NAME, parentFolder.getName(),
|
||||
Map<String, Object> parentProperties = Map.of(PropertyIds.NAME, parentFolderSharded.getName(),
|
||||
PropertyIds.OBJECT_TYPE_ID, "cmis:folder",
|
||||
"cmis:secondaryObjectTypeIds", secondaryTypes,
|
||||
"shard:shardId", "0");
|
||||
|
||||
// Create a first child in parent folder. It will be indexed in the parent shard (shard 0)
|
||||
FileModel firstChildFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
|
||||
Map<String, Object> propertiesFirstChild = Map.of(PropertyIds.NAME, firstChildFile.getName(),
|
||||
firstChildFileSharded = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
|
||||
Map<String, Object> propertiesFirstChild = Map.of(PropertyIds.NAME, firstChildFileSharded.getName(),
|
||||
PropertyIds.OBJECT_TYPE_ID, "cmis:document",
|
||||
"cmis:secondaryObjectTypeIds", secondaryTypes,
|
||||
"shard:shardId", "0");
|
||||
|
||||
// Create a second child in parent folder. It will be indexed in shard 1.
|
||||
FileModel secondChildFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
|
||||
Map<String, Object> propertiesSecondChild = Map.of(PropertyIds.NAME, secondChildFile.getName(),
|
||||
secondChildFileSharded = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
|
||||
Map<String, Object> propertiesSecondChild = Map.of(PropertyIds.NAME, secondChildFileSharded.getName(),
|
||||
PropertyIds.OBJECT_TYPE_ID, "cmis:document",
|
||||
"cmis:secondaryObjectTypeIds", secondaryTypes,
|
||||
"shard:shardId", "1");
|
||||
|
||||
|
||||
cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(parentFolder, parentProperties).then()
|
||||
.usingResource(parentFolder)
|
||||
.createFile(firstChildFile, propertiesFirstChild, VersioningState.MAJOR)
|
||||
.createFile(secondChildFile, propertiesSecondChild, VersioningState.MAJOR);
|
||||
cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(parentFolderSharded, parentProperties).then()
|
||||
.usingResource(parentFolderSharded)
|
||||
.createFile(firstChildFileSharded, propertiesFirstChild, VersioningState.MAJOR)
|
||||
.createFile(secondChildFileSharded, propertiesSecondChild, VersioningState.MAJOR);
|
||||
|
||||
// Check everything is indexed
|
||||
Assert.assertTrue(waitForIndexing(firstChildFile.getName(), true), "file: " + firstChildFile.getName() + " has not been indexed.");
|
||||
Assert.assertTrue(waitForIndexing(secondChildFile.getName(), true), "file: " + secondChildFile.getName() + " has not been indexed.");
|
||||
Assert.assertTrue(waitForIndexing(parentFolder.getName(), true), "file: " + parentFolder.getName() + " has not been indexed.");
|
||||
assertTrue(waitForIndexing(firstChildFileSharded.getName(), true), "file: " + firstChildFileSharded.getName() + " has not been indexed.");
|
||||
assertTrue(waitForIndexing(secondChildFileSharded.getName(), true), "file: " + secondChildFileSharded.getName() + " has not been indexed.");
|
||||
assertTrue(waitForIndexing(parentFolderSharded.getName(), true), "file: " + parentFolderSharded.getName() + " has not been indexed.");
|
||||
|
||||
// Query to find nodes where Path with original folder name matches
|
||||
String parentQuery = "PATH:\"/app:company_home/st:sites/cm:" + testSite.getTitle() +
|
||||
"/cm:documentLibrary/cm:" + parentFolder.getName() + "/*\"";
|
||||
"/cm:documentLibrary/cm:" + parentFolderSharded.getName() + "/*\"";
|
||||
|
||||
// Rename parent folder
|
||||
String parentNewName = "parentRenamedSharding";
|
||||
parentFolder.setName(parentNewName);
|
||||
parentFolderSharded.setName(parentNewName);
|
||||
ContentModel parentNewNameModel = new ContentModel(parentNewName);
|
||||
dataContent.usingUser(testUser).usingResource(parentFolder).renameContent(parentNewNameModel);
|
||||
dataContent.usingUser(testUser).usingResource(parentFolderSharded).renameContent(parentNewNameModel);
|
||||
|
||||
String parentQueryAfterRename = "PATH:\"/app:company_home/st:sites/cm:" + testSite.getTitle() +
|
||||
"/cm:documentLibrary/cm:" + parentNewName + "/*\"";
|
||||
@@ -199,9 +243,9 @@ public class CascadingTrackerIntegrationTest extends AbstractE2EFunctionalTest
|
||||
Assert.assertEquals(descendantCountOfNewNameBeforeUpdate, 0, "There should be 0 results performing the new query before updating parent name");
|
||||
|
||||
|
||||
Assert.assertTrue(waitForMetadataIndexing(parentNewName, true), "failing while renaming " + parentFolder.getName() + " to " + parentNewName);
|
||||
assertTrue(waitForMetadataIndexing(parentNewName, true), "failing while renaming " + parentFolderSharded.getName() + " to " + parentNewName);
|
||||
|
||||
boolean indexingInProgress = !isContentInSearchResults(parentQueryAfterRename, firstChildFile.getName(), true);
|
||||
boolean indexingInProgress = !isContentInSearchResults(parentQueryAfterRename, firstChildFileSharded.getName(), true);
|
||||
|
||||
// Query using new parent name: Expect the two children
|
||||
int descendantCountOfNewName = query(parentQueryAfterRename).getPagination().getCount();
|
||||
@@ -210,6 +254,7 @@ public class CascadingTrackerIntegrationTest extends AbstractE2EFunctionalTest
|
||||
// Query using old parent name: Expect no descendant after rename
|
||||
int descendantCountOfOriginalName = query(parentQuery).getPagination().getCount();
|
||||
Assert.assertEquals(descendantCountOfOriginalName, 0, "Old path still has descendants: " + parentQuery);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,10 @@
|
||||
<connection>scm:git:https://git.alfresco.com/search_discovery/insightengine.git</connection>
|
||||
<developerConnection>scm:git:https://git.alfresco.com/search_discovery/insightengine.git</developerConnection>
|
||||
<url>https://git.alfresco.com/search_discovery/insightengine.git</url>
|
||||
<tag>1.1.0</tag>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
<solr.base.version>6.6.5</solr.base.version>
|
||||
<solr.version>${solr.base.version}-patched</solr.version>
|
||||
<!-- The location to download the solr zip file from. -->
|
||||
@@ -38,7 +39,23 @@
|
||||
<modules>
|
||||
<module>search-services</module>
|
||||
<module>insight-engine</module>
|
||||
<module>e2e-test</module>
|
||||
</modules>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<release>${java.version}</release>
|
||||
<target>${java.version}</target>
|
||||
<showWarnings>true</showWarnings>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<!-- Used to declare false positives for FindBugs -->
|
||||
<dependency>
|
||||
|
||||
+55
-17
@@ -24,6 +24,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
@@ -59,6 +60,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import static java.util.Optional.of;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static org.alfresco.solr.tracker.DocRouterFactory.SHARD_KEY_KEY;
|
||||
|
||||
/*
|
||||
@@ -82,9 +84,9 @@ public class MetadataTracker extends AbstractTracker implements Tracker
|
||||
private ConcurrentLinkedQueue<String> queriesToReindex = new ConcurrentLinkedQueue<String>();
|
||||
private DocRouter docRouter;
|
||||
/** The string representation of the shard key. */
|
||||
private String shardKey;
|
||||
private Optional<String> shardKey;
|
||||
/** The property to use for determining the shard. */
|
||||
private QName shardProperty;
|
||||
private Optional<QName> shardProperty = Optional.empty();
|
||||
|
||||
public MetadataTracker(Properties p, SOLRAPIClient client, String coreName,
|
||||
InformationServer informationServer)
|
||||
@@ -92,8 +94,8 @@ public class MetadataTracker extends AbstractTracker implements Tracker
|
||||
super(p, client, coreName, informationServer, Tracker.Type.MetaData);
|
||||
transactionDocsBatchSize = Integer.parseInt(p.getProperty("alfresco.transactionDocsBatchSize", "100"));
|
||||
shardMethod = p.getProperty("shard.method", SHARD_METHOD_DBID);
|
||||
shardKey = p.getProperty(SHARD_KEY_KEY);
|
||||
updateShardProperty();
|
||||
shardKey = ofNullable(p.getProperty(SHARD_KEY_KEY));
|
||||
firstUpdateShardProperty();
|
||||
docRouter = DocRouterFactory.getRouter(p, ShardMethodEnum.getShardMethod(shardMethod));
|
||||
nodeBatchSize = Integer.parseInt(p.getProperty("alfresco.nodeBatchSize", "10"));
|
||||
threadHandler = new ThreadHandler(p, coreName, "MetadataTracker");
|
||||
@@ -104,12 +106,35 @@ public class MetadataTracker extends AbstractTracker implements Tracker
|
||||
*/
|
||||
private void updateShardProperty()
|
||||
{
|
||||
if(shardProperty == null && shardKey != null)
|
||||
{
|
||||
shardProperty = getShardProperty(shardKey);
|
||||
}
|
||||
shardKey.ifPresent(shardKeyName -> {
|
||||
Optional<QName> updatedShardProperty = getShardProperty(shardKeyName);
|
||||
if (!shardProperty.equals(updatedShardProperty))
|
||||
{
|
||||
if (updatedShardProperty.isEmpty())
|
||||
{
|
||||
log.warn("The model defining " + shardKeyName + " property has been disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
log.info("New " + SHARD_KEY_KEY + " property found for " + shardKeyName);
|
||||
}
|
||||
}
|
||||
shardProperty = updatedShardProperty;
|
||||
});
|
||||
}
|
||||
|
||||
private void firstUpdateShardProperty()
|
||||
{
|
||||
shardKey.ifPresent( shardKeyName -> {
|
||||
updateShardProperty();
|
||||
if (shardProperty.isEmpty())
|
||||
{
|
||||
log.warn("Sharding property " + SHARD_KEY_KEY + " was set to " + shardKeyName + ", but no such property was found.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
MetadataTracker()
|
||||
{
|
||||
super(Tracker.Type.MetaData);
|
||||
@@ -174,7 +199,6 @@ public class MetadataTracker extends AbstractTracker implements Tracker
|
||||
* will pull its data from a "tracking" Solr node using Solr's master/slave replication, rather then tracking the repository.
|
||||
*
|
||||
*/
|
||||
|
||||
ShardState shardstate = getShardState();
|
||||
client.getTransactions(0L, null, 0L, null, 0, shardstate);
|
||||
return;
|
||||
@@ -240,8 +264,9 @@ public class MetadataTracker extends AbstractTracker implements Tracker
|
||||
propertyBag.put("coreName", coreName);
|
||||
HashMap<String, String> extendedPropertyBag = new HashMap<>(propertyBag);
|
||||
updateShardProperty();
|
||||
extendedPropertyBag.putAll(docRouter.getProperties(shardProperty));
|
||||
|
||||
|
||||
shardProperty.ifPresent(p -> extendedPropertyBag.putAll(docRouter.getProperties(p)));
|
||||
|
||||
return ShardStateBuilder.shardState()
|
||||
.withMaster(isMaster)
|
||||
.withLastUpdated(System.currentTimeMillis())
|
||||
@@ -382,7 +407,9 @@ public class MetadataTracker extends AbstractTracker implements Tracker
|
||||
gnp.setStoreProtocol(storeRef.getProtocol());
|
||||
gnp.setStoreIdentifier(storeRef.getIdentifier());
|
||||
updateShardProperty();
|
||||
gnp.setShardProperty(shardProperty);
|
||||
|
||||
shardProperty.ifPresent(p -> gnp.setShardProperty(p));
|
||||
|
||||
gnp.setCoreName(coreName);
|
||||
|
||||
List<Node> nodes = client.getNodes(gnp, (int) info.getUpdates());
|
||||
@@ -478,7 +505,7 @@ public class MetadataTracker extends AbstractTracker implements Tracker
|
||||
gnp.setStoreProtocol(storeRef.getProtocol());
|
||||
gnp.setStoreIdentifier(storeRef.getIdentifier());
|
||||
gnp.setCoreName(coreName);
|
||||
List<Node> nodes = client.getNodes(gnp, (int) info.getUpdates());
|
||||
List<Node> nodes = client.getNodes(gnp, (int) info.getUpdates());
|
||||
for (Node node : nodes)
|
||||
{
|
||||
docCount++;
|
||||
@@ -903,7 +930,8 @@ public class MetadataTracker extends AbstractTracker implements Tracker
|
||||
gnp.setStoreProtocol(storeRef.getProtocol());
|
||||
gnp.setStoreIdentifier(storeRef.getIdentifier());
|
||||
updateShardProperty();
|
||||
gnp.setShardProperty(shardProperty);
|
||||
shardProperty.ifPresent(p -> gnp.setShardProperty(p));
|
||||
|
||||
gnp.setCoreName(coreName);
|
||||
List<Node> nodes = client.getNodes(gnp, Integer.MAX_VALUE);
|
||||
|
||||
@@ -1203,7 +1231,17 @@ public class MetadataTracker extends AbstractTracker implements Tracker
|
||||
this.queriesToReindex.offer(query);
|
||||
}
|
||||
|
||||
public static QName getShardProperty(String field)
|
||||
|
||||
/**
|
||||
* Given the field name, returns the name of the property definition.
|
||||
* If the property definition is not found, Empty optional is returned.
|
||||
*
|
||||
* @param field
|
||||
*
|
||||
* @return the name of the associated property definition if present, Optional.Empty() otherwise
|
||||
*
|
||||
*/
|
||||
public static Optional<QName> getShardProperty(String field)
|
||||
{
|
||||
if (StringUtils.isBlank(field))
|
||||
{
|
||||
@@ -1218,8 +1256,8 @@ public class MetadataTracker extends AbstractTracker implements Tracker
|
||||
field);
|
||||
if (propertyDef == null)
|
||||
{
|
||||
throw new IllegalStateException("Sharding property " + SHARD_KEY_KEY + " was set to " + field + ", but no such property was found.");
|
||||
return Optional.empty();
|
||||
}
|
||||
return propertyDef.getName();
|
||||
return of(propertyDef.getName());
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -20,6 +20,7 @@ package org.alfresco.solr.tracker;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.solr.AbstractAlfrescoDistributedTest;
|
||||
import org.alfresco.solr.AlfrescoSolrDataModel;
|
||||
import org.alfresco.solr.client.Acl;
|
||||
@@ -43,6 +44,7 @@ import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.stream.IntStream.range;
|
||||
@@ -120,8 +122,11 @@ public abstract class DistributedDateAbstractSolrTrackerTest extends AbstractAlf
|
||||
indexTransaction(bigTxn, nodes, nodeMetaDatas);
|
||||
waitForDocCount(new TermQuery(new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "world")), numNodes, 100000);
|
||||
|
||||
Optional<QName> shardProperty = MetadataTracker.getShardProperty("created");
|
||||
assertTrue("'created' field is expected to be found in data model", shardProperty.isPresent());
|
||||
|
||||
List<AlfrescoSolrDataModel.FieldInstance> fieldInstanceList =
|
||||
AlfrescoSolrDataModel.getInstance().getIndexedFieldNamesForProperty(MetadataTracker.getShardProperty("created")).getFields();
|
||||
AlfrescoSolrDataModel.getInstance().getIndexedFieldNamesForProperty(shardProperty.get()).getFields();
|
||||
|
||||
AlfrescoSolrDataModel.FieldInstance fieldInstance = fieldInstanceList.get(0);
|
||||
String fieldName = fieldInstance.getField();
|
||||
|
||||
+6
-1
@@ -32,6 +32,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.indexAclChangeSet;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.index.shard.ShardMethodEnum;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.solr.AbstractAlfrescoDistributedTest;
|
||||
import org.alfresco.solr.AlfrescoSolrDataModel;
|
||||
import org.alfresco.solr.SolrInformationServer;
|
||||
@@ -57,6 +58,7 @@ import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.TimeZone;
|
||||
|
||||
@@ -139,7 +141,10 @@ public class DistributedDateMonthAlfrescoSolrTrackerTest extends AbstractAlfresc
|
||||
waitForDocCount(new TermQuery(new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "world")), numNodes, 100000);
|
||||
waitForDocCountAllCores(new TermQuery(new Term(FIELD_DOC_TYPE, SolrInformationServer.DOC_TYPE_ACL)), numAcls, 100000);
|
||||
|
||||
List<AlfrescoSolrDataModel.FieldInstance> fieldInstanceList = AlfrescoSolrDataModel.getInstance().getIndexedFieldNamesForProperty(MetadataTracker.getShardProperty("created")).getFields();
|
||||
Optional<QName> shardProperty = MetadataTracker.getShardProperty("created");
|
||||
assertTrue(shardProperty.isPresent());
|
||||
|
||||
List<AlfrescoSolrDataModel.FieldInstance> fieldInstanceList = AlfrescoSolrDataModel.getInstance().getIndexedFieldNamesForProperty(shardProperty.get()).getFields();
|
||||
AlfrescoSolrDataModel.FieldInstance fieldInstance = fieldInstanceList.get(0);
|
||||
String fieldName = fieldInstance.getField();
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
</distributionManagement>
|
||||
|
||||
<properties>
|
||||
<dependency.alfresco-data-model.version>8.48</dependency.alfresco-data-model.version>
|
||||
<dependency.alfresco-data-model.version>8.49</dependency.alfresco-data-model.version>
|
||||
<dependency.jackson.version>2.10.0.pr2</dependency.jackson.version>
|
||||
</properties>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user