@Override
  public void run() {
    try {
      installShutdownHook();
      registerConfigurationObservers();
      Threads.setDaemonThreadRunning(new Thread(TraceUtil.tracedRunnable(() -> {
        try {
          int infoPort = putUpJettyServer();
          startActiveMasterManager(infoPort);
        } catch (Throwable t) {
          // Make sure we log the exception.
          String error = "Failed to become Active Master";
          LOG.error(error, t);
          // Abort should have been called already.
          if (!isAborted()) {
            abort(error, t);
          }
        }
      }, "HMaster.becomeActiveMaster")), getName() + ":becomeActiveMaster");
      while (!isStopped() && !isAborted()) {
        sleeper.sleep();
      }
      final Span span = TraceUtil.createSpan("HMaster exiting main loop");
      try (Scope ignored = span.makeCurrent()) {
        stopInfoServer();
        closeClusterConnection();
        stopServiceThreads();
        if (this.rpcServices != null) {
          this.rpcServices.stop();
        }
        closeZooKeeper();
        closeTableDescriptors();
        span.setStatus(StatusCode.OK);
      } finally {
        span.end();
      }
    } finally {
      if (this.clusterSchemaService != null) {
        // If on way out, then we are no longer active master.
        this.clusterSchemaService.stopAsync();
        try {
          this.clusterSchemaService
            .awaitTerminated(getConfiguration().getInt(HBASE_MASTER_WAIT_ON_SERVICE_IN_SECONDS,
              DEFAULT_HBASE_MASTER_WAIT_ON_SERVICE_IN_SECONDS), TimeUnit.SECONDS);
        } catch (TimeoutException te) {
          LOG.warn("Failed shutdown of clusterSchemaService", te);
        }
      }
      this.activeMaster = false;
    }
  }
Protected to have custom implementations in tests override the default ActiveMaster
implementation.
hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java