You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2020/10/02 19:28:53 UTC

[geode] 07/19: GEODE-7667: Add a 'clear' gfsh command for PR and RR clear (#4818)

This is an automated email from the ASF dual-hosted git repository.

jinmeiliao pushed a commit to branch feature/GEODE-7665
in repository https://gitbox.apache.org/repos/asf/geode.git

commit af79a1be8db757c4347f140d5f5af805af4f8360
Author: BenjaminPerryRoss <39...@users.noreply.github.com>
AuthorDate: Tue May 5 11:40:34 2020 -0700

    GEODE-7667: Add a 'clear' gfsh command for PR and RR clear (#4818)
    
    * Added clear command and modified remove functionality to clear PR
    
    Authored-by: Benjamin Ross <br...@pivotal.io>
---
 .../geode/management/internal/i18n/CliStrings.java |  14 ++-
 .../cli/commands/ClearCommandDUnitTest.java        | 120 +++++++++++++++++++++
 .../cli/commands/RemoveCommandDUnitTest.java       |  13 ++-
 .../{RemoveCommand.java => ClearCommand.java}      |  53 ++++-----
 .../cli/commands/CommandAvailabilityIndicator.java |   1 +
 .../internal/cli/commands/RemoveCommand.java       |   9 +-
 .../internal/cli/domain/DataCommandResult.java     |  12 +++
 .../cli/functions/DataCommandFunction.java         |  23 ++--
 .../internal/cli/commands/ClearCommandTest.java    | 115 ++++++++++++++++++++
 9 files changed, 309 insertions(+), 51 deletions(-)

diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/i18n/CliStrings.java b/geode-core/src/main/java/org/apache/geode/management/internal/i18n/CliStrings.java
index c354d030..6df013e 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/i18n/CliStrings.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/i18n/CliStrings.java
@@ -811,6 +811,14 @@ public class CliStrings {
   public static final String CLEAR_DEFINED_INDEX__SUCCESS__MSG =
       "Index definitions successfully cleared";
 
+  /* clear region */
+  public static final String CLEAR_REGION = "clear region";
+  public static final String CLEAR_REGION_HELP =
+      "Clears/Removes all keys from the specified region.";
+  public static final String CLEAR_REGION_REGION_NAME = "name";
+  public static final String CLEAR_REGION_REGION_NAME_HELP = "Region to clear keys from.";
+  public static final String CLEAR_REGION_CLEARED_ALL_KEYS = "Cleared all keys in the region";
+
   /* create region */
   public static final String CREATE_REGION = "create region";
   public static final String CREATE_REGION__HELP =
@@ -1930,9 +1938,9 @@ public class CliStrings {
   public static final String REMOVE__MSG__KEY_EMPTY = "Key is Null";
   public static final String REMOVE__MSG__REGION_NOT_FOUND = "Region <{0}> Not Found";
   public static final String REMOVE__MSG__KEY_NOT_FOUND_REGION = "Key is not present in the region";
-  public static final String REMOVE__MSG__CLEARED_ALL_CLEARS = "Cleared all keys in the region";
-  public static final String REMOVE__MSG__CLEARALL_NOT_SUPPORTED_FOR_PARTITIONREGION =
-      "Option --" + REMOVE__ALL + " is not supported on partitioned region";
+  public static final String REMOVE__MSG__CLEARALL_DEPRECATION_WARNING =
+      "Warning: The --all option for the 'remove' command is deprecated. Please"
+          + " use the 'clear' command instead.";
 
   /* resume gateway-sender */
   public static final String RESUME_GATEWAYSENDER = "resume gateway-sender";
diff --git a/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/ClearCommandDUnitTest.java b/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/ClearCommandDUnitTest.java
new file mode 100644
index 0000000..e51fc0f
--- /dev/null
+++ b/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/ClearCommandDUnitTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.apache.geode.management.internal.cli.commands.RemoveCommand.REGION_NOT_FOUND;
+import static org.apache.geode.management.internal.i18n.CliStrings.CLEAR_REGION_CLEARED_ALL_KEYS;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.cache.Region;
+import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
+import org.apache.geode.management.internal.i18n.CliStrings;
+import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.junit.rules.GfshCommandRule;
+import org.apache.geode.test.junit.rules.VMProvider;
+
+@RunWith(JUnitParamsRunner.class)
+public class ClearCommandDUnitTest {
+  private static final String REPLICATE_REGION_NAME = "replicateRegion";
+  private static final String PARTITIONED_REGION_NAME = "partitionedRegion";
+  private static final String EMPTY_STRING = "";
+  private static final int NUM_ENTRIES = 200;
+
+  @Rule
+  public ClusterStartupRule clusterStartupRule = new ClusterStartupRule();
+
+  @Rule
+  public GfshCommandRule gfsh = new GfshCommandRule();
+
+  private MemberVM locator;
+  private MemberVM server1;
+  private MemberVM server2;
+
+  @Before
+  public void setup() throws Exception {
+    locator = clusterStartupRule.startLocatorVM(0);
+    server1 = clusterStartupRule.startServerVM(1, locator.getPort());
+    server2 = clusterStartupRule.startServerVM(2, locator.getPort());
+
+    gfsh.connectAndVerify(locator);
+    gfsh.executeAndAssertThat("create region --name=" + REPLICATE_REGION_NAME + " --type=REPLICATE")
+        .statusIsSuccess();
+    gfsh.executeAndAssertThat(
+        "create region --name=" + PARTITIONED_REGION_NAME + " --type=PARTITION").statusIsSuccess();
+
+    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + REPLICATE_REGION_NAME, 2);
+    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + PARTITIONED_REGION_NAME, 2);
+
+    VMProvider.invokeInEveryMember(ClearCommandDUnitTest::populateTestRegions, server1, server2);
+  }
+
+  private static void populateTestRegions() {
+    Cache cache = CacheFactory.getAnyInstance();
+
+    Region<String, String> replicateRegion = cache.getRegion(REPLICATE_REGION_NAME);
+    replicateRegion.put(EMPTY_STRING, "valueForEmptyKey");
+    for (int i = 0; i < NUM_ENTRIES; i++) {
+      replicateRegion.put("key" + i, "value" + i);
+    }
+
+    Region<String, String> partitionedRegion = cache.getRegion(PARTITIONED_REGION_NAME);
+    replicateRegion.put(EMPTY_STRING, "valueForEmptyKey");
+    for (int i = 0; i < NUM_ENTRIES; i++) {
+      partitionedRegion.put("key" + i, "value" + i);
+    }
+  }
+
+  @Test
+  public void clearFailsWhenRegionIsNotFound() {
+    String invalidRegionName = "NotAValidRegion";
+    String command = new CommandStringBuilder(CliStrings.CLEAR_REGION)
+        .addOption(CliStrings.CLEAR_REGION_REGION_NAME, invalidRegionName).getCommandString();
+    gfsh.executeAndAssertThat(command).statusIsError()
+        .containsOutput(String.format(REGION_NOT_FOUND, "/" + invalidRegionName));
+  }
+
+  @Test
+  @Parameters({REPLICATE_REGION_NAME, PARTITIONED_REGION_NAME})
+  public void clearSucceedsWithValidRegion(String regionName) {
+    String command = new CommandStringBuilder(CliStrings.CLEAR_REGION)
+        .addOption(CliStrings.CLEAR_REGION_REGION_NAME, regionName).getCommandString();
+
+    gfsh.executeAndAssertThat(command).statusIsSuccess();
+
+    assertThat(gfsh.getGfshOutput()).contains(CLEAR_REGION_CLEARED_ALL_KEYS);
+
+    server1.invoke(() -> verifyAllKeysAreRemoved(regionName));
+    server2.invoke(() -> verifyAllKeysAreRemoved(regionName));
+  }
+
+  private static void verifyAllKeysAreRemoved(String regionName) {
+    Region region = getRegion(regionName);
+    assertThat(region.size()).isEqualTo(0);
+  }
+
+  private static Region getRegion(String regionName) {
+    return CacheFactory.getAnyInstance().getRegion(regionName);
+  }
+}
diff --git a/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java b/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java
index 92a65ec..2a88d64 100644
--- a/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java
+++ b/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java
@@ -16,6 +16,7 @@ package org.apache.geode.management.internal.cli.commands;
 
 import static org.apache.geode.cache.Region.SEPARATOR;
 import static org.apache.geode.management.internal.cli.commands.RemoveCommand.REGION_NOT_FOUND;
+import static org.apache.geode.management.internal.i18n.CliStrings.CLEAR_REGION_CLEARED_ALL_KEYS;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import org.junit.Before;
@@ -25,6 +26,7 @@ import org.junit.Test;
 import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.cache.Region;
+import org.apache.geode.management.internal.i18n.CliStrings;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
@@ -128,7 +130,8 @@ public class RemoveCommandDUnitTest {
     gfsh.executeAndAssertThat("list regions").statusIsSuccess();
     gfsh.executeAndAssertThat(command).statusIsSuccess();
 
-    assertThat(gfsh.getGfshOutput()).contains("Cleared all keys in the region");
+    assertThat(gfsh.getGfshOutput()).contains(CLEAR_REGION_CLEARED_ALL_KEYS)
+        .contains(CliStrings.REMOVE__MSG__CLEARALL_DEPRECATION_WARNING);
 
     server1.invoke(() -> verifyAllKeysAreRemoved(REPLICATE_REGION_NAME));
     server2.invoke(() -> verifyAllKeysAreRemoved(REPLICATE_REGION_NAME));
@@ -139,11 +142,13 @@ public class RemoveCommandDUnitTest {
   public void removeAllFromPartitionedRegion() {
     String command = "remove --all --region=" + PARTITIONED_REGION_NAME;
 
-    // Maybe this should return an "error" status, but the current behavior is status "OK"
     gfsh.executeAndAssertThat(command).statusIsSuccess();
 
-    assertThat(gfsh.getGfshOutput())
-        .contains("Option --all is not supported on partitioned region");
+    assertThat(gfsh.getGfshOutput()).contains(CLEAR_REGION_CLEARED_ALL_KEYS)
+        .contains(CliStrings.REMOVE__MSG__CLEARALL_DEPRECATION_WARNING);;
+
+    server1.invoke(() -> verifyAllKeysAreRemoved(PARTITIONED_REGION_NAME));
+    server2.invoke(() -> verifyAllKeysAreRemoved(PARTITIONED_REGION_NAME));
   }
 
   /**
diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/ClearCommand.java
similarity index 63%
copy from geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
copy to geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/ClearCommand.java
index c15f01f..75ac720 100644
--- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
+++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/ClearCommand.java
@@ -38,59 +38,52 @@ import org.apache.geode.management.internal.i18n.CliStrings;
 import org.apache.geode.security.ResourcePermission.Operation;
 import org.apache.geode.security.ResourcePermission.Resource;
 
-public class RemoveCommand extends GfshCommand {
+public class ClearCommand extends GfshCommand {
   public static final String REGION_NOT_FOUND = "Region <%s> not found in any of the members";
 
   @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_DATA, CliStrings.TOPIC_GEODE_REGION})
-  @CliCommand(value = {CliStrings.REMOVE}, help = CliStrings.REMOVE__HELP)
-  public ResultModel remove(
-      @CliOption(key = {CliStrings.REMOVE__KEY}, help = CliStrings.REMOVE__KEY__HELP,
-          specifiedDefaultValue = "") String key,
-      @CliOption(key = {CliStrings.REMOVE__REGION}, mandatory = true,
-          help = CliStrings.REMOVE__REGION__HELP,
-          optionContext = ConverterHint.REGION_PATH) String regionPath,
-      @CliOption(key = CliStrings.REMOVE__ALL, help = CliStrings.REMOVE__ALL__HELP,
-          specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") boolean removeAllKeys,
-      @CliOption(key = {CliStrings.REMOVE__KEYCLASS},
-          help = CliStrings.REMOVE__KEYCLASS__HELP) String keyClass) {
-    Cache cache = getCache();
+  @CliCommand(value = {CliStrings.CLEAR_REGION}, help = CliStrings.CLEAR_REGION_HELP)
+  public ResultModel clear(
+      @CliOption(key = {CliStrings.CLEAR_REGION_REGION_NAME}, mandatory = true,
+          help = CliStrings.CLEAR_REGION_REGION_NAME_HELP,
+          optionContext = ConverterHint.REGION_PATH) String regionPath) {
 
-    if (!removeAllKeys && (key == null)) {
-      return new ResultModel().createError(CliStrings.REMOVE__MSG__KEY_EMPTY);
-    }
+    Cache cache = getCache();
 
-    if (removeAllKeys) {
-      authorize(Resource.DATA, Operation.WRITE, regionPath);
-    } else {
-      authorize(Resource.DATA, Operation.WRITE, regionPath, key);
-    }
+    authorize(Resource.DATA, Operation.WRITE, regionPath);
 
-    key = DataCommandsUtils.makeBrokenJsonCompliant(key);
 
     Region region = cache.getRegion(regionPath);
-    DataCommandFunction removefn = new DataCommandFunction();
+    DataCommandFunction clearfn = createCommandFunction();
     DataCommandResult dataResult;
     if (region == null) {
       Set<DistributedMember> memberList = findAnyMembersForRegion(regionPath);
 
       if (CollectionUtils.isEmpty(memberList)) {
-        return new ResultModel().createError(String.format(REGION_NOT_FOUND, regionPath));
+        return ResultModel.createError(String.format(REGION_NOT_FOUND, regionPath));
       }
 
       DataCommandRequest request = new DataCommandRequest();
       request.setCommand(CliStrings.REMOVE);
-      request.setKey(key);
-      request.setKeyClass(keyClass);
-      request.setRemoveAllKeys(removeAllKeys ? "ALL" : null);
+      request.setRemoveAllKeys("ALL");
       request.setRegionName(regionPath);
-      dataResult = callFunctionForRegion(request, removefn, memberList);
+      dataResult = callFunctionForRegion(request, clearfn, memberList);
     } else {
-      dataResult = removefn.remove(key, keyClass, regionPath, removeAllKeys ? "ALL" : null,
+      dataResult = clearfn.remove(null, null, regionPath, "ALL",
           (InternalCache) cache);
     }
 
-    dataResult.setKeyClass(keyClass);
+    dataResult.setKeyClass(null);
 
     return dataResult.toResultModel();
   }
+
+  DataCommandResult callFunctionForRegion(DataCommandRequest request, DataCommandFunction clearfn,
+      Set<DistributedMember> memberList) {
+    return DataCommandsUtils.callFunctionForRegion(request, clearfn, memberList);
+  }
+
+  DataCommandFunction createCommandFunction() {
+    return new DataCommandFunction();
+  }
 }
diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CommandAvailabilityIndicator.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CommandAvailabilityIndicator.java
index ae0b7c4..50f811d 100644
--- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CommandAvailabilityIndicator.java
+++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CommandAvailabilityIndicator.java
@@ -26,6 +26,7 @@ public class CommandAvailabilityIndicator extends GfshCommand {
       CliStrings.DESCRIBE_CONFIG, CliStrings.EXPORT_CONFIG, CliStrings.ALTER_RUNTIME_CONFIG,
       CliStrings.ALTER_REGION, CliStrings.CREATE_REGION, CliStrings.DESTROY_REGION,
       CliStrings.REBALANCE, CliStrings.GET, CliStrings.PUT, CliStrings.REMOVE,
+      CliStrings.CLEAR_REGION,
       CliStrings.LOCATE_ENTRY, CliStrings.QUERY, CliStrings.IMPORT_DATA, CliStrings.EXPORT_DATA,
       CliStrings.DEPLOY, CliStrings.UNDEPLOY, CliStrings.LIST_DEPLOYED,
       CliStrings.BACKUP_DISK_STORE, CliStrings.COMPACT_DISK_STORE, CliStrings.DESCRIBE_DISK_STORE,
diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
index c15f01f..062428d 100644
--- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
+++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
@@ -90,7 +90,14 @@ public class RemoveCommand extends GfshCommand {
     }
 
     dataResult.setKeyClass(keyClass);
+    ResultModel result;
 
-    return dataResult.toResultModel();
+    if (removeAllKeys) {
+      result = dataResult.toResultModel(CliStrings.REMOVE__MSG__CLEARALL_DEPRECATION_WARNING);
+    } else {
+      result = dataResult.toResultModel();
+    }
+
+    return result;
   }
 }
diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/DataCommandResult.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/DataCommandResult.java
index 3f00a95..6bc91cb 100644
--- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/DataCommandResult.java
+++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/DataCommandResult.java
@@ -33,6 +33,7 @@ import org.apache.geode.cache.query.internal.Undefined;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.GfshParser;
 import org.apache.geode.management.internal.cli.result.model.DataResultModel;
+import org.apache.geode.management.internal.cli.result.model.InfoResultModel;
 import org.apache.geode.management.internal.cli.result.model.ResultModel;
 import org.apache.geode.management.internal.cli.result.model.TabularResultModel;
 import org.apache.geode.management.internal.i18n.CliStrings;
@@ -49,6 +50,7 @@ public class DataCommandResult implements Serializable {
 
   public static final Logger logger = LogManager.getLogger();
   public static final String DATA_INFO_SECTION = "data-info";
+  public static final String WARNING_INFO_SECTION = "header-info";
   public static final String QUERY_SECTION = "query";
   public static final String LOCATION_SECTION = "location";
   private String command;
@@ -372,6 +374,10 @@ public class DataCommandResult implements Serializable {
   }
 
   public ResultModel toResultModel() {
+    return toResultModel("");
+  }
+
+  public ResultModel toResultModel(String warningMessage) {
     if (StringUtils.isEmpty(keyClass)) {
       keyClass = "java.lang.String";
     }
@@ -381,6 +387,12 @@ public class DataCommandResult implements Serializable {
     }
 
     ResultModel result = new ResultModel();
+
+    if (warningMessage != null && !warningMessage.isEmpty()) {
+      InfoResultModel info = result.addInfo(WARNING_INFO_SECTION);
+      info.addLine(warningMessage);
+    }
+
     DataResultModel data = result.addData(DATA_INFO_SECTION);
 
     if (errorString != null) {
diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/DataCommandFunction.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/DataCommandFunction.java
index 17cf20f..44c84b5 100644
--- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/DataCommandFunction.java
+++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/DataCommandFunction.java
@@ -29,7 +29,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.Logger;
 
-import org.apache.geode.cache.DataPolicy;
 import org.apache.geode.cache.Region;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.partition.PartitionRegionHelper;
@@ -315,22 +314,20 @@ public class DataCommandFunction implements InternalFunction<DataCommandRequest>
               CliStrings.REMOVE__MSG__KEY_NOT_FOUND_REGION, false);
         }
       } else {
-        DataPolicy policy = region.getAttributes().getDataPolicy();
-        if (!policy.withPartitioning()) {
-          region.clear();
-          if (logger.isDebugEnabled()) {
-            logger.debug("Cleared all keys in the region - {}", regionName);
-          }
-          return DataCommandResult.createRemoveInfoResult(key, null, null,
-              CliStrings.format(CliStrings.REMOVE__MSG__CLEARED_ALL_CLEARS, regionName), true);
-        } else {
-          return DataCommandResult.createRemoveInfoResult(key, null, null,
-              CliStrings.REMOVE__MSG__CLEARALL_NOT_SUPPORTED_FOR_PARTITIONREGION, false);
-        }
+        return clear(region, regionName);
       }
     }
   }
 
+  public DataCommandResult clear(Region region, String regionName) {
+    region.clear();
+    if (logger.isDebugEnabled()) {
+      logger.debug("Cleared all keys in the region - {}", regionName);
+    }
+    return DataCommandResult.createRemoveInfoResult(null, null, null,
+        CliStrings.format(CliStrings.CLEAR_REGION_CLEARED_ALL_KEYS, regionName), true);
+  }
+
   @SuppressWarnings({"rawtypes"})
   public DataCommandResult get(Object principal, String key, String keyClass, String valueClass,
       String regionName, Boolean loadOnCacheMiss, InternalCache cache) {
diff --git a/geode-gfsh/src/test/java/org/apache/geode/management/internal/cli/commands/ClearCommandTest.java b/geode-gfsh/src/test/java/org/apache/geode/management/internal/cli/commands/ClearCommandTest.java
new file mode 100644
index 0000000..a716ef5
--- /dev/null
+++ b/geode-gfsh/src/test/java/org/apache/geode/management/internal/cli/commands/ClearCommandTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.apache.geode.management.internal.cli.commands.ClearCommand.REGION_NOT_FOUND;
+import static org.apache.geode.management.internal.i18n.CliStrings.CLEAR_REGION;
+import static org.apache.geode.management.internal.i18n.CliStrings.CLEAR_REGION_REGION_NAME;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.management.internal.cli.domain.DataCommandResult;
+import org.apache.geode.management.internal.cli.functions.DataCommandFunction;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
+import org.apache.geode.test.junit.rules.GfshParserRule;
+
+public class ClearCommandTest {
+
+  @ClassRule
+  public static GfshParserRule gfsh = new GfshParserRule();
+
+  static final String regionName = "regionName";
+  static final String success = "SUCCESS";
+
+  InternalCache cache;
+  ClearCommand command;
+  Region<Object, Object> region;
+  Set<DistributedMember> membersList;
+  DistributedMember member;
+  DataCommandResult dataResult;
+
+  @SuppressWarnings("unchecked")
+  @Before
+  public void setup() {
+    cache = mock(InternalCache.class);
+    command = spy(new ClearCommand());
+    region = mock(Region.class);
+    dataResult = mock(DataCommandResult.class);
+
+    membersList = new HashSet<>();
+    membersList.add(member);
+
+    doNothing().when(command).authorize(any(), any(), anyString());
+    doReturn(cache).when(command).getCache();
+    doReturn(membersList).when(command).findAnyMembersForRegion(anyString());
+
+    ResultModel result = ResultModel.createInfo(success);
+    doReturn(result).when(dataResult).toResultModel();
+  }
+
+  @Test
+  public void commandReturnsErrorIfRegionIsNotFound() {
+    membersList.clear();
+
+    gfsh.executeAndAssertThat(command,
+        CLEAR_REGION + " --" + CLEAR_REGION_REGION_NAME + "=/" + regionName)
+        .statusIsError().containsOutput(String.format(REGION_NOT_FOUND, "/" + regionName));
+  }
+
+  @Test
+  public void commandReturnsSuccessfullyIfRegionIsFoundOnServersButNotLocator() {
+    doReturn(dataResult).when(command).callFunctionForRegion(any(), any(), any());
+
+    gfsh.executeAndAssertThat(command,
+        CLEAR_REGION + " --" + CLEAR_REGION_REGION_NAME + "=/" + regionName)
+        .statusIsSuccess().containsOutput(success);
+
+    verify(command).callFunctionForRegion(any(), any(), any());
+  }
+
+  @Test
+  public void commandReturnsSuccessfullyIfRegionIsFoundOnLocator() {
+    DataCommandFunction dataCommandFunction = mock(DataCommandFunction.class);
+    doReturn(dataCommandFunction).when(command).createCommandFunction();
+    when(cache.getRegion("/" + regionName)).thenReturn(region);
+
+    doReturn(dataResult).when(dataCommandFunction)
+        .remove(null, null, "/" + regionName, "ALL", cache);
+
+    gfsh.executeAndAssertThat(command,
+        CLEAR_REGION + " --" + CLEAR_REGION_REGION_NAME + "=/" + regionName)
+        .statusIsSuccess().containsOutput(success);
+
+    verify(dataCommandFunction).remove(null, null, "/" + regionName,
+        "ALL", cache);
+  }
+}