@Override
  public PartitionId getRandomWritablePartition(String partitionClass, List<PartitionId> partitionsToExclude) {
    List<? extends PartitionId> partitions = getWritablePartitionIds(partitionClass);
    partitions.removeAll(partitionsToExclude);
    return partitions.isEmpty() ? null : partitions.get(ThreadLocalRandom.current().nextInt(partitions.size()));
  }
Randomly select a writable partition from a list of writable partition ids obtained from both the underlying
{@link StaticClusterManager} and the underlying {@link HelixClusterManager}. This implementation can add to put
latency because getWritablePartitionIds called within this method, scans all the partitions to get writable partitions.
However, since {@link CompositeClusterManager} is used only during migrations, when both static and helix cluster
managers co-exist, the latency can be an acceptable trade-off for the extra metrics obtained from
getWritablePartitionIds.
@param partitionClass the partition class whose writable partitions are required. Can be {@code null}
@param partitionsToExclude A list of partitions that should be excluded from consideration.
@return A writable partition id object. Can be {@code null}
ambry-clustermap/src/main/java/com/github/ambry/clustermap/CompositeClusterManager.java