Skip to content

[AMBARI-24162] Support for cluster-settings (remove cluster-env)#1627

Merged
benyoka merged 8 commits into
apache:branch-feature-AMBARI-14714from
benyoka:AMBARI-24162-branch-feature-AMBARI-14714
Jun 29, 2018
Merged

[AMBARI-24162] Support for cluster-settings (remove cluster-env)#1627
benyoka merged 8 commits into
apache:branch-feature-AMBARI-14714from
benyoka:AMBARI-24162-branch-feature-AMBARI-14714

Conversation

@benyoka
Copy link
Copy Markdown
Contributor

@benyoka benyoka commented Jun 26, 2018

What changes were proposed in this pull request?

  1. Properties from cluster-env that are recognized as cluster settings are copied/moved (copied in case ambari code still relies on cluster-env for a property) to the setting object.
  2. cluster settings coming from blueprint are processed during initial resource creation
  3. fixed the handling of the setting object in the blueprint (it was not saved)
  4. retry related settings are based on cluster settings instead of cluster-env

How was this patch tested?

  • tested cluster installation manually
  • wrote new unit tests
  • unit test run results:

Tests run: 4810, Failures: 12, Errors: 60, Skipped: 97
vs
Tests run: 4809, Failures: 13, Errors: 63, Skipped: 97 on feature branch

@asfgit
Copy link
Copy Markdown

asfgit commented Jun 26, 2018

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/Ambari-Github-PullRequest-Builder/2882/
Test FAILed.
Test FAILured.

Copy link
Copy Markdown

@rnettleton rnettleton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The patch looks fine to me, just a few questions/clarifications based on this change.

}
}

/**
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How will existing Blueprints that set these properties be handled?

We should make sure that if these properties are set in the older location ("cluster-env") then the Blueprint processor should move these over to "cluster-settings".

Copy link
Copy Markdown
Contributor Author

@benyoka benyoka Jun 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic is the following:

  • all properties in cluster-env which are recognized as cluster settings are copied from cluster-env to cluster settings.
  • recognition is based on the default cluster settings. It is stored in cluster-settings.xml and is exposed by a read only API. If a default setting is found for a cluster-env property, the property will be treated as cluster setting.
  • Legacy Ambari code may still use cluster-env to get some of these properties, so as a temporary workaround the properties will remain in cluster-env too (in addition to being copied to cluster settings). Exceptions are the cases where migration has happened; such case is the retry related settings.
  • Users are safe the continue using cluster-env with blueprints; the properties will be automatically copied to cluster settings (provided they are recognized cluster setting properties based on the logic above)
  • Handling recovery related settings in the BlueprintConfigurationProcessor is no more necessary as there are defaults defined in cluster-settings.xml for these properties.

topologyManager.provisionCluster(request, "{}");
}

private static ServiceResponse service(String serviceName, long serviceId) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this method should be moved into a utility class, since it appears to be repeated in several test cases.

@adoroszlai adoroszlai changed the title Ambari 24162 branch feature ambari 14714 [AMBARI-24162] Support for cluster-settings (remove cluster-env) Jun 27, 2018
@benyoka benyoka requested a review from jayush June 27, 2018 08:55
@benyoka
Copy link
Copy Markdown
Contributor Author

benyoka commented Jun 27, 2018

Hey @rnettleton and @jayush

This PR enables users to send cluster settings with blueprints in two ways:

  1. They can be defined as properties in cluster-env (the legacy way)
  2. They can be defined in the setting part in the blueprint in a new section called cluster_settings. In addition, the recovery_settings section is also treated as cluster settings. (the proposed new way)

Please let me know if you are fine with the syntax. Here is an example:

...
"settings" : [
    "cluster_settings": [
       {
           "command_retry_enabled": "true",
           "commands_to_retry": "INSTALL,START,STOP",
           "command_retry_max_time_in_sec": "500"
       }
    ]
    "deployment_settings": [
      {"skip_failure":"true"}
    ],
    "repository_settings":[
       ...
    ],
    "recovery_settings":[
      {"recovery_enabled":"true"}
    ],
    "service_settings":[
      {
        "name":"SERVICE_ONE",
        "recovery_enabled":"true"
      },
      {
        "name":"SERVICE_TWO",
        "recovery_enabled":"true"
      }
    ],
    "component_settings":[
        ...
    ]
  ],
...

The current settings structure is overly granular for cluster settings (it defines a set of maps for each section), so there is some flexibility: cluster settings can be set both as a single map in the set (see the example above) or a set of maps like this:

...
    "cluster_settings": [
       { "command_retry_enabled": "true" },
       { "commands_to_retry": "INSTALL,START,STOP" },
       { "command_retry_max_time_in_sec": "500" }
    ]
...

Copy link
Copy Markdown
Contributor

@adoroszlai adoroszlai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but please consider some opportunities below to simplify parts of the code.

cluster.addClusterSetting(p.getName(), p.getValue());
Map<String, String> defaultClusterSettings =
getController().getAmbariMetaInfo().getClusterProperties().stream()
.collect(toMap(p -> p.getName(), p -> p.getValue()));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lambda can be simplified to method reference.


Map<String, Object> settingProperties = properties.entrySet().stream()
.filter(entry -> SETTING_PROPERTY_ID.equals(entry.getKey()) || entry.getKey().startsWith(SETTING_PROPERTY_ID + "/"))
.collect(toMap(entry -> entry.getKey(), entry -> entry.getValue()));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lambda can be simplified to method reference.

private static void setRetryConfiguration(Configuration configuration, Set<String> configTypesUpdated) {
boolean wasUpdated = false;

if (configuration.getPropertyValue(CLUSTER_ENV_CONFIG_TYPE_NAME, COMMAND_RETRY_ENABLED_PROPERTY_NAME) == null) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please also remove leftover unused constants?

*/
private void adjustTopology() {
Set<PropertyInfo> clusterProperties = AmbariContext.getController().getAmbariMetaInfo().getClusterProperties();
Set<String> clusterSettingPropertyNames = clusterProperties.stream().map(prop -> prop.getName()).collect(toSet());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lambda can be simplified to method reference.

ImmutableSet.of(SETTING_NAME_CLUSTER_SETTINGS, SETTING_NAME_RECOVERY_SETTINGS);
return settingsToExtract.stream()
.flatMap( settingCategory ->
Optional.ofNullable(properties.get(settingCategory)).orElseGet(() -> emptySet()).stream())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional.ofNullable(properties.get(settingCategory)).orElseGet(() -> emptySet())

can be simplified to

properties.getOrDefault(settingCategory, emptySet())

.flatMap( settingCategory ->
Optional.ofNullable(properties.get(settingCategory)).orElseGet(() -> emptySet()).stream())
.flatMap( map -> map.entrySet().stream() )
.collect(toMap(e -> e.getKey(), e -> e.getValue()));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lambda can be simplified to method reference.

Set<String> clusterSettingPropertyNames = clusterProperties.stream().map(prop -> prop.getName()).collect(toSet());
Map<String, String> clusterEnv = Optional
.ofNullable(configuration.getFullProperties().get(ConfigHelper.CLUSTER_ENV))
.orElse(ImmutableMap.of());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be simplified using getOrDefault.

Setting.SETTING_NAME_CLUSTER_SETTINGS,
__ -> Sets.newHashSet(Maps.newHashMap()))
.iterator().next()
.put(entry.getKey(), entry.getValue());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sets.newHashSet(Maps.newHashMap()) produces unchecked warning.

I think it would be simpler to collect these properties into a single, temporary map, and putAll them into the first set outside of forEach. Better yet, use collection methods (removeAll, retainAll) to avoid the loop. Something like this:

    Map<String, String> converted = new HashMap<>(clusterEnv);
    Map<String, String> remaining = new HashMap<>(clusterEnv);
    remaining.keySet().removeAll(clusterSettingPropertyNames);
    converted.keySet().retainAll(clusterSettingPropertyNames);
    setting.addProperties(Setting.SETTING_NAME_CLUSTER_SETTINGS, converted);

    Sets.intersection(converted.keySet(), SAFE_TO_REMOVE_FROM_CLUSTER_ENV)
      .forEach(key -> configuration.removeProperty(ConfigHelper.CLUSTER_ENV, key));

With the logic to add properties to Setting extracted to a method in that class:

  public void addProperties(String name, Map<String, String> values) {
    Set<Map<String, String>> set = properties.computeIfAbsent(name, __ -> new HashSet<>(1));
    if (set.isEmpty()) {
      set.add(new HashMap<>(values));
    } else {
      set.iterator().next().putAll(values);
    }
  }

@asfgit
Copy link
Copy Markdown

asfgit commented Jun 28, 2018

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/Ambari-Github-PullRequest-Builder/2917/
Test FAILed.
Test FAILured.

@adoroszlai
Copy link
Copy Markdown
Contributor

@benyoka something is wrong with the merge, unit test errors increased to 209.

@benyoka
Copy link
Copy Markdown
Contributor Author

benyoka commented Jun 28, 2018

It is mostly caused by BlueprintConfigurationProcessorTest failures.

@asfgit
Copy link
Copy Markdown

asfgit commented Jun 28, 2018

Refer to this link for build results (access rights to CI server needed):
https://builds.apache.org/job/Ambari-Github-PullRequest-Builder/2921/
Test FAILed.
Test FAILured.

@benyoka benyoka merged commit 48ddb09 into apache:branch-feature-AMBARI-14714 Jun 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants