class HostsRepositoryVersionCheck extends AbstractCheckDescriptor {

  @Override
  public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request)
      throws AmbariException {
    final String clusterName = request.getClusterName();
    final Cluster cluster = clustersProvider.get().getCluster(clusterName);
    final Map<String, Host> clusterHosts = clustersProvider.get().getHostsForCluster(clusterName);

    for (Host host : clusterHosts.values()) {
      // hosts in MM will produce a warning if they do not have the repo version
      MaintenanceState maintenanceState = host.getMaintenanceState(cluster.getClusterId());
      if (maintenanceState != MaintenanceState.OFF) {
        continue;
      }

      RepositoryVersionEntity repositoryVersion = request.getTargetRepositoryVersion();
      StackId repositoryStackId = repositoryVersion.getStackId();

      // get the host version entity for this host and repository
      final HostVersionEntity hostVersion = hostVersionDaoProvider.get().findByClusterStackVersionAndHost(
          clusterName, repositoryStackId, repositoryVersion.getVersion(), host.getHostName());

      // the repo needs to either be installed or not required
      Set<RepositoryVersionState> okStates = EnumSet.of(RepositoryVersionState.INSTALLED,
          RepositoryVersionState.NOT_REQUIRED);

      if (hostVersion == null || !okStates.contains(hostVersion.getState())) {
        prerequisiteCheck.getFailedOn().add(host.getHostName());

        prerequisiteCheck.getFailedDetail().add(
            new HostDetail(host.getHostId(), host.getHostName()));
      }
    }

    if (!prerequisiteCheck.getFailedOn().isEmpty()) {
      prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
      prerequisiteCheck.setFailReason(getFailReason(prerequisiteCheck, request));
    }
  }

  public  HostsRepositoryVersionCheck();

}