@Experimental(feature = ExperimentalFeature.CUSTOM_SERVICE_REPOS,
    comment = "Remove logic for handling custom service repos after enabling multi-mpack cluster deployment")
  private Set<RepositoryResponse> getRepositories(RepositoryRequest request) throws AmbariException {

    String stackName = request.getStackName();
    String stackVersion = request.getStackVersion();
    String osType = request.getOsType();
    String repoId = request.getRepoId();
    Long repositoryVersionId = request.getRepositoryVersionId();
    String versionDefinitionId = request.getVersionDefinitionId();

    // !!! when asking for Repository responses for a versionDefinition, it is either for
    // an established repo version (a Long) OR from the in-memory generated ones (a String)
    if (null == repositoryVersionId && null != versionDefinitionId) {

      if (NumberUtils.isDigits(versionDefinitionId)) {
        repositoryVersionId = Long.valueOf(versionDefinitionId);
      }
    }

    Set<RepositoryResponse> responses = new HashSet<>();

    if (repositoryVersionId != null) {
      final RepositoryVersionEntity repositoryVersion = repositoryVersionDAO.findByPK(repositoryVersionId);
      if (repositoryVersion != null) {
        for (RepoOsEntity operatingSystem : repositoryVersion.getRepoOsEntities()) {
          if (operatingSystem.getFamily().equals(osType)) {
            for (RepoDefinitionEntity repository : operatingSystem.getRepoDefinitionEntities()) {

              final RepositoryResponse response = new RepositoryResponse(repository.getBaseUrl(), osType, repository.getRepoID(),
                  repository.getRepoName(), repository.getDistribution(), repository.getComponents(), "", "",
                      repository.getTags(), repository.getApplicableServices());
              if (null != versionDefinitionId) {
                response.setVersionDefinitionId(versionDefinitionId);
              } else {
                response.setRepositoryVersionId(repositoryVersionId);
              }
              response.setStackName(repositoryVersion.getStackName());
              response.setStackVersion(repositoryVersion.getStackVersion());

              responses.add(response);
            }
            break;
          }
        }
      }
    } else if (null != versionDefinitionId) {
      VersionDefinitionXml xml = ambariMetaInfo.getVersionDefinition(versionDefinitionId);

      if (null == xml) {
        throw new AmbariException(String.format("Version identified by %s does not exist",
            versionDefinitionId));
      }
      StackId stackId = new StackId(xml.release.stackId);

      ListMultimap<String, RepositoryInfo> stackRepositoriesByOs = ambariMetaInfo.getStackManager().getStack(stackName, stackVersion).getRepositoriesByOs();
      for (RepositoryXml.Os os : xml.repositoryInfo.getOses()) {

        for (RepositoryXml.Repo repo : os.getRepos()) {
          RepositoryResponse resp = new RepositoryResponse(repo.getBaseUrl(), os.getFamily(),
              repo.getRepoId(), repo.getRepoName(), repo.getDistribution(), repo.getComponents(), repo.getMirrorsList(),
              repo.getBaseUrl(), repo.getTags(), Collections.EMPTY_LIST);

          resp.setVersionDefinitionId(versionDefinitionId);
          resp.setStackName(stackId.getStackName());
          resp.setStackVersion(stackId.getStackVersion());

          responses.add(resp);
        }
      }

      // Add service repos to the response. (These are not contained by the VDF but are present in the stack model)
      List<RepositoryInfo> serviceRepos =
          RepoUtil.getServiceRepos(xml.repositoryInfo.getRepositories(), stackRepositoriesByOs);
      responses.addAll(RepoUtil.asResponses(serviceRepos, versionDefinitionId, stackName, stackVersion));

    } else {
      if (repoId == null) {
        List<RepositoryInfo> repositories = ambariMetaInfo.getRepositories(stackName, stackVersion, osType);

        for (RepositoryInfo repository: repositories) {
          responses.add(repository.convertToResponse());
        }

      } else {
        RepositoryInfo repository = ambariMetaInfo.getRepository(stackName, stackVersion, osType, repoId);
        responses = Collections.singleton(repository.convertToResponse());
      }
    }

    return responses;
  }
Chooses a healthy host from the list of candidate hosts randomly. If there
are no healthy hosts, then this method will return {@code null}.
<p/>
The host's {@link HostState} is used to determine if a host is healthy.

@return a random healthy host, or {@code null}.
@throws AmbariException
@see {@link HostState#HEALTHY}
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java