Browse Source

AMBARI-5072. Mirroring: stabilize datasets initial loading. (akovalenko)

Aleksandr Kovalenko 11 years ago
parent
commit
9e870b2cc8

+ 26 - 13
ambari-web/app/assets/data/services/HDP2/services.json

@@ -6,7 +6,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "GANGLIA"
+        "service_name" : "GANGLIA",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -21,7 +22,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "HBASE"
+        "service_name" : "HBASE",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -36,7 +38,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "HCATALOG"
+        "service_name" : "HCATALOG",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -51,7 +54,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "HDFS"
+        "service_name" : "HDFS",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -66,7 +70,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "MAPREDUCE2"
+        "service_name" : "MAPREDUCE2",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -81,7 +86,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "NAGIOS"
+        "service_name" : "NAGIOS",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -96,7 +102,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "OOZIE"
+        "service_name" : "OOZIE",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -111,7 +118,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "SQOOP"
+        "service_name" : "SQOOP",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -126,7 +134,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "PIG"
+        "service_name" : "PIG",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -141,7 +150,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "YARN"
+        "service_name" : "YARN",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -156,7 +166,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "ZOOKEEPER"
+        "service_name" : "ZOOKEEPER",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -171,7 +182,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "OFF",
         "cluster_name" : "cl",
-        "service_name" : "FALCON"
+        "service_name" : "FALCON",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {
@@ -186,7 +198,8 @@
       "ServiceInfo" : {
         "maintenance_state" : "ON",
         "cluster_name" : "cl",
-        "service_name" : "STORM"
+        "service_name" : "STORM",
+        "state": "STARTED"
       },
       "alerts" : {
         "summary" : {

+ 37 - 10
ambari-web/app/controllers/main/mirroring_controller.js

@@ -39,6 +39,14 @@ App.MainMirroringController = Em.ArrayController.extend({
 
   isTargetClustersLoaded: false,
 
+  isRequiredServicesStarted: false,
+
+  isDatasetLoadingError: false,
+
+  actionsDisabled: function () {
+    return !this.get('isRequiredServicesStarted') || this.get('isDatasetLoadingError');
+  }.property('isRequiredServicesStarted', 'isDatasetLoadingError'),
+
   isLoaded: function () {
     return this.get('isDatasetsLoaded') && this.get('isTargetClustersLoaded');
   }.property('isDatasetsLoaded', 'isTargetClustersLoaded'),
@@ -46,12 +54,19 @@ App.MainMirroringController = Em.ArrayController.extend({
   datasets: App.Dataset.find(),
 
   loadData: function () {
-    this.get('datasetsData').clear();
-    this.set('clustersData', {});
-    this.set('datasetCount', 0);
-    this.set('clusterCount', 0);
-    this.loadDatasets();
-    this.loadClusters();
+    var isRequiredServicesStarted = App.Service.find().findProperty('serviceName', 'OOZIE').get('workStatus') == 'STARTED' && App.Service.find().findProperty('serviceName', 'FALCON').get('workStatus') == 'STARTED';
+    this.set('isRequiredServicesStarted', isRequiredServicesStarted);
+    if (isRequiredServicesStarted) {
+      this.set('isDatasetLoadingError', false);
+      this.get('datasetsData').clear();
+      this.set('clustersData', {});
+      this.set('datasetCount', 0);
+      this.set('clusterCount', 0);
+      this.loadDatasets();
+      this.loadClusters();
+    } else {
+      this.set('isDatasetLoadingError', true);
+    }
   },
 
   loadDatasets: function () {
@@ -93,6 +108,7 @@ App.MainMirroringController = Em.ArrayController.extend({
   },
 
   onLoadDatasetsListError: function () {
+    this.set('isDatasetLoadingError', true);
     console.error('Failed to load datasets list.');
   },
 
@@ -138,12 +154,13 @@ App.MainMirroringController = Em.ArrayController.extend({
   },
 
   onLoadDatasetDefinitionError: function () {
+    this.set('isDatasetLoadingError', true);
     console.error('Failed to load dataset definition.');
   },
 
   onLoadDatasetInstancesSuccess: function (data, sender, opts) {
     var datasetsData = this.get('datasetsData');
-    if (data.instances) {
+    if (data && data.instances) {
       var datasetJobs = [];
       data.instances.forEach(function (instance) {
         datasetJobs.push({
@@ -156,12 +173,17 @@ App.MainMirroringController = Em.ArrayController.extend({
         });
       }, this);
       datasetsData.findProperty('name', opts.dataset).set('instances', datasetJobs);
+    } else {
+      datasetsData.findProperty('name', opts.dataset).set('instances', []);
     }
+    this.saveDataset();
+  },
+
+  saveDataset: function () {
     this.set('datasetCount', this.get('datasetCount') - 1);
     if (this.get('datasetCount') < 1) {
-      var sortedDatasets = [];
-      App.dataSetMapper.map(datasetsData);
-      sortedDatasets = App.Dataset.find().toArray().sortProperty('name');
+      App.dataSetMapper.map(this.get('datasetsData'));
+      var sortedDatasets = App.Dataset.find().toArray().sortProperty('name');
       this.set('isDatasetsLoaded', true);
       var selectedDataset = this.get('selectedDataset');
       if (!selectedDataset) {
@@ -172,6 +194,9 @@ App.MainMirroringController = Em.ArrayController.extend({
 
   onLoadDatasetsInstancesError: function () {
     console.error('Failed to load dataset instances.');
+    var datasetName = arguments[4].dataset;
+    this.get('datasetsData').findProperty('name', datasetName).set('instances', []);
+    this.saveDataset();
   },
 
   loadClusters: function () {
@@ -268,6 +293,7 @@ App.MainMirroringController = Em.ArrayController.extend({
   },
 
   onLoadClustersListError: function () {
+    this.set('isDatasetLoadingError', true);
     console.error('Failed to load clusters list.');
   },
 
@@ -308,6 +334,7 @@ App.MainMirroringController = Em.ArrayController.extend({
   },
 
   onLoadClusterDefinitionError: function () {
+    this.set('isDatasetLoadingError', true);
     console.error('Failed to load cluster definition.');
   },
 

+ 10 - 0
ambari-web/app/mappers/status_mapper.js

@@ -27,6 +27,7 @@ App.statusMapper = App.QuickDataMapper.create({
       var previousComponentStatuses = App.cache['previousComponentStatuses'];
       var previousComponentPassiveStates = App.cache['previousComponentPassiveStates'];
       var hostComponentRecordsMap = App.cache['hostComponentRecordsMap'];
+      var servicesCache = App.cache['services'];
       var hostStatuses = {};
       var addedHostComponents = [];
       var updatedHostComponents = [];
@@ -132,6 +133,15 @@ App.statusMapper = App.QuickDataMapper.create({
         });
       }
 
+      // update services workStatus and passiveState
+      App.Service.find().forEach(function (service) {
+        var cachedServiceData = servicesCache.findProperty('ServiceInfo.service_name', service.get('serviceName'));
+        if (cachedServiceData) {
+          service.set('workStatus', cachedServiceData.ServiceInfo.state);
+          service.set('passiveState', cachedServiceData.ServiceInfo.passive_state);
+        }
+      }, this);
+
       App.cache['previousHostStatuses'] = currentHostStatuses;
       App.cache['previousComponentStatuses'] = currentComponentStatuses;
       App.cache['previousComponentPassiveStates'] = currentComponentPassiveStates;

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

@@ -1863,6 +1863,9 @@ Em.I18n.translations = {
   'mirroring.dataset.middayPeriod.am':'AM',
   'mirroring.dataset.middayPeriod.pm':'PM',
   'mirroring.dataset.entity':'entity',
+  'mirroring.dataset.services.not.started':'Both Falcon and Oozie should be started for correct work',
+  'mirroring.dataset.dataset.loading.error':'Unable to load datasets',
+  'mirroring.dataset.dataset.loading.instances':'Unable to load instances',
 
   'mirroring.manageClusters.ambariServer':'Ambari Server',
   'mirroring.manageClusters.interfaces':'Interfaces',

+ 33 - 22
ambari-web/app/templates/main/mirroring/datasets.hbs

@@ -16,6 +16,9 @@
 * limitations under the License.
 }}
 <div id="mirroring">
+  {{#unless controller.isRequiredServicesStarted}}
+    <div class="alert alert-error">{{t mirroring.dataset.services.not.started}}</div>
+  {{/unless}}
   <div class="row-fluid">
     <div class="span4">
       <div>
@@ -24,8 +27,8 @@
         </div>
         {{#if App.isAdmin}}
           <div class="mirroring-top-nav pull-right btn-group">
-            <button class="btn">{{t common.actions}}</button>
-            <button class="btn dropdown-toggle" data-toggle="dropdown">
+            <button {{bindAttr disabled="controller.actionsDisabled"}} class="btn">{{t common.actions}}</button>
+            <button {{bindAttr disabled="controller.actionsDisabled"}} class="btn dropdown-toggle" data-toggle="dropdown">
               <span class="caret"></span>
             </button>
             <ul class="dropdown-menu pull-left">
@@ -59,33 +62,41 @@
         </tr>
         </thead>
         <tbody>
-        {{#if controller.isLoaded}}
-          {{#if view.pageContent}}
-            {{#each dataset in view.pageContent}}
-            {{#view view.DatasetView contentBinding="dataset"}}
-            <td class="first">
-              <span {{bindAttr class="dataset.healthClass"}}></span>
-            </td>
-            <td class="name">
-              <a title="{{unbound dataset.name}}" href="javascript:void(null)">{{unbound dataset.name}}</a>
-            </td>
-            <td><span {{bindAttr class="dataset.isRunning:text-info dataset.isSuspended:text-warning"}}>{{dataset.statusFormatted}}</span></td>
-            {{/view}}
-            {{/each}}
+        {{#if controller.isDatasetLoadingError}}
+          <td class="first"></td>
+          <td colspan="2">
+            {{t mirroring.dataset.dataset.loading.error}}
+          </td>
+        {{else}}
+          {{#if controller.isLoaded}}
+            {{#if view.pageContent}}
+              {{#each dataset in view.pageContent}}
+              {{#view view.DatasetView contentBinding="dataset"}}
+              <td class="first">
+                <span {{bindAttr class="dataset.healthClass"}}></span>
+              </td>
+              <td class="name">
+                <a title="{{unbound dataset.name}}" href="javascript:void(null)">{{unbound dataset.name}}</a>
+              </td>
+              <td><span {{bindAttr class="dataset.isRunning:text-info dataset.isSuspended:text-warning"}}>{{dataset.statusFormatted}}</span></td>
+              {{/view}}
+              {{/each}}
+            {{else}}
+              <tr>
+                <td class="first"></td>
+                <td colspan="2">
+                  {{t mirroring.table.noDatasets}}
+                </td>
+              </tr>
+            {{/if}}
           {{else}}
             <tr>
               <td class="first"></td>
               <td colspan="2">
-                {{t mirroring.table.noDatasets}}
+                <div class="spinner"></div>
               </td>
             </tr>
           {{/if}}
-        {{else}}
-          <tr>
-            <td colspan="3">
-              <div class="spinner"></div>
-            </td>
-          </tr>
         {{/if}}
         </tbody>
       </table>

+ 51 - 43
ambari-web/app/templates/main/mirroring/jobs.hbs

@@ -96,59 +96,67 @@
     </tr>
     </thead>
     <tbody>
-    {{#if view.isLoaded}}
-      {{#if view.pageContent}}
-        {{#each job in view.pageContent}}
-          {{#view view.JobView contentBinding="job"}}
-          <td class="first">
-            <span {{ bindAttr class="job.healthClass"}}></span>
-          </td>
+    {{#if view.parentView.controller.isDatasetLoadingError}}
+      <td class="first"></td>
+      <td colspan="4">
+        {{t mirroring.dataset.dataset.loading.instances}}
+      </td>
+    {{else}}
+      {{#if view.isLoaded}}
+        {{#if view.pageContent}}
+          {{#each job in view.pageContent}}
+            {{#view view.JobView contentBinding="job"}}
+            <td class="first">
+              <span {{ bindAttr class="job.healthClass"}}></span>
+            </td>
 
-          <td>{{unbound job.name}}</td>
-          <td>{{unbound job.startFormatted}}</td>
-          <td>{{unbound job.endFormatted}}</td>
-          <td>
-            {{#if view.showActions}}
-              <div class="btn-group display-inline-block">
-                <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
-                  {{job.statusFormatted}}
-                  <span class="caret"></span>
-                </a>
-                <ul class="dropdown-menu">
-                  {{#if job.isSuspended}}
-                    <li>
-                      <a href="javascript:void(null)" {{action resumeInstance job target="controller"}}>{{t mirroring.dataset.resumeInstance}}</a>
-                    </li>
-                  {{else}}
+            <td>{{unbound job.name}}</td>
+            <td>{{unbound job.startFormatted}}</td>
+            <td>{{unbound job.endFormatted}}</td>
+            <td>
+              {{#if view.showActions}}
+                <div class="btn-group display-inline-block">
+                  <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
+                    {{job.statusFormatted}}
+                    <span class="caret"></span>
+                  </a>
+                  <ul class="dropdown-menu">
+                    {{#if job.isSuspended}}
+                      <li>
+                        <a href="javascript:void(null)" {{action resumeInstance job target="controller"}}>{{t mirroring.dataset.resumeInstance}}</a>
+                      </li>
+                    {{else}}
+                      <li>
+                        <a href="javascript:void(null)" {{action suspendInstance job target="controller"}}>{{t mirroring.dataset.suspendInstance}}</a>
+                      </li>
+                    {{/if}}
                     <li>
-                      <a href="javascript:void(null)" {{action suspendInstance job target="controller"}}>{{t mirroring.dataset.suspendInstance}}</a>
+                      <a href="javascript:void(null)" {{action killInstance job target="controller"}}>{{t mirroring.dataset.killInstance}}</a>
                     </li>
-                  {{/if}}
-                  <li>
-                    <a href="javascript:void(null)" {{action killInstance job target="controller"}}>{{t mirroring.dataset.killInstance}}</a>
-                  </li>
-                </ul>
-              </div>
-            {{else}}
-              {{job.statusFormatted}}
-            {{/if}}
-          </td>
-          {{/view}}
-        {{/each}}
+                  </ul>
+                </div>
+              {{else}}
+                {{job.statusFormatted}}
+              {{/if}}
+            </td>
+            {{/view}}
+          {{/each}}
+        {{else}}
+          <tr>
+            <td class="first"></td>
+            <td colspan="4">
+              {{t mirroring.table.noJobs}}
+            </td>
+          </tr>
+        {{/if}}
       {{else}}
         <tr>
           <td class="first"></td>
           <td colspan="4">
-            {{t mirroring.table.noJobs}}
+            <div class="spinner"></div>
           </td>
         </tr>
       {{/if}}
-    {{else}}
-      <tr>
-        <td colspan="5">
-          <div class="spinner"></div>
-        </td>
-      </tr>
     {{/if}}
     </tbody>
   </table>