Merge pull request #1502 from Alfresco/servicepack/MNT-23154_cherrypick

Servicepack/MNT-23154 (cherrypick)
This commit is contained in:
Andrea Gazzarini
2022-09-16 11:21:22 +02:00
committed by GitHub
8 changed files with 479 additions and 22 deletions
@@ -36,6 +36,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@@ -45,6 +46,7 @@ import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
@@ -128,17 +130,42 @@ import static org.alfresco.solr.SolrInformationServer.UNIT_OF_TIME_YEAR_FIELD_SU
*/
public class AlfrescoSolrDataModel implements QueryConstants
{
public static class ContentPropertySpecs {
public final String fieldName;
public final String locale;
public ContentPropertySpecs(String fieldName, String locale) {
this.fieldName = fieldName;
this.locale = locale;
}
}
public static class TenantDbId
{
public String tenant;
public Long dbId;
private List<ContentPropertySpecs> contentPropertySpecsList;
public Map<String, Object> optionalBag = new HashMap<>();
public void setProperty(String name, Object value)
{
optionalBag.put(name, value);
}
public boolean hasAtLeastOneContentProperty() {
return contentPropertySpecsList != null && !contentPropertySpecsList.isEmpty();
}
public void addContentPropertiesSpecs(List<ContentPropertySpecs> specsList)
{
contentPropertySpecsList = Collections.unmodifiableList(specsList);
}
public Stream<ContentPropertySpecs> contentPropertySpecsStream() {
return contentPropertySpecsList.stream();
}
}
public enum FieldUse
@@ -28,8 +28,10 @@ package org.alfresco.solr;
import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.Collections.emptyList;
import static java.util.Optional.empty;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList;
import static org.alfresco.repo.search.adaptor.QueryConstants.FIELD_ACLID;
import static org.alfresco.repo.search.adaptor.QueryConstants.FIELD_ACLTXCOMMITTIME;
import static org.alfresco.repo.search.adaptor.QueryConstants.FIELD_ACLTXID;
@@ -361,6 +363,9 @@ public class SolrInformationServer implements InformationServer
private static final long CONTENT_OUTDATED_MARKER = -10;
private static final long CONTENT_UPDATED_MARKER = -20;
private static final String CONTENT_FIELD_NAME = "contentFieldName";
private static final String CONTENT_LOCALE = "contentLocale";
private static final String CONTENT_LOCALE_FIELD = "content@s__locale@{http://www.alfresco.org/model/content/1.0}content";
private static final Set<String> ID_AND_CONTENT_VERSION_ID_AND_CONTENT_LOCALE =
new HashSet<>(asList(FIELD_SOLR4_ID, LATEST_APPLIED_CONTENT_VERSION_ID, CONTENT_LOCALE_FIELD));
@@ -460,6 +465,8 @@ public class SolrInformationServer implements InformationServer
private final boolean dateFieldDestructuringHasBeenEnabledOnThisInstance;
private final boolean enabledIndexCustomContent;
static class DocListCollector implements Collector, LeafCollector
{
private final IntArrayList docs = new IntArrayList();
@@ -642,6 +649,8 @@ public class SolrInformationServer implements InformationServer
port = portNumber(props);
baseUrl = baseUrl(props);
enabledIndexCustomContent = Boolean.parseBoolean(coreConfiguration.getProperty("solr.enableIndexingCustomContent", "false"));
dateFieldDestructuringHasBeenEnabledOnThisInstance = Boolean.parseBoolean(coreConfiguration.getProperty("alfresco.destructureDateFields", "true"));
LOGGER.info(
"Date fields destructuring has been {} on this instance.",
@@ -999,9 +1008,17 @@ public class SolrInformationServer implements InformationServer
String idString = id.stringValue();
TenantDbId tenantAndDbId = AlfrescoSolrDataModel.decodeNodeDocumentId(idString);
ofNullable(document.getField(CONTENT_LOCALE_FIELD))
.map(IndexableField::stringValue)
.ifPresent(value -> tenantAndDbId.setProperty(CONTENT_LOCALE_FIELD, value));
tenantAndDbId.addContentPropertiesSpecs(
enabledIndexCustomContent
? document.getFields().stream()
.filter(field -> field.name().startsWith(AlfrescoSolrDataModel.CONTENT_S_LOCALE_PREFIX))
.map(field -> new AlfrescoSolrDataModel.ContentPropertySpecs(field.name(),field.stringValue()))
.collect(toList())
: ofNullable(document.getField(CONTENT_LOCALE_FIELD))
.map(IndexableField::stringValue)
.map(value -> new AlfrescoSolrDataModel.ContentPropertySpecs(CONTENT_LOCALE_FIELD, value))
.map(Collections::singletonList)
.orElse(emptyList()));
tenantAndDbId.setProperty(
LATEST_APPLIED_CONTENT_VERSION_ID,
@@ -1879,7 +1896,7 @@ public class SolrInformationServer implements InformationServer
nmdp.setMaxResults(1);
// Gets only one
Optional<Collection<NodeMetaData>> nodeMetaDatas = getNodesMetaDataFromRepository(nmdp);
allNodeMetaDatas.addAll(nodeMetaDatas.orElse(Collections.emptyList()));
allNodeMetaDatas.addAll(nodeMetaDatas.orElse(emptyList()));
}
return allNodeMetaDatas;
@@ -1933,7 +1950,7 @@ public class SolrInformationServer implements InformationServer
docRef.tenant,
docRef.dbId));
if (docRef.optionalBag.containsKey(CONTENT_LOCALE_FIELD))
if (docRef.hasAtLeastOneContentProperty())
{
addContentToDoc(docRef, doc, docRef.dbId);
}
@@ -1985,8 +2002,8 @@ public class SolrInformationServer implements InformationServer
categorizeNodes(nodes, nodeIdsToNodes, nodeStatusToNodeIds);
List<Long> deletedNodeIds = notNullOrEmpty(nodeStatusToNodeIds.get(SolrApiNodeStatus.DELETED));
List<Long> shardDeletedNodeIds = Collections.emptyList();
List<Long> shardUpdatedNodeIds = Collections.emptyList();
List<Long> shardDeletedNodeIds = emptyList();
List<Long> shardUpdatedNodeIds = emptyList();
if (cascadeTrackingEnabled())
{
shardDeletedNodeIds = notNullOrEmpty(nodeStatusToNodeIds.get(SolrApiNodeStatus.NON_SHARD_DELETED));
@@ -2438,7 +2455,7 @@ public class SolrInformationServer implements InformationServer
dataModel.getIndexedFieldNamesForProperty(propertyQName).getFields()
.stream()
.map(FieldInstance::getField)
.collect(Collectors.toList()));
.collect(toList()));
for (PropertyValue singleValue : typedValue.getValues())
{
@@ -2711,12 +2728,17 @@ public class SolrInformationServer implements InformationServer
}
}
private void addContentToDoc(TenantDbId docRef, SolrInputDocument doc, long dbId) throws AuthenticationException, IOException
private void addContentToDoc(TenantDbId docRef, SolrInputDocument doc, long dbId)
{
String locale = (String) docRef.optionalBag.get(CONTENT_LOCALE_FIELD);
String qNamePart = CONTENT_LOCALE_FIELD.substring(AlfrescoSolrDataModel.CONTENT_S_LOCALE_PREFIX.length());
QName propertyQName = QName.createQName(qNamePart);
addContentPropertyToDocUsingAlfrescoRepository(doc, propertyQName, dbId, locale);
docRef.contentPropertySpecsStream()
.forEach(propertySpecs -> {
try {
var propertyQName = QName.createQName(propertySpecs.fieldName.substring(AlfrescoSolrDataModel.CONTENT_S_LOCALE_PREFIX.length()));
addContentPropertyToDocUsingAlfrescoRepository(doc, propertyQName, dbId, propertySpecs.locale);
} catch (AuthenticationException | IOException exception) {
throw new RuntimeException(exception);
}
});
}
@@ -2829,7 +2851,7 @@ public class SolrInformationServer implements InformationServer
{
if (mlTextPropertyValue == null)
{
return Collections.emptyList();
return emptyList();
}
List<String> values = new ArrayList<>();
@@ -2891,7 +2913,7 @@ public class SolrInformationServer implements InformationServer
.stream()
.filter(Objects::nonNull)
.map(mlTextPropertyValue::getValue)
.collect(Collectors.toList());
.collect(toList());
if (!localisedValues.isEmpty())
{
@@ -234,6 +234,11 @@ solr.request.content.compress=false
#
solr.initial.transaction.range=0-2000
# set it to true to allow custom d:content fields to be indexed.
# N.B. At most one content field can be indexed for each document
solr.enableIndexingCustomContent=false
# Facet query limit when retrieving info for the stats (used in the acl transaction and index transaction reports
# and fix)
alfresco.stats.facetLimit=100
@@ -29,6 +29,8 @@ package org.alfresco.solr;
import static java.util.Arrays.asList;
import static org.alfresco.repo.search.adaptor.QueryConstants.FIELD_DOC_TYPE;
import org.alfresco.model.ContentModel;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.client.Node;
import org.alfresco.solr.client.NodeMetaData;
import org.alfresco.solr.client.SOLRAPIQueueClient;
@@ -79,6 +81,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
@@ -776,6 +779,23 @@ public abstract class AbstractAlfrescoDistributedIT extends SolrITInitializer
//First map the nodes to a transaction.
SOLRAPIQueueClient.NODE_MAP.put(transaction.getId(), nodes);
//Next map a node to the NodeMetaData
int i=0;
for(NodeMetaData nodeMetaData : nodeMetaDatas)
{
SOLRAPIQueueClient.NODE_META_DATA_MAP.put(nodeMetaData.getId(), nodeMetaData);
SOLRAPIQueueClient.NODE_CONTENT_MAP.put(nodeMetaData.getId(), Map.of(ContentModel.PROP_CONTENT, content.get(i++)));
}
//Next add the transaction to the queue
SOLRAPIQueueClient.TRANSACTION_QUEUE.add(transaction);
}
public static void indexTransactionWithMultipleContentFields(Transaction transaction, List<Node> nodes, List<NodeMetaData> nodeMetaDatas, List<Map<QName, String>> content)
{
//First map the nodes to a transaction.
SOLRAPIQueueClient.NODE_MAP.put(transaction.getId(), nodes);
//Next map a node to the NodeMetaData
int i=0;
for(NodeMetaData nodeMetaData : nodeMetaDatas)
@@ -26,6 +26,7 @@
package org.alfresco.solr;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.search.impl.parsers.FTSQueryParser;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.search.SearchParameters;
@@ -85,6 +86,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import static java.util.Optional.of;
@@ -662,7 +664,7 @@ public abstract class AbstractAlfrescoSolrIT implements SolrTestFiles, AlfrescoS
for(NodeMetaData nodeMetaData : nodeMetaDatas)
{
SOLRAPIQueueClient.NODE_META_DATA_MAP.put(nodeMetaData.getId(), nodeMetaData);
SOLRAPIQueueClient.NODE_CONTENT_MAP.put(nodeMetaData.getId(), content.get(i++));
SOLRAPIQueueClient.NODE_CONTENT_MAP.put(nodeMetaData.getId(), Map.of(ContentModel.PROP_CONTENT, content.get(i++)));
}
//Next add the transaction to the queue
@@ -2,7 +2,7 @@
* #%L
* Alfresco Search Services
* %%
* Copyright (C) 2005 - 2020 Alfresco Software Limited
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -46,7 +46,7 @@ import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ContentTrackerIT
public class ContentTrackerTest
{
private ContentTracker contentTracker;
@@ -0,0 +1,382 @@
/*
* #%L
* Alfresco Search Services
* %%
* Copyright (C) 2005 - 2022 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.solr.tracker;
import org.alfresco.model.ContentModel;
import org.alfresco.service.namespace.QName;
import org.alfresco.solr.AbstractAlfrescoDistributedIT;
import org.alfresco.solr.client.Acl;
import org.alfresco.solr.client.ContentPropertyValue;
import org.alfresco.solr.client.Node;
import org.alfresco.solr.client.NodeMetaData;
import org.alfresco.solr.client.Transaction;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.TermQuery;
import org.apache.solr.SolrTestCaseJ4;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Stream;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
import static java.util.stream.IntStream.range;
import static org.alfresco.solr.AlfrescoSolrUtils.MAX_WAIT_TIME;
import static org.alfresco.solr.AlfrescoSolrUtils.getAcl;
import static org.alfresco.solr.AlfrescoSolrUtils.getAclChangeSet;
import static org.alfresco.solr.AlfrescoSolrUtils.getAclReaders;
import static org.alfresco.solr.AlfrescoSolrUtils.getNode;
import static org.alfresco.solr.AlfrescoSolrUtils.getNodeMetaData;
import static org.alfresco.solr.AlfrescoSolrUtils.getTransaction;
import static org.alfresco.solr.AlfrescoSolrUtils.indexAclChangeSet;
@SolrTestCaseJ4.SuppressSSL
public class DistributedContentPropertiesIT extends AbstractAlfrescoDistributedIT
{
@BeforeClass
public static void initData() throws Throwable
{
var solrCoreProperties = DEFAULT_CORE_PROPS;
solrCoreProperties.setProperty("solr.enableIndexingCustomContent", "true");
initSolrServers(3, DistributedContentPropertiesIT.class.getSimpleName(), solrCoreProperties);
}
@After
public void clearData() throws Exception
{
deleteByQueryAllClients("*:*");
explicitCommitOnAllClients();
}
@AfterClass
public static void destroyData()
{
dismissSolrServers();
}
/**
* In this scenario we have n nodes.
* Among them:
*
* <ul>
* <li>n-m have one default cm:content field </li>
* <li>the m do not have a value for the content field (i.e. the value of the content field is empty) </li>
* </ul>
*/
@Test
public void eachNodeHasAtMaximumOneCmContentField() throws Exception
{
putHandleDefaults();
var aclChangeSet = getAclChangeSet(1, 1);
var acl = getAcl(aclChangeSet);
var aclReaders = getAclReaders(aclChangeSet, acl, singletonList("joel"), singletonList("phil"), null);
indexAclChangeSet(aclChangeSet, singletonList(acl), singletonList(aclReaders));
var howManyTestNodes = 10;
var transaction = getTransaction(0, howManyTestNodes);
var nodes = nodes(howManyTestNodes, transaction, acl);
var metadata = metadata(nodes, transaction, acl);
var howManyNodesWithContent = howManyTestNodes - 3;
indexTransaction(transaction, nodes, metadata, textContent(nodes, "Lorem ipsum dolor sit amet", howManyNodesWithContent));
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "ipsum")),
howManyNodesWithContent, MAX_WAIT_TIME);
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}" + ContentModel.PROP_PERSONDESC.getLocalName(), "ipsum")),
0, MAX_WAIT_TIME);
}
/**
* In this scenario we have n nodes.
* Among them:
*
* <ul>
* <li>n-m have one custom content field (i.e. a field different from cm:content).</li>
* <li>the m do not have a value for the content field (i.e. the value of the content field is empty) </li>
* </ul>
*/
@Test
public void eachNodeHasAtMaximumOneCustomContentField() throws Exception
{
putHandleDefaults();
var aclChangeSet = getAclChangeSet(1, 1);
var acl = getAcl(aclChangeSet);
// Arbitrary acl data.
var aclReaders = getAclReaders(aclChangeSet, acl, singletonList("joel"), singletonList("phil"), null);
indexAclChangeSet(aclChangeSet, singletonList(acl), singletonList(aclReaders));
var howManyTestNodes = 10;
var transaction = getTransaction(0, howManyTestNodes);
var nodes = nodes(howManyTestNodes, transaction, acl);
var metadata =
metadata(nodes, transaction, acl).stream()
.peek(nodeMetadata -> {
nodeMetadata.getProperties().remove(ContentModel.PROP_CONTENT);
nodeMetadata.getProperties().put(ContentModel.PROP_PERSONDESC,
new ContentPropertyValue(Locale.US, 0L, "UTF-8", "text/plain", null));})
.collect(toList());
var howManyNodesWithContent = howManyTestNodes - 4;
var howManyNodesWithoutContent = howManyTestNodes - howManyNodesWithContent;
var textContents =
Stream.concat(
range(0, howManyNodesWithContent)
.mapToObj(index -> Map.of(ContentModel.PROP_PERSONDESC, "consectetur Adipiscing elit " + System.currentTimeMillis())),
range(0, howManyNodesWithoutContent)
.mapToObj(index -> Map.of(ContentModel.PROP_PERSONDESC, "")))
.collect(toList());
indexTransactionWithMultipleContentFields(transaction, nodes, metadata, textContents);
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}" + ContentModel.PROP_PERSONDESC.getLocalName(), "adipiscing")),
howManyNodesWithContent,
MAX_WAIT_TIME);
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "adipiscing")),
0, MAX_WAIT_TIME);
}
/**
* In this scenario we have n nodes.
* Among them:
*
* <ul>
* <li>n-m have one default and one custom content field (i.e. a field different from cm:content).</li>
* <li>the m do not have a value for those content fields (i.e. the value of the content fields is empty) </li>
* </ul>
*/
@Test
public void eachNodeHasOneCustomAndOneDefaultContentField() throws Exception
{
putHandleDefaults();
var aclChangeSet = getAclChangeSet(1, 1);
var acl = getAcl(aclChangeSet);
var aclReaders = getAclReaders(aclChangeSet, acl, singletonList("joel"), singletonList("phil"), null);
indexAclChangeSet(aclChangeSet, singletonList(acl), singletonList(aclReaders));
var howManyTestNodes = 10;
var transaction = getTransaction(0, howManyTestNodes);
var nodes = nodes(howManyTestNodes, transaction, acl);
var metadata =
metadata(nodes, transaction, acl).stream()
.peek(nodeMetadata ->
nodeMetadata.getProperties().put(ContentModel.PROP_PERSONDESC,
new ContentPropertyValue(Locale.US, 0L, "UTF-8", "text/plain", null)))
.collect(toList());
var howManyNodesWithContent = howManyTestNodes - 2;
indexTransactionWithMultipleContentFields(
transaction,
nodes,
metadata,
textContentWithMultipleContentFields(
nodes,
"Lorem ipsum dolor sit amet",
"consectetur Adipiscing elit",
howManyNodesWithContent));
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}" + ContentModel.PROP_PERSONDESC.getLocalName(), "consectetur")),
howManyNodesWithContent,
MAX_WAIT_TIME);
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "ipsum")),
howManyNodesWithContent, MAX_WAIT_TIME);
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}" + ContentModel.PROP_PERSONDESC.getLocalName(), "ipsum")),
0,
MAX_WAIT_TIME);
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "elit")),
0, MAX_WAIT_TIME);
}
/**
* In this scenario we have n + m + y nodes.
* Among them:
*
* <ul>
* <li>n nodes have one custom content field (i.e. a field different from cm:content).</li>
* <li>m nodes have one default content field (i.e. cm:content).</li>
* <li>y nodes do not have a value for the content field </li>
* </ul>
*/
@Test
public void someNodeHasOneCustomAndSomeNodeHasOneDefaultContentField() throws Exception
{
putHandleDefaults();
var aclChangeSet = getAclChangeSet(1, 1);
var acl = getAcl(aclChangeSet);
var aclReaders = getAclReaders(aclChangeSet, acl, singletonList("joel"), singletonList("phil"), null);
indexAclChangeSet(aclChangeSet, singletonList(acl), singletonList(aclReaders));
var howManyTestNodes = 10;
var transaction = getTransaction(0, howManyTestNodes);
var nodes = nodes(howManyTestNodes, transaction, acl);
var metadata =
metadata(nodes, transaction, acl).stream()
.peek(nodeMetadata ->
nodeMetadata.getProperties().put(ContentModel.PROP_PERSONDESC,
new ContentPropertyValue(Locale.US, 0L, "UTF-8", "text/plain", null)))
.collect(toList());
var howManyNodesWithContent = howManyTestNodes - 2;
var howManyNodesWithDefaultContentField = 3;
var howManyNodesWithCustomContentField = howManyNodesWithContent - howManyNodesWithDefaultContentField;
var howManyNodesWithoutContent = howManyTestNodes - howManyNodesWithContent;
var baseCmContentText = "Lorem ipsum dolor sit amet";
var basePersonDescriptionText = "consectetur Adipiscing elit";
var texts =
Stream.concat(
range(0, howManyNodesWithDefaultContentField)
.mapToObj(index -> Map.of(
ContentModel.PROP_CONTENT, baseCmContentText + " " + System.currentTimeMillis(),
ContentModel.PROP_PERSONDESC, "")),
range(0, howManyNodesWithCustomContentField)
.mapToObj(index -> Map.of(
ContentModel.PROP_CONTENT, "",
ContentModel.PROP_PERSONDESC, basePersonDescriptionText + " " + System.currentTimeMillis())));
var textContents =
Stream.concat(
texts,
range(0, howManyNodesWithoutContent)
.mapToObj(index -> Map.of(
ContentModel.PROP_CONTENT, "",
ContentModel.PROP_PERSONDESC, ""))).collect(toList());
indexTransactionWithMultipleContentFields(
transaction,
nodes,
metadata,
textContents);
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}" + ContentModel.PROP_PERSONDESC.getLocalName(), "consectetur")),
howManyNodesWithCustomContentField,
MAX_WAIT_TIME);
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "ipsum")),
howManyNodesWithDefaultContentField, MAX_WAIT_TIME);
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}" + ContentModel.PROP_PERSONDESC.getLocalName(), "ipsum")),
0,
MAX_WAIT_TIME);
waitForDocCount(
new TermQuery(
new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "elit")),
0, MAX_WAIT_TIME);
}
private List<Node> nodes(int howMany, Transaction transaction, Acl acl)
{
return range(0, howMany)
.mapToObj(index -> getNode(transaction, acl, Node.SolrApiNodeStatus.UPDATED))
.collect(toList());
}
private List<NodeMetaData> metadata(List<Node> nodes, Transaction transaction, Acl acl)
{
return nodes.stream()
.map(node -> getNodeMetaData(node, transaction, acl, "mike", null, false))
.collect(toList());
}
private List<String> textContent(List<Node> nodes, String baseText, int limit)
{
return Stream.concat(
nodes.stream()
.map(node -> baseText + " " + System.currentTimeMillis())
.limit(limit),
range(0, nodes.size() - limit)
.mapToObj(index -> "")).collect(toList());
}
private List<Map<QName, String>> textContentWithMultipleContentFields(List<Node> nodes, String baseCmContentText, String basePersonDescriptionText, int limit)
{
var texts = nodes.stream()
.map(node -> Map.of(
ContentModel.PROP_CONTENT, baseCmContentText + " " + System.currentTimeMillis(),
ContentModel.PROP_PERSONDESC, basePersonDescriptionText + " " + System.currentTimeMillis()))
.limit(limit);
return Stream.concat(
texts,
range(0, nodes.size() - limit)
.mapToObj(index -> Map.of(
ContentModel.PROP_CONTENT, "",
ContentModel.PROP_PERSONDESC, ""))).collect(toList());
}
}
@@ -2,7 +2,7 @@
* #%L
* Alfresco Search Services
* %%
* Copyright (C) 2005 - 2020 Alfresco Software Limited
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -65,7 +65,7 @@ public class SOLRAPIQueueClient extends SOLRAPIClient
public final static List<Transaction> TRANSACTION_QUEUE = Collections.synchronizedList(new ArrayList<>());
public final static Map<Long, List<Node>> NODE_MAP = Collections.synchronizedMap(new HashMap<>());
public final static Map<Long, NodeMetaData> NODE_META_DATA_MAP = Collections.synchronizedMap(new HashMap<>());
public final static Map<Long, String> NODE_CONTENT_MAP = Collections.synchronizedMap(new HashMap<>());
public final static Map<Long, Map<QName, String>> NODE_CONTENT_MAP = Collections.synchronizedMap(new HashMap<>());
private static boolean throwException;
@@ -154,7 +154,6 @@ public class SOLRAPIQueueClient extends SOLRAPIClient
.collect(toList());
}
public List<AlfrescoModelDiff> getModelsDiff(String coreName, List<AlfrescoModel> currentModels) throws IOException, JSONException
{
if(throwException)
@@ -365,7 +364,7 @@ public class SOLRAPIQueueClient extends SOLRAPIClient
if(NODE_CONTENT_MAP.containsKey(nodeId))
{
return new GetTextContentResponse(new DummyResponse(NODE_CONTENT_MAP.get(nodeId)));
return new GetTextContentResponse(new DummyResponse(NODE_CONTENT_MAP.get(nodeId).get(propertyQName)));
}
return new GetTextContentResponse(new DummyResponse("Hello world " + nodeId));