Collection<Account> fetchAccountMetadata() {
    long startTimeMs = System.currentTimeMillis();
    logger.trace("Start reading ZNRecord from path={}", znRecordPath);
    Stat stat = new Stat();
    ZNRecord znRecord = helixStore.get(znRecordPath, stat, AccessOption.PERSISTENT);
    long helixFetchTime = System.currentTimeMillis() - startTimeMs;
    accountServiceMetrics.fetchRemoteAccountTimeInMs.update(helixFetchTime);
    logger.trace("Fetched ZNRecord from path={}, took time={} ms", znRecordPath, helixFetchTime);
    if (znRecord == null) {
      logger.info("The ZNRecord to read does not exist on path={}", znRecordPath);
      return null;
    }
    Map<String, String> newAccountMap = fetchAccountMetadataFromZNRecord(znRecord);
    Map<Short, Account> idToAccountMap = new HashMap<>();
    Map<String, Account> nameToAccountMap = new HashMap<>();
    for (Map.Entry<String, String> entry : newAccountMap.entrySet()) {
      String idKey = entry.getKey();
      if (idKey == null) {
        accountServiceMetrics.remoteDataCorruptionErrorCount.inc();
        throw new IllegalStateException("Invalid account record when reading accountMap because idKey=null");
      }
      String valueString = entry.getValue();
      Account account;
      try {
        account = objectMapper.readValue(valueString, Account.class);
      } catch (JsonProcessingException e) {
        logger.error("Failed to deserialize {} to an Account object", valueString, e);
        throw new RuntimeException(e);
      }

      if (account.getId() != Short.parseShort(idKey)) {
        accountServiceMetrics.remoteDataCorruptionErrorCount.inc();
        throw new IllegalStateException(
            "Invalid account record when reading accountMap because idKey and accountId do not match. idKey=" + idKey
                + " accountId=" + account.getId());
      }
      if (idToAccountMap.containsKey(account.getId()) || nameToAccountMap.containsKey(account.getName())) {
        throw new IllegalStateException(
            "Duplicate account id or name exists. id=" + account.getId() + " name=" + account.getName());
      }
      idToAccountMap.put(account.getId(), account);
      nameToAccountMap.put(account.getName(), account);
    }
    if (newAccountMap != null) {
      backupFileManager.persistAccountMap(idToAccountMap.values(), stat.getVersion(), stat.getMtime() / 1000);
    }
    return idToAccountMap.values();
  }
fetchAccountMetadata would fetch the latest full set of {@link Account} metadata from the store. It returns null
when there is no {@link Account} created.
@return A collection of {@link Account} metadata.
ambry-account/src/main/java/com/github/ambry/account/AccountMetadataStore.java