public static void updateResourceAndPartition(String srcZkString, String srcClusterName, String destZkString,
      String destClusterName, VcrHelixConfig config, boolean dryRun) {

    HelixAdmin srcAdmin = new ZKHelixAdmin(srcZkString);
    Set<String> srcResources = new HashSet<>(srcAdmin.getResourcesInCluster(srcClusterName));
    HelixAdmin destAdmin = new ZKHelixAdmin(destZkString);
    Set<String> destResources = new HashSet<>(destAdmin.getResourcesInCluster(destClusterName));
    // Remove stale resources
    for (String resource : destResources) {
      if (!srcResources.contains(resource)) {
        if (dryRun) {
          logger.info("DryRun: Drop Resource {}", resource);
        } else {
          // This resource need to be dropped.
          logger.info("Dropped Resource {}, Partitions: {}", resource,
              destAdmin.getResourceIdealState(destClusterName, resource).getPartitionSet());
          destAdmin.dropResource(destClusterName, resource);
        }
      }
    }
    for (String resource : srcResources) {
      if (!isPartitionResourceName(resource)) {
        continue;
      }
      boolean createNewResource = false;
      boolean dropResource = false;
      if (destResources.contains(resource)) {
        // check if every partition exist.
        Set<String> srcPartitions = srcAdmin.getResourceIdealState(srcClusterName, resource).getPartitionSet();
        Set<String> destPartitions = destAdmin.getResourceIdealState(destClusterName, resource).getPartitionSet();
        if (srcPartitions.size() != destPartitions.size()) {
          dropResource = true;
          createNewResource = true;
        } else {
          for (String partition : srcPartitions) {
            if (!destPartitions.contains(partition)) {
              dropResource = true;
              createNewResource = true;
              break;
            }
          }
        }
        if (dropResource && dryRun) {
          logger.info("DryRun: Drop Resource {}", resource);
        } else if (dropResource) {
          // This resource need to be recreate.
          logger.info("Dropped Resource {}, Partitions: {}", resource,
              destAdmin.getResourceIdealState(destClusterName, resource).getPartitionSet());
          destAdmin.dropResource(destClusterName, resource);
        }
      } else {
        createNewResource = true;
      }
      if (createNewResource) {
        // add new resource
        Set<String> srcPartitions = srcAdmin.getResourceIdealState(srcClusterName, resource).getPartitionSet();
        IdealState idealState = buildIdealState(resource, srcPartitions, config.getIdealStateConfigFields());
        if (dryRun) {
          logger.info("DryRun: Add Resource {} with partition {}", resource, srcPartitions);
        } else {
          destAdmin.addResource(destClusterName, resource, idealState);
          destAdmin.rebalance(destClusterName, resource, config.getIdealStateConfigFields().getNumReplicas(), "", "");
          logger.info("Added Resource {}  with partition {}", resource, srcPartitions);
        }
      }
    }
    logger.info("Cluster {} is updated successfully!", destClusterName);
  }
Update dest cluster information based on src cluster.
Dest cluster resource will be recreated if it mismatches that in src cluster.
@param srcZkString the src cluster's zk string
@param srcClusterName the src cluster's name
@param destZkString the dest cluster's zk string
@param destClusterName the dest cluster's name
@param dryRun run the update process but without actual change.
ambry-commons/src/main/java/com/github/ambry/clustermap/HelixVcrUtil.java