private static void setClusterConfig(String clusterName, ConfigAccessor configAccessor,
      ClusterConfigFields clusterConfigFields, boolean dryRun) {
    ClusterConfig clusterConfig = configAccessor.getClusterConfig(clusterName);

    // 1. Set topology awareness. For example, if fault_zone_type is rack, helix avoids placing replicas on the hosts
    // in same rack
    clusterConfig.setTopologyAwareEnabled(true);
    clusterConfig.setTopology(TOPOLOGY);
    clusterConfig.setFaultZoneType(FAULT_ZONE_TYPE);

    // 2. Set max number of concurrent state transitions at resource level. This avoids too many replica movements in the cluster.
    StateTransitionThrottleConfig stateTransitionThrottleConfig =
        new StateTransitionThrottleConfig(StateTransitionThrottleConfig.RebalanceType.LOAD_BALANCE,
            StateTransitionThrottleConfig.ThrottleScope.RESOURCE, clusterConfigFields.maxPartitionInTransition);
    clusterConfig.setStateTransitionThrottleConfigs(Collections.singletonList(stateTransitionThrottleConfig));

    // 3. Set delay re-balancing to true to avoid replica movements if host is temporarily down due to deployment,
    // maintenance, etc
    clusterConfig.setDelayRebalaceEnabled(true);
    clusterConfig.setRebalanceDelayTime(clusterConfigFields.delayRebalanceTimeInMs);

    // 4. Set persistence of the best possible assignment. This will allow us to see the partition assignment in IDEAL state.
    clusterConfig.setPersistBestPossibleAssignment(true);

    // 5. Set default weight for each partition. Helix will do partition assignment based on partition weight and host
    // capacity.
    Map<String, Integer> defaultPartitionWeightMap = new HashMap<>();
    defaultPartitionWeightMap.put(DISK_KEY,
        clusterConfigFields.partitionDiskWeightInGB + PARTITION_BUFFER_CAPACITY_FOR_INDEX_FILES_IN_GB);
    clusterConfig.setDefaultPartitionWeightMap(defaultPartitionWeightMap);

    // 6. Set instance capacity keys
    clusterConfig.setInstanceCapacityKeys(Collections.singletonList(DISK_KEY));

    // 7. Set evenness and less movement for cluster. These help to balance evenness and replica movements in cluster.
    // Below are calculated values based on simulation.
    Map<ClusterConfig.GlobalRebalancePreferenceKey, Integer> globalRebalancePreferenceKeyIntegerMap = new HashMap<>();
    globalRebalancePreferenceKeyIntegerMap.put(ClusterConfig.GlobalRebalancePreferenceKey.EVENNESS,
        clusterConfigFields.evenness);
    globalRebalancePreferenceKeyIntegerMap.put(ClusterConfig.GlobalRebalancePreferenceKey.LESS_MOVEMENT,
        clusterConfigFields.lessMovement);
    clusterConfig.setGlobalRebalancePreference(globalRebalancePreferenceKeyIntegerMap);

    // 8. Set error or partition recovery
    clusterConfig.setErrorOrRecoveryPartitionThresholdForLoadBalance(clusterConfigFields.errorThresholdForLoadBalance);

    // 9. Set maximum number of threads that can be used by helix for state transition callbacks
    ZNRecord record = clusterConfig.getRecord();
    record.setIntField(Message.MessageType.STATE_TRANSITION.name() + "." + HelixTaskExecutor.MAX_THREADS,
        clusterConfigFields.maxThreadsForStateTransition);

    // Update cluster config in Helix/ZK
    if (!dryRun) {
      configAccessor.setClusterConfig(clusterName, clusterConfig);
      info("Updated cluster config fields for Full-Auto waged rebalancer. TOPOLOGY: {}, FAULT_ZONE_TYPE: {}, "
              + "MAX_PARTITION_IN_TRANSITION: {}, DELAY_REBALANCE_TIME (ms): {}, DEFAULT_PARTITION_WEIGHT_MAP_DISK: {}, "
              + "EVENNESS: {}, LESS_MOVEMENT: {}, ERROR_OR_RECOVERY_PARTITION_THRESHOLD_FOR_LOAD_BALANCE: {} ", TOPOLOGY,
          FAULT_ZONE_TYPE, clusterConfigFields.maxPartitionInTransition, clusterConfigFields.delayRebalanceTimeInMs,
          clusterConfigFields.partitionDiskWeightInGB, clusterConfigFields.evenness, clusterConfigFields.lessMovement,
          clusterConfig.getErrorOrRecoveryPartitionThresholdForLoadBalance());
    } else {
      info("Dry run. This will update cluster config fields for Full-Auto waged rebalancer with values as, "
              + "TOPOLOGY: {}, FAULT_ZONE_TYPE: {}, MAX_PARTITION_IN_TRANSITION: {}, "
              + "DELAY_REBALANCE_TIME (ms): {}, DEFAULT_PARTITION_WEIGHT_MAP_DISK: {}, EVENNESS: {}, LESS_MOVEMENT: {}, ERROR_OR_RECOVERY_PARTITION_THRESHOLD_FOR_LOAD_BALANCE: {} ",
          TOPOLOGY, FAULT_ZONE_TYPE, clusterConfigFields.maxPartitionInTransition,
          clusterConfigFields.delayRebalanceTimeInMs, clusterConfigFields.partitionDiskWeightInGB,
          clusterConfigFields.evenness, clusterConfigFields.lessMovement,
          clusterConfig.getErrorOrRecoveryPartitionThresholdForLoadBalance());
    }
  }
Sets up cluster to use waged rebalancer
@param clusterName         the cluster name
@param configAccessor      the {@link ConfigAccessor} to access configuration in Helix.
@param clusterConfigFields disk capacity of each partition.
@param dryRun               if true, perform a dry run; do not change ideal state to Full-Auto in Helix.
ambry-clustermap/src/main/java/com/github/ambry/clustermap/HelixBootstrapUpgradeUtil.java