public Map<String, Collection<String>> getChangedConfigTypes(Cluster cluster,
                                                                ServiceConfigEntity currentServiceConfigEntity,
                                                                Long configGroupId, Long clusterId, String serviceName) {
    ServiceConfigEntity previousServiceConfigEntity;
    List<ClusterConfigEntity> previousConfigEntities = new ArrayList<>();
    List<ClusterConfigEntity> currentConfigEntities = new ArrayList<>();
    currentConfigEntities.addAll(currentServiceConfigEntity.getClusterConfigEntities());
    // Retrieve group cluster configs
    if (configGroupId != null) {
      previousServiceConfigEntity =
          serviceConfigDAO.getLastServiceConfigVersionsForGroup(configGroupId);
      if (previousServiceConfigEntity != null) {
        previousConfigEntities.addAll(previousServiceConfigEntity.getClusterConfigEntities());
      }
    }
    // Service config with custom group contains not all config types, so it is needed
    // to complement it with configs from default group
    previousServiceConfigEntity =
        serviceConfigDAO.getLastServiceConfigForServiceDefaultGroup(clusterId, serviceName);
    if (previousServiceConfigEntity != null) {
      for (ClusterConfigEntity clusterConfigEntity : previousServiceConfigEntity.getClusterConfigEntities()) {
        // Add only configs not present yet
        ClusterConfigEntity exist =
            previousConfigEntities.stream()
                .filter(c -> c.getType().equals(clusterConfigEntity.getType())).findAny().orElse(null);
        if (exist == null) {
          previousConfigEntities.add(clusterConfigEntity);
        }
        // Complement current custom group service config to correct comparing
        if (configGroupId != null) {
          exist = currentConfigEntities.stream()
              .filter(c -> c.getType().equals(clusterConfigEntity.getType())).findAny().orElse(null);
          if (exist == null) {
            currentConfigEntities.add(clusterConfigEntity);
          }
        }
      }
    }
    Map<String, String> previousConfigs = new HashMap<>();
    Map<String, String> currentConfigs = new HashMap<>();

    for (ClusterConfigEntity clusterConfigEntity : currentConfigEntities) {
      currentConfigs.put(clusterConfigEntity.getType(), clusterConfigEntity.getTag());
    }
    for (ClusterConfigEntity clusterConfigEntity : previousConfigEntities) {
      previousConfigs.put(clusterConfigEntity.getType(), clusterConfigEntity.getTag());
    }

    Map<String, Collection<String>> changedConfigs = new HashMap<>();
    for (Map.Entry<String, String> currentConfig : currentConfigs.entrySet()) {
      String type = currentConfig.getKey();
      String tag = currentConfig.getValue();
      Collection<String> changedKeys;
      if (previousConfigs.containsKey(type)) {
        changedKeys = findChangedKeys(cluster, type, Collections.singletonList(tag),
            Collections.singletonList(previousConfigs.get(type)));
      } else {
        changedKeys = cluster.getConfig(type, tag).getProperties().keySet();
      }
      if (CollectionUtils.isNotEmpty(changedKeys)) {
        changedConfigs.put(type, changedKeys);
      }
    }
    return changedConfigs;
  }
Calculates config types and keys were changed during configs change.
@param currentServiceConfigEntity service config entity with populated current cluster configs
@param configGroupId id of config group contained changed configs. Can be null in case group is default
@param clusterId cluster id
@param serviceName service name configs were changed for
@return map of type names to collections of properties' names were changed.
ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java