Browse Source

AMBARI-3634. Load service configurations based on config-group selection. (srimanth)

Srimanth Gunturi 11 years ago
parent
commit
2a0bf718ef

+ 60 - 16
ambari-web/app/controllers/main/service/info/configs.js

@@ -25,6 +25,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
   stepConfigs: [], //contains all field properties that are viewed in this service
   stepConfigs: [], //contains all field properties that are viewed in this service
   selectedService: null,
   selectedService: null,
   serviceConfigTags: null,
   serviceConfigTags: null,
+  selectedConfigGroup: null,
+  configGroups: [],
   globalConfigs: [],
   globalConfigs: [],
   uiConfigs: [],
   uiConfigs: [],
   customConfig: [],
   customConfig: [],
@@ -253,25 +255,53 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     var serviceConfigsDef = params.serviceConfigsDef;
     var serviceConfigsDef = params.serviceConfigsDef;
     var serviceName = this.get('content.serviceName');
     var serviceName = this.get('content.serviceName');
     console.debug("loadServiceConfigs(): data=", data);
     console.debug("loadServiceConfigs(): data=", data);
-
-    this.loadedClusterSiteToTagMap = {};
-    //STEP 1: handle tags from JSON data
+    var allConfigGroups = [];
+    // Create default configuration group
+    var defaultConfigGroup = App.ConfigGroup.create({
+      name: "Default",
+      description: "Default cluster level " + serviceName + " configuration",
+      isDefault: true,
+      parentConfigGroup: null,
+      service: this.get('content'),
+      configSiteTags: []
+    });
+    var configSiteTags = defaultConfigGroup.configSiteTags;
     for (var site in data.Clusters.desired_configs) {
     for (var site in data.Clusters.desired_configs) {
       if (serviceConfigsDef.sites.indexOf(site) > -1) {
       if (serviceConfigsDef.sites.indexOf(site) > -1) {
-        this.loadedClusterSiteToTagMap[site] = data.Clusters.desired_configs[site]['tag'];
-        var overrides = data.Clusters.desired_configs[site].host_overrides;
-        if (overrides) {
-          overrides.forEach(function (override) {
-            var hostname = override.host_name;
-            var tag = override.tag;
-            if (!this.loadedHostToOverrideSiteToTagMap[hostname]) {
-              this.loadedHostToOverrideSiteToTagMap[hostname] = {};
-            }
-            this.loadedHostToOverrideSiteToTagMap[hostname][site] = tag;
-          }, this);
-        }
+        configSiteTags.push(App.ConfigSiteTag.create({
+          site: site,
+          tag: data.Clusters.desired_configs[site].tag
+        }));
       }
       }
     }
     }
+    
+    allConfigGroups.push(defaultConfigGroup);
+    this.configGroups = allConfigGroups;
+    this.set('selectedConfigGroup', defaultConfigGroup);
+  },
+  
+  loadConfigGroup: function () {
+    var selectedConfigGroup = this.get('selectedConfigGroup');
+    var serviceName = selectedConfigGroup.get('service.serviceName');
+    this.loadedClusterSiteToTagMap = {};
+    //STEP 1: handle tags from JSON data
+    var selectedSiteTags = selectedConfigGroup.get('configSiteTags');
+    selectedSiteTags.forEach( function(siteTag) {
+      var site = siteTag.get('site');
+      var tag = siteTag.get('tag');
+      this.loadedClusterSiteToTagMap[site] = tag;
+//      var overrides = data.Clusters.desired_configs[site].host_overrides;
+//      if (overrides) {
+//        overrides.forEach(function (override) {
+//          var hostname = override.host_name;
+//          var tag = override.tag;
+//          if (!this.loadedHostToOverrideSiteToTagMap[hostname]) {
+//            this.loadedHostToOverrideSiteToTagMap[hostname] = {};
+//          }
+//          this.loadedHostToOverrideSiteToTagMap[hostname][site] = tag;
+//        }, this);
+//      }
+    }, this);
     //STEP 2: Create an array of objects defining tag names to be polled and new tag names to be set after submit
     //STEP 2: Create an array of objects defining tag names to be polled and new tag names to be set after submit
     this.setServiceConfigTags(this.loadedClusterSiteToTagMap);
     this.setServiceConfigTags(this.loadedClusterSiteToTagMap);
     //STEP 3: Load advanced configs from server
     //STEP 3: Load advanced configs from server
@@ -316,7 +346,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     this.set('selectedService', this.get('stepConfigs').objectAt(0));
     this.set('selectedService', this.get('stepConfigs').objectAt(0));
     this.checkForSecureConfig(this.get('selectedService'));
     this.checkForSecureConfig(this.get('selectedService'));
     this.set('dataIsLoaded', true);
     this.set('dataIsLoaded', true);
-  },
+  }.observes('selectedConfigGroup'),
   
   
   loadServiceConfigHostsOverrides: function(allConfigs, loadedHostToOverrideSiteToTagMap) {
   loadServiceConfigHostsOverrides: function(allConfigs, loadedHostToOverrideSiteToTagMap) {
     App.config.loadServiceConfigHostsOverrides(allConfigs, loadedHostToOverrideSiteToTagMap);
     App.config.loadServiceConfigHostsOverrides(allConfigs, loadedHostToOverrideSiteToTagMap);
@@ -1016,6 +1046,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
         var serverGlobalConfigs = this.createGlobalSiteObj(_serviceTags.newTagName);
         var serverGlobalConfigs = this.createGlobalSiteObj(_serviceTags.newTagName);
         siteNameToServerDataMap['global'] = serverGlobalConfigs;
         siteNameToServerDataMap['global'] = serverGlobalConfigs;
         var loadedProperties = configController.getConfigsByTags([{siteName: 'global', tagName: this.loadedClusterSiteToTagMap['global']}]);
         var loadedProperties = configController.getConfigsByTags([{siteName: 'global', tagName: this.loadedClusterSiteToTagMap['global']}]);
+        if (loadedProperties && loadedProperties[0]) {
+          loadedProperties = loadedProperties[0].properties;
+        }
         if (this.isConfigChanged(loadedProperties, serverGlobalConfigs.properties)) {
         if (this.isConfigChanged(loadedProperties, serverGlobalConfigs.properties)) {
           result = result && this.doPUTClusterConfigurationSite(serverGlobalConfigs);
           result = result && this.doPUTClusterConfigurationSite(serverGlobalConfigs);
         }
         }
@@ -1025,6 +1058,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
           var coreSiteConfigs = this.createCoreSiteObj(_serviceTags.newTagName);
           var coreSiteConfigs = this.createCoreSiteObj(_serviceTags.newTagName);
           siteNameToServerDataMap['core-site'] = coreSiteConfigs;
           siteNameToServerDataMap['core-site'] = coreSiteConfigs;
           var loadedProperties = configController.getConfigsByTags([{siteName: 'core-site', tagName: this.loadedClusterSiteToTagMap['core-site']}]);
           var loadedProperties = configController.getConfigsByTags([{siteName: 'core-site', tagName: this.loadedClusterSiteToTagMap['core-site']}]);
+          if (loadedProperties && loadedProperties[0]) {
+            loadedProperties = loadedProperties[0].properties;
+          }
           if (this.isConfigChanged(loadedProperties, coreSiteConfigs.properties)) {
           if (this.isConfigChanged(loadedProperties, coreSiteConfigs.properties)) {
             result = result && this.doPUTClusterConfigurationSite(coreSiteConfigs);
             result = result && this.doPUTClusterConfigurationSite(coreSiteConfigs);
           }
           }
@@ -1033,6 +1069,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
         var serverConfigs = this.createSiteObj(_serviceTags.siteName, _serviceTags.newTagName);
         var serverConfigs = this.createSiteObj(_serviceTags.siteName, _serviceTags.newTagName);
         siteNameToServerDataMap[_serviceTags.siteName] = serverConfigs;
         siteNameToServerDataMap[_serviceTags.siteName] = serverConfigs;
         var loadedProperties = configController.getConfigsByTags([{siteName: _serviceTags.siteName, tagName: this.loadedClusterSiteToTagMap[_serviceTags.siteName]}]);
         var loadedProperties = configController.getConfigsByTags([{siteName: _serviceTags.siteName, tagName: this.loadedClusterSiteToTagMap[_serviceTags.siteName]}]);
+        if (loadedProperties && loadedProperties[0]) {
+          loadedProperties = loadedProperties[0].properties;
+        }
         if (this.isConfigChanged(loadedProperties, serverConfigs.properties)) {
         if (this.isConfigChanged(loadedProperties, serverConfigs.properties)) {
           result = result && this.doPUTClusterConfigurationSite(serverConfigs);
           result = result && this.doPUTClusterConfigurationSite(serverConfigs);
         }
         }
@@ -1546,6 +1585,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
   doCancel: function () {
   doCancel: function () {
     this.loadStep();
     this.loadStep();
   },
   },
+
   restartComponents: function() {
   restartComponents: function() {
     App.showConfirmationPopup(function() {
     App.showConfirmationPopup(function() {
 
 
@@ -1594,5 +1634,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
       }),
       }),
       secondary: null
       secondary: null
     });
     });
+  },
+  
+  selectConfigGroup: function (event) {
+    this.set('selectedConfigGroup', event.context);
   }
   }
 });
 });

+ 2 - 0
ambari-web/app/controllers/wizard/step8_controller.js

@@ -60,6 +60,8 @@ App.WizardStep8Controller = Em.Controller.extend({
    * @see loadedHostToOverrideSiteToTagMap
    * @see loadedHostToOverrideSiteToTagMap
    */
    */
   savedHostToOverrideSiteToTagMap: {},
   savedHostToOverrideSiteToTagMap: {},
+  selectedConfigGroup: null,
+  configGroups: [],
 
 
   selectedServices: function () {
   selectedServices: function () {
     return this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false);
     return this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false);

+ 1 - 0
ambari-web/app/models.js

@@ -48,3 +48,4 @@ require('models/dataset');
 require('models/dataset_job');
 require('models/dataset_job');
 require('classes/run_class');
 require('classes/run_class');
 require('classes/job_class');
 require('classes/job_class');
+require('models/config_group');

+ 98 - 0
ambari-web/app/models/config_group.js

@@ -0,0 +1,98 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+/**
+ * Represents a configuration-group on the cluster. 
+ * A configuration-group is a collection of hosts
+ * on which a collection of configurations are applied.
+ * 
+ * Configuration group hierarchy is at 2 levels. For 
+ * each service there is a 'Default' configuration group
+ * containing all hosts not belonging to any group of that
+ * service. 
+ * 
+ * A default configuration group has child configuration
+ * groups which contain configuration overrides (deltas)
+ * for a bunch of hosts. This allows different configurations 
+ * for different hosts in a heterogeneous cluster environment.
+ */
+App.ConfigGroup = Ember.Object.extend({
+  id: DS.attr('number'),
+  name: DS.attr('string'),
+  description: DS.attr('string'),
+  isDefault: DS.attr('boolean'),
+  
+  /**
+   * Parent configuration group for this group.
+   * When {@link #isDefault} is true, this value is <code>null</code>
+   * When {@link #isDefault} is false, this represents the configuration
+   * deltas that are applied on the default.
+   */
+  parentConfigGroup: DS.belongsTo('App.ConfigGroup'),
+  
+  /**
+   * Children configuration groups for this group.
+   * When {@link #isDefault} is false, this value is <code>null</code>
+   * When {@link #isDefault} is true, this represents the various
+   * configuration groups that override the default.
+   */
+  childConfigGroups: DS.hasMany('App.ConfigGroup'),
+  
+  /**
+   * Service for which this configuration-group 
+   * is applicable.
+   */
+  service: DS.belongsTo('App.Service'),
+  
+  /**
+   * Hosts on which this configuration-group 
+   * is to be applied. For a service, a host can 
+   * belong to only one non-default configuration-group.
+   * 
+   * When {#isDefault} is false, this contains hosts
+   * for which the overrides will apply.
+   * 
+   * When {#isDefault} is true, this value is empty, as 
+   * it dynamically reflects hosts not belonging to other
+   * non-default groups.
+   * 
+   */
+  hosts: DS.hasMany('App.Host'),
+  
+  /**
+   * Provides hosts which are available for inclusion in 
+   * non-default configuration groups. 
+   */
+  availableHosts: function() {
+    
+  }.property('isDefault', 'parentConfigGroup', 'childConfigGroups'),
+  
+  /**
+   * Collection of (site, tag) pairs representing properties.
+   * 
+   * When {#isDefault} is true, this represents the 
+   * default cluster configurations for that service.
+   * 
+   * When {#isDefault} is false, this represents the
+   * configuration overrides on top of the cluster default for the
+   * hosts identified by 'hosts'.
+   */
+  configSiteTags: DS.hasMany('App.ConfigSiteTag')
+});

+ 24 - 1
ambari-web/app/templates/common/configs/service_config.hbs

@@ -45,7 +45,30 @@
 	</div>
 	</div>
 	{{/if}}
 	{{/if}}
 {{/if}}
 {{/if}}
-
+{{#if App.supports.hostOverrides}}
+	<div class="alert alert-info">
+	  {{t common.group}}&nbsp; 
+	  <span class="btn-group">
+		  <button class="btn">{{selectedConfigGroup.name}}</button>
+		  <button class="btn dropdown-toggle" data-toggle="dropdown">
+		    <span class="caret"></span>
+		  </button>
+		  <ul class="dropdown-menu">
+		    <!-- available config group menu links -->
+		    {{#each configGroup in configGroups}}
+           <li>
+             <a href="#" {{action "selectConfigGroup" configGroup target="controller"}}>
+               {{configGroup.name}}
+             </a>
+           </li>
+        {{/each}}
+		  </ul>
+		</span>
+     <div class="pull-right">
+       {{view App.FilterComboboxView filterBinding="view.filter" columnsBinding="view.columns" }}
+     </div>
+	</div>
+{{/if}}
 <div class="accordion">
 <div class="accordion">
   {{#each category in selectedService.configCategories}}
   {{#each category in selectedService.configCategories}}
     {{#if category.isCustomView}}
     {{#if category.isCustomView}}

+ 0 - 3
ambari-web/app/templates/main/host/configs_service.hbs

@@ -18,9 +18,6 @@
 
 
 <div id="serviceConfig">
 <div id="serviceConfig">
   {{#if dataIsLoaded}}
   {{#if dataIsLoaded}}
-    <div class="pull-right">
-      {{view App.FilterComboboxView filterBinding="controller.filter" columnsBinding="controller.filterColumns" }}
-    </div>
     <div class="clearfix"></div>
     <div class="clearfix"></div>
     {{view App.ServiceConfigView canEditBinding="view.isConfigsEditable" filterBinding="controller.filter" columnsBinding="controller.filterColumns"}}
     {{view App.ServiceConfigView canEditBinding="view.isConfigsEditable" filterBinding="controller.filter" columnsBinding="controller.filterColumns"}}
   {{else}}
   {{else}}

+ 2 - 5
ambari-web/app/templates/main/service/info/configs.hbs

@@ -29,10 +29,7 @@
           </div>
           </div>
         </div>
         </div>
       {{/if}}
       {{/if}}
-    <div class="pull-right">
-      {{view App.FilterComboboxView filterBinding="controller.filter" columnsBinding="controller.filterColumns" }}
-    </div>
-	  {{/if}}
+    {{/if}}
     <div class="clearfix"></div>
     <div class="clearfix"></div>
     {{view App.ServiceConfigView filterBinding="controller.filter" columnsBinding="controller.filterColumns"}}
     {{view App.ServiceConfigView filterBinding="controller.filter" columnsBinding="controller.filterColumns"}}
     {{#if App.isAdmin}}
     {{#if App.isAdmin}}
@@ -46,4 +43,4 @@
   {{else}}
   {{else}}
     <div class="spinner"></div>
     <div class="spinner"></div>
   {{/if}}
   {{/if}}
-</div>
+</div>

+ 23 - 0
ambari-web/app/utils/config.js

@@ -942,6 +942,29 @@ App.config = Em.Object.create({
     if (snCategory && activeNn) {
     if (snCategory && activeNn) {
       configCategories.removeObject(snCategory);
       configCategories.removeObject(snCategory);
     }
     }
+  },
+  
+
+  /**
+   * Gets all the configuration-groups for the given service.
+   * 
+   * @param serviceId
+   *          (string) ID of the service. Ex: HDFS
+   * @return Array of App.ConfigGroups
+   */
+  getConfigGroupsForService: function (serviceId) {
+
+  },
+
+  /**
+   * Gets all the configuration-groups for a host.
+   * 
+   * @param hostName
+   *          (string) host name used to register
+   * @return Array of App.ConfigGroups
+   */
+  getConfigGroupsForHost: function (hostName) {
+
   }
   }
 
 
 });
 });