protected synchronized void updateHosts(Set<HostRequest> requests) throws AmbariException {

    if (requests.isEmpty()) {
      LOG.warn("Received an empty requests set");
      return;
    }

    AmbariManagementController controller = getManagementController();
    Clusters clusters = controller.getClusters();

    for (HostRequest request : requests) {
      if (request.getHostname() == null || request.getHostname().isEmpty()) {
        throw new IllegalArgumentException("Invalid arguments, hostname should be provided");
      }
    }

    for (HostRequest request : requests) {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "Received an updateHost request"
                + ", hostname="
                + request.getHostname()
                + ", request="
                + request);
      }

      Host host = clusters.getHost(request.getHostname());

      String clusterName = request.getClusterName();

      try {
        // The below method call throws an exception when trying to create a duplicate mapping in
        // the clusterhostmapping
        // table. This is done to detect duplicates during host create. In order to be robust,
        // handle these gracefully.
        clusters.mapHostToCluster(request.getHostname(), clusterName);
      } catch (DuplicateResourceException e) {
        // do nothing
      }

      if (null != request.getHostAttributes()) {
        host.setHostAttributes(request.getHostAttributes());
      }

      String rackInfo = host.getRackInfo();
      String requestRackInfo = request.getRackInfo();
      boolean rackChange = requestRackInfo != null && !requestRackInfo.equals(rackInfo);

      if (rackChange) {
        host.setRackInfo(requestRackInfo);
      }

      if (null != request.getPublicHostName()) {
        host.setPublicHostName(request.getPublicHostName());
      }

      if (null != clusterName && null != request.getMaintenanceState()) {
        Cluster c = clusters.getCluster(clusterName);
        MaintenanceState newState = MaintenanceState.valueOf(request.getMaintenanceState());
        MaintenanceState oldState = host.getMaintenanceState(c.getClusterId());
        if (!newState.equals(oldState)) {
          if (newState.equals(MaintenanceState.IMPLIED_FROM_HOST)
              || newState.equals(MaintenanceState.IMPLIED_FROM_SERVICE)) {
            throw new IllegalArgumentException(
                "Invalid arguments, can only set "
                    + "maintenance state to one of "
                    + EnumSet.of(MaintenanceState.OFF, MaintenanceState.ON));
          } else {
            host.setMaintenanceState(c.getClusterId(), newState);
          }
        }
      }

      // Create configurations
      if (null != clusterName && null != request.getDesiredConfigs()) {
        Cluster c = clusters.getCluster(clusterName);

        if (clusters.getHostsForCluster(clusterName).containsKey(host.getHostName())) {

          for (ConfigurationRequest cr : request.getDesiredConfigs()) {

            if (null != cr.getProperties() && cr.getProperties().size() > 0) {
              LOG.info(
                  MessageFormat.format(
                      "Applying configuration with tag ''{0}'' to host ''{1}'' in cluster ''{2}''",
                      cr.getVersionTag(), request.getHostname(), clusterName));

              cr.setClusterName(c.getClusterName());
              controller.createConfiguration(cr);
            }

            Config baseConfig = c.getConfig(cr.getType(), cr.getVersionTag());
            if (null != baseConfig) {
              String authName = controller.getAuthName();
              DesiredConfig oldConfig = host.getDesiredConfigs(c.getClusterId()).get(cr.getType());

              if (host.addDesiredConfig(c.getClusterId(), cr.isSelected(), authName, baseConfig)) {
                Logger logger = LoggerFactory.getLogger("configchange");
                logger.info(
                    "cluster '"
                        + c.getClusterName()
                        + "', "
                        + "host '"
                        + host.getHostName()
                        + "' "
                        + "changed by: '"
                        + authName
                        + "'; "
                        + "type='"
                        + baseConfig.getType()
                        + "' "
                        + "version='"
                        + baseConfig.getVersion()
                        + "'"
                        + "tag='"
                        + baseConfig.getTag()
                        + "'"
                        + (null == oldConfig ? "" : ", from='" + oldConfig.getTag() + "'"));
              }
            }
          }
        }
      }

      if (clusterName != null && !clusterName.isEmpty()) {
        clusters.getCluster(clusterName).recalculateAllClusterVersionStates();
        if (rackChange) {
          controller.registerRackChange(clusterName);
        }
      }

      // todo: if attempt was made to update a property other than those
      // todo: that are allowed above, should throw exception
    }
  }