You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by pa...@apache.org on 2016/09/02 08:17:23 UTC

ambari git commit: AMBARI-18261. CapSched View: Showing warning icons to refresh or restart capsched once after configs are saved (Akhil PB via pallavkul)

Repository: ambari
Updated Branches:
  refs/heads/trunk 8f7506c5a -> 1f18805d3


AMBARI-18261. CapSched View: Showing warning icons to refresh or restart capsched once after configs are saved (Akhil PB via pallavkul)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1f18805d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1f18805d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1f18805d

Branch: refs/heads/trunk
Commit: 1f18805d3022020525c2d4b6ef97b9c0ad818b72
Parents: 8f7506c
Author: Pallav Kulshreshtha <pa...@gmail.com>
Authored: Fri Sep 2 13:46:40 2016 +0530
Committer: Pallav Kulshreshtha <pa...@gmail.com>
Committed: Fri Sep 2 13:46:40 2016 +0530

----------------------------------------------------------------------
 .../src/main/resources/ui/app/adapters.js       |  19 +++-
 .../ui/app/components/capacityInput.js          |  21 +++-
 .../ui/app/components/editLabelCapacity.js      |   8 +-
 .../ui/app/components/editQueueCapacity.js      |   8 +-
 .../ui/app/components/labelCapacityBar.js       |   2 +
 .../resources/ui/app/components/queueMapping.js |   1 +
 .../resources/ui/app/components/queueSummary.js |  40 +++++--
 .../ui/app/components/saveConfigDialog.js       |   3 +-
 .../resources/ui/app/controllers/advanced.js    |   8 +-
 .../resources/ui/app/controllers/editqueue.js   |  71 +++++++++++-
 .../resources/ui/app/controllers/queuesconf.js  |  32 ++++--
 .../resources/ui/app/controllers/scheduler.js   |  17 ++-
 .../src/main/resources/ui/app/models/queue.js   |   7 +-
 .../src/main/resources/ui/app/router.js         | 110 +++++++++++++++++--
 .../src/main/resources/ui/app/store.js          |  11 ++
 .../resources/ui/app/styles/application.less    |   8 ++
 .../ui/app/templates/capsched/advanced.hbs      |  11 +-
 .../capsched/partials/accessControlList.hbs     |   6 +-
 .../capsched/partials/labelCapacity.hbs         |  30 +++--
 .../templates/capsched/partials/preemption.hbs  |  82 ++++++++------
 .../capsched/partials/queueCapacity.hbs         |  14 ++-
 .../capsched/partials/queueResources.hbs        |   6 +-
 .../ui/app/templates/capsched/queuesconf.hbs    |  10 +-
 .../ui/app/templates/capsched/scheduler.hbs     |  25 +++--
 .../templates/components/editQueueCapacity.hbs  |   4 +-
 .../app/templates/components/queueMapping.hbs   |   5 +-
 .../app/templates/components/queueSummary.hbs   |   8 +-
 27 files changed, 452 insertions(+), 115 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
index f300b5b..e4f7df9 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
@@ -256,9 +256,9 @@ App.QueueAdapter = DS.Adapter.extend({
         var parsedData = JSON.parse(data), labels;
 
         if (parsedData !== null) {
-          store.set('isNodeLabelsEnabledByRM', true);
+          store.set('isNodeLabelsConfiguredByRM', true);
         } else {
-          store.set('isNodeLabelsEnabledByRM', false);
+          store.set('isNodeLabelsConfiguredByRM', false);
         }
 
         if (stackVersion >= 2.5) {
@@ -320,6 +320,21 @@ App.QueueAdapter = DS.Adapter.extend({
         }
       });
     }.bind(this),'App: QueueAdapter#checkCluster');
+  },
+
+  getRmSchedulerConfigInfo: function() {
+    var uri = [_getCapacitySchedulerViewUri(this), 'rmCurrentConfig'].join('/');
+    if (App.testMode) {
+      uri = uri + ".json";
+    }
+    return new Ember.RSVP.Promise(function(resolve, reject) {
+      _ajax(uri, 'GET').then(function(data) {
+        Ember.run(null, resolve, data);
+      }, function(jqXHR) {
+        jqXHR.then = null;
+        Ember.run(null, reject, jqXHR);
+      });
+    }.bind(this),'App: QueueAdapter#getRmSchedulerConfigInfo');
   }
 });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/capacityInput.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/capacityInput.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/capacityInput.js
index b86719f..8f0246a 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/capacityInput.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/capacityInput.js
@@ -159,11 +159,28 @@ App.DecimalCapacityInputComponent = Ember.TextField.extend({
     return parseFloat(val) <= 100;
   },
 
+  debounceId: null,
+  cancelDebounceCallback: function() {
+    Ember.run.cancel(this.get('debounceId'));
+    this.set('debounceId', null);
+  },
+  initDebounceCallback: function(val, maxVal) {
+    var debounce = Ember.run.debounce(this, function() {
+      this.set('value', (parseFloat(val) > maxVal)? parseFloat(maxVal) : parseFloat(val));
+    }, 3000);
+    this.set('debounceId', debounce);
+  },
+
   valueDidChange: function() {
     var val = this.get('value'),
     maxVal = this.get('maxVal');
-    if (/^\d+(\.\d{1,2})?$/.test(val)) {
-      this.set('value', (parseFloat(val) > maxVal)? parseFloat(maxVal) : parseFloat(val));
+    this.cancelDebounceCallback();
+    if (/^\d+(\.(\d{1,2})?)?$/.test(val)) {
+      if (/^\d+\.[0]$/.test(val) || /^\d+\.$/.test(val)) {
+        this.initDebounceCallback(val, maxVal);
+      } else {
+        this.set('value', (parseFloat(val) > maxVal)? parseFloat(maxVal) : parseFloat(val));
+      }
     }
   }.observes('value').on('change')
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/editLabelCapacity.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/editLabelCapacity.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/editLabelCapacity.js
index ed22c2b..bfdfae6 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/editLabelCapacity.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/editLabelCapacity.js
@@ -59,11 +59,15 @@ App.EditLabelCapacityComponent = Ember.Component.extend({
   }.property('parentQueue', 'parentQueue.labels.[]'),
 
   isLabelCapacityDirty: function() {
-    return this.get('label').changedAttributes().hasOwnProperty('capacity');
+    var isDirty = this.get('label').changedAttributes().hasOwnProperty('capacity');
+    this.set('label.isDirtyLabelCapacity', isDirty);
+    return isDirty;
   }.property('label.capacity'),
 
   isLabelMaxCapacityDirty: function() {
-    return this.get('label').changedAttributes().hasOwnProperty('maximum_capacity');
+    var isDirty = this.get('label').changedAttributes().hasOwnProperty('maximum_capacity');
+    this.set('label.isDirtyLabelMaxCapacity', isDirty);
+    return isDirty;
   }.property('label.maximum_capacity'),
 
   isInvalidLabelMaxCapacity: function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/editQueueCapacity.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/editQueueCapacity.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/editQueueCapacity.js
index b244097..a594a45 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/editQueueCapacity.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/editQueueCapacity.js
@@ -33,11 +33,15 @@ App.EditQueueCapacityComponent = Ember.Component.extend({
   },
 
   isQueueCapacityDirty: function() {
-    return this.get('queue').changedAttributes().hasOwnProperty('capacity');
+    var isDirty = this.get('queue').changedAttributes().hasOwnProperty('capacity');
+    this.set('queue.isDirtyCapacity', isDirty);
+    return isDirty;
   }.property('queue.capacity'),
 
   isQueueMaximumCapacityDirty: function() {
-    return this.get('queue').changedAttributes().hasOwnProperty('maximum_capacity');
+    var isDirty = this.get('queue').changedAttributes().hasOwnProperty('maximum_capacity');
+    this.set('queue.isDirtyMaxCapacity', isDirty);
+    return isDirty;
   }.property('queue.maximum_capacity'),
 
   isInvalidQueueMaximumCapacity: function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/labelCapacityBar.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/labelCapacityBar.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/labelCapacityBar.js
index 89e7cac..7776452 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/labelCapacityBar.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/labelCapacityBar.js
@@ -23,6 +23,7 @@ App.LabelCapacityBarComponent = Ember.Component.extend({
   queueLabels: null,
   labels: null,
   queues: null,
+  warnInvalidTotalLabelCapacity: false,
 
   extractLabels: function() {
     var qLabels = this.get('queueLabels'),
@@ -53,6 +54,7 @@ App.LabelCapacityBarComponent = Ember.Component.extend({
       isInvalid = true;
     }
     this.get('labels').setEach('overCapacity', isInvalid);
+    this.set('warnInvalidTotalLabelCapacity', isInvalid);
     return isInvalid;
   }.property('childrenQueueLabelsTotalCapacity'),
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js
index 8118805..107b377 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueMapping.js
@@ -33,6 +33,7 @@
    customGroupMappings: '',
    selectedLeafQueueNameForUsers: null,
    selectedLeafQueueNameForGroups: null,
+   isQueueMappingsDirty: false,
 
    actions: {
      showMappingOptions: function(){

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js
index c15f100..2690c40 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/queueSummary.js
@@ -29,14 +29,31 @@
    precision: 2,
    queuesNeedRefresh: null,
 
-   isQueueNeedRefreshOrRestart: function() {
+   isQueueStateNeedRefresh: function() {
      var qsNeedRefresh = this.get('queuesNeedRefresh'),
-     qq = this.get('queue');
+      qq = this.get('queue');
+
      if (qsNeedRefresh && qsNeedRefresh.findBy('path', qq.get('path'))) {
        return true;
+     } else if (this.get('isDirtyState')) {
+       return true;
+     } else {
+       return false;
      }
-     return false;
-   }.property('queuesNeedRefresh.[]', 'queue'),
+   }.property('queuesNeedRefresh.[]', 'queue', 'isDirtyState'),
+
+   isQueueCapacityNeedRefresh: function() {
+     var qsNeedRefresh = this.get('queuesNeedRefresh'),
+      qq = this.get('queue');
+
+     if (qsNeedRefresh && qsNeedRefresh.findBy('path', qq.get('path'))) {
+       return true;
+     } else if (this.get('isDirtyCapacity')) {
+       return true;
+     } else {
+       return false;
+     }
+   }.property('queuesNeedRefresh.[]', 'queue', 'isDirtyCapacity'),
 
    isRunningState: function() {
      return this.get('queue.state') === _runState || this.get('queue.state') === null;
@@ -66,21 +83,28 @@
      return this.get('queue').changedAttributes().hasOwnProperty('state');
    }.property('queue.state'),
 
+   isDirtyCapacity: function() {
+     return this.get('queue').changedAttributes().hasOwnProperty('capacity');
+   }.property('queue.capacity'),
+
    isNewQueue: function() {
      return this.get('queue.isNewQueue');
    }.property('queue.isNewQueue'),
 
    effectiveCapacity: function() {
      var currentQ = this.get('queue'),
-     allQueues = this.get('allQueues'),
-     effectiveCapacityRatio = 1;
+       allQueues = this.get('allQueues'),
+       effectiveCapacityRatio = 1;
+
      while (currentQ !== null) {
        effectiveCapacityRatio *= (currentQ.get('capacity') / 100);
        currentQ = allQueues.findBy('id', currentQ.get('parentPath').toLowerCase()) || null;
      }
+
      var effectiveCapacityPercent = effectiveCapacityRatio * 100,
-     absoluteCapacity = parseFloat(parseFloat(effectiveCapacityPercent).toFixed(this.get('precision')));
-     this.get('queue').set('absolute_capacity', absoluteCapacity || 0);
+       absoluteCapacity = parseFloat(parseFloat(effectiveCapacityPercent).toFixed(this.get('precision')));
+       this.get('queue').set('absolute_capacity', absoluteCapacity || 0);
+
      return absoluteCapacity;
    }.property('queue.capacity', 'allQueues.@each.capacity', 'allQueues.length')
  });

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/saveConfigDialog.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/saveConfigDialog.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/saveConfigDialog.js
index ea5262d..ec17e3f 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/saveConfigDialog.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/components/saveConfigDialog.js
@@ -23,12 +23,13 @@ App.SaveConfigDialogComponent = Ember.Component.extend({
  isDialogOpen: false,
  configNote: '',
  param: '',
+ forceRefresh: false,
 
  actions: {
    saveConfigs: function() {
      this.set('isDialogOpen', false);
      var mode = this.get('param');
-     this.sendAction('action', mode);
+     this.sendAction('action', mode, this.get('forceRefresh'));
    },
    closeDialog: function() {
      this.set('isDialogOpen', false);

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js
index edd8a3b..c079079 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/advanced.js
@@ -53,6 +53,8 @@ App.CapschedAdvancedController = Ember.Controller.extend({
 
   isQueueMappingsDirty: false,
   queueMappingProps: ['queue_mappings', 'queue_mappings_override_enable'],
+  isRefreshOrRestartNeeded: false,
+  isQueueMappignsNeedSaveOrRefresh: cmp.or('isQueueMappingsDirty', 'isRefreshOrRestartNeeded'),
 
   saveMode: '',
 
@@ -69,6 +71,10 @@ App.CapschedAdvancedController = Ember.Controller.extend({
       return attributes.hasOwnProperty(prop);
     });
     this.set('isQueueMappingsDirty', isDirty);
-  }.observes('scheduler.queue_mappings', 'scheduler.queue_mappings_override_enable')
+    this.set('isRefreshOrRestartNeeded', isDirty);
+  }.observes('scheduler.queue_mappings', 'scheduler.queue_mappings_override_enable'),
 
+  forceRefreshRequired: function() {
+    return !this.get('isQueueMappingsDirty') && this.get('isRefreshOrRestartNeeded');
+  }.property('isQueueMappingsDirty', 'isRefreshOrRestartNeeded')
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js
index dd46b2c..7c62ef0 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/editqueue.js
@@ -22,14 +22,18 @@ var _runState = 'RUNNING';
 var _stopState = 'STOPPED';
 
 App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({
-  needs: ['capsched'],
+  needs: ['capsched', 'capschedQueuesconf'],
   isOperator: Ember.computed.alias('controllers.capsched.isOperator'),
   isNotOperator: Ember.computed.not('isOperator'),
   scheduler: Ember.computed.alias('controllers.capsched.content'),
   allQueues: Ember.computed.alias('controllers.capsched.queues'),
   isNodeLabelsEnabledByRM: Ember.computed.alias('store.isNodeLabelsEnabledByRM'),
+  isNodeLabelsConfiguredByRM: Ember.computed.alias('store.isNodeLabelsConfiguredByRM'),
   isRmOffline: Ember.computed.alias('store.isRmOffline'),
+  queuesNeedRefresh: Ember.computed.alias('store.queuesNeedRefresh'),
   precision: 2,
+  isNodeLabelsEnabledAndConfiguredByRM: Ember.computed.and('isNodeLabelsEnabledByRM', 'isNodeLabelsConfiguredByRM'),
+  isRefreshOrRestartNeeded: Ember.computed.alias('controllers.capschedQueuesconf.isRefreshOrRestartNeeded'),
 
   isRangerEnabledForYarn: function() {
     var isRanger = this.get('controllers.capsched.isRangerEnabledForYarn');
@@ -43,6 +47,14 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({
     return false;
   }.property('controllers.capsched.isRangerEnabledForYarn'),
 
+  isPreemptionEnabledByYarn: function() {
+    var isEnabled = this.get('controllers.capsched.isPreemptionEnabledByYarn');
+    if (isEnabled === 'true') {
+      return true;
+    }
+    return false;
+  }.property('controllers.capsched.isPreemptionEnabledByYarn'),
+
   actions: {
     toggleProperty: function (property, target) {
       target = target || this;
@@ -66,6 +78,11 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({
       }
       this.set('content.name', this.get('updatedQName'));
       this.set('enableEditQName', false);
+    },
+    rollbackPreemptionProps: function() {
+      this.send('rollbackProp', 'disable_preemption', this.get('content'));
+      this.send('rollbackProp', 'isPreemptionInherited', this.get('content'));
+      this.set('content.isPreemptionOverriden', false);
     }
   },
 
@@ -232,6 +249,19 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({
      return this.get('scheduler.maximum_am_resource_percent');
    },
 
+   isAnyQueueResourcesDirty: function() {
+     return this.get('queueDirtyFields.user_limit_factor') || this.get('queueDirtyFields.minimum_user_limit_percent')
+      || this.get('queueDirtyFields.maximum_applications') || this.get('queueDirtyFields.maximum_am_resource_percent')
+      || this.get('queueDirtyFields.ordering_policy') || this.get('queueDirtyFields.enable_size_based_weight');
+   }.property(
+     'content.user_limit_factor',
+     'content.minimum_user_limit_percent',
+     'content.maximum_applications',
+     'content.maximum_am_resource_percent',
+     'content.ordering_policy',
+     'content.enable_size_based_weight'
+   ),
+
    /**
     * Sets ACL value to '*' or ' ' and returns '*' and 'custom' respectively.
     * @param  {String} key   - ACL attribute
@@ -351,6 +381,10 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({
       return permissions;
     },
 
+    isAnyAccessControlListDirty: function() {
+      return this.get('queueDirtyFields.acl_administer_queue') || this.get('queueDirtyFields.acl_submit_applications');
+    }.property('content.acl_submit_applications', 'content.acl_administer_queue'),
+
     /**
      * Array of children queues.
      * @return {Array}
@@ -405,6 +439,13 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({
       return this.get('widthPattern').fmt(totalCap);
     }.property('childrenQueuesTotalCapacity'),
 
+    isAnyChildrenQueueCapacityDirty: function() {
+      if (this.get('isLeafQ')) {
+        return false;
+      }
+      return this.get('queueDirtyFields.queues') || this.get('childrenQueues').anyBy('isDirtyCapacity', true) || this.get('childrenQueues').anyBy('isDirtyMaxCapacity', true);
+    }.property('content', 'content.queues', 'childrenQueues.@each.isDirtyCapacity', 'childrenQueues.@each.isDirtyMaxCapacity'),
+
    /**
     * Adds observers for each queue attribute.
     * @method dirtyObserver
@@ -544,6 +585,26 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({
      return this.get('selectedDefaultNodeLabel') !== 'None';
    }.property('selectedDefaultNodeLabel'),
 
+   childrenLabelsForQueue: function() {
+     var childrenLabels = [];
+     this.get('childrenQueues').forEach(function(child){
+       child.get('labels').forEach(function(label){
+         childrenLabels.addObject(label);
+       });
+     });
+     return childrenLabels;
+   }.property('childrenQueues.length', 'childrenQueues.@each.labels.[]'),
+
+   warnInvalidTotalLabelCapacity: false,
+
+   isAnyChildrenQueueLabelDirty: function() {
+     if (this.get('isLeafQ')) {
+       return this.get('queueDirtyFields.default_node_label_expression') || false;
+     }
+     return this.get('childrenQueues').anyBy('isLabelsDirty', true) || this.get('queueDirtyFields.default_node_label_expression')
+      || this.get('childrenLabelsForQueue').anyBy('isDirtyLabelCapacity', true) || this.get('childrenLabelsForQueue').anyBy('isDirtyLabelMaxCapacity', true);
+   }.property('content', 'childrenQueues.@each.isLabelsDirty', 'childrenLabelsForQueue.@each.isDirtyLabelCapacity', 'childrenLabelsForQueue.@each.isDirtyLabelMaxCapacity', 'content.default_node_label_expression'),
+
    //Preemption
    isPreemptionSupported: Ember.computed.alias('store.isPreemptionSupported'),
    currentStack: Ember.computed.alias('store.stackId'),
@@ -598,7 +659,7 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({
      }
    }.property('content.disable_preemption', 'content.isPreemptionInherited'),
 
-   preemptionOvierideWatcher: function() {
+   preemptionOverrideWatcher: function() {
      var override = this.get('content.isPreemptionOverriden'),
      wasInheritedInitially = (this.get('content').changedAttributes().hasOwnProperty('isPreemptionInherited')
       && this.get('content').changedAttributes()['isPreemptionInherited'][0] === true);
@@ -606,6 +667,10 @@ App.CapschedQueuesconfEditqueueController = Ember.Controller.extend({
        this.set('content.isPreemptionInherited', true);
        this.set('content.disable_preemption', '');
      }
-   }.observes('content.isPreemptionOverriden')
+   }.observes('content.isPreemptionOverriden'),
 
+   saveRefreshRestartWatcher: function() {
+     this.set('isRefreshOrRestartNeeded', this.get('isAnyQueueResourcesDirty') || this.get('isAnyAccessControlListDirty')
+      || this.get('isAnyChildrenQueueCapacityDirty') || this.get('isAnyChildrenQueueLabelDirty') || this.get('isQueuePreemptionDirty'));
+   }.observes('isAnyQueueResourcesDirty', 'isAnyAccessControlListDirty', 'isAnyChildrenQueueCapacityDirty', 'isAnyChildrenQueueLabelDirty', 'isQueuePreemptionDirty')
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js
index a68a2aa..6a6717a 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queuesconf.js
@@ -22,14 +22,16 @@ var _runState = 'RUNNING';
 var _stopState = 'STOPPED';
 
 App.CapschedQueuesconfController = Ember.Controller.extend({
-  needs: ['capsched', 'loading'],
+  needs: ['capsched'],
   queues: Ember.computed.alias('controllers.capsched.queues'),
   isOperator: Ember.computed.alias('controllers.capsched.isOperator'),
   allNodeLabels: Ember.computed.alias('store.nodeLabels.content'),
   isRmOffline: Ember.computed.alias('store.isRmOffline'),
   isNodeLabelsEnabledByRM: Ember.computed.alias('store.isNodeLabelsEnabledByRM'),
+  isNodeLabelsConfiguredByRM: Ember.computed.alias('store.isNodeLabelsConfiguredByRM'),
   allNodeLabelRecords: [],
   queuesNeedRefresh: Ember.computed.alias('store.queuesNeedRefresh'),
+  isRefreshOrRestartNeeded: false,
 
   actions: {
     addNewQueue: function() {
@@ -67,7 +69,7 @@ App.CapschedQueuesconfController = Ember.Controller.extend({
         depth: depth,
         isNewQueue: true,
         capacity: qCapacity,
-        maximum_capacity: qCapacity
+        maximum_capacity: 100
       });
       this.set('newQueue', newQueue);
       store.saveAndUpdateQueue(newQueue).then(Em.run.bind(this, 'saveAndUpdateQueueSuccess', newQueue));
@@ -141,9 +143,15 @@ App.CapschedQueuesconfController = Ember.Controller.extend({
   },
 
   isAnyQueueDirty: function() {
-    return this.get('queues').isAny('isAnyDirty');
+    return this.get('queues').isAny('isAnyDirty', true);
   }.property('queues.@each.isAnyDirty'),
 
+  isQueuesNeedRefreshOrRestart: Ember.computed.or('isAnyQueueDirty', 'needRefresh', 'needRestart', 'isRefreshOrRestartNeeded'),
+
+  forceRefreshOrRestartRequired: function() {
+    return !this.get('isAnyQueueDirty') && this.get('isRefreshOrRestartNeeded');
+  }.property('isAnyQueueDirty', 'isRefreshOrRestartNeeded'),
+
   selectedQueue: null,
   newQueue: null,
   newQueueName: '',
@@ -174,7 +182,7 @@ App.CapschedQueuesconfController = Ember.Controller.extend({
   }.observes('newQueueName', 'newQueueName.length'),
 
   initNodeLabelRecords: function() {
-    if (!this.get('isNodeLabelsEnabledByRM') || this.get('isRmOffline')) {
+    if (!this.get('isNodeLabelsEnabledByRM') || !this.get('isNodeLabelsConfiguredByRM') || this.get('isRmOffline')) {
       return;
     }
     this.setDefaultNodeLabelAccesses('root');
@@ -189,10 +197,12 @@ App.CapschedQueuesconfController = Ember.Controller.extend({
       nonAccessible = [];
       allLabels.forEach(function(label) {
         var qLabel = store.getById('label', [queue.get('path'), label.name].join('.'));
-        if (!queue.get('labels').contains(qLabel)) {
-          nonAccessible.pushObject(qLabel);
+        if (qLabel) {
+          if (!queue.get('labels').contains(qLabel)) {
+            nonAccessible.pushObject(qLabel);
+          }
+          records.pushObject(qLabel);
         }
-        records.pushObject(qLabel);
       });
       queue.set('nonAccessibleLabels', nonAccessible);
     });
@@ -211,12 +221,16 @@ App.CapschedQueuesconfController = Ember.Controller.extend({
       if (parentQ && parentQ.get('labels.length') > 0) {
         parentQ.get('labels').forEach(function(label) {
           var qlabel = store.getById('label', [queue.get('path'), label.get('name')].join('.'));
-          queue.addQueueNodeLabel(qlabel);
+          if (qlabel) {
+            queue.addQueueNodeLabel(qlabel);
+          }
         });
       } else {
         allLabels.forEach(function(label) {
           var qlabel = store.getById('label', [queue.get('path'), label.name].join('.'));
-          queue.addQueueNodeLabel(qlabel);
+          if (qlabel) {
+            queue.addQueueNodeLabel(qlabel);
+          }
         });
       }
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js
index 6638b4c..40e3e24 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/scheduler.js
@@ -24,6 +24,7 @@ App.CapschedSchedulerController = Ember.Controller.extend({
   needs: ['capsched'],
   scheduler: cmp.alias('controllers.capsched.content'),
   schedulerProps: ['maximum_am_resource_percent', 'maximum_applications', 'node_locality_delay', 'resource_calculator'],
+  isRefreshOrRestartNeeded: false,
 
   actions: {
     rollbackSchedulerProps: function() {
@@ -60,21 +61,29 @@ App.CapschedSchedulerController = Ember.Controller.extend({
 
   isSchedulerDirty: false,
 
+  isSchedulerPropsNeedSaveOrRestart: cmp.or('isRefreshOrRestartNeeded', 'isSchedulerDirty'),
+
+  forceRestartRequired: function() {
+    return !this.get('isSchedulerDirty') && this.get('isRefreshOrRestartNeeded');
+  }.property('isSchedulerDirty', 'isRefreshOrRestartNeeded'),
+
   schedulerBecomeDirty: function() {
     var sched = this.get('scheduler'),
-    attributes = sched.changedAttributes(),
-    props = this.schedulerProps;
+      attributes = sched.changedAttributes(),
+      props = this.schedulerProps;
+
     var isDirty = props.any(function(prop){
       return attributes.hasOwnProperty(prop);
     });
     this.set('isSchedulerDirty', isDirty);
+    this.set('isRefreshOrRestartNeeded', isDirty);
   }.observes('scheduler.maximum_am_resource_percent', 'scheduler.maximum_applications', 'scheduler.node_locality_delay', 'scheduler.resource_calculator'),
 
   /**
    * Collection of modified fields in Scheduler.
    * @type {Object} - { [fileldName] : {Boolean} }
    */
-  schedulerDirtyFilelds: {},
+  schedulerDirtyFields: {},
 
   dirtyObserver:function () {
     this.get('scheduler.constructor.transformedAttributes.keys.list').forEach(function(item) {
@@ -84,7 +93,7 @@ App.CapschedSchedulerController = Ember.Controller.extend({
 
   propertyBecomeDirty:function (controller, property) {
     var schedProp = property.split('.').objectAt(1);
-    this.set('schedulerDirtyFilelds.' + schedProp, this.get('scheduler').changedAttributes().hasOwnProperty(schedProp));
+    this.set('schedulerDirtyFields.' + schedProp, this.get('scheduler').changedAttributes().hasOwnProperty(schedProp));
   },
 
   resourceCalculatorValues: [{

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
index acf6465..0f68a10 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
@@ -42,7 +42,9 @@ App.Label = DS.Model.extend({
   },
   setMaxCapacity: function(maxCap) {
     this.set('maximum_capacity', maxCap);
-  }
+  },
+  isDirtyLabelCapacity: false,
+  isDirtyLabelMaxCapacity: false
 });
 
 App.Scheduler = DS.Model.extend({
@@ -243,11 +245,14 @@ App.Queue = DS.Model.extend({
   capacity: DS.attr('number', { defaultValue: 0 }),
   maximum_capacity: DS.attr('number', { defaultValue: 0 }),
   //unfunded_capacity: DS.attr('number', { defaultValue: 0 }),
+  isDirtyCapacity: false,
+  isDirtyMaxCapacity: false,
 
   user_limit_factor: DS.attr('number', { defaultValue: 1 }),
   minimum_user_limit_percent: DS.attr('number', { defaultValue: 100 }),
   maximum_applications: DS.attr('number', { defaultValue: null }),
   maximum_am_resource_percent: DS.attr('number', { defaultValue: null }),
+
   disable_preemption: DS.attr('string', {defaultValue: ''}),
   isPreemptionInherited: DS.attr('boolean', {defaultValue: true}),
   isPreemptionOverriden: false,

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
index 0b13a8a..fd996ae 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
@@ -36,6 +36,10 @@ App.Router.map(function() {
 
 var RANGER_SITE = 'ranger-yarn-plugin-properties';
 var RANGER_YARN_ENABLED = 'ranger-yarn-plugin-enabled';
+
+var YARN_SITE = 'yarn-site';
+var PREEMPTION_YARN_ENABLE = 'yarn.resourcemanager.scheduler.monitor.enable';
+var NODE_LABELS_YARN_ENABLED = 'yarn.node-labels.enabled';
 /**
  * The queues route.
  *
@@ -204,10 +208,22 @@ App.CapschedRoute = Ember.Route.extend({
         item.set(prop, attributes[prop][0]);
       }
     },
-    saveCapSchedConfigs: function(saveMode) {
+    saveCapSchedConfigs: function(saveMode, forceRefresh) {
       var store = this.get('store'),
         that = this,
-        capschedCtrl = this.controllerFor("capsched");
+        capschedCtrl = this.controllerFor("capsched"),
+        schedulerCtrl = this.controllerFor("capsched.scheduler"),
+        queuesconfCtrl = this.controllerFor("capsched.queuesconf"),
+        advancedCtrl = this.controllerFor("capsched.advanced"),
+        restartOrRefreshMap = {
+          schedulerTab: schedulerCtrl.get('isRefreshOrRestartNeeded') || false,
+          queuesTab: queuesconfCtrl.get('isRefreshOrRestartNeeded') || false,
+          advancedTab: advancedCtrl.get('isRefreshOrRestartNeeded') || false
+        };
+
+      if (forceRefresh) {
+        return this.forceRefreshOrRestartCapSched(saveMode);
+      }
 
       var collectedLabels = capschedCtrl.get('queues').reduce(function (prev,q) {
         return prev.pushObjects(q.get('labels.content'));
@@ -224,21 +240,37 @@ App.CapschedRoute = Ember.Route.extend({
         opt = 'saveAndRefresh';
       }
 
-      capschedCtrl.startSpinner();
+      capschedCtrl.startSpinner(saveMode);
       Em.RSVP.Promise.all([labels, queues, scheduler]).then(
         Em.run.bind(that,'saveConfigsSuccess'),
         Em.run.bind(that,'saveConfigsError', 'save')
       ).then(function () {
+        schedulerCtrl.set('isRefreshOrRestartNeeded', restartOrRefreshMap.schedulerTab);
+        queuesconfCtrl.set('isRefreshOrRestartNeeded', restartOrRefreshMap.queuesTab);
+        advancedCtrl.set('isRefreshOrRestartNeeded', restartOrRefreshMap.advancedTab);
         if (opt) {
           return store.relaunchCapSched(opt);
         }
       }).then(function(){
+        if (opt) {
+          schedulerCtrl.set('isRefreshOrRestartNeeded', false);
+          queuesconfCtrl.set('isRefreshOrRestartNeeded', false);
+          advancedCtrl.set('isRefreshOrRestartNeeded', false);
+        }
         return store.getRmSchedulerConfigInfo();
       }).catch(
         Em.run.bind(this,'saveConfigsError', opt)
       ).finally(function(){
         capschedCtrl.stopSpinner();
+        store.setLastSavedConfigXML();
       });
+    },
+    viewConfigXmlDiff: function() {
+      var store = this.get('store'),
+        controller = this.controllerFor("capsched"),
+        lastSavedXML = store.get('lastSavedConfigXML'),
+        currentXmlConfigs = store.buildConfig('xml'),
+        diffConfigs = {baseXML: lastSavedXML, newXML: currentXmlConfigs};
     }
   },
   beforeModel: function(transition) {
@@ -265,14 +297,29 @@ App.CapschedRoute = Ember.Route.extend({
         });
         return store.get('nodeLabels');
       }).then(function() {
-        return store.findQuery('config', {
+        var rangerEnabled = store.findQuery('config', {
           siteName: RANGER_SITE,
           configName: RANGER_YARN_ENABLED
-        }).then(function() {
-          return store.find('config', "siteName_" + RANGER_SITE + "_configName_" + RANGER_YARN_ENABLED)
-            .then(function(data) {
-              controller.set('isRangerEnabledForYarn', data.get('configValue'));
-            });
+        });
+        var nodeLabelsEnabled = store.findQuery('config', {
+          siteName: YARN_SITE,
+          configName: NODE_LABELS_YARN_ENABLED
+        });
+        var preemptionEnabled = store.findQuery('config', {
+          siteName: YARN_SITE,
+          configName: PREEMPTION_YARN_ENABLE
+        });
+        Ember.RSVP.Promise.all([rangerEnabled, nodeLabelsEnabled, preemptionEnabled]).then(function() {
+          var rangerConfig = store.getById('config', "siteName_" + RANGER_SITE + "_configName_" + RANGER_YARN_ENABLED),
+            nodeLabelConfig = store.getById('config', "siteName_" + YARN_SITE + "_configName_" + NODE_LABELS_YARN_ENABLED),
+            preemptionConfig = store.getById('config', "siteName_" + YARN_SITE + "_configName_" + PREEMPTION_YARN_ENABLE),
+            rangerValue = rangerConfig.get('configValue'),
+            nodeLabelValue = nodeLabelConfig.get('configValue'),
+            preemptionValue = preemptionConfig.get('configValue');
+
+          controller.set('isRangerEnabledForYarn', rangerValue);
+          store.set('isNodeLabelsEnabledByRM', nodeLabelValue === "true");
+          controller.set('isPreemptionEnabledByYarn', preemptionValue);
         });
       }).then(function() {
         loadingController.set('model', {
@@ -288,6 +335,7 @@ App.CapschedRoute = Ember.Route.extend({
       }).then(function() {
         return store.find('scheduler', 'scheduler');
       }).then(function(scheduler){
+        store.setLastSavedConfigXML();
         resolve(scheduler);
       }).catch(function(e) {
         reject(e);
@@ -295,7 +343,7 @@ App.CapschedRoute = Ember.Route.extend({
     }, 'App: CapschedRoute#model');
   },
   loadingError: function (transition, error) {
-    var refuseController = this.container.lookup('controller:capsched.refuse') || this.generateController('capsched.refuse'),
+    var refuseController = this.container.lookup('controller:refuse') || this.generateController('refuse'),
         message = error.responseJSON || {'message': 'Something went wrong.'};
 
     transition.abort();
@@ -306,10 +354,41 @@ App.CapschedRoute = Ember.Route.extend({
     this.set('store.deletedQueues', []);
   },
   saveConfigsError: function(operation, err) {
-    var response = error.responseJSON || {};
+    this.controllerFor("capsched").stopSpinner();
+    var response = {};
+    if (err && err.responseJSON) {
+      response = err.responseJSON;
+    }
     response.simpleMessage = operation.capitalize() + ' failed!';
     this.controllerFor("capsched").set('alertMessage', response);
-    throw Error(err);
+    throw Error("Configs Error: ", err);
+  },
+  forceRefreshOrRestartCapSched: function(saveMode) {
+    var opt = '',
+      that = this,
+      store = this.get('store'),
+      capschedCtrl = this.controllerFor("capsched"),
+      schedulerCtrl = this.controllerFor("capsched.scheduler"),
+      queuesconfCtrl = this.controllerFor("capsched.queuesconf"),
+      advancedCtrl = this.controllerFor("capsched.advanced");
+
+    if (saveMode == 'restart') {
+      opt = 'saveAndRestart';
+    } else {
+      opt = 'saveAndRefresh';
+    }
+
+    capschedCtrl.startSpinner(saveMode);
+    store.relaunchCapSched(opt).then(function() {
+      schedulerCtrl.set('isRefreshOrRestartNeeded', false);
+      advancedCtrl.set('isRefreshOrRestartNeeded', false);
+      queuesconfCtrl.set('isRefreshOrRestartNeeded', false);
+    }).catch(
+      Em.run.bind(that, 'saveConfigsError', opt)
+    ).finally(function() {
+      capschedCtrl.stopSpinner();
+      store.setLastSavedConfigXML();
+    });
   }
 });
 
@@ -327,6 +406,13 @@ App.CapschedQueuesconfIndexRoute = Ember.Route.extend({
 });
 
 App.CapschedQueuesconfEditqueueRoute = Ember.Route.extend({
+  model: function(params, transition) {
+    var queue = this.store.getById('queue', params.queue_id);
+    if (queue) {
+      return queue;
+    }
+    this.transitionTo('capsched.queuesconf.editqueue', this.store.getById('queue', 'root'));
+  },
   setupController: function(controller, model) {
     controller.set('model', model);
     this.controllerFor('capsched.queuesconf').set('selectedQueue', model);

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/store.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/store.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/store.js
index 01a7d6a..dce00c1 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/store.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/store.js
@@ -174,6 +174,12 @@ App.ApplicationStore = DS.Store.extend({
 
   queuesNeedRefresh: [],
 
+  lastSavedConfigXML: '',
+
+  setLastSavedConfigXML: function() {
+    this.set('lastSavedConfigXML', this.buildConfig('xml'));
+  },
+
   buildConfig: function (fmt) {
     var records = [],
         config = '',
@@ -214,6 +220,9 @@ App.ApplicationStore = DS.Store.extend({
         this.get('deletedQueues').pushObject(this.buildDeletedQueue(queue));
       }
 
+      if (this.get('queuesNeedRefresh').findBy('path', queue.get('path'))) {
+        this.get('queuesNeedRefresh').removeObject(this.get('queuesNeedRefresh').findBy('path', queue.get('path')));
+      }
     }
     this.all('queue').findBy('path',queue.get('parentPath')).set('queuesArray',{'exclude':queue.get('name')});
     return queue.destroyRecord();
@@ -358,6 +367,8 @@ App.ApplicationStore = DS.Store.extend({
 
   isNodeLabelsEnabledByRM: false,
 
+  isNodeLabelsConfiguredByRM: false,
+
   isInitialized: Ember.computed.and('tag', 'clusterName'),
 
   relaunchCapSched: function (opt) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less b/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less
index 195b55d..bd875ba 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/styles/application.less
@@ -1136,6 +1136,10 @@
       }
     }
   }
+  .resfresh-restart-warning {
+    vertical-align: middle;
+    font-size: 1.5em;
+  }
 }
 
 .queue-summary {
@@ -1249,6 +1253,10 @@
   .capsched-versions-panel {
     .panel-heading {
       margin-bottom: -1px;
+      padding: 6px 15px;
+      .panel-title {
+        font-size: 14px;
+      }
     }
     .panel-body {
       padding: 0px 15px 5px 15px;

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs
index a9ef778..5a54d85 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/advanced.hbs
@@ -20,18 +20,21 @@
   {{!-- QUEUE MAPPING --}}
   {{#if isOperator}}
     <div class="hidden-sm hidden-xs">
-      {{queue-mapping mappings=scheduler.queue_mappings mappingsOverrideEnable=scheduler.queue_mappings_override_enable queues=queues}}
+      {{queue-mapping mappings=scheduler.queue_mappings mappingsOverrideEnable=scheduler.queue_mappings_override_enable queues=queues isQueueMappingsDirty=isQueueMappingsDirty}}
     </div>
   {{/if}}
 </div>
 <div class="row">
-  <div class="btn btn-group-md col-md-offset-3">
+  <div class="btn btn-group-sm col-sm-offset-3">
+    {{#if isQueueMappignsNeedSaveOrRefresh}}
+      {{warning-info class="yellow-warning fa-2x resfresh-restart-warning" tooltip="Refresh queues is required"}}
+    {{/if}}
     <button type="button" {{bind-attr class=":btn :btn-default :btn-success isQueueMappingsDirty::disabled"}} name="saveOnly" {{action "showSaveConfigDialog"}}>Save Only</button>
-    <button type="button" {{bind-attr class=":btn :btn-default :btn-success isQueueMappingsDirty::disabled"}} name="saveRefresh" {{action "showSaveConfigDialog" "refresh"}}>Save And Refresh Queues</button>
+    <button type="button" {{bind-attr class=":btn :btn-default :btn-success isQueueMappignsNeedSaveOrRefresh::disabled"}} name="saveRefresh" {{action "showSaveConfigDialog" "refresh"}}>Save And Refresh Queues</button>
     <button type="button" {{bind-attr class=":btn :btn-default :btn-danger isQueueMappingsDirty::disabled"}} name="cancelAdvanced" {{action "showConfirmDialog"}}>Discard Changes</button>
   </div>
 </div>
 
 {{confirm-discard-changes isDialogOpen=isConfirmDialogOpen action="rollbackQueueMappingProps"}}
 
-{{save-config-dialog isDialogOpen=isSaveConfigDialogOpen configNote=configNote action="saveCapSchedConfigs" param=saveMode}}
+{{save-config-dialog isDialogOpen=isSaveConfigDialogOpen configNote=configNote action="saveCapSchedConfigs" param=saveMode forceRefresh=forceRefreshRequired}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs
index 1f6fbda..922e27e 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/accessControlList.hbs
@@ -20,7 +20,11 @@
   <div class="panel panel-default">
     <div class="panel-heading">
       <div class="panel-title">
-        Access Control List <a id="collapseQueueAclPanelBtn" href="#collapsibleQueueAclPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isAclPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isAclPanelCollapsed:fa-plus:fa-minus"}}></i></a>
+        Access Control List
+        {{#if isAnyAccessControlListDirty}}
+          {{warning-info class="yellow-warning" tooltip="Need refresh queues / restart RM"}}
+        {{/if}}
+        <a id="collapseQueueAclPanelBtn" href="#collapsibleQueueAclPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isAclPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isAclPanelCollapsed:fa-plus:fa-minus"}}></i></a>
       </div>
     </div>
     <div id="collapsibleQueueAclPanel" {{bind-attr class=":panel-collapse :collapse view.isAclPanelCollapsed::in"}}>

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/labelCapacity.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/labelCapacity.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/labelCapacity.hbs
index 9073910..873fb6f 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/labelCapacity.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/labelCapacity.hbs
@@ -20,13 +20,21 @@
   <div class="panel panel-default">
     <div class="panel-heading">
       <div class="panel-title">
-        Label Capacity <a id="collapseLabelCapacityPanelBtn" href="#collapsibleLabelCapacityPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isLabelsPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isLabelsPanelCollapsed:fa-plus:fa-minus"}}></i></a>
+        Label Capacity
+        {{#if isAnyChildrenQueueLabelDirty}}
+          {{#if warnInvalidTotalLabelCapacity}}
+            {{warning-info class="red" tooltip="Invalid label total capacity"}}
+          {{else}}
+            {{warning-info class="yellow-warning" tooltip="Need refresh queues / restart RM"}}
+          {{/if}}
+        {{/if}}
+        <a id="collapseLabelCapacityPanelBtn" href="#collapsibleLabelCapacityPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isLabelsPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isLabelsPanelCollapsed:fa-plus:fa-minus"}}></i></a>
       </div>
     </div>
     <div id="collapsibleLabelCapacityPanel" {{bind-attr class=":panel-collapse :collapse view.isLabelsPanelCollapsed::in"}}>
       <div class="panel-body">
         {{#if isOperator}}
-          {{#if isNodeLabelsEnabledByRM}}
+          {{#if isNodeLabelsEnabledAndConfiguredByRM}}
             <div class="label-names">
               <label>Accessible Node Labels: </label>
               <span>{{accessibleLabelNames}}</span>
@@ -118,7 +126,7 @@
                       {{edit-label-capacity label=row.label queue=row.queue parentQueue=row.parentQueue}}
                     {{/each}}
 
-                    {{label-capacity-bar queueLabels=childQLabel.childrenQueueLabels}}
+                    {{label-capacity-bar queueLabels=childQLabel.childrenQueueLabels warnInvalidTotalLabelCapacity=warnInvalidTotalLabelCapacity}}
                   </div>
                 {{/each}}
               {{else}}
@@ -132,12 +140,16 @@
               {{#if isRmOffline}}
                 <small>Unable to obtain information about the node labels from the resource manager</small>
               {{else}}
-                <small>Node labels are disabled by resource manager. Enable node labels to map the labels to queues.</small>
+                {{#unless isNodeLabelsConfiguredByRM}}
+                  <small>Node labels are not configured by resource manager</small>
+                {{else}}
+                  <small>Node labels are disabled by resource manager. Enable node labels to map the labels to queues.</small>
+                {{/unless}}
               {{/if}}
             </div>
           {{/if}}
         {{else}}
-          {{#if isNodeLabelsEnabledByRM}}
+          {{#if isNodeLabelsEnabledAndConfiguredByRM}}
             <div class="label-names">
               <label>Accessible Node Labels: </label>
               <span>{{accessibleLabelNames}}</span>
@@ -148,7 +160,7 @@
               {{/each}}
             {{else}}
               <div class="">
-                <small>Node labels are not enabled</small>
+                <small>Node labels are not enabled for this queue</small>
               </div>
             {{/if}}
           {{else}}
@@ -156,7 +168,11 @@
               {{#if isRmOffline}}
                 <small>Unable to obtain information about the node labels from the resource manager</small>
               {{else}}
-                <small>Node labels are disabled by resource manager</small>
+                {{#unless isNodeLabelsConfiguredByRM}}
+                  <small>Node labels are not configured by resource manager</small>
+                {{else}}
+                  <small>Node labels are disabled by resource manager</small>
+                {{/unless}}
               {{/if}}
             </div>
           {{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/preemption.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/preemption.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/preemption.hbs
index 73a9e21..d594c7e 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/preemption.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/preemption.hbs
@@ -20,53 +20,65 @@
   <div class="panel panel-default">
     <div class="panel-heading">
       <div class="panel-title">
-        Preemption <a id="collapseQueuePreemptionPanelBtn" href="#collapsibleQueuePreemptionPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isPreemptionPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isPreemptionPanelCollapsed:fa-plus:fa-minus"}}></i></a>
+        Preemption
+        {{#if isQueuePreemptionDirty}}
+          {{warning-info class="yellow-warning" tooltip="Need refresh queues / restart RM"}}
+        {{/if}}
+        <a id="collapseQueuePreemptionPanelBtn" href="#collapsibleQueuePreemptionPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isPreemptionPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isPreemptionPanelCollapsed:fa-plus:fa-minus"}}></i></a>
       </div>
     </div>
     <div id="collapsibleQueuePreemptionPanel" {{bind-attr class=":panel-collapse :collapse view.isPreemptionPanelCollapsed::in"}}>
       <div class="panel-body">
-        {{#if isPreemptionSupported}}
-          <div class="row">
-            <div class="col-sm-10 col-md-10">
-              <label>Can this queue be preempted by other queues: </label>
-              {{#if queueDisablePreemption}}
-                <span class="text-danger">Disabled </span>
-              {{else}}
-                <span class="text-success">Enabled </span>
-              {{/if}}
-              {{#if isPreemptionInherited}}
-                {{#if isRoot}}
-                  <span>(Inherited from global settings)</span>
+        {{#if isPreemptionEnabledByYarn}}
+          {{#if isPreemptionSupported}}
+            <div class="row">
+              <div class="col-sm-10 col-md-10">
+                <label>Can this queue be preempted by other queues: </label>
+                {{#if queueDisablePreemption}}
+                  <span class="text-danger">Disabled </span>
                 {{else}}
-                  <span>(Inherited)</span>
+                  <span class="text-success">Enabled </span>
+                {{/if}}
+                {{#if isPreemptionInherited}}
+                  {{#if isRoot}}
+                    <span>(Inherited from global settings)</span>
+                  {{else}}
+                    <span>(Inherited)</span>
+                  {{/if}}
                 {{/if}}
-              {{/if}}
-              {{#if isQueuePreemptionDirty}}
-                {{warning-info class="yellow-warning" tooltip="Need refresh queues/restart RM"}}
-              {{/if}}
-            </div>
-          </div>
-          <div class="row">
-            <div class="col-sm-4 col-md-4">
-              <div class="checkbox">
-                <label>
-                  {{input type="checkbox" name="preemptionOverride" checked=isPreemptionOverriden}}
-                  Override Preemption
-                </label>
               </div>
             </div>
-            {{#if isPreemptionOverriden}}
-              <div class="col-sm-3 col-md-3">
-                <div class="btn-group btn-group-sm override-btns" data-toggle="buttons">
-                  {{radio-button label="Enable" classNames="btn-small" selectionBinding="doOverridePreemption" value="enable"}}
-                  {{radio-button label="Disable" classNames="btn-small" selectionBinding="doOverridePreemption" value="disable"}}
+            <div class="row">
+              <div class="col-sm-4 col-md-4">
+                <div class="checkbox">
+                  <label>
+                    {{input type="checkbox" name="preemptionOverride" checked=isPreemptionOverriden}}
+                    Override preempt-able settings
+                  </label>
                 </div>
               </div>
-            {{/if}}
-          </div>
+              {{#if isPreemptionOverriden}}
+                <div class="col-sm-4 col-md-4">
+                  <div class="btn-group btn-group-sm override-btns" data-toggle="buttons">
+                    {{radio-button label="Enable" classNames="btn-small" selectionBinding="doOverridePreemption" value="enable"}}
+                    {{radio-button label="Disable" classNames="btn-small" selectionBinding="doOverridePreemption" value="disable"}}
+                  </div>
+                  {{#if isQueuePreemptionDirty}}
+                    <div class="btn-group btn-group-xs override-btns">
+                      <a {{action 'rollbackPreemptionProps'}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
+                    </div>
+                  {{/if}}
+                </div>
+              {{/if}}
+            </div>
+          {{else}}
+            <div class="text-warning">
+              <span>Preemption is not supported for your current stack version {{currentStack}}</span>
+            </div>
+          {{/if}}
         {{else}}
           <div class="text-warning">
-            <span>Preemption is not supported for your current stack version {{currentStack}}</span>
+            <span>Preemption is disabled by resource manager </span>
           </div>
         {{/if}}
       </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs
index 7b25af3..608758f 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueCapacity.hbs
@@ -20,7 +20,15 @@
   <div class="panel panel-default">
     <div class="panel-heading">
       <div class="panel-title">
-        Queue Capacity <a id="collapseQueueCapacityPanelBtn" href="#collapsibleQueueCapacityPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isCapacityPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isCapacityPanelCollapsed:fa-plus:fa-minus"}}></i></a>
+        Children Queue Capacites for Default Partition
+        {{#if isAnyChildrenQueueCapacityDirty}}
+          {{#if warnInvalidCapacity}}
+            {{warning-info class="red" tooltip="Invalid queue total capacity"}}
+          {{else}}
+            {{warning-info class="yellow-warning" tooltip="Need refresh queues / restart RM"}}
+          {{/if}}
+        {{/if}}
+        <a id="collapseQueueCapacityPanelBtn" href="#collapsibleQueueCapacityPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isCapacityPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isCapacityPanelCollapsed:fa-plus:fa-minus"}}></i></a>
       </div>
     </div>
     <div id="collapsibleQueueCapacityPanel" {{bind-attr class=":panel-collapse :collapse view.isCapacityPanelCollapsed::in"}}>
@@ -69,7 +77,7 @@
             {{#if parentQueue}}
               <div class="row">
                 <div class="col-md-10 col-sm-10">
-                  <small>To edit capacity and maximum capacity at parent queue level</small>
+                  <small><strong>For this queue:</strong> To edit capacity and maximum capacity at parent queue level</small>
                   <small>{{#link-to 'capsched.queuesconf.editqueue' parentQueue}}Click Here{{/link-to}}</small>
                 </div>
               </div>
@@ -87,7 +95,7 @@
             </div>
             <div class="row">
               <div class="col-md-10 col-sm-10">
-                <small>To edit capacity and maximum capacity at parent queue level</small>
+                <small><strong>For this queue:</strong> To edit capacity and maximum capacity at parent queue level</small>
                 <small>{{#link-to 'capsched.queuesconf.editqueue' parentQueue}}Click Here{{/link-to}}</small>
               </div>
             </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs
index 262f380..809c1c0 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/partials/queueResources.hbs
@@ -20,7 +20,11 @@
   <div class="panel panel-default">
     <div class="panel-heading">
       <div class="panel-title">
-        Other Configs (User Limit factor, Max AM Resource etc) <a id="collapseResourcesPanelBtn" href="#collapsibleQueueResourcesPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isResourcesPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isResourcesPanelCollapsed:fa-plus:fa-minus"}}></i></a>
+        Other Configs (User Limit factor, Max AM Resource etc)
+        {{#if isAnyQueueResourcesDirty}}
+          {{warning-info class="yellow-warning" tooltip="Need refresh queues / restart RM"}}
+        {{/if}}
+        <a id="collapseResourcesPanelBtn" href="#collapsibleQueueResourcesPanel" data-toggle="collapse" {{bind-attr class=":pull-right view.isResourcesPanelCollapsed:collapsed"}}><i {{bind-attr class=":fa view.isResourcesPanelCollapsed:fa-plus:fa-minus"}}></i></a>
       </div>
     </div>
     <div id="collapsibleQueueResourcesPanel" {{bind-attr class=":panel-collapse :collapse view.isResourcesPanelCollapsed::in"}}>

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf.hbs
index 1bc3380..0c70ee5 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/queuesconf.hbs
@@ -82,15 +82,19 @@
   </div>
   {{#if isOperator}}
     <div class="btn btn-group-sm col-sm-offset-2">
+      {{#if isQueuesNeedRefreshOrRestart}}
+        {{warning-info class="yellow-warning fa-2x resfresh-restart-warning" tooltip="Refresh queues / restart RM is required"}}
+      {{/if}}
       <button type="button" {{bind-attr class=":btn :btn-success canNotSave:disabled needSave::disabled"}} name="saveOnly" {{action "showSaveConfigDialog"}}>Save Only</button>
-      <button type="button" {{bind-attr class=":btn :btn-success canNotSave:disabled needRefresh::disabled"}} name="saveAndRefresh" {{action "showSaveConfigDialog" "refresh"}}>Save And Refresh Queues</button>
-      <button type="button" {{bind-attr class=":btn :btn-success canNotSave:disabled needRestart::disabled"}} name="saveAndRestart" {{action "showSaveConfigDialog" "restart"}}>Save And Restart RM</button>
+      <button type="button" {{bind-attr class=":btn :btn-success canNotSave:disabled isQueuesNeedRefreshOrRestart::disabled"}} name="saveAndRefresh" {{action "showSaveConfigDialog" "refresh"}}>Save And Refresh Queues</button>
+      <button type="button" {{bind-attr class=":btn :btn-success canNotSave:disabled isQueuesNeedRefreshOrRestart::disabled"}} name="saveAndRestart" {{action "showSaveConfigDialog" "restart"}}>Save And Restart RM</button>
       <button type="button" {{bind-attr class=":btn :btn-danger isAnyQueueDirty::disabled"}} name="cancelQueuesconfBtn" {{action "showConfirmDialog"}}>Discard Changes</button>
+      <button type="button" {{bind-attr class=":btn :btn-primary isAnyQueueDirty::disabled"}} name="viewXmlDiff" {{action "viewConfigXmlDiff"}} style="display:none;">View XML Diff</button>
     </div>
   {{/if}}
 </div>
 
-{{save-config-dialog isDialogOpen=isSaveConfigDialogOpen configNote=configNote action="saveCapSchedConfigs" param=saveMode}}
+{{save-config-dialog isDialogOpen=isSaveConfigDialogOpen configNote=configNote action="saveCapSchedConfigs" param=saveMode forceRefresh=forceRefreshOrRestartRequired}}
 
 {{confirm-discard-changes isDialogOpen=isConfirmDialogOpen action="discardQueuesChanges"}}
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/scheduler.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/scheduler.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/scheduler.hbs
index 7649512..66ef1ad 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/scheduler.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/capsched/scheduler.hbs
@@ -18,6 +18,14 @@
 
 <div class="scheduler-panel">
   <div class="panel panel-default">
+    <div class="panel-heading">
+      <div class="panel-title">
+        Scheduler Configurations
+        {{#if isSchedulerDirty}}
+          {{warning-info class="yellow-warning" tooltip="Need restart RM to take effect"}}
+        {{/if}}
+      </div>
+    </div>
     <div class="panel-body">
       <div class="row form-group">
         <div class="col-md-4">
@@ -30,7 +38,7 @@
         {{#if isOperator}}
           <div class="col-sm-3">
             {{int-input value=scheduler.maximum_applications maxlength=15 class="input-sm input-int input-control"}}
-            {{#if schedulerDirtyFilelds.maximum_applications}}
+            {{#if schedulerDirtyFields.maximum_applications}}
               <div class="btn-group btn-group-xs">
                   <a {{action 'rollbackProp' 'maximum_applications' scheduler}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
               </div>
@@ -56,7 +64,7 @@
               {{int-input value=scheduler.maximum_am_resource_percent class="input-sm" maxVal=100}}
               <span class="input-group-addon">%</span>
             </div>
-            {{#if schedulerDirtyFilelds.maximum_am_resource_percent}}
+            {{#if schedulerDirtyFields.maximum_am_resource_percent}}
               <div class="btn-group btn-group-xs rollback-resource-percent">
                   <a {{action 'rollbackProp' 'maximum_am_resource_percent' scheduler}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
               </div>
@@ -83,7 +91,7 @@
         {{#if isOperator}}
           <div class="col-sm-3">
             {{int-input value=scheduler.node_locality_delay maxlength=10 class="input-sm input-int input-control"}}
-            {{#if schedulerDirtyFilelds.node_locality_delay}}
+            {{#if schedulerDirtyFields.node_locality_delay}}
               <div class="btn-group btn-group-xs" >
                   <a {{action 'rollbackProp' 'node_locality_delay' scheduler}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
               </div>
@@ -116,7 +124,7 @@
               optionValuePath="content.value"
               value=scheduler.resource_calculator
             }}
-            {{#if schedulerDirtyFilelds.resource_calculator}}
+            {{#if schedulerDirtyFields.resource_calculator}}
               <div class="btn-group btn-group-xs">
                 <a {{action 'rollbackProp' 'resource_calculator' scheduler}} href="#" class="btn btn-default btn-warning"><i class="fa fa-undo"></i></a>
               </div>
@@ -129,9 +137,12 @@
 </div>
 {{#if isOperator}}
   <div class="row">
-    <div class="btn btn-group-md col-md-offset-3">
+    <div class="btn btn-group-sm col-sm-offset-3">
+      {{#if isSchedulerPropsNeedSaveOrRestart}}
+        {{warning-info class="yellow-warning fa-2x resfresh-restart-warning" tooltip="Restart RM is required"}}
+      {{/if}}
       <button type="button" {{bind-attr class=":btn :btn-default :btn-success isSchedulerDirty::disabled"}} name="saveOnly" {{action 'showSaveConfigDialog'}}>Save Only</button>
-      <button type="button" {{bind-attr class=":btn :btn-default :btn-success isSchedulerDirty::disabled"}} name="saveRestart" {{action 'showSaveConfigDialog' 'restart'}}>Save And Restart RM</button>
+      <button type="button" {{bind-attr class=":btn :btn-default :btn-success isSchedulerPropsNeedSaveOrRestart::disabled"}} name="saveRestart" {{action 'showSaveConfigDialog' 'restart'}}>Save And Restart RM</button>
       <button type="button" {{bind-attr class=":btn :btn-default :btn-danger isSchedulerDirty::disabled"}} name="cancelAdvanced" {{action 'showConfirmDialog'}}>Discard Changes</button>
     </div>
   </div>
@@ -139,4 +150,4 @@
 
 {{confirm-discard-changes isDialogOpen=isConfirmDialogOpen action="rollbackSchedulerProps"}}
 
-{{save-config-dialog isDialogOpen=isSaveConfigDialogOpen configNote=configNote action="saveCapSchedConfigs" param=saveMode}}
+{{save-config-dialog isDialogOpen=isSaveConfigDialogOpen configNote=configNote action="saveCapSchedConfigs" param=saveMode forceRefresh=forceRestartRequired}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/editQueueCapacity.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/editQueueCapacity.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/editQueueCapacity.hbs
index a7901b8..baa77db 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/editQueueCapacity.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/editQueueCapacity.hbs
@@ -22,7 +22,7 @@
   </div>
   <div class="col-md-5 col-md-5">
     <div {{bind-attr class=":form-group :input-group :capacity-input-percent warnInvalidTotalCapacity:has-error"}}>
-      {{capacity-input class='input-sm' value=queue.capacity queue=this maxVal=100}}
+      {{decimal-capacity-input class='input-sm' value=queue.capacity queue=queue maxVal=100}}
       <span class="input-group-addon">%</span>
     </div>
     <div class="form-group capacity-input-slider">
@@ -36,7 +36,7 @@
   </div>
   <div class="col-md-5 col-sm-5">
     <div {{bind-attr class=":form-group :input-group :capacity-input-percent isInvalidQueueMaximumCapacity:has-error"}}>
-      {{max-capacity-input class='input-sm' value=queue.maximum_capacity queue=queue maxVal=100}}
+      {{decimal-maxcapacity-input class='input-sm' value=queue.maximum_capacity queue=queue maxVal=100}}
       <span class="input-group-addon">%</span>
     </div>
     <div class="form-group capacity-input-slider">

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueMapping.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueMapping.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueMapping.hbs
index fa35518..33540e9 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueMapping.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueMapping.hbs
@@ -19,6 +19,9 @@
   <div class="panel-heading">
     <div class="panel-title">
       Queue Mappings
+      {{#if isQueueMappingsDirty}}
+        {{warning-info class="yellow-warning" tooltip="Need refresh queues"}}
+      {{/if}}
       <a href="#queueMappingsCollapsiblePanel" id="collapseQueueMappingsBtn" data-toggle="collapse" {{bind-attr class=":pull-right isCollapsed:collapsed"}}><i {{bind-attr class=":fa isCollapsed:fa-plus:fa-minus"}}></i></a>
     </div>
   </div>
@@ -158,7 +161,7 @@
               {{input type="checkbox" name="queueMappingOverride" checked=mappingsOverrideEnable}}
               {{tooltip-label
                 label='Allow application to override user-queue mapping'
-                message='When checked, applications submitted with queues specified will be used other than those defined in default queue mapping'
+                message='When checked, applications submitted with queues specified will be used other than those defined in configured queue mapping'
               }}
             </label>
           </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/1f18805d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueSummary.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueSummary.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueSummary.hbs
index 9c3ffd0..a7ae9b0 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueSummary.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/components/queueSummary.hbs
@@ -38,12 +38,12 @@
         </div>
         <div class="row">
           <div class="col-sm-5">
-            <label>Capacity</label>
+            <label>Capacity of my parent</label>
           </div>
           <div class="col-sm-5">
             <span>{{queue.capacity}}%</span>
           </div>
-          {{#if isQueueNeedRefreshOrRestart}}
+          {{#if isQueueCapacityNeedRefresh}}
             <div class="col-sm-2">
               {{warning-info class="yellow-warning" tooltip="Need refresh queues/restart RM to take effect"}}
             </div>
@@ -56,7 +56,7 @@
           <div class="col-sm-5">
             <span>{{effectiveCapacity}}%</span>
           </div>
-          {{#if isQueueNeedRefreshOrRestart}}
+          {{#if isQueueCapacityNeedRefresh}}
             <div class="col-sm-2">
               {{warning-info class="yellow-warning" tooltip="Need refresh queues/restart RM to take effect"}}
             </div>
@@ -69,7 +69,7 @@
           <div class="col-sm-5">
             <span {{bind-attr class="qStateColor"}}>{{queueState}}</span>
           </div>
-          {{#if isQueueNeedRefreshOrRestart}}
+          {{#if isQueueStateNeedRefresh}}
             <div class="col-sm-2">
               {{warning-info class="yellow-warning" tooltip="Need refresh queues/restart RM to take effect"}}
             </div>