You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2017/02/23 13:15:31 UTC

[2/4] ambari git commit: AMBARI-20143 Merge changes in branch-feature-preview-configs to branch-2.5. (ababiichuk)

http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/templates/main/service/reassign/step3.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/reassign/step3.hbs b/ambari-web/app/templates/main/service/reassign/step3.hbs
index 1ffe989..1b9c8ff 100644
--- a/ambari-web/app/templates/main/service/reassign/step3.hbs
+++ b/ambari-web/app/templates/main/service/reassign/step3.hbs
@@ -27,17 +27,37 @@
   </div>
 {{/if}}
 <div id="step8-content" class="well pre-scrollable">
-  <div id="printReview">
-    <a class="btn btn-info pull-right" {{action printReview target="view"}}>{{t common.print}}</a> <br/>
-  </div>
   <div id="step8-info">
-    <p><b>{{t services.reassign.step3.component}}</b> {{controller.content.reassign.display_name}}</p>
-
-    <p><b>{{t services.reassign.step3.sourceHost}}</b> {{view.sourceHost}}</p>
-
-    <p><b>{{t services.reassign.step3.targetHost}}</b> {{view.targetHost}}</p>
+    <table id="reassign-review-table">
+      <tr>
+        <td><b>{{t services.reassign.step3.component}}</b></td>
+        <td colspan="2">{{controller.content.reassign.display_name}}</td>
+      </tr>
+      <tr>
+        <td><b>{{t services.reassign.step3.sourceHost}}</b></td>
+        <td>{{view.sourceHost}}</td>
+        <td><span class="to-be-disabled-red"><i class="icon-minus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeDeleted}}</span></td>
+      </tr>
+      <tr>
+        <td><b>{{t services.reassign.step3.targetHost}}</b></td>
+        <td>{{view.targetHost}}</td>
+        <td><span class="to-be-installed-green"><i class="icon-plus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeInstalled}}</span></td>
+      </tr>
+    </table>
   </div>
 </div>
+{{#if wizardController.isComponentWithReconfiguration}}
+  {{#if isLoaded}}
+    {{#if stepConfigs.length}}
+      <div id="serviceConfig">
+        {{t services.reassign.step3.configs}}
+        {{view App.ServiceConfigView}}
+      </div>
+    {{/if}}
+  {{else}}
+    {{view App.SpinnerView}}
+  {{/if}}
+{{/if}}
 <div class="btn-area">
   <a class="btn pull-left" {{action back href="true"}}>&larr; {{t common.back}}</a>
   <a class="btn btn-success pull-right"

http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/views/main/admin/highAvailability/rangerAdmin/step3_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/highAvailability/rangerAdmin/step3_view.js b/ambari-web/app/views/main/admin/highAvailability/rangerAdmin/step3_view.js
index 8aa0125..1c55608 100644
--- a/ambari-web/app/views/main/admin/highAvailability/rangerAdmin/step3_view.js
+++ b/ambari-web/app/views/main/admin/highAvailability/rangerAdmin/step3_view.js
@@ -21,6 +21,10 @@ var App = require('app');
 
 App.RAHighAvailabilityWizardStep3View = Em.View.extend({
 
-  templateName: require('templates/main/admin/highAvailability/rangerAdmin/step3')
+  templateName: require('templates/main/admin/highAvailability/rangerAdmin/step3'),
+
+  didInsertElement: function () {
+    this.get('controller').loadStep();
+  }
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/views/main/host/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/summary.js b/ambari-web/app/views/main/host/summary.js
index 80c4890..89332de 100644
--- a/ambari-web/app/views/main/host/summary.js
+++ b/ambari-web/app/views/main/host/summary.js
@@ -215,11 +215,7 @@ App.MainHostSummaryView = Em.View.extend(App.TimeRangeMixin, {
    */
   addableComponentObject: Em.Object.extend({
     componentName: '',
-    subComponentNames: null,
     displayName: function () {
-      if (this.get('componentName') === 'CLIENTS') {
-        return this.t('common.clients');
-      }
       return App.format.role(this.get('componentName'), false);
     }.property('componentName')
   }),

http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/views/main/service/reassign/step3_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/reassign/step3_view.js b/ambari-web/app/views/main/service/reassign/step3_view.js
index 003fcb6..b6a379e 100644
--- a/ambari-web/app/views/main/service/reassign/step3_view.js
+++ b/ambari-web/app/views/main/service/reassign/step3_view.js
@@ -27,8 +27,8 @@ App.ReassignMasterWizardStep3View = Em.View.extend({
 
   targetHost: Em.computed.alias('controller.content.reassignHosts.target'),
 
-  printReview: function () {
-    $("#step8-info").jqprint();
+  didInsertElement: function () {
+    this.get('controller').loadStep();
   },
 
   jdbcSetupMessage: function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/views/main/service/reassign/step5_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/reassign/step5_view.js b/ambari-web/app/views/main/service/reassign/step5_view.js
index c5fc3c8..e10dc14 100644
--- a/ambari-web/app/views/main/service/reassign/step5_view.js
+++ b/ambari-web/app/views/main/service/reassign/step5_view.js
@@ -42,8 +42,8 @@ App.ReassignMasterWizardStep5View = Em.View.extend({
     }
 
     if (this.get('controller.content.reassign.component_name') === 'APP_TIMELINE_SERVER') {
-      user = this.get('controller.content.serviceProperties.yarn-env.yarn_user');
-      path = this.get('controller.content.serviceProperties.yarn-site')['yarn.timeline-service.leveldb-timeline-store.path'];
+      user = this.get('controller.content.configs.yarn-env.yarn_user');
+      path = this.get('controller.content.configs.yarn-site')['yarn.timeline-service.leveldb-timeline-store.path'];
     }
 
     return Em.I18n.t('services.reassign.step5.body.' + this.get('controller.content.reassign.component_name').toLowerCase() + ha).

http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/admin/highAvailability/rangerAdmin/step3_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/highAvailability/rangerAdmin/step3_controller_test.js b/ambari-web/test/controllers/main/admin/highAvailability/rangerAdmin/step3_controller_test.js
new file mode 100644
index 0000000..4dc3539
--- /dev/null
+++ b/ambari-web/test/controllers/main/admin/highAvailability/rangerAdmin/step3_controller_test.js
@@ -0,0 +1,104 @@
+/**
+ * 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');
+require('controllers/main/admin/highAvailability/rangerAdmin/step3_controller');
+require('controllers/main/admin/highAvailability/rangerAdmin/wizard_controller');
+require('controllers/main');
+
+describe('App.RAHighAvailabilityWizardStep3Controller', function () {
+
+  var controller;
+
+  beforeEach(function () {
+    controller = App.RAHighAvailabilityWizardStep3Controller.create();
+  });
+
+  describe('#loadStep', function () {
+
+    var dfd,
+      testCases = [
+        {
+          path: 'isLoaded',
+          result: true
+        },
+        {
+          path: 'selectedService.configs.length',
+          result: 1,
+          massage: 'configs length'
+        },
+        {
+          path: 'selectedService.configs.firstObject.name',
+          result: 'policymgr_external_url',
+          message: 'property name'
+        },
+        {
+          path: 'selectedService.configs.firstObject.category',
+          result: 'RANGER',
+          message: 'config category'
+        },
+        {
+          path: 'selectedService.configs.firstObject.value',
+          result: 'http://localhost:1111',
+          message: 'property value'
+        }
+      ],
+      service = Em.Object.create({
+        serviceName: 'RANGER',
+        displayName: 'Ranger'
+      });
+
+    beforeEach(function () {
+      dfd = $.Deferred();
+      sinon.stub(App.get('router.mainController'), 'isLoading').returns(dfd);
+      sinon.stub(App.Service, 'find').returns([service]);
+      sinon.stub(App.config, 'get').withArgs('serviceByConfigTypeMap').returns({
+        'admin-properties': service
+      });
+      sinon.stub(App.configsCollection, 'getConfigByName').returns({
+        name: 'policymgr_external_url'
+      });
+      controller.setProperties({
+        wizardController: App.get('router.rAHighAvailabilityWizardController'),
+        content: {
+          loadBalancerURL: 'http://localhost:1111'
+        }
+      });
+      controller.loadStep();
+      dfd.resolve();
+    });
+
+    afterEach(function () {
+      App.get('router.mainController.isLoading').restore();
+      App.Service.find.restore();
+      App.config.get.restore();
+      App.configsCollection.getConfigByName.restore();
+    });
+
+    testCases.forEach(function (testCase) {
+
+      it(testCase.message || testCase.path, function () {
+        expect(controller.get(testCase.path)).to.equal(testCase.result);
+      });
+
+    });
+
+  });
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/host/details_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/host/details_test.js b/ambari-web/test/controllers/main/host/details_test.js
index 9efece0..57c81dd 100644
--- a/ambari-web/test/controllers/main/host/details_test.js
+++ b/ambari-web/test/controllers/main/host/details_test.js
@@ -500,125 +500,72 @@ describe('App.MainHostDetailsController', function () {
   });
 
   describe('#addComponent()', function () {
+    var cases = [
+      {
+        componentName: 'ZOOKEEPER_SERVER',
+        showAddComponentPopupCallCount: 1,
+        showConfirmationPopupCallCount: 0
+      },
+      {
+        componentName: 'RESOURCEMANAGER',
+        showAddComponentPopupCallCount: 1,
+        showConfirmationPopupCallCount: 0
+      },
+      {
+        componentName: 'JOURNALNODE',
+        showAddComponentPopupCallCount: 0,
+        showConfirmationPopupCallCount: 1
+      },
+      {
+        componentName: 'HIVE_CLIENT',
+        showAddComponentPopupCallCount: 1,
+        showConfirmationPopupCallCount: 0
+      }
+    ];
     beforeEach(function () {
-      sinon.spy(App, "showConfirmationPopup");
-      sinon.stub(controller, "addClientComponent", Em.K);
-      sinon.stub(controller, "installHostComponentCall", Em.K);
       sinon.stub(controller, "checkComponentDependencies", Em.K);
+      sinon.stub(controller, "showAddComponentPopup", Em.K);
+      sinon.stub(controller, "clearConfigsChanges", Em.K);
+      sinon.stub(App, "showConfirmationPopup", Em.K);
       controller.set('content', {
         hostComponents: [Em.Object.create({
           componentName: "HDFS_CLIENT"
         })]
       });
-      controller.reopen({
-        securityEnabled: false
-      });
     });
 
     afterEach(function () {
-      App.showConfirmationPopup.restore();
-      controller.addClientComponent.restore();
-      controller.installHostComponentCall.restore();
       controller.checkComponentDependencies.restore();
+      controller.showAddComponentPopup.restore();
+      controller.clearConfigsChanges.restore();
+      App.showConfirmationPopup.restore();
     });
 
-    it('add ZOOKEEPER_SERVER', function () {
-      var event = {
-        context: Em.Object.create({
-          componentName: 'ZOOKEEPER_SERVER'
-        })
-      };
-      controller.addComponent(event);
-      expect(App.showConfirmationPopup.calledOnce).to.be.true;
-    });
-    it('add WEBHCAT_SERVER', function () {
-      var event = {
-        context: Em.Object.create({
-          componentName: 'WEBHCAT_SERVER'
-        })
-      };
-      controller.addComponent(event);
-      expect(App.showConfirmationPopup.calledOnce).to.be.true;
-    });
-    it('add slave component', function () {
-      var event = {
-        context: Em.Object.create({
-          componentName: 'HIVE_CLIENT'
-        })
-      };
-      controller.set('securityEnabled', false);
-      controller.addComponent(event);
-      expect(controller.addClientComponent.calledWith(Em.Object.create({
-        componentName: 'HIVE_CLIENT'
-      }))).to.be.true;
-    });
-  });
+    cases.forEach(function (testCase) {
 
-  describe('#formatClientsMessage()', function () {
-    var testCases = [
-      {
-        title: 'subComponentNames is null',
-        client: Em.Object.create({
-          subComponentNames: null,
-          displayName: 'CLIENTS'
-        }),
-        result: 'CLIENTS'
-      },
-      {
-        title: 'subComponentNames is empty',
-        client: Em.Object.create({
-          subComponentNames: [],
-          displayName: 'CLIENTS'
-        }),
-        result: 'CLIENTS'
-      },
-      {
-        title: 'displayName is null',
-        client: Em.Object.create({
-          subComponentNames: ['DATANODE'],
-          displayName: null
-        }),
-        result: ' (DataNode)'
-      },
-      {
-        title: 'displayName is CLIENTS',
-        client: Em.Object.create({
-          subComponentNames: ['DATANODE'],
-          displayName: 'CLIENTS'
-        }),
-        result: 'CLIENTS (DataNode)'
-      }
-    ];
-    testCases.forEach(function (test) {
-      it(test.title, function () {
-        expect(controller.formatClientsMessage(test.client)).to.equal(test.result);
-      });
-    });
-  });
+      describe('add ' + testCase.componentName, function () {
 
-  describe('#addClientComponent()', function () {
+        beforeEach(function () {
+          var event = {
+            context: Em.Object.create({
+              componentName: testCase.componentName
+            })
+          };
+          controller.addComponent(event);
+        });
 
-    var component = Em.Object.create({
-      componentName: ' Comp1'
-    });
+        it('controller.showAddComponentPopup', function () {
+          expect(controller.showAddComponentPopup.callCount).to.equal(testCase.showAddComponentPopupCallCount);
+        });
 
-    beforeEach(function () {
-      sinon.spy(controller, 'showAddComponentPopup');
-      sinon.stub(controller, 'installHostComponentCall', Em.K);
-    });
+        it('App.showConfirmationPopup', function () {
+          expect(App.showConfirmationPopup.callCount).to.equal(testCase.showConfirmationPopupCallCount);
+        });
 
-    afterEach(function () {
-      controller.showAddComponentPopup.restore();
-      controller.installHostComponentCall.restore();
-    });
+      });
 
-    it('any CLIENT component', function () {
-      controller.set('content.hostName', 'host1');
-      var popup = controller.addClientComponent(component);
-      expect(controller.showAddComponentPopup.calledOnce).to.be.true;
-      popup.onPrimary();
-      expect(controller.installHostComponentCall.calledWith('host1', component)).to.be.true;
     });
+
   });
 
   describe("#loadOozieConfigs()", function() {
@@ -647,7 +594,7 @@ describe('App.MainHostDetailsController', function () {
             tag: 'tag'
           }
         }
-      }});
+      }}, null, {});
       var args = testHelpers.findAjaxRequest('name', 'admin.get.all_configurations');
       expect(args[0]).exists;
       expect(args[0].sender).to.be.eql(controller);
@@ -672,6 +619,7 @@ describe('App.MainHostDetailsController', function () {
       sinon.stub(controller, 'getStormNimbusHosts').returns("host1");
       sinon.stub(controller, 'updateZkConfigs', Em.K);
       sinon.stub(controller, 'saveConfigsBatch', Em.K);
+      sinon.stub(controller, 'saveLoadedConfigs', Em.K);
       controller.set('nimbusHost', 'host2');
       controller.onLoadStormConfigs(data);
     });
@@ -679,6 +627,7 @@ describe('App.MainHostDetailsController', function () {
       controller.getStormNimbusHosts.restore();
       controller.updateZkConfigs.restore();
       controller.saveConfigsBatch.restore();
+      controller.saveLoadedConfigs.restore();
     });
     it("updateZkConfigs called with valid arguments", function() {
       expect(controller.updateZkConfigs.calledWith({'storm-site': {
@@ -718,7 +667,7 @@ describe('App.MainHostDetailsController', function () {
             tag: 'tag'
           }
         }
-      }});
+      }}, null, {});
       var args = testHelpers.findAjaxRequest('name', 'admin.get.all_configurations');
       expect(args[0]).exists;
       expect(args[0].sender).to.be.eql(controller);
@@ -742,7 +691,7 @@ describe('App.MainHostDetailsController', function () {
             tag: 'tag'
           }
         }
-      }});
+      }}, null, {});
       var args = testHelpers.findAjaxRequest('name', 'admin.get.all_configurations');
       expect(args[0]).exists;
       expect(args[0].sender).to.be.eql(controller);
@@ -812,10 +761,8 @@ describe('App.MainHostDetailsController', function () {
 
   describe('#showAddComponentPopup()', function () {
 
-    var message = 'Comp1';
-
     beforeEach(function () {
-      sinon.spy(App.ModalPopup, 'show');
+      sinon.stub(App.ModalPopup, 'show');
     });
 
     afterEach(function () {
@@ -823,9 +770,8 @@ describe('App.MainHostDetailsController', function () {
     });
 
     it('should display add component confirmation', function () {
-      var popup = controller.showAddComponentPopup(message, false, Em.K);
+      controller.showAddComponentPopup(Em.Object.create());
       expect(App.ModalPopup.show.calledOnce).to.be.true;
-      expect(popup.get('addComponentMsg')).to.eql(Em.I18n.t('hosts.host.addComponent.msg').format(message));
     });
   });
 
@@ -1008,7 +954,7 @@ describe('App.MainHostDetailsController', function () {
     });
 
     it('url params is empty', function () {
-      expect(controller.loadConfigsSuccessCallback()).to.be.false;
+      expect(controller.loadConfigsSuccessCallback(null, null, {})).to.be.false;
       var args = testHelpers.findAjaxRequest('name', 'reassign.load_configs');
       expect(args).not.exists;
     });
@@ -1017,6 +963,12 @@ describe('App.MainHostDetailsController', function () {
       var args = testHelpers.findAjaxRequest('name', 'reassign.load_configs');
       expect(args).exists;
     });
+    it('isConfigsLoadingInProgress is false', function () {
+      mockUrlParams = [];
+      controller.set('isConfigsLoadingInProgress', true);
+      controller.loadConfigsSuccessCallback(null, null, {});
+      expect(controller.get('isConfigsLoadingInProgress')).to.be.false;
+    });
   });
 
   describe('#saveZkConfigs()', function () {
@@ -1074,6 +1026,7 @@ describe('App.MainHostDetailsController', function () {
     beforeEach(function () {
       sinon.stub(controller, 'saveConfigsBatch', Em.K);
       sinon.stub(controller, 'updateZkConfigs', Em.K);
+      sinon.stub(controller, 'saveLoadedConfigs', Em.K);
       sinon.stub(App.Service, 'find', function() {
         return [
           Em.Object.create({ serviceName: 'HIVE' }),
@@ -1090,77 +1043,78 @@ describe('App.MainHostDetailsController', function () {
       App.Service.find.restore();
       controller.updateZkConfigs.restore();
       controller.saveConfigsBatch.restore();
+      controller.saveLoadedConfigs.restore();
     });
 
-      it('configs for YARN', function () {
-        var expected = {
-          properties: {
-            'yarn-site': {
-              p: 'ys'
-            }
-          },
-          properties_attributes: {
-            'yarn-site': {
-              p: 'pa_ys'
-            }
+    it('configs for YARN', function () {
+      var expected = {
+        properties: {
+          'yarn-site': {
+            p: 'ys'
           }
-        };
-        expect(this.groups[1]).to.be.eql(expected);
-      });
+        },
+        properties_attributes: {
+          'yarn-site': {
+            p: 'pa_ys'
+          }
+        }
+      };
+      expect(this.groups[1]).to.be.eql(expected);
+    });
 
-      it('configs for HIVE', function () {
-        var expected = {
-          "properties": {
-            "hive-site": {
-              "hs": "hs"
-            },
-            "webhcat-site": {
-              "ws": "ws"
-            }
+    it('configs for HIVE', function () {
+      var expected = {
+        "properties": {
+          "hive-site": {
+            "hs": "hs"
           },
-          "properties_attributes": {
-            "hive-site": {
-              "hs": "pa_hs"
-            },
-            "webhcat-site": {
-              "ws": "pa_ws"
-            }
+          "webhcat-site": {
+            "ws": "ws"
           }
-        };
-        expect(this.groups[0]).to.be.eql(expected);
-      });
-
-      it('configs for HBASE', function () {
-        var expected = {
-          "properties": {
-            "hbase-site": {
-              "hbs": "hbs"
-            }
+        },
+        "properties_attributes": {
+          "hive-site": {
+            "hs": "pa_hs"
           },
-          "properties_attributes": {
-            "hbase-site": {
-              "hbs": "pa_hbs"
-            }
+          "webhcat-site": {
+            "ws": "pa_ws"
           }
-        };
-        expect(this.groups[2]).to.be.eql(expected);
-      });
+        }
+      };
+      expect(this.groups[0]).to.be.eql(expected);
+    });
 
-      it('configs for ACCUMULO', function () {
-        var expected = {
-          "properties": {
-            "accumulo-site": {
-              "as": "as"
-            }
-          },
-          "properties_attributes": {
-            "accumulo-site": {
-              "as": "pa_as"
-            }
+    it('configs for HBASE', function () {
+      var expected = {
+        "properties": {
+          "hbase-site": {
+            "hbs": "hbs"
           }
-        };
-        expect(this.groups[3]).to.be.eql(expected);
-      });
+        },
+        "properties_attributes": {
+          "hbase-site": {
+            "hbs": "pa_hbs"
+          }
+        }
+      };
+      expect(this.groups[2]).to.be.eql(expected);
+    });
+
+    it('configs for ACCUMULO', function () {
+      var expected = {
+        "properties": {
+          "accumulo-site": {
+            "as": "as"
+          }
+        },
+        "properties_attributes": {
+          "accumulo-site": {
+            "as": "pa_as"
+          }
+        }
+      };
+      expect(this.groups[3]).to.be.eql(expected);
+    });
 
   });
 
@@ -1928,9 +1882,9 @@ describe('App.MainHostDetailsController', function () {
       expect(App.showConfirmationPopup.calledOnce).to.be.true;
       popup.onPrimary();
       expect(controller.sendComponentCommand.calledWith(
-          controller.get('serviceNonClientActiveComponents'),
-          Em.I18n.t('hosts.host.maintainance.startAllComponents.context'),
-          App.HostComponentStatus.started)
+        controller.get('serviceNonClientActiveComponents'),
+        Em.I18n.t('hosts.host.maintainance.startAllComponents.context'),
+        App.HostComponentStatus.started)
       ).to.be.true;
     });
   });
@@ -1966,9 +1920,9 @@ describe('App.MainHostDetailsController', function () {
       expect(App.showConfirmationPopup.calledOnce).to.be.true;
       popup.onPrimary();
       expect(controller.sendComponentCommand.calledWith(
-          controller.get('serviceNonClientActiveComponents'),
-          Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'),
-          App.HostComponentStatus.stopped)
+        controller.get('serviceNonClientActiveComponents'),
+        Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'),
+        App.HostComponentStatus.stopped)
       ).to.be.true;
     });
     it('serviceNonClientActiveComponents is correct, NAMENODE started', function () {
@@ -2556,8 +2510,8 @@ describe('App.MainHostDetailsController', function () {
   describe('#_doDeleteHostComponent()', function () {
     it('single component', function () {
       controller.set('content.hostName', 'host1');
-      var component = Em.Object.create({componentName: 'COMP'});
-      controller._doDeleteHostComponent(component);
+      var componentName = 'COMP';
+      controller._doDeleteHostComponent(componentName);
       var args = testHelpers.findAjaxRequest('name', 'common.delete.host_component');
       expect(args[0]).exists;
       expect(args[0].data).to.be.eql({
@@ -2578,73 +2532,28 @@ describe('App.MainHostDetailsController', function () {
   });
 
   describe('#_doDeleteHostComponentSuccessCallback()', function () {
+    var data = {
+      componentName: 'COMPONENT',
+      hostName: 'h1'
+    };
+
     beforeEach(function () {
       sinon.stub(controller, 'removeHostComponentModel', Em.K);
-      sinon.stub(controller, 'isServiceMetricsLoaded', function (callback) {
-        callback();
-      });
-      sinon.stub(controller, 'loadConfigs', Em.K);
+      controller.set('_deletedHostComponentResult', {});
+      controller._doDeleteHostComponentSuccessCallback({}, {}, data);
     });
 
     afterEach(function () {
       controller.removeHostComponentModel.restore();
-      controller.isServiceMetricsLoaded.restore();
-      controller.loadConfigs.restore();
     });
 
-    it('ZOOKEEPER_SERVER component', function () {
-      var data = {
-        componentName: 'ZOOKEEPER_SERVER'
-      };
-      controller._doDeleteHostComponentSuccessCallback({}, {}, data);
-      expect(controller.get('_deletedHostComponentResult')).to.be.null;
-      expect(controller.get('fromDeleteZkServer')).to.be.true;
-      expect(controller.loadConfigs.calledOnce).to.be.true;
-    });
-    it('Not ZOOKEEPER_SERVER component', function () {
-      var data = {
-        componentName: 'COMP'
-      };
-      controller.set('fromDeleteZkServer', false);
-      controller._doDeleteHostComponentSuccessCallback({}, {}, data);
+    it('should reset `_deletedHostComponentResult`', function () {
       expect(controller.get('_deletedHostComponentResult')).to.be.null;
-      expect(controller.get('fromDeleteZkServer')).to.be.false;
     });
+
     it('should call `removeHostComponentModel` with correct params', function () {
-      var data = {
-        componentName: 'COMPONENT',
-        hostName: 'h1'
-      };
-      controller._doDeleteHostComponentSuccessCallback({}, {}, data);
       expect(controller.removeHostComponentModel.calledWith('COMPONENT', 'h1')).to.be.true;
     });
-    it('HIVE_METASTORE component', function () {
-      var data = {
-        componentName: 'HIVE_METASTORE'
-      };
-      controller._doDeleteHostComponentSuccessCallback({}, {}, data);
-      expect(controller.get('_deletedHostComponentResult')).to.be.null;
-      expect(controller.get('deleteHiveMetaStore')).to.be.true;
-      expect(controller.loadConfigs.calledWith('loadHiveConfigs')).to.be.true;
-    });
-    it('NIMBUS component', function () {
-      var data = {
-        componentName: 'NIMBUS'
-      };
-      controller._doDeleteHostComponentSuccessCallback({}, {}, data);
-      expect(controller.get('_deletedHostComponentResult')).to.be.null;
-      expect(controller.get('deleteNimbusHost')).to.be.true;
-      expect(controller.loadConfigs.calledWith('loadStormConfigs')).to.be.true;
-    });
-    it('RANGER_KMS_SERVER component', function () {
-      var data = {
-        componentName: 'RANGER_KMS_SERVER'
-      };
-      controller._doDeleteHostComponentSuccessCallback({}, {}, data);
-      expect(controller.get('_deletedHostComponentResult')).to.be.null;
-      expect(controller.get('deleteRangerKMSServer')).to.be.true;
-      expect(controller.loadConfigs.calledWith('loadRangerConfigs')).to.be.true;
-    });
   });
 
   describe('#upgradeComponentSuccessCallback()', function () {
@@ -2679,62 +2588,6 @@ describe('App.MainHostDetailsController', function () {
     });
   });
 
-  describe('#checkZkConfigs()', function () {
-    beforeEach(function () {
-      sinon.stub(controller, 'removeObserver');
-      sinon.stub(controller, 'loadConfigs');
-      sinon.stub(controller, 'isServiceMetricsLoaded', Em.clb);
-      this.stub = sinon.stub(App.router, 'get');
-    });
-    afterEach(function () {
-      controller.loadConfigs.restore();
-      controller.removeObserver.restore();
-      controller.isServiceMetricsLoaded.restore();
-      this.stub.restore();
-    });
-
-    it('No operations of ZOOKEEPER_SERVER', function () {
-      this.stub.withArgs('backgroundOperationsController.services').returns([]);
-      controller.checkZkConfigs();
-      expect(controller.removeObserver.called).to.be.false;
-      expect(controller.loadConfigs.called).to.be.false;
-    });
-
-    it('Operation of ZOOKEEPER_SERVER running', function () {
-      this.stub.withArgs('backgroundOperationsController.services').returns([Em.Object.create({
-        id: 1,
-        isRunning: true
-      })]);
-      controller.set('zkRequestId', 1);
-      controller.checkZkConfigs();
-      expect(controller.removeObserver.called).to.be.false;
-      expect(controller.loadConfigs.called).to.be.false;
-    });
-
-    describe('Operation of ZOOKEEPER_SERVER finished', function () {
-
-      beforeEach(function () {
-        this.stub.withArgs('backgroundOperationsController.services').returns([Em.Object.create({
-          id: 1
-        })]);
-        this.clock = sinon.useFakeTimers();
-        controller.set('zkRequestId', 1);
-        controller.checkZkConfigs();
-      });
-
-      afterEach(function () {
-        this.clock.restore();
-      });
-
-      it('loadConfigs is called after `componentsUpdateInterval`', function () {
-        expect(controller.removeObserver.calledWith('App.router.backgroundOperationsController.serviceTimestamp', controller, controller.checkZkConfigs)).to.be.true;
-        this.clock.tick(App.get('componentsUpdateInterval'));
-        expect(controller.loadConfigs.calledOnce).to.be.true;
-      });
-
-    });
-  });
-
   describe('#_doDeleteHostComponentErrorCallback()', function () {
     it('call showBackgroundOperationsPopup', function () {
       controller._doDeleteHostComponentErrorCallback({}, 'textStatus', {}, {url: 'url'});
@@ -2883,86 +2736,86 @@ describe('App.MainHostDetailsController', function () {
   describe('#installClients()', function () {
 
     var cases = [
-        {
-          context: [
-            Em.Object.create({
-              componentName: 'c0',
-              workStatus: 'INSTALLED'
-            }),
-            Em.Object.create({
-              componentName: 'c1',
-              workStatus: 'INIT'
-            }),
-            Em.Object.create({
-              componentName: 'c2',
-              workStatus: 'INSTALL_FAILED'
-            })
-          ],
-          dependencies: {
-            c0: [],
-            c1: [],
-            c2: []
-          },
-          getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
-          getKDCSessionStateCalled: true,
-          sendComponentCommandCalled: true,
-          showAlertPopupCalled: false,
-          title: 'No clients to add, some clients to install'
+      {
+        context: [
+          Em.Object.create({
+            componentName: 'c0',
+            workStatus: 'INSTALLED'
+          }),
+          Em.Object.create({
+            componentName: 'c1',
+            workStatus: 'INIT'
+          }),
+          Em.Object.create({
+            componentName: 'c2',
+            workStatus: 'INSTALL_FAILED'
+          })
+        ],
+        dependencies: {
+          c0: [],
+          c1: [],
+          c2: []
         },
-        {
-          context: [
-            Em.Object.create({
-              componentName: 'c3',
-              displayName: 'c3'
-            })
-          ],
-          dependencies: {
-            c3: []
-          },
-          getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
-          getKDCSessionStateCalled: true,
-          sendComponentCommandCalled: false,
-          showAlertPopupCalled: false,
-          title: 'No clients to install, some clients to add'
+        getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
+        getKDCSessionStateCalled: true,
+        sendComponentCommandCalled: true,
+        showAlertPopupCalled: false,
+        title: 'No clients to add, some clients to install'
+      },
+      {
+        context: [
+          Em.Object.create({
+            componentName: 'c3',
+            displayName: 'c3'
+          })
+        ],
+        dependencies: {
+          c3: []
         },
-        {
-          context: [
-            Em.Object.create({
-              componentName: 'c4',
-              displayName: 'c4'
-            })
-          ],
-          dependencies: {
-            c4: ['c5']
-          },
-          getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
-          getKDCSessionStateCalled: false,
-          sendComponentCommandCalled: false,
-          showAlertPopupCalled: true,
-          title: 'Clients to add have unresolved dependencies'
+        getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
+        getKDCSessionStateCalled: true,
+        sendComponentCommandCalled: false,
+        showAlertPopupCalled: false,
+        title: 'No clients to install, some clients to add'
+      },
+      {
+        context: [
+          Em.Object.create({
+            componentName: 'c4',
+            displayName: 'c4'
+          })
+        ],
+        dependencies: {
+          c4: ['c5']
         },
-        {
-          context: [
-            Em.Object.create({
-              componentName: 'c5',
-              displayName: 'c5'
-            }),
-            Em.Object.create({
-              componentName: 'c6',
-              displayName: 'c6'
-            })
-          ],
-          dependencies: {
-            c5: ['c6'],
-            c6: ['c5']
-          },
-          getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
-          getKDCSessionStateCalled: true,
-          sendComponentCommandCalled: false,
-          showAlertPopupCalled: false,
-          title: 'Clients to add have mutual dependencies'
-        }
-      ];
+        getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
+        getKDCSessionStateCalled: false,
+        sendComponentCommandCalled: false,
+        showAlertPopupCalled: true,
+        title: 'Clients to add have unresolved dependencies'
+      },
+      {
+        context: [
+          Em.Object.create({
+            componentName: 'c5',
+            displayName: 'c5'
+          }),
+          Em.Object.create({
+            componentName: 'c6',
+            displayName: 'c6'
+          })
+        ],
+        dependencies: {
+          c5: ['c6'],
+          c6: ['c5']
+        },
+        getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
+        getKDCSessionStateCalled: true,
+        sendComponentCommandCalled: false,
+        showAlertPopupCalled: false,
+        title: 'Clients to add have mutual dependencies'
+      }
+    ];
 
     beforeEach(function () {
       sinon.stub(controller, 'sendComponentCommand', Em.K);
@@ -3096,9 +2949,7 @@ describe('App.MainHostDetailsController', function () {
       });
 
       it('_doDeleteHostComponent is called with correct arguments', function () {
-        expect(controller._doDeleteHostComponent.calledWith(Em.Object.create({
-          componentName: 'COMP1'
-        }))).to.be.true;
+        expect(controller._doDeleteHostComponent.calledWith('COMP1')).to.be.true;
       });
       it('fromDeleteHost is true', function () {
         expect(controller.get('fromDeleteHost')).to.be.true;
@@ -3429,11 +3280,13 @@ describe('App.MainHostDetailsController', function () {
     ];
 
     beforeEach(function () {
-      sinon.spy(controller, 'saveConfigsBatch')
+      sinon.spy(controller, 'saveConfigsBatch');
+      sinon.stub(controller, 'saveLoadedConfigs', Em.K);
     });
 
     afterEach(function () {
       controller.saveConfigsBatch.restore();
+      controller.saveLoadedConfigs.restore();
     });
 
     cases.forEach(function (item) {
@@ -3510,43 +3363,6 @@ describe('App.MainHostDetailsController', function () {
     });
   });
 
-  describe("#updateStormConfigs()", function () {
-    beforeEach(function () {
-      this.serviceMock = sinon.stub(App.Service, 'find');
-      sinon.stub(controller, 'loadConfigs');
-      this.mock = sinon.stub(App, 'get')
-    });
-    afterEach(function () {
-      this.serviceMock.restore();
-      this.mock.restore();
-      controller.loadConfigs.restore();
-    });
-    it("storm not installed, hadoop stack is 2.2", function () {
-      this.serviceMock.returns(Em.Object.create({
-        isLoaded: false
-      }));
-      this.mock.returns(false);
-      controller.updateStormConfigs();
-      expect(controller.loadConfigs.called).to.be.false;
-    });
-    it("storm installed, hadoop stack is 2.2", function () {
-      this.serviceMock.returns(Em.Object.create({
-        isLoaded: true
-      }));
-      this.mock.returns(false);
-      controller.updateStormConfigs();
-      expect(controller.loadConfigs.called).to.be.false;
-    });
-    it("storm installed, hadoop stack is 2.3", function () {
-      this.serviceMock.returns(Em.Object.create({
-        isLoaded: true
-      }));
-      this.mock.returns(true);
-      controller.updateStormConfigs();
-      expect(controller.loadConfigs.calledWith('loadStormConfigs')).to.be.true;
-    });
-  });
-
   describe("#parseNnCheckPointTime", function () {
     var tests = [
       {
@@ -3714,10 +3530,13 @@ describe('App.MainHostDetailsController', function () {
 
     beforeEach(function() {
       sinon.stub(controller, 'saveConfigsBatch', Em.K);
+      sinon.stub(controller, 'saveLoadedConfigs', Em.K);
+      controller.set('configs', {});
     });
 
     afterEach(function() {
       controller.saveConfigsBatch.restore();
+      controller.saveLoadedConfigs.restore();
     });
 
     var makeHostComponentModel = function(componentName, hostNames) {
@@ -4054,4 +3873,237 @@ describe('App.MainHostDetailsController', function () {
       });
     });
   });
+
+  describe('#setConfigsChangesForDisplay', function () {
+
+    var propertiesToChange = [
+        {
+          propertyName: 'n0',
+          propertyFileName: 'f0'
+        },
+        {
+          propertyName: 'n1',
+          propertyFileName: 'f1'
+        },
+        {
+          propertyName: 'n2',
+          propertyFileName: 'f2'
+        },
+        {
+          propertyName: 'n3',
+          propertyFileName: 'f3'
+        }
+      ],
+      result = {
+        recommendedPropertiesToChange: [
+          {
+            propertyName: 'n0',
+            propertyFileName: 'f0',
+            saveRecommended: true
+          },
+          {
+            propertyName: 'n3',
+            propertyFileName: 'f3',
+            saveRecommended: true
+          }
+        ],
+        requiredPropertiesToChange: [
+          {
+            propertyName: 'n1',
+            propertyFileName: 'f1'
+          },
+          {
+            propertyName: 'n2',
+            propertyFileName: 'f2'
+          }
+        ]
+      };
+
+    beforeEach(function () {
+      controller.setProperties({
+        allPropertiesToChange: propertiesToChange,
+        recommendedPropertiesToChange: [],
+        requiredPropertiesToChange: []
+      });
+      sinon.stub(App.configsCollection, 'getConfigByName', function (propertyName) {
+        var map = {
+          n0: {
+            isEditable: true,
+            isReconfigurable: true
+          },
+          n1: {
+            isEditable: true,
+            isReconfigurable: false
+          },
+          n2: {
+            isEditable: false,
+            isReconfigurable: false
+          }
+        };
+        return map[propertyName];
+      });
+      sinon.stub(App, 'get').withArgs('router.clusterController.isConfigsPropertiesLoaded').returns(true);
+      controller.set('isConfigsLoadingInProgress', true);
+      controller.setConfigsChangesForDisplay();
+    });
+
+    afterEach(function () {
+      App.configsCollection.getConfigByName.restore();
+      App.get.restore();
+    });
+
+    it('editable changes', function () {
+      expect(controller.get('recommendedPropertiesToChange').toArray()).to.eql(result.recommendedPropertiesToChange);
+    });
+
+    it('non-editable changes', function () {
+      expect(controller.get('requiredPropertiesToChange').toArray()).to.eql(result.requiredPropertiesToChange);
+    });
+
+    it('isConfigsLoadingInProgress', function () {
+      expect(controller.get('isConfigsLoadingInProgress')).to.be.false;
+    });
+
+  });
+
+  describe('#clearConfigsChanges', function () {
+
+    beforeEach(function () {
+      sinon.stub(controller, 'abortRequests', Em.K);
+      controller.setProperties({
+        allPropertiesToChange: [{}],
+        recommendedPropertiesToChange: [{}],
+        requiredPropertiesToChange: [{}],
+        groupedPropertiesToChange: [{}],
+        isReconfigureRequired: true,
+        configs: {}
+      });
+    });
+
+    afterEach(function () {
+      controller.abortRequests.restore();
+    });
+
+    describe('default case', function () {
+
+      beforeEach(function () {
+        controller.clearConfigsChanges();
+      });
+
+      it('allPropertiesToChange', function () {
+        expect(controller.get('allPropertiesToChange')).to.have.length(0);
+      });
+
+      it('recommendedPropertiesToChange', function () {
+        expect(controller.get('recommendedPropertiesToChange')).to.have.length(0);
+      });
+
+      it('groupedPropertiesToChange', function () {
+        expect(controller.get('groupedPropertiesToChange')).to.have.length(0);
+      });
+
+      it('isReconfigureRequired', function () {
+        expect(controller.get('isReconfigureRequired')).to.be.false;
+      });
+
+      it('configs', function () {
+        expect(controller.get('configs')).to.be.null;
+      });
+
+    });
+
+    describe('no loaded configs cleanup', function () {
+
+      beforeEach(function () {
+        controller.clearConfigsChanges(true);
+      });
+
+      it('configs shouldn\'t be cleared', function () {
+        expect(controller.get('configs')).to.not.be.null;
+      });
+
+    });
+
+  });
+
+  describe('#saveLoadedConfigs', function () {
+
+    var data = {
+      items: [
+        {
+          type: 't0',
+          properties: {
+            p0: 'v0',
+            p1: 'v1'
+          },
+          properties_attributes: {}
+        },
+        {
+          type: 't1',
+          properties: {
+            p2: 'v2',
+            p3: 'v3'
+          },
+          properties_attributes: {}
+        }
+      ]
+    };
+
+    it('should store data in configs object', function () {
+      controller.set('configs', null);
+      controller.saveLoadedConfigs(data);
+      expect(controller.get('configs')).to.eql(data);
+    });
+
+  });
+
+  describe('#loadComponentRelatedConfigs', function () {
+
+    var testCases = [
+      {
+        isReconfigureRequired: true,
+        loadConfigsCallCount: 1,
+        isConfigsLoadingInProgress: true,
+        message: 'reconfigure required'
+      },
+      {
+        isReconfigureRequired: false,
+        loadConfigsCallCount: 0,
+        isConfigsLoadingInProgress: false,
+        message: 'no reconfigure required'
+      }
+    ];
+
+    testCases.forEach(function (test) {
+
+      describe(test.message, function () {
+
+        beforeEach(function () {
+          sinon.stub(controller, 'isServiceMetricsLoaded', Em.clb);
+          sinon.stub(controller, 'loadConfigs', Em.K);
+          controller.setProperties({
+            isReconfigureRequired: test.isReconfigureRequired,
+            isConfigsLoadingInProgress: false
+          });
+          controller.loadComponentRelatedConfigs();
+        });
+
+        afterEach(function () {
+          controller.isServiceMetricsLoaded.restore();
+          controller.loadConfigs.restore();
+        });
+
+        it('loadConfigs', function () {
+          expect(controller.loadConfigs.callCount).to.equal(test.loadConfigsCallCount);
+        });
+
+        it('isConfigsLoadingInProgress', function () {
+          expect(controller.get('isConfigsLoadingInProgress')).to.equal(test.isConfigsLoadingInProgress);
+        });
+
+      });
+
+    });
+
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/service/info/config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/info/config_test.js b/ambari-web/test/controllers/main/service/info/config_test.js
index 09772ff..874a104 100644
--- a/ambari-web/test/controllers/main/service/info/config_test.js
+++ b/ambari-web/test/controllers/main/service/info/config_test.js
@@ -535,20 +535,23 @@ describe("App.MainServiceInfoConfigsController", function () {
     beforeEach(function () {
       sinon.stub(Em.run, 'once', Em.K);
       sinon.stub(mainServiceInfoConfigsController, 'loadSelectedVersion');
-      sinon.stub(mainServiceInfoConfigsController, 'clearRecommendationsInfo');
+      sinon.spy(mainServiceInfoConfigsController, 'clearRecommendations');
+      mainServiceInfoConfigsController.set('groupsToSave', { HDFS: 'my cool group'});
+      mainServiceInfoConfigsController.set('recommendations', Em.A([{name: 'prop_1'}]));
+      mainServiceInfoConfigsController.doCancel();
     });
     afterEach(function () {
       Em.run.once.restore();
       mainServiceInfoConfigsController.loadSelectedVersion.restore();
-      mainServiceInfoConfigsController.clearRecommendationsInfo.restore();
+      mainServiceInfoConfigsController.clearRecommendations.restore();
+    });
+
+    it("should launch recommendations cleanup", function() {
+      expect(mainServiceInfoConfigsController.clearRecommendations.calledOnce).to.be.true;
     });
 
     it("should clear dependent configs", function() {
-      mainServiceInfoConfigsController.set('groupsToSave', { HDFS: 'my cool group'});
-      mainServiceInfoConfigsController.set('recommendations', Em.A([{name: 'prop_1'}]));
-      mainServiceInfoConfigsController.doCancel();
       expect(App.isEmptyObject(mainServiceInfoConfigsController.get('recommendations'))).to.be.true;
-      expect(mainServiceInfoConfigsController.clearRecommendationsInfo.calledOnce).to.be.true;
     });
   });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/service/item_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/item_test.js b/ambari-web/test/controllers/main/service/item_test.js
index 1b21b78..969305d 100644
--- a/ambari-web/test/controllers/main/service/item_test.js
+++ b/ambari-web/test/controllers/main/service/item_test.js
@@ -1416,6 +1416,7 @@ describe('App.MainServiceItemController', function () {
       sinon.stub(App.ModalPopup, 'show');
       sinon.stub(App.format, 'role', function(name) {return name});
       sinon.stub(mainServiceItemController, 'kerberosDeleteWarning');
+      sinon.stub(mainServiceItemController, 'showLastWarning');
 
       mainServiceItemController.reopen({
         interDependentServices: []
@@ -1475,7 +1476,7 @@ describe('App.MainServiceItemController', function () {
       this.allowUninstallServices.returns(true);
       this.mockService.returns([Em.Object.create({workStatus: App.Service.statesMap.stopped}), Em.Object.create({workStatus: App.Service.statesMap.stopped})]);
       mainServiceItemController.deleteService('S1');
-      expect(App.showConfirmationPopup.calledOnce).to.be.true;
+      expect(mainServiceItemController.showLastWarning.calledOnce).to.be.true;
     });
 
     it("service has not dependent services, and install failed", function() {
@@ -1483,7 +1484,7 @@ describe('App.MainServiceItemController', function () {
       this.allowUninstallServices.returns(true);
       this.mockService.returns([Em.Object.create({workStatus: App.Service.statesMap.install_failed}), Em.Object.create({workStatus: App.Service.statesMap.install_failed})]);
       mainServiceItemController.deleteService('S1');
-      expect(App.showConfirmationPopup.calledOnce).to.be.true;
+      expect(mainServiceItemController.showLastWarning.calledOnce).to.be.true;
     });
 
     it("service has not dependent services, and not stopped", function() {
@@ -1707,29 +1708,27 @@ describe('App.MainServiceItemController', function () {
 
     beforeEach(function() {
       mainServiceItemController = App.MainServiceItemController.create({});
-      sinon.stub(mainServiceItemController, 'loadConfigRecommendations', Em.K);
+      sinon.stub(mainServiceItemController, 'saveConfigs', Em.K);
       sinon.stub(mainServiceItemController, 'deleteServiceCall', Em.K);
-      sinon.stub(App.get('router.mainController'), 'isLoading').returns($.Deferred().resolve().promise());
       mainServiceItemController.reopen({
         interDependentServices: []
       })
     });
     afterEach(function() {
-      mainServiceItemController.loadConfigRecommendations.restore();
+      mainServiceItemController.saveConfigs.restore();
       mainServiceItemController.deleteServiceCall.restore();
-      App.get('router.mainController').isLoading.restore();
     });
 
-    it("loadConfigRecommendations should be called", function() {
+    it("saveConfigs should be called", function() {
       mainServiceItemController.deleteServiceCallSuccessCallback([], null, {});
       expect(mainServiceItemController.deleteServiceCall.called).to.be.false;
-      expect(mainServiceItemController.loadConfigRecommendations.calledOnce).to.be.true;
+      expect(mainServiceItemController.saveConfigs.calledOnce).to.be.true;
     });
 
     it("deleteServiceCall should be called", function() {
       mainServiceItemController.deleteServiceCallSuccessCallback([], null, {servicesToDeleteNext: true});
       expect(mainServiceItemController.deleteServiceCall.calledOnce).to.be.true;
-      expect(mainServiceItemController.loadConfigRecommendations.called).to.be.false;
+      expect(mainServiceItemController.saveConfigs.called).to.be.false;
     });
   });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js
index a43d91f..7dbf24a 100644
--- a/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js
+++ b/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js
@@ -33,7 +33,7 @@ describe('App.ReassignMasterWizardStep1Controller', function () {
   });
   controller.set('_super', Em.K);
 
-  describe('#loadConfigTags', function() {
+  describe('#loadConfigsTags', function() {
     beforeEach(function() {
       this.stub = sinon.stub(App.router, 'get');
     });
@@ -42,7 +42,7 @@ describe('App.ReassignMasterWizardStep1Controller', function () {
       this.stub.restore();
     });
 
-    it('tests loadConfigTags', function() {
+    it('tests loadConfigsTags', function() {
       controller.loadConfigsTags();
       var args = testHelpers.findAjaxRequest('name', 'config.tags');
       expect(args).exists;
@@ -77,8 +77,11 @@ describe('App.ReassignMasterWizardStep1Controller', function () {
     });
 
     it('tests getDatabaseHost', function() {
-      controller.set('content.serviceProperties', {
-        'javax.jdo.option.ConnectionURL': "jdbc:mysql://c6401/hive?createDatabaseIfNotExist=true"
+      controller.set('content.configs', {
+        'hive-site': {
+          'javax.jdo.option.ConnectionURL': 'jdbc:mysql://c6401/hive?createDatabaseIfNotExist=true'
+
+        }
       });
 
       controller.set('content.reassign.service_id', 'HIVE');
@@ -108,7 +111,8 @@ describe('App.ReassignMasterWizardStep1Controller', function () {
       sinon.stub(controller, 'getDatabaseHost', Em.K);
       sinon.stub(controller, 'saveDatabaseType', Em.K);
       sinon.stub(controller, 'saveServiceProperties', Em.K);
-    
+      sinon.stub(controller, 'saveConfigs', Em.K);
+
       reassignCtrl = App.router.reassignMasterController;
       reassignCtrl.set('content.hasManualSteps', true);
     });
@@ -117,12 +121,14 @@ describe('App.ReassignMasterWizardStep1Controller', function () {
       controller.getDatabaseHost.restore();
       controller.saveDatabaseType.restore();
       controller.saveServiceProperties.restore();
+      controller.saveConfigs.restore();
     });
   
     it('should not set hasManualSteps to false for oozie with derby db', function() {
       var data = {
         items: [
           {
+            type: 'oozie-site',
             properties: {
               'oozie.service.JPAService.jdbc.driver': 'jdbc:derby:${oozie.data.dir}/${oozie.db.schema.name}-db;create=true'
             }
@@ -141,6 +147,7 @@ describe('App.ReassignMasterWizardStep1Controller', function () {
       var data = {
         items: [
           {
+            type: 'oozie-site',
             properties: {
               'oozie.service.JPAService.jdbc.driver': 'mysql'
             }

http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js
index e433f47..203d162 100644
--- a/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js
+++ b/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js
@@ -18,6 +18,8 @@
 
 var App = require('app');
 require('controllers/main/service/reassign/step3_controller');
+require('controllers/main/service/reassign_controller');
+var testHelpers = require('test/helpers');
 var controller;
 
 describe('App.ReassignMasterWizardStep3Controller', function () {
@@ -50,4 +52,636 @@ describe('App.ReassignMasterWizardStep3Controller', function () {
       expect(App.router.send.calledWith("next")).to.be.true;
     });
   });
+
+  describe('#setAdditionalConfigs()', function () {
+
+    beforeEach(function () {
+      sinon.stub(App, 'get').withArgs('isHaEnabled').returns(true);
+    });
+
+    afterEach(function () {
+      App.get.restore();
+    });
+
+    it('Component is absent', function () {
+      controller.set('additionalConfigsMap', []);
+      var configs = {};
+
+      expect(controller.setAdditionalConfigs(configs, 'COMP1', '')).to.be.false;
+      expect(configs).to.eql({});
+    });
+
+    it('configs for Hadoop 2 is present', function () {
+      controller.set('additionalConfigsMap', [
+        {
+          componentName: 'COMP1',
+          configs: {
+            'test-site': {
+              'property1': '<replace-value>:1111'
+            }
+          },
+          configs_Hadoop2: {
+            'test-site': {
+              'property2': '<replace-value>:2222'
+            }
+          }
+        }
+      ]);
+      var configs = {
+        'test-site': {}
+      };
+
+      expect(controller.setAdditionalConfigs(configs, 'COMP1', 'host1')).to.be.true;
+      expect(configs).to.eql({
+        'test-site': {
+          'property2': 'host1:2222'
+        }
+      });
+    });
+
+    it('ignore some configs for NameNode after HA', function () {
+      controller.set('additionalConfigsMap', [
+        {
+          componentName: 'NAMENODE',
+          configs: {
+            'test-site': {
+              'fs.defaultFS': '<replace-value>:1111',
+              'dfs.namenode.rpc-address': '<replace-value>:1111'
+            }
+          }
+        }
+      ]);
+      var configs = {'test-site': {}};
+
+      expect(controller.setAdditionalConfigs(configs, 'NAMENODE', 'host1')).to.be.true;
+      expect(configs).to.eql({'test-site': {}});
+    });
+  });
+
+  describe('#getConfigUrlParams()', function () {
+    var testCases = [
+      {
+        componentName: 'NAMENODE',
+        result: [
+          "(type=hdfs-site&tag=1)",
+          "(type=core-site&tag=2)"
+        ]
+      },
+      {
+        componentName: 'SECONDARY_NAMENODE',
+        result: [
+          "(type=hdfs-site&tag=1)",
+          "(type=core-site&tag=2)"
+        ]
+      },
+      {
+        componentName: 'JOBTRACKER',
+        result: [
+          "(type=mapred-site&tag=4)"
+        ]
+      },
+      {
+        componentName: 'RESOURCEMANAGER',
+        result: [
+          "(type=yarn-site&tag=5)"
+        ]
+      },
+      {
+        componentName: 'APP_TIMELINE_SERVER',
+        result: [
+          "(type=yarn-site&tag=5)",
+          "(type=yarn-env&tag=8)"
+        ]
+      },
+      {
+        componentName: 'OOZIE_SERVER',
+        result: [
+          "(type=oozie-site&tag=6)",
+          "(type=core-site&tag=2)",
+          "(type=oozie-env&tag=2)"
+        ]
+      },
+      {
+        componentName: 'WEBHCAT_SERVER',
+        result: [
+          "(type=hive-env&tag=11)",
+          "(type=webhcat-site&tag=7)",
+          "(type=core-site&tag=2)"
+        ]
+      },
+      {
+        componentName: 'HIVE_SERVER',
+        result: [
+          '(type=hive-site&tag=10)',
+          '(type=webhcat-site&tag=7)',
+          '(type=hive-env&tag=11)',
+          '(type=core-site&tag=2)'
+        ]
+      },
+      {
+        componentName: 'HIVE_METASTORE',
+        result: [
+          '(type=hive-site&tag=10)',
+          '(type=webhcat-site&tag=7)',
+          '(type=hive-env&tag=11)',
+          '(type=core-site&tag=2)'
+        ]
+      },
+      {
+        componentName: 'MYSQL_SERVER',
+        result: [
+          '(type=hive-site&tag=10)'
+        ]
+      },
+      {
+        componentName: 'HISTORYSERVER',
+        result: [
+          '(type=mapred-site&tag=4)'
+        ]
+      }
+    ];
+
+    var data = {
+      Clusters: {
+        desired_configs: {
+          'hdfs-site': {tag: 1},
+          'core-site': {tag: 2},
+          'hbase-site': {tag: 3},
+          'mapred-site': {tag: 4},
+          'yarn-site': {tag: 5},
+          'oozie-site': {tag: 6},
+          'oozie-env': {tag: 2},
+          'webhcat-site': {tag: 7},
+          'yarn-env': {tag: 8},
+          'accumulo-site': {tag: 9},
+          'hive-site': {tag: 10},
+          'hive-env': {tag: 11}
+        }
+      }
+    };
+
+    var services = [];
+
+    beforeEach(function () {
+      controller.set('wizardController', App.get('router.reassignMasterController'));
+      sinon.stub(App.Service, 'find', function () {
+        return services;
+      });
+    });
+    afterEach(function () {
+      App.Service.find.restore();
+    });
+
+    testCases.forEach(function (test) {
+      it('get config of ' + test.componentName, function () {
+        expect(controller.getConfigUrlParams(test.componentName, data)).to.eql(test.result);
+      });
+    });
+    it('get config of NAMENODE when HBASE installed', function () {
+      services = [
+        {
+          serviceName: 'HBASE'
+        }
+      ];
+      expect(controller.getConfigUrlParams('NAMENODE', data)).to.eql([
+        "(type=hdfs-site&tag=1)",
+        "(type=core-site&tag=2)",
+        "(type=hbase-site&tag=3)"
+      ]);
+    });
+
+    it('get config of NAMENODE when ACCUMULO installed', function () {
+      services = [
+        {
+          serviceName: 'ACCUMULO'
+        }
+      ];
+      expect(controller.getConfigUrlParams('NAMENODE', data)).to.eql([
+        "(type=hdfs-site&tag=1)",
+        "(type=core-site&tag=2)",
+        "(type=accumulo-site&tag=9)"
+      ]);
+    });
+
+  });
+
+  describe('#onLoadConfigsTags()', function () {
+    var dummyData = {
+      Clusters: {
+        desired_configs : {}
+      }
+    };
+
+    beforeEach(function () {
+      sinon.stub(controller, 'getConfigUrlParams', function () {
+        return [];
+      });
+      controller.set('content', {
+        reassign: {
+          component_name: 'COMP1'
+        }
+      });
+      controller.onLoadConfigsTags(dummyData);
+      this.args = testHelpers.findAjaxRequest('name', 'reassign.load_configs');
+    });
+
+    afterEach(function () {
+      controller.getConfigUrlParams.restore();
+    });
+
+    it('request is sent', function () {
+      expect(this.args).exists;
+    });
+
+    it('getConfigUrlParams is called with correct data', function () {
+      expect(controller.getConfigUrlParams.calledWith('COMP1', dummyData)).to.be.true;
+    });
+  });
+
+  describe('#setSecureConfigs()', function () {
+
+    beforeEach(function () {
+      this.stub = sinon.stub(App, 'get');
+    });
+
+    afterEach(function () {
+      Em.tryInvoke(App.get, 'restore');
+    });
+
+    it('undefined component and security disabled', function () {
+      var secureConfigs = [];
+      this.stub.withArgs('isKerberosEnabled').returns(false);
+      controller.set('secureConfigsMap', []);
+      expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
+      expect(secureConfigs).to.eql([]);
+    });
+
+    it('component exist and security disabled', function () {
+      var secureConfigs = [];
+      this.stub.withArgs('isKerberosEnabled').returns(false);
+      controller.set('secureConfigsMap', [{
+        componentName: 'COMP1'
+      }]);
+      expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
+      expect(secureConfigs).to.eql([]);
+    });
+
+    it('undefined component and security enabled', function () {
+      var secureConfigs = [];
+      this.stub.withArgs('isKerberosEnabled').returns(true);
+      controller.set('secureConfigsMap', []);
+      expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
+      expect(secureConfigs).to.eql([]);
+    });
+    it('component exist and security enabled', function () {
+      var secureConfigs = [];
+      this.stub.withArgs('isKerberosEnabled').returns(true);
+      var configs = {'s1': {
+        'k1': 'kValue',
+        'p1': 'pValue'
+      }};
+      controller.set('secureConfigsMap', [{
+        componentName: 'COMP1',
+        configs: [{
+          site: 's1',
+          keytab: 'k1',
+          principal: 'p1'
+        }]
+      }]);
+      expect(controller.setSecureConfigs(secureConfigs, configs, 'COMP1')).to.be.true;
+      expect(secureConfigs).to.eql([
+        {
+          "keytab": "kValue",
+          "principal": "pValue"
+        }
+      ]);
+    });
+  });
+
+  describe('#setDynamicCinfigs()', function () {
+
+    describe('HIVE', function() {
+      beforeEach(function () {
+        controller.set('content', Em.Object.create({
+          masterComponentHosts: [
+            {
+              component: 'HIVE_METASTORE',
+              hostName: 'host1'
+            },
+            {
+              component: 'HIVE_METASTORE',
+              hostName: 'host3'
+            },
+            {
+              component: 'HIVE_SERVER',
+              hostName: 'host4'
+            }
+          ],
+          reassignHosts: {
+            source: 'host1',
+            target: 'host2'
+          }
+        }));
+      });
+      it("reassign component is HIVE_METASTORE", function() {
+        var configs = {
+          'hive-env': {
+            'hive_user': 'hive_user'
+          },
+          'hive-site': {
+            'hive.metastore.uris': ''
+          },
+          'webhcat-site': {
+            'templeton.hive.properties': 'thrift'
+          },
+          'core-site': {
+            'hadoop.proxyuser.hive_user.hosts': ''
+          }
+        };
+        App.MoveHmConfigInitializer.setup(controller._getHiveInitializerSettings(configs));
+        configs = controller.setDynamicConfigs(configs, App.MoveHmConfigInitializer);
+        expect(configs['hive-site']['hive.metastore.uris']).to.equal('thrift://host3:9083,thrift://host2:9083');
+        expect(configs['webhcat-site']['templeton.hive.properties']).to.equal('thrift');
+        expect(configs['core-site']['hadoop.proxyuser.hive_user.hosts']).to.equal('host2,host3,host4');
+      });
+
+      it("reassign component is HIVE_SERVER", function() {
+        controller.get('content.masterComponentHosts').pushObject({component: 'HIVE_SERVER', hostName: 'host1'});
+        var configs = {
+          'hive-env': {
+            'hive_user': 'hive_user'
+          },
+          'hive-site': {
+            'hive.metastore.uris': ''
+          },
+          'webhcat-site': {
+            'templeton.hive.properties': 'thrift'
+          },
+          'core-site': {
+            'hadoop.proxyuser.hive_user.hosts': ''
+          }
+        };
+        App.MoveHsConfigInitializer.setup(controller._getHiveInitializerSettings(configs));
+        configs = controller.setDynamicConfigs(configs, App.MoveHsConfigInitializer);
+        expect(configs['core-site']['hadoop.proxyuser.hive_user.hosts']).to.equal('host1,host2,host3,host4');
+      });
+
+      it("reassign component is WEBHCAT_SERVER", function() {
+        controller.get('content.masterComponentHosts').pushObject({component: 'WEBHCAT_SERVER', hostName: 'host1'});
+        var configs = {
+          'hive-env': {
+            'webhcat_user': 'webhcat_user'
+          },
+          'hive-site': {
+            'hive.metastore.uris': ''
+          },
+          'webhcat-site': {
+            'templeton.hive.properties': 'thrift'
+          },
+          'core-site': {
+            'hadoop.proxyuser.webhcat_user.hosts': ''
+          }
+        };
+        App.MoveWsConfigInitializer.setup(controller._getWsInitializerSettings(configs));
+        configs = controller.setDynamicConfigs(configs, App.MoveWsConfigInitializer);
+        expect(configs['core-site']['hadoop.proxyuser.webhcat_user.hosts']).to.equal('host2');
+      });
+    });
+
+    describe('RESOURCEMANAGER', function () {
+      beforeEach(function () {
+        sinon.stub(App, 'get').withArgs('isRMHaEnabled').returns(true);
+      });
+      afterEach(function () {
+        App.get.restore();
+        App.MoveRmConfigInitializer.cleanup();
+      });
+
+      it('HA enabled and resource manager 1', function () {
+        controller.set('content', Em.Object.create({
+          reassignHosts: {
+            source: 'host1',
+            target: 'host3'
+          }
+        }));
+        var configs = {
+          'yarn-site': {
+            'yarn.resourcemanager.hostname.rm1': 'host1',
+            'yarn.resourcemanager.webapp.address.rm1': 'host1:8088',
+            'yarn.resourcemanager.webapp.https.address.rm1': 'host1:8443',
+            'yarn.resourcemanager.hostname.rm2': 'host2',
+            'yarn.resourcemanager.webapp.address.rm2': 'host2:8088',
+            'yarn.resourcemanager.webapp.https.address.rm2': 'host2:8443'
+          }
+        };
+        var additionalDependencies = controller._getRmAdditionalDependencies(configs);
+        App.MoveRmConfigInitializer.setup(controller._getRmInitializerSettings(configs));
+        configs = controller.setDynamicConfigs(configs, App.MoveRmConfigInitializer, additionalDependencies);
+        expect(configs['yarn-site']).to.eql({
+          'yarn.resourcemanager.hostname.rm1': 'host3',
+          'yarn.resourcemanager.webapp.address.rm1': 'host3:8088',
+          'yarn.resourcemanager.webapp.https.address.rm1': 'host3:8443',
+          'yarn.resourcemanager.hostname.rm2': 'host2',
+          'yarn.resourcemanager.webapp.address.rm2': 'host2:8088',
+          'yarn.resourcemanager.webapp.https.address.rm2': 'host2:8443'
+        });
+      });
+
+      it('HA enabled and resource manager 2', function () {
+        controller.set('content', Em.Object.create({
+          reassignHosts: {
+            source: 'host2',
+            target: 'host3'
+          }
+        }));
+        var configs = {
+          'yarn-site': {
+            'yarn.resourcemanager.hostname.rm1': 'host1',
+            'yarn.resourcemanager.webapp.address.rm1': 'host1:8088',
+            'yarn.resourcemanager.webapp.https.address.rm1': 'host1:8443',
+            'yarn.resourcemanager.hostname.rm2': 'host2',
+            'yarn.resourcemanager.webapp.address.rm2': 'host2:8088',
+            'yarn.resourcemanager.webapp.https.address.rm2': 'host2:8443'
+          }
+        };
+        var additionalDependencies = controller._getRmAdditionalDependencies(configs);
+        App.MoveRmConfigInitializer.setup(controller._getRmInitializerSettings(configs));
+        configs = controller.setDynamicConfigs(configs, App.MoveRmConfigInitializer, additionalDependencies);
+
+        expect(configs['yarn-site']).to.eql({
+          'yarn.resourcemanager.hostname.rm1': 'host1',
+          'yarn.resourcemanager.webapp.address.rm1': 'host1:8088',
+          'yarn.resourcemanager.webapp.https.address.rm1': 'host1:8443',
+          'yarn.resourcemanager.hostname.rm2': 'host3',
+          'yarn.resourcemanager.webapp.address.rm2': 'host3:8088',
+          'yarn.resourcemanager.webapp.https.address.rm2': 'host3:8443'
+        });
+      });
+    });
+
+    describe('NAMENODE', function () {
+      var isHaEnabled = false;
+
+      beforeEach(function () {
+        sinon.stub(App, 'get', function () {
+          return isHaEnabled;
+        });
+        sinon.stub(App.Service, 'find', function () {
+          return [
+            {serviceName: 'HDFS'},
+            {serviceName: 'ACCUMULO'},
+            {serviceName: 'HBASE'},
+            {serviceName: 'HAWQ'}
+          ];
+        });
+        controller.set('content', Em.Object.create({
+          reassignHosts: {
+            source: 'host1'
+          }
+        }));
+      });
+
+      afterEach(function () {
+        App.get.restore();
+        App.Service.find.restore();
+        App.MoveNameNodeConfigInitializer.cleanup();
+      });
+
+      it('HA isn\'t enabled and HBASE, HAWQ and ACCUMULO service', function () {
+        isHaEnabled = false;
+        var configs = {
+          'hbase-site': {
+            'hbase.rootdir': 'hdfs://localhost:8020/apps/hbase/data'
+          },
+          'accumulo-site': {
+            'instance.volumes': 'hdfs://localhost:8020/apps/accumulo/data',
+            'instance.volumes.replacements': ''
+          },
+          'hawq-site': {
+            'hawq_dfs_url': 'localhost:8020/hawq/data'
+          }
+        };
+
+        controller.set('content.reassignHosts.target', 'host2');
+
+        App.MoveNameNodeConfigInitializer.setup(controller._getNnInitializerSettings(configs));
+        configs = controller.setDynamicConfigs(configs, App.MoveNameNodeConfigInitializer);
+
+        expect(configs['hbase-site']['hbase.rootdir']).to.equal('hdfs://host2:8020/apps/hbase/data');
+        expect(configs['accumulo-site']['instance.volumes']).to.equal('hdfs://host2:8020/apps/accumulo/data');
+        expect(configs['accumulo-site']['instance.volumes.replacements']).to.equal('hdfs://host1:8020/apps/accumulo/data hdfs://host2:8020/apps/accumulo/data');
+        expect(configs['hawq-site'].hawq_dfs_url).to.equal('host2:8020/hawq/data');
+      });
+
+      it('HA enabled and namenode 1', function () {
+        isHaEnabled = true;
+        var configs = {
+          'hdfs-site': {
+            'dfs.nameservices': 's',
+            'dfs.namenode.http-address.s.nn1': 'host1:50070',
+            'dfs.namenode.https-address.s.nn1': 'host1:50470',
+            'dfs.namenode.rpc-address.s.nn1': 'host1:8020'
+          },
+          'hdfs-client': {
+            'dfs.namenode.rpc-address.s.nn1': '',
+            'dfs.namenode.http-address.s.nn1': 'host1:50070'
+          }
+        };
+
+        controller.set('content.reassignHosts.target', 'host2');
+        App.MoveNameNodeConfigInitializer.setup(controller._getNnInitializerSettings(configs));
+        configs = controller.setDynamicConfigs(configs, App.MoveNameNodeConfigInitializer);
+        expect(configs['hdfs-site']).to.eql({
+          "dfs.nameservices": "s",
+          "dfs.namenode.http-address.s.nn1": "host2:50070",
+          "dfs.namenode.https-address.s.nn1": "host2:50470",
+          "dfs.namenode.rpc-address.s.nn1": "host2:8020"
+        });
+        expect(configs['hdfs-client']).to.eql({
+          "dfs.namenode.http-address.s.nn1": "host2:50070",
+          "dfs.namenode.rpc-address.s.nn1": "host2:8020"
+        });
+      });
+
+      it('HA enabled and namenode 2', function () {
+        isHaEnabled = true;
+        var configs = {
+          'hdfs-site': {
+            'dfs.nameservices': 's',
+            "dfs.namenode.http-address.s.nn1": "host1:50070",
+            'dfs.namenode.http-address.s.nn2': 'host2:50070',
+            'dfs.namenode.https-address.s.nn2': 'host2:50470',
+            'dfs.namenode.rpc-address.s.nn2': 'host2:8020'
+          },
+          'hdfs-client': {
+            'dfs.namenode.rpc-address.s.nn2': '',
+            'dfs.namenode.http-address.s.nn2': 'host2:50070'
+          }
+        };
+        controller.set('content.reassignHosts.source', 'host2');
+        controller.set('content.reassignHosts.target', 'host3');
+
+        App.MoveNameNodeConfigInitializer.setup(controller._getNnInitializerSettings(configs));
+        configs = controller.setDynamicConfigs(configs, App.MoveNameNodeConfigInitializer);
+
+        expect(configs['hdfs-site']).to.eql({
+          "dfs.nameservices": "s",
+          "dfs.namenode.http-address.s.nn1": "host1:50070",
+          "dfs.namenode.http-address.s.nn2": "host3:50070",
+          "dfs.namenode.https-address.s.nn2": "host3:50470",
+          "dfs.namenode.rpc-address.s.nn2": "host3:8020"
+        });
+        expect(configs['hdfs-client']).to.eql({
+          "dfs.namenode.http-address.s.nn2": "host3:50070",
+          "dfs.namenode.rpc-address.s.nn2": "host3:8020"
+        });
+      });
+
+    });
+
+    describe('OOZIE_SERVER', function () {
+
+      it('should upodate hadoop.proxyuser.${oozie_user}.hosts', function () {
+
+        var configs = {
+          'oozie-env': {
+            'oozie_user': 'cool_dude'
+          },
+          'core-site': {
+            'hadoop.proxyuser.cool_dude.hosts': ''
+          }
+        };
+
+        controller.set('content', Em.Object.create({
+          masterComponentHosts: [
+            {
+              component: 'OOZIE_SERVER',
+              hostName: 'host2'
+            },
+            {
+              component: 'OOZIE_SERVER',
+              hostName: 'host3'
+            },
+            {
+              component: 'OOZIE_SERVER',
+              hostName: 'host1'
+            }
+          ],
+          reassignHosts: {
+            source: 'host1',
+            target: 'host4'
+          }
+        }));
+
+        App.MoveOSConfigInitializer.setup(controller._getOsInitializerSettings(configs));
+        configs = controller.setDynamicConfigs(configs, App.MoveOSConfigInitializer);
+        App.MoveOSConfigInitializer.cleanup();
+
+        expect(configs['core-site']['hadoop.proxyuser.cool_dude.hosts']).to.equal('host2,host3,host4');
+
+      });
+
+    });
+
+  });
 });