class AmbariServerConfigurationHandler extends RootServiceComponentConfigurationHandler {

  @Override
  public void updateComponentCategory(String categoryName, Map<String, String> properties, boolean removePropertiesIfNotSpecified) throws AmbariException {
    boolean toBePublished = false;
    final Iterator<Map.Entry<String, String>> propertiesIterator = properties.entrySet().iterator();
    while (propertiesIterator.hasNext()) {
      Map.Entry<String, String> property = propertiesIterator.next();

      // Ensure the incoming property is valid
      AmbariServerConfigurationKey key = AmbariServerConfigurationUtils.getConfigurationKey(categoryName, property.getKey());
      if(key == null) {
        throw new IllegalArgumentException(String.format("Invalid Ambari server configuration key: %s:%s", categoryName, property.getKey()));
      }

      if (AmbariServerConfigurationUtils.isPassword(key)) {
        final String passwordFileOrCredentialStoreAlias = fetchPasswordFileNameOrCredentialStoreAlias(categoryName, property.getKey());
        if (StringUtils.isNotBlank(passwordFileOrCredentialStoreAlias)) { //if blank -> this is the first time setup; we simply need to store the alias/file name
          if (updatePasswordIfNeeded(categoryName, property.getKey(), property.getValue())) {
            toBePublished = true;
          }
          propertiesIterator.remove(); //we do not need to change the any PASSWORD type configuration going forward
        }
      }
    }

    if (!properties.isEmpty()) {
      toBePublished = ambariConfigurationDAO.reconcileCategory(categoryName, properties, removePropertiesIfNotSpecified) || toBePublished;
    }

    if (toBePublished) {
      // notify subscribers about the configuration changes
      publisher.publish(new AmbariConfigurationChangedEvent(categoryName));
    }
  }

  @Inject  AmbariServerConfigurationHandler(AmbariConfigurationDAO ambariConfigurationDAO, AmbariEventPublisher publisher, Configuration ambariConfiguration);

}