You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by bu...@apache.org on 2017/09/11 07:42:55 UTC

[28/50] [abbrv] hbase git commit: HBASE-18621 Refactor ClusterOptions before applying to code base

HBASE-18621 Refactor ClusterOptions before applying to code base

Signed-off-by: Chia-Ping Tsai <ch...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/77ca743d
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/77ca743d
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/77ca743d

Branch: refs/heads/HBASE-18467
Commit: 77ca743d095de11bbe30cdc230d8198f0c3d7d4d
Parents: af21572
Author: Reid Chan <re...@outlook.com>
Authored: Sat Sep 9 03:27:47 2017 +0800
Committer: Chia-Ping Tsai <ch...@gmail.com>
Committed: Sat Sep 9 03:31:28 2017 +0800

----------------------------------------------------------------------
 .../org/apache/hadoop/hbase/ClusterStatus.java  | 236 +++----------------
 .../org/apache/hadoop/hbase/client/Admin.java   |  17 +-
 .../apache/hadoop/hbase/client/AsyncAdmin.java  |   5 +-
 .../hadoop/hbase/client/AsyncHBaseAdmin.java    |  13 +-
 .../apache/hadoop/hbase/client/HBaseAdmin.java  |   7 +-
 .../hadoop/hbase/client/RawAsyncHBaseAdmin.java |   7 +-
 .../hbase/shaded/protobuf/ProtobufUtil.java     | 103 +++++---
 .../hbase/shaded/protobuf/RequestConverter.java |   7 +-
 .../src/main/protobuf/ClusterStatus.proto       |  20 +-
 .../src/main/protobuf/Master.proto              |   2 +-
 .../src/main/protobuf/ClusterStatus.proto       |  20 +-
 .../org/apache/hadoop/hbase/master/HMaster.java |  73 +++---
 .../hadoop/hbase/master/MasterRpcServices.java  |   2 +-
 .../hbase/client/TestClientClusterStatus.java   |  54 ++---
 14 files changed, 208 insertions(+), 358 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterStatus.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterStatus.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterStatus.java
index 0dc4984..d12ad0d 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterStatus.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/ClusterStatus.java
@@ -29,6 +29,8 @@ import org.apache.hadoop.hbase.classification.InterfaceAudience;
 import org.apache.hadoop.hbase.master.RegionState;
 import org.apache.hadoop.io.VersionedWritable;
 
+import com.google.common.base.Objects;
+
 
 /**
  * Status information on the HBase cluster.
@@ -47,26 +49,23 @@ import org.apache.hadoop.io.VersionedWritable;
  * <li>Regions in transition at master</li>
  * <li>The unique cluster ID</li>
  * </ul>
- * <tt>{@link Options}</tt> provides a way to filter out infos which unwanted.
- * The following codes will retrieve all the cluster information.
+ * <tt>{@link Option}</tt> provides a way to get desired ClusterStatus information.
+ * The following codes will get all the cluster information.
  * <pre>
  * {@code
  * // Original version still works
  * Admin admin = connection.getAdmin();
  * ClusterStatus status = admin.getClusterStatus();
  * // or below, a new version which has the same effects
- * ClusterStatus status = admin.getClusterStatus(Options.defaultOptions());
+ * ClusterStatus status = admin.getClusterStatus(EnumSet.allOf(Option.class));
  * }
  * </pre>
- * If information about dead servers and master coprocessors are unwanted,
+ * If information about live servers is the only wanted.
  * then codes in the following way:
  * <pre>
  * {@code
  * Admin admin = connection.getAdmin();
- * ClusterStatus status = admin.getClusterStatus(
- *                                Options.defaultOptions()
- *                                       .excludeDeadServers()
- *                                       .excludeMasterCoprocessors());
+ * ClusterStatus status = admin.getClusterStatus(EnumSet.of(Option.LIVE_SERVERS));
  * }
  * </pre>
  */
@@ -208,23 +207,23 @@ public class ClusterStatus extends VersionedWritable {
     if (!(o instanceof ClusterStatus)) {
       return false;
     }
-    return (getVersion() == ((ClusterStatus)o).getVersion()) &&
-      getHBaseVersion().equals(((ClusterStatus)o).getHBaseVersion()) &&
-      this.liveServers.equals(((ClusterStatus)o).liveServers) &&
-      this.deadServers.containsAll(((ClusterStatus)o).deadServers) &&
-      Arrays.equals(this.masterCoprocessors,
-                    ((ClusterStatus)o).masterCoprocessors) &&
-      this.master.equals(((ClusterStatus)o).master) &&
-      this.backupMasters.containsAll(((ClusterStatus)o).backupMasters);
+    ClusterStatus other = (ClusterStatus) o;
+    //TODO Override the equals() methods in ServerLoad.
+    return (getVersion() == other.getVersion()) &&
+      Objects.equal(getHBaseVersion(), other.getHBaseVersion()) &&
+      Objects.equal(this.liveServers, other.liveServers) &&
+      getDeadServerNames().containsAll(other.getDeadServerNames()) &&
+      Arrays.equals(getMasterCoprocessors(), other.getMasterCoprocessors()) &&
+      Objects.equal(getMaster(), other.getMaster()) &&
+      getBackupMasters().containsAll(other.getBackupMasters());
   }
 
   /**
    * @see java.lang.Object#hashCode()
    */
   public int hashCode() {
-    return VERSION + hbaseVersion.hashCode() + this.liveServers.hashCode() +
-      this.deadServers.hashCode() + this.master.hashCode() +
-      this.backupMasters.hashCode();
+    return VERSION + Objects.hashCode(hbaseVersion, liveServers, deadServers,
+      master, backupMasters);
   }
 
   /** @return the object version number */
@@ -436,194 +435,17 @@ public class ClusterStatus extends VersionedWritable {
   }
 
   /**
-   * Options provides a way to filter out unwanted information.
-   * For compatibility, default options includes all the information about a ClusterStatus.
-   * To filter out unwanted information, use the specific excludeXXX() method.
+   * Kinds of ClusterStatus
    */
-  public static class Options {
-    private boolean includeHBaseVersion = true;
-    private boolean includeLiveServers = true;
-    private boolean includeDeadServers = true;
-    private boolean includeMaster = true;
-    private boolean includeBackupMasters = true;
-    private boolean includeRegionState = true;
-    private boolean includeClusterId = true;
-    private boolean includeMasterCoprocessors = true;
-    private boolean includeBalancerOn = true;
-
-    private Options() {}
-
-    /**
-     * Include all information about a ClusterStatus.
-     */
-    public static Options getDefaultOptions() {
-      return new Options();
-    }
-
-    /**
-     * Filter out hbase verision.
-     */
-    public Options excludeHBaseVersion() {
-      includeHBaseVersion = false;
-      return this;
-    }
-
-    /**
-     * Filter out live servers.
-     */
-    public Options excludeLiveServers() {
-      includeLiveServers = false;
-      return this;
-    }
-
-    /**
-     * Filter out dead servers info.
-     */
-    public Options excludeDeadServers() {
-      includeDeadServers = false;
-      return this;
-    }
-
-    /**
-     * Filter out master info.
-     */
-    public Options excludeMaster() {
-      includeMaster = false;
-      return this;
-    }
-
-    /**
-     * Filter out backup masters info.
-     */
-    public Options excludeBackupMasters() {
-      includeBackupMasters = false;
-      return this;
-    }
-
-    /**
-     * Filter out region state.
-     */
-    public Options excludeRegionState() {
-      includeRegionState = false;
-      return this;
-    }
-
-    /**
-     * Filter out cluster id.
-     */
-    public Options excludeClusterId() {
-      includeClusterId = false;
-      return this;
-    }
-
-    /**
-     * Filter out master's coprocessors info.
-     */
-    public Options excludeMasterCoprocessors() {
-      includeMasterCoprocessors = false;
-      return this;
-    }
-
-    /**
-     * Filter out balancer on info.
-     */
-    public Options excludeBalancerOn() {
-      includeBalancerOn = false;
-      return this;
-    }
-
-    /**
-     * Include hbase version info.
-     */
-    public boolean includeHBaseVersion() {
-      return includeHBaseVersion;
-    }
-
-    /**
-     * Include live servers info.
-     */
-    public boolean includeLiveServers() {
-      return includeLiveServers;
-    }
-
-    /**
-     * Include dead servers info.
-     */
-    public boolean includeDeadServers() {
-      return includeDeadServers;
-    }
-
-    /**
-     * Include master info.
-     */
-    public boolean includeMaster() {
-      return includeMaster;
-    }
-
-    /**
-     * Include backup masters info.
-     */
-    public boolean includeBackupMasters() {
-      return includeBackupMasters;
-    }
-
-    /**
-     * Include region states info.
-     */
-    public boolean includeRegionState() {
-      return includeRegionState;
-    }
-
-    /**
-     * Include cluster id info.
-     */
-    public boolean includeClusterId() {
-      return includeClusterId;
-    }
-
-    /**
-     * Include master's coprocessors.
-     */
-    public boolean includeMasterCoprocessors() {
-      return includeMasterCoprocessors;
-    }
-
-    /**
-     * Include balancer on info.
-     */
-    public boolean includeBalancerOn() {
-      return includeBalancerOn;
-    }
-
-    /**
-     * For an options reusable convenience, reset options to default.
-     */
-    public Options reset() {
-      includeHBaseVersion = true;
-      includeLiveServers = true;
-      includeDeadServers = true;
-      includeMaster = true;
-      includeBackupMasters = true;
-      includeRegionState = true;
-      includeClusterId = true;
-      includeMasterCoprocessors = true;
-      includeBalancerOn = true;
-      return this;
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder builder = new StringBuilder("ClusterStatus info: [");
-      builder.append("include hbase version: " + includeHBaseVersion + ", ");
-      builder.append("include cluster id: " + includeClusterId + ", ");
-      builder.append("include master info: " + includeMaster + ", ");
-      builder.append("include backup masters info: " + includeBackupMasters + ", ");
-      builder.append("include live servers info: " + includeLiveServers + ", ");
-      builder.append("include dead servers info: " + includeDeadServers + ", ");
-      builder.append("include masters coprocessors: " + includeMasterCoprocessors + ", ");
-      builder.append("include region state: " + includeRegionState + ", ");
-      builder.append("include balancer on: " + includeBalancerOn + "]");
-      return builder.toString();
-    }
+  public enum Option {
+    HBASE_VERSION, /** status about hbase version */
+    CLUSTER_ID, /** status about cluster id */
+    BALANCER_ON, /** status about balancer is on or not */
+    LIVE_SERVERS, /** status about live region servers */
+    DEAD_SERVERS, /** status about dead region servers */
+    MASTER, /** status about master */
+    BACKUP_MASTERS, /** status about backup masters */
+    MASTER_COPROCESSORS, /** status about master coprocessors */
+    REGIONS_IN_TRANSITION; /** status about regions in transition */
   }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java
index 26384c9..9f2084c 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java
@@ -22,6 +22,7 @@ import java.io.Closeable;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -31,7 +32,7 @@ import java.util.regex.Pattern;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.Abortable;
 import org.apache.hadoop.hbase.ClusterStatus;
-import org.apache.hadoop.hbase.ClusterStatus.Options;
+import org.apache.hadoop.hbase.ClusterStatus.Option;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.NamespaceDescriptor;
@@ -1231,17 +1232,27 @@ public interface Admin extends Abortable, Closeable {
   void stopRegionServer(final String hostnamePort) throws IOException;
 
   /**
+   * Get whole cluster status, containing status about:
+   * <pre>
+   * hbase version
+   * cluster id
+   * primary/backup master(s)
+   * master's coprocessors
+   * live/dead regionservers
+   * balancer
+   * regions in transition
+   * </pre>
    * @return cluster status
    * @throws IOException if a remote or network exception occurs
    */
   ClusterStatus getClusterStatus() throws IOException;
 
   /**
-   * Get cluster status with options to filter out unwanted status.
+   * Get cluster status with a set of {@link Option} to get desired status.
    * @return cluster status
    * @throws IOException if a remote or network exception occurs
    */
-  ClusterStatus getClusterStatus(Options options) throws IOException;
+  ClusterStatus getClusterStatus(EnumSet<Option> options) throws IOException;
 
   /**
    * Get {@link RegionLoad} of all regions hosted on a regionserver.

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java
index 923a573..995a18f 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java
@@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.client;
 
 import java.util.List;
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
@@ -27,7 +28,7 @@ import java.util.function.Function;
 import java.util.regex.Pattern;
 
 import org.apache.hadoop.hbase.ClusterStatus;
-import org.apache.hadoop.hbase.ClusterStatus.Options;
+import org.apache.hadoop.hbase.ClusterStatus.Option;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.RegionLoad;
 import org.apache.hadoop.hbase.ServerName;
@@ -838,7 +839,7 @@ public interface AsyncAdmin {
   /**
    * @return cluster status wrapped by {@link CompletableFuture}
    */
-  CompletableFuture<ClusterStatus> getClusterStatus(Options options);
+  CompletableFuture<ClusterStatus> getClusterStatus(EnumSet<Option> options);
 
   /**
    * @return current master server name wrapped by {@link CompletableFuture}

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java
index b0b6ba6..e8e8c95 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java
@@ -18,6 +18,7 @@
 package org.apache.hadoop.hbase.client;
 
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -26,17 +27,11 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutorService;
 import java.util.function.Function;
 import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import org.apache.hadoop.hbase.shaded.com.google.common.annotations.VisibleForTesting;
-
-import org.apache.hadoop.hbase.shaded.io.netty.util.Timeout;
-import org.apache.hadoop.hbase.shaded.io.netty.util.TimerTask;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.ClusterStatus;
-import org.apache.hadoop.hbase.ClusterStatus.Options;
+import org.apache.hadoop.hbase.ClusterStatus.Option;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.RegionLoad;
 import org.apache.hadoop.hbase.ServerName;
@@ -493,11 +488,11 @@ public class AsyncHBaseAdmin implements AsyncAdmin {
 
   @Override
   public CompletableFuture<ClusterStatus> getClusterStatus() {
-    return getClusterStatus(Options.getDefaultOptions());
+    return getClusterStatus(EnumSet.allOf(Option.class));
   }
 
   @Override
-  public CompletableFuture<ClusterStatus> getClusterStatus(Options options) {
+  public CompletableFuture<ClusterStatus> getClusterStatus(EnumSet<Option> options) {
     return wrap(rawAdmin.getClusterStatus(options));
   }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
index 5866439..5803408 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
@@ -24,6 +24,7 @@ import java.io.InterruptedIOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -45,7 +46,7 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.Abortable;
 import org.apache.hadoop.hbase.ClusterStatus;
-import org.apache.hadoop.hbase.ClusterStatus.Options;
+import org.apache.hadoop.hbase.ClusterStatus.Option;
 import org.apache.hadoop.hbase.CompoundConfiguration;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
 import org.apache.hadoop.hbase.HBaseConfiguration;
@@ -2038,11 +2039,11 @@ public class HBaseAdmin implements Admin {
 
   @Override
   public ClusterStatus getClusterStatus() throws IOException {
-    return getClusterStatus(Options.getDefaultOptions());
+    return getClusterStatus(EnumSet.allOf(Option.class));
   }
 
   @Override
-  public ClusterStatus getClusterStatus(Options options) throws IOException {
+  public ClusterStatus getClusterStatus(EnumSet<Option> options) throws IOException {
     return executeCallable(new MasterCallable<ClusterStatus>(getConnection(),
         this.rpcControllerFactory) {
       @Override

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java
index 47ca32f..9e6f106 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -44,7 +45,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.AsyncMetaTableAccessor;
 import org.apache.hadoop.hbase.ClusterStatus;
-import org.apache.hadoop.hbase.ClusterStatus.Options;
+import org.apache.hadoop.hbase.ClusterStatus.Option;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.HRegionLocation;
@@ -2430,11 +2431,11 @@ public class RawAsyncHBaseAdmin implements AsyncAdmin {
 
   @Override
   public CompletableFuture<ClusterStatus> getClusterStatus() {
-    return getClusterStatus(Options.getDefaultOptions());
+    return getClusterStatus(EnumSet.allOf(Option.class));
   }
 
   @Override
-  public CompletableFuture<ClusterStatus> getClusterStatus(Options options) {
+  public CompletableFuture<ClusterStatus>getClusterStatus(EnumSet<Option> options) {
     return this
         .<ClusterStatus> newMasterCaller()
         .action(

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java
index 71cd674..b4f23ff 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java
@@ -25,6 +25,7 @@ import java.lang.reflect.Method;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -48,6 +49,7 @@ import org.apache.hadoop.hbase.CellScanner;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.ClusterId;
 import org.apache.hadoop.hbase.ClusterStatus;
+import org.apache.hadoop.hbase.ClusterStatus.Option;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
 import org.apache.hadoop.hbase.ExtendedCellBuilder;
 import org.apache.hadoop.hbase.ExtendedCellBuilderFactory;
@@ -3001,42 +3003,71 @@ public final class ProtobufUtil {
   }
 
   /**
-   * Convert proto ClusterStatus.Options to ClusterStatusProtos.Options
-   * @param opt
-   * @return proto ClusterStatus.Options
-   */
-  public static ClusterStatus.Options toOptions (ClusterStatusProtos.Options opt) {
-    ClusterStatus.Options option = ClusterStatus.Options.getDefaultOptions();
-    if (!opt.getIncludeHbaseVersion()) option.excludeHBaseVersion();
-    if (!opt.getIncludeLiveServers()) option.excludeLiveServers();
-    if (!opt.getIncludeDeadServers()) option.excludeDeadServers();
-    if (!opt.getIncludeRegionsState()) option.excludeRegionState();
-    if (!opt.getIncludeClusterId()) option.excludeClusterId();
-    if (!opt.getIncludeMasterCoprocessors()) option.excludeMasterCoprocessors();
-    if (!opt.getIncludeMaster()) option.excludeMaster();
-    if (!opt.getIncludeBackupMasters()) option.excludeBackupMasters();
-    if (!opt.getIncludeBalancerOn()) option.excludeBalancerOn();
-    return option;
-  }
-
-  /**
-   * Convert ClusterStatus.Options to proto ClusterStatusProtos.Options
-   * @param opt
-   * @return ClusterStatus.Options
-   */
-  public static ClusterStatusProtos.Options toOptions(ClusterStatus.Options opt) {
-    ClusterStatusProtos.Options.Builder option =
-        ClusterStatusProtos.Options.newBuilder();
-    option.setIncludeHbaseVersion(opt.includeHBaseVersion())
-          .setIncludeLiveServers(opt.includeLiveServers())
-          .setIncludeDeadServers(opt.includeDeadServers())
-          .setIncludeRegionsState(opt.includeRegionState())
-          .setIncludeClusterId(opt.includeClusterId())
-          .setIncludeMasterCoprocessors(opt.includeMasterCoprocessors())
-          .setIncludeMaster(opt.includeMaster())
-          .setIncludeBackupMasters(opt.includeBackupMasters())
-          .setIncludeBalancerOn(opt.includeBalancerOn());
-    return option.build();
+   * Convert ClusterStatusProtos.Option to ClusterStatus.Option
+   * @param option a ClusterStatusProtos.Option
+   * @return converted ClusterStatus.Option
+   */
+  public static ClusterStatus.Option toOption(ClusterStatusProtos.Option option) {
+    switch (option) {
+      case HBASE_VERSION: return ClusterStatus.Option.HBASE_VERSION;
+      case LIVE_SERVERS: return ClusterStatus.Option.LIVE_SERVERS;
+      case DEAD_SERVERS: return ClusterStatus.Option.DEAD_SERVERS;
+      case REGIONS_IN_TRANSITION: return ClusterStatus.Option.REGIONS_IN_TRANSITION;
+      case CLUSTER_ID: return ClusterStatus.Option.CLUSTER_ID;
+      case MASTER_COPROCESSORS: return ClusterStatus.Option.MASTER_COPROCESSORS;
+      case MASTER: return ClusterStatus.Option.MASTER;
+      case BACKUP_MASTERS: return ClusterStatus.Option.BACKUP_MASTERS;
+      case BALANCER_ON: return ClusterStatus.Option.BALANCER_ON;
+      // should not reach here
+      default: throw new IllegalArgumentException("Invalid option: " + option);
+    }
+  }
+
+  /**
+   * Convert ClusterStatus.Option to ClusterStatusProtos.Option
+   * @param option a ClusterStatus.Option
+   * @return converted ClusterStatusProtos.Option
+   */
+  public static ClusterStatusProtos.Option toOption(ClusterStatus.Option option) {
+    switch (option) {
+      case HBASE_VERSION: return ClusterStatusProtos.Option.HBASE_VERSION;
+      case LIVE_SERVERS: return ClusterStatusProtos.Option.LIVE_SERVERS;
+      case DEAD_SERVERS: return ClusterStatusProtos.Option.DEAD_SERVERS;
+      case REGIONS_IN_TRANSITION: return ClusterStatusProtos.Option.REGIONS_IN_TRANSITION;
+      case CLUSTER_ID: return ClusterStatusProtos.Option.CLUSTER_ID;
+      case MASTER_COPROCESSORS: return ClusterStatusProtos.Option.MASTER_COPROCESSORS;
+      case MASTER: return ClusterStatusProtos.Option.MASTER;
+      case BACKUP_MASTERS: return ClusterStatusProtos.Option.BACKUP_MASTERS;
+      case BALANCER_ON: return ClusterStatusProtos.Option.BALANCER_ON;
+      // should not reach here
+      default: throw new IllegalArgumentException("Invalid option: " + option);
+    }
+  }
+
+  /**
+   * Convert a list of ClusterStatusProtos.Option to an enum set of ClusterStatus.Option
+   * @param options
+   * @return an enum set of ClusterStatus.Option
+   */
+  public static EnumSet<Option> toOptions(List<ClusterStatusProtos.Option> options) {
+    EnumSet<Option> result = EnumSet.noneOf(Option.class);
+    for (ClusterStatusProtos.Option opt : options) {
+      result.add(toOption(opt));
+    }
+    return result;
+  }
+
+  /**
+   * Convert an enum set of ClusterStatus.Option to a list of ClusterStatusProtos.Option
+   * @param options
+   * @return a list of ClusterStatusProtos.Option
+   */
+  public static List<ClusterStatusProtos.Option> toOptions(EnumSet<Option> options) {
+    List<ClusterStatusProtos.Option> result = new ArrayList<>(options.size());
+    for (ClusterStatus.Option opt : options) {
+      result.add(toOption(opt));
+    }
+    return result;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java
index e620a91..00f051b 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java
@@ -20,13 +20,14 @@ package org.apache.hadoop.hbase.shaded.protobuf;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.regex.Pattern;
 
 import org.apache.hadoop.hbase.CellScannable;
-import org.apache.hadoop.hbase.ClusterStatus.Options;
+import org.apache.hadoop.hbase.ClusterStatus.Option;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
@@ -1516,9 +1517,9 @@ public final class RequestConverter {
    *
    * @return A GetClusterStatusRequest
    */
-  public static GetClusterStatusRequest buildGetClusterStatusRequest(Options opt) {
+  public static GetClusterStatusRequest buildGetClusterStatusRequest(EnumSet<Option> options) {
     return GetClusterStatusRequest.newBuilder()
-                                  .setClusterOptions(ProtobufUtil.toOptions(opt))
+                                  .addAllOptions(ProtobufUtil.toOptions(options))
                                   .build();
   }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-protocol-shaded/src/main/protobuf/ClusterStatus.proto
----------------------------------------------------------------------
diff --git a/hbase-protocol-shaded/src/main/protobuf/ClusterStatus.proto b/hbase-protocol-shaded/src/main/protobuf/ClusterStatus.proto
index 51489b2..52fcc3e 100644
--- a/hbase-protocol-shaded/src/main/protobuf/ClusterStatus.proto
+++ b/hbase-protocol-shaded/src/main/protobuf/ClusterStatus.proto
@@ -226,14 +226,14 @@ message ClusterStatus {
   optional bool balancer_on = 9;
 }
 
-message Options {
-  optional bool include_hbase_version = 1 [default = true];
-  optional bool include_live_servers = 2 [default = true];
-  optional bool include_dead_servers = 3 [default = true];
-  optional bool include_regions_state = 4 [default = true];
-  optional bool include_cluster_id = 5 [default = true];
-  optional bool include_master_coprocessors = 6 [default = true];
-  optional bool include_master = 7 [default = true];
-  optional bool include_backup_masters = 8 [default = true];
-  optional bool include_balancer_on = 9 [default = true];
+enum Option {
+  HBASE_VERSION = 0;
+  CLUSTER_ID = 1;
+  LIVE_SERVERS = 2;
+  DEAD_SERVERS = 3;
+  MASTER = 4;
+  BACKUP_MASTERS = 5;
+  MASTER_COPROCESSORS = 6;
+  REGIONS_IN_TRANSITION = 7;
+  BALANCER_ON = 8;
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-protocol-shaded/src/main/protobuf/Master.proto
----------------------------------------------------------------------
diff --git a/hbase-protocol-shaded/src/main/protobuf/Master.proto b/hbase-protocol-shaded/src/main/protobuf/Master.proto
index 2c1694e..44a6a76 100644
--- a/hbase-protocol-shaded/src/main/protobuf/Master.proto
+++ b/hbase-protocol-shaded/src/main/protobuf/Master.proto
@@ -485,7 +485,7 @@ message GetTableStateResponse {
 }
 
 message GetClusterStatusRequest {
-  required Options cluster_options = 1;
+  repeated Option options = 1;
 }
 
 message GetClusterStatusResponse {

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-protocol/src/main/protobuf/ClusterStatus.proto
----------------------------------------------------------------------
diff --git a/hbase-protocol/src/main/protobuf/ClusterStatus.proto b/hbase-protocol/src/main/protobuf/ClusterStatus.proto
index 1bf128c..b172db5 100644
--- a/hbase-protocol/src/main/protobuf/ClusterStatus.proto
+++ b/hbase-protocol/src/main/protobuf/ClusterStatus.proto
@@ -226,14 +226,14 @@ message ClusterStatus {
   optional bool balancer_on = 9;
 }
 
-message Options {
-  optional bool include_hbase_version = 1 [default = true];
-  optional bool include_live_servers = 2 [default = true];
-  optional bool include_dead_servers = 3 [default = true];
-  optional bool include_regions_state = 4 [default = true];
-  optional bool include_cluster_id = 5 [default = true];
-  optional bool include_master_coprocessors = 6 [default = true];
-  optional bool include_master = 7 [default = true];
-  optional bool include_backup_masters = 8 [default = true];
-  optional bool include_balancer_on = 9 [default = true];
+enum Option {
+  HBASE_VERSION = 0;
+  CLUSTER_ID = 1;
+  LIVE_SERVERS = 2;
+  DEAD_SERVERS = 3;
+  MASTER = 4;
+  BACKUP_MASTERS = 5;
+  MASTER_COPROCESSORS = 6;
+  REGIONS_IN_TRANSITION = 7;
+  BALANCER_ON = 8;
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
index 0c79c58..87594a5 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
@@ -29,6 +29,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -56,7 +57,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.ClusterStatus;
-import org.apache.hadoop.hbase.ClusterStatus.Options;
+import org.apache.hadoop.hbase.ClusterStatus.Option;
 import org.apache.hadoop.hbase.CoordinatedStateException;
 import org.apache.hadoop.hbase.CoordinatedStateManager;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
@@ -2457,43 +2458,51 @@ public class HMaster extends HRegionServer implements MasterServices {
    * @return cluster status
    */
   public ClusterStatus getClusterStatus() throws InterruptedIOException {
-    return getClusterStatus(Options.getDefaultOptions());
+    return getClusterStatus(EnumSet.allOf(Option.class));
   }
 
   /**
    * @return cluster status
    */
-  public ClusterStatus getClusterStatus(Options options) throws InterruptedIOException {
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Retrieving cluster status info. " + options);
-    }
+  public ClusterStatus getClusterStatus(EnumSet<Option> options) throws InterruptedIOException {
     ClusterStatus.Builder builder = ClusterStatus.newBuilder();
-    if (options.includeHBaseVersion()) {
-      builder.setHBaseVersion(VersionInfo.getVersion());
-    }
-    if (options.includeClusterId()) {
-      builder.setClusterId(getClusterId());
-    }
-    if (options.includeLiveServers() && serverManager != null) {
-      builder.setLiveServers(serverManager.getOnlineServers());
-    }
-    if (options.includeDeadServers() && serverManager != null) {
-      builder.setDeadServers(serverManager.getDeadServers().copyServerNames());
-    }
-    if (options.includeMaster()) {
-      builder.setMaster(getServerName());
-    }
-    if (options.includeBackupMasters()) {
-      builder.setBackupMasters(getBackupMasters());
-    }
-    if (options.includeRegionState() && assignmentManager != null) {
-      builder.setRegionState(assignmentManager.getRegionStates().getRegionsStateInTransition());
-    }
-    if (options.includeMasterCoprocessors() && cpHost != null) {
-      builder.setMasterCoprocessors(getMasterCoprocessors());
-    }
-    if (options.includeBalancerOn() && loadBalancerTracker != null) {
-      builder.setBalancerOn(loadBalancerTracker.isBalancerOn());
+    for (Option opt : options) {
+      switch (opt) {
+        case HBASE_VERSION: builder.setHBaseVersion(VersionInfo.getVersion()); break;
+        case CLUSTER_ID: builder.setClusterId(getClusterId()); break;
+        case MASTER: builder.setMaster(getServerName()); break;
+        case BACKUP_MASTERS: builder.setBackupMasters(getBackupMasters()); break;
+        case LIVE_SERVERS: {
+          if (serverManager != null) {
+            builder.setLiveServers(serverManager.getOnlineServers());
+          }
+          break;
+        }
+        case DEAD_SERVERS: {
+          if (serverManager != null) {
+            builder.setDeadServers(serverManager.getDeadServers().copyServerNames());
+          }
+          break;
+        }
+        case MASTER_COPROCESSORS: {
+          if (cpHost != null) {
+            builder.setMasterCoprocessors(getMasterCoprocessors());
+          }
+          break;
+        }
+        case REGIONS_IN_TRANSITION: {
+          if (assignmentManager != null) {
+            builder.setRegionState(assignmentManager.getRegionStates().getRegionsStateInTransition());
+          }
+          break;
+        }
+        case BALANCER_ON: {
+          if (loadBalancerTracker != null) {
+            builder.setBalancerOn(loadBalancerTracker.isBalancerOn());
+          }
+          break;
+        }
+      }
     }
     return builder.build();
   }

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
index 971fa3b..47523a3 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
@@ -870,7 +870,7 @@ public class MasterRpcServices extends RSRpcServices
     try {
       master.checkInitialized();
       response.setClusterStatus(ProtobufUtil.convert(
-        master.getClusterStatus(ProtobufUtil.toOptions(req.getClusterOptions()))));
+        master.getClusterStatus(ProtobufUtil.toOptions(req.getOptionsList()))));
     } catch (IOException e) {
       throw new ServiceException(e);
     }

http://git-wip-us.apache.org/repos/asf/hbase/blob/77ca743d/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientClusterStatus.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientClusterStatus.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientClusterStatus.java
index 484ee06..2f03310 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientClusterStatus.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientClusterStatus.java
@@ -17,18 +17,18 @@
  */
 package org.apache.hadoop.hbase.client;
 
+import java.util.EnumSet;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.ClusterStatus;
 import org.apache.hadoop.hbase.HBaseConfiguration;
-import org.apache.hadoop.hbase.ClusterStatus.Options;
+import org.apache.hadoop.hbase.ClusterStatus.Option;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.MiniHBaseCluster;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.master.HMaster;
-import org.apache.hadoop.hbase.master.LoadBalancer;
 import org.apache.hadoop.hbase.regionserver.HRegionServer;
 import org.apache.hadoop.hbase.security.User;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
@@ -73,7 +73,7 @@ public class TestClientClusterStatus {
   @Test
   public void testDefaults() throws Exception {
     ClusterStatus origin = ADMIN.getClusterStatus();
-    ClusterStatus defaults = ADMIN.getClusterStatus(Options.getDefaultOptions());
+    ClusterStatus defaults = ADMIN.getClusterStatus(EnumSet.allOf(Option.class));
     Assert.assertEquals(origin.getHBaseVersion(), defaults.getHBaseVersion());
     Assert.assertEquals(origin.getClusterId(), defaults.getClusterId());
     Assert.assertTrue(origin.getAverageLoad() == defaults.getAverageLoad());
@@ -84,18 +84,8 @@ public class TestClientClusterStatus {
   }
 
   @Test
-  public void testExclude() throws Exception {
-    ClusterStatus.Options options = Options.getDefaultOptions();
-    // Only retrieve master's coprocessors which are null in this test env.
-    options.excludeHBaseVersion()
-           .excludeBackupMasters()
-           .excludeBalancerOn()
-           .excludeClusterId()
-           .excludeLiveServers()
-           .excludeDeadServers()
-           .excludeMaster()
-           .excludeRegionState();
-    ClusterStatus status = ADMIN.getClusterStatus(options);
+  public void testNone() throws Exception {
+    ClusterStatus status = ADMIN.getClusterStatus(EnumSet.noneOf(Option.class));
     // Other cluster status info should be either null or empty.
     Assert.assertTrue(status.getMasterCoprocessors().length == 0);
     Assert.assertNull(status.getHBaseVersion());
@@ -106,6 +96,11 @@ public class TestClientClusterStatus {
     Assert.assertTrue(status.getDeadServerNames().isEmpty());
     Assert.assertNull(status.getMaster());
     Assert.assertTrue(status.getBackupMasters().isEmpty());
+    // No npe thrown is expected
+    Assert.assertNotNull(status.hashCode());
+    ClusterStatus nullEqualsCheck =
+        ADMIN.getClusterStatus(EnumSet.noneOf(Option.class));
+    Assert.assertNotNull(status.equals(nullEqualsCheck));
   }
 
   @Test
@@ -117,7 +112,7 @@ public class TestClientClusterStatus {
     CompletableFuture<ClusterStatus> originFuture =
         asyncAdmin.getClusterStatus();
     CompletableFuture<ClusterStatus> defaultsFuture =
-        asyncAdmin.getClusterStatus(Options.getDefaultOptions());
+        asyncAdmin.getClusterStatus(EnumSet.allOf(Option.class));
     ClusterStatus origin = originFuture.get();
     ClusterStatus defaults = defaultsFuture.get();
     Assert.assertEquals(origin.getHBaseVersion(), defaults.getHBaseVersion());
@@ -143,14 +138,7 @@ public class TestClientClusterStatus {
       }
     }
     // Retrieve live servers and dead servers info.
-    ClusterStatus.Options options = Options.getDefaultOptions();
-    options.excludeHBaseVersion()
-           .excludeBackupMasters()
-           .excludeBalancerOn()
-           .excludeClusterId()
-           .excludeMaster()
-           .excludeMasterCoprocessors()
-           .excludeRegionState();
+    EnumSet<Option> options = EnumSet.of(Option.LIVE_SERVERS, Option.DEAD_SERVERS);
     ClusterStatus status = ADMIN.getClusterStatus(options);
     Assert.assertNotNull(status);
     Assert.assertNotNull(status.getServers());
@@ -187,14 +175,7 @@ public class TestClientClusterStatus {
     Assert.assertEquals(1, numActive);
     Assert.assertEquals(MASTERS, masterThreads.size());
     // Retrieve master and backup masters infos only.
-    ClusterStatus.Options options = Options.getDefaultOptions();
-    options.excludeHBaseVersion()
-           .excludeBalancerOn()
-           .excludeClusterId()
-           .excludeLiveServers()
-           .excludeDeadServers()
-           .excludeMasterCoprocessors()
-           .excludeRegionState();
+    EnumSet<Option> options = EnumSet.of(Option.MASTER, Option.BACKUP_MASTERS);
     ClusterStatus status = ADMIN.getClusterStatus(options);
     Assert.assertTrue(status.getMaster().equals(activeName));
     Assert.assertEquals(MASTERS - 1, status.getBackupMastersSize());
@@ -202,12 +183,9 @@ public class TestClientClusterStatus {
 
   @Test
   public void testOtherStatusInfos() throws Exception {
-    ClusterStatus.Options options = Options.getDefaultOptions();
-    options.excludeMaster()
-           .excludeBackupMasters()
-           .excludeRegionState()
-           .excludeLiveServers()
-           .excludeBackupMasters();
+    EnumSet<Option> options =
+        EnumSet.of(Option.MASTER_COPROCESSORS, Option.HBASE_VERSION,
+                   Option.CLUSTER_ID, Option.BALANCER_ON);
     ClusterStatus status = ADMIN.getClusterStatus(options);
     Assert.assertTrue(status.getMasterCoprocessors().length == 0);
     Assert.assertNotNull(status.getHBaseVersion());