mirror of
https://github.com/Alfresco/SearchServices.git
synced 2025-09-17 14:21:20 +00:00
[MNT-20179] Integration Test + some test refactor
This commit is contained in:
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2017 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package org.alfresco.dataload;
|
||||
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrClient;
|
||||
import org.apache.solr.client.solrj.request.UpdateRequest;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Random;
|
||||
|
||||
public class Loader {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
int num = Integer.parseInt(args[0]);
|
||||
int start = Integer.parseInt(args[1]);
|
||||
//String url = "http://localhost:8985/solr/joel";
|
||||
String url = "http://localhost:8983/solr/collection1";
|
||||
|
||||
HttpSolrClient client = new HttpSolrClient(url);
|
||||
UpdateRequest request = new UpdateRequest();
|
||||
int i = start;
|
||||
LocalDateTime localDate = LocalDateTime.now();
|
||||
|
||||
Random rand = new Random();
|
||||
for(i=start; i<num+start; i++) {
|
||||
String s = rand.nextInt(1000)+"helloworld123";
|
||||
SolrInputDocument doc = new SolrInputDocument();
|
||||
doc.addField("id", i);
|
||||
doc.addField("test_s", s);
|
||||
doc.addField("test_t", "hello world we love you");
|
||||
int year = rand.nextInt(50);
|
||||
int month = rand.nextInt(12);
|
||||
int day = rand.nextInt(30);
|
||||
float f = rand.nextFloat();
|
||||
|
||||
doc.addField("year_i", Integer.toString(year));
|
||||
doc.addField("month_i", Integer.toString(month));
|
||||
doc.addField("day_i", Integer.toString(day));
|
||||
doc.addField("price_f", Float.toString(f));
|
||||
|
||||
LocalDateTime randomDate = localDate.plusDays(rand.nextInt(1000));
|
||||
doc.addField("date_dt", DateTimeFormatter.ISO_INSTANT.format(randomDate.toInstant(ZoneOffset.UTC)));
|
||||
doc.addField("epoch_l", randomDate.atZone(ZoneOffset.UTC).toInstant().toEpochMilli());
|
||||
|
||||
request.add(doc);
|
||||
if(i % 5000 == 0) {
|
||||
request.process(client);
|
||||
client.commit();
|
||||
request = new UpdateRequest();
|
||||
}
|
||||
|
||||
|
||||
for(int l=0; l<5; l++) {
|
||||
String ps = "product"+rand.nextInt(35);
|
||||
doc.addField("prod_ss",ps);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if((i % 5000) != 0) {
|
||||
request.process(client);
|
||||
client.commit();
|
||||
}
|
||||
|
||||
client.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.alfresco.solr;
|
||||
|
||||
import static java.util.Optional.of;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static junit.framework.TestCase.assertNotNull;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
import static org.alfresco.repo.search.adaptor.lucene.QueryConstants.FIELD_ACLID;
|
||||
@@ -68,6 +70,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.index.shard.ShardState;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -86,11 +89,11 @@ import org.alfresco.solr.client.StringPropertyValue;
|
||||
import org.alfresco.solr.client.Transaction;
|
||||
import org.alfresco.util.ISO9075;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
import org.apache.solr.SolrTestCaseJ4.XmlDoc;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.apache.solr.common.params.CoreAdminParams;
|
||||
import org.apache.solr.common.params.ModifiableSolrParams;
|
||||
import org.apache.solr.common.params.SolrParams;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.common.util.XML;
|
||||
import org.apache.solr.core.CoreContainer;
|
||||
@@ -108,6 +111,8 @@ import org.apache.solr.update.CommitUpdateCommand;
|
||||
public class AlfrescoSolrUtils
|
||||
{
|
||||
public static final String TEST_NAMESPACE = "http://www.alfresco.org/test/solrtest";
|
||||
public static long MAX_WAIT_TIME = 80000;
|
||||
|
||||
/**
|
||||
* Get transaction.
|
||||
* @param deletes
|
||||
@@ -884,5 +889,40 @@ public class AlfrescoSolrUtils
|
||||
assertTrue("There must be a searcher for "+coreName, ((Integer)coreSummary.get("Number of Searchers")) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the input {@link ShardState} and the CoreAdmin.SUMMARY response give the same information.
|
||||
*
|
||||
* @param state the {@link ShardState} instance.
|
||||
* @param core the target {@link SolrCore} instance.
|
||||
*/
|
||||
public static void assertShardAndCoreSummaryConsistency(ShardState state, SolrCore core) {
|
||||
SolrParams params =
|
||||
new ModifiableSolrParams()
|
||||
.add(CoreAdminParams.CORE, core.getName())
|
||||
.add(CoreAdminParams.ACTION, "SUMMARY");
|
||||
|
||||
}
|
||||
SolrQueryRequest request = new LocalSolrQueryRequest(core, params);
|
||||
SolrQueryResponse response = new SolrQueryResponse();
|
||||
coreAdminHandler(core).handleRequest(request, response);
|
||||
|
||||
NamedList<?> summary =
|
||||
ofNullable(response.getValues())
|
||||
.map(values -> values.get("Summary"))
|
||||
.map(NamedList.class::cast)
|
||||
.map(values -> values.get(core.getName()))
|
||||
.map(NamedList.class::cast)
|
||||
.orElseGet(NamedList::new);
|
||||
|
||||
assertEquals(state.getLastIndexedChangeSetId(), summary.get("Id for last Change Set in index"));
|
||||
assertEquals(state.getLastIndexedChangeSetCommitTime(), summary.get("Last Index Change Set Commit Time"));
|
||||
assertEquals(state.getLastIndexedTxCommitTime(), summary.get("Last Index TX Commit Time"));
|
||||
assertEquals(state.getLastIndexedTxId(), summary.get("Id for last TX in index"));
|
||||
}
|
||||
|
||||
public static AlfrescoCoreAdminHandler coreAdminHandler(SolrCore core) {
|
||||
return of(core).map(SolrCore::getCoreContainer)
|
||||
.map(CoreContainer::getMultiCoreHandler)
|
||||
.map(AlfrescoCoreAdminHandler.class::cast)
|
||||
.orElseThrow(() -> new IllegalStateException("Cannot retrieve the Core Admin Handler on this test core."));
|
||||
}
|
||||
}
|
@@ -16,10 +16,11 @@
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.solr.query.afts;
|
||||
package org.alfresco.solr.dataload;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.stream.IntStream.range;
|
||||
import static org.alfresco.model.ContentModel.ASSOC_CONTAINS;
|
||||
import static org.alfresco.model.ContentModel.ASSOC_CHILDREN;
|
||||
import static org.alfresco.model.ContentModel.PROP_NAME;
|
||||
@@ -28,6 +29,8 @@ import static org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.addNode;
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.createGUID;
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.addStoreRoot;
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.getNode;
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.getNodeMetaData;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
@@ -39,19 +42,27 @@ import org.alfresco.service.cmr.repository.datatype.Duration;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.solr.AlfrescoSolrConstants;
|
||||
import org.alfresco.solr.AlfrescoSolrDataModel;
|
||||
import org.alfresco.solr.client.Acl;
|
||||
import org.alfresco.solr.client.ContentPropertyValue;
|
||||
import org.alfresco.solr.client.MLTextPropertyValue;
|
||||
import org.alfresco.solr.client.MultiPropertyValue;
|
||||
import org.alfresco.solr.client.Node;
|
||||
import org.alfresco.solr.client.NodeMetaData;
|
||||
import org.alfresco.solr.client.PropertyValue;
|
||||
import org.alfresco.solr.client.StringPropertyValue;
|
||||
import org.alfresco.solr.client.Transaction;
|
||||
import org.alfresco.util.ISO9075;
|
||||
import org.apache.solr.client.solrj.io.Tuple;
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.util.TestHarness;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Test datasets provider.
|
||||
@@ -855,6 +866,14 @@ public class TestDataProvider implements AlfrescoSolrConstants
|
||||
return testProperties;
|
||||
}
|
||||
|
||||
public static Map.Entry<List<Node>, List<NodeMetaData>> nSampleNodesWithSampleContent(Acl acl, Transaction txn, int howManyNodes) {
|
||||
|
||||
List<Node> nodes = range(0, howManyNodes).mapToObj(index -> getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED)).collect(Collectors.toList());
|
||||
List<NodeMetaData> metadata = nodes.stream().map(node -> getNodeMetaData(node, txn, acl, "mike", null, false)).collect(Collectors.toList());
|
||||
|
||||
return new AbstractMap.SimpleImmutableEntry<>(nodes, metadata);
|
||||
}
|
||||
|
||||
public NodeRef newNodeRef()
|
||||
{
|
||||
return new NodeRef(new StoreRef("workspace", "SpacesStore"), createGUID());
|
@@ -19,7 +19,7 @@
|
||||
package org.alfresco.solr.query.afts.qparser;
|
||||
|
||||
import org.alfresco.repo.search.adaptor.lucene.QueryConstants;
|
||||
import org.alfresco.solr.query.afts.TestDataProvider;
|
||||
import org.alfresco.solr.dataload.TestDataProvider;
|
||||
import org.alfresco.util.ISO9075;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
@@ -30,7 +30,7 @@ import static org.alfresco.model.ContentModel.TYPE_THUMBNAIL;
|
||||
|
||||
import org.alfresco.repo.search.adaptor.lucene.QueryConstants;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.solr.query.afts.TestDataProvider;
|
||||
import org.alfresco.solr.dataload.TestDataProvider;
|
||||
import org.alfresco.util.CachingDateFormat;
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
import org.junit.BeforeClass;
|
||||
|
@@ -22,7 +22,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.solr.client.PropertyValue;
|
||||
import org.alfresco.solr.client.StringPropertyValue;
|
||||
import org.alfresco.solr.query.afts.TestDataProvider;
|
||||
import org.alfresco.solr.dataload.TestDataProvider;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.solr.client.PropertyValue;
|
||||
import org.alfresco.solr.client.StringPropertyValue;
|
||||
import org.alfresco.solr.query.afts.TestDataProvider;
|
||||
import org.alfresco.solr.dataload.TestDataProvider;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@@ -27,7 +27,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.solr.client.PropertyValue;
|
||||
import org.alfresco.solr.client.StringPropertyValue;
|
||||
import org.alfresco.solr.query.afts.TestDataProvider;
|
||||
import org.alfresco.solr.dataload.TestDataProvider;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@@ -28,7 +28,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.solr.client.PropertyValue;
|
||||
import org.alfresco.solr.client.StringPropertyValue;
|
||||
import org.alfresco.solr.query.afts.TestDataProvider;
|
||||
import org.alfresco.solr.dataload.TestDataProvider;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
@@ -10,7 +10,7 @@ import org.alfresco.repo.search.adaptor.lucene.QueryConstants;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.solr.AlfrescoSolrDataModel;
|
||||
import org.alfresco.solr.SolrInformationServer;
|
||||
import org.alfresco.solr.query.afts.TestDataProvider;
|
||||
import org.alfresco.solr.dataload.TestDataProvider;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
import org.junit.BeforeClass;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package org.alfresco.solr.query.afts.requestHandler;
|
||||
|
||||
import org.alfresco.solr.query.afts.TestDataProvider;
|
||||
import org.alfresco.solr.dataload.TestDataProvider;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@@ -19,7 +19,6 @@
|
||||
|
||||
package org.alfresco.solr.tracker;
|
||||
|
||||
import org.alfresco.repo.index.shard.ShardState;
|
||||
import org.alfresco.repo.search.adaptor.lucene.QueryConstants;
|
||||
import org.alfresco.solr.AbstractAlfrescoSolrTests;
|
||||
import org.alfresco.solr.AlfrescoCoreAdminHandler;
|
||||
@@ -29,135 +28,98 @@ import org.alfresco.solr.client.AclReaders;
|
||||
import org.alfresco.solr.client.Node;
|
||||
import org.alfresco.solr.client.NodeMetaData;
|
||||
import org.alfresco.solr.client.Transaction;
|
||||
import org.alfresco.solr.dataload.TestDataProvider;
|
||||
import org.apache.lucene.document.LongPoint;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.LegacyNumericRangeQuery;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.solr.common.params.CoreAdminParams;
|
||||
import org.apache.solr.common.params.ModifiableSolrParams;
|
||||
import org.apache.solr.common.params.SolrParams;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.core.CoreContainer;
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.request.LocalSolrQueryRequest;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.response.SolrQueryResponse;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Optional.of;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.MAX_WAIT_TIME;
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.assertShardAndCoreSummaryConsistency;
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.coreAdminHandler;
|
||||
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;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* A partial state of {@link org.alfresco.solr.TrackerState} is exposed through two interfaces: AdminHandler.SUMMARY and
|
||||
* {@link MetadataTracker#getShardState}.
|
||||
*
|
||||
* This test makes sure that state is consistent across the two mentioned approaches. That is, properties returned by the
|
||||
* Core SUMMARY must have the same value of the same properties in the ShardState.
|
||||
*
|
||||
* @author agazzarini
|
||||
*/
|
||||
public class AlfrescoSolrTrackerStateTest extends AbstractAlfrescoSolrTests
|
||||
{
|
||||
private static long MAX_WAIT_TIME = 80000;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception
|
||||
{
|
||||
initAlfrescoCore("schema.xml");
|
||||
}
|
||||
|
||||
private Acl acl;
|
||||
|
||||
@Before
|
||||
public void prepare() throws Exception
|
||||
{
|
||||
AclChangeSet aclChangeSet = getAclChangeSet(1);
|
||||
acl = getAcl(aclChangeSet);
|
||||
|
||||
Acl acl = getAcl(aclChangeSet);
|
||||
Acl acl2 = getAcl(aclChangeSet);
|
||||
|
||||
AclReaders aclReaders = getAclReaders(aclChangeSet, acl, singletonList("joel"), singletonList("phil"), null);
|
||||
AclReaders aclReaders2 = getAclReaders(aclChangeSet, acl2, singletonList("jim"), singletonList("phil"), null);
|
||||
|
||||
indexAclChangeSet(aclChangeSet,
|
||||
asList(acl, acl2),
|
||||
asList(aclReaders, aclReaders2));
|
||||
indexAclChangeSet(aclChangeSet, asList(acl, acl2), asList(aclReaders, aclReaders2));
|
||||
|
||||
// Check for the ACL state stamp.
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!ACLTX")), BooleanClause.Occur.MUST));
|
||||
builder.add(new BooleanClause(LegacyNumericRangeQuery.newLongRange(QueryConstants.FIELD_S_ACLTXID, aclChangeSet.getId(), aclChangeSet.getId() + 1, true, false), BooleanClause.Occur.MUST));
|
||||
BooleanQuery waitForQuery = builder.build();
|
||||
waitForDocCount(waitForQuery, 1, MAX_WAIT_TIME);
|
||||
|
||||
int howManyTestNodes = 4;
|
||||
|
||||
Transaction txn = getTransaction(0, howManyTestNodes);
|
||||
Map.Entry<List<Node>, List<NodeMetaData>> data = TestDataProvider.nSampleNodesWithSampleContent(acl, txn, howManyTestNodes);
|
||||
|
||||
indexTransaction(txn, data.getKey(), data.getValue());
|
||||
|
||||
makeSureTransactionHasBeenIndexed(txn.getId());
|
||||
makeSureNodesHaveBeenIndexed(data.getKey().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shardStateMustBeConsistentWithCoreSummaryStats() throws Exception
|
||||
@SuppressWarnings("deprecated")
|
||||
public void shardStateMustBeConsistentWithCoreSummaryStats()
|
||||
{
|
||||
Transaction txn = getTransaction(0, 4);
|
||||
|
||||
Node node1 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED);
|
||||
Node node2 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED);
|
||||
Node node3 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED);
|
||||
Node node4 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED);
|
||||
|
||||
NodeMetaData nodeMetaData1 = getNodeMetaData(node1, txn, acl, "mike", null, false);
|
||||
NodeMetaData nodeMetaData2 = getNodeMetaData(node2, txn, acl, "mike", null, false);
|
||||
NodeMetaData nodeMetaData3 = getNodeMetaData(node3, txn, acl, "mike", null, false);
|
||||
NodeMetaData nodeMetaData4 = getNodeMetaData(node4, txn, acl, "mike", null, false);
|
||||
|
||||
indexTransaction(txn,
|
||||
asList(node1, node2, node3, node4),
|
||||
asList(nodeMetaData1, nodeMetaData2, nodeMetaData3, nodeMetaData4));
|
||||
|
||||
makeSureTransactionHasBeenIndexed(txn.getId());
|
||||
makeSureNodesHaveBeenIndexed("mike", 4);
|
||||
|
||||
SolrCore core = getCore();
|
||||
AlfrescoCoreAdminHandler adminHandler =
|
||||
of(core).map(SolrCore::getCoreContainer)
|
||||
.map(CoreContainer::getMultiCoreHandler)
|
||||
.map(AlfrescoCoreAdminHandler.class::cast)
|
||||
.orElseThrow(() -> new IllegalStateException("Cannot retrieve the Core Admin Handler on this test core."));
|
||||
|
||||
MetadataTracker tracker =
|
||||
of(adminHandler)
|
||||
.map(AlfrescoCoreAdminHandler::getTrackerRegistry)
|
||||
.map(registry -> registry.getTrackerForCore(core.getName(), MetadataTracker.class))
|
||||
.orElseThrow(() -> new IllegalStateException("Cannot retrieve the Metadata tracker on this test core."));
|
||||
of(coreAdminHandler(core))
|
||||
.map(AlfrescoCoreAdminHandler::getTrackerRegistry)
|
||||
.map(registry -> registry.getTrackerForCore(core.getName(), MetadataTracker.class))
|
||||
.orElseThrow(() -> new IllegalStateException("Cannot retrieve the Metadata tracker on this test core."));
|
||||
|
||||
|
||||
ShardState state = tracker.getShardState();
|
||||
|
||||
SolrParams params =
|
||||
new ModifiableSolrParams()
|
||||
.add(CoreAdminParams.CORE, core.getName())
|
||||
.add(CoreAdminParams.ACTION, "SUMMARY");
|
||||
|
||||
SolrQueryRequest request = new LocalSolrQueryRequest(core, params);
|
||||
SolrQueryResponse response = new SolrQueryResponse();
|
||||
adminHandler.handleRequest(request, response);
|
||||
|
||||
NamedList<?> summary =
|
||||
ofNullable(response.getValues())
|
||||
.map(values -> values.get("Summary"))
|
||||
.map(NamedList.class::cast)
|
||||
.map(values -> values.get(core.getName()))
|
||||
.map(NamedList.class::cast)
|
||||
.orElseGet(NamedList::new);
|
||||
|
||||
assertEquals(state.getLastIndexedChangeSetId(), summary.get("Id for last Change Set in index"));
|
||||
assertEquals(state.getLastIndexedChangeSetCommitTime(), summary.get("Last Index Change Set Commit Time"));
|
||||
assertEquals(state.getLastIndexedTxCommitTime(), summary.get("Last Index TX Commit Time"));
|
||||
assertEquals(state.getLastIndexedTxId(), summary.get("Id for last TX in index"));
|
||||
assertShardAndCoreSummaryConsistency(tracker.getShardState(), core);
|
||||
}
|
||||
|
||||
private void makeSureTransactionHasBeenIndexed(long transactionId) throws Exception
|
||||
{
|
||||
//Check for the TXN state stamp.
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!TX")), BooleanClause.Occur.MUST));
|
||||
builder.add(new BooleanClause(LegacyNumericRangeQuery.newLongRange(QueryConstants.FIELD_S_TXID, transactionId, transactionId + 1, true, false), BooleanClause.Occur.MUST));
|
||||
@@ -165,36 +127,14 @@ public class AlfrescoSolrTrackerStateTest extends AbstractAlfrescoSolrTests
|
||||
waitForDocCount(waitForQuery, 1, MAX_WAIT_TIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the index using a token from the (dummy) text produced by the test framework.
|
||||
* Once the query returns a positive result we are sure the ContentTracker
|
||||
*
|
||||
* <ol>
|
||||
* <li>
|
||||
* Fetched the text content associated with the test nodes, from Alfresco
|
||||
* </li>
|
||||
* <li>
|
||||
* Computed a fingerprint (using the retrieved text) for each node
|
||||
* </li>
|
||||
* <li>
|
||||
* Updated the nodes definitions in the (Solr)ContentStore and in Solr
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* Last but not least, we are also making sure that CommitTracker executed its cycle as well (otherwise documents
|
||||
* wouldn't be searchable).
|
||||
*
|
||||
* @param owner the #FIELD_OWNER which will be used as an additional required query clause.
|
||||
* @throws Exception in case the MAX_WAIT_TIME is reached and the node is not in results.
|
||||
*/
|
||||
private void makeSureNodesHaveBeenIndexed(final String owner, final int expectedCount) throws Exception
|
||||
private void makeSureNodesHaveBeenIndexed(int expectedCount) throws Exception
|
||||
{
|
||||
waitForDocCount(new TermQuery(new Term(QueryConstants.FIELD_READER, "jim")), 1, MAX_WAIT_TIME);
|
||||
waitForDocCount(new TermQuery(new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "world")), expectedCount, MAX_WAIT_TIME);
|
||||
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.add(new BooleanClause(new TermQuery(new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "world")), BooleanClause.Occur.MUST));
|
||||
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_OWNER, owner)), BooleanClause.Occur.MUST));
|
||||
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_OWNER, "mike")), BooleanClause.Occur.MUST));
|
||||
waitForDocCount(builder.build(), expectedCount, MAX_WAIT_TIME);
|
||||
}
|
||||
}
|
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package org.alfresco.solr.tracker;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Optional.of;
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.MAX_WAIT_TIME;
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.assertShardAndCoreSummaryConsistency;
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.coreAdminHandler;
|
||||
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.getTransaction;
|
||||
import static org.alfresco.solr.AlfrescoSolrUtils.indexAclChangeSet;
|
||||
|
||||
import org.alfresco.repo.search.adaptor.lucene.QueryConstants;
|
||||
import org.alfresco.solr.AbstractAlfrescoDistributedTest;
|
||||
import org.alfresco.solr.AlfrescoCoreAdminHandler;
|
||||
import org.alfresco.solr.client.Acl;
|
||||
import org.alfresco.solr.client.AclChangeSet;
|
||||
import org.alfresco.solr.client.AclReaders;
|
||||
import org.alfresco.solr.client.Node;
|
||||
import org.alfresco.solr.client.NodeMetaData;
|
||||
import org.alfresco.solr.client.Transaction;
|
||||
import org.alfresco.solr.dataload.TestDataProvider;
|
||||
import org.apache.lucene.document.LongPoint;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.LegacyNumericRangeQuery;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A partial state of {@link org.alfresco.solr.TrackerState} is exposed through two interfaces: AdminHandler.SUMMARY and
|
||||
* {@link MetadataTracker#getShardState}.
|
||||
* This test makes sure that state is consistent across the two mentioned approaches. That is, properties returned by the
|
||||
* Core SUMMARY must have the same value of the same properties in the ShardState.
|
||||
*
|
||||
* Note that this is the distributed version of {@link AlfrescoSolrTrackerStateTest}.
|
||||
*
|
||||
* @author agazzarini
|
||||
*/
|
||||
public class DistributedAlfrescoSolrTrackerStateTest extends AbstractAlfrescoDistributedTest
|
||||
{
|
||||
@BeforeClass
|
||||
private static void initData() throws Throwable
|
||||
{
|
||||
int howManyShards = 5;
|
||||
int howManyNodes = 15;
|
||||
|
||||
initSolrServers(howManyShards, getClassName(),null);
|
||||
|
||||
AclChangeSet aclChangeSet = getAclChangeSet(1);
|
||||
|
||||
Acl acl = getAcl(aclChangeSet);
|
||||
Acl acl2 = getAcl(aclChangeSet);
|
||||
|
||||
AclReaders aclReaders = getAclReaders(aclChangeSet, acl, singletonList("joel"), singletonList("phil"), null);
|
||||
AclReaders aclReaders2 = getAclReaders(aclChangeSet, acl2, singletonList("jim"), singletonList("phil"), null);
|
||||
|
||||
indexAclChangeSet(aclChangeSet, asList(acl, acl2), asList(aclReaders, aclReaders2));
|
||||
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!ACLTX")), BooleanClause.Occur.MUST));
|
||||
builder.add(new BooleanClause(LongPoint.newExactQuery(QueryConstants.FIELD_S_ACLTXID, aclChangeSet.getId()), BooleanClause.Occur.MUST));
|
||||
BooleanQuery waitForQuery = builder.build();
|
||||
waitForDocCountAllCores(waitForQuery, 1, MAX_WAIT_TIME);
|
||||
|
||||
Transaction txn = getTransaction(0, howManyNodes);
|
||||
Map.Entry<List<Node>, List<NodeMetaData>> data = TestDataProvider.nSampleNodesWithSampleContent(acl, txn, howManyNodes);
|
||||
|
||||
indexTransaction(txn, data.getKey(), data.getValue());
|
||||
builder = new BooleanQuery.Builder();
|
||||
builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!TX")), BooleanClause.Occur.MUST));
|
||||
builder.add(new BooleanClause(LongPoint.newExactQuery(QueryConstants.FIELD_S_TXID, txn.getId()), BooleanClause.Occur.MUST));
|
||||
waitForQuery = builder.build();
|
||||
|
||||
waitForDocCountAllCores(waitForQuery, 1, MAX_WAIT_TIME);
|
||||
waitForDocCountAllCores(new TermQuery(new Term(QueryConstants.FIELD_READER, "jim")), 1, MAX_WAIT_TIME);
|
||||
waitForDocCount(new TermQuery(new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "world")), howManyNodes, MAX_WAIT_TIME);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
private static void destroyData()
|
||||
{
|
||||
dismissSolrServers();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shardStateMustBeConsistentWithCoreSummaryStats()
|
||||
{
|
||||
putHandleDefaults();
|
||||
|
||||
getJettyCores(solrShards).forEach(core -> {
|
||||
MetadataTracker tracker =
|
||||
of(coreAdminHandler(core))
|
||||
.map(AlfrescoCoreAdminHandler::getTrackerRegistry)
|
||||
.map(registry -> registry.getTrackerForCore(core.getName(), MetadataTracker.class))
|
||||
.orElseThrow(() -> new IllegalStateException("Cannot retrieve the Metadata tracker on this test core."));
|
||||
|
||||
assertShardAndCoreSummaryConsistency(tracker.getShardState(), core);
|
||||
});
|
||||
}
|
||||
}
|
@@ -118,7 +118,9 @@ public class DistributedDateMonthAlfrescoSolrTrackerTest extends AbstractAlfresc
|
||||
Date[] dates = new Date[5];
|
||||
|
||||
Calendar cal = new GregorianCalendar();
|
||||
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
for (int i = 0; i < dates.length; i++) {
|
||||
|
||||
cal.set(1980, i, 21);
|
||||
dates[i] = cal.getTime();
|
||||
}
|
||||
|
Reference in New Issue
Block a user