public static void main(String[] args) throws Exception {
    VerifiableProperties verifiableProperties = ToolUtils.getVerifiableProperties(args);
    BlobValidatorConfig config = new BlobValidatorConfig(verifiableProperties);
    ClusterMapConfig clusterMapConfig = new ClusterMapConfig(verifiableProperties);
    ClusterMap clusterMap =
        ((ClusterAgentsFactory) Utils.getObj(clusterMapConfig.clusterMapClusterAgentsFactory, clusterMapConfig,
            config.hardwareLayoutFilePath, config.partitionLayoutFilePath)).getClusterMap();
    List<BlobId> blobIds = getBlobIds(config, clusterMap);
    SSLFactory sslFactory = !clusterMapConfig.clusterMapSslEnabledDatacenters.isEmpty() ? SSLFactory.getNewInstance(
        new SSLConfig(verifiableProperties)) : null;
    StoreKeyFactory storeKeyFactory = new BlobIdFactory(clusterMap);
    BlobValidator validator =
        new BlobValidator(clusterMap, config.replicasToContactPerSec, sslFactory, verifiableProperties);
    LOGGER.info("Validation starting");
    switch (config.typeOfOperation) {
      case ValidateBlobOnAllReplicas:
        Map<BlobId, List<String>> mismatchDetailsMap =
            validator.validateBlobsOnAllReplicas(blobIds, config.getOption, clusterMap, storeKeyFactory);
        logMismatches(mismatchDetailsMap);
        break;
      case ValidateBlobOnDatacenter:
        if (config.datacenter.isEmpty() || !clusterMap.hasDatacenter(config.datacenter)) {
          throw new IllegalArgumentException("Please provide a valid datacenter");
        }
        mismatchDetailsMap =
            validator.validateBlobsOnDatacenter(config.datacenter, blobIds, config.getOption, clusterMap,
                storeKeyFactory);
        logMismatches(mismatchDetailsMap);
        break;
      case ValidateBlobOnReplica:
        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);
        }
        List<ServerErrorCode> validErrorCodes =
            Arrays.asList(ServerErrorCode.NoError, ServerErrorCode.BlobDeleted, ServerErrorCode.BlobExpired);
        Map<BlobId, ServerErrorCode> blobIdToErrorCode =
            validator.validateBlobsOnReplica(dataNodeId, blobIds, config.getOption, clusterMap, storeKeyFactory);
        for (Map.Entry<BlobId, ServerErrorCode> entry : blobIdToErrorCode.entrySet()) {
          ServerErrorCode errorCode = entry.getValue();
          if (!validErrorCodes.contains(errorCode)) {
            LOGGER.error("[{}] received error code: {}", entry.getKey(), errorCode);
          }
        }
        break;
      default:
        throw new IllegalStateException("Recognized but unsupported operation: " + config.typeOfOperation);
    }
    LOGGER.info("Validation complete");
    validator.close();
    clusterMap.close();
  }
Runs the BlobValidator
@param args associated arguments.
@throws Exception
ambry-tools/src/main/java/com/github/ambry/tools/admin/BlobValidator.java