Pārlūkot izejas kodu

AMBARI-12162 Error after renaming config group and creating new one with the same name. (atkach)

Andrii Tkach 10 gadi atpakaļ
vecāks
revīzija
e01a0ba836

+ 112 - 62
ambari-web/app/controllers/main/service/manage_config_groups_controller.js

@@ -752,81 +752,131 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
 
       primary: Em.I18n.t('common.save'),
 
-      subViewController: function () {
-        return configsController;
-      }.property(),
+      subViewController: configsController,
+
+      /**
+       * handle onPrimary action particularly in wizard
+       * @param {Em.Controller} controller
+       * @param {object} modifiedConfigGroups
+       */
+      onPrimaryWizard: function (controller, modifiedConfigGroups) {
+        controller.set('selectedService.configGroups', configsController.get('configGroups'));
+        controller.selectedServiceObserver();
+        if (controller.get('name') == "wizardStep7Controller") {
+          if (controller.get('selectedService.selected') === false && modifiedConfigGroups.toDelete.length > 0) {
+            controller.setGroupsToDelete(modifiedConfigGroups.toDelete);
+          }
+          configsController.persistConfigGroups();
+          this.updateConfigGroupOnServicePage();
+        }
+        this.hide();
+      },
+
+      /**
+       * run requests which delete config group and clear its hosts
+       * @param {Function} finishFunction
+       * @param {object} modifiedConfigGroups
+       */
+      runClearCGQueue: function (finishFunction, modifiedConfigGroups) {
+        var counter = 0;
+        var dfd = $.Deferred();
+        var doneFunction = function (xhr, text, errorThrown) {
+          counter--;
+          if (counter === 0) dfd.resolve();
+          finishFunction(xhr, text, errorThrown);
+        };
+
+        modifiedConfigGroups.toClearHosts.forEach(function (cg) {
+          counter++;
+          var initialGroupState = modifiedConfigGroups.initialGroups.findProperty('name', cg.get('name'));
+          configsController.clearConfigurationGroupHosts(cg, initialGroupState, doneFunction, doneFunction);
+        }, this);
+        modifiedConfigGroups.toDelete.forEach(function (cg) {
+          counter++;
+          configsController.deleteConfigurationGroup(cg, doneFunction, doneFunction);
+        }, this);
+        if (counter === 0) dfd.resolve();
+        return dfd.promise();
+      },
+
+      /**
+       * run requests which change properties of config group
+       * @param {Function} finishFunction
+       * @param {object} modifiedConfigGroups
+       */
+      runModifyCGQueue: function (finishFunction, modifiedConfigGroups) {
+        var counter = 0;
+        var dfd = $.Deferred();
+        var doneFunction = function (xhr, text, errorThrown) {
+          counter--;
+          if (counter === 0) dfd.resolve();
+          finishFunction(xhr, text, errorThrown);
+        };
+
+        modifiedConfigGroups.toSetHosts.forEach(function (cg) {
+          counter++;
+          configsController.updateConfigurationGroup(cg, doneFunction, doneFunction);
+        }, this);
+        if (counter === 0) dfd.resolve();
+        return dfd.promise();
+      },
+
+      /**
+       * run requests which create new config group
+       * @param {Function} finishFunction
+       * @param {object} modifiedConfigGroups
+       */
+      runCreateCGQueue: function (finishFunction, modifiedConfigGroups) {
+        var counter = 0;
+        var dfd = $.Deferred();
+        var doneFunction = function (xhr, text, errorThrown) {
+          counter--;
+          if (counter === 0) dfd.resolve();
+          finishFunction(xhr, text, errorThrown);
+        };
+
+        modifiedConfigGroups.toCreate.forEach(function (cg) {
+          counter++;
+          configsController.postNewConfigurationGroup(cg, doneFunction);
+        }, this);
+        if (counter === 0) dfd.resolve();
+        return dfd.promise();
+      },
 
       onPrimary: function () {
         var modifiedConfigGroups = configsController.get('hostsModifiedConfigGroups');
-        // Save modified config-groups
-        if (!!controller) {
-          controller.set('selectedService.configGroups', configsController.get('configGroups'));
-          controller.selectedServiceObserver();
-          if (controller.get('name') == "wizardStep7Controller") {
-            if (controller.get('selectedService.selected') === false && modifiedConfigGroups.toDelete.length > 0) {
-              controller.setGroupsToDelete(modifiedConfigGroups.toDelete);
-            }
-            configsController.persistConfigGroups();
-            this.updateConfigGroupOnServicePage();
-          }
-          this.hide();
-          return;
-        }
-        var self = this;
         var errors = [];
-        var deleteQueriesCounter = modifiedConfigGroups.toClearHosts.length + modifiedConfigGroups.toDelete.length;
-        var createQueriesCounter = modifiedConfigGroups.toSetHosts.length + modifiedConfigGroups.toCreate.length;
-        var deleteQueriesRun = false;
-        var createQueriesRun = false;
-        var runNextQuery = function () {
-          if (!deleteQueriesRun && deleteQueriesCounter > 0) {
-            deleteQueriesRun = true;
-            modifiedConfigGroups.toClearHosts.forEach(function (cg) {
-              var initalGroupState = modifiedConfigGroups.initialGroups.findProperty('name', cg.get('name'));
-              configsController.clearConfigurationGroupHosts(cg, initalGroupState, finishFunction, finishFunction);
-            }, this);
-            modifiedConfigGroups.toDelete.forEach(function (cg) {
-              var deleteSuccess = function() {
-                var groupFromModel = App.ServiceConfigGroup.find().filterProperty('serviceName', cg.get('service.serviceName')).findProperty('name', cg.get('name'));
-                if (groupFromModel) {
-                  App.configGroupsMapper.deleteRecord(groupFromModel);
-                }
-                finishFunction();
-              };
-              configsController.deleteConfigurationGroup(cg, deleteSuccess, finishFunction);
-            }, this);
-          } else if (!createQueriesRun && deleteQueriesCounter < 1) {
-            createQueriesRun = true;
-            modifiedConfigGroups.toSetHosts.forEach(function (cg) {
-              configsController.updateConfigurationGroup(cg, finishFunction, finishFunction);
-            }, this);
-            modifiedConfigGroups.toCreate.forEach(function (cg) {
-              configsController.postNewConfigurationGroup(cg, finishFunction);
-            }, this);
-          }
-        };
+        var self = this;
         var finishFunction = function (xhr, text, errorThrown) {
           if (xhr && errorThrown) {
             var error = xhr.status + "(" + errorThrown + ") ";
             try {
               var json = $.parseJSON(xhr.responseText);
               error += json.message;
-            } catch (err) {}
-            errors.push(error);
-          }
-          createQueriesRun ? createQueriesCounter-- : deleteQueriesCounter--;
-          if (deleteQueriesCounter + createQueriesCounter < 1) {
-            if (errors.length > 0) {
-              self.get('subViewController').set('errorMessage', errors.join(". "));
-            } else {
-              self.updateConfigGroupOnServicePage();
-              self.hide();
+            } catch (err) {
             }
-          } else {
-            runNextQuery();
+            errors.push(error);
           }
         };
-        runNextQuery();
+
+        // Save modified config-groups
+        if (controller) {
+          //called only in Wizard
+          return this.onPrimaryWizard(controller, modifiedConfigGroups);
+        }
+
+        this.runClearCGQueue(finishFunction, modifiedConfigGroups).done(function () {
+          self.runModifyCGQueue(finishFunction, modifiedConfigGroups).done(function () {
+            self.runCreateCGQueue(finishFunction, modifiedConfigGroups).done(function () {
+              if (errors.length > 0) {
+                self.get('subViewController').set('errorMessage', errors.join(". "));
+              } else {
+                self.updateConfigGroupOnServicePage();
+                self.hide();
+              }
+            });
+          });
+        });
       },
 
       updateConfigGroupOnServicePage: function () {

+ 10 - 7
ambari-web/app/mixins/main/service/configs/config_overridable.js

@@ -259,8 +259,7 @@ App.ConfigOverridable = Em.Mixin.create({
       }
     };
     sendData.sender = sendData;
-    App.ajax.send(sendData);
-    return newConfigGroupData;
+    return App.ajax.send(sendData);
   },
 
   /**
@@ -367,16 +366,16 @@ App.ConfigOverridable = Em.Mixin.create({
    * Update config group's hosts list and leave only unmodified hosts in the group
    * Save updated config group on server
    * @param {App.ConfigGroup} configGroup
-   * @param {App.ConfigGroup} initalGroupState
+   * @param {App.ConfigGroup} initialGroupState
    * @param {Function} successCallback
    * @param {Function} errorCallback
    * @method clearConfigurationGroupHosts
    */
-  clearConfigurationGroupHosts: function (configGroup, initalGroupState, successCallback, errorCallback) {
+  clearConfigurationGroupHosts: function (configGroup, initialGroupState, successCallback, errorCallback) {
     configGroup = jQuery.extend({}, configGroup);
-    var unmodifiedHosts = this.getUnmodifiedHosts(configGroup, initalGroupState);
+    var unmodifiedHosts = this.getUnmodifiedHosts(configGroup, initialGroupState);
     configGroup.set('hosts', unmodifiedHosts);
-    this.updateConfigurationGroup(configGroup, successCallback, errorCallback);
+    return this.updateConfigurationGroup(configGroup, successCallback, errorCallback);
   },
 
   /**
@@ -409,7 +408,11 @@ App.ConfigOverridable = Em.Mixin.create({
       },
       success: 'successFunction',
       error: 'errorFunction',
-      successFunction: function () {
+      successFunction: function (data, xhr, params) {
+        var groupFromModel = App.ServiceConfigGroup.find().findProperty('configGroupId', params.id);
+        if (groupFromModel) {
+          App.configGroupsMapper.deleteRecord(groupFromModel);
+        }
         if (successCallback) {
           successCallback();
         }

+ 169 - 0
ambari-web/test/controllers/main/service/manage_config_groups_controller_test.js

@@ -157,4 +157,173 @@ describe('App.ManageConfigGroupsController', function() {
 
   });
 
+  describe("#manageConfigurationGroups", function () {
+    var service = Em.Object.create({});
+    manageConfigGroupsController.set('hostsModifiedConfigGroups', {});
+    describe("#controller passed", function () {
+      var controller = Em.Object.create({
+        content: Em.Object.create()
+      });
+      var popup = manageConfigGroupsController.manageConfigurationGroups(controller, service);
+
+      describe("#onPrimary()", function () {
+        beforeEach(function () {
+          sinon.stub(popup, 'onPrimaryWizard', Em.K);
+        });
+        afterEach(function () {
+          popup.onPrimaryWizard.restore();
+        });
+        it("", function () {
+          popup.onPrimary();
+          expect(popup.onPrimaryWizard.calledOnce).to.be.true;
+        });
+      });
+
+      describe("#onPrimaryWizard()", function () {
+        var ctrl = Em.Object.create({
+          selectedService: Em.Object.create({
+            selected: false
+          }),
+          selectedServiceObserver: Em.K,
+          setGroupsToDelete: Em.K
+        });
+        beforeEach(function () {
+          sinon.spy(ctrl, 'selectedServiceObserver');
+          sinon.spy(ctrl, 'setGroupsToDelete');
+          sinon.stub(manageConfigGroupsController, 'persistConfigGroups', Em.K);
+          sinon.stub(popup, 'updateConfigGroupOnServicePage', Em.K);
+          sinon.stub(popup, 'hide', Em.K);
+        });
+        afterEach(function () {
+          ctrl.setGroupsToDelete.restore();
+          ctrl.selectedServiceObserver.restore();
+          manageConfigGroupsController.persistConfigGroups.restore();
+          popup.updateConfigGroupOnServicePage.restore();
+          popup.hide.restore();
+        });
+        it("groups deleted on 7th step", function () {
+          ctrl.set('name', 'wizardStep7Controller');
+          popup.onPrimaryWizard(ctrl, {toDelete: [1]});
+          expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
+          expect(ctrl.setGroupsToDelete.calledWith([1])).to.be.true;
+          expect(manageConfigGroupsController.persistConfigGroups.calledOnce).to.be.true;
+          expect(popup.updateConfigGroupOnServicePage.calledOnce).to.be.true;
+          expect(popup.hide.calledOnce).to.be.true;
+        });
+        it("wizard not on 7th step", function () {
+          ctrl.set('name', '');
+          popup.onPrimaryWizard(ctrl, {});
+          expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
+          expect(ctrl.setGroupsToDelete.called).to.be.false;
+          expect(manageConfigGroupsController.persistConfigGroups.called).to.be.false;
+          expect(popup.updateConfigGroupOnServicePage.called).to.be.false;
+          expect(popup.hide.calledOnce).to.be.true;
+        });
+        it("wizard on 7th step, service selected", function () {
+          ctrl.set('name', 'wizardStep7Controller');
+          ctrl.set('selectedService.selected', true);
+          popup.onPrimaryWizard(ctrl, {toDelete: [1]});
+          expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
+          expect(ctrl.setGroupsToDelete.called).to.be.false;
+          expect(manageConfigGroupsController.persistConfigGroups.calledOnce).to.be.true;
+          expect(popup.updateConfigGroupOnServicePage.calledOnce).to.be.true;
+          expect(popup.hide.calledOnce).to.be.true;
+        });
+        it("wizard on 7th step, no groups to delete", function () {
+          ctrl.set('name', 'wizardStep7Controller');
+          ctrl.set('selectedService.selected', false);
+          popup.onPrimaryWizard(ctrl, {toDelete: []});
+          expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
+          expect(ctrl.setGroupsToDelete.called).to.be.false;
+          expect(manageConfigGroupsController.persistConfigGroups.calledOnce).to.be.true;
+          expect(popup.updateConfigGroupOnServicePage.calledOnce).to.be.true;
+          expect(popup.hide.calledOnce).to.be.true;
+        });
+      });
+    });
+
+    describe("#controller not passed", function () {
+      var popup = manageConfigGroupsController.manageConfigurationGroups(null, service);
+
+      describe("#onPrimary()", function () {
+        beforeEach(function () {
+          sinon.stub(popup, 'runClearCGQueue').returns({
+            done: function (callback) {
+              callback();
+            }
+          });
+          sinon.stub(popup, 'runModifyCGQueue').returns({
+            done: function (callback) {
+              callback();
+            }
+          });
+          sinon.stub(popup, 'runCreateCGQueue').returns({
+            done: function (callback) {
+              callback();
+            }
+          });
+          sinon.stub(popup, 'updateConfigGroupOnServicePage', Em.K);
+          sinon.stub(popup, 'hide', Em.K);
+        });
+        afterEach(function () {
+          popup.runCreateCGQueue.restore();
+          popup.runModifyCGQueue.restore();
+          popup.runClearCGQueue.restore();
+          popup.updateConfigGroupOnServicePage.restore();
+          popup.hide.restore();
+        });
+        it("", function () {
+          popup.onPrimary();
+          expect(popup.runClearCGQueue.calledOnce).to.be.true;
+          expect(popup.runModifyCGQueue.calledOnce).to.be.true;
+          expect(popup.runCreateCGQueue.calledOnce).to.be.true;
+          expect(popup.updateConfigGroupOnServicePage.calledOnce).to.be.true;
+          expect(popup.hide.calledOnce).to.be.true;
+        });
+      });
+      describe("#runClearCGQueue()", function () {
+        beforeEach(function () {
+          sinon.stub(manageConfigGroupsController, 'clearConfigurationGroupHosts', Em.K);
+          sinon.stub(manageConfigGroupsController, 'deleteConfigurationGroup', Em.K);
+        });
+        afterEach(function () {
+          manageConfigGroupsController.clearConfigurationGroupHosts.restore();
+          manageConfigGroupsController.deleteConfigurationGroup.restore();
+        });
+        it("", function () {
+          popup.runClearCGQueue(Em.K, {
+            initialGroups: [],
+            toClearHosts: [Em.Object.create()],
+            toDelete: [1]
+          });
+          expect(manageConfigGroupsController.clearConfigurationGroupHosts.calledOnce).to.be.true;
+          expect(manageConfigGroupsController.deleteConfigurationGroup.calledOnce).to.be.true;
+        });
+      });
+      describe("#runModifyCGQueue()", function () {
+        beforeEach(function () {
+          sinon.stub(manageConfigGroupsController, 'updateConfigurationGroup', Em.K);
+        });
+        afterEach(function () {
+          manageConfigGroupsController.updateConfigurationGroup.restore();
+        });
+        it("", function () {
+          popup.runModifyCGQueue(Em.K, {toSetHosts: [1]});
+          expect(manageConfigGroupsController.updateConfigurationGroup.calledOnce).to.be.true;
+        });
+      });
+      describe("#runCreateCGQueue()", function () {
+        beforeEach(function () {
+          sinon.stub(manageConfigGroupsController, 'postNewConfigurationGroup', Em.K);
+        });
+        afterEach(function () {
+          manageConfigGroupsController.postNewConfigurationGroup.restore();
+        });
+        it("", function () {
+          popup.runCreateCGQueue(Em.K, {toCreate: [1]});
+          expect(manageConfigGroupsController.postNewConfigurationGroup.calledOnce).to.be.true;
+        });
+      });
+    });
+  });
 });