Quellcode durchsuchen

AMBARI-8721 Give ability for user to change Database and Database url for hive and oozie. (atkach)

Andrii Tkach vor 10 Jahren
Ursprung
Commit
828dc79fae

+ 1 - 0
ambari-web/app/assets/test/tests.js

@@ -213,6 +213,7 @@ var files = ['test/init_model_test',
   'test/views/wizard/step3/hostLogPopupBody_view_test',
   'test/views/wizard/step3/hostWarningPopupBody_view_test',
   'test/views/wizard/step3/hostWarningPopupFooter_view_test',
+  'test/views/wizard/controls_view_test',
   'test/views/wizard/step0_view_test',
   'test/views/wizard/step1_view_test',
   'test/views/wizard/step2_view_test',

+ 2 - 2
ambari-web/app/data/BIGTOP/site_properties.js

@@ -2601,7 +2601,7 @@ module.exports =
       ],
       "description": "PostgreSQL will be installed by Ambari",
       "displayType": "radio button",
-      "isReconfigurable": false,
+      "isReconfigurable": true,
       "radioName": "hive-database",
       "isOverridable": false,
       "isVisible": true,
@@ -2935,7 +2935,7 @@ module.exports =
       ],
       "description": "Current Derby Database will be installed by Ambari",
       "displayType": "radio button",
-      "isReconfigurable": false,
+      "isReconfigurable": true,
       "isOverridable": false,
       "radioName": "oozie-database",
       "isVisible": true,

+ 2 - 2
ambari-web/app/data/HDP2/site_properties.js

@@ -3372,7 +3372,7 @@ module.exports =
       ],
       "description": "MySQL will be installed by Ambari",
       "displayType": "radio button",
-      "isReconfigurable": false,
+      "isReconfigurable": true,
       "radioName": "hive-database",
       "isOverridable": false,
       "isVisible": true,
@@ -3809,7 +3809,7 @@ module.exports =
       ],
       "description": "Current Derby Database will be installed by Ambari",
       "displayType": "radio button",
-      "isReconfigurable": false,
+      "isReconfigurable": true,
       "isOverridable": false,
       "radioName": "oozie-database",
       "isVisible": true,

+ 2 - 2
ambari-web/app/data/PHD/site_properties.js

@@ -2450,7 +2450,7 @@ module.exports =
       ],
       "description": "PostgreSQL will be installed by Ambari",
       "displayType": "radio button",
-      "isReconfigurable": false,
+      "isReconfigurable": true,
       "radioName": "hive-database",
       "isOverridable": false,
       "isVisible": true,
@@ -2792,7 +2792,7 @@ module.exports =
       ],
       "description": "Current Derby Database will be installed by Ambari",
       "displayType": "radio button",
-      "isReconfigurable": false,
+      "isReconfigurable": true,
       "isOverridable": false,
       "radioName": "oozie-database",
       "isVisible": true,

+ 2 - 2
ambari-web/app/data/site_properties.js

@@ -1701,7 +1701,7 @@ module.exports =
       ],
       "description": "MySQL will be installed by Ambari",
       "displayType": "radio button",
-      "isReconfigurable": false,
+      "isReconfigurable": true,
       "radioName": "hive-database",
       "isOverridable": false,
       "isVisible": true,
@@ -2026,7 +2026,7 @@ module.exports =
       ],
       "description": "Current Derby Database will be installed by Ambari",
       "displayType": "radio button",
-      "isReconfigurable": false,
+      "isReconfigurable": true,
       "isOverridable": false,
       "radioName": "oozie-database",
       "isVisible": true,

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

@@ -393,6 +393,7 @@ App.config = Em.Object.create({
           serviceConfigObj.id = 'site property';
           serviceConfigObj.displayName = configsPropertyDef && configsPropertyDef.displayName ? configsPropertyDef.displayName : index;
           serviceConfigObj.options = configsPropertyDef ? configsPropertyDef.options : null;
+          serviceConfigObj.radioName = configsPropertyDef ? configsPropertyDef.radioName : null;
           serviceConfigObj.serviceName = configsPropertyDef && configsPropertyDef.serviceName ? configsPropertyDef.serviceName : serviceName;
           serviceConfigObj.belongsToService = configsPropertyDef && configsPropertyDef.belongsToService ? configsPropertyDef.belongsToService : [];
           this.calculateConfigProperties(serviceConfigObj, isAdvanced, advancedConfigs);

+ 38 - 30
ambari-web/app/views/wizard/controls_view.js

@@ -201,8 +201,8 @@ App.ServiceConfigRadioButtons = Ember.View.extend({
   didInsertElement: function () {
     // on page render, automatically populate JDBC URLs only for default database settings
     // so as to not lose the user's customizations on these fields
-    if (['addServiceController', 'installerController'].contains(App.clusterStatus.wizardControllerName)) {
-      if (['New PostgreSQL Database', 'New MySQL Database', 'New Derby Database'].contains(this.get('serviceConfig.value'))) {
+    if (['addServiceController', 'installerController'].contains(this.get('controller.wizardController.name'))) {
+      if (/^New\s\w+\sDatabase$/.test(this.get('serviceConfig.value'))) {
         this.onOptionsChange();
       } else {
         this.handleDBConnectionProperty();
@@ -317,25 +317,28 @@ App.ServiceConfigRadioButtons = Ember.View.extend({
         connectionUrl.set('defaultValue', connectionUrl.get('value'));
       }
     }
-  }.observes('databaseName', 'hostName', 'connectionUrl','dbClass'),
+  }.observes('databaseName', 'hostName'),
 
   nameBinding: 'serviceConfig.radioName',
 
-  databaseName: function () {
+  databaseNameProperty: function () {
     switch (this.get('serviceConfig.serviceName')) {
       case 'HIVE':
-        return this.get('categoryConfigsAll').findProperty('name', 'ambari.hive.db.schema.name').get('value');
+        return this.get('categoryConfigsAll').findProperty('name', 'ambari.hive.db.schema.name');
       case 'HDFS':
-        return this.get('categoryConfigsAll').findProperty('name', 'sink.db.schema.name').get('value');
+        return this.get('categoryConfigsAll').findProperty('name', 'sink.db.schema.name');
       case 'OOZIE':
-        return this.get('categoryConfigsAll').findProperty('name', 'oozie.db.schema.name').get('value');
+        return this.get('categoryConfigsAll').findProperty('name', 'oozie.db.schema.name');
       default:
         return null;
     }
-  }.property('configs.@each.value', 'serviceConfig.serviceName'),
+  }.property('serviceConfig.serviceName'),
 
+  databaseName: function () {
+    return this.get('databaseNameProperty.value');
+  }.property('databaseNameProperty.value'),
 
-  hostName: function () {
+  hostNameProperty: function () {
     var value = this.get('serviceConfig.value');
     var returnValue;
     var hostname;
@@ -361,9 +364,9 @@ App.ServiceConfigRadioButtons = Ember.View.extend({
           break;
       }
       if (hostname) {
-        returnValue = hostname.get('value');
+        returnValue = hostname;
       } else {
-        returnValue = this.get('categoryConfigsAll').findProperty('name', 'hive_hostname').get('value');
+        returnValue = this.get('categoryConfigsAll').findProperty('name', 'hive_hostname');
       }
     } else if (this.get('serviceConfig.serviceName') === 'HDFS') {
       switch (value) {
@@ -371,13 +374,13 @@ App.ServiceConfigRadioButtons = Ember.View.extend({
           hostname = this.get('categoryConfigsAll').findProperty('name', 'sink_existing_mssql_server_host');
           break;
         case 'Existing MSSQL Server database with sql auth':
-           hostname = this.get('categoryConfigsAll').findProperty('name', 'sink_existing_mssql_server_2_host');
-           break;
+          hostname = this.get('categoryConfigsAll').findProperty('name', 'sink_existing_mssql_server_2_host');
+          break;
       }
       if (hostname) {
-        returnValue = hostname.get('value');
+        returnValue = hostname;
       } else {
-        returnValue = this.get('categoryConfigsAll').findProperty('name', 'sink.dbservername').get('value');
+        returnValue = this.get('categoryConfigsAll').findProperty('name', 'sink.dbservername');
       }
     } else if (this.get('serviceConfig.serviceName') === 'OOZIE') {
       switch (value) {
@@ -401,13 +404,17 @@ App.ServiceConfigRadioButtons = Ember.View.extend({
           break;
       }
       if (hostname) {
-        returnValue = hostname.get('value');
+        returnValue = hostname;
       } else {
-        returnValue = this.get('categoryConfigsAll').findProperty('name', 'oozie_hostname').get('value');
+        returnValue = this.get('categoryConfigsAll').findProperty('name', 'oozie_hostname');
       }
     }
     return returnValue;
-  }.property('serviceConfig.serviceName', 'serviceConfig.value', 'configs.@each.value'),
+  }.property('serviceConfig.serviceName', 'serviceConfig.value'),
+
+  hostName: function () {
+    return this.get('hostNameProperty.value');
+  }.property('hostNameProperty.value'),
 
   connectionUrl: function () {
     if (this.get('serviceConfig.serviceName') === 'HIVE') {
@@ -438,7 +445,6 @@ App.ServiceConfigRadioButtons = Ember.View.extend({
    * @method handleDBConnectionProperty
    **/
   handleDBConnectionProperty: function() {
-    if (!['addServiceController', 'installerController'].contains(App.clusterStatus.wizardControllerName)) return;
     var handledProperties = ['oozie_database', 'hive_database', 'sink_database'];
     var currentValue = this.get('serviceConfig.value');
     var databases = /MySQL|PostgreSQL|Oracle|Derby|MSSQL/gi;
@@ -447,15 +453,13 @@ App.ServiceConfigRadioButtons = Ember.View.extend({
     var currentDBType = currentValue.match(databasesTypes)[0];
     var existingDatabase = /existing/gi.test(currentValue);
     // db connection check button show up if existed db selected
-    if (App.supports.databaseConnection) {
-      var propertyAppendTo1 = this.get('categoryConfigsAll').findProperty('displayName', 'Database URL');
-      if (currentDB && existingDatabase) {
-        if (handledProperties.contains(this.get('serviceConfig.name'))) {
-          if (propertyAppendTo1) propertyAppendTo1.set('additionalView', App.CheckDBConnectionView.extend({databaseName: currentDB}));
-        }
-      } else {
-        propertyAppendTo1.set('additionalView', null);
+    var propertyAppendTo1 = this.get('categoryConfigsAll').findProperty('displayName', 'Database URL');
+    if (currentDB && existingDatabase) {
+      if (handledProperties.contains(this.get('serviceConfig.name'))) {
+        if (propertyAppendTo1) propertyAppendTo1.set('additionalView', App.CheckDBConnectionView.extend({databaseName: currentDB}));
       }
+    } else {
+      propertyAppendTo1.set('additionalView', null);
     }
     // warning msg under database type radio buttons, to warn the user to setup jdbc driver if existed db selected
     var propertyHive = this.get('categoryConfigsAll').findProperty('displayName', 'Hive Database');
@@ -474,14 +478,17 @@ App.ServiceConfigRadioButtons = Ember.View.extend({
     } else {
       propertyAppendTo2.set('additionalView', null);
     }
-  }.observes('serviceConfig.value', 'configs.@each.value'),
+    if (!['addServiceController', 'installerController'].contains(this.get('controller.wizardController.name'))) {
+      propertyAppendTo2.propertyDidChange('isVisible');
+    }
+  }.observes('serviceConfig.value'),
 
   optionsBinding: 'serviceConfig.options'
 });
 
 App.ServiceConfigRadioButton = Ember.Checkbox.extend({
   tagName: 'input',
-  attributeBindings: ['type', 'name', 'value', 'checked'],
+  attributeBindings: ['type', 'name', 'value', 'checked', 'disabled'],
   checked: false,
   type: 'radio',
   name: null,
@@ -525,7 +532,8 @@ App.ServiceConfigRadioButton = Ember.Checkbox.extend({
   }.observes('checked'),
 
   disabled: function () {
-    return !this.get('parentView.serviceConfig.isEditable');
+    return !this.get('parentView.serviceConfig.isEditable') ||
+      !['addServiceController', 'installerController'].contains(this.get('controller.wizardController.name')) && /^New\s\w+\sDatabase$/.test(this.get('value'));
   }.property('parentView.serviceConfig.isEditable')
 });
 

+ 405 - 0
ambari-web/test/views/wizard/controls_view_test.js

@@ -0,0 +1,405 @@
+/**
+ * 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('views/wizard/controls_view');
+
+describe('App.ServiceConfigRadioButtons', function () {
+
+  describe('#didInsertElement', function () {
+
+    var view = App.ServiceConfigRadioButtons.create({
+        categoryConfigsAll: [],
+        controller: Em.Object.create({
+          wizardController: Em.Object.create({})
+        }),
+        serviceConfig: Em.Object.create({
+          value: null
+        })
+      }),
+      cases = [
+        {
+          wizardControllerName: 'addServiceController',
+          serviceConfigValue: 'New MySQL Database',
+          onOptionsChangeCalledTwice: true,
+          handleDBConnectionPropertyCalledTwice: false,
+          title: 'Add Service Wizard, New MySQL Database'
+        },
+        {
+          wizardControllerName: 'addServiceController',
+          serviceConfigValue: 'Existing MySQL Database',
+          onOptionsChangeCalledTwice: false,
+          handleDBConnectionPropertyCalledTwice: true,
+          title: 'Add Service Wizard, Existing MySQL Database'
+        },
+        {
+          wizardControllerName: 'installerController',
+          serviceConfigValue: 'New MySQL Database',
+          onOptionsChangeCalledTwice: true,
+          handleDBConnectionPropertyCalledTwice: false,
+          title: 'Install Wizard, New MySQL Database'
+        },
+        {
+          wizardControllerName: 'installerController',
+          serviceConfigValue: 'Existing MySQL Database',
+          onOptionsChangeCalledTwice: false,
+          handleDBConnectionPropertyCalledTwice: true,
+          title: 'Install Wizard, Existing MySQL Database'
+        },
+        {
+          wizardControllerName: null,
+          serviceConfigValue: null,
+          onOptionsChangeCalledTwice: false,
+          handleDBConnectionPropertyCalledTwice: false,
+          title: 'Service Configs Page'
+        }
+      ];
+
+    beforeEach(function () {
+      sinon.stub(view, 'onOptionsChange', Em.K);
+      sinon.stub(view, 'handleDBConnectionProperty', Em.K);
+    });
+
+    afterEach(function () {
+      view.onOptionsChange.restore();
+      view.handleDBConnectionProperty.restore();
+    });
+
+    cases.forEach(function (item) {
+      it(item.title, function () {
+        view.set('controller.wizardController.name', item.wizardControllerName);
+        view.set('serviceConfig.value', item.serviceConfigValue);
+        view.didInsertElement();
+        expect(view.onOptionsChange.calledTwice).to.equal(item.onOptionsChangeCalledTwice);
+        expect(view.handleDBConnectionProperty.calledTwice).to.equal(item.handleDBConnectionPropertyCalledTwice);
+      });
+    });
+
+  });
+
+  describe('#databaseNameProperty', function () {
+
+    var view = App.ServiceConfigRadioButtons.create({
+        serviceConfig: Em.Object.create(),
+        categoryConfigsAll: [
+          {
+            name: 'ambari.hive.db.schema.name',
+            value: 'db0'
+          },
+          {
+            name: 'sink.db.schema.name',
+            value: 'db1'
+          },
+          {
+            name: 'oozie.db.schema.name',
+            value: 'db2'
+          }
+        ]
+      }),
+      cases = [
+        {
+          serviceName: 'HIVE',
+          value: 'db0'
+        },
+        {
+          serviceName: 'HDFS',
+          value: 'db1'
+        },
+        {
+          serviceName: 'OOZIE',
+          value: 'db2'
+        }
+      ];
+
+    cases.forEach(function (item) {
+      it(item.serviceName, function () {
+        view.set('serviceConfig.serviceName', item.serviceName);
+        expect(view.get('databaseNameProperty.value')).to.equal(item.value);
+        expect(view.get('databaseName')).to.equal(item.value);
+      });
+    });
+
+    it('default case', function () {
+      view.set('serviceConfig.serviceName', 'YARN');
+      expect(view.get('databaseNameProperty')).to.be.null;
+      expect(view.get('databaseName')).to.be.null;
+    });
+
+  });
+
+  describe('#hostNameProperty', function () {
+
+    var view = App.ServiceConfigRadioButtons.create({
+        serviceConfig: Em.Object.create(),
+        categoryConfigsAll: [
+          {
+            name: 'hive_ambari_host',
+            value: 'h0'
+          },
+          {
+            name: 'hive_existing_mysql_host',
+            value: 'h1'
+          },
+          {
+            name: 'hive_existing_postgresql_host',
+            value: 'h2'
+          },
+          {
+            name: 'hive_existing_oracle_host',
+            value: 'h3'
+          },
+          {
+            name: 'hive_existing_mssql_server_host',
+            value: 'h4'
+          },
+          {
+            name: 'hive_existing_mssql_server_2_host',
+            value: 'h5'
+          },
+          {
+            name: 'hive_hostname',
+            value: 'h6'
+          },
+          {
+            name: 'sink_existing_mssql_server_host',
+            value: 'h7'
+          },
+          {
+            name: 'sink_existing_mssql_server_2_host',
+            value: 'h8'
+          },
+          {
+            name: 'sink.dbservername',
+            value: 'h9'
+          },
+          {
+            name: 'oozie_ambari_host',
+            value: 'h10'
+          },
+          {
+            name: 'oozie_existing_mysql_host',
+            value: 'h11'
+          },
+          {
+            name: 'oozie_existing_postgresql_host',
+            value: 'h12'
+          },
+          {
+            name: 'oozie_existing_oracle_host',
+            value: 'h13'
+          },
+          {
+            name: 'oozie_existing_mssql_server_host',
+            value: 'h14'
+          },
+          {
+            name: 'oozie_existing_mssql_server_2_host',
+            value: 'h15'
+          },
+          {
+            name: 'oozie_hostname',
+            value: 'h16'
+          }
+        ]
+      }),
+      cases = [
+        {
+          serviceName: 'HIVE',
+          value: 'New MySQL Database',
+          expected: 'h0'
+        },
+        {
+          serviceName: 'HIVE',
+          value: 'Existing MySQL Database',
+          expected: 'h1'
+        },
+        {
+          serviceName: 'HIVE',
+          value: Em.I18n.t('services.service.config.hive.oozie.postgresql'),
+          expected: 'h2'
+        },
+        {
+          serviceName: 'HIVE',
+          value: 'Existing Oracle Database',
+          expected: 'h3'
+        },
+        {
+          serviceName: 'HIVE',
+          value: 'Existing MSSQL Server database with integrated authentication',
+          expected: 'h4'
+        },
+        {
+          serviceName: 'HIVE',
+          value: 'Existing MSSQL Server database with sql auth',
+          expected: 'h5'
+        },
+        {
+          serviceName: 'HIVE',
+          value: 'default case',
+          expected: 'h6'
+        },
+        {
+          serviceName: 'HDFS',
+          value: 'Existing MSSQL Server database with integrated authentication',
+          expected: 'h7'
+        },
+        {
+          serviceName: 'HDFS',
+          value: 'Existing MSSQL Server database with sql auth',
+          expected: 'h8'
+        },
+        {
+          serviceName: 'HDFS',
+          value: 'default case',
+          expected: 'h9'
+        },
+        {
+          serviceName: 'OOZIE',
+          value: 'New Derby Database',
+          expected: 'h10'
+        },
+        {
+          serviceName: 'OOZIE',
+          value: 'Existing MySQL Database',
+          expected: 'h11'
+        },
+        {
+          serviceName: 'OOZIE',
+          value: Em.I18n.t('services.service.config.hive.oozie.postgresql'),
+          expected: 'h12'
+        },
+        {
+          serviceName: 'OOZIE',
+          value: 'Existing Oracle Database',
+          expected: 'h13'
+        },
+        {
+          serviceName: 'OOZIE',
+          value: 'Existing MSSQL Server database with integrated authentication',
+          expected: 'h14'
+        },
+        {
+          serviceName: 'OOZIE',
+          value: 'Existing MSSQL Server database with sql auth',
+          expected: 'h15'
+        },
+        {
+          serviceName: 'OOZIE',
+          value: 'default case',
+          expected: 'h16'
+        }
+      ];
+
+    before(function () {
+      sinon.stub(view, 'handleDBConnectionProperty', Em.K);
+    });
+
+    after(function () {
+      view.handleDBConnectionProperty.restore();
+    });
+
+    cases.forEach(function (item) {
+      it(item.serviceName + ', ' + item.value, function () {
+        view.get('serviceConfig').setProperties({
+          serviceName: item.serviceName,
+          value: item.value
+        });
+        expect(view.get('hostNameProperty.value')).to.equal(item.expected);
+        expect(view.get('hostName')).to.equal(item.expected);
+      });
+    });
+
+  });
+
+});
+
+describe('App.ServiceConfigRadioButton', function () {
+
+  describe('#disabled', function () {
+
+    var cases = [
+      {
+        wizardControllerName: 'addServiceController',
+        value: 'New MySQL Database',
+        title: 'Add Service Wizard, new database',
+        disabled: false
+      },
+      {
+        wizardControllerName: 'installerController',
+        value: 'New MySQL Database',
+        title: 'Install Wizard, new database',
+        disabled: false
+      },
+      {
+        wizardControllerName: 'addServiceController',
+        value: 'Existing MySQL Database',
+        title: 'Add Service Wizard, existing database',
+        disabled: false
+      },
+      {
+        wizardControllerName: 'installerController',
+        value: 'Existing MySQL Database',
+        title: 'Install Wizard, existing database',
+        disabled: false
+      },
+      {
+        wizardControllerName: null,
+        value: 'New MySQL Database',
+        title: 'No installer, new database',
+        disabled: true
+      },
+      {
+        wizardControllerName: null,
+        value: 'Existing MySQL Database',
+        title: 'No installer, existing database',
+        disabled: false
+      }
+    ];
+
+    cases.forEach(function (item) {
+      it(item.title, function () {
+        var view = App.ServiceConfigRadioButton.create({
+          parentView: Em.Object.create({
+            serviceConfig: Em.Object.create()
+          }),
+          controller: Em.Object.create({
+            wizardController: Em.Object.create({
+              name: null
+            })
+          })
+        });
+        view.set('value', item.value);
+        view.set('controller.wizardController.name', item.wizardControllerName);
+        view.set('parentView.serviceConfig.isEditable', true);
+        expect(view.get('disabled')).to.equal(item.disabled);
+      });
+    });
+
+    it('parent view is disabled', function () {
+      var view = view = App.ServiceConfigRadioButton.create({
+        parentView: Em.Object.create({
+          serviceConfig: Em.Object.create()
+        })
+      });
+      view.set('parentView.serviceConfig.isEditable', false);
+      expect(view.get('disabled')).to.be.true;
+    });
+
+  });
+
+});