Merged searchrep (5.2.1) to 5.2.N (5.2.1)

136676 gjames: SEARCH-441: Adding a "history" scope that uses a fake store mapping to call a /solr/history index


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@137039 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gethin James
2017-06-01 11:08:01 +00:00
parent be9d0cc1f7
commit 743b6b2759
6 changed files with 89 additions and 10 deletions

View File

@@ -33,11 +33,14 @@ import org.alfresco.rest.api.search.model.Query;
import org.alfresco.rest.api.search.model.SearchQuery; import org.alfresco.rest.api.search.model.SearchQuery;
import org.alfresco.service.cmr.search.IntervalParameters; import org.alfresco.service.cmr.search.IntervalParameters;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -52,12 +55,15 @@ public class SearchRequestContext
private final Query query; private final Query query;
private final boolean includeRequest; private final boolean includeRequest;
private final Map<String, String> pivotKeys; private final Map<String, String> pivotKeys;
private final Set<String> stores;
private SearchRequestContext(Query query, boolean includeRequest) private SearchRequestContext(Query query, boolean includeRequest)
{ {
this.query = query; this.query = query;
this.includeRequest = includeRequest; this.includeRequest = includeRequest;
this.pivotKeys = new HashMap<>(); this.pivotKeys = new HashMap<>();
this.stores = new HashSet<>();
/** /**
this.facetQueries = facetQueries!=null?Collections.unmodifiableList(facetQueries): Collections.emptyList(); this.facetQueries = facetQueries!=null?Collections.unmodifiableList(facetQueries): Collections.emptyList();
this.facetFields = new FacetFields(facetFields!=null?Collections.unmodifiableList(facetFields.getFacets()):Collections.emptyList()); this.facetFields = new FacetFields(facetFields!=null?Collections.unmodifiableList(facetFields.getFacets()):Collections.emptyList());
@@ -87,4 +93,9 @@ public class SearchRequestContext
{ {
return pivotKeys; return pivotKeys;
} }
public Set<String> getStores()
{
return stores;
}
} }

View File

@@ -27,6 +27,7 @@
package org.alfresco.rest.api.search.impl; package org.alfresco.rest.api.search.impl;
import static org.alfresco.rest.api.search.impl.StoreMapper.DELETED; import static org.alfresco.rest.api.search.impl.StoreMapper.DELETED;
import static org.alfresco.rest.api.search.impl.StoreMapper.HISTORY;
import static org.alfresco.rest.api.search.impl.StoreMapper.LIVE_NODES; import static org.alfresco.rest.api.search.impl.StoreMapper.LIVE_NODES;
import static org.alfresco.rest.api.search.impl.StoreMapper.VERSIONS; import static org.alfresco.rest.api.search.impl.StoreMapper.VERSIONS;
import org.alfresco.repo.search.impl.lucene.SolrJSONResultSet; import org.alfresco.repo.search.impl.lucene.SolrJSONResultSet;
@@ -148,10 +149,11 @@ public class ResultMapper
Map<String, UserInfo> mapUserInfo = new HashMap<>(10); Map<String, UserInfo> mapUserInfo = new HashMap<>(10);
Map<NodeRef, List<Pair<String, List<String>>>> hightLighting = results.getHighlighting(); Map<NodeRef, List<Pair<String, List<String>>>> hightLighting = results.getHighlighting();
int notFound = 0; int notFound = 0;
boolean isHistory = searchRequestContext.getStores().contains(StoreMapper.HISTORY);
for (ResultSetRow row:results) for (ResultSetRow row:results)
{ {
Node aNode = getNode(row, params, mapUserInfo); Node aNode = getNode(row, params, mapUserInfo, isHistory);
if (aNode != null) if (aNode != null)
{ {
@@ -201,20 +203,27 @@ public class ResultMapper
/** /**
* Builds a node representation based on a ResultSetRow; * Builds a node representation based on a ResultSetRow;
* @param searchRequestContext
* @param aRow * @param aRow
* @param params * @param params
* @param mapUserInfo * @param mapUserInfo
* @param isHistory
* @return Node * @return Node
*/ */
public Node getNode(ResultSetRow aRow, Params params, Map<String, UserInfo> mapUserInfo) public Node getNode(ResultSetRow aRow, Params params, Map<String, UserInfo> mapUserInfo, boolean isHistory)
{ {
String nodeStore = storeMapper.getStore(aRow.getNodeRef()); String nodeStore = storeMapper.getStore(aRow.getNodeRef());
if (isHistory) nodeStore = HISTORY;
Node aNode = null; Node aNode = null;
switch (nodeStore) switch (nodeStore)
{ {
case LIVE_NODES: case LIVE_NODES:
aNode = nodes.getFolderOrDocument(aRow.getNodeRef(), null, null, params.getInclude(), mapUserInfo); aNode = nodes.getFolderOrDocument(aRow.getNodeRef(), null, null, params.getInclude(), mapUserInfo);
break; break;
case HISTORY:
aNode = nodes.getFolderOrDocument(aRow.getNodeRef(), null, null, params.getInclude(), mapUserInfo);
break;
case VERSIONS: case VERSIONS:
Map<QName, Serializable> properties = serviceRegistry.getNodeService().getProperties(aRow.getNodeRef()); Map<QName, Serializable> properties = serviceRegistry.getNodeService().getProperties(aRow.getNodeRef());
NodeRef frozenNodeRef = ((NodeRef) properties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF)); NodeRef frozenNodeRef = ((NodeRef) properties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF));

View File

@@ -119,7 +119,7 @@ public class SearchMapper
fromSpellCheck(sp, searchQuery.getSpellcheck()); fromSpellCheck(sp, searchQuery.getSpellcheck());
fromHighlight(sp, searchQuery.getHighlight()); fromHighlight(sp, searchQuery.getHighlight());
fromFacetIntervals(sp, searchQuery.getFacetIntervals()); fromFacetIntervals(sp, searchQuery.getFacetIntervals());
fromScope(sp, searchQuery.getScope()); fromScope(sp, searchQuery.getScope(), searchRequestContext);
fromLimits(sp, searchQuery.getLimits()); fromLimits(sp, searchQuery.getLimits());
return sp; return sp;
@@ -445,10 +445,11 @@ public class SearchMapper
/** /**
* SearchParameters from Scope object * SearchParameters from Scope object
* @param sp SearchParameters
* @param Scope scope * @param Scope scope
* @param sp SearchParameters
* @param searchRequestContext
*/ */
public void fromScope(SearchParameters sp, Scope scope) public void fromScope(SearchParameters sp, Scope scope, SearchRequestContext searchRequestContext)
{ {
if (scope != null) if (scope != null)
{ {
@@ -457,6 +458,8 @@ public class SearchMapper
{ {
//First reset the stores then add them. //First reset the stores then add them.
sp.getStores().clear(); sp.getStores().clear();
searchRequestContext.getStores().addAll(stores);
for (String aStore:stores) for (String aStore:stores)
{ {
try try
@@ -469,6 +472,12 @@ public class SearchMapper
new Object[] { aStore }); new Object[] { aStore });
} }
} }
if (stores.contains(StoreMapper.HISTORY) && (stores.size() > 1))
{
throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID,
new Object[] { ": scope 'history' can only be used on its own" });
}
} }
} }
} }

View File

@@ -43,10 +43,12 @@ public class StoreMapper
public static final String LIVE_NODES = "nodes"; public static final String LIVE_NODES = "nodes";
public static final String VERSIONS = "versions"; public static final String VERSIONS = "versions";
public static final String DELETED = "deleted-nodes"; public static final String DELETED = "deleted-nodes";
public static final String HISTORY = "history";
private static Log logger = LogFactory.getLog(StoreMapper.class); private static Log logger = LogFactory.getLog(StoreMapper.class);
public static final StoreRef STORE_REF_VERSION2_SPACESSTORE = new StoreRef("workspace", Version2Model.STORE_ID); public static final StoreRef STORE_REF_VERSION2_SPACESSTORE = new StoreRef("workspace", Version2Model.STORE_ID);
public static final StoreRef STORE_REF_HISTORY = new StoreRef("workspace", "history");
/** /**
* Work out which StoreRef this store belongs to. * Work out which StoreRef this store belongs to.
@@ -65,6 +67,8 @@ public class StoreMapper
return STORE_REF_VERSION2_SPACESSTORE; return STORE_REF_VERSION2_SPACESSTORE;
case DELETED: case DELETED:
return StoreRef.STORE_REF_ARCHIVE_SPACESSTORE; return StoreRef.STORE_REF_ARCHIVE_SPACESSTORE;
case HISTORY:
return STORE_REF_HISTORY;
} }
} }
throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID, throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID,
@@ -94,6 +98,11 @@ public class StoreMapper
{ {
return DELETED; return DELETED;
} }
if (STORE_REF_HISTORY.equals(nodeRef.getStoreRef()))
{
return HISTORY;
}
} }
logger.warn("Unknown store ref: "+nodeRef); logger.warn("Unknown store ref: "+nodeRef);

View File

@@ -249,7 +249,8 @@ public class ResultMapperTests
@Test @Test
public void testNoResults() throws Exception public void testNoResults() throws Exception
{ {
CollectionWithPagingInfo<Node> collection = mapper.toCollectionWithPagingInfo(EMPTY_PARAMS, null, null, new EmptyResultSet()); SearchRequestContext searchRequest = SearchRequestContext.from(SearchQuery.EMPTY);
CollectionWithPagingInfo<Node> collection = mapper.toCollectionWithPagingInfo(EMPTY_PARAMS, searchRequest, null, new EmptyResultSet());
assertNotNull(collection); assertNotNull(collection);
assertFalse(collection.hasMoreItems()); assertFalse(collection.hasMoreItems());
assertTrue(collection.getTotalItems() < 1); assertTrue(collection.getTotalItems() < 1);

View File

@@ -445,17 +445,18 @@ public class SearchMapperTests
{ {
SearchParameters searchParameters = new SearchParameters(); SearchParameters searchParameters = new SearchParameters();
searchMapper.setDefaults(searchParameters); searchMapper.setDefaults(searchParameters);
SearchRequestContext searchRequestContext = SearchRequestContext.from(minimalQuery());
//Doesn't error, has default store //Doesn't error, has default store
searchMapper.fromScope(searchParameters, null); searchMapper.fromScope(searchParameters, null, searchRequestContext);
assertEquals(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,searchParameters.getStores().get(0)); assertEquals(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,searchParameters.getStores().get(0));
searchMapper.fromScope(searchParameters, new Scope(null)); searchMapper.fromScope(searchParameters, new Scope(null), searchRequestContext);
assertEquals(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,searchParameters.getStores().get(0)); assertEquals(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,searchParameters.getStores().get(0));
try try
{ {
searchMapper.fromScope(searchParameters, new Scope(Arrays.asList("nonsense"))); searchMapper.fromScope(searchParameters, new Scope(Arrays.asList("nonsense")), searchRequestContext);
fail(); fail();
} }
catch (InvalidArgumentException iae) catch (InvalidArgumentException iae)
@@ -464,11 +465,50 @@ public class SearchMapperTests
assertNotNull(iae); assertNotNull(iae);
} }
searchMapper.fromScope(searchParameters, new Scope(Arrays.asList(StoreMapper.DELETED, StoreMapper.LIVE_NODES, StoreMapper.VERSIONS))); searchMapper.fromScope(searchParameters, new Scope(Arrays.asList(StoreMapper.DELETED, StoreMapper.LIVE_NODES, StoreMapper.VERSIONS)),
searchRequestContext);
assertEquals(3 ,searchParameters.getStores().size()); assertEquals(3 ,searchParameters.getStores().size());
assertEquals(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE.toString(),searchParameters.getStores().get(0).toString()); assertEquals(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE.toString(),searchParameters.getStores().get(0).toString());
assertEquals(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.toString(),searchParameters.getStores().get(1).toString()); assertEquals(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.toString(),searchParameters.getStores().get(1).toString());
assertEquals(StoreMapper.STORE_REF_VERSION2_SPACESSTORE.toString(),searchParameters.getStores().get(2).toString()); assertEquals(StoreMapper.STORE_REF_VERSION2_SPACESSTORE.toString(),searchParameters.getStores().get(2).toString());
searchMapper.fromScope(searchParameters, new Scope(Arrays.asList(StoreMapper.HISTORY)), searchRequestContext);
assertEquals(1 ,searchParameters.getStores().size());
assertEquals(StoreMapper.STORE_REF_HISTORY.toString(),searchParameters.getStores().get(0).toString());
try
{
searchMapper.fromScope(searchParameters, new Scope(Arrays.asList(StoreMapper.HISTORY, StoreMapper.DELETED)), searchRequestContext);
fail();
}
catch (InvalidArgumentException iae)
{
//Must be a valid scope with history
assertNotNull(iae);
}
try
{
searchMapper.fromScope(searchParameters, new Scope(Arrays.asList(StoreMapper.HISTORY, StoreMapper.LIVE_NODES)), searchRequestContext);
fail();
}
catch (InvalidArgumentException iae)
{
//Must be a valid scope with history
assertNotNull(iae);
}
try
{
searchMapper.fromScope(searchParameters, new Scope(Arrays.asList(StoreMapper.HISTORY, StoreMapper.VERSIONS)), searchRequestContext);
fail();
}
catch (InvalidArgumentException iae)
{
//Must be a valid scope with history
assertNotNull(iae);
}
} }
@Test @Test