private boolean isStaleConfiguration(Configuration config) {
    String delimiter = "-";
    String configId = config.getId();

    // Bypasses item of "global" and folders of "version", just check db configurations.
    if (configId == null || configId.equals(Constants.GLOBAL_ID) || !configId.contains(delimiter)) {
      return false;
    }

    if (_serviceInfo.getId().endsWith(Constants.STANDALONE_ID)) {
      if (!configId.equals(_serviceInfo.getId())) {
        return true;
      }
    } else {
      CoordinatorClientInetAddressMap nodeMap = _coordinator.getInetAddessLookupMap();
      int nodeCount = nodeMap.getControllerNodeIPLookupMap().size();

      String nodeIndex = configId.split(delimiter)[1];
      if (Constants.STANDALONE_ID.equalsIgnoreCase(nodeIndex)
          || Integer.parseInt(nodeIndex) > nodeCount) {
        return true;
      }
    }
    return false;
  }
  /** Check offline event info to see if dbsvc/geodbsvc on this node could get started */
  private void checkDBOfflineInfo() {
    Configuration config =
        _coordinator.queryConfiguration(
            _coordinator.getSiteId(), Constants.DB_DOWNTIME_TRACKER_CONFIG, _serviceInfo.getName());
    DbOfflineEventInfo dbOfflineEventInfo = new DbOfflineEventInfo(config);

    String localNodeId = _coordinator.getInetAddessLookupMap().getNodeId();
    Long lastActiveTimestamp = dbOfflineEventInfo.geLastActiveTimestamp(localNodeId);
    long zkTimeStamp =
        (lastActiveTimestamp == null) ? TimeUtils.getCurrentTime() : lastActiveTimestamp;

    File localDbDir = new File(dbDir);
    Date lastModified = getLastModified(localDbDir);
    boolean isDirEmpty = lastModified == null || localDbDir.list().length == 0;
    long localTimeStamp = (isDirEmpty) ? TimeUtils.getCurrentTime() : lastModified.getTime();

    _log.info("Service timestamp in ZK is {}, local file is: {}", zkTimeStamp, localTimeStamp);
    long diffTime = (zkTimeStamp > localTimeStamp) ? (zkTimeStamp - localTimeStamp) : 0;
    if (diffTime >= MAX_SERVICE_OUTAGE_TIME) {
      String errMsg =
          String.format(
              "We detect database files on local disk are more than %s days older "
                  + "than last time it was seen in the cluster. It may bring stale data into the database, "
                  + "so the service cannot continue to boot. It may be the result of a VM snapshot rollback. "
                  + "Please contact with EMC support engineer for solution.",
              diffTime / TimeUtils.DAYS);
      alertLog.error(errMsg);
      throw new IllegalStateException(errMsg);
    }

    Long offlineTime = dbOfflineEventInfo.getOfflineTimeInMS(localNodeId);
    if (!isDirEmpty && offlineTime != null && offlineTime >= MAX_SERVICE_OUTAGE_TIME) {
      String errMsg =
          String.format(
              "This node is offline for more than %s days. It may bring stale data into "
                  + "database, so the service cannot continue to boot. Please poweroff this node and follow our "
                  + "node recovery procedure to recover this node",
              offlineTime / TimeUtils.DAYS);
      alertLog.error(errMsg);
      throw new IllegalStateException(errMsg);
    }
  }
  /**
   * Checks and registers db configuration information, this is one time when cluster is coming up
   * for the first time
   */
  private Configuration checkConfiguration() {
    String configKind = _coordinator.getDbConfigPath(_serviceInfo.getName());
    Configuration config =
        _coordinator.queryConfiguration(_coordinator.getSiteId(), configKind, _serviceInfo.getId());
    if (config == null) {
      // check if it is upgraded from previous version to yoda - configuration may be stored in
      // zk global area /config. Since SeedProvider still need access that, so we remove the config
      // from global in migration callback after migration is done.
      config = _coordinator.queryConfiguration(configKind, _serviceInfo.getId());
      if (config != null) {
        _log.info("Upgrade from pre-yoda release, move dbconfig to new location");
        _coordinator.persistServiceConfiguration(_coordinator.getSiteId(), config);
        return config;
      }

      // this is a new node
      // 1. register its configuration with coordinator
      // 2. assume autobootstrap configuration
      // this means that when a node is added, it take 1/2 of biggest token rage and
      // copies its data over
      ConfigurationImpl cfg = new ConfigurationImpl();
      cfg.setId(_serviceInfo.getId());
      cfg.setKind(configKind);
      cfg.setConfig(DbConfigConstants.NODE_ID, _coordinator.getInetAddessLookupMap().getNodeId());
      cfg.setConfig(DbConfigConstants.AUTOBOOT, Boolean.TRUE.toString());

      // check other existing db nodes
      List<Configuration> configs =
          _coordinator.queryAllConfiguration(_coordinator.getSiteId(), configKind);
      if (configs.isEmpty()) {
        // we are the first node - turn off autobootstrap
        cfg.setConfig(DbConfigConstants.AUTOBOOT, Boolean.FALSE.toString());
      }
      // persist configuration
      _coordinator.persistServiceConfiguration(_coordinator.getSiteId(), cfg);
      config = cfg;
    }
    return config;
  }