AMBARI-22510. Handle new error type from Stack Advisor (akovalenko)

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

Branch: refs/heads/branch-3.0-perf
Commit: c5fe6cb96a6530d0fc44c4ffced2ec46db97233b
Parents: 0249073
Author: Aleksandr Kovalenko <[email protected]>
Authored: Fri Nov 24 11:37:07 2017 +0200
Committer: Aleksandr Kovalenko <[email protected]>
Committed: Fri Nov 24 17:59:19 2017 +0200

----------------------------------------------------------------------
 ambari-web/app/messages.js                      |   5 +-
 ambari-web/app/mixins/common/serverValidator.js |  41 +++++---
 ambari-web/app/styles/application.less          |   3 +-
 .../config_recommendation_popup.hbs             | 102 +++++++++++++------
 .../config_validation_popup.js                  |   7 +-
 .../test/mixins/common/serverValidator_test.js  |  15 +--
 6 files changed, 112 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/c5fe6cb9/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 390f803..b294877 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -359,6 +359,7 @@ Em.I18n.translations = {
   'common.rolling.downgrade': 'Rolling Downgrade',
   'common.express.downgrade': 'Express Downgrade',
   'common.views': 'Views',
+  'common.critical.error': 'Critical',
 
   'models.alert_instance.tiggered.verbose': "Occurred on {0} <br> Checked on 
{1}",
   'models.alert_definition.triggered.verbose': "Occurred on {0}",
@@ -951,8 +952,8 @@ Em.I18n.translations = {
   'installer.step7.popup.validation.failed.body': 'Some services are not 
properly configured. You have to change the highlighted configs according to 
the recommended values.',
   'installer.step7.popup.validation.request.failed.body': 'The configuration 
changes could not be validated for consistency due to an unknown error.  Your 
changes have not been saved yet.  Would you like to proceed and save the 
changes?',
   'installer.step7.popup.validation.warning.header': 'Configurations',
-  'installer.step7.popup.validation.warning.body': 'Some service 
configurations are not configured properly. We recommend you review and change 
the highlighted configuration values. Are you sure you want to proceed without 
correcting configurations?',
-  'installer.step7.popup.validation.error.body': 'Service configurations 
resulted in validation errors. Please address them before proceeding.',
+  'installer.step7.popup.validation.issues.body': 'The following configuration 
changes are highly recommended, but can be skipped.',
+  'installer.step7.popup.validation.criticalIssues.body': 'You must correct 
the following critical issues before proceeding:',
   'installer.step7.popup.oozie.derby.warning': 'Derby is not recommended for 
production use. With Derby, Oozie Server HA and concurrent connection support 
will not be available.',
   'installer.step7.oozie.database.new': 'New Derby Database',
   'installer.step7.hive.database.new.mysql': 'New MySQL Database',

http://git-wip-us.apache.org/repos/asf/ambari/blob/c5fe6cb9/ambari-web/app/mixins/common/serverValidator.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/serverValidator.js 
b/ambari-web/app/mixins/common/serverValidator.js
index 319c281..65f43b7 100644
--- a/ambari-web/app/mixins/common/serverValidator.js
+++ b/ambari-web/app/mixins/common/serverValidator.js
@@ -57,7 +57,10 @@ App.ServerValidatorMixin = Em.Mixin.create({
    *
    * @type {Object[]}
    */
-  configErrorList: [],
+  configErrorList: Em.Object.create({
+    issues: [],
+    criticalIssues: []
+  }),
 
   /**
    * Map with allowed error types
@@ -65,6 +68,7 @@ App.ServerValidatorMixin = Em.Mixin.create({
    * @type {Object}
    */
   errorTypes: {
+    CRITICAL_ERROR: 'NOT_APPLICABLE',
     ERROR: 'ERROR',
     WARN: 'WARN',
     GENERAL: 'GENERAL'
@@ -113,10 +117,13 @@ App.ServerValidatorMixin = Em.Mixin.create({
       self = this,
       primary = function() { deferred.resolve(); },
       secondary = function() { deferred.reject('invalid_configs'); };
-    this.set('configErrorList', []);
+    this.set('configErrorList', Em.Object.create({
+      issues: [],
+      criticalIssues: []
+    }));
 
     this.runServerSideValidation().done(function() {
-      if (self.get('configErrorList.length')) {
+      if (self.get('configErrorList.issues.length') || 
self.get('configErrorList.criticalIssues.length')) {
         App.showConfigValidationPopup(self.get('configErrorList'), primary, 
secondary);
       } else {
         deferred.resolve();
@@ -228,13 +235,14 @@ App.ServerValidatorMixin = Em.Mixin.create({
     var errorTypes = this.get('errorTypes');
     var error = {
       type: type,
+      isCriticalError: type === errorTypes.CRITICAL_ERROR,
       isError: type === errorTypes.ERROR,
       isWarn: type === errorTypes.WARN,
       isGeneral: type === errorTypes.GENERAL,
       messages: Em.makeArray(messages)
     };
 
-    Em.assert('Unknown config error type ' + type, error.isError || 
error.isWarn || error.isGeneral);
+    Em.assert('Unknown config error type ' + type, error.isError || 
error.isWarn || error.isGeneral || error.isCriticalError);
     if (property) {
       error.id = Em.get(property, 'id');
       error.serviceName = Em.get(property, 'serviceDisplayName') || 
App.StackService.find(Em.get(property, 'serviceName')).get('displayName');
@@ -298,29 +306,33 @@ App.ServerValidatorMixin = Em.Mixin.create({
    */
   collectAllIssues: function(configErrorsMap, generalErrors)  {
     var errorTypes = this.get('errorTypes');
-    var configErrorList = [];
+    var configErrorList = {};
+    configErrorList[errorTypes.WARN] = [];
+    configErrorList[errorTypes.ERROR] = [];
+    configErrorList[errorTypes.CRITICAL_ERROR] = [];
+    configErrorList[errorTypes.GENERAL] = [];
 
     this.get('stepConfigs').forEach(function(service) {
       service.get('configs').forEach(function(property) {
         if (property.get('isVisible') && !property.get('hiddenBySection')) {
           var serverIssue = configErrorsMap[property.get('id')];
           if (serverIssue) {
-            configErrorList.push(this.createErrorMessage(serverIssue.type, 
property, serverIssue.messages));
+            
configErrorList[serverIssue.type].push(this.createErrorMessage(serverIssue.type,
 property, serverIssue.messages));
           } else if (property.get('warnMessage')) {
-            configErrorList.push(this.createErrorMessage(errorTypes.WARN, 
property, [property.get('warnMessage')]));
+            
configErrorList[errorTypes.WARN].push(this.createErrorMessage(errorTypes.WARN, 
property, [property.get('warnMessage')]));
           }
         }
       }, this);
     }, this);
 
     generalErrors.forEach(function(serverIssue) {
-      configErrorList.push(this.createErrorMessage(errorTypes.GENERAL, null, 
serverIssue.messages));
+      
configErrorList[errorTypes.GENERAL].push(this.createErrorMessage(errorTypes.GENERAL,
 null, serverIssue.messages));
     }, this);
 
     Em.keys(configErrorsMap).forEach(function (id) {
-      if (!configErrorList.someProperty('id', id)) {
-        var serverIssue = configErrorsMap[id],
-          filename = Em.get(serverIssue, 'filename'),
+      var serverIssue = configErrorsMap[id];
+      if (!configErrorList[serverIssue.type].someProperty('id', id)) {
+        var filename = Em.get(serverIssue, 'filename'),
           service = App.config.get('serviceByConfigTypeMap')[filename],
           property = {
             id: id,
@@ -328,11 +340,14 @@ App.ServerValidatorMixin = Em.Mixin.create({
             filename: App.config.getOriginalFileName(filename),
             serviceDisplayName: service && Em.get(service, 'displayName')
           };
-        configErrorList.push(this.createErrorMessage(serverIssue.type, 
property, serverIssue.messages));
+        
configErrorList[serverIssue.type].push(this.createErrorMessage(serverIssue.type,
 property, serverIssue.messages));
       }
     }, this);
 
-    return configErrorList;
+    return Em.Object.create({
+      criticalIssues: configErrorList[errorTypes.CRITICAL_ERROR],
+      issues: 
configErrorList[errorTypes.ERROR].concat(configErrorList[errorTypes.WARN], 
configErrorList[errorTypes.GENERAL])
+    });
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/c5fe6cb9/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less 
b/ambari-web/app/styles/application.less
index df86c7f..2a908b3 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -2308,7 +2308,7 @@ input[type="radio"].align-checkbox, 
input[type="checkbox"].align-checkbox {
 .table td.error { background-color: @error-background; }
 .table td.warning { background-color: @warning-background; }
 
-#config-validation-warnings {
+.config-validation-warnings {
   table {
     tbody{
       tr {
@@ -2332,7 +2332,6 @@ input[type="radio"].align-checkbox, 
input[type="checkbox"].align-checkbox {
   }
 }
 
-
 @config-dependency-t-name-width: 180px;
 @config-dependency-t-service-width: 100px;
 @config-dependency-t-group-width: 140px;

http://git-wip-us.apache.org/repos/asf/ambari/blob/c5fe6cb9/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs
----------------------------------------------------------------------
diff --git 
a/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs 
b/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs
index 1fe4d39..07125ac 100644
--- 
a/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs
+++ 
b/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs
@@ -16,34 +16,25 @@
 * limitations under the License.
 }}
 
-<p>{{view.messageBody}}</p>
-<div id="config-validation-warnings" class="limited-height-2">
-  <table class="table table-hover">
-    <thead>
-    <tr>
-      <th>{{t common.type}}</th>
-      <th>{{t common.service}}</th>
-      <th>{{t common.property}}</th>
-      <th>{{t common.value}}</th>
-      <th>{{t common.description}}</th>
-    </tr>
-    </thead>
-    <tbody>
-    {{#each error in view.configErrors}}
-      <tr {{bindAttr class="error.isError:error:warning"}}>
-        <td>
-          {{#if error.isError}}
-            {{t common.error}}
-          {{else}}
-            {{t common.warning}}
-          {{/if}}
-        </td>
-
-        {{#if error.isGeneral}}
-          {{#each message in error.messages}}
-            <td colspan="4">{{error.message}}</td>
-          {{/each}}
-        {{else}}
+{{#if view.configErrors.criticalIssues.length}}
+  <p>{{t installer.step7.popup.validation.criticalIssues.body}}</p>
+  <div class="limited-height-2 config-validation-warnings">
+    <table class="table table-hover">
+      <thead>
+      <tr>
+        <th>{{t common.type}}</th>
+        <th>{{t common.service}}</th>
+        <th>{{t common.property}}</th>
+        <th>{{t common.value}}</th>
+        <th>{{t common.description}}</th>
+      </tr>
+      </thead>
+      <tbody>
+      {{#each error in view.configErrors.criticalIssues}}
+        <tr class="error">
+          <td>
+            {{t common.critical}}
+          </td>
           <td>{{error.serviceName}}</td>
           <td>{{error.propertyName}}</td>
           <td>{{error.value}}</td>
@@ -53,9 +44,54 @@
             {{/each}}
             <div class="property-description">{{error.description}}</div>
           </td>
-        {{/if}}
+        </tr>
+      {{/each}}
+      </tbody>
+    </table>
+  </div>
+{{/if}}
+{{#if view.configErrors.issues.length}}
+  <p>{{t installer.step7.popup.validation.issues.body}}</p>
+  <div class="limited-height-2 config-validation-warnings">
+    <table class="table table-hover">
+      <thead>
+      <tr>
+        <th>{{t common.type}}</th>
+        <th>{{t common.service}}</th>
+        <th>{{t common.property}}</th>
+        <th>{{t common.value}}</th>
+        <th>{{t common.description}}</th>
       </tr>
-    {{/each}}
-    </tbody>
-  </table>
-</div>
+      </thead>
+      <tbody>
+      {{#each error in view.configErrors.issues}}
+        <tr {{bindAttr class="error.isError:error:warning"}}>
+          <td>
+            {{#if error.isError}}
+              {{t common.error}}
+            {{else}}
+              {{t common.warning}}
+            {{/if}}
+          </td>
+
+          {{#if error.isGeneral}}
+            {{#each message in error.messages}}
+              <td colspan="4">{{error.message}}</td>
+            {{/each}}
+          {{else}}
+            <td>{{error.serviceName}}</td>
+            <td>{{error.propertyName}}</td>
+            <td>{{error.value}}</td>
+            <td>
+              {{#each message in error.messages}}
+                <div class="property-message">{{message}}</div>
+              {{/each}}
+              <div class="property-description">{{error.description}}</div>
+            </td>
+          {{/if}}
+        </tr>
+      {{/each}}
+      </tbody>
+    </table>
+  </div>
+{{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c5fe6cb9/ambari-web/app/views/common/modal_popups/config_validation/config_validation_popup.js
----------------------------------------------------------------------
diff --git 
a/ambari-web/app/views/common/modal_popups/config_validation/config_validation_popup.js
 
b/ambari-web/app/views/common/modal_popups/config_validation/config_validation_popup.js
index 2fe7b62..07c891e 100644
--- 
a/ambari-web/app/views/common/modal_popups/config_validation/config_validation_popup.js
+++ 
b/ambari-web/app/views/common/modal_popups/config_validation/config_validation_popup.js
@@ -43,13 +43,10 @@ App.showConfigValidationPopup = function (configErrors, 
primary, secondary) {
       this._super();
       secondary();
     },
+    disablePrimary: !!configErrors.get('criticalIssues.length'),
     bodyClass: Em.View.extend({
       templateName: 
require('templates/common/modal_popups/config_recommendation_popup'),
-      configErrors: configErrors,
-      configValidationError: Em.computed.someBy('configErrors', 'isError', 
true),
-      messageBody: Em.I18n.t(this.get('configValidationError')
-        ? 'installer.step7.popup.validation.error.body'
-        : 'installer.step7.popup.validation.warning.body')
+      configErrors: configErrors
     })
   });
 };

http://git-wip-us.apache.org/repos/asf/ambari/blob/c5fe6cb9/ambari-web/test/mixins/common/serverValidator_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mixins/common/serverValidator_test.js 
b/ambari-web/test/mixins/common/serverValidator_test.js
index cdd69fb..4a12a69 100644
--- a/ambari-web/test/mixins/common/serverValidator_test.js
+++ b/ambari-web/test/mixins/common/serverValidator_test.js
@@ -94,35 +94,35 @@ describe('App.ServerValidatorMixin', function () {
     });
 
     it('should add server warnings', function () {
-      var error = result.find(function(r) { return r.propertyName === 'c1' && 
r.filename === 'f1'; });
+      var error = result.issues.find(function(r) { return r.propertyName === 
'c1' && r.filename === 'f1'; });
       expect(error.type).to.equal('WARN');
       expect(error.messages).to.eql(['warn1']);
     });
 
     it('should add server errors', function () {
-      var error = result.find(function(r) { return r.propertyName === 'c2' && 
r.filename === 'f2'; });
+      var error = result.issues.find(function(r) { return r.propertyName === 
'c2' && r.filename === 'f2'; });
       expect(error.type).to.equal('ERROR');
       expect(error.messages).to.eql(['error2']);
     });
 
     it('should add ui warning', function () {
-      var error = result.find(function(r) { return r.propertyName === 'c3' && 
r.filename === 'f3'; });
+      var error = result.issues.find(function(r) { return r.propertyName === 
'c3' && r.filename === 'f3'; });
       expect(error.type).to.equal('WARN');
       expect(error.messages).to.eql(['warn3']);
     });
 
     it('should add general issues', function () {
-      var error = result.findProperty('type', 'GENERAL');
+      var error = result.issues.findProperty('type', 'GENERAL');
       expect(error.messages).to.eql(['general issue']);
     });
 
     it('should ignore issues for hidden configs', function () {
-      var error = result.find(function(r) { return r.propertyName === 'c4' && 
r.filename === 'f4'; });
+      var error = result.issues.find(function(r) { return r.propertyName === 
'c4' && r.filename === 'f4'; });
       expect(error).to.be.undefined;
     });
 
     it('should add issues for deleted properties', function () {
-      var error = result.find(function(r) { return r.id === 'c5_f5'; });
+      var error = result.issues.find(function(r) { return r.id === 'c5_f5'; });
       expect(error.messages).to.eql(['error5']);
     });
   });
@@ -150,6 +150,7 @@ describe('App.ServerValidatorMixin', function () {
     it('creates warn object', function() {
       expect(instanceObject.createErrorMessage('WARN', property, 
['msg1'])).to.eql({
         type: 'WARN',
+        isCriticalError: false,
         isError: false,
         isWarn: true,
         isGeneral: false,
@@ -166,6 +167,7 @@ describe('App.ServerValidatorMixin', function () {
     it('creates error object', function() {
       expect(instanceObject.createErrorMessage('ERROR', $.extend({}, property, 
{serviceDisplayName: 'S Name'}), ['msg2'])).to.eql({
         type: 'ERROR',
+        isCriticalError: false,
         isError: true,
         isWarn: false,
         isGeneral: false,
@@ -182,6 +184,7 @@ describe('App.ServerValidatorMixin', function () {
     it('creates general issue object', function() {
       expect(instanceObject.createErrorMessage('GENERAL', null, 
['msg3'])).to.eql({
         type: 'GENERAL',
+        isCriticalError: false,
         isError: false,
         isWarn: false,
         isGeneral: true,

Reply via email to