You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by zh...@apache.org on 2016/07/29 02:16:36 UTC
incubator-geode git commit: This closes #219
Repository: incubator-geode
Updated Branches:
refs/heads/develop a4f93cdd6 -> 547fc4886
This closes #219
GEODE-11: Added Limit to lucene search gfsh commands
Added an option to specify limit in gfsh search. Added a dunit test to verify.
GEODE-11 : Pagination for gfsh lucene search command
Added pagination for gfsh lucene search results. Added junit test to verify.
GEODE-11 : Fixing display messages in pagination
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/547fc488
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/547fc488
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/547fc488
Branch: refs/heads/develop
Commit: 547fc48860c178c1e024379d58128264275fbc98
Parents: a4f93cd
Author: Aparna Dharmakkan <ad...@pivotal.io>
Authored: Wed Jul 20 13:50:59 2016 -0700
Committer: zhouxh <gz...@pivotal.io>
Committed: Thu Jul 28 19:09:44 2016 -0700
----------------------------------------------------------------------
.../lucene/internal/cli/LuceneCliStrings.java | 4 +
.../internal/cli/LuceneIndexCommands.java | 143 ++++++++++++++++---
.../lucene/internal/cli/LuceneQueryInfo.java | 11 +-
.../functions/LuceneSearchIndexFunction.java | 5 +-
.../cli/LuceneIndexCommandsDUnitTest.java | 32 +++++
.../cli/LuceneIndexCommandsJUnitTest.java | 98 ++++++++++++-
.../LuceneSearchIndexFunctionJUnitTest.java | 9 +-
7 files changed, 271 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/547fc488/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneCliStrings.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneCliStrings.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneCliStrings.java
index 2f61cf9..15d2ca7 100644
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneCliStrings.java
+++ b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneCliStrings.java
@@ -65,8 +65,12 @@ public class LuceneCliStrings {
public static final String LUCENE_SEARCH_INDEX__NAME__HELP = "Name of the lucene index to search.";
public static final String LUCENE_SEARCH_INDEX__REGION_HELP = "Name/Path of the region where the lucene index exists.";
public static final String LUCENE_SEARCH_INDEX__QUERY_STRING="queryStrings";
+ public static final String LUCENE_SEARCH_INDEX__LIMIT="limit";
+ public static final String LUCENE_SEARCH_INDEX__LIMIT__HELP="Number of search results needed";
public static final String LUCENE_SEARCH_INDEX__QUERY_STRING__HELP="Query string to search the lucene index";
public static final String LUCENE_SEARCH_INDEX__DEFAULT_FIELD="defaultField";
public static final String LUCENE_SEARCH_INDEX__DEFAULT_FIELD__HELP="Default field to search in";
public static final String LUCENE_SEARCH_INDEX__NO_RESULTS_MESSAGE="No results";
+ public static final String LUCENE_SEARCH_INDEX__PAGE_SIZE="pageSize";
+ public static final String LUCENE_SEARCH_INDEX__PAGE_SIZE__HELP="Number of results to be returned in a page";
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/547fc488/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommands.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommands.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommands.java
index 7f681da..0edd2ff 100755
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommands.java
+++ b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommands.java
@@ -16,6 +16,7 @@
*/
package com.gemstone.gemfire.cache.lucene.internal.cli;
+import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -31,6 +32,7 @@ import com.gemstone.gemfire.cache.execute.Execution;
import com.gemstone.gemfire.cache.execute.FunctionAdapter;
import com.gemstone.gemfire.cache.execute.FunctionInvocationTargetException;
import com.gemstone.gemfire.cache.execute.ResultCollector;
+
import com.gemstone.gemfire.cache.lucene.internal.cli.functions.LuceneCreateIndexFunction;
import com.gemstone.gemfire.cache.lucene.internal.cli.functions.LuceneDescribeIndexFunction;
import com.gemstone.gemfire.cache.lucene.internal.cli.functions.LuceneListIndexFunction;
@@ -45,9 +47,11 @@ import com.gemstone.gemfire.management.internal.cli.CliUtil;
import com.gemstone.gemfire.management.internal.cli.commands.AbstractCommandsSupport;
import com.gemstone.gemfire.management.internal.cli.functions.CliFunctionResult;
import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
+import com.gemstone.gemfire.management.internal.cli.result.CommandResult;
import com.gemstone.gemfire.management.internal.cli.result.CommandResultException;
import com.gemstone.gemfire.management.internal.cli.result.ResultBuilder;
import com.gemstone.gemfire.management.internal.cli.result.TabularResultData;
+import com.gemstone.gemfire.management.internal.cli.shell.Gfsh;
import com.gemstone.gemfire.management.internal.configuration.domain.XmlEntity;
import com.gemstone.gemfire.management.internal.security.ResourceOperation;
@@ -63,6 +67,7 @@ public class LuceneIndexCommands extends AbstractCommandsSupport {
private static final LuceneCreateIndexFunction createIndexFunction = new LuceneCreateIndexFunction();
private static final LuceneDescribeIndexFunction describeIndexFunction = new LuceneDescribeIndexFunction();
private static final LuceneSearchIndexFunction searchIndexFunction = new LuceneSearchIndexFunction();
+ private List<LuceneSearchResults> searchResults=null;
@CliCommand(value = LuceneCliStrings.LUCENE_LIST_INDEX, help = LuceneCliStrings.LUCENE_LIST_INDEX__HELP)
@CliMetaData(shellOnly = false, relatedTopic={CliStrings.TOPIC_GEODE_REGION, CliStrings.TOPIC_GEODE_DATA })
@@ -254,30 +259,43 @@ public class LuceneIndexCommands extends AbstractCommandsSupport {
}
@CliCommand(value = LuceneCliStrings.LUCENE_SEARCH_INDEX, help = LuceneCliStrings.LUCENE_SEARCH_INDEX__HELP)
- @CliMetaData(shellOnly = false, relatedTopic={CliStrings.TOPIC_GEODE_REGION, CliStrings.TOPIC_GEODE_DATA })
+ @CliMetaData(shellOnly = false, relatedTopic = { CliStrings.TOPIC_GEODE_REGION, CliStrings.TOPIC_GEODE_DATA })
@ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
public Result searchIndex(
@CliOption(key = LuceneCliStrings.LUCENE__INDEX_NAME,
- mandatory=true,
+ mandatory = true,
help = LuceneCliStrings.LUCENE_SEARCH_INDEX__NAME__HELP) final String indexName,
- @CliOption (key = LuceneCliStrings.LUCENE__REGION_PATH,
+ @CliOption(key = LuceneCliStrings.LUCENE__REGION_PATH,
mandatory = true,
optionContext = ConverterHint.REGIONPATH,
help = LuceneCliStrings.LUCENE_SEARCH_INDEX__REGION_HELP) final String regionPath,
- @CliOption (key = LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING,
+ @CliOption(key = LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING,
mandatory = true,
help = LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING__HELP) final String queryString,
- @CliOption (key = LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD,
+ @CliOption(key = LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD,
mandatory = true,
- help = LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD__HELP) final String defaultField) {
- try {
+ help = LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD__HELP) final String defaultField,
- LuceneQueryInfo queryInfo=new LuceneQueryInfo(indexName,regionPath,queryString, defaultField);
- return getSearchResults(queryInfo);
+ @CliOption(key = LuceneCliStrings.LUCENE_SEARCH_INDEX__LIMIT,
+ mandatory = false,
+ unspecifiedDefaultValue = "-1",
+ help = LuceneCliStrings.LUCENE_SEARCH_INDEX__LIMIT__HELP) final int limit,
+ @CliOption(key = LuceneCliStrings.LUCENE_SEARCH_INDEX__PAGE_SIZE,
+ mandatory = false,
+ unspecifiedDefaultValue = "-1",
+ help = LuceneCliStrings.LUCENE_SEARCH_INDEX__PAGE_SIZE__HELP) int pageSize)
+ {
+ try {
+ LuceneQueryInfo queryInfo = new LuceneQueryInfo(indexName, regionPath, queryString, defaultField, limit);
+ if (pageSize == -1) {
+ pageSize = Integer.MAX_VALUE;
+ }
+ searchResults = getSearchResults(queryInfo);
+ return displayResults(pageSize);
}
catch (FunctionInvocationTargetException ignore) {
return ResultBuilder.createGemFireErrorResult(CliStrings.format(CliStrings.COULD_NOT_EXECUTE_COMMAND_TRY_AGAIN,
@@ -295,29 +313,108 @@ public class LuceneIndexCommands extends AbstractCommandsSupport {
}
}
- private Result getSearchResults(final LuceneQueryInfo queryInfo) throws Exception {
+ private Result displayResults(int pageSize) throws IOException {
+ if (searchResults.size() == 0) {
+ return ResultBuilder.createInfoResult(LuceneCliStrings.LUCENE_SEARCH_INDEX__NO_RESULTS_MESSAGE);
+ }
+
+ Gfsh gfsh = initGfsh();
+ boolean pagination = searchResults.size() > pageSize;
+ int fromIndex = 0;
+ int toIndex = pageSize < searchResults.size() ? pageSize : searchResults.size();
+ int currentPage = 1;
+ int totalPages = (int) Math.ceil((float) searchResults.size() / pageSize);
+ boolean skipDisplay = false;
+ String step = null;
+ do {
+
+ if (!skipDisplay) {
+ CommandResult commandResult = (CommandResult) getResults(fromIndex, toIndex);
+ if (!pagination) {
+ return commandResult;
+ }
+ Gfsh.println();
+ while (commandResult.hasNextLine()) {
+ gfsh.printAsInfo(commandResult.nextLine());
+ }
+ gfsh.printAsInfo("\t\tPage " + currentPage + " of " + totalPages);
+ String message = ("Press n to move to next page, q to quit and p to previous page : ");
+ step = gfsh.interact(message);
+ }
+
+ switch (step) {
+ case "n":
+ {
+ if (currentPage == totalPages) {
+ gfsh.printAsInfo("No more results to display.");
+ step = gfsh.interact("Press p to move to last page and q to quit.");
+ skipDisplay = true;
+ continue;
+ }
+
+ if(skipDisplay) {
+ skipDisplay=false;
+ }
+ else {
+ currentPage++;
+ int current = fromIndex;
+ fromIndex = toIndex;
+ toIndex = (pageSize + fromIndex >= searchResults.size()) ? searchResults.size() : pageSize + fromIndex;
+ }
+ break;
+ }
+ case "p": {
+ if (currentPage == 1) {
+ gfsh.printAsInfo("At the top of the search results.");
+ step = gfsh.interact("Press n to move to the first page and q to quit.");
+ skipDisplay=true;
+ continue;
+ }
+
+ if (skipDisplay) {
+ skipDisplay = false;
+ }
+ else {
+ currentPage--;
+ int current = fromIndex;
+ toIndex = fromIndex;
+ fromIndex = current - pageSize <= 0 ? 0 : current - pageSize;
+ }
+ break;
+ }
+ case "q":
+ return ResultBuilder.createInfoResult("Search complete.");
+ default:
+ Gfsh.println("Invalid option");
+ break;
+ }
+ } while(true);
+ }
+
+ protected Gfsh initGfsh() {
+ return Gfsh.getCurrentInstance();
+ }
+
+ private List<LuceneSearchResults> getSearchResults(final LuceneQueryInfo queryInfo) throws CommandResultException {
GeodeSecurityUtil.authorizeRegionManage(queryInfo.getRegionPath());
final String[] groups = {};
final ResultCollector<?, ?> rc = this.executeFunctionOnGroups(searchIndexFunction, groups, queryInfo);
final List<Set<LuceneSearchResults>> functionResults = (List<Set<LuceneSearchResults>>) rc.getResult();
- List<LuceneSearchResults> results = functionResults.stream()
+ return functionResults.stream()
.flatMap(set -> set.stream())
.sorted()
.collect(Collectors.toList());
- if (results.size() != 0) {
- final TabularResultData data = ResultBuilder.createTabularResultData();
- for (LuceneSearchResults struct : results) {
- data.accumulate("key", struct.getKey());
- data.accumulate("value", struct.getValue());
- data.accumulate("score", struct.getScore());
- }
- return ResultBuilder.buildResult(data);
- }
- else {
- return ResultBuilder.createInfoResult(LuceneCliStrings.LUCENE_SEARCH_INDEX__NO_RESULTS_MESSAGE);
+ }
+
+ private Result getResults(int fromIndex, int toIndex){
+ final TabularResultData data = ResultBuilder.createTabularResultData();
+ for (int i = fromIndex; i < toIndex; i++) {
+ data.accumulate("key", searchResults.get(i).getKey());
+ data.accumulate("value", searchResults.get(i).getValue());
+ data.accumulate("score", searchResults.get(i).getScore());
}
- //@TODO : Pagination
+ return ResultBuilder.buildResult(data);
}
protected ResultCollector<?, ?> executeFunctionOnGroups(FunctionAdapter function, String[]groups, final LuceneIndexInfo indexInfo) throws CommandResultException {
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/547fc488/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneQueryInfo.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneQueryInfo.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneQueryInfo.java
index 2f86064..0e5012e 100644
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneQueryInfo.java
+++ b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneQueryInfo.java
@@ -19,22 +19,27 @@ package com.gemstone.gemfire.cache.lucene.internal.cli;
import java.io.Serializable;
+import com.gemstone.gemfire.cache.lucene.LuceneQueryFactory;
+
public class LuceneQueryInfo implements Serializable {
private static final long serialVersionUID = 1L;
private String indexName;
private String regionPath;
private String queryString;
private String defaultField;
+ private int limit;
public LuceneQueryInfo(final String indexName,
final String regionPath,
final String queryString,
- final String defaultField)
+ final String defaultField,
+ final int limit)
{
this.indexName = indexName;
this.regionPath = regionPath;
this.queryString = queryString;
this.defaultField = defaultField;
+ this.limit = limit;
}
public String getIndexName() {
@@ -52,4 +57,8 @@ public class LuceneQueryInfo implements Serializable {
public String getDefaultField() {
return defaultField;
}
+
+ public int getLimit() {
+ if (limit == -1) return LuceneQueryFactory.DEFAULT_LIMIT;
+ else return limit; }
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/547fc488/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneSearchIndexFunction.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneSearchIndexFunction.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneSearchIndexFunction.java
index a76a741..8d73790 100755
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneSearchIndexFunction.java
+++ b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneSearchIndexFunction.java
@@ -71,8 +71,9 @@ public class LuceneSearchIndexFunction<K,V> extends FunctionAdapter implements I
LuceneService luceneService = LuceneServiceProvider.get(getCache());
try {
if (cache.getRegion(queryInfo.getRegionPath())!=null) {
- final LuceneQuery<K, V> query = luceneService.createLuceneQueryFactory().create(
- queryInfo.getIndexName(), queryInfo.getRegionPath(), queryInfo.getQueryString(), queryInfo.getDefaultField());
+ final LuceneQuery<K, V> query = luceneService.createLuceneQueryFactory()
+ .setResultLimit(queryInfo.getLimit())
+ .create(queryInfo.getIndexName(), queryInfo.getRegionPath(), queryInfo.getQueryString(), queryInfo.getDefaultField());
PageableLuceneQueryResults pageableLuceneQueryResults = query.findPages();
while (pageableLuceneQueryResults.hasNext()) {
List<LuceneResultStruct> page = pageableLuceneQueryResults.next();
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/547fc488/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java
index 32de8e4..141063f 100755
--- a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java
+++ b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java
@@ -318,6 +318,8 @@ public class LuceneIndexCommandsDUnitTest extends CliCommandTestBase {
csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH,REGION_NAME);
csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING,"field1:value1");
csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD,"field1");
+ executeCommandAndLogResult(csb);
+
TabularResultData data = (TabularResultData) executeCommandAndGetResult(csb).getResultData();
assertEquals(4,data.retrieveAllValues("key").size());
}
@@ -343,9 +345,39 @@ public class LuceneIndexCommandsDUnitTest extends CliCommandTestBase {
csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH,REGION_NAME);
csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING,"NotAnExistingValue");
csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD,"field1");
+ executeCommandAndLogResult(csb);
+
String resultAsString = executeCommandAndLogResult(csb);
assertTrue(resultAsString.contains(LuceneCliStrings.LUCENE_SEARCH_INDEX__NO_RESULTS_MESSAGE));
}
+
+ @Test
+ public void searchWithLimitShouldReturnCorrectResults() throws Exception {
+ final VM vm1 = Host.getHost(0).getVM(1);
+
+ createIndex(vm1);
+ Map<String,TestObject> entries=new HashMap<>();
+ entries.put("A",new TestObject("field1:value1 ","field2:value2","field3:value3"));
+ entries.put("B",new TestObject("ABC","EFG","HIJ"));
+ entries.put("C",new TestObject("field1:value1","QWE","RTY"));
+ entries.put("D",new TestObject("ABC","EFG","HIJ"));
+ entries.put("E",new TestObject("field1 :value1","ABC","EFG"));
+ entries.put("F",new TestObject("ABC","EFG","HIJ"));
+ entries.put("G",new TestObject("field1: value1","JKR","POW"));
+ entries.put("H",new TestObject("ABC","EFG","H2J"));
+ putEntries(vm1,entries,8);
+
+ CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_SEARCH_INDEX);
+ csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME,INDEX_NAME);
+ csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH,REGION_NAME);
+ csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING,"field1:value1");
+ csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD,"field1");
+ csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__LIMIT,"2");
+ executeCommandAndLogResult(csb);
+ TabularResultData data = (TabularResultData) executeCommandAndGetResult(csb).getResultData();
+ assertEquals(2,data.retrieveAllValues("key").size());
+ }
+
private void createRegion() {
getCache().createRegionFactory(RegionShortcut.PARTITION).create(REGION_NAME);
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/547fc488/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommandsJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommandsJUnitTest.java b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommandsJUnitTest.java
index b9e4e86..09cd737 100644
--- a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommandsJUnitTest.java
+++ b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexCommandsJUnitTest.java
@@ -19,6 +19,8 @@ import static org.junit.Assert.*;
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.*;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -34,6 +36,7 @@ import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import org.mockito.ArgumentCaptor;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.execute.Execution;
@@ -50,7 +53,9 @@ import com.gemstone.gemfire.management.cli.Result.Status;
import com.gemstone.gemfire.management.internal.cli.functions.CliFunctionResult;
import com.gemstone.gemfire.management.internal.cli.result.CommandResult;
import com.gemstone.gemfire.management.internal.cli.result.CommandResultException;
+import com.gemstone.gemfire.management.internal.cli.result.ResultBuilder;
import com.gemstone.gemfire.management.internal.cli.result.TabularResultData;
+import com.gemstone.gemfire.management.internal.cli.shell.Gfsh;
import com.gemstone.gemfire.test.junit.categories.UnitTest;
/**
@@ -125,7 +130,6 @@ public class LuceneIndexCommandsJUnitTest {
final LuceneIndexDetails indexDetails2 = createIndexDetails("memberSix", "/Employees", searchableFields, fieldAnalyzers,mockIndexStats2, true);
final LuceneIndexDetails indexDetails3 = createIndexDetails("memberTen", "/Employees", searchableFields, fieldAnalyzers,mockIndexStats3, true);
-
final List<Set<LuceneIndexDetails>> results = new ArrayList<>();
results.add(CollectionUtils.asSet(indexDetails2, indexDetails1,indexDetails3));
@@ -225,7 +229,7 @@ public class LuceneIndexCommandsJUnitTest {
doReturn(mockResultCollector).when(commands).executeFunctionOnGroups(isA(LuceneSearchIndexFunction.class),any(),any(LuceneQueryInfo.class));
doReturn(queryResultsList).when(mockResultCollector).getResult();
- CommandResult result = (CommandResult) commands.searchIndex("index","region","Result1","field1");
+ CommandResult result = (CommandResult) commands.searchIndex("index","region","Result1","field1",-1,-1);
TabularResultData data = (TabularResultData) result.getResultData();
@@ -234,6 +238,96 @@ public class LuceneIndexCommandsJUnitTest {
assertEquals(Arrays.asList("1.1","1.2","1.3"), data.retrieveAllValues("score"));
}
+ @Test
+ public void testSearchIndexWithPaging() throws Exception {
+ final Cache mockCache = mock(Cache.class, "Cache");
+ final Gfsh mockGfsh = mock(Gfsh.class);
+ final ResultCollector mockResultCollector = mock(ResultCollector.class, "ResultCollector");
+ final LuceneIndexCommands commands=spy(createIndexCommands(mockCache,null));
+ ArgumentCaptor<String> resultCaptor = ArgumentCaptor.forClass(String.class);
+
+ LuceneSearchResults result1=createQueryResults("A","Result1",Float.valueOf("1.7"));
+ LuceneSearchResults result2=createQueryResults("B","Result1",Float.valueOf("1.6"));
+ LuceneSearchResults result3=createQueryResults("C","Result1",Float.valueOf("1.5"));
+ LuceneSearchResults result4=createQueryResults("D","Result1",Float.valueOf("1.4"));
+ LuceneSearchResults result5=createQueryResults("E","Result1",Float.valueOf("1.3"));
+ LuceneSearchResults result6=createQueryResults("F","Result1",Float.valueOf("1.2"));
+ LuceneSearchResults result7=createQueryResults("G","Result1",Float.valueOf("1.1"));
+ final List<Set<LuceneSearchResults>> queryResultsList = getSearchResults(result1, result2, result3, result4, result5, result6, result7);
+
+ doReturn(mockResultCollector).when(commands).executeFunctionOnGroups(isA(LuceneSearchIndexFunction.class),any(),any(LuceneQueryInfo.class));
+ doReturn(queryResultsList).when(mockResultCollector).getResult();
+ doReturn(mockGfsh).when(commands).initGfsh();
+ when(mockGfsh.interact(anyString())).thenReturn("n").thenReturn("n").thenReturn("n").thenReturn("n")
+ .thenReturn("p").thenReturn("p").thenReturn("p").thenReturn("p").thenReturn("p").thenReturn("n").thenReturn("q");
+
+ LuceneSearchResults[] expectedResults = new LuceneSearchResults[] {result7,result6,result5,result4,result3,result2,result1};
+ String expectedPage1 = getPage(expectedResults, new int[] {0,1});
+ String expectedPage2 = getPage(expectedResults, new int[] {2,3});
+ String expectedPage3 = getPage(expectedResults, new int[] {4,5});
+ String expectedPage4 = getPage(expectedResults, new int[] {6});
+
+ commands.searchIndex("index","region","Result1","field1",-1,2);
+ verify(mockGfsh, times(20)).printAsInfo(resultCaptor.capture());
+ List<String> actualPageResults=resultCaptor.getAllValues();
+
+ assertEquals(expectedPage1,actualPageResults.get(0));
+ assertEquals("\t\tPage 1 of 4",actualPageResults.get(1));
+
+ assertEquals(expectedPage2,actualPageResults.get(2));
+ assertEquals("\t\tPage 2 of 4",actualPageResults.get(3));
+
+ assertEquals(expectedPage3,actualPageResults.get(4));
+ assertEquals("\t\tPage 3 of 4",actualPageResults.get(5));
+
+ assertEquals(expectedPage4,actualPageResults.get(6));
+ assertEquals("\t\tPage 4 of 4",actualPageResults.get(7));
+
+ assertEquals("No more results to display.", actualPageResults.get(8));
+
+ assertEquals(expectedPage4,actualPageResults.get(9));
+ assertEquals("\t\tPage 4 of 4",actualPageResults.get(10));
+
+ assertEquals(expectedPage3,actualPageResults.get(11));
+ assertEquals("\t\tPage 3 of 4",actualPageResults.get(12));
+
+ assertEquals(expectedPage2,actualPageResults.get(13));
+ assertEquals("\t\tPage 2 of 4",actualPageResults.get(14));
+
+ assertEquals(expectedPage1,actualPageResults.get(15));
+ assertEquals("\t\tPage 1 of 4",actualPageResults.get(16));
+
+ assertEquals("At the top of the search results.", actualPageResults.get(17));
+
+ assertEquals(expectedPage1,actualPageResults.get(18));
+ assertEquals("\t\tPage 1 of 4",actualPageResults.get(19));
+
+ }
+
+ private String getPage(final LuceneSearchResults[] expectedResults, int[] indexList) {
+ final TabularResultData data = ResultBuilder.createTabularResultData();
+ for (int i:indexList) {
+ data.accumulate("key", expectedResults[i].getKey());
+ data.accumulate("value", expectedResults[i].getValue());
+ data.accumulate("score", expectedResults[i].getScore());
+ }
+ CommandResult commandResult = (CommandResult) ResultBuilder.buildResult(data);
+ StringBuffer buffer = new StringBuffer();
+ while (commandResult.hasNextLine())
+ buffer.append(commandResult.nextLine());
+ return buffer.toString();
+ }
+
+ private List<Set<LuceneSearchResults>> getSearchResults(LuceneSearchResults ... results)
+ {
+ final List<Set<LuceneSearchResults>> queryResultsList = new ArrayList<>();
+ HashSet<LuceneSearchResults> queryResults = new HashSet<>();
+ for(LuceneSearchResults result : results)
+ queryResults.add(result);
+ queryResultsList.add(queryResults);
+ return queryResultsList;
+ }
+
private LuceneIndexStats getMockIndexStats(int queries, int commits, int updates, int docs) {
LuceneIndexStats mockIndexStats=mock(LuceneIndexStats.class);
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/547fc488/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneSearchIndexFunctionJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneSearchIndexFunctionJUnitTest.java b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneSearchIndexFunctionJUnitTest.java
index 88f608c..f3e970f 100644
--- a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneSearchIndexFunctionJUnitTest.java
+++ b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneSearchIndexFunctionJUnitTest.java
@@ -54,7 +54,7 @@ public class LuceneSearchIndexFunctionJUnitTest {
ResultSender resultSender = mock(ResultSender.class);
GemFireCacheImpl cache = Fakes.cache();
- LuceneQueryInfo queryInfo = createMockQueryInfo("index","region","field1:region1","field1");
+ LuceneQueryInfo queryInfo = createMockQueryInfo("index","region","field1:region1","field1",1);
InternalLuceneService service = getMockLuceneService("A","Value","1.2");
Region mockRegion=mock(Region.class);
@@ -81,7 +81,8 @@ public class LuceneSearchIndexFunctionJUnitTest {
}
private InternalLuceneService getMockLuceneService(String resultKey, String resultValue, String resultScore) throws LuceneQueryException{
InternalLuceneService service=mock(InternalLuceneService.class);
- LuceneQueryFactory mockQueryFactory = mock(LuceneQueryFactory.class);
+ LuceneQueryFactory mockQueryFactory = spy(LuceneQueryFactory.class);
+ LuceneQueryFactory mockQueryFactory2 = mock(LuceneQueryFactory.class);
LuceneQuery mockQuery=mock(LuceneQuery.class);
PageableLuceneQueryResults pageableLuceneQueryResults = mock(PageableLuceneQueryResults.class);
LuceneResultStruct<String,String> resultStruct = new LuceneResultStructImpl(resultKey,resultValue,Float.valueOf(resultScore));
@@ -89,6 +90,7 @@ public class LuceneSearchIndexFunctionJUnitTest {
queryResults.add(resultStruct);
doReturn(mockQueryFactory).when(service).createLuceneQueryFactory();
+ doReturn(mockQueryFactory).when(mockQueryFactory).setResultLimit(anyInt());
doReturn(mockQuery).when(mockQueryFactory).create(any(),any(),any(),any());
when(mockQuery.findPages()).thenReturn(pageableLuceneQueryResults);
when(pageableLuceneQueryResults.hasNext()).thenReturn(true).thenReturn(false);
@@ -97,12 +99,13 @@ public class LuceneSearchIndexFunctionJUnitTest {
return service;
}
- private LuceneQueryInfo createMockQueryInfo(final String index, final String region, final String query, final String field) {
+ private LuceneQueryInfo createMockQueryInfo(final String index, final String region, final String query, final String field, final int limit) {
LuceneQueryInfo queryInfo = mock(LuceneQueryInfo.class);
when(queryInfo.getIndexName()).thenReturn(index);
when(queryInfo.getRegionPath()).thenReturn(region);
when(queryInfo.getQueryString()).thenReturn(query);
when(queryInfo.getDefaultField()).thenReturn(field);
+ when(queryInfo.getLimit()).thenReturn(limit);
return queryInfo;
}