浏览代码

AMBARI-8642. Issues with 'Test DB Connection' in HiveServer2 Move Master Wizard (Szilard Nemethy via ncole)

Nate Cole 10 年之前
父节点
当前提交
f74c490fa2

+ 0 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/files/addMysqlUser.sh

@@ -32,4 +32,3 @@ sudo su mysql -s /bin/bash - -c "mysql -u root -e \"GRANT ALL PRIVILEGES ON *.*
 sudo su mysql -s /bin/bash - -c "mysql -u root -e \"DELETE FROM mysql.user WHERE user='';\""
 sudo su mysql -s /bin/bash - -c "mysql -u root -e \"flush privileges;\""
 
-sudo service $mysqldservice stop

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

@@ -88,6 +88,7 @@ var files = ['test/init_model_test',
   'test/controllers/main/service/add_controller_test',
   'test/controllers/main/service/manage_config_groups_controller_test',
   'test/controllers/main/service/reassign_controller_test',
+  'test/controllers/main/service/reassign/step1_controller_test',
   'test/controllers/main/service/reassign/step2_controller_test',
   'test/controllers/main/service/reassign/step4_controller_test',
   'test/controllers/main/service/reassign/step6_controller_test',

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

@@ -1034,7 +1034,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
    */
   createConfigProperty: function (_serviceConfigProperty, defaultGroupSelected, serviceConfigsData) {
     if (!_serviceConfigProperty) return null;
-    
+
     var overrides = _serviceConfigProperty.overrides;
     // we will populate the override properties below
     Em.set(_serviceConfigProperty, 'overrides', null);

+ 46 - 7
ambari-web/app/controllers/main/service/reassign/step1_controller.js

@@ -40,14 +40,12 @@ App.ReassignMasterWizardStep1Controller = Em.Controller.extend({
   },
 
   loadConfigsTags: function () {
-    if(!this.get('databaseType')) {
       App.ajax.send({
         name: 'config.tags',
         sender: this,
         success: 'onLoadConfigsTags',
         error: ''
       });
-    }
   },
 
   /**
@@ -61,10 +59,12 @@ App.ReassignMasterWizardStep1Controller = Em.Controller.extend({
     switch (componentName) {
       case 'OOZIE_SERVER':
         urlParams.push('(type=oozie-site&tag=' + data.Clusters.desired_configs['oozie-site'].tag + ')');
+        urlParams.push('(type=oozie-env&tag=' + data.Clusters.desired_configs['oozie-env'].tag + ')');
         break;
       case 'HIVE_SERVER':
       case 'HIVE_METASTORE':
         urlParams.push('(type=hive-site&tag=' + data.Clusters.desired_configs['hive-site'].tag + ')');
+        urlParams.push('(type=hive-env&tag=' + data.Clusters.desired_configs['hive-env'].tag + ')');
         break;
     }
     return urlParams;
@@ -85,21 +85,60 @@ App.ReassignMasterWizardStep1Controller = Em.Controller.extend({
   },
 
   onLoadConfigs: function (data) {
-    var databaseProperty = data.items[0].properties[this.dbProperty()];
-    var databaseType = databaseProperty.match(/MySQL|PostgreS|Oracle|Derby|MSSQL/gi)[0];
+    var databaseProperty = null,
+        databaseType = null,
+        properties = {},
+        isRemoteDB = null;
+
+    data.items.forEach(function(item) {
+      $.extend(properties, item.properties);
+    });
+
+    this.set('content.serviceProperties', properties);
+
+    databaseProperty = properties[ this.dbProperty() ];
+    databaseType = databaseProperty.match(/MySQL|PostgreS|Oracle|Derby|MSSQL/gi)[0];
+    this.set('databaseType', databaseType);
 
     if (databaseType !== 'derby') {
       App.router.reassignMasterController.set('content.hasManualSteps', false);
     }
 
-    this.saveDatabaseType(databaseType)
+    var serviceDbProp = this.get('content.reassign.service_id').toLowerCase() + "_database";
+    properties['is_remote_db'] = /Existing/ig.test( properties[serviceDbProp] );
+
+    properties['database_hostname'] = this.getDatabaseHost();
+
+    this.saveDatabaseType(databaseType);
+    this.saveServiceProperties(properties);
   },
 
   saveDatabaseType: function(type) {
     if(type) {
-      this.set('databaseType', type);
       App.router.get(this.get('content.controllerName')).saveDatabaseType(type);
     }
+  },
+
+  saveServiceProperties: function(properties) {
+    if(properties) {
+      App.router.get(this.get('content.controllerName')).saveServiceProperties(properties);
+    }
+  },
+
+  getDatabaseHost: function() {
+    var db_type = this.get('databaseType');
+    var connectionURLPRops = {
+      'HIVE': 'javax.jdo.option.ConnectionURL',
+      'OOZIE': 'oozie.service.JPAService.jdbc.url'
+    };
+
+    var service = this.get('content.reassign.service_id');
+    var connectionURL = this.get('content.serviceProperties')[connectionURLPRops[service]];
+
+    connectionURL = connectionURL.replace("jdbc:" + db_type + "://", "");
+    connectionURL = connectionURL.replace("/hive?createDatabaseIfNotExist=true", "");
+    connectionURL = connectionURL.replace("/oozie", "");
+
+    return connectionURL;
   }
 });
-

+ 57 - 51
ambari-web/app/controllers/main/service/reassign/step4_controller.js

@@ -22,7 +22,8 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
 
   isReassign: true,
 
-  commands: ['stopServices', 'cleanMySqlServer', 'createHostComponents', 'putHostComponentsInMaintenanceMode', 'reconfigure', 'installHostComponents', 'startZooKeeperServers', 'startNameNode', 'deleteHostComponents', 'configureMySqlServer', 'startMySqlServer', 'startServices'],
+  commands: ['stopServices', 'cleanMySqlServer', 'createHostComponents', 'putHostComponentsInMaintenanceMode', 'reconfigure', 'installHostComponents', 'startZooKeeperServers', 'startNameNode', 'deleteHostComponents', 'configureMySqlServer',
+  'startMySqlServer', 'startNewMySqlServer' , 'startServices'],
   // custom commands for Components with DB Configuration and Check
   commandsForDB: ['createHostComponents', 'installHostComponents', 'configureMySqlServer', 'startMySqlServer', 'testDBConnection', 'stopServices', 'cleanMySqlServer', 'putHostComponentsInMaintenanceMode', 'reconfigure', 'deleteHostComponents', 'configureMySqlServer', 'startServices'],
 
@@ -32,8 +33,6 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
 
   hostComponents: [],
 
-  hiveSiteConfig: null,
-
   /**
    * Map with lists of unrelated services.
    * Used to define list of services to stop/start.
@@ -263,8 +262,10 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
   removeUnneededTasks: function () {
     if(this.isComponentWithDB()) {
       var db_type = this.get('content.databaseType');
+      var is_remote_db = this.get('content.serviceProperties.is_remote_db');
+
 
-      if (db_type !== 'mysql') {
+      if(is_remote_db || db_type !== 'mysql') {
         this.removeTasks(['configureMySqlServer', 'startMySqlServer', 'cleanMySqlServer', 'configureMySqlServer']);
       }
 
@@ -274,7 +275,11 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
     }
 
     if ( this.get('content.reassign.component_name') !== 'MYSQL_SERVER' && !this.isComponentWithDB()) {
-      this.removeTasks(['configureMySqlServer', 'startMySqlServer', 'cleanMySqlServer', 'configureMySqlServer']);
+      this.removeTasks(['configureMySqlServer', 'startMySqlServer', 'cleanMySqlServer', 'startNewMySqlServer', 'configureMySqlServer']);
+    }
+
+    if ( this.get('content.reassign.component_name') === 'MYSQL_SERVER' ) {
+      this.removeTasks(['cleanMySqlServer']);
     }
 
     if (this.get('content.hasManualSteps')) {
@@ -787,11 +792,17 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
    * make server call to clean MYSQL
    */
   cleanMySqlServer: function () {
+    var hostname = App.HostComponent.find().filterProperty('componentName', 'MYSQL_SERVER').get('firstObject.hostName');
+
+    if (this.get('content.reassign.component_name') === 'MYSQL_SERVER') {
+      hostname = this.get('content.reassignHosts.target');
+    }
+
     App.ajax.send({
       name: 'service.mysql.clean',
       sender: this,
       data: {
-        host: App.HostComponent.find().filterProperty('componentName', 'MYSQL_SERVER').get('firstObject.hostName')
+        host: hostname
       },
       success: 'startPolling',
       error: 'onTaskError'
@@ -802,11 +813,17 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
    * make server call to configure MYSQL
    */
   configureMySqlServer : function () {
+    var hostname = App.HostComponent.find().filterProperty('componentName', 'MYSQL_SERVER').get('firstObject.hostName');
+
+    if (this.get('content.reassign.component_name') === 'MYSQL_SERVER') {
+      hostname = this.get('content.reassignHosts.target');
+    }
+
     App.ajax.send({
       name: 'service.mysql.configure',
       sender: this,
       data: {
-        host: App.HostComponent.find().filterProperty('componentName', 'MYSQL_SERVER').get('firstObject.hostName')
+        host: hostname
       },
       success: 'startPolling',
       error: 'onTaskError'
@@ -831,36 +848,31 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
     });
   },
 
-  testDBConnection: function() {
-    this.loadServiceConfigsTags();
-    //this.onTaskCompleted();
-  },
-
-  isComponentWithDB: function() {
-    return ['HIVE_SERVER', 'HIVE_METASTORE', 'OOZIE_SERVER'].contains(this.get('content.reassign.component_name'));
-  },
-
-  loadServiceConfigsTags: function() {
+  startNewMySqlServer: function() {
     App.ajax.send({
-      name: 'config.tags',
+      name: 'common.host.host_component.update',
       sender: this,
-      success: 'onLoadServiceConfigsTags',
+      data: {
+        context: "Start MySQL Server",
+        hostName: this.get('content.reassignHosts.target'),
+        serviceName: "HIVE",
+        componentName: "MYSQL_SERVER",
+        HostRoles: {
+          state: "STARTED"
+        }
+      },
+      success: 'startPolling',
       error: 'onTaskError'
     });
   },
 
-  onLoadServiceConfigsTags: function(data) {
-    var urlParams = this.getConfigUrlParams(this.get('content.reassign.component_name'), data);
+  testDBConnection: function() {
+    this.prepareDBCheckAction();
+    // this.onTaskCompleted();
+  },
 
-    App.ajax.send({
-      name: 'reassign.load_configs',
-      sender: this,
-      data: {
-        urlParams: urlParams.join('|')
-      },
-      success: 'onLoadServiceConfigs',
-      error: 'onTaskError'
-    });
+  isComponentWithDB: function() {
+    return ['HIVE_SERVER', 'HIVE_METASTORE', 'OOZIE_SERVER'].contains(this.get('content.reassign.component_name'));
   },
 
   dbProperty: function() {
@@ -888,7 +900,7 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
       db_connection_url: /jdbc\.url|connectionurl/ig,
       driver_class: /ConnectionDriverName|jdbc\.driver/ig,
       schema_name: /db\.schema\.name/ig
-    }
+    };
   }.property(),
 
   /** @property {Object} connectionProperties - service specific config values mapped for custom action request **/
@@ -906,6 +918,7 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
     })[0];
     return this.get('content.serviceProperties')[propertyName];
   },
+
   /**
    * Properties that stores in local storage used for handling
    * last success connection.
@@ -924,10 +937,10 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
   /** @property {object} requiredProperties - properties that necessary for database connection **/
   requiredProperties: function() {
     var propertiesMap = {
-      HDFS: ['sink.db.schema.name','sink.dblogin','sink.dbpassword','sink.jdbc.driver','sink.jdbc.url'],
       OOZIE: ['oozie.db.schema.name','oozie.service.JPAService.jdbc.username','oozie.service.JPAService.jdbc.password','oozie.service.JPAService.jdbc.driver','oozie.service.JPAService.jdbc.url'],
       HIVE: ['ambari.hive.db.schema.name','javax.jdo.option.ConnectionUserName','javax.jdo.option.ConnectionPassword','javax.jdo.option.ConnectionDriverName','javax.jdo.option.ConnectionURL']
     };
+
     return propertiesMap[this.get('content.reassign.service_id')];
   }.property(),
 
@@ -938,15 +951,14 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
     return databaseProp.match(databaseTypes)[0];
   }.property('dbProperty'),
 
-  onLoadServiceConfigs: function(data) {
-    var properties = data.items.get('firstObject.properties');
-    this.saveServiceProperties(properties);
-
+  prepareDBCheckAction: function() {
+    var ambariProperties = null;
+    var properties = this.get('content.serviceProperties');
     var params = this.get('preparedDBProperties');
-    params['db_name'] = this.get('dbType');
 
-    var ambariProperties = App.router.get('clusterController.ambariProperties');
+    ambariProperties = App.router.get('clusterController.ambariProperties');
 
+    params['db_name'] = this.get('dbType');
     params['jdk_location'] = ambariProperties['jdk_location'];
     params['jdk_name'] = ambariProperties['jdk.name'];
     params['java_home'] = ambariProperties['java.home'];
@@ -964,7 +976,7 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
           "action": "check_host",
           "parameters": params
         },
-        filteredHosts: [App.HostComponent.find().filterProperty('componentName', 'MYSQL_SERVER').get('firstObject.hostName')]
+        filteredHosts: [this.get('content.reassignHosts.target')]
       },
       success: 'onCreateActionSuccess',
       error: 'onTaskError'
@@ -989,10 +1001,10 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
   },
 
   startDBCheckPolling: function() {
-      this.getTaskInfo();
+      this.getDBConnTaskInfo();
   },
 
-  getTaskInfo: function() {
+  getDBConnTaskInfo: function() {
     this.setTaskStatus(this.get('currentTaskId'), 'IN_PROGRESS');
     this.get('tasks').findProperty('id', this.get('currentTaskId')).set('progress', 100);
 
@@ -1004,11 +1016,11 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
         requestId: this.get('checkDBRequestId'),
         taskId: this.get('checkDBTaskId')
       },
-      success: 'getTaskInfoSuccess'
+      success: 'getDBConnTaskInfoSuccess'
     });
   },
 
-  getTaskInfoSuccess: function(data) {
+  getDBConnTaskInfoSuccess: function(data) {
     var task = data.Tasks;
     if (task.status === 'COMPLETED') {
       var structuredOut = task.structured_out.db_connection_check;
@@ -1037,7 +1049,7 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
   },
 
   testDBRetryTooltip: function() {
-    var db_host = App.HostComponent.find().filterProperty('componentName', 'MYSQL_SERVER').get('firstObject.hostName');
+    var db_host = this.get('content.serviceProperties.database_hostname');
     var db_type = this.get('dbType');
     var db_props = this.get('preparedDBProperties');
 
@@ -1045,12 +1057,6 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
       db_host, db_type, db_props['schema_name'], db_props['user_name'],
       db_props['user_passwd'], db_props['driver_class'], db_props['db_connection_url']
     );
-  }.property('dbProperties'),
+  }.property('dbProperties')
 
-  saveServiceProperties: function(properties) {
-    if(properties) {
-      this.set('content.serviceProperties', properties);
-      App.router.get(this.get('content.controllerName')).saveServiceProperties(properties);
-    }
-  }
 });

+ 71 - 2
ambari-web/app/controllers/main/service/reassign/step6_controller.js

@@ -22,7 +22,7 @@ App.ReassignMasterWizardStep6Controller = App.HighAvailabilityProgressPageContro
 
   isReassign: true,
 
-  commands: ['deleteHostComponents', 'startServices'],
+  commands: ['putHostComponentsInMaintenanceMode', 'stopMysqlService', 'deleteHostComponents', 'startServices'],
 
   clusterDeployState: 'REASSIGN_MASTER_INSTALLING',
 
@@ -48,7 +48,7 @@ App.ReassignMasterWizardStep6Controller = App.HighAvailabilityProgressPageContro
     }, this);
     var currentStep = App.router.get('reassignMasterController.currentStep');
     for (var i = 0; i < commands.length; i++) {
-      var title = Em.I18n.t('services.reassign.step6.task' + i + '.title').format(hostComponentsNames);
+      var title =  Em.I18n.t('services.reassign.step6.tasks.' + commands[i] + '.title').format(hostComponentsNames);
       this.get('tasks').pushObject(Ember.Object.create({
         title: title,
         status: 'PENDING',
@@ -63,6 +63,35 @@ App.ReassignMasterWizardStep6Controller = App.HighAvailabilityProgressPageContro
         hosts: []
       }));
     }
+
+    this.removeUnneededTasks();
+  },
+
+  removeUnneededTasks: function () {
+    if ( this.get('content.reassign.component_name') !== 'MYSQL_SERVER' ) {
+      this.removeTasks(['putHostComponentsInMaintenanceMode', 'stopServices']);
+    }
+  },
+
+  /**
+   * remove tasks by command name
+   */
+  removeTasks: function(commands) {
+    var tasks = this.get('tasks'),
+        index = null
+        cmd = null;
+
+    commands.forEach(function(command) {
+      cmd = tasks.filterProperty('command', command);
+
+      if (cmd.length === 0) {
+        return false;
+      } else {
+        index = tasks.indexOf( cmd[0] );
+      }
+
+      tasks.splice( index, 1 );
+    });
   },
 
   hideRollbackButton: function () {
@@ -119,5 +148,45 @@ App.ReassignMasterWizardStep6Controller = App.HighAvailabilityProgressPageContro
     } else {
       this.onTaskError();
     }
+  },
+
+  putHostComponentsInMaintenanceMode: function () {
+    this.set('multiTaskCounter', 0);
+    var hostComponents = this.get('hostComponents');
+    var hostName = this.get('content.reassignHosts.source');
+    for (var i = 0; i < hostComponents.length; i++) {
+      App.ajax.send({
+        name: 'common.host.host_component.passive',
+        sender: this,
+        data: {
+          hostName: hostName,
+          passive_state: "ON",
+          componentName: hostComponents[i]
+        },
+        success: 'onComponentsTasksSuccess',
+        error: 'onTaskError'
+      });
+    }
+  },
+
+  /**
+   * make server call to stop services
+   */
+  stopMysqlService: function () {
+    var data = {
+      "ServiceInfo": {
+        "state": "INSTALLED"
+      }
+    };
+    data.context = "Stop required services";
+    data.urlParams = "ServiceInfo/service_name.in(MYSQL_SERVER)";
+
+    App.ajax.send({
+      name: 'common.services.update',
+      sender: this,
+      data: data,
+      success: 'startPolling',
+      error: 'onTaskError'
+    });
   }
 });

+ 6 - 1
ambari-web/app/controllers/main/service/reassign_controller.js

@@ -287,6 +287,11 @@ App.ReassignMasterController = App.WizardController.extend({
   loadDatabaseType: function () {
     var databaseType = this.getDBProperty('databaseType');
     this.set('content.databaseType', databaseType);
+
+    if (this.get('content.hasCheckDBStep') && databaseType !== 'derby') {
+      App.router.reassignMasterController.set('content.hasManualSteps', false);
+      App.router.reassignMasterController.get('content.componentsWithManualCommands').splice(2,1);
+    }
   },
 
   /**
@@ -301,7 +306,6 @@ App.ReassignMasterController = App.WizardController.extend({
         this.loadSecureConfigs();
         this.loadComponentDir();
       case '4':
-        this.loadServiceProperties();
         this.loadTasksStatuses();
         this.loadTasksRequestIds();
         this.loadRequestIds();
@@ -314,6 +318,7 @@ App.ReassignMasterController = App.WizardController.extend({
       case '1':
         this.loadComponentToReassign();
         this.loadDatabaseType();
+        this.loadServiceProperties();
         this.load('cluster');
     }
   },

+ 9 - 3
ambari-web/app/messages.js

@@ -1724,6 +1724,7 @@ Em.I18n.translations = {
   'services.reassign.step4.task6.title':'Start NameNode',
   'services.reassign.step4.task7.title':'Delete disabled {0}',
   'services.reassign.step4.task8.title':'Start Required Services',
+  'services.reassign.step4.tasks.startNewMySqlServer.title':'Start New MYSQL Server',
   'services.reassign.step4.status.success': 'Successfully moved <b>{0}</b> from <b>{1}</b> host to <b>{2}</b> host',
   'services.reassign.step4.status.success.withManualSteps': 'Proceed to the next step',
   'services.reassign.step4.status.failed': 'Failed to move <b>{0}</b> from <b>{1}</b> host to <b>{2}</b> host',
@@ -1775,7 +1776,10 @@ Em.I18n.translations = {
     '<ol>' +
     '<li>On <b>{1}</b> using a terminal you can export your Metastore DB (MYSQL) using:' +
     '<div class="code-snippet">mysqldump db_name > backup-file.sql</div></li>' +
-    '<li>Copy the file to the target host <b>{2}</b> hosting the MySQL DB and import' +
+    '<li>Copy the file to the target host <b>{2}</b> hosting the MySQL DB<li>' +
+    '<li>Execute this SQL inside <b>mysql<b>' +
+    '<div class="code-snippet">CREATE DATABASE db_name;</div></li>' +
+    '<li>Import the database using' +
     '<div class="code-snippet">mysql db_name < backup-file.sql</div></li>' +
     '</ol>' +
     '</div>',
@@ -1786,8 +1790,10 @@ Em.I18n.translations = {
   'services.reassign.step5.body.proceedMsg': 'Please proceed once you have completed the steps above',
   'services.reassign.step5.confirmPopup.body': 'Please confirm that you have run the manual steps before continuing.',
   'services.reassign.step6.header': 'Start and Test services',
-  'services.reassign.step6.task0.title': 'Delete disabled {0}',
-  'services.reassign.step6.task1.title': 'Start All Services',
+  'services.reassign.step6.tasks.putHostComponentsInMaintenanceMode.title':'Disable {0}',
+  'services.reassign.step6.tasks.deleteHostComponents.title': 'Delete disabled {0}',
+  'services.reassign.step6.tasks.startServices.title': 'Start All Services',
+  'services.reassign.step6.tasks.stopMysqlService.title': 'Stop Mysql Server',
   'services.reassign.step6.status.success': 'Successfully moved <b>{0}</b> from <b>{1}</b> host to <b>{2}</b> host.',
   'services.reassign.step6.status.failed': 'Failed to move <b>{0}</b> from <b>{1}</b> host to <b>{2}</b> host.',
   'services.reassign.step6.status.info': 'Reassigning {0}. \nPlease wait for all tasks to be completed.',

+ 2 - 0
ambari-web/app/routes/reassign_master_routes.js

@@ -363,6 +363,8 @@ module.exports = App.WizardRoute.extend({
     }
   }),
 
+  gotoStep7: Em.Router.transitionTo('step7'),
+
   backToServices: function (router) {
     App.router.get('updateController').set('isWorking', true);
     router.transitionTo('services');

+ 64 - 0
ambari-web/app/templates/main/admin/highAvailability/progress.hbs

@@ -0,0 +1,64 @@
+{{!
+* 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.
+}}
+<div id="ha-progress-page">
+  <h2>{{view.headerTitle}}</h2>
+
+  <div {{bindAttr class="view.noticeClass"}}>{{{view.notice}}}</div>
+  {{#each task in controller.tasks}}
+  {{#view view.taskView contentBinding="task"}}
+    <div class="item">
+      <div {{bindAttr class=":pull-left view.linkClass controller.isHA:span4 controller.isRMHA:span5 controller.isRollback:span3 controller.isReassign:span5"}}>
+        <i {{bindAttr class="view.icon view.iconColor"}}></i>
+        <a {{action "showHostProgressPopup" task target="controller"}} >{{task.title}}</a>
+      </div>
+      <div {{bindAttr class="view.showProgressBar::hide :row :span5 :pull-left" }}>
+        <div {{bindAttr class=":progress-bar controller.isRollback::span8 controller.isRollback:span3"}}>
+          <div class="progress-striped active progress-info progress">
+            <div class="bar" {{bindAttr style="view.barWidth"}}></div>
+          </div>
+        </div>
+        <div {{bindAttr class=":span1 view.hidePercent:noDisplay"}}>{{task.progress}}&#37;</div>
+      </div>
+      <div>
+      {{#if task.showRetry}}
+        <a {{action retryTask target="controller"}} class="btn btn-primary retry"
+           rel="tooltip" data-trigger="click" {{bindAttr title="view.showDBTooltip:testDBRetryTooltip"}}>
+          <i class="icon-repeat icon-white"></i>
+          {{t common.retry}}
+        </a>
+      {{/if}}
+      {{#if task.showRollback}}
+        <a {{action rollback target="controller"}} class="btn btn-primary retry">
+          <i class="icon-repeat icon-white"></i>
+          {{t common.rollBack}}
+        </a>
+      {{/if}}
+      {{#if task.showSkip}}
+        <a {{action skipTask target="controller"}} class="btn btn-primary retry">
+          <i class="icon-step-forward icon-white"></i>
+          {{t common.skip}}
+        </a>
+      {{/if}}
+      </div>
+    </div>
+  {{/view}}
+  {{/each}}
+  <div class="btn-area">
+    <button class="btn btn-success pull-right" {{bindAttr disabled="controller.isSubmitDisabled"}} {{action done target="controller"}}>{{view.submitButtonText}}</button>
+  </div>
+</div>

+ 0 - 5
ambari-web/app/templates/main/service/reassign/step1.hbs

@@ -22,11 +22,6 @@
     {{{message}}}
   {{/each}}
 </div>
-{{#if view.jdbcSetupMessage}}
-  <div class="alert alert-warning">
-    {{{view.jdbcSetupMessage}}}
-  </div>
-{{/if}}
 <div class="btn-area">
   <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action next}}>{{t common.next}} &rarr;</a>
 </div>

+ 5 - 1
ambari-web/app/templates/main/service/reassign/step3.hbs

@@ -21,7 +21,11 @@
 <div class="alert alert-info">
   {{t services.reassign.step3.body}}
 </div>
-
+{{#if view.jdbcSetupMessage}}
+  <div class="alert alert-warning">
+    {{{view.jdbcSetupMessage}}}
+  </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/>

+ 0 - 12
ambari-web/app/views/main/service/reassign/step1_view.js

@@ -32,18 +32,6 @@ App.ReassignMasterWizardStep1View = Em.View.extend({
     return messages;
   }.property('controller.content.reassign.display_name','controller.content.hasManualSteps'),
 
-  jdbcSetupMessage: function() {
-    if(['HIVE_SERVER', 'HIVE_METASTORE', 'OOZIE_SERVER'].contains(this.get('controller.content.reassign.component_name'))) {
-      if(this.get('controller.content.reassign.component_name') === 'OOZIE_SERVER' && this.get('controller.databaseType') === 'derby') {
-        return false;
-      }
-
-      return Em.I18n.t('services.service.config.database.msg.jdbcSetup').format(this.get('controller.databaseType'), this.get('controller.databaseType'));
-    }
-
-    return false;
-  }.property('controller.content.reassign.display_name, controller.databaseType'),
-
   templateName: require('templates/main/service/reassign/step1')
 
 });

+ 13 - 1
ambari-web/app/views/main/service/reassign/step3_view.js

@@ -33,5 +33,17 @@ App.ReassignMasterWizardStep3View = Em.View.extend({
 
   printReview: function () {
     $("#step8-info").jqprint();
-  }
+  },
+
+  jdbcSetupMessage: function() {
+    if(['HIVE_SERVER', 'HIVE_METASTORE', 'OOZIE_SERVER'].contains(this.get('controller.content.reassign.component_name'))) {
+      if(this.get('controller.content.reassign.component_name') === 'OOZIE_SERVER' && this.get('controller.content.databaseType') === 'derby') {
+        return false;
+      }
+
+      return Em.I18n.t('services.service.config.database.msg.jdbcSetup').format(this.get('controller.content.databaseType'), this.get('controller.content.databaseType'));
+    }
+
+    return false;
+  }.property('controller.content.reassign.display_name, controller.content.databaseType')
 });

+ 106 - 0
ambari-web/test/controllers/main/service/reassign/step1_controller_test.js

@@ -0,0 +1,106 @@
+/**
+ * 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/service/reassign/step1_controller');
+require('models/host_component');
+
+describe('App.ReassignMasterWizardStep1Controller', function () {
+
+
+  var controller = App.ReassignMasterWizardStep1Controller.create({
+    content: Em.Object.create({
+      reassign: Em.Object.create({}),
+      services: []
+    })
+  });
+  controller.set('_super', Em.K);
+
+  describe('#loadConfigTags', function() {
+    beforeEach(function() {
+      sinon.stub(App.ajax, 'send', Em.K);
+    });
+
+    afterEach(function() {
+      App.ajax.send.restore();
+    });
+
+    it('tests loadConfigTags', function() {
+      controller.loadConfigsTags();
+
+      expect(App.ajax.send.calledOnce).to.be.true;
+    });
+
+    it('tests saveDatabaseType with type', function() {
+      sinon.stub(App.router, 'get', function() {
+        return { saveDatabaseType: Em.K};
+      });
+
+      controller.saveDatabaseType(true);
+      expect(App.router.get.calledOnce).to.be.true;
+
+      App.router.get.restore();
+    });
+
+    it('tests saveDatabaseType without type', function() {
+      sinon.stub(App.router, 'get', function() {
+        return { saveDatabaseType: Em.K};
+      });
+
+      controller.saveDatabaseType(false);
+      expect(App.router.get.called).to.be.false;
+
+      App.router.get.restore();
+    });
+
+    it('tests saveServiceProperties with propertie', function() {
+      sinon.stub(App.router, 'get', function() {
+        return { saveServiceProperties: Em.K};
+      });
+
+      controller.saveServiceProperties(true);
+      expect(App.router.get.calledOnce).to.be.true;
+
+      App.router.get.restore();
+    });
+
+    it('tests saveServiceProperties without properties', function() {
+      sinon.stub(App.router, 'get', function() {
+        return { saveServiceProperties: Em.K};
+      });
+
+      controller.saveServiceProperties(false);
+      expect(App.router.get.called).to.be.false;
+
+      App.router.get.restore();
+    });
+
+    it('tests getDatabaseHost', function() {
+      controller.set('content.serviceProperties', {
+        'javax.jdo.option.ConnectionURL': "jdbc:mysql://c6401/hive?createDatabaseIfNotExist=true"
+      });
+
+      controller.set('content.reassign.service_id', 'HIVE');
+      controller.set('databaseType', 'mysql');
+
+      expect(controller.getDatabaseHost()).to.equal('c6401')
+    });
+
+  });
+});

+ 52 - 2
ambari-web/test/controllers/main/service/reassign/step4_controller_test.js

@@ -151,6 +151,37 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
     });
   });
 
+  describe('#testDBConnection', function() {
+    beforeEach(function() {
+      controller.set('requiredProperties', Em.A([]));
+      controller.set('content.serviceProperties', Em.Object.create({'javax.jdo.option.ConnectionDriverName': 'mysql'}));
+      controller.set('content.reassign.component_name', 'HIVE_SERVER');
+      sinon.stub(controller, 'getConnectionProperty', Em.K);
+      sinon.stub(App.router, 'get', Em.K);
+    });
+
+    afterEach(function() {
+      controller.getConnectionProperty.restore();
+      App.router.get.restore();
+    });
+
+    it('tests database connection', function() {
+      sinon.stub(controller, 'prepareDBCheckAction', Em.K);
+
+      controller.testDBConnection();
+      expect(controller.prepareDBCheckAction.calledOnce).to.be.true;
+
+      controller.prepareDBCheckAction.restore();
+    });
+
+    it('tests prepareDBCheckAction', function() {
+      controller.prepareDBCheckAction();
+
+      expect(App.ajax.send.calledOnce).to.be.true;
+    });
+
+  });
+
   describe('#removeUnneededTasks()', function () {
     var isHaEnabled = false;
 
@@ -231,7 +262,6 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
       isHaEnabled = false;
 
       controller.removeUnneededTasks();
-      console.log(controller.get('tasks').mapProperty('id'))
       expect(controller.get('tasks').mapProperty('id')).to.eql([1, 2, 3, 4, 5, 6, 9, 10, 11, 12]);
     });
 
@@ -242,9 +272,29 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
       isHaEnabled = false;
 
       controller.removeUnneededTasks();
-      console.log(controller.get('tasks').mapProperty('id'))
       expect(controller.get('tasks').mapProperty('id')).to.eql([1, 3, 4, 5, 6, 9, 12]);
     });
+
+    it('reassign component is Oozie Server and db type is derby', function () {
+      controller.set('content.hasManualSteps', true);
+      controller.set('content.databaseType', 'derby');
+      controller.set('content.reassign.component_name', 'OOZIE_SERVER');
+      isHaEnabled = false;
+
+      controller.removeUnneededTasks();
+      expect(controller.get('tasks').mapProperty('id')).to.eql([1,3,4,5,6]);
+    });
+
+    it('reassign component is Oozie Server and db type is mysql', function () {
+      controller.set('content.hasManualSteps', false);
+      controller.set('content.databaseType', 'mysql');
+      controller.set('content.reassign.component_name', 'OOZIE_SERVER');
+      isHaEnabled = false;
+
+
+      controller.removeUnneededTasks();
+      expect(controller.get('tasks').mapProperty('id')).to.eql([1,2,3,4,5,6,9,10,11,12]);
+    });
   });
 
   describe('#initializeTasks()', function () {