geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aba...@apache.org
Subject [09/50] [abbrv] incubator-geode git commit: This closes #205
Date Mon, 22 Aug 2016 16:39:37 GMT
This closes #205

GEODE-11: Adding stats option to list lucene index gfsh command

Added an option to display lucene index stats in the list lucene index command. Added junit
and dunit tests to verify the same.

GEODE-11: Added describe lucene index gfsh command

Added describe lucene index gfsh command that takes the index name and region as arguments
and displays information about the lucene index (fields, analyzers and stats). Also added
junit and dunit tests for the same.

Signed-off-by: Gester Zhou <gzhou@pivotal.io>


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/ce0b7e7d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/ce0b7e7d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/ce0b7e7d

Branch: refs/heads/master
Commit: ce0b7e7df89616c5f4a4d9d41ed0d63a24978dd0
Parents: 8a28f52
Author: Aparna Dharmakkan <adharmakkan@pivotal.io>
Authored: Tue Jul 12 16:31:02 2016 -0700
Committer: zhouxh <gzhou@pivotal.io>
Committed: Thu Jul 14 11:14:28 2016 -0700

----------------------------------------------------------------------
 .../lucene/internal/cli/LuceneCliStrings.java   |  24 +++-
 .../internal/cli/LuceneIndexCommands.java       |  80 ++++++++++--
 .../lucene/internal/cli/LuceneIndexDetails.java |  30 ++++-
 .../lucene/internal/cli/LuceneIndexInfo.java    |   4 +
 .../functions/LuceneDescribeIndexFunction.java  |  68 ++++++++++
 .../cli/LuceneIndexCommandsDUnitTest.java       |  72 +++++++++--
 .../cli/LuceneIndexCommandsJUnitTest.java       | 124 +++++++++++++++++--
 .../LuceneDescribeIndexFunctionJUnitTest.java   | 103 +++++++++++++++
 8 files changed, 463 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ce0b7e7d/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 3248e75..282e691 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
@@ -19,17 +19,22 @@
 package com.gemstone.gemfire.cache.lucene.internal.cli;
 
 public class LuceneCliStrings {
-  //List Lucene Index commands
+  //Common parameters/options
+  public static final String LUCENE__INDEX_NAME = "name";
+  public static final String LUCENE__REGION_PATH = "region";
+
+  //List lucene index commands
   public static final String LUCENE_LIST_INDEX = "list lucene index";
   public static final String LUCENE_LIST_INDEX__HELP = "Display the list of lucene indexes
created for all members.";
   public static final String LUCENE_LIST_INDEX__ERROR_MESSAGE = "An error occurred while
collecting all lucene index information across the Geode cluster: %1$s";
-  public static final String LUCENE_LIST_INDEX__INDEXES_NOT_FOUND_MESSAGE = "No lucene indexes
Found";
+  public static final String LUCENE_LIST_INDEX__INDEXES_NOT_FOUND_MESSAGE = "No lucene indexes
found";
+  public static final String LUCENE_LIST_INDEX__STATS = "stats";
+  public static final String LUCENE_LIST_INDEX__STATS__HELP = "Display lucene index stats";
 
+  //Create lucene index commands 
   public static final String LUCENE_CREATE_INDEX = "create lucene index";
   public static final String LUCENE_CREATE_INDEX__HELP = "Create a lucene index that can
be used to execute queries.";
-  public static final String LUCENE_CREATE_INDEX__NAME = "name";
   public static final String LUCENE_CREATE_INDEX__NAME__HELP = "Name of the lucene index
to create.";
-  public static final String LUCENE_CREATE_INDEX__REGION = "region";
   public static final String LUCENE_CREATE_INDEX__REGION_HELP = "Name/Path of the region
where the lucene index is created on.";
   public static final String LUCENE_CREATE_INDEX__FIELD = "field";
   public static final String LUCENE_CREATE_INDEX__FIELD_HELP = "fields on the region values
which are stored in the lucene index.";
@@ -37,7 +42,6 @@ public class LuceneCliStrings {
   public static final String LUCENE_CREATE_INDEX__ANALYZER_HELP = "Type of the analyzer for
each field.";
   public static final String LUCENE_CREATE_INDEX__GROUP = "group";
   public static final String LUCENE_CREATE_INDEX__GROUP__HELP = "Group of members in which
the lucene index will be created.";
-
   public static final String CREATE_INDEX__SUCCESS__MSG = "Index successfully created with
following details";
   public static final String CREATE_INDEX__FAILURE__MSG = "Failed to create index \"{0}\"
due to following reasons";
   public static final String CREATE_INDEX__NAME__MSG = "Name       : {0}";
@@ -45,4 +49,14 @@ public class LuceneCliStrings {
   public static final String CREATE_INDEX__MEMBER__MSG = "Members which contain the index";
   public static final String CREATE_INDEX__NUMBER__AND__MEMBER = "{0}. {1}";
   public static final String CREATE_INDEX__EXCEPTION__OCCURRED__ON = "Occurred on following
members";
+  
+  //Describe lucene index commands
+  public static final String LUCENE_DESCRIBE_INDEX = "describe lucene index";
+  public static final String LUCENE_DESCRIBE_INDEX__HELP = "Display the describe of lucene
indexes created for all members.";
+  public static final String LUCENE_DESCRIBE_INDEX__ERROR_MESSAGE = "An error occurred while
collecting lucene index information across the Geode cluster: %1$s";
+  public static final String LUCENE_DESCRIBE_INDEX__NAME__HELP = "Name of the lucene index
to describe.";
+  public static final String LUCENE_DESCRIBE_INDEX__REGION_HELP = "Name/Path of the region
where the lucene index to be described exists.";
+
+
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ce0b7e7d/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 4715389..30028be 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,10 @@
  */
 package com.gemstone.gemfire.cache.lucene.internal.cli;
 
+import static com.gemstone.gemfire.cache.operations.OperationContext.*;
+
+import java.util.ArrayList;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -31,9 +35,11 @@ import org.springframework.shell.core.annotation.CliOption;
 import com.gemstone.gemfire.SystemFailure;
 import com.gemstone.gemfire.cache.Cache;
 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;
 import com.gemstone.gemfire.distributed.DistributedMember;
 import com.gemstone.gemfire.internal.cache.execute.AbstractExecution;
@@ -62,15 +68,21 @@ import com.gemstone.gemfire.management.internal.security.ResourceOperation;
  */
 @SuppressWarnings("unused")
 public class LuceneIndexCommands extends AbstractCommandsSupport {
-
   private static final LuceneCreateIndexFunction createIndexFunction = new LuceneCreateIndexFunction();
+  private static final LuceneDescribeIndexFunction describeIndexFunction = new LuceneDescribeIndexFunction();
 
   @CliCommand(value = LuceneCliStrings.LUCENE_LIST_INDEX, help = LuceneCliStrings.LUCENE_LIST_INDEX__HELP)
   @CliMetaData(shellOnly = false, relatedTopic={CliStrings.TOPIC_GEODE_REGION, CliStrings.TOPIC_GEODE_DATA
})
   @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
-  public Result listIndex() {
+  public Result listIndex(
+    @CliOption(key = LuceneCliStrings.LUCENE_LIST_INDEX__STATS,
+      mandatory=false,
+      specifiedDefaultValue = "true",
+      unspecifiedDefaultValue = "false",
+      help = LuceneCliStrings.LUCENE_LIST_INDEX__STATS__HELP) final boolean stats) {
+
     try {
-      return toTabularResult(getIndexListing());
+      return toTabularResult(getIndexListing(),stats);
     }
     catch (FunctionInvocationTargetException ignore) {
       return ResultBuilder.createGemFireErrorResult(CliStrings.format(CliStrings.COULD_NOT_EXECUTE_COMMAND_TRY_AGAIN,
@@ -105,7 +117,7 @@ public class LuceneIndexCommands extends AbstractCommandsSupport {
       .collect(Collectors.toList());
   }
 
-  protected Result toTabularResult(final List<LuceneIndexDetails> indexDetailsList)
{
+  protected Result toTabularResult(final List<LuceneIndexDetails> indexDetailsList,
boolean stats) {
     if (!indexDetailsList.isEmpty()) {
       final TabularResultData indexData = ResultBuilder.createTabularResultData();
 
@@ -114,6 +126,13 @@ public class LuceneIndexCommands extends AbstractCommandsSupport {
         indexData.accumulate("Region Path", indexDetails.getRegionPath());
         indexData.accumulate("Indexed Fields", indexDetails.getSearchableFieldNamesString());
         indexData.accumulate("Field Analyzer", indexDetails.getFieldAnalyzersString());
+
+        if (stats==true) {
+          indexData.accumulate("Query Executions",indexDetails.getIndexStats().get("queryExecutions"));
+          indexData.accumulate("Updates",indexDetails.getIndexStats().get("updates"));
+          indexData.accumulate("Commits",indexDetails.getIndexStats().get("commits"));
+          indexData.accumulate("Documents",indexDetails.getIndexStats().get("documents"));
+        }
       }
       return ResultBuilder.buildResult(indexData);
     }
@@ -126,11 +145,11 @@ public class LuceneIndexCommands extends AbstractCommandsSupport {
   @CliMetaData(shellOnly = false, relatedTopic={CliStrings.TOPIC_GEODE_REGION, CliStrings.TOPIC_GEODE_DATA
}, writesToSharedConfiguration=true)
   //TODO : Add optionContext for indexName
   public Result createIndex(
-    @CliOption(key = LuceneCliStrings.LUCENE_CREATE_INDEX__NAME,
+    @CliOption(key = LuceneCliStrings.LUCENE__INDEX_NAME,
       mandatory=true,
       help = LuceneCliStrings.LUCENE_CREATE_INDEX__NAME__HELP) final String indexName,
 
-    @CliOption (key = LuceneCliStrings.LUCENE_CREATE_INDEX__REGION,
+    @CliOption (key = LuceneCliStrings.LUCENE__REGION_PATH,
       mandatory = true,
       optionContext = ConverterHint.REGIONPATH,
       help = LuceneCliStrings.LUCENE_CREATE_INDEX__REGION_HELP) final String regionPath,
@@ -159,7 +178,7 @@ public class LuceneIndexCommands extends AbstractCommandsSupport {
     try {
       final Cache cache = getCache();
       LuceneIndexInfo indexInfo = new LuceneIndexInfo(indexName, regionPath, fields, analyzers);
-      final ResultCollector<?, ?> rc = this.createIndexOnGroups(groups, indexInfo);
+      final ResultCollector<?, ?> rc = this.executeFunctionOnGroups(createIndexFunction,
groups, indexInfo);
       final List<CliFunctionResult> funcResults = (List<CliFunctionResult>) rc.getResult();
 
       final Set<String> successfulMembers = new TreeSet<String>();
@@ -236,8 +255,49 @@ public class LuceneIndexCommands extends AbstractCommandsSupport {
     return result;
   }
 
-  protected ResultCollector<?, ?> createIndexOnGroups( String[] groups, final LuceneIndexInfo
indexInfo) throws CommandResultException {
+  @CliCommand(value = LuceneCliStrings.LUCENE_DESCRIBE_INDEX, help = LuceneCliStrings.LUCENE_DESCRIBE_INDEX__HELP)
+  @CliMetaData(shellOnly = false, relatedTopic={CliStrings.TOPIC_GEODE_REGION, CliStrings.TOPIC_GEODE_DATA
})
+  @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
+  public Result describeIndex(
+    @CliOption(key = LuceneCliStrings.LUCENE__INDEX_NAME,
+      mandatory=true,
+      help = LuceneCliStrings.LUCENE_DESCRIBE_INDEX__NAME__HELP) final String indexName,
+
+    @CliOption (key = LuceneCliStrings.LUCENE__REGION_PATH,
+      mandatory = true,
+      optionContext = ConverterHint.REGIONPATH,
+      help = LuceneCliStrings.LUCENE_DESCRIBE_INDEX__REGION_HELP) final String regionPath)
{
+    try {
+      LuceneIndexInfo indexInfo = new LuceneIndexInfo(indexName, regionPath);
+      return toTabularResult(getIndexDetails(indexInfo),true);
+    }
+    catch (FunctionInvocationTargetException ignore) {
+      return ResultBuilder.createGemFireErrorResult(CliStrings.format(CliStrings.COULD_NOT_EXECUTE_COMMAND_TRY_AGAIN,
+        LuceneCliStrings.LUCENE_DESCRIBE_INDEX));
+    }
+    catch (VirtualMachineError e) {
+      SystemFailure.initiateFailure(e);
+      throw e;
+    }
+    catch (Throwable t) {
+      SystemFailure.checkFailure();
+      getCache().getLogger().error(t);
+      return ResultBuilder.createGemFireErrorResult(String.format(LuceneCliStrings.LUCENE_DESCRIBE_INDEX__ERROR_MESSAGE,
+        toString(t, isDebugging())));
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  protected List<LuceneIndexDetails> getIndexDetails(LuceneIndexInfo indexInfo) throws
Exception {
+    GeodeSecurityUtil.authorizeRegionManage(indexInfo.getRegionPath());
+    final String[] groups = {};
+    final ResultCollector<?, ?> rc = this.executeFunctionOnGroups(describeIndexFunction,
groups, indexInfo);
+    final List<LuceneIndexDetails> funcResults = (List<LuceneIndexDetails>) rc.getResult();
+    return funcResults.stream().filter(indexDetails -> indexDetails != null).collect(Collectors.toList());
+  }
+
+  protected ResultCollector<?, ?> executeFunctionOnGroups(FunctionAdapter function,
String[]groups, final LuceneIndexInfo indexInfo) throws CommandResultException {
     final Set<DistributedMember> targetMembers = CliUtil.findAllMatchingMembers(groups,
null);
-    return CliUtil.executeFunction(createIndexFunction, indexInfo, targetMembers);
+    return CliUtil.executeFunction(function, indexInfo, targetMembers);
   }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ce0b7e7d/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexDetails.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexDetails.java
b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexDetails.java
index c967530..7526425 100644
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexDetails.java
+++ b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexDetails.java
@@ -22,7 +22,9 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
+
 import com.gemstone.gemfire.cache.lucene.internal.LuceneIndexImpl;
+import com.gemstone.gemfire.cache.lucene.internal.LuceneIndexStats;
 
 import org.apache.lucene.analysis.Analyzer;
 
@@ -33,16 +35,35 @@ public class LuceneIndexDetails implements Comparable<LuceneIndexDetails>,
Seria
   private final String regionPath;
   private final String[] searchableFieldNames;
   private final Map<String, String> fieldAnalyzers;
+  private final Map<String,Integer> indexStats;
 
-  public LuceneIndexDetails(final String indexName, final String regionPath, final String[]
searchableFieldNames, Map<String, Analyzer> fieldAnalyzers) {
+  public LuceneIndexDetails(final String indexName, final String regionPath, final String[]
searchableFieldNames, Map<String, Analyzer> fieldAnalyzers, LuceneIndexStats indexStats)
{
     this.indexName = indexName;
     this.regionPath = regionPath;
     this.searchableFieldNames = searchableFieldNames;
     this.fieldAnalyzers = getAnalyzerStrings(fieldAnalyzers);
+    this.indexStats=getIndexStatsMap(indexStats);
   }
 
   public LuceneIndexDetails(LuceneIndexImpl index) {
-    this(index.getName(), index.getRegionPath(), index.getFieldNames(), index.getFieldAnalyzers());
+    this(index.getName(), index.getRegionPath(), index.getFieldNames(), index.getFieldAnalyzers(),index.getIndexStats());
+  }
+
+  public Map<String,Integer> getIndexStats() {
+    return indexStats;
+  }
+  private  Map<String,Integer> getIndexStatsMap(LuceneIndexStats indexStats) {
+    Map<String,Integer> statsMap = new HashMap<>();
+    if (indexStats==null) return statsMap;
+    statsMap.put("queryExecutions",indexStats.getQueryExecutions());
+    statsMap.put("updates",indexStats.getUpdates());
+    statsMap.put("commits",indexStats.getCommits());
+    statsMap.put("documents",indexStats.getDocuments());
+    return statsMap;
+  }
+
+  public String getIndexStatsString() {
+    return indexStats.toString();
   }
 
   private Map<String, String> getAnalyzerStrings(Map<String, Analyzer> fieldAnalyzers)
{
@@ -77,6 +98,7 @@ public class LuceneIndexDetails implements Comparable<LuceneIndexDetails>,
Seria
     buffer.append(",\tRegion Path = "+regionPath);
     buffer.append(",\tIndexed Fields = "+getSearchableFieldNamesString());
     buffer.append(",\tField Analyzer = "+getFieldAnalyzersString());
+    buffer.append(",\tIndex Statistics =\n\t"+getIndexStatsString());
     buffer.append("\n}\n");
     return buffer.toString();
   }
@@ -90,10 +112,6 @@ public class LuceneIndexDetails implements Comparable<LuceneIndexDetails>,
Seria
     return regionPath;
   }
 
-  public String[] getSearchableFieldNames() {
-    return searchableFieldNames;
-  }
-
   private static <T extends Comparable<T>> int compare(final T obj1, final T
obj2) {
     return (obj1 == null && obj2 == null ? 0 : (obj1 == null ? 1 : (obj2 == null
? -1 : obj1.compareTo(obj2))));
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ce0b7e7d/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexInfo.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexInfo.java
b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexInfo.java
index 76b7b60..3df292c 100644
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexInfo.java
+++ b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/LuceneIndexInfo.java
@@ -41,6 +41,10 @@ public class LuceneIndexInfo implements Serializable {
     this.fieldAnalyzers = fieldAnalyzers;
   }
 
+  public LuceneIndexInfo(final String indexName, final String regionPath) {
+    this(indexName,regionPath,null,null);
+  }
+
   public String getIndexName() {
     return indexName;
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ce0b7e7d/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneDescribeIndexFunction.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneDescribeIndexFunction.java
b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneDescribeIndexFunction.java
new file mode 100755
index 0000000..b91db60
--- /dev/null
+++ b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneDescribeIndexFunction.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.gemstone.gemfire.cache.lucene.internal.cli.functions;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.execute.FunctionAdapter;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.lucene.LuceneIndex;
+import com.gemstone.gemfire.cache.lucene.LuceneService;
+import com.gemstone.gemfire.cache.lucene.LuceneServiceProvider;
+import com.gemstone.gemfire.cache.lucene.internal.LuceneIndexImpl;
+import com.gemstone.gemfire.cache.lucene.internal.cli.LuceneIndexDetails;
+import com.gemstone.gemfire.cache.lucene.internal.cli.LuceneIndexInfo;
+import com.gemstone.gemfire.internal.InternalEntity;
+
+/**
+ * The LuceneDescribeIndexFunction class is a function used to collect the information on
a particular lucene index.
+ * </p>
+ * @see Cache
+ * @see com.gemstone.gemfire.cache.execute.Function
+ * @see FunctionAdapter
+ * @see FunctionContext
+ * @see InternalEntity
+ * @see LuceneIndexDetails
+ * @see LuceneIndexInfo
+ */
+@SuppressWarnings("unused")
+public class LuceneDescribeIndexFunction extends FunctionAdapter implements InternalEntity
{
+
+  protected Cache getCache() {
+    return CacheFactory.getAnyInstance();
+  }
+
+  public String getId() {
+    return LuceneDescribeIndexFunction.class.getName();
+  }
+
+  public void execute(final FunctionContext context) {
+    LuceneIndexDetails result = null;
+    final Cache cache = getCache();
+    final LuceneIndexInfo indexInfo = (LuceneIndexInfo) context.getArguments();
+    LuceneService service = LuceneServiceProvider.get(cache);
+    LuceneIndex index = service.getIndex(indexInfo.getIndexName(), indexInfo.getRegionPath());
+    if (index != null) {
+      result = new LuceneIndexDetails((LuceneIndexImpl) index);
+    }
+    context.getResultSender().lastResult(result);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ce0b7e7d/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 2647bcc..06cc410 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
@@ -28,7 +28,6 @@ import com.gemstone.gemfire.management.internal.cli.result.CommandResult;
 import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder;
 import com.gemstone.gemfire.test.dunit.*;
 import com.gemstone.gemfire.test.junit.categories.DistributedTest;
-import com.sun.org.apache.regexp.internal.RE;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.core.KeywordAnalyzer;
@@ -45,7 +44,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-import java.util.stream.Collectors;
 
 @Category(DistributedTest.class)
 public class LuceneIndexCommandsDUnitTest extends CliCommandTestBase {
@@ -57,15 +55,41 @@ public class LuceneIndexCommandsDUnitTest extends CliCommandTestBase {
   }
 
   @Test
-  public void listIndexShouldReturnExistingIndex() throws Exception {
+  public void listIndexShouldReturnExistingIndexWithStats() throws Exception {
     final VM vm1 = Host.getHost(0).getVM(1);
 
     createIndex(vm1);
     CommandManager.getInstance().add(LuceneIndexCommands.class.newInstance());
 
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_LIST_INDEX);
+    csb.addOption(LuceneCliStrings.LUCENE_LIST_INDEX__STATS,"true");
     String resultAsString = executeCommandAndLogResult(csb);
     assertTrue(resultAsString.contains(INDEX_NAME));
+    assertTrue(resultAsString.contains("Documents"));
+  }
+
+  @Test
+  public void listIndexShouldReturnExistingIndexWithoutStats() throws Exception {
+    final VM vm1 = Host.getHost(0).getVM(1);
+
+    createIndex(vm1);
+    CommandManager.getInstance().add(LuceneIndexCommands.class.newInstance());
+
+    CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_LIST_INDEX);
+    String resultAsString = executeCommandAndLogResult(csb);
+    assertTrue(resultAsString.contains(INDEX_NAME));
+    assertFalse(resultAsString.contains("Documents"));
+  }
+
+  @Test
+  public void listIndexWhenNoExistingIndexShouldReturnNoIndex() throws Exception {
+    final VM vm1 = Host.getHost(0).getVM(1);
+
+    CommandManager.getInstance().add(LuceneIndexCommands.class.newInstance());
+
+    CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_LIST_INDEX);
+    String resultAsString = executeCommandAndLogResult(csb);
+    assertTrue(resultAsString.contains("No lucene indexes found"));
   }
 
   @Test
@@ -76,8 +100,8 @@ public class LuceneIndexCommandsDUnitTest extends CliCommandTestBase {
     CommandManager.getInstance().add(LuceneIndexCommands.class.newInstance());
 
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_CREATE_INDEX);
-    csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__NAME,INDEX_NAME);
-    csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__REGION,REGION_NAME);
+    csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME,INDEX_NAME);
+    csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH,REGION_NAME);
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD,"field1,field2,field3");
 
     String resultAsString = executeCommandAndLogResult(csb);
@@ -104,8 +128,8 @@ public class LuceneIndexCommandsDUnitTest extends CliCommandTestBase {
 
 
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_CREATE_INDEX);
-    csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__NAME,INDEX_NAME);
-    csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__REGION,REGION_NAME);
+    csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME,INDEX_NAME);
+    csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH,REGION_NAME);
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD,"field1,field2,field3");
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER,String.join(",",analyzerNames));
 
@@ -136,12 +160,11 @@ public class LuceneIndexCommandsDUnitTest extends CliCommandTestBase
{
       getCache();
     });
 
-
     CommandManager.getInstance().add(LuceneIndexCommands.class.newInstance());
 
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_CREATE_INDEX);
-    csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__NAME,INDEX_NAME);
-    csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__REGION,REGION_NAME);
+    csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME,INDEX_NAME);
+    csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH,REGION_NAME);
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD,"field1,field2,field3");
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__GROUP,"group1");
     String resultAsString = executeCommandAndLogResult(csb);
@@ -164,6 +187,35 @@ public class LuceneIndexCommandsDUnitTest extends CliCommandTestBase
{
     });
   }
 
+  @Test
+  public void describeIndexShouldReturnExistingIndex() throws Exception {
+    final VM vm1 = Host.getHost(0).getVM(1);
+
+    createIndex(vm1);
+    CommandManager.getInstance().add(LuceneIndexCommands.class.newInstance());
+
+    CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_DESCRIBE_INDEX);
+    csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME,INDEX_NAME);
+    csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH,REGION_NAME);
+    String resultAsString = executeCommandAndLogResult(csb);
+    assertTrue(resultAsString.contains(INDEX_NAME));
+  }
+
+  @Test
+  public void describeIndexShouldNotReturnResultWhenIndexNotFound() throws Exception {
+    final VM vm1 = Host.getHost(0).getVM(1);
+
+    createIndex(vm1);
+    CommandManager.getInstance().add(LuceneIndexCommands.class.newInstance());
+
+    CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_DESCRIBE_INDEX);
+    csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME,"notAnIndex");
+    csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH,REGION_NAME);
+    String resultAsString = executeCommandAndLogResult(csb);
+
+    assertTrue(resultAsString.contains("No lucene indexes found"));
+  }
+
   private void createRegion() {
     getCache().createRegionFactory(RegionShortcut.PARTITION).create(REGION_NAME);
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ce0b7e7d/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 0ebfa10..41f1ca4 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
@@ -38,6 +38,9 @@ import org.junit.experimental.categories.Category;
 import com.gemstone.gemfire.cache.Cache;
 import com.gemstone.gemfire.cache.execute.Execution;
 import com.gemstone.gemfire.cache.execute.ResultCollector;
+import com.gemstone.gemfire.cache.lucene.internal.LuceneIndexStats;
+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;
 import com.gemstone.gemfire.distributed.DistributedMember;
 import com.gemstone.gemfire.internal.cache.execute.AbstractExecution;
@@ -45,6 +48,7 @@ import com.gemstone.gemfire.internal.util.CollectionUtils;
 import com.gemstone.gemfire.management.cli.Result;
 import com.gemstone.gemfire.management.cli.Result.Status;
 import com.gemstone.gemfire.management.internal.cli.functions.CliFunctionResult;
+import com.gemstone.gemfire.management.internal.cli.functions.CreateIndexFunction;
 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;
@@ -70,16 +74,8 @@ import com.gemstone.gemfire.test.junit.categories.UnitTest;
 @Category(UnitTest.class)
 public class LuceneIndexCommandsJUnitTest {
 
-  private LuceneIndexCommands createIndexCommands(final Cache cache, final Execution functionExecutor)
{
-    return new LuceneTestIndexCommands(cache, functionExecutor);
-  }
-
-  private LuceneIndexDetails createIndexDetails(final String indexName, final String regionPath,
final String[] searchableFields, final Map<String, Analyzer> fieldAnalyzers) {
-    return new LuceneIndexDetails(indexName, regionPath, searchableFields, fieldAnalyzers);
-  }
-
   @Test
-  public void testListIndex() {
+  public void testListIndexWithoutStats() {
 
     final Cache mockCache = mock(Cache.class, "Cache");
     final AbstractExecution mockFunctionExecutor = mock(AbstractExecution.class, "Function
Executor");
@@ -112,7 +108,7 @@ public class LuceneIndexCommandsJUnitTest {
 
     final LuceneIndexCommands commands = createIndexCommands(mockCache, mockFunctionExecutor);
 
-    CommandResult result = (CommandResult) commands.listIndex();
+    CommandResult result = (CommandResult) commands.listIndex(false);
     TabularResultData data = (TabularResultData) result.getResultData();
     assertEquals(Arrays.asList("memberFive", "memberSix", "memberTen"), data.retrieveAllValues("Index
Name"));
     assertEquals(Arrays.asList("/Employees", "/Employees", "/Employees"), data.retrieveAllValues("Region
Path"));
@@ -121,6 +117,53 @@ public class LuceneIndexCommandsJUnitTest {
   }
 
   @Test
+  public void testListIndexWithStats() {
+
+    final Cache mockCache = mock(Cache.class, "Cache");
+    final AbstractExecution mockFunctionExecutor = mock(AbstractExecution.class, "Function
Executor");
+    final ResultCollector mockResultCollector = mock(ResultCollector.class, "ResultCollector");
+    final LuceneIndexStats mockIndexStats1=getMockIndexStats(1,10,5,1);
+    final LuceneIndexStats mockIndexStats2=getMockIndexStats(2,20,10,2);
+    final LuceneIndexStats mockIndexStats3=getMockIndexStats(3,30,15,3);
+    String[] searchableFields={"field1","field2","field3"};
+    Map<String, Analyzer> fieldAnalyzers = new HashMap<>();
+    fieldAnalyzers.put("field1", new StandardAnalyzer());
+    fieldAnalyzers.put("field2", new KeywordAnalyzer());
+    fieldAnalyzers.put("field3", null);
+    final LuceneIndexDetails indexDetails1 = createIndexDetails("memberFive", "/Employees",
searchableFields, fieldAnalyzers,mockIndexStats1);
+    final LuceneIndexDetails indexDetails2 = createIndexDetails("memberSix", "/Employees",
searchableFields, fieldAnalyzers,mockIndexStats2);
+    final LuceneIndexDetails indexDetails3 = createIndexDetails("memberTen", "/Employees",
searchableFields, fieldAnalyzers,mockIndexStats3);
+
+
+    final List<LuceneIndexDetails> expectedIndexDetails = new ArrayList<>(3);
+    expectedIndexDetails.add(indexDetails1);
+    expectedIndexDetails.add(indexDetails2);
+    expectedIndexDetails.add(indexDetails3);
+
+    final List<Set<LuceneIndexDetails>> results = new ArrayList<>();
+
+    results.add(CollectionUtils.asSet(indexDetails2, indexDetails1,indexDetails3));
+
+    when(mockFunctionExecutor.execute(isA(LuceneListIndexFunction.class)))
+      .thenReturn(mockResultCollector);
+    when(mockResultCollector.getResult())
+      .thenReturn(results);
+
+    final LuceneIndexCommands commands = createIndexCommands(mockCache, mockFunctionExecutor);
+
+    CommandResult result = (CommandResult) commands.listIndex(true);
+    TabularResultData data = (TabularResultData) result.getResultData();
+    assertEquals(Arrays.asList("memberFive", "memberSix", "memberTen"), data.retrieveAllValues("Index
Name"));
+    assertEquals(Arrays.asList("/Employees", "/Employees", "/Employees"), data.retrieveAllValues("Region
Path"));
+    assertEquals(Arrays.asList("[field1, field2, field3]", "[field1, field2, field3]", "[field1,
field2, field3]"), data.retrieveAllValues("Indexed Fields"));
+    assertEquals(Arrays.asList("{field1=StandardAnalyzer, field2=KeywordAnalyzer}", "{field1=StandardAnalyzer,
field2=KeywordAnalyzer}", "{field1=StandardAnalyzer, field2=KeywordAnalyzer}"), data.retrieveAllValues("Field
Analyzer"));
+    assertEquals(Arrays.asList("1","2","3"), data.retrieveAllValues("Query Executions"));
+    assertEquals(Arrays.asList("10","20","30"), data.retrieveAllValues("Commits"));
+    assertEquals(Arrays.asList("5","10","15"), data.retrieveAllValues("Updates"));
+    assertEquals(Arrays.asList("1","2","3"), data.retrieveAllValues("Documents"));
+  }
+
+  @Test
   public void testCreateIndex() throws CommandResultException {
     final Cache mockCache=mock(Cache.class);
     final ResultCollector mockResultCollector = mock(ResultCollector.class);
@@ -129,7 +172,7 @@ public class LuceneIndexCommandsJUnitTest {
     final List<CliFunctionResult> cliFunctionResults=new ArrayList<>();
     cliFunctionResults.add(new CliFunctionResult(memberId,true,"Index Created"));
 
-    doReturn(mockResultCollector).when(commands).createIndexOnGroups(any(),any(LuceneIndexInfo.class));
+    doReturn(mockResultCollector).when(commands).executeFunctionOnGroups(isA(LuceneCreateIndexFunction.class),any(),any(LuceneIndexInfo.class));
     doReturn(cliFunctionResults).when(mockResultCollector).getResult();
 
     String indexName ="index";
@@ -153,6 +196,65 @@ public class LuceneIndexCommandsJUnitTest {
     return ResultBuilder.buildResult(infoResult);
   }
 
+  @Test
+  public void testDescribeIndex() throws CommandResultException {
+
+    final Cache mockCache = mock(Cache.class, "Cache");
+    final ResultCollector mockResultCollector = mock(ResultCollector.class, "ResultCollector");
+    final LuceneIndexCommands commands=spy(createIndexCommands(mockCache,null));
+
+    String[] searchableFields={"field1","field2","field3"};
+    Map<String, Analyzer> fieldAnalyzers = new HashMap<>();
+    fieldAnalyzers.put("field1", new StandardAnalyzer());
+    fieldAnalyzers.put("field2", new KeywordAnalyzer());
+    fieldAnalyzers.put("field3", null);
+    final LuceneIndexStats mockIndexStats=getMockIndexStats(1,10,5,1);
+    final List<LuceneIndexDetails> indexDetails = new ArrayList<>();
+    indexDetails.add(createIndexDetails("memberFive", "/Employees", searchableFields, fieldAnalyzers,mockIndexStats));
+
+    doReturn(mockResultCollector).when(commands).executeFunctionOnGroups(isA(LuceneDescribeIndexFunction.class),any(),any(LuceneIndexInfo.class));
+    doReturn(indexDetails).when(mockResultCollector).getResult();
+
+    CommandResult result = (CommandResult) commands.describeIndex("memberFive","/Employees");
+
+    TabularResultData data = (TabularResultData) result.getResultData();
+    assertEquals(Arrays.asList("memberFive"), data.retrieveAllValues("Index Name"));
+    assertEquals(Arrays.asList("/Employees"), data.retrieveAllValues("Region Path"));
+    assertEquals(Arrays.asList("[field1, field2, field3]"), data.retrieveAllValues("Indexed
Fields"));
+    assertEquals(Arrays.asList("{field1=StandardAnalyzer, field2=KeywordAnalyzer}"), data.retrieveAllValues("Field
Analyzer"));
+    assertEquals(Arrays.asList("1"), data.retrieveAllValues("Query Executions"));
+    assertEquals(Arrays.asList("10"), data.retrieveAllValues("Commits"));
+    assertEquals(Arrays.asList("5"), data.retrieveAllValues("Updates"));
+    assertEquals(Arrays.asList("1"), data.retrieveAllValues("Documents"));
+
+  }
+
+
+  private LuceneIndexStats getMockIndexStats(int queries, int commits, int updates, int docs)
{
+    LuceneIndexStats mockIndexStats=mock(LuceneIndexStats.class);
+    when(mockIndexStats.getQueryExecutions())
+      .thenReturn(queries);
+    when(mockIndexStats.getCommits())
+      .thenReturn(commits);
+    when(mockIndexStats.getUpdates())
+      .thenReturn(updates);
+    when(mockIndexStats.getDocuments())
+      .thenReturn(docs);
+    return mockIndexStats;
+  }
+
+  private LuceneIndexCommands createIndexCommands(final Cache cache, final Execution functionExecutor)
{
+    return new LuceneTestIndexCommands(cache, functionExecutor);
+  }
+
+  private LuceneIndexDetails createIndexDetails(final String indexName, final String regionPath,
final String[] searchableFields, final Map<String, Analyzer> fieldAnalyzers, LuceneIndexStats
indexStats) {
+    return new LuceneIndexDetails(indexName, regionPath, searchableFields, fieldAnalyzers,indexStats);
+  }
+
+  private LuceneIndexDetails createIndexDetails(final String indexName, final String regionPath,
final String[] searchableFields, final Map<String, Analyzer> fieldAnalyzers) {
+    return new LuceneIndexDetails(indexName, regionPath, searchableFields, fieldAnalyzers,null);
+  }
+
   private static class LuceneTestIndexCommands extends LuceneIndexCommands {
 
     private final Cache cache;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ce0b7e7d/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneDescribeIndexFunctionJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneDescribeIndexFunctionJUnitTest.java
b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneDescribeIndexFunctionJUnitTest.java
new file mode 100644
index 0000000..3669b90
--- /dev/null
+++ b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/cli/functions/LuceneDescribeIndexFunctionJUnitTest.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.cache.lucene.internal.cli.functions;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.execute.ResultSender;
+import com.gemstone.gemfire.cache.lucene.LuceneIndex;
+import com.gemstone.gemfire.cache.lucene.internal.InternalLuceneService;
+import com.gemstone.gemfire.cache.lucene.internal.LuceneIndexImpl;
+import com.gemstone.gemfire.cache.lucene.internal.cli.LuceneIndexDetails;
+import com.gemstone.gemfire.cache.lucene.internal.cli.LuceneIndexInfo;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.test.fake.Fakes;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.core.KeywordAnalyzer;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+@Category(UnitTest.class)
+
+public class LuceneDescribeIndexFunctionJUnitTest {
+  
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testExecute() throws Throwable {
+    GemFireCacheImpl cache = Fakes.cache();
+    InternalLuceneService service = mock(InternalLuceneService.class);
+    when(cache.getService(InternalLuceneService.class)).thenReturn(service);
+    FunctionContext context = mock(FunctionContext.class);
+    ResultSender resultSender = mock(ResultSender.class);
+    LuceneIndexInfo indexInfo=getMockLuceneInfo("index1");
+    LuceneIndexImpl index1 = getMockLuceneIndex("index1");
+    LuceneDescribeIndexFunction function = spy(LuceneDescribeIndexFunction.class);
+
+    doReturn(indexInfo).when(context).getArguments();
+    doReturn(resultSender).when(context).getResultSender();
+    doReturn(cache).when(function).getCache();
+    when(service.getIndex(indexInfo.getIndexName(),indexInfo.getRegionPath())).thenReturn(index1);
+
+    function.execute(context);
+    ArgumentCaptor<LuceneIndexDetails> resultCaptor  = ArgumentCaptor.forClass(LuceneIndexDetails.class);
+    verify(resultSender).lastResult(resultCaptor.capture());
+    LuceneIndexDetails result = resultCaptor.getValue();
+    LuceneIndexDetails expected=new LuceneIndexDetails(index1);
+
+    assertEquals(expected.getIndexName(),result.getIndexName());
+    assertEquals(expected.getRegionPath(),result.getRegionPath());
+    assertEquals(expected.getIndexStats(),result.getIndexStats());
+    assertEquals(expected.getFieldAnalyzersString(),result.getFieldAnalyzersString());
+    assertEquals(expected.getSearchableFieldNamesString(),result.getSearchableFieldNamesString());
+  }
+
+  private LuceneIndexInfo getMockLuceneInfo(final String index1) {
+    LuceneIndexInfo mockInfo=mock(LuceneIndexInfo.class);
+    doReturn(index1).when(mockInfo).getIndexName();
+    doReturn("/region").when(mockInfo).getRegionPath();
+    return mockInfo;
+  }
+
+  private LuceneIndexImpl getMockLuceneIndex(final String indexName)
+  {
+    String[] searchableFields={"field1","field2"};
+    Map<String, Analyzer> fieldAnalyzers = new HashMap<>();
+    fieldAnalyzers.put("field1", new StandardAnalyzer());
+    fieldAnalyzers.put("field2", new KeywordAnalyzer());
+
+    LuceneIndexImpl index = mock(LuceneIndexImpl.class);
+    when(index.getName()).thenReturn(indexName);
+    when(index.getRegionPath()).thenReturn("/region");
+    when(index.getFieldNames()).thenReturn(searchableFields);
+    when(index.getFieldAnalyzers()).thenReturn(fieldAnalyzers);
+    return index;
+  }
+
+}



Mime
View raw message