geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jinmeil...@apache.org
Subject [geode] branch develop updated: GEODE-2563: destroy region should be idempotent (#926)
Date Mon, 16 Oct 2017 18:24:37 GMT
This is an automated email from the ASF dual-hosted git repository.

jinmeiliao pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 43cdee9  GEODE-2563: destroy region should be idempotent (#926)
43cdee9 is described below

commit 43cdee997b973369bf0f0df4d73396857aef2bea
Author: jinmeiliao <jiliao@pivotal.io>
AuthorDate: Mon Oct 16 11:24:34 2017 -0700

    GEODE-2563: destroy region should be idempotent (#926)
    
    * GEODE-2563: destroy region should be idempotent
    
    * added the if-exists option for destroy region
    * refactor the RegionPathConverter for better validation of regionPath
    * cleaned up commands that uses the RegionPathConverter to not do unnecessary validation
    * reworked DestroyRegionCommandDUnitTest
    * added more tests
---
 .../geode/management/DistributedSystemMXBean.java  |   2 +-
 .../internal/cli/commands/CreateIndexCommand.java  |   5 -
 .../internal/cli/commands/DefineIndexCommand.java  |   4 -
 .../cli/commands/DescribeRegionCommand.java        | 259 ++++++-------
 .../cli/commands/DestroyRegionCommand.java         | 195 ++--------
 .../internal/cli/commands/DisconnectCommand.java   |   3 +-
 .../internal/cli/commands/GetCommand.java          |  11 -
 .../internal/cli/commands/GfshCommand.java         |   4 +
 .../internal/cli/commands/LocateEntryCommand.java  |  11 -
 .../internal/cli/commands/PutCommand.java          |  15 -
 .../internal/cli/commands/RemoveCommand.java       |   5 -
 .../internal/cli/commands/ShowMetricsCommand.java  |  26 +-
 .../cli/converters/RegionPathConverter.java        |  52 ++-
 .../management/internal/cli/i18n/CliStrings.java   |   3 +
 .../geode/management/internal/cli/shell/Gfsh.java  |  11 +-
 .../commands/DestroyRegionCommandDUnitTest.java    | 420 ++++++---------------
 .../cli/commands/DestroyRegionCommandTest.java     |  76 ++++
 .../cli/commands/IndexCommandsIntegrationTest.java |  11 +-
 .../cli/commands/RemoveCommandDUnitTest.java       |   5 +-
 .../converters/RegionPathConverterJUnitTest.java   |  90 +++--
 .../internal/cli/shell/GfshJunitTest.java          |  12 +-
 .../apache/geode/test/dunit/rules/MemberVM.java    |   4 +
 .../test/junit/rules/GfshShellConnectionRule.java  |  10 +-
 .../cache/lucene/internal/LuceneServiceImpl.java   |   2 +-
 .../lucene/internal/cli/LuceneIndexCommands.java   | 105 ++----
 .../cli/functions/LuceneDestroyIndexFunction.java  |   7 +-
 .../internal/ValidateCommandParametersTest.java    |  40 +-
 .../internal/cli/LuceneIndexCommandsDUnitTest.java | 180 +++------
 .../LuceneDestroyIndexFunctionJUnitTest.java       |  33 +-
 .../LuceneClusterConfigurationDUnitTest.java       |  45 +--
 30 files changed, 634 insertions(+), 1012 deletions(-)

diff --git a/geode-core/src/main/java/org/apache/geode/management/DistributedSystemMXBean.java b/geode-core/src/main/java/org/apache/geode/management/DistributedSystemMXBean.java
index 3d52115..e917895 100644
--- a/geode-core/src/main/java/org/apache/geode/management/DistributedSystemMXBean.java
+++ b/geode-core/src/main/java/org/apache/geode/management/DistributedSystemMXBean.java
@@ -311,7 +311,7 @@ public interface DistributedSystemMXBean {
   String[] listRegions();
 
   /**
-   * Returns a list of full paths for all regions.
+   * Returns a list of full paths for all regions. Returns an empty array if no region exists
    */
   String[] listAllRegionPaths();
 
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommand.java
index 91b3d28..7ea6e37 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommand.java
@@ -25,7 +25,6 @@ import java.util.concurrent.atomic.AtomicReference;
 import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
-import org.apache.geode.cache.Region;
 import org.apache.geode.cache.execute.ResultCollector;
 import org.apache.geode.cache.query.IndexType;
 import org.apache.geode.distributed.DistributedMember;
@@ -77,10 +76,6 @@ public class CreateIndexCommand implements GfshCommand {
     Result result;
     AtomicReference<XmlEntity> xmlEntity = new AtomicReference<>();
 
-    if (!regionPath.startsWith(Region.SEPARATOR)) {
-      regionPath = Region.SEPARATOR + regionPath;
-    }
-
     final Set<DistributedMember> targetMembers = findMembers(group, memberNameOrID);
 
     if (targetMembers.isEmpty()) {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DefineIndexCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DefineIndexCommand.java
index 692125c..c356667 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DefineIndexCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DefineIndexCommand.java
@@ -18,7 +18,6 @@ package org.apache.geode.management.internal.cli.commands;
 import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
-import org.apache.geode.cache.Region;
 import org.apache.geode.cache.query.IndexType;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.ConverterHint;
@@ -49,9 +48,6 @@ public class DefineIndexCommand implements GfshCommand {
           help = CliStrings.DEFINE_INDEX__TYPE__HELP) final IndexType indexType) {
 
     Result result;
-    if (!regionPath.startsWith(Region.SEPARATOR)) {
-      regionPath = Region.SEPARATOR + regionPath;
-    }
 
     IndexInfo indexInfo = new IndexInfo(indexName, indexedExpression, regionPath, indexType);
     IndexDefinition.indexDefinitions.add(indexInfo);
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DescribeRegionCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DescribeRegionCommand.java
index eb74793..ebbdb6c 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DescribeRegionCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DescribeRegionCommand.java
@@ -24,8 +24,6 @@ import java.util.Set;
 import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.execute.FunctionInvocationTargetException;
 import org.apache.geode.cache.execute.ResultCollector;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.management.cli.CliMetaData;
@@ -58,170 +56,151 @@ public class DescribeRegionCommand implements GfshCommand {
           help = CliStrings.DESCRIBE_REGION__NAME__HELP, mandatory = true) String regionName) {
 
     Result result;
-    try {
 
-      if (regionName == null || regionName.isEmpty()) {
-        return ResultBuilder.createUserErrorResult("Please provide a region name");
-      }
-
-      if (regionName.equals(Region.SEPARATOR)) {
-        return ResultBuilder.createUserErrorResult(CliStrings.INVALID_REGION_NAME);
-      }
+    InternalCache cache = getCache();
+    ResultCollector<?, ?> rc =
+        CliUtil.executeFunction(getRegionDescription, regionName, CliUtil.getAllMembers(cache));
 
-      InternalCache cache = getCache();
-      ResultCollector<?, ?> rc =
-          CliUtil.executeFunction(getRegionDescription, regionName, CliUtil.getAllMembers(cache));
+    List<?> resultList = (List<?>) rc.getResult();
 
-      List<?> resultList = (List<?>) rc.getResult();
+    // The returned result could be a region description with per member and /or single local
+    // region
+    Object[] results = resultList.toArray();
+    List<RegionDescription> regionDescriptionList = new ArrayList<>();
 
-      // The returned result could be a region description with per member and /or single local
-      // region
-      Object[] results = resultList.toArray();
-      List<RegionDescription> regionDescriptionList = new ArrayList<>();
+    for (int i = 0; i < results.length; i++) {
 
-      for (int i = 0; i < results.length; i++) {
+      if (results[i] instanceof RegionDescriptionPerMember) {
+        RegionDescriptionPerMember regionDescPerMember = (RegionDescriptionPerMember) results[i];
 
-        if (results[i] instanceof RegionDescriptionPerMember) {
-          RegionDescriptionPerMember regionDescPerMember = (RegionDescriptionPerMember) results[i];
+        if (regionDescPerMember != null) {
+          RegionDescription regionDescription = new RegionDescription();
+          regionDescription.add(regionDescPerMember);
 
-          if (regionDescPerMember != null) {
-            RegionDescription regionDescription = new RegionDescription();
-            regionDescription.add(regionDescPerMember);
-
-            for (int j = i + 1; j < results.length; j++) {
-              if (results[j] != null && results[j] instanceof RegionDescriptionPerMember) {
-                RegionDescriptionPerMember preyRegionDescPerMember =
-                    (RegionDescriptionPerMember) results[j];
-                if (regionDescription.add(preyRegionDescPerMember)) {
-                  results[j] = null;
-                }
+          for (int j = i + 1; j < results.length; j++) {
+            if (results[j] != null && results[j] instanceof RegionDescriptionPerMember) {
+              RegionDescriptionPerMember preyRegionDescPerMember =
+                  (RegionDescriptionPerMember) results[j];
+              if (regionDescription.add(preyRegionDescPerMember)) {
+                results[j] = null;
               }
             }
-            regionDescriptionList.add(regionDescription);
           }
-        } else if (results[i] instanceof Throwable) {
-          Throwable t = (Throwable) results[i];
-          LogWrapper.getInstance().info(t.getMessage(), t);
+          regionDescriptionList.add(regionDescription);
         }
+      } else if (results[i] instanceof Throwable) {
+        Throwable t = (Throwable) results[i];
+        LogWrapper.getInstance().info(t.getMessage(), t);
       }
+    }
 
-      if (regionDescriptionList.isEmpty()) {
-        return ResultBuilder
-            .createUserErrorResult(CliStrings.format(CliStrings.REGION_NOT_FOUND, regionName));
+    if (regionDescriptionList.isEmpty()) {
+      return ResultBuilder
+          .createUserErrorResult(CliStrings.format(CliStrings.REGION_NOT_FOUND, regionName));
+    }
+
+    CompositeResultData crd = ResultBuilder.createCompositeResultData();
+
+    for (RegionDescription regionDescription : regionDescriptionList) {
+      // No point in displaying the scope for PR's
+      if (regionDescription.isPartition()) {
+        regionDescription.getCndRegionAttributes().remove(RegionAttributesNames.SCOPE);
+      } else {
+        String scope = regionDescription.getCndRegionAttributes().get(RegionAttributesNames.SCOPE);
+        if (scope != null) {
+          scope = scope.toLowerCase().replace('_', '-');
+          regionDescription.getCndRegionAttributes().put(RegionAttributesNames.SCOPE, scope);
+        }
       }
+      CompositeResultData.SectionResultData regionSection = crd.addSection();
+      regionSection.addSeparator('-');
+      regionSection.addData("Name", regionDescription.getName());
+
+      String dataPolicy =
+          regionDescription.getDataPolicy().toString().toLowerCase().replace('_', ' ');
+      regionSection.addData("Data Policy", dataPolicy);
 
-      CompositeResultData crd = ResultBuilder.createCompositeResultData();
+      String memberType;
 
-      for (RegionDescription regionDescription : regionDescriptionList) {
-        // No point in displaying the scope for PR's
+      if (regionDescription.isAccessor()) {
+        memberType = CliStrings.DESCRIBE_REGION__ACCESSOR__MEMBER;
+      } else {
+        memberType = CliStrings.DESCRIBE_REGION__HOSTING__MEMBER;
+      }
+      regionSection.addData(memberType,
+          CliUtil.convertStringSetToString(regionDescription.getHostingMembers(), '\n'));
+      regionSection.addSeparator('.');
+
+      TabularResultData commonNonDefaultAttrTable = regionSection.addSection().addTable();
+
+      commonNonDefaultAttrTable.setHeader(CliStrings
+          .format(CliStrings.DESCRIBE_REGION__NONDEFAULT__COMMONATTRIBUTES__HEADER, memberType));
+      // Common Non Default Region Attributes
+      Map<String, String> cndRegionAttrsMap = regionDescription.getCndRegionAttributes();
+
+      // Common Non Default Eviction Attributes
+      Map<String, String> cndEvictionAttrsMap = regionDescription.getCndEvictionAttributes();
+
+      // Common Non Default Partition Attributes
+      Map<String, String> cndPartitionAttrsMap = regionDescription.getCndPartitionAttributes();
+
+      writeCommonAttributesToTable(commonNonDefaultAttrTable,
+          CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__REGION, cndRegionAttrsMap);
+      writeCommonAttributesToTable(commonNonDefaultAttrTable,
+          CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__EVICTION, cndEvictionAttrsMap);
+      writeCommonAttributesToTable(commonNonDefaultAttrTable,
+          CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__PARTITION, cndPartitionAttrsMap);
+
+      // Member-wise non default Attributes
+      Map<String, RegionDescriptionPerMember> regDescPerMemberMap =
+          regionDescription.getRegionDescriptionPerMemberMap();
+      Set<String> members = regDescPerMemberMap.keySet();
+
+      TabularResultData table = regionSection.addSection().addTable();
+
+      boolean setHeader = false;
+      for (String member : members) {
+        RegionDescriptionPerMember regDescPerMem = regDescPerMemberMap.get(member);
+        Map<String, String> ndRa = regDescPerMem.getNonDefaultRegionAttributes();
+        Map<String, String> ndEa = regDescPerMem.getNonDefaultEvictionAttributes();
+        Map<String, String> ndPa = regDescPerMem.getNonDefaultPartitionAttributes();
+
+        // Get all the member-specific non-default attributes by removing the common keys
+        ndRa.keySet().removeAll(cndRegionAttrsMap.keySet());
+        ndEa.keySet().removeAll(cndEvictionAttrsMap.keySet());
+        ndPa.keySet().removeAll(cndPartitionAttrsMap.keySet());
+
+        // Scope is not valid for PR's
         if (regionDescription.isPartition()) {
-          regionDescription.getCndRegionAttributes().remove(RegionAttributesNames.SCOPE);
-        } else {
-          String scope =
-              regionDescription.getCndRegionAttributes().get(RegionAttributesNames.SCOPE);
-          if (scope != null) {
-            scope = scope.toLowerCase().replace('_', '-');
-            regionDescription.getCndRegionAttributes().put(RegionAttributesNames.SCOPE, scope);
+          if (ndRa.get(RegionAttributesNames.SCOPE) != null) {
+            ndRa.remove(RegionAttributesNames.SCOPE);
           }
         }
-        CompositeResultData.SectionResultData regionSection = crd.addSection();
-        regionSection.addSeparator('-');
-        regionSection.addData("Name", regionDescription.getName());
 
-        String dataPolicy =
-            regionDescription.getDataPolicy().toString().toLowerCase().replace('_', ' ');
-        regionSection.addData("Data Policy", dataPolicy);
+        List<FixedPartitionAttributesInfo> fpaList = regDescPerMem.getFixedPartitionAttributes();
 
-        String memberType;
+        if (!(ndRa.isEmpty() && ndEa.isEmpty() && ndPa.isEmpty()) || fpaList != null) {
+          setHeader = true;
+          boolean memberNameAdded;
+          memberNameAdded = writeAttributesToTable(table,
+              CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__REGION, ndRa, member, false);
+          memberNameAdded = writeAttributesToTable(table,
+              CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__EVICTION, ndEa, member, memberNameAdded);
+          memberNameAdded =
+              writeAttributesToTable(table, CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__PARTITION,
+                  ndPa, member, memberNameAdded);
 
-        if (regionDescription.isAccessor()) {
-          memberType = CliStrings.DESCRIBE_REGION__ACCESSOR__MEMBER;
-        } else {
-          memberType = CliStrings.DESCRIBE_REGION__HOSTING__MEMBER;
-        }
-        regionSection.addData(memberType,
-            CliUtil.convertStringSetToString(regionDescription.getHostingMembers(), '\n'));
-        regionSection.addSeparator('.');
-
-        TabularResultData commonNonDefaultAttrTable = regionSection.addSection().addTable();
-
-        commonNonDefaultAttrTable.setHeader(CliStrings
-            .format(CliStrings.DESCRIBE_REGION__NONDEFAULT__COMMONATTRIBUTES__HEADER, memberType));
-        // Common Non Default Region Attributes
-        Map<String, String> cndRegionAttrsMap = regionDescription.getCndRegionAttributes();
-
-        // Common Non Default Eviction Attributes
-        Map<String, String> cndEvictionAttrsMap = regionDescription.getCndEvictionAttributes();
-
-        // Common Non Default Partition Attributes
-        Map<String, String> cndPartitionAttrsMap = regionDescription.getCndPartitionAttributes();
-
-        writeCommonAttributesToTable(commonNonDefaultAttrTable,
-            CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__REGION, cndRegionAttrsMap);
-        writeCommonAttributesToTable(commonNonDefaultAttrTable,
-            CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__EVICTION, cndEvictionAttrsMap);
-        writeCommonAttributesToTable(commonNonDefaultAttrTable,
-            CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__PARTITION, cndPartitionAttrsMap);
-
-        // Member-wise non default Attributes
-        Map<String, RegionDescriptionPerMember> regDescPerMemberMap =
-            regionDescription.getRegionDescriptionPerMemberMap();
-        Set<String> members = regDescPerMemberMap.keySet();
-
-        TabularResultData table = regionSection.addSection().addTable();
-
-        boolean setHeader = false;
-        for (String member : members) {
-          RegionDescriptionPerMember regDescPerMem = regDescPerMemberMap.get(member);
-          Map<String, String> ndRa = regDescPerMem.getNonDefaultRegionAttributes();
-          Map<String, String> ndEa = regDescPerMem.getNonDefaultEvictionAttributes();
-          Map<String, String> ndPa = regDescPerMem.getNonDefaultPartitionAttributes();
-
-          // Get all the member-specific non-default attributes by removing the common keys
-          ndRa.keySet().removeAll(cndRegionAttrsMap.keySet());
-          ndEa.keySet().removeAll(cndEvictionAttrsMap.keySet());
-          ndPa.keySet().removeAll(cndPartitionAttrsMap.keySet());
-
-          // Scope is not valid for PR's
-          if (regionDescription.isPartition()) {
-            if (ndRa.get(RegionAttributesNames.SCOPE) != null) {
-              ndRa.remove(RegionAttributesNames.SCOPE);
-            }
-          }
-
-          List<FixedPartitionAttributesInfo> fpaList = regDescPerMem.getFixedPartitionAttributes();
-
-          if (!(ndRa.isEmpty() && ndEa.isEmpty() && ndPa.isEmpty()) || fpaList != null) {
-            setHeader = true;
-            boolean memberNameAdded;
-            memberNameAdded = writeAttributesToTable(table,
-                CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__REGION, ndRa, member, false);
-            memberNameAdded =
-                writeAttributesToTable(table, CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__EVICTION,
-                    ndEa, member, memberNameAdded);
-            memberNameAdded = writeAttributesToTable(table,
-                CliStrings.DESCRIBE_REGION__ATTRIBUTE__TYPE__PARTITION, ndPa, member,
-                memberNameAdded);
-
-            writeFixedPartitionAttributesToTable(table, fpaList, member, memberNameAdded);
-          }
-        }
-
-        if (setHeader) {
-          table.setHeader(CliStrings.format(
-              CliStrings.DESCRIBE_REGION__NONDEFAULT__PERMEMBERATTRIBUTES__HEADER, memberType));
+          writeFixedPartitionAttributesToTable(table, fpaList, member, memberNameAdded);
         }
       }
 
-      result = ResultBuilder.buildResult(crd);
-    } catch (FunctionInvocationTargetException e) {
-      result = ResultBuilder.createGemFireErrorResult(CliStrings
-          .format(CliStrings.COULD_NOT_EXECUTE_COMMAND_TRY_AGAIN, CliStrings.DESCRIBE_REGION));
-    } catch (Exception e) {
-      String errorMessage = CliStrings.format(CliStrings.EXCEPTION_CLASS_AND_MESSAGE,
-          e.getClass().getName(), e.getMessage());
-      result = ResultBuilder.createGemFireErrorResult(errorMessage);
+      if (setHeader) {
+        table.setHeader(CliStrings.format(
+            CliStrings.DESCRIBE_REGION__NONDEFAULT__PERMEMBERATTRIBUTES__HEADER, memberType));
+      }
     }
+
+    result = ResultBuilder.buildResult(crd);
     return result;
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommand.java
index 12b6dc1..821eb64 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommand.java
@@ -14,34 +14,18 @@
  */
 package org.apache.geode.management.internal.cli.commands;
 
-import java.text.MessageFormat;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
 
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-import org.apache.commons.lang.StringUtils;
 import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
-import org.apache.geode.LogWriter;
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.Scope;
 import org.apache.geode.cache.execute.ResultCollector;
 import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.ManagementService;
-import org.apache.geode.management.RegionAttributesData;
-import org.apache.geode.management.RegionMXBean;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.ConverterHint;
 import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.MBeanJMXAdapter;
 import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.cli.LogWrapper;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
@@ -59,79 +43,58 @@ public class DestroyRegionCommand implements GfshCommand {
       operation = ResourcePermission.Operation.MANAGE)
   public Result destroyRegion(
       @CliOption(key = CliStrings.DESTROY_REGION__REGION, optionContext = ConverterHint.REGION_PATH,
-          mandatory = true, help = CliStrings.DESTROY_REGION__REGION__HELP) String regionPath) {
-
-    if (regionPath == null) {
-      return ResultBuilder
-          .createInfoResult(CliStrings.DESTROY_REGION__MSG__SPECIFY_REGIONPATH_TO_DESTROY);
-    }
-
-    if (StringUtils.isBlank(regionPath) || regionPath.equals(Region.SEPARATOR)) {
-      return ResultBuilder.createInfoResult(CliStrings.format(
-          CliStrings.DESTROY_REGION__MSG__REGIONPATH_0_NOT_VALID, new Object[] {regionPath}));
-    }
+          mandatory = true, help = CliStrings.DESTROY_REGION__REGION__HELP) String regionPath,
+      @CliOption(key = CliStrings.IFEXISTS, help = CliStrings.IFEXISTS_HELP,
+          specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") boolean ifExists) {
 
+    // regionPath should already be converted to have "/" in front of it.
     Result result;
     AtomicReference<XmlEntity> xmlEntity = new AtomicReference<>();
-    try {
-      InternalCache cache = getCache();
-      ManagementService managementService = ManagementService.getExistingManagementService(cache);
-      String regionPathToUse = regionPath;
-
-      if (!regionPathToUse.startsWith(Region.SEPARATOR)) {
-        regionPathToUse = Region.SEPARATOR + regionPathToUse;
-      }
 
-      Set<DistributedMember> regionMembersList =
-          findMembersForRegion(cache, managementService, regionPathToUse);
+    Set<DistributedMember> regionMembersList = findMembersForRegion(getCache(), regionPath);
 
-      if (regionMembersList.size() == 0) {
+    if (regionMembersList.size() == 0) {
+      if (ifExists) {
+        return ResultBuilder.createInfoResult("");
+      } else {
         return ResultBuilder.createUserErrorResult(
             CliStrings.format(CliStrings.DESTROY_REGION__MSG__COULD_NOT_FIND_REGIONPATH_0_IN_GEODE,
                 regionPath, "jmx-manager-update-rate milliseconds"));
       }
+    }
 
-      CliFunctionResult destroyRegionResult;
-
-      ResultCollector<?, ?> resultCollector =
-          CliUtil.executeFunction(RegionDestroyFunction.INSTANCE, regionPath, regionMembersList);
-      List<CliFunctionResult> resultsList = (List<CliFunctionResult>) resultCollector.getResult();
-      String message =
-          CliStrings.format(CliStrings.DESTROY_REGION__MSG__REGION_0_1_DESTROYED, regionPath, "");
-
-      // Only if there is an error is this set to false
-      boolean isRegionDestroyed = true;
-      for (CliFunctionResult aResultsList : resultsList) {
-        destroyRegionResult = aResultsList;
-        if (destroyRegionResult.isSuccessful()) {
-          xmlEntity.set(destroyRegionResult.getXmlEntity());
-        } else if (destroyRegionResult.getThrowable() != null) {
-          Throwable t = destroyRegionResult.getThrowable();
-          LogWrapper.getInstance().info(t.getMessage(), t);
-          message = CliStrings.format(
-              CliStrings.DESTROY_REGION__MSG__ERROR_OCCURRED_WHILE_DESTROYING_0_REASON_1,
-              regionPath, t.getMessage());
-          isRegionDestroyed = false;
-        } else {
-          message = CliStrings.format(
-              CliStrings.DESTROY_REGION__MSG__UNKNOWN_RESULT_WHILE_DESTROYING_REGION_0_REASON_1,
-              regionPath, destroyRegionResult.getMessage());
-          isRegionDestroyed = false;
-        }
-      }
-      if (isRegionDestroyed) {
-        result = ResultBuilder.createInfoResult(message);
+    CliFunctionResult destroyRegionResult;
+
+    ResultCollector<?, ?> resultCollector =
+        CliUtil.executeFunction(RegionDestroyFunction.INSTANCE, regionPath, regionMembersList);
+    List<CliFunctionResult> resultsList = (List<CliFunctionResult>) resultCollector.getResult();
+    String message =
+        CliStrings.format(CliStrings.DESTROY_REGION__MSG__REGION_0_1_DESTROYED, regionPath, "");
+
+    // Only if there is an error is this set to false
+    boolean isRegionDestroyed = true;
+    for (CliFunctionResult aResultsList : resultsList) {
+      destroyRegionResult = aResultsList;
+      if (destroyRegionResult.isSuccessful()) {
+        xmlEntity.set(destroyRegionResult.getXmlEntity());
+      } else if (destroyRegionResult.getThrowable() != null) {
+        Throwable t = destroyRegionResult.getThrowable();
+        LogWrapper.getInstance().info(t.getMessage(), t);
+        message = CliStrings.format(
+            CliStrings.DESTROY_REGION__MSG__ERROR_OCCURRED_WHILE_DESTROYING_0_REASON_1, regionPath,
+            t.getMessage());
+        isRegionDestroyed = false;
       } else {
-        result = ResultBuilder.createUserErrorResult(message);
+        message = CliStrings.format(
+            CliStrings.DESTROY_REGION__MSG__UNKNOWN_RESULT_WHILE_DESTROYING_REGION_0_REASON_1,
+            regionPath, destroyRegionResult.getMessage());
+        isRegionDestroyed = false;
       }
-    } catch (IllegalStateException e) {
-      result = ResultBuilder.createUserErrorResult(CliStrings.format(
-          CliStrings.DESTROY_REGION__MSG__ERROR_WHILE_DESTROYING_REGION_0_REASON_1, regionPath,
-          e.getMessage()));
-    } catch (Exception e) {
-      result = ResultBuilder.createGemFireErrorResult(CliStrings.format(
-          CliStrings.DESTROY_REGION__MSG__ERROR_WHILE_DESTROYING_REGION_0_REASON_1, regionPath,
-          e.getMessage()));
+    }
+    if (isRegionDestroyed) {
+      result = ResultBuilder.createInfoResult(message);
+    } else {
+      result = ResultBuilder.createUserErrorResult(message);
     }
 
     if (xmlEntity.get() != null) {
@@ -141,82 +104,4 @@ public class DestroyRegionCommand implements GfshCommand {
 
     return result;
   }
-
-  private Set<DistributedMember> findMembersForRegion(InternalCache cache,
-      ManagementService managementService, String regionPath) {
-    Set<DistributedMember> membersList = new HashSet<>();
-    Set<String> regionMemberIds = new HashSet<>();
-    MBeanServer mbeanServer = MBeanJMXAdapter.mbeanServer;
-
-    // needs to be escaped with quotes if it contains a hyphen
-    if (regionPath.contains("-")) {
-      regionPath = "\"" + regionPath + "\"";
-    }
-
-    String queryExp =
-        MessageFormat.format(MBeanJMXAdapter.OBJECTNAME__REGION_MXBEAN, regionPath, "*");
-
-    try {
-      ObjectName queryExpON = new ObjectName(queryExp);
-      Set<ObjectName> queryNames = mbeanServer.queryNames(null, queryExpON);
-      if (queryNames == null || queryNames.isEmpty()) {
-        return membersList; // protects against null pointer exception below
-      }
-
-      boolean addedOneRemote = false;
-      for (ObjectName regionMBeanObjectName : queryNames) {
-        try {
-          RegionMXBean regionMXBean =
-              managementService.getMBeanInstance(regionMBeanObjectName, RegionMXBean.class);
-          if (regionMXBean != null) {
-            RegionAttributesData regionAttributes = regionMXBean.listRegionAttributes();
-            String scope = regionAttributes.getScope();
-            // For Scope.LOCAL regions we need to identify each hosting member, but for
-            // other scopes we just need a single member as the region destroy will be
-            // propagated.
-            if (Scope.LOCAL.equals(Scope.fromString(scope))) {
-              regionMemberIds.add(regionMXBean.getMember());
-            } else {
-              if (!addedOneRemote) {
-                regionMemberIds.add(regionMXBean.getMember());
-                addedOneRemote = true;
-              }
-            }
-          }
-        } catch (ClassCastException e) {
-          LogWriter logger = cache.getLogger();
-          if (logger.finerEnabled()) {
-            logger.finer(regionMBeanObjectName + " is not a " + RegionMXBean.class.getSimpleName(),
-                e);
-          }
-        }
-      }
-
-      if (!regionMemberIds.isEmpty()) {
-        membersList = getMembersByIds(cache, regionMemberIds);
-      }
-    } catch (MalformedObjectNameException | NullPointerException e) {
-      LogWrapper.getInstance().info(e.getMessage(), e);
-    }
-
-    return membersList;
-  }
-
-  private Set<DistributedMember> getMembersByIds(InternalCache cache, Set<String> memberIds) {
-    Set<DistributedMember> foundMembers = Collections.emptySet();
-    if (memberIds != null && !memberIds.isEmpty()) {
-      foundMembers = new HashSet<>();
-      Set<DistributedMember> allNormalMembers = CliUtil.getAllNormalMembers(cache);
-
-      for (String memberId : memberIds) {
-        for (DistributedMember distributedMember : allNormalMembers) {
-          if (memberId.equals(distributedMember.getId())
-              || memberId.equals(distributedMember.getName())) {
-            foundMembers.add(distributedMember);
-          }
-        }
-      }
-    }
-    return foundMembers;
-  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DisconnectCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DisconnectCommand.java
index 5ffd4b0..2d7da45 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DisconnectCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DisconnectCommand.java
@@ -20,7 +20,6 @@ import org.springframework.shell.core.annotation.CliCommand;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.LogWrapper;
-import org.apache.geode.management.internal.cli.converters.RegionPathConverter;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
 import org.apache.geode.management.internal.cli.result.InfoResultData;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
@@ -49,7 +48,7 @@ public class DisconnectCommand implements GfshCommand {
           LogWrapper.getInstance().info(CliStrings.format(CliStrings.DISCONNECT__MSG__DISCONNECTED,
               operationInvoker.toString()));
           if (!gfshInstance.isHeadlessMode()) {
-            gfshInstance.setPromptPath(RegionPathConverter.DEFAULT_APP_CONTEXT_PATH);
+            gfshInstance.setPromptPath(gfshInstance.getEnvAppContextPath());
           }
         } else {
           infoResultData.addLine(CliStrings.DISCONNECT__MSG__NOTCONNECTED);
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GetCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GetCommand.java
index cf72207..0ccdfe0 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GetCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GetCommand.java
@@ -22,7 +22,6 @@ import static org.apache.geode.management.internal.cli.commands.DataCommandsUtil
 import java.util.Set;
 
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.StringUtils;
 import org.apache.shiro.subject.Subject;
 import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
@@ -61,16 +60,6 @@ public class GetCommand implements GfshCommand {
     cache.getSecurityService().authorize(Resource.DATA, Operation.READ, regionPath, key);
     DataCommandResult dataResult;
 
-    if (StringUtils.isEmpty(regionPath)) {
-      return makePresentationResult(DataCommandResult.createGetResult(key, null, null,
-          CliStrings.GET__MSG__REGIONNAME_EMPTY, false));
-    }
-
-    if (StringUtils.isEmpty(key)) {
-      return makePresentationResult(DataCommandResult.createGetResult(key, null, null,
-          CliStrings.GET__MSG__KEY_EMPTY, false));
-    }
-
     @SuppressWarnings("rawtypes")
     Region region = cache.getRegion(regionPath);
     DataCommandFunction getfn = new DataCommandFunction();
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshCommand.java
index 87452da..c6699d4 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshCommand.java
@@ -150,4 +150,8 @@ public interface GfshCommand extends CommandMarker {
     return CliUtil.findMembers(groups, members);
   }
 
+  default Set<DistributedMember> findMembersForRegion(InternalCache cache, String regionPath) {
+    return CliUtil.getRegionAssociatedMembers(regionPath, cache);
+  }
+
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LocateEntryCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LocateEntryCommand.java
index 7f3379a..d3746c5 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LocateEntryCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LocateEntryCommand.java
@@ -22,7 +22,6 @@ import static org.apache.geode.management.internal.cli.commands.DataCommandsUtil
 import java.util.Set;
 
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.StringUtils;
 import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
@@ -58,16 +57,6 @@ public class LocateEntryCommand implements GfshCommand {
 
     DataCommandResult dataResult;
 
-    if (StringUtils.isEmpty(regionPath)) {
-      return makePresentationResult(DataCommandResult.createLocateEntryResult(key, null, null,
-          CliStrings.LOCATE_ENTRY__MSG__REGIONNAME_EMPTY, false));
-    }
-
-    if (StringUtils.isEmpty(key)) {
-      return makePresentationResult(DataCommandResult.createLocateEntryResult(key, null, null,
-          CliStrings.LOCATE_ENTRY__MSG__KEY_EMPTY, false));
-    }
-
     DataCommandFunction locateEntry = new DataCommandFunction();
     Set<DistributedMember> memberList = getRegionAssociatedMembers(regionPath, getCache(), true);
     if (CollectionUtils.isNotEmpty(memberList)) {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/PutCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/PutCommand.java
index c6a5042..a2e1903 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/PutCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/PutCommand.java
@@ -22,7 +22,6 @@ import static org.apache.geode.management.internal.cli.commands.DataCommandsUtil
 import java.util.Set;
 
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.StringUtils;
 import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
@@ -60,20 +59,6 @@ public class PutCommand implements GfshCommand {
     InternalCache cache = getCache();
     cache.getSecurityService().authorize(Resource.DATA, Operation.WRITE, regionPath);
     DataCommandResult dataResult;
-    if (StringUtils.isEmpty(regionPath)) {
-      return makePresentationResult(DataCommandResult.createPutResult(key, null, null,
-          CliStrings.PUT__MSG__REGIONNAME_EMPTY, false));
-    }
-
-    if (StringUtils.isEmpty(key)) {
-      return makePresentationResult(DataCommandResult.createPutResult(key, null, null,
-          CliStrings.PUT__MSG__KEY_EMPTY, false));
-    }
-
-    if (StringUtils.isEmpty(value)) {
-      return makePresentationResult(DataCommandResult.createPutResult(value, null, null,
-          CliStrings.PUT__MSG__VALUE_EMPTY, false));
-    }
 
     @SuppressWarnings("rawtypes")
     Region region = cache.getRegion(regionPath);
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
index e48f1b5..fa5f4b9 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
@@ -23,7 +23,6 @@ import static org.apache.geode.management.internal.cli.result.ResultBuilder.crea
 import java.util.Set;
 
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.StringUtils;
 import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
@@ -57,10 +56,6 @@ public class RemoveCommand implements GfshCommand {
           help = CliStrings.REMOVE__KEYCLASS__HELP) String keyClass) {
     InternalCache cache = getCache();
 
-    if (StringUtils.isEmpty(regionPath)) {
-      return createUserErrorResult(CliStrings.REMOVE__MSG__REGIONNAME_EMPTY);
-    }
-
     if (!removeAllKeys && (key == null)) {
       return createUserErrorResult(CliStrings.REMOVE__MSG__KEY_EMPTY);
     }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ShowMetricsCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ShowMetricsCommand.java
index 1fb7150..c26c97e 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ShowMetricsCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ShowMetricsCommand.java
@@ -15,6 +15,18 @@
 
 package org.apache.geode.management.internal.cli.commands;
 
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.ObjectName;
+
+import org.apache.logging.log4j.Logger;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.logging.LogService;
@@ -42,16 +54,6 @@ import org.apache.geode.management.internal.cli.result.ResultDataException;
 import org.apache.geode.management.internal.cli.result.TabularResultData;
 import org.apache.geode.management.internal.security.ResourceOperation;
 import org.apache.geode.security.ResourcePermission;
-import org.apache.logging.log4j.Logger;
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import javax.management.ObjectName;
 
 public class ShowMetricsCommand implements GfshCommand {
   private static final Logger logger = LogService.getLogger();
@@ -84,10 +86,6 @@ public class ShowMetricsCommand implements GfshCommand {
     }
 
     if (regionName != null) {
-      // MBean names contain the forward slash
-      if (!regionName.startsWith("/")) {
-        regionName = "/" + regionName;
-      }
       if (memberNameOrId != null) {
         result = ResultBuilder.buildResult(
             getRegionMetricsFromMember(regionName, member, export_to_report_to, categories));
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/converters/RegionPathConverter.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/converters/RegionPathConverter.java
index a992ddb..d7d70f9 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/converters/RegionPathConverter.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/converters/RegionPathConverter.java
@@ -14,25 +14,25 @@
  */
 package org.apache.geode.management.internal.cli.converters;
 
-import org.apache.geode.management.cli.ConverterHint;
-import org.apache.geode.management.internal.cli.shell.Gfsh;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 import org.springframework.shell.core.Completion;
 import org.springframework.shell.core.Converter;
 import org.springframework.shell.core.MethodTarget;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
+import org.apache.geode.cache.Region;
+import org.apache.geode.management.cli.ConverterHint;
+import org.apache.geode.management.internal.cli.shell.Gfsh;
 
 /**
  * 
  * @since GemFire 7.0
  */
 public class RegionPathConverter implements Converter<String> {
-
-  public static final String DEFAULT_APP_CONTEXT_PATH = "";
-
   @Override
   public boolean supports(Class<?> type, String optionContext) {
     return String.class.equals(type) && optionContext.contains(ConverterHint.REGION_PATH);
@@ -40,6 +40,18 @@ public class RegionPathConverter implements Converter<String> {
 
   @Override
   public String convertFromText(String value, Class<?> targetType, String optionContext) {
+    // When value is null, this should not be called. this is here for safety reasons
+    if (value == null) {
+      return null;
+    }
+
+    if (value.equals(Region.SEPARATOR)) {
+      throw new IllegalArgumentException("invalid region path: " + value);
+    }
+
+    if (!value.startsWith(Region.SEPARATOR)) {
+      value = Region.SEPARATOR + value;
+    }
     return value;
   }
 
@@ -47,18 +59,6 @@ public class RegionPathConverter implements Converter<String> {
   public boolean getAllPossibleValues(List<Completion> completions, Class<?> targetType,
       String existingData, String optionContext, MethodTarget target) {
     Set<String> regionPathSet = getAllRegionPaths();
-    Gfsh gfsh = Gfsh.getCurrentInstance();
-    String currentContextPath = "";
-    if (gfsh != null) {
-      currentContextPath = gfsh.getEnvProperty(Gfsh.ENV_APP_CONTEXT_PATH);
-      if (currentContextPath != null
-          && !org.apache.geode.management.internal.cli.converters.RegionPathConverter.DEFAULT_APP_CONTEXT_PATH
-              .equals(currentContextPath)) {
-        regionPathSet.remove(currentContextPath);
-        regionPathSet.add(
-            org.apache.geode.management.internal.cli.converters.RegionPathConverter.DEFAULT_APP_CONTEXT_PATH);
-      }
-    }
 
     for (String regionPath : regionPathSet) {
       if (existingData != null) {
@@ -79,16 +79,8 @@ public class RegionPathConverter implements Converter<String> {
     if (gfsh != null && gfsh.isConnectedAndReady()) {
       String[] regionPaths =
           gfsh.getOperationInvoker().getDistributedSystemMXBean().listAllRegionPaths();
-      if (regionPaths != null && regionPaths.length > 0) {
-        regionPathSet = new TreeSet<String>();
-        for (String regionPath : regionPaths) {
-          if (regionPath != null) { // Not needed after 46387/46502 are addressed
-            regionPathSet.add(regionPath);
-          }
-        }
-      }
+      regionPathSet = Arrays.stream(regionPaths).collect(Collectors.toSet());
     }
-
     return regionPathSet;
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java
index db0b08c..72ef5fa 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java
@@ -79,9 +79,12 @@ public class CliStrings {
   public static final String GROUPS = "groups";
   public static final String MEMBER = "member";
   public static final String MEMBERS = "members";
+  public static final String IFEXISTS = "if-exists";
   public static final String JAR = "jar";
   public static final String JARS = "jars";
 
+  public static final String IFEXISTS_HELP =
+      "If true, the command will be a no-op if the entity does not exist.";
   private static final String LOG_LEVEL_VALUES =
       "Possible values for log-level include: ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF.";
 
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java
index 1cf1fae..db85309 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java
@@ -56,7 +56,6 @@ import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.cli.CommandManager;
 import org.apache.geode.management.internal.cli.GfshParser;
 import org.apache.geode.management.internal.cli.LogWrapper;
-import org.apache.geode.management.internal.cli.converters.RegionPathConverter;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
 import org.apache.geode.management.internal.cli.result.CommandResult;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
@@ -975,6 +974,14 @@ public class Gfsh extends JLineShell {
     return env.get(propertyName);
   }
 
+  public String getEnvAppContextPath() {
+    String path = getEnvProperty(Gfsh.ENV_APP_CONTEXT_PATH);
+    if (path == null) {
+      return "";
+    }
+    return path;
+  }
+
   public Map<String, String> getEnv() {
     Map<String, String> map = new TreeMap<>();
     map.putAll(env);
@@ -1096,7 +1103,7 @@ public class Gfsh extends JLineShell {
     if (gfshFileLogger.severeEnabled()) {
       gfshFileLogger.severe(message);
     }
-    setPromptPath(RegionPathConverter.DEFAULT_APP_CONTEXT_PATH);
+    setPromptPath(getEnvAppContextPath());
   }
 
   public boolean getDebug() {
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java
index 8598a4c..5a193d5 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java
@@ -12,183 +12,125 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
+
 package org.apache.geode.management.internal.cli.commands;
 
-import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
-import static org.apache.geode.distributed.ConfigurationProperties.GROUPS;
-import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
-import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER;
-import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_BIND_ADDRESS;
-import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
-import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_START;
-import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
-import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
-import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
-import static org.apache.geode.distributed.ConfigurationProperties.NAME;
-import static org.apache.geode.distributed.ConfigurationProperties.USE_CLUSTER_CONFIGURATION;
-import static org.apache.geode.test.dunit.LogWriterUtils.getLogWriter;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.awaitility.Awaitility.waitAtMost;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
+
 import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
 import java.text.MessageFormat;
-import java.util.Properties;
-import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 
 import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.PartitionAttributesFactory;
-import org.apache.geode.cache.Region;
 import org.apache.geode.cache.RegionFactory;
 import org.apache.geode.cache.RegionShortcut;
 import org.apache.geode.cache.Scope;
 import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.internal.ClusterConfigurationService;
 import org.apache.geode.distributed.internal.InternalLocator;
-import org.apache.geode.internal.AvailablePort;
-import org.apache.geode.internal.AvailablePortHelper;
-import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.MBeanJMXAdapter;
 import org.apache.geode.management.internal.ManagementConstants;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
-import org.apache.geode.management.internal.cli.result.CommandResult;
-import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.categories.DistributedTest;
-import org.apache.geode.test.junit.categories.FlakyTest;
+import org.apache.geode.test.junit.rules.GfshShellConnectionRule;
+
+@Category(DistributedTest.class)
+public class DestroyRegionCommandDUnitTest {
+  @ClassRule
+  public static LocatorServerStartupRule lsRule = new LocatorServerStartupRule();
 
-@Category({DistributedTest.class, FlakyTest.class}) // GEODE-3530
-@SuppressWarnings("serial")
-public class DestroyRegionCommandDUnitTest extends CliCommandTestBase {
+  @Rule
+  public GfshShellConnectionRule gfsh = new GfshShellConnectionRule();
+
+  private static MemberVM locator, server1, server2, server3;
+
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    locator = lsRule.startLocatorVM(0);
+    server1 = lsRule.startServerVM(1, locator.getPort());
+    server2 = lsRule.startServerVM(2, locator.getPort());
+    server3 = lsRule.startServerVM(3, locator.getPort());
+  }
+
+  @Before
+  public void before() throws Exception {
+    gfsh.connectAndVerify(locator);
+  }
 
   @Test
   public void testDestroyDistributedRegion() {
-    setUpJmxManagerOnVm0ThenConnect(null);
-
-    for (int i = 1; i <= 2; i++) {
-      Host.getHost(0).getVM(i).invoke(() -> {
-        final Cache cache = getCache();
-
-        RegionFactory<Object, Object> factory = cache.createRegionFactory(RegionShortcut.PARTITION);
-        factory.create("Customer");
-
-        PartitionAttributesFactory paFactory = new PartitionAttributesFactory();
-        paFactory.setColocatedWith("Customer");
-        factory.setPartitionAttributes(paFactory.create());
-        factory.create("Order");
-      });
-    }
-
-    waitForRegionMBeanCreation("/Customer", 2);
-    waitForRegionMBeanCreation("/Order", 2);
-
-    // Test failure when region not found
-    String command = "destroy region --name=DOESNOTEXIST";
-    getLogWriter().info("testDestroyRegion command=" + command);
-    CommandResult cmdResult = executeCommand(command);
-    String strr = commandResultToString(cmdResult);
-    getLogWriter().info("testDestroyRegion strr=" + strr);
-    assertTrue(stringContainsLine(strr, "Could not find.*\"DOESNOTEXIST\".*"));
-    assertEquals(Result.Status.ERROR, cmdResult.getStatus());
+    MemberVM.invokeInEveryMember(() -> {
+      Cache cache = LocatorServerStartupRule.serverStarter.getCache();
+      RegionFactory<Object, Object> factory = cache.createRegionFactory(RegionShortcut.PARTITION);
+      factory.create("Customer");
+
+      PartitionAttributesFactory paFactory = new PartitionAttributesFactory();
+      paFactory.setColocatedWith("Customer");
+      factory.setPartitionAttributes(paFactory.create());
+      factory.create("Order");
+    }, server1, server2);
+
+    locator.invoke(() -> waitForRegionMBeanCreation("/Customer", 2));
+    locator.invoke(() -> waitForRegionMBeanCreation("/Order", 2));
 
     // Test unable to destroy with co-location
-    command = "destroy region --name=/Customer";
-    getLogWriter().info("testDestroyRegion command=" + command);
-    cmdResult = executeCommand(command);
-    strr = commandResultToString(cmdResult);
-    getLogWriter().info("testDestroyRegion strr=" + strr);
-    assertEquals(Result.Status.ERROR, cmdResult.getStatus());
+    gfsh.executeAndVerifyCommandError("destroy region --name=/Customer",
+        "The parent region [/Customer] in colocation chain cannot be destroyed");
 
     // Test success
-    command = "destroy region --name=/Order";
-    getLogWriter().info("testDestroyRegion command=" + command);
-    cmdResult = executeCommand(command);
-    strr = commandResultToString(cmdResult);
-    assertTrue(stringContainsLine(strr, ".*Order.*destroyed successfully.*"));
-    getLogWriter().info("testDestroyRegion strr=" + strr);
-    assertEquals(Result.Status.OK, cmdResult.getStatus());
-
-    command = "destroy region --name=/Customer";
-    getLogWriter().info("testDestroyRegion command=" + command);
-    cmdResult = executeCommand(command);
-    strr = commandResultToString(cmdResult);
-    assertTrue(stringContainsLine(strr, ".*Customer.*destroyed successfully.*"));
-    getLogWriter().info("testDestroyRegion strr=" + strr);
-    assertEquals(Result.Status.OK, cmdResult.getStatus());
+    gfsh.executeAndVerifyCommand("destroy region --name=/Order", "destroyed successfully");
+    gfsh.executeAndVerifyCommand("destroy region --name=/Customer", "destroyed successfully");
+
+    // destroy something that's not exist anymore
+    gfsh.executeAndVerifyCommandError("destroy region --name=/Customer", "Could not find a Region");
+    gfsh.executeAndVerifyCommand("destroy region --name=/Customer --if-exists");
   }
 
   @Test
   public void testDestroyLocalRegions() {
-    setUpJmxManagerOnVm0ThenConnect(null);
-
-    for (int i = 1; i <= 3; i++) {
-      Host.getHost(0).getVM(i).invoke(() -> {
-        final Cache cache = getCache();
-
-        RegionFactory<Object, Object> factory = cache.createRegionFactory(RegionShortcut.REPLICATE);
-        factory.setScope(Scope.LOCAL);
-        factory.create("Customer");
-      });
-    }
-
-    waitForRegionMBeanCreation("/Customer", 3);
-
-    // Test failure when region not found
-    String command = "destroy region --name=DOESNOTEXIST";
-    getLogWriter().info("testDestroyRegion command=" + command);
-    CommandResult cmdResult = executeCommand(command);
-    String strr = commandResultToString(cmdResult);
-    getLogWriter().info("testDestroyRegion strr=" + strr);
-    assertTrue(stringContainsLine(strr, "Could not find.*\"DOESNOTEXIST\".*"));
-    assertEquals(Result.Status.ERROR, cmdResult.getStatus());
-
-    command = "destroy region --name=/Customer";
-    getLogWriter().info("testDestroyRegion command=" + command);
-    cmdResult = executeCommand(command);
-    strr = commandResultToString(cmdResult);
-    assertTrue(stringContainsLine(strr, ".*Customer.*destroyed successfully.*"));
-    getLogWriter().info("testDestroyRegion strr=" + strr);
-    assertEquals(Result.Status.OK, cmdResult.getStatus());
-
-    for (int i = 1; i <= 3; i++) {
-      final int x = i;
-      Host.getHost(0).getVM(i).invoke(
-          () -> assertNull("Region still exists in VM " + x, getCache().getRegion("Customer")));
-    }
+    MemberVM.invokeInEveryMember(() -> {
+      Cache cache = LocatorServerStartupRule.serverStarter.getCache();
+      RegionFactory<Object, Object> factory = cache.createRegionFactory(RegionShortcut.REPLICATE);
+      factory.setScope(Scope.LOCAL);
+      factory.create("Customer");
+    }, server1, server2, server3);
+
+    locator.invoke(() -> waitForRegionMBeanCreation("/Customer", 3));
+
+    gfsh.executeAndVerifyCommand("destroy region --name=Customer", "destroyed successfully");
+
+    MemberVM.invokeInEveryMember(() -> {
+      Cache cache = LocatorServerStartupRule.serverStarter.getCache();
+      assertThat(cache.getRegion("Customer")).isNull();
+    }, server1, server2, server3);
   }
 
   @Test
   public void testDestroyLocalAndDistributedRegions() {
-    setUpJmxManagerOnVm0ThenConnect(null);
-
-    for (int i = 1; i <= 2; i++) {
-      Host.getHost(0).getVM(i).invoke(() -> {
-        final Cache cache = getCache();
-        RegionFactory<Object, Object> factory = cache.createRegionFactory(RegionShortcut.PARTITION);
-        factory.create("Customer");
-        factory.create("Customer-2");
-        factory.create("Customer_3");
-      });
-    }
-
-    Host.getHost(0).getVM(3).invoke(() -> {
-      final Cache cache = getCache();
+    MemberVM.invokeInEveryMember(() -> {
+      Cache cache = LocatorServerStartupRule.serverStarter.getCache();
+      RegionFactory<Object, Object> factory = cache.createRegionFactory(RegionShortcut.PARTITION);
+      factory.create("Customer");
+      factory.create("Customer-2");
+      factory.create("Customer_3");
+    }, server1, server2);
+
+    server3.invoke(() -> {
+      Cache cache = LocatorServerStartupRule.serverStarter.getCache();
       RegionFactory<Object, Object> factory = cache.createRegionFactory(RegionShortcut.REPLICATE);
       factory.setScope(Scope.LOCAL);
       factory.create("Customer");
@@ -196,182 +138,62 @@ public class DestroyRegionCommandDUnitTest extends CliCommandTestBase {
       factory.create("Customer_3");
     });
 
-    waitForRegionMBeanCreation("/Customer", 3);
-
-    // Test failure when region not found
-    String command = "destroy region --name=DOESNOTEXIST";
-    getLogWriter().info("testDestroyRegion command=" + command);
-    CommandResult cmdResult = executeCommand(command);
-    String strr = commandResultToString(cmdResult);
-    getLogWriter().info("testDestroyRegion strr=" + strr);
-    assertTrue(stringContainsLine(strr, "Could not find.*\"DOESNOTEXIST\".*"));
-    assertEquals(Result.Status.ERROR, cmdResult.getStatus());
-
-    command = "destroy region --name=/Customer";
-    getLogWriter().info("testDestroyRegion command=" + command);
-    cmdResult = executeCommand(command);
-    strr = commandResultToString(cmdResult);
-    assertTrue(stringContainsLine(strr, ".*Customer.*destroyed successfully.*"));
-    getLogWriter().info("testDestroyRegion strr=" + strr);
-    assertEquals(Result.Status.OK, cmdResult.getStatus());
-
-    command = "destroy region --name=/Customer_3";
-    getLogWriter().info("testDestroyRegion command=" + command);
-    cmdResult = executeCommand(command);
-    strr = commandResultToString(cmdResult);
-    assertTrue(stringContainsLine(strr, ".*Customer_3.*destroyed successfully.*"));
-    getLogWriter().info("testDestroyRegion strr=" + strr);
-    assertEquals(Result.Status.OK, cmdResult.getStatus());
-
-    command = "destroy region --name=/Customer-2";
-    getLogWriter().info("testDestroyRegion command=" + command);
-    cmdResult = executeCommand(command);
-    strr = commandResultToString(cmdResult);
-    assertTrue(stringContainsLine(strr, ".*Customer-2.*destroyed successfully.*"));
-    getLogWriter().info("testDestroyRegion strr=" + strr);
-    assertEquals(Result.Status.OK, cmdResult.getStatus());
-
-    for (int i = 1; i <= 3; i++) {
-      final int x = i;
-      Host.getHost(0).getVM(i).invoke(() -> {
-        assertNull("Region still exists in VM " + x, getCache().getRegion("Customer"));
-        assertNull("Region still exists in VM " + x, getCache().getRegion("Customer-2"));
-        assertNull("Region still exists in VM " + x, getCache().getRegion("Customer_3"));
-      });
-    }
-  }
-
-  @Test
-  public void testDestroyRegionWithSharedConfig() {
-    disconnectAllFromDS();
-
-    final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
-    jmxPort = ports[0];
-    httpPort = ports[1];
-    try {
-      jmxHost = InetAddress.getLocalHost().getHostName();
-    } catch (UnknownHostException ignore) {
-      jmxHost = "localhost";
-    }
-
-
-    final String regionName = "testRegionSharedConfigRegion";
-    final String regionPath = "/" + regionName;
-    final String groupName = "testRegionSharedConfigGroup";
-
-    // Start the Locator and wait for shared configuration to be available
-    final int locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-
-    final Properties locatorProps = new Properties();
-    locatorProps.setProperty(NAME, "Locator");
-    locatorProps.setProperty(MCAST_PORT, "0");
-    locatorProps.setProperty(LOG_LEVEL, "fine");
-    locatorProps.setProperty(ENABLE_CLUSTER_CONFIGURATION, "true");
-    locatorProps.setProperty(JMX_MANAGER, "true");
-    locatorProps.setProperty(JMX_MANAGER_START, "true");
-    locatorProps.setProperty(JMX_MANAGER_BIND_ADDRESS, String.valueOf(jmxHost));
-    locatorProps.setProperty(JMX_MANAGER_PORT, String.valueOf(jmxPort));
-    locatorProps.setProperty(HTTP_SERVICE_PORT, String.valueOf(httpPort));
-
-    Host.getHost(0).getVM(0).invoke(() -> {
-      final File locatorLogFile = new File("locator-" + locatorPort + ".log");
-      try {
-        final InternalLocator locator = (InternalLocator) Locator.startLocatorAndDS(locatorPort,
-            locatorLogFile, null, locatorProps);
-
-        waitAtMost(5, TimeUnit.SECONDS).until(locator::isSharedConfigurationRunning);
-      } catch (IOException ioex) {
-        fail("Unable to create a locator with a shared configuration");
-      }
-    });
+    locator.invoke(() -> waitForRegionMBeanCreation("/Customer", 3));
 
-    connect(jmxHost, jmxPort, httpPort, getDefaultShell());
-
-    // Create a cache in VM 1
-    VM vm = Host.getHost(0).getVM(1);
-    vm.invoke(() -> {
-      Properties localProps = new Properties();
-      localProps.setProperty(MCAST_PORT, "0");
-      localProps.setProperty(LOCATORS, "localhost[" + locatorPort + "]");
-      localProps.setProperty(GROUPS, groupName);
-      getSystem(localProps);
-      assertNotNull(getCache());
-    });
+    gfsh.executeAndVerifyCommand("destroy region --name=Customer", "destroyed successfully");
+    gfsh.executeAndVerifyCommand("destroy region --name=Customer-2", "destroyed successfully");
+    gfsh.executeAndVerifyCommand("destroy region --name=Customer_3", "destroyed successfully");
 
-    // Test creating the region
-    CommandStringBuilder commandStringBuilder = new CommandStringBuilder(CliStrings.CREATE_REGION);
-    commandStringBuilder.addOption(CliStrings.CREATE_REGION__REGION, regionName);
-    commandStringBuilder.addOption(CliStrings.CREATE_REGION__REGIONSHORTCUT, "REPLICATE");
-    commandStringBuilder.addOption(CliStrings.CREATE_REGION__STATISTICSENABLED, "true");
-    commandStringBuilder.addOption(CliStrings.GROUP, groupName);
-    CommandResult cmdResult = executeCommand(commandStringBuilder.toString());
-    assertEquals(Result.Status.OK, cmdResult.getStatus());
+    MemberVM.invokeInEveryMember(() -> {
+      Cache cache = LocatorServerStartupRule.serverStarter.getCache();
+      assertThat(cache.getRegion("Customer")).isNull();
+      assertThat(cache.getRegion("Customer-2")).isNull();
+      assertThat(cache.getRegion("Customer_3")).isNull();
+    }, server1, server2, server3);
+  }
 
-    // Make sure that the region has been registered with the Manager MXBean
-    waitForRegionMBeanCreation(regionPath, 1);
+  @Test
+  public void testDestroyRegionWithSharedConfig() throws IOException {
+    gfsh.executeAndVerifyCommand("create region --name=Customer --type=REPLICATE");
 
-    // Make sure the region exists in the shared config
-    Host.getHost(0).getVM(0).invoke(() -> {
+    locator.invoke(() -> {
+      // Make sure the region exists in the cluster config
       ClusterConfigurationService sharedConfig =
           ((InternalLocator) Locator.getLocator()).getSharedConfiguration();
-      try {
-        assertTrue(
-            sharedConfig.getConfiguration(groupName).getCacheXmlContent().contains(regionName));
-      } catch (Exception e) {
-        fail("Error occurred in cluster configuration service");
-      }
+      assertThat(sharedConfig.getConfiguration("cluster").getCacheXmlContent())
+          .contains("Customer");
     });
 
-    // Test destroying the region
-    commandStringBuilder = new CommandStringBuilder(CliStrings.DESTROY_REGION);
-    commandStringBuilder.addOption(CliStrings.DESTROY_REGION__REGION, regionName);
-    cmdResult = executeCommand(commandStringBuilder.toString());
-    getLogWriter().info("#SB" + commandResultToString(cmdResult));
-    assertEquals(Result.Status.OK, cmdResult.getStatus());
+    // make sure region does exists
+    MemberVM.invokeInEveryMember(() -> {
+      Cache cache = LocatorServerStartupRule.serverStarter.getCache();
+      assertThat(cache.getRegion("Customer")).isNotNull();
+    }, server1, server2, server3);
 
-    // Make sure the region was removed from the shared config
-    Host.getHost(0).getVM(0).invoke(() -> {
+    // destroy the region
+    gfsh.executeAndVerifyCommand("destroy region --name=Customer", "destroyed successfully");
+
+    // make sure the region was removed from cluster config
+    locator.invoke(() -> {
       ClusterConfigurationService sharedConfig =
           ((InternalLocator) Locator.getLocator()).getSharedConfiguration();
-      try {
-        assertFalse(
-            sharedConfig.getConfiguration(groupName).getCacheXmlContent().contains(regionName));
-      } catch (Exception e) {
-        fail("Error occurred in cluster configuration service");
-      }
+      assertThat(sharedConfig.getConfiguration("cluster").getCacheXmlContent())
+          .doesNotContain("Customer");
     });
 
+    // restart one server to make sure the region does not exist anymore
+    lsRule.stopVM(1);
+    lsRule.startServerVM(1, locator.getPort());
 
-    // Restart the data vm to make sure the region is not existing any more
-    vm = Host.getHost(0).getVM(1);
-    vm.invoke(() -> {
-      Cache cache = getCache();
-      assertNotNull(cache);
-      cache.close();
-      assertTrue(cache.isClosed());
-
-      Properties localProps = new Properties();
-      localProps.setProperty(MCAST_PORT, "0");
-      localProps.setProperty(LOCATORS, "localhost[" + locatorPort + "]");
-      localProps.setProperty(GROUPS, groupName);
-      localProps.setProperty(USE_CLUSTER_CONFIGURATION, "true");
-      getSystem(localProps);
-      cache = getCache();
-      assertNotNull(cache);
-      Region region = cache.getRegion(regionName);
-      assertNull(region);
-
-      return null;
-    });
+    // make sure region does not exist
+    MemberVM.invokeInEveryMember(() -> {
+      Cache cache = LocatorServerStartupRule.serverStarter.getCache();
+      assertThat(cache.getRegion("Customer")).isNull();
+    }, server1, server2, server3);
   }
 
-  private void waitForRegionMBeanCreation(final String regionPath, final int mbeanCount) {
-    Host.getHost(0).getVM(0).invoke(() -> waitAtMost(5, TimeUnit.SECONDS)
-        .until(newRegionMBeanIsCreated(regionPath, mbeanCount)));
-  }
-
-  private Callable<Boolean> newRegionMBeanIsCreated(final String regionPath, final int mbeanCount) {
-    return () -> {
+  private static void waitForRegionMBeanCreation(String regionPath, int mbeanCount) {
+    waitAtMost(5, TimeUnit.SECONDS).until(() -> {
       try {
         MBeanServer mbeanServer = MBeanJMXAdapter.mbeanServer;
         String queryExp =
@@ -379,10 +201,8 @@ public class DestroyRegionCommandDUnitTest extends CliCommandTestBase {
         ObjectName queryExpON = new ObjectName(queryExp);
         return mbeanServer.queryNames(null, queryExpON).size() == mbeanCount;
       } catch (MalformedObjectNameException mone) {
-        getLogWriter().error(mone);
-        fail(mone.getMessage());
-        return false;
+        throw new RuntimeException(mone);
       }
-    };
+    });
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandTest.java
new file mode 100644
index 0000000..b519c8d
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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 org.apache.geode.management.internal.cli.commands;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+
+import java.util.Collections;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.management.cli.Result;
+import org.apache.geode.management.internal.cli.result.CommandResult;
+import org.apache.geode.test.junit.categories.UnitTest;
+import org.apache.geode.test.junit.rules.GfshParserRule;
+
+@Category(UnitTest.class)
+public class DestroyRegionCommandTest {
+
+  @ClassRule
+  public static GfshParserRule parser = new GfshParserRule();
+
+  private DestroyRegionCommand command;
+  private CommandResult result;
+
+  @Before
+  public void before() throws Exception {
+    command = spy(DestroyRegionCommand.class);
+    doReturn(mock(InternalCache.class)).when(command).getCache();
+  }
+
+  @Test
+  public void invalidRegion() throws Exception {
+    result = parser.executeCommandWithInstance(command, "destroy region");
+    assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+    assertThat(result.getContent().toString()).contains("Invalid command");
+
+    result = parser.executeCommandWithInstance(command, "destroy region --name=");
+    assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+    assertThat(result.getContent().toString()).contains("Invalid command");
+
+    result = parser.executeCommandWithInstance(command, "destroy region --name=/");
+    assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+    assertThat(result.getContent().toString()).contains("Invalid command");
+  }
+
+  @Test
+  public void whenNoRegionIsFoundOnAnyMembers() throws Exception {
+    doReturn(Collections.emptySet()).when(command).findMembersForRegion(any(), any());
+    result = parser.executeCommandWithInstance(command, "destroy region --name=test");
+    assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+
+    result = parser.executeCommandWithInstance(command, "destroy region --name=test --if-exists");
+    assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/IndexCommandsIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/IndexCommandsIntegrationTest.java
index 359fc52..48737fb 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/IndexCommandsIntegrationTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/IndexCommandsIntegrationTest.java
@@ -236,8 +236,8 @@ public class IndexCommandsIntegrationTest {
 
     CommandStringBuilder csb = new CommandStringBuilder(CliStrings.DESTROY_INDEX);
     csb.addOption(CliStrings.DESTROY_INDEX__REGION, regionName);
-    gfsh.executeAndVerifyCommand(csb.toString());
-    assertThat(gfsh.getGfshOutput()).contains("Indexes on region : regionA successfully destroyed");
+    gfsh.executeAndVerifyCommand(csb.toString(),
+        "Indexes on region : /regionA successfully destroyed");
   }
 
   @Test
@@ -246,9 +246,7 @@ public class IndexCommandsIntegrationTest {
 
     CommandStringBuilder csb = new CommandStringBuilder(CliStrings.DESTROY_INDEX);
     csb.addOption(CliStrings.GROUP, groupName);
-    gfsh.executeAndVerifyCommand(csb.toString());
-
-    assertThat(gfsh.getGfshOutput()).contains("Indexes successfully destroyed");
+    gfsh.executeAndVerifyCommand(csb.toString(), "Indexes successfully destroyed");
   }
 
   private void createSimpleIndexA() throws Exception {
@@ -256,8 +254,7 @@ public class IndexCommandsIntegrationTest {
     csb.addOption(CliStrings.CREATE_INDEX__NAME, indexName);
     csb.addOption(CliStrings.CREATE_INDEX__EXPRESSION, "key");
     csb.addOption(CliStrings.CREATE_INDEX__REGION, "/" + regionName);
-    gfsh.executeAndVerifyCommand(csb.toString());
-    assertThat(gfsh.getGfshOutput()).contains("Index successfully created");
+    gfsh.executeAndVerifyCommand(csb.toString(), "Index successfully created");
   }
 
   private static Region<?, ?> createPartitionedRegion(String regionName, Cache cache,
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java
index 655eeb8..5a1d7a9 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java
@@ -15,7 +15,7 @@
 package org.apache.geode.management.internal.cli.commands;
 
 import static org.apache.geode.management.internal.cli.commands.DataCommandsUtils.getRegionAssociatedMembers;
-import static org.apache.geode.management.internal.cli.commands.RemoveCommand.*;
+import static org.apache.geode.management.internal.cli.commands.RemoveCommand.REGION_NOT_FOUND;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.Serializable;
@@ -94,8 +94,7 @@ public class RemoveCommandDUnitTest implements Serializable {
   public void removeFromInvalidRegion() throws Exception {
     String command = "remove --all --region=NotAValidRegion";
 
-    gfsh.executeAndVerifyCommandError(command);
-    assertThat(gfsh.getGfshOutput()).contains(String.format(REGION_NOT_FOUND, "NotAValidRegion"));
+    gfsh.executeAndVerifyCommandError(command, String.format(REGION_NOT_FOUND, "/NotAValidRegion"));
   }
 
   @Test
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/converters/RegionPathConverterJUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/converters/RegionPathConverterJUnitTest.java
index ebe6f34..fdfec25 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/converters/RegionPathConverterJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/converters/RegionPathConverterJUnitTest.java
@@ -14,70 +14,66 @@
  */
 package org.apache.geode.management.internal.cli.converters;
 
-import static org.junit.Assert.assertEquals;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.when;
 
 import java.util.Arrays;
-import java.util.Set;
-import java.util.TreeSet;
+import java.util.stream.Collectors;
 
-import org.jmock.Expectations;
-import org.jmock.Mockery;
-import org.jmock.lib.concurrent.Synchroniser;
-import org.jmock.lib.legacy.ClassImposteriser;
-import org.junit.After;
-import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.management.cli.ConverterHint;
 import org.apache.geode.test.junit.categories.UnitTest;
+import org.apache.geode.test.junit.rules.GfshParserRule;
+import org.apache.geode.test.junit.rules.GfshParserRule.CommandCandidate;
 
 @Category(UnitTest.class)
 public class RegionPathConverterJUnitTest {
-
-  private Mockery mockContext;
-
-  @Before
-  public void setup() {
-    mockContext = new Mockery() {
-      {
-        setImposteriser(ClassImposteriser.INSTANCE);
-        setThreadingPolicy(new Synchroniser());
-      }
-    };
-  }
-
-  @After
-  public void tearDown() {
-    mockContext.assertIsSatisfied();
-    mockContext = null;
+  @ClassRule
+  public static GfshParserRule parser = new GfshParserRule();
+  private static RegionPathConverter converter;
+
+  private static String[] allRegionPaths = {"/region1", "/region2", "/rg3"};
+
+  @BeforeClass
+  public static void before() {
+    // this will let the parser use the spied converter instead of creating its own
+    converter = parser.spyConverter(RegionPathConverter.class);
+    when(converter.getAllRegionPaths())
+        .thenReturn(Arrays.stream(allRegionPaths).collect(Collectors.toSet()));
   }
 
-  private RegionPathConverter createMockRegionPathConverter(final String[] allRegionPaths) {
-
-    final RegionPathConverter mockRegionPathConverter =
-        mockContext.mock(RegionPathConverter.class, "RPC");
-    mockContext.checking(new Expectations() {
-      {
-        oneOf(mockRegionPathConverter).getAllRegionPaths();
-        will(returnValue(new TreeSet<String>(Arrays.asList(allRegionPaths))));
-      }
-    });
 
-    return mockRegionPathConverter;
+  @Test
+  public void testSupports() throws Exception {
+    assertThat(converter.supports(String.class, ConverterHint.REGION_PATH)).isTrue();
   }
 
-
   @Test
-  public void testGetAllRegionPaths() throws Exception {
-    String[] allRegionPaths = {"/region1", "/region2", "/rg3"};
-    TreeSet<String> expectedPaths = new TreeSet<String>(Arrays.asList(allRegionPaths));
-
-    final RegionPathConverter mockRegionPathConverter =
-        createMockRegionPathConverter(allRegionPaths);
-
-    Set<String> mocked = mockRegionPathConverter.getAllRegionPaths();
+  public void convert() throws Exception {
+    assertThatThrownBy(() -> converter.convertFromText("/", String.class, ""))
+        .isInstanceOf(IllegalArgumentException.class).hasMessage("invalid region path: /");
 
-    assertEquals("mocked paths don't match expectedPaths.", mocked, expectedPaths);
+    assertThat(converter.convertFromText("region", String.class, "")).isEqualTo("/region");
+    assertThat(converter.convertFromText("/region/t", String.class, "")).isEqualTo("/region/t");
   }
 
+  @Test
+  public void complete() throws Exception {
+    CommandCandidate candidate = parser.complete("destroy region --name=");
+    assertThat(candidate.size()).isEqualTo(allRegionPaths.length);
+    assertThat(candidate.getFirstCandidate()).isEqualTo("destroy region --name=/region1");
+
+    candidate = parser.complete("destroy region --name=/");
+    assertThat(candidate.size()).isEqualTo(allRegionPaths.length);
+    assertThat(candidate.getFirstCandidate()).isEqualTo("destroy region --name=/region1");
+
+    candidate = parser.complete("destroy region --name=/region");
+    assertThat(candidate.size()).isEqualTo(2);
+    assertThat(candidate.getFirstCandidate()).isEqualTo("destroy region --name=/region1");
+  }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshJunitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshJunitTest.java
index bf10904..049ee1d 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshJunitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshJunitTest.java
@@ -17,19 +17,21 @@ package org.apache.geode.management.internal.cli.shell;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import org.apache.geode.management.internal.cli.shell.Gfsh;
-import org.apache.geode.test.junit.categories.UnitTest;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.test.junit.categories.UnitTest;
+
 @Category(UnitTest.class)
 public class GfshJunitTest {
   private String testString;
+  private Gfsh gfsh;
 
   @Before
   public void before() {
     testString = "This is a test string.";
+    gfsh = new Gfsh();
   }
 
   @Test
@@ -44,4 +46,10 @@ public class GfshJunitTest {
         .isEqualTo(Gfsh.LINE_INDENT + Gfsh.LINE_INDENT + testString);
   }
 
+  @Test
+  public void getAppContextPath() throws Exception {
+    assertThat(gfsh.getEnvAppContextPath()).isEqualTo("");
+    gfsh.setEnvProperty(Gfsh.ENV_APP_CONTEXT_PATH, "test");
+    assertThat(gfsh.getEnvAppContextPath()).isEqualTo("test");
+  }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MemberVM.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MemberVM.java
index 81e3561..18c6985 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MemberVM.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MemberVM.java
@@ -113,4 +113,8 @@ public class MemberVM<T extends Member> implements Member {
         return !name.startsWith("locator0view");
       })).forEach(FileUtils::deleteQuietly);
   }
+
+  public static void invokeInEveryMember(SerializableRunnableIF runnableIF, MemberVM... members) {
+    Arrays.stream(members).forEach(member -> member.invoke(runnableIF));
+  }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/junit/rules/GfshShellConnectionRule.java b/geode-core/src/test/java/org/apache/geode/test/junit/rules/GfshShellConnectionRule.java
index 5640fef..a6e24e5 100644
--- a/geode-core/src/test/java/org/apache/geode/test/junit/rules/GfshShellConnectionRule.java
+++ b/geode-core/src/test/java/org/apache/geode/test/junit/rules/GfshShellConnectionRule.java
@@ -245,7 +245,7 @@ public class GfshShellConnectionRule extends DescribedExternalResource {
     return gfsh.outputString;
   }
 
-  public CommandResult executeAndVerifyCommand(String command) {
+  public CommandResult executeAndVerifyCommand(String command, String... expectedOutputs) {
     CommandResult result = null;
     try {
       result = executeCommand(command);
@@ -253,10 +253,13 @@ public class GfshShellConnectionRule extends DescribedExternalResource {
       throw new RuntimeException(e);
     }
     assertThat(result.getStatus()).describedAs(getGfshOutput()).isEqualTo(Result.Status.OK);
+    for (String expectedOutput : expectedOutputs) {
+      assertThat(getGfshOutput()).contains(expectedOutput);
+    }
     return result;
   }
 
-  public CommandResult executeAndVerifyCommandError(String command) {
+  public CommandResult executeAndVerifyCommandError(String command, String... expectedOutputs) {
     CommandResult result = null;
     try {
       result = executeCommand(command);
@@ -264,6 +267,9 @@ public class GfshShellConnectionRule extends DescribedExternalResource {
       throw new RuntimeException(e);
     }
     assertThat(result.getStatus()).describedAs(getGfshOutput()).isEqualTo(Result.Status.ERROR);
+    for (String expectedOutput : expectedOutputs) {
+      assertThat(getGfshOutput()).contains(expectedOutput);
+    }
     return result;
   }
 
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneServiceImpl.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneServiceImpl.java
index 1b125ed..8da8538 100644
--- a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneServiceImpl.java
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneServiceImpl.java
@@ -167,7 +167,7 @@ public class LuceneServiceImpl implements InternalLuceneService {
         case REGION_PATH:
           matcher = Pattern.compile("[aA-zZ0-9-_./]+").matcher(name);
           msg = "Region" + msg + ", underscores, or forward slashes: ";
-          iae = name.startsWith("__") || !matcher.matches();
+          iae = name.startsWith("__") || name.startsWith("/__") || !matcher.matches();
           break;
         case INDEX_NAME:
           matcher = Pattern.compile("[aA-zZ0-9-_.]+").matcher(name);
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommands.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommands.java
index ba296a8..d54fe12 100755
--- a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommands.java
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommands.java
@@ -30,7 +30,6 @@ import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
 import org.apache.geode.SystemFailure;
-import org.apache.geode.cache.Region;
 import org.apache.geode.cache.execute.Execution;
 import org.apache.geode.cache.execute.Function;
 import org.apache.geode.cache.execute.FunctionInvocationTargetException;
@@ -48,7 +47,6 @@ import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.ConverterHint;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.CliUtil;
-import org.apache.geode.management.internal.cli.LogWrapper;
 import org.apache.geode.management.internal.cli.commands.GfshCommand;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
@@ -181,7 +179,8 @@ public class LuceneIndexCommands implements GfshCommand {
           help = LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD_HELP) final String[] fields,
 
       @CliOption(key = LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER,
-          help = LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER_HELP) final String[] analyzers) {
+          help = LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER_HELP) final String[] analyzers)
+      throws CommandResultException {
 
     Result result;
     XmlEntity xmlEntity = null;
@@ -189,45 +188,31 @@ public class LuceneIndexCommands implements GfshCommand {
     // Every lucene index potentially writes to disk.
     getSecurityService().authorize(Resource.CLUSTER, Operation.MANAGE, LucenePermission.TARGET);
 
-    try {
-      final InternalCache cache = getCache();
-
-      // trim fields for any leading trailing spaces.
-      String[] trimmedFields = Arrays.stream(fields).map(String::trim).toArray(String[]::new);
-      LuceneIndexInfo indexInfo =
-          new LuceneIndexInfo(indexName, regionPath, trimmedFields, analyzers);
-
-      final ResultCollector<?, ?> rc =
-          this.executeFunctionOnAllMembers(createIndexFunction, indexInfo);
-      final List<CliFunctionResult> funcResults = (List<CliFunctionResult>) rc.getResult();
-
-      final TabularResultData tabularResult = ResultBuilder.createTabularResultData();
-      for (final CliFunctionResult cliFunctionResult : funcResults) {
-        tabularResult.accumulate("Member", cliFunctionResult.getMemberIdOrName());
-
-        if (cliFunctionResult.isSuccessful()) {
-          tabularResult.accumulate("Status", "Successfully created lucene index");
-          // if (xmlEntity == null) {
-          // xmlEntity = cliFunctionResult.getXmlEntity();
-          // }
-        } else {
-          tabularResult.accumulate("Status", "Failed: " + cliFunctionResult.getMessage());
-        }
+    final InternalCache cache = getCache();
+
+    // trim fields for any leading trailing spaces.
+    String[] trimmedFields = Arrays.stream(fields).map(String::trim).toArray(String[]::new);
+    LuceneIndexInfo indexInfo =
+        new LuceneIndexInfo(indexName, regionPath, trimmedFields, analyzers);
+
+    final ResultCollector<?, ?> rc = executeFunctionOnAllMembers(createIndexFunction, indexInfo);
+    final List<CliFunctionResult> funcResults = (List<CliFunctionResult>) rc.getResult();
+
+    final TabularResultData tabularResult = ResultBuilder.createTabularResultData();
+    for (final CliFunctionResult cliFunctionResult : funcResults) {
+      tabularResult.accumulate("Member", cliFunctionResult.getMemberIdOrName());
+
+      if (cliFunctionResult.isSuccessful()) {
+        tabularResult.accumulate("Status", "Successfully created lucene index");
+        // if (xmlEntity == null) {
+        // xmlEntity = cliFunctionResult.getXmlEntity();
+        // }
+      } else {
+        tabularResult.accumulate("Status", "Failed: " + cliFunctionResult.getMessage());
       }
-      result = ResultBuilder.buildResult(tabularResult);
-    } catch (IllegalArgumentException iae) {
-      LogWrapper.getInstance().info(iae.getMessage());
-      result = ResultBuilder.createUserErrorResult(iae.getMessage());
-    } catch (CommandResultException crex) {
-      result = crex.getResult();
-    } catch (Exception e) {
-      result = ResultBuilder.createGemFireErrorResult(e.getMessage());
     }
-    // TODO - store in cluster config
-    // if (xmlEntity != null) {
-    // result.setCommandPersisted((new SharedConfigurationWriter()).addXmlEntity(xmlEntity,
-    // groups));
-    // }
+    result = ResultBuilder.buildResult(tabularResult);
+
 
     return result;
   }
@@ -337,44 +322,24 @@ public class LuceneIndexCommands implements GfshCommand {
           optionContext = ConverterHint.REGION_PATH,
           help = LuceneCliStrings.LUCENE_DESTROY_INDEX__REGION_HELP) final String regionPath) {
 
-    if (StringUtils.isBlank(regionPath) || regionPath.equals(Region.SEPARATOR)) {
-      return ResultBuilder.createInfoResult(
-          CliStrings.format(LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__REGION_CANNOT_BE_EMPTY));
-    }
-
     if (indexName != null && StringUtils.isEmpty(indexName)) {
       return ResultBuilder.createInfoResult(
           CliStrings.format(LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__INDEX_CANNOT_BE_EMPTY));
     }
 
     getSecurityService().authorize(Resource.CLUSTER, Operation.MANAGE, LucenePermission.TARGET);
-
     Result result;
-    try {
-      List<CliFunctionResult> accumulatedResults = new ArrayList<>();
-      final XmlEntity xmlEntity =
-          executeDestroyIndexFunction(accumulatedResults, indexName, regionPath);
-      result = getDestroyIndexResult(accumulatedResults, indexName, regionPath);
-      if (xmlEntity != null) {
-        persistClusterConfiguration(result, () -> {
-          // Delete the xml entity to remove the index(es) in all groups
-          getSharedConfiguration().deleteXmlEntity(xmlEntity, null);
-        });
-      }
-    } catch (FunctionInvocationTargetException ignore) {
-      result = ResultBuilder.createGemFireErrorResult(CliStrings.format(
-          CliStrings.COULD_NOT_EXECUTE_COMMAND_TRY_AGAIN, LuceneCliStrings.LUCENE_DESTROY_INDEX));
-    } catch (VirtualMachineError e) {
-      SystemFailure.initiateFailure(e);
-      throw e;
-    } catch (IllegalArgumentException e) {
-      result = ResultBuilder.createInfoResult(e.getMessage());
-    } catch (Throwable t) {
-      t.printStackTrace();
-      SystemFailure.checkFailure();
-      getCache().getLogger().warning(LuceneCliStrings.LUCENE_DESTROY_INDEX__EXCEPTION_MESSAGE, t);
-      result = ResultBuilder.createGemFireErrorResult(t.getMessage());
+    List<CliFunctionResult> accumulatedResults = new ArrayList<>();
+    final XmlEntity xmlEntity =
+        executeDestroyIndexFunction(accumulatedResults, indexName, regionPath);
+    result = getDestroyIndexResult(accumulatedResults, indexName, regionPath);
+    if (xmlEntity != null) {
+      persistClusterConfiguration(result, () -> {
+        // Delete the xml entity to remove the index(es) in all groups
+        getSharedConfiguration().deleteXmlEntity(xmlEntity, null);
+      });
     }
+
     return result;
   }
 
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneDestroyIndexFunction.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneDestroyIndexFunction.java
index 7e3d2a6..9803192 100644
--- a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneDestroyIndexFunction.java
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneDestroyIndexFunction.java
@@ -14,8 +14,8 @@
  */
 package org.apache.geode.cache.lucene.internal.cli.functions;
 
-import org.apache.geode.cache.Cache;
-import org.apache.geode.cache.CacheFactory;
+import org.apache.commons.lang.StringUtils;
+
 import org.apache.geode.cache.execute.Function;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.lucene.LuceneService;
@@ -62,7 +62,8 @@ public class LuceneDestroyIndexFunction implements Function, InternalEntity {
   }
 
   protected XmlEntity getXmlEntity(String indexName, String regionPath) {
-    return new XmlEntity(CacheXml.REGION, "name", regionPath, LuceneXmlConstants.PREFIX,
+    String regionName = StringUtils.stripStart(regionPath, "/");
+    return new XmlEntity(CacheXml.REGION, "name", regionName, LuceneXmlConstants.PREFIX,
         LuceneXmlConstants.NAMESPACE, LuceneXmlConstants.INDEX, "name", indexName);
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshJunitTest.java b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/ValidateCommandParametersTest.java
similarity index 50%
copy from geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshJunitTest.java
copy to geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/ValidateCommandParametersTest.java
index bf10904..958c72f 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshJunitTest.java
+++ b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/ValidateCommandParametersTest.java
@@ -13,35 +13,31 @@
  * the License.
  */
 
-package org.apache.geode.management.internal.cli.shell;
+package org.apache.geode.cache.lucene.internal;
 
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-import org.apache.geode.management.internal.cli.shell.Gfsh;
-import org.apache.geode.test.junit.categories.UnitTest;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-@Category(UnitTest.class)
-public class GfshJunitTest {
-  private String testString;
+import org.apache.geode.cache.lucene.internal.LuceneServiceImpl.validateCommandParameters;
+import org.apache.geode.test.junit.categories.UnitTest;
 
-  @Before
-  public void before() {
-    testString = "This is a test string.";
-  }
+@Category(UnitTest.class)
+public class ValidateCommandParametersTest {
 
   @Test
-  public void testWrapTest() {
-    assertThat(Gfsh.wrapText(testString, 0, -1)).isEqualTo(testString);
-    assertThat(Gfsh.wrapText(testString, 0, 0)).isEqualTo(testString);
-    assertThat(Gfsh.wrapText(testString, 0, 1)).isEqualTo(testString);
-    assertThat(Gfsh.wrapText(testString, 0, 10))
-        .isEqualTo("This is a" + Gfsh.LINE_SEPARATOR + "test" + Gfsh.LINE_SEPARATOR + "string.");
-    assertThat(Gfsh.wrapText(testString, 1, 100)).isEqualTo(Gfsh.LINE_INDENT + testString);
-    assertThat(Gfsh.wrapText(testString, 2, 100))
-        .isEqualTo(Gfsh.LINE_INDENT + Gfsh.LINE_INDENT + testString);
+  public void validateRegionName() throws Exception {
+    validateCommandParameters region = validateCommandParameters.REGION_PATH;
+    region.validateName("/test");
+    region.validateName("test");
+    assertThatThrownBy(() -> region.validateName("__#@T"))
+        .isInstanceOf(IllegalArgumentException.class);
+    assertThatThrownBy(() -> region.validateName("/__#@T"))
+        .isInstanceOf(IllegalArgumentException.class);
+    assertThatThrownBy(() -> region.validateName("__"))
+        .isInstanceOf(IllegalArgumentException.class);
+    assertThatThrownBy(() -> region.validateName("/__"))
+        .isInstanceOf(IllegalArgumentException.class);
   }
-
 }
diff --git a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java
index bbe863c..16986be 100755
--- a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java
+++ b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/LuceneIndexCommandsDUnitTest.java
@@ -18,8 +18,8 @@ import static org.apache.geode.cache.lucene.test.LuceneTestUtilities.INDEX_NAME;
 import static org.apache.geode.cache.lucene.test.LuceneTestUtilities.REGION_NAME;
 import static org.apache.geode.test.dunit.Assert.assertArrayEquals;
 import static org.apache.geode.test.dunit.Assert.assertEquals;
-import static org.apache.geode.test.dunit.Assert.assertFalse;
 import static org.apache.geode.test.dunit.Assert.assertTrue;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -98,26 +98,21 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
 
     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"));
+    gfsh.executeAndVerifyCommand(csb.toString(), INDEX_NAME, "Documents");
   }
 
   @Test
   public void listIndexShouldReturnExistingIndexWithoutStats() throws Exception {
     createIndex();
-
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_LIST_INDEX);
-    String resultAsString = executeCommandAndLogResult(csb);
-    assertTrue(resultAsString.contains(INDEX_NAME));
-    assertFalse(resultAsString.contains("Documents"));
+    gfsh.executeAndVerifyCommand(csb.toString(), INDEX_NAME);
+    assertThat(gfsh.getGfshOutput()).doesNotContain("Documents");
   }
 
   @Test
   public void listIndexWhenNoExistingIndexShouldReturnNoIndex() throws Exception {
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_LIST_INDEX);
-    String resultAsString = executeCommandAndLogResult(csb);
-    assertTrue(resultAsString.contains("No lucene indexes found"));
+    gfsh.executeAndVerifyCommand(csb.toString(), "No lucene indexes found");
   }
 
   @Test
@@ -126,7 +121,8 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
 
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_LIST_INDEX);
     csb.addOption(LuceneCliStrings.LUCENE_LIST_INDEX__STATS, "true");
-    TabularResultData data = (TabularResultData) executeCommandAndGetResult(csb).getResultData();
+    TabularResultData data =
+        (TabularResultData) gfsh.executeAndVerifyCommand(csb.toString()).getResultData();
     assertEquals(Collections.singletonList(INDEX_NAME), data.retrieveAllValues("Index Name"));
     assertEquals(Collections.singletonList("Defined"), data.retrieveAllValues("Status"));
   }
@@ -143,7 +139,8 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
 
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_LIST_INDEX);
     csb.addOption(LuceneCliStrings.LUCENE_LIST_INDEX__STATS, "true");
-    TabularResultData data = (TabularResultData) executeCommandAndGetResult(csb).getResultData();
+    TabularResultData data =
+        (TabularResultData) gfsh.executeAndVerifyCommand(csb.toString()).getResultData();
 
     assertEquals(Collections.singletonList(INDEX_NAME), data.retrieveAllValues("Index Name"));
     assertEquals(Collections.singletonList("Initialized"), data.retrieveAllValues("Status"));
@@ -156,16 +153,12 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
 
   @Test
   public void createIndexShouldCreateANewIndex() throws Exception {
-    serverVM.invoke(() -> {
-      getCache();
-    });
-
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_CREATE_INDEX);
     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);
+    gfsh.executeAndVerifyCommand(csb.toString());
 
     serverVM.invoke(() -> {
       LuceneService luceneService = LuceneServiceProvider.get(getCache());
@@ -177,10 +170,6 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
 
   @Test
   public void createIndexWithAnalyzersShouldCreateANewIndex() throws Exception {
-    serverVM.invoke(() -> {
-      getCache();
-    });
-
     List<String> analyzerNames = new ArrayList<>();
     analyzerNames.add(StandardAnalyzer.class.getCanonicalName());
     analyzerNames.add(KeywordAnalyzer.class.getCanonicalName());
@@ -192,7 +181,7 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD, "field1,field2,field3");
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER, String.join(",", analyzerNames));
 
-    String resultAsString = executeCommandAndLogResult(csb);
+    gfsh.executeAndVerifyCommand(csb.toString());
 
     serverVM.invoke(() -> {
       LuceneService luceneService = LuceneServiceProvider.get(getCache());
@@ -207,53 +196,42 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
 
   @Test
   public void createIndexShouldNotAcceptBadIndexOrRegionNames() {
-    serverVM.invoke(() -> {
-      getCache();
-    });
-
+    // CommandStringBuilder csb;
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_CREATE_INDEX);
     csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME, INDEX_NAME);
     csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH, "\'__\'");
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD, "field1,field2,field3");
 
-    String resultAsString = executeCommandAndLogResult(csb);
-    assertTrue(resultAsString.contains(
-        "Region names may only be alphanumeric, must not begin with double-underscores, but can contain hyphens, underscores, or forward slashes:"));
+    gfsh.executeAndVerifyCommand(csb.toString(),
+        "Region names may only be alphanumeric, must not begin with double-underscores, but can contain hyphens, underscores, or forward slashes:");
 
     csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_CREATE_INDEX);
     csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME, INDEX_NAME);
     csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH, "\' @@@*%\'");
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD, "field1,field2,field3");
 
-    resultAsString = executeCommandAndLogResult(csb);
-    assertTrue(resultAsString.contains(
-        "Region names may only be alphanumeric, must not begin with double-underscores, but can contain hyphens, underscores, or forward slashes:"));
+    gfsh.executeAndVerifyCommand(csb.toString(),
+        "Region names may only be alphanumeric, must not begin with double-underscores, but can contain hyphens, underscores, or forward slashes:");
 
     csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_CREATE_INDEX);
     csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME, "\'__\'");
     csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH, REGION_NAME);
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD, "field1,field2,field3");
 
-    resultAsString = executeCommandAndLogResult(csb);
-    assertTrue(resultAsString.contains(
-        "Index names may only be alphanumeric, must not begin with double-underscores, but can contain hyphens or underscores:"));
+    gfsh.executeAndVerifyCommand(csb.toString(),
+        "Index names may only be alphanumeric, must not begin with double-underscores, but can contain hyphens or underscores:");
 
     csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_CREATE_INDEX);
     csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME, "\' @@@*%\'");
     csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH, REGION_NAME);
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD, "field1,field2,field3");
 
-    resultAsString = executeCommandAndLogResult(csb);
-    assertTrue(resultAsString.contains(
-        "Index names may only be alphanumeric, must not begin with double-underscores, but can contain hyphens or underscores:"));
+    gfsh.executeAndVerifyCommand(csb.toString(),
+        "Index names may only be alphanumeric, must not begin with double-underscores, but can contain hyphens or underscores:");
   }
 
   @Test
   public void createIndexShouldTrimAnalyzerNames() throws Exception {
-    serverVM.invoke(() -> {
-      getCache();
-    });
-
     List<String> analyzerNames = new ArrayList<>();
     analyzerNames.add(StandardAnalyzer.class.getCanonicalName());
     analyzerNames.add(KeywordAnalyzer.class.getCanonicalName());
@@ -266,7 +244,7 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER,
         "\"org.apache.lucene.analysis.standard.StandardAnalyzer, org.apache.lucene.analysis.core.KeywordAnalyzer, org.apache.lucene.analysis.standard.StandardAnalyzer\"");
 
-    String resultAsString = executeCommandAndLogResult(csb);
+    gfsh.executeAndVerifyCommand(csb.toString());
 
     serverVM.invoke(() -> {
       LuceneService luceneService = LuceneServiceProvider.get(getCache());
@@ -281,16 +259,12 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
 
   @Test
   public void createIndexWithoutRegionShouldReturnCorrectResults() throws Exception {
-    serverVM.invoke(() -> {
-      getCache();
-    });
-
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_CREATE_INDEX);
     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);
+    gfsh.executeAndVerifyCommand(csb.toString());
 
     serverVM.invoke(() -> {
       LuceneServiceImpl luceneService = (LuceneServiceImpl) LuceneServiceProvider.get(getCache());
@@ -304,10 +278,6 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
   @Test
   public void createIndexWithWhitespaceOrDefaultKeywordAnalyzerShouldUseStandardAnalyzer()
       throws Exception {
-    serverVM.invoke(() -> {
-      getCache();
-    });
-
     // Test whitespace analyzer name
     String analyzerList = StandardAnalyzer.class.getCanonicalName() + ",     ,"
         + KeywordAnalyzer.class.getCanonicalName();
@@ -317,7 +287,7 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD, "field1,field2,field3");
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER, "'" + analyzerList + "'");
 
-    String resultAsString = executeCommandAndLogResult(csb);
+    gfsh.executeAndVerifyCommand(csb.toString());
 
     // Test empty analyzer name
     analyzerList =
@@ -328,7 +298,7 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD, "field1,field2,field3");
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER, analyzerList);
 
-    resultAsString = executeCommandAndLogResult(csb);
+    gfsh.executeAndVerifyCommand(csb.toString());
 
     // Test keyword analyzer name
     analyzerList = StandardAnalyzer.class.getCanonicalName() + ",DEFAULT,"
@@ -339,7 +309,7 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__FIELD, "field1,field2,field3");
     csb.addOption(LuceneCliStrings.LUCENE_CREATE_INDEX__ANALYZER, analyzerList);
 
-    resultAsString = executeCommandAndLogResult(csb);
+    gfsh.executeAndVerifyCommand(csb.toString());
 
     serverVM.invoke(() -> {
       LuceneService luceneService = LuceneServiceProvider.get(getCache());
@@ -386,8 +356,7 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     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));
+    gfsh.executeAndVerifyCommand(csb.toString(), INDEX_NAME);
   }
 
   @Test
@@ -397,9 +366,7 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     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"));
+    gfsh.executeAndVerifyCommand(csb.toString(), "No lucene indexes found");
   }
 
   @Test
@@ -408,8 +375,7 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     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(getRegionNotFoundErrorMessage(REGION_NAME)));
+    gfsh.executeAndVerifyCommand(csb.toString(), REGION_NAME);
   }
 
   @Test
@@ -431,9 +397,9 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     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();
+    TabularResultData data =
+        (TabularResultData) gfsh.executeAndVerifyCommand(csb.toString()).getResultData();
     assertEquals(4, data.retrieveAllValues("key").size());
   }
 
@@ -454,9 +420,9 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH, REGION_NAME);
     csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING, "field1:jon~");
     csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD, "field1");
-    executeCommandAndLogResult(csb);
 
-    TabularResultData data = (TabularResultData) executeCommandAndGetResult(csb).getResultData();
+    TabularResultData data =
+        (TabularResultData) gfsh.executeAndVerifyCommand(csb.toString()).getResultData();
     assertEquals(4, data.retrieveAllValues("key").size());
 
     // confirm the order
@@ -486,10 +452,9 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     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));
+    gfsh.executeAndVerifyCommand(csb.toString(),
+        LuceneCliStrings.LUCENE_SEARCH_INDEX__NO_RESULTS_MESSAGE);
   }
 
   @Test
@@ -512,8 +477,8 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     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();
+    TabularResultData data =
+        (TabularResultData) gfsh.executeAndVerifyCommand(csb.toString()).getResultData();
     assertEquals(2, data.retrieveAllValues("key").size());
   }
 
@@ -536,9 +501,9 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH, REGION_NAME);
     csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING, "QWE");
     csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD, "field2");
-    executeCommandAndLogResult(csb);
 
-    TabularResultData data = (TabularResultData) executeCommandAndGetResult(csb).getResultData();
+    TabularResultData data =
+        (TabularResultData) gfsh.executeAndVerifyCommand(csb.toString()).getResultData();
     assertEquals(1, data.retrieveAllValues("key").size());
   }
 
@@ -552,8 +517,7 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING, "EFG");
     csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD, "field2");
 
-    String resultAsString = executeCommandAndLogResult(csb);
-    assertTrue(resultAsString.contains(getRegionNotFoundErrorMessage(REGION_NAME)));
+    gfsh.executeAndVerifyCommand(csb.toString(), getRegionNotFoundErrorMessage("/region"));
   }
 
   @Test
@@ -597,9 +561,9 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__QUERY_STRING, "value1");
     csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__DEFAULT_FIELD, "field1");
     csb.addOption(LuceneCliStrings.LUCENE_SEARCH_INDEX__KEYSONLY, "true");
-    executeCommandAndLogResult(csb);
 
-    TabularResultData data = (TabularResultData) executeCommandAndGetResult(csb).getResultData();
+    TabularResultData data =
+        (TabularResultData) gfsh.executeAndVerifyCommand(csb.toString()).getResultData();
     assertEquals(4, data.retrieveAllValues("key").size());
   }
 
@@ -611,12 +575,12 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     } else {
       createIndexWithoutRegion();
     }
-    CommandResult result = createAndExecuteDestroyIndexCommand(INDEX_NAME, REGION_NAME);
-    String resultAsString = gfsh.getGfshOutput();
+
     String expectedStatus = CliStrings.format(
         LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__SUCCESSFULLY_DESTROYED_INDEX_0_FROM_REGION_1,
-        new Object[] {INDEX_NAME, REGION_NAME});
-    assertTrue(resultAsString.contains(expectedStatus));
+        new Object[] {"index", "/region"});
+    gfsh.executeAndVerifyCommand("destroy lucene index --name=index --region=region",
+        expectedStatus);
   }
 
   @Test
@@ -627,68 +591,34 @@ public class LuceneIndexCommandsDUnitTest implements Serializable {
     } else {
       createIndexWithoutRegion();
     }
-    CommandResult result = createAndExecuteDestroyIndexCommand(null, REGION_NAME);
-    String resultAsString = gfsh.getGfshOutput();
-    String expectedStatus = CliStrings.format(
-        LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__SUCCESSFULLY_DESTROYED_INDEXES_FROM_REGION_0,
-        new Object[] {REGION_NAME});
-    assertTrue(resultAsString.contains(expectedStatus));
+    gfsh.executeAndVerifyCommand("destroy lucene index --region=region",
+        CliStrings.format(
+            LuceneCliStrings.LUCENE_DESTROY_INDEX__MSG__SUCCESSFULLY_DESTROYED_INDEXES_FROM_REGION_0,
+            new Object[] {"/region"}));
   }
 
   @Test
   public void testDestroyNonExistentSingleIndex() throws Exception {
     serverVM.invoke(() -> createRegion());
-    CommandResult result = createAndExecuteDestroyIndexCommand(INDEX_NAME, REGION_NAME);
-    String resultAsString = gfsh.getGfshOutput();
     String expectedStatus = LocalizedStrings.LuceneService_INDEX_0_NOT_FOUND_IN_REGION_1
         .toLocalizedString(new Object[] {INDEX_NAME, '/' + REGION_NAME});
-    assertTrue(resultAsString.contains(expectedStatus));
+
+    gfsh.executeAndVerifyCommand("destroy lucene index --name=index --region=region",
+        expectedStatus);
   }
 
   @Test
   public void testDestroyNonExistentIndexes() throws Exception {
     serverVM.invoke(() -> createRegion());
-    CommandResult result = createAndExecuteDestroyIndexCommand(null, REGION_NAME);
-    String resultAsString = gfsh.getGfshOutput();
-    String expectedStatus = LocalizedStrings.LuceneService_NO_INDEXES_WERE_FOUND_IN_REGION_0
-        .toLocalizedString(new Object[] {'/' + REGION_NAME});
-    assertTrue(resultAsString.contains(expectedStatus));
-  }
-
-  private CommandResult createAndExecuteDestroyIndexCommand(String indexName, String regionPath)
-      throws Exception {
-    CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_DESTROY_INDEX);
-    if (indexName != null) {
-      csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME, indexName);
-    }
-    csb.addOption(LuceneCliStrings.LUCENE__REGION_PATH, regionPath);
-    return executeCommandAndGetResult(csb);
+    gfsh.executeAndVerifyCommand("destroy lucene index --region=region",
+        LocalizedStrings.LuceneService_NO_INDEXES_WERE_FOUND_IN_REGION_0
+            .toLocalizedString(new Object[] {"/region"}));
   }
 
   private void createRegion() {
     getCache().createRegionFactory(RegionShortcut.PARTITION).create(REGION_NAME);
   }
 
-  private String executeCommandAndLogResult(final CommandStringBuilder csb) {
-    String commandString = csb.toString();
-    writeToLog("Command String :\n ", commandString);
-    CommandResult commandResult = gfsh.executeAndVerifyCommand(commandString);
-    String resultAsString = gfsh.getGfshOutput();
-    writeToLog("Result String :\n ", resultAsString);
-    assertEquals("Command failed\n" + resultAsString, Status.OK, commandResult.getStatus());
-    return resultAsString;
-  }
-
-  private CommandResult executeCommandAndGetResult(final CommandStringBuilder csb) {
-    String commandString = csb.toString();
-    writeToLog("Command String :\n ", commandString);
-    CommandResult commandResult = gfsh.executeAndVerifyCommand(commandString);
-    String resultAsString = gfsh.getGfshOutput();
-    writeToLog("Result String :\n ", resultAsString);
-    assertEquals("Command failed\n" + resultAsString, Status.OK, commandResult.getStatus());
-    return commandResult;
-  }
-
   private void createIndex() {
     serverVM.invoke(() -> {
       LuceneService luceneService =
diff --git a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneDestroyIndexFunctionJUnitTest.java b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneDestroyIndexFunctionJUnitTest.java
index 924a60d..b65c547 100644
--- a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneDestroyIndexFunctionJUnitTest.java
+++ b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/cli/functions/LuceneDestroyIndexFunctionJUnitTest.java
@@ -14,6 +14,22 @@
  */
 package org.apache.geode.cache.lucene.internal.cli.functions;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.ArgumentCaptor;
+
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.ResultSender;
 import org.apache.geode.cache.lucene.internal.InternalLuceneService;
@@ -21,15 +37,9 @@ import org.apache.geode.cache.lucene.internal.LuceneServiceImpl;
 import org.apache.geode.cache.lucene.internal.cli.LuceneDestroyIndexInfo;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.management.internal.cli.functions.CliFunctionResult;
+import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.test.fake.Fakes;
 import org.apache.geode.test.junit.categories.UnitTest;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.mockito.ArgumentCaptor;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.*;
 
 @Category(UnitTest.class)
 public class LuceneDestroyIndexFunctionJUnitTest {
@@ -169,6 +179,15 @@ public class LuceneDestroyIndexFunctionJUnitTest {
     verifyFunctionResult(false);
   }
 
+  @Test
+  public void getXmlEntity() throws Exception {
+    LuceneDestroyIndexFunction function = new LuceneDestroyIndexFunction();
+    XmlEntity entity1 = function.getXmlEntity("index", "/region");
+    XmlEntity entity2 = function.getXmlEntity("index", "region");
+    assertThat(entity1).isEqualTo(entity2);
+    assertThat(entity1.getSearchString()).isEqualTo(entity2.getSearchString());
+  }
+
   private void verifyFunctionResult(boolean result) {
     ArgumentCaptor<CliFunctionResult> resultCaptor =
         ArgumentCaptor.forClass(CliFunctionResult.class);
diff --git a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/configuration/LuceneClusterConfigurationDUnitTest.java b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/configuration/LuceneClusterConfigurationDUnitTest.java
index 2c9ed66..c34e14d 100755
--- a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/configuration/LuceneClusterConfigurationDUnitTest.java
+++ b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/internal/configuration/LuceneClusterConfigurationDUnitTest.java
@@ -17,11 +17,10 @@ package org.apache.geode.cache.lucene.internal.configuration;
 import static org.apache.geode.cache.lucene.test.LuceneTestUtilities.INDEX_NAME;
 import static org.apache.geode.cache.lucene.test.LuceneTestUtilities.REGION_NAME;
 import static org.apache.geode.distributed.ConfigurationProperties.GROUPS;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
 
 import java.util.Arrays;
 import java.util.List;
@@ -48,11 +47,10 @@ import org.apache.geode.management.internal.cli.result.TabularResultData;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
 import org.apache.geode.management.internal.configuration.domain.Configuration;
 import org.apache.geode.test.dunit.SerializableRunnableIF;
-import org.apache.geode.test.junit.rules.GfshShellConnectionRule;
 import org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
-import org.apache.geode.test.junit.rules.Member;
 import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.categories.DistributedTest;
+import org.apache.geode.test.junit.rules.GfshShellConnectionRule;
 
 
 @Category(DistributedTest.class)
@@ -73,7 +71,7 @@ public class LuceneClusterConfigurationDUnitTest {
 
   @Test
   public void indexGetsCreatedUsingClusterConfiguration() throws Exception {
-    Member vm1 = startNodeUsingClusterConfiguration(1);
+    ls.startServerVM(1, locator.getPort());
 
     // Connect Gfsh to locator.
     gfshConnector.connectAndVerify(locator);
@@ -85,7 +83,7 @@ public class LuceneClusterConfigurationDUnitTest {
 
     // Start vm2. This should have lucene index created using cluster
     // configuration.
-    MemberVM vm2 = startNodeUsingClusterConfiguration(2);
+    MemberVM vm2 = ls.startServerVM(2, locator.getPort());
     vm2.invoke(() -> {
       LuceneService luceneService =
           LuceneServiceProvider.get(LocatorServerStartupRule.serverStarter.getCache());
@@ -98,20 +96,19 @@ public class LuceneClusterConfigurationDUnitTest {
 
   @Test
   public void indexWithAnalyzerGetsCreatedUsingClusterConfiguration() throws Exception {
-    startNodeUsingClusterConfiguration(1);
+    ls.startServerVM(1, locator.getPort());
 
     // Connect Gfsh to locator.
     gfshConnector.connectAndVerify(locator);
 
     // Create lucene index.
-    // createLuceneIndexUsingGfsh();
-    createLuceneIndexWithAnalyzerUsingGfsh(false);
+    createLuceneIndexWithAnalyzerUsingGfsh();
 
     createRegionUsingGfsh(REGION_NAME, RegionShortcut.PARTITION, null);
 
     // Start vm2. This should have lucene index created using cluster
     // configuration.
-    MemberVM vm2 = startNodeUsingClusterConfiguration(2);
+    MemberVM vm2 = ls.startServerVM(2, locator.getPort());
     vm2.invoke(() -> {
       LuceneService luceneService =
           LuceneServiceProvider.get(LocatorServerStartupRule.serverStarter.getCache());
@@ -130,7 +127,7 @@ public class LuceneClusterConfigurationDUnitTest {
 
   @Test
   public void verifyClusterConfigurationAfterDestroyIndex() throws Exception {
-    Member vm1 = startNodeUsingClusterConfiguration(1);
+    ls.startServerVM(1, locator.getPort());
 
     // Connect Gfsh to locator.
     gfshConnector.connectAndVerify(locator);
@@ -150,7 +147,7 @@ public class LuceneClusterConfigurationDUnitTest {
 
   @Test
   public void verifyClusterConfigurationAfterDestroyIndexes() throws Exception {
-    Member vm1 = startNodeUsingClusterConfiguration(1);
+    ls.startServerVM(1, locator.getPort());
 
     // Connect Gfsh to locator.
     gfshConnector.connectAndVerify(locator);
@@ -168,13 +165,13 @@ public class LuceneClusterConfigurationDUnitTest {
   @Test
   public void verifyMemberWithGroupStartsAfterAlterRegion() throws Exception {
     // Start a member with no group
-    startNodeUsingClusterConfiguration(1);
+    ls.startServerVM(1, locator.getPort());
 
     // Start a member with group
     String group = "group1";
     Properties properties = new Properties();
     properties.setProperty(GROUPS, group);
-    MemberVM vm2 = startNodeUsingClusterConfiguration(2, properties);
+    MemberVM vm2 = ls.startServerVM(2, properties, locator.getPort());
 
     // Connect Gfsh to locator
     gfshConnector.connectAndVerify(locator);
@@ -194,7 +191,7 @@ public class LuceneClusterConfigurationDUnitTest {
         alterRegionResultDataStatus.get(0));
 
     // Start another member with group
-    startNodeUsingClusterConfiguration(3, properties);
+    ls.startServerVM(3, properties, locator.getPort());
 
     // Verify all members have indexes
     CommandResult listIndexesResult = listIndexesUsingGfsh();
@@ -233,23 +230,15 @@ public class LuceneClusterConfigurationDUnitTest {
           + " xmlns:lucene=\"" + LuceneXmlConstants.NAMESPACE + "\" " + LuceneXmlConstants.NAME
           + "=\"" + INDEX_NAME + "1" + "\">";
       if (verifyIndexesExist) {
-        assertTrue(xmlContent.contains(luceneIndex0Config));
-        assertTrue(xmlContent.contains(luceneIndex1Config));
+        assertThat(xmlContent).contains(luceneIndex0Config);
+        assertThat(xmlContent).contains(luceneIndex1Config);
       } else {
-        assertFalse(xmlContent.contains(luceneIndex0Config));
-        assertFalse(xmlContent.contains(luceneIndex1Config));
+        assertThat(xmlContent).doesNotContain(luceneIndex0Config);
+        assertThat(xmlContent).doesNotContain(luceneIndex1Config);
       }
     };
   }
 
-  private MemberVM startNodeUsingClusterConfiguration(int vmIndex) throws Exception {
-    return startNodeUsingClusterConfiguration(vmIndex, new Properties());
-  }
-
-  private MemberVM startNodeUsingClusterConfiguration(int vmIndex, Properties nodeProperties)
-      throws Exception {
-    return ls.startServerVM(vmIndex, nodeProperties, ls.getMember(0).getPort());
-  }
 
   private void createLuceneIndexUsingGfsh() throws Exception {
     createLuceneIndexUsingGfsh(INDEX_NAME);
@@ -264,7 +253,7 @@ public class LuceneClusterConfigurationDUnitTest {
     gfshConnector.executeAndVerifyCommand(csb.toString());
   }
 
-  private void createLuceneIndexWithAnalyzerUsingGfsh(boolean addGroup) throws Exception {
+  private void createLuceneIndexWithAnalyzerUsingGfsh() throws Exception {
     // Gfsh command to create lucene index.
     CommandStringBuilder csb = new CommandStringBuilder(LuceneCliStrings.LUCENE_CREATE_INDEX);
     csb.addOption(LuceneCliStrings.LUCENE__INDEX_NAME, INDEX_NAME);

-- 
To stop receiving notification emails like this one, please contact
['"commits@geode.apache.org" <commits@geode.apache.org>'].

Mime
View raw message