public static void main(String[] args) throws Exception {
    VerifiableProperties verifiableProperties = ToolUtils.getVerifiableProperties(args);
    SafeServerShutdownToolConfig config = new SafeServerShutdownToolConfig(verifiableProperties);
    ClusterMapConfig clusterMapConfig = new ClusterMapConfig(verifiableProperties);
    try (ClusterMap clusterMap = ((ClusterAgentsFactory) Utils.getObj(clusterMapConfig.clusterMapClusterAgentsFactory,
        clusterMapConfig, config.hardwareLayoutFilePath, config.partitionLayoutFilePath)).getClusterMap()) {
      SSLFactory sslFactory = !clusterMapConfig.clusterMapSslEnabledDatacenters.isEmpty() ? SSLFactory.getNewInstance(
          new SSLConfig(verifiableProperties)) : null;
      try (ServerAdminTool serverAdminTool = new ServerAdminTool(clusterMap, sslFactory, verifiableProperties)) {
        DataNodeId dataNodeId = clusterMap.getDataNodeId(config.hostname, config.port);
        if (dataNodeId == null) {
          throw new IllegalArgumentException(
              "Could not find a data node corresponding to " + config.hostname + ":" + config.port);
        }
        SafeServerShutdownTool safeServerShutdownTool =
            new SafeServerShutdownTool(serverAdminTool, SystemTime.getInstance());
        int exitStatus =
            safeServerShutdownTool.prepareServerForShutdown(dataNodeId, config.logGrowthPauseLagThresholdBytes,
                config.numReplicasCaughtUpPerPartition, config.timeoutSecs, config.checkRepeatDelaySecs) ? 0 : 1;
        System.exit(exitStatus);
      }
    }
  }
Constructs the configs associated with the tool.
@param verifiableProperties the props to use to load the config.
ambry-tools/src/main/java/com/github/ambry/tools/admin/SafeServerShutdownTool.java