private DataNodeConfigSource buildDataNodeConfigSource(ClusterMapConfig clusterMapConfig, String zkAddr,
      DataNodeConfigSourceMetrics metrics) {
    try {
      InstanceConfigToDataNodeConfigAdapter instanceConfigSource = null;
      if (clusterMapConfig.clusterMapDataNodeConfigSourceType.isInstanceConfigAware()) {
        instanceConfigSource = new InstanceConfigToDataNodeConfigAdapter(
            getZkHelixManagerAndConnect(clusterMapConfig.clusterMapClusterName,
                ClusterMapUtils.getInstanceName(clusterMapConfig.clusterMapHostName, clusterMapConfig.clusterMapPort),
                InstanceType.SPECTATOR, zkAddr, clusterMapConfig), clusterMapConfig);
      }
      PropertyStoreToDataNodeConfigAdapter propertyStoreSource = null;
      if (clusterMapConfig.clusterMapDataNodeConfigSourceType.isPropertyStoreAware()) {
        propertyStoreSource = new PropertyStoreToDataNodeConfigAdapter(zkAddr, clusterMapConfig);
      }

      switch (clusterMapConfig.clusterMapDataNodeConfigSourceType) {
        case INSTANCE_CONFIG:
          return instanceConfigSource;
        case PROPERTY_STORE:
          return propertyStoreSource;
        case COMPOSITE_INSTANCE_CONFIG_PRIMARY:
          return new CompositeDataNodeConfigSource(instanceConfigSource, propertyStoreSource, SystemTime.getInstance(),
              metrics);
        case COMPOSITE_PROPERTY_STORE_PRIMARY:
          return new CompositeDataNodeConfigSource(propertyStoreSource, instanceConfigSource, SystemTime.getInstance(),
              metrics);
        default:
          throw new IllegalArgumentException("Unknown type: " + clusterMapConfig.clusterMapDataNodeConfigSourceType);
      }
    } catch (Exception e) {
      throw new RuntimeException("Exception while instantiating DataNodeConfigSource", e);
    }
  }
@param clusterMapConfig the {@link ClusterMapConfig} to use.
@param zkAddr the ZooKeeper address to connect to. If a {@link HelixManager} is required and one is already in the
              pool with this address, it will be reused.
@param metrics the {@link DataNodeConfigSourceMetrics} to use.
@return a new instance of {@link DataNodeConfigSource} with the supplied configuration.
ambry-clustermap/src/main/java/com/github/ambry/clustermap/HelixFactory.java