ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From onechipore...@apache.org
Subject [1/2] git commit: AMBARI-6562. Create mapper for view service/components state. (onechiporenko)
Date Tue, 22 Jul 2014 13:37:45 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk b84430366 -> fe7f25b54


AMBARI-6562. Create mapper for view service/components state. (onechiporenko)


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

Branch: refs/heads/trunk
Commit: f1a5d05318a2d9e08f0051a1adbc8bdbbf298996
Parents: 46fd611
Author: Oleg Nechiporenko <onechiporenko@apache.org>
Authored: Tue Jul 22 16:35:05 2014 +0300
Committer: Oleg Nechiporenko <onechiporenko@apache.org>
Committed: Tue Jul 22 16:35:05 2014 +0300

----------------------------------------------------------------------
 .../src/main/resources/ui/app/scripts/app.js    |  10 +-
 .../ui/app/scripts/assets/clusters.json         |  10 +
 .../ui/app/scripts/assets/components.json       |  94 +++++++++
 .../ui/app/scripts/assets/components_hosts.json |  16 ++
 .../ui/app/scripts/assets/services.json         |  39 ++++
 .../app/scripts/controllers/jobs_controller.js  |  96 ++++-----
 .../resources/ui/app/scripts/helpers/ajax.js    |  22 +-
 .../mappers/application_status_mapper.js        | 208 +++++++++++++++++++
 .../ui/app/scripts/models/component.js          |  40 ++++
 .../resources/ui/app/scripts/models/service.js  |  40 ++++
 .../resources/ui/app/scripts/views/jobs_view.js |   6 +-
 .../main/resources/ui/app/templates/jobs.hbs    |  10 +-
 12 files changed, 527 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/scripts/app.js
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/app.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/app.js
index c5d68f2..11fc15b 100644
--- a/contrib/views/jobs/src/main/resources/ui/app/scripts/app.js
+++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/app.js
@@ -38,10 +38,18 @@ App.initializer({
        * Prefix for API-requests
        * @type {string}
        */
-      urlPrefix: '/api/v1'
+      urlPrefix: '/api/v1',
+
+      /**
+       * Current cluster name
+       * @type {null|string}
+       */
+      clusterName: null
 
     });
 
+    application.ApplicationStatusMapper.getClusterName();
+
   }
 });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/clusters.json
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/clusters.json b/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/clusters.json
new file mode 100644
index 0000000..b8e616b
--- /dev/null
+++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/clusters.json
@@ -0,0 +1,10 @@
+{
+  "items" : [
+    {
+      "Clusters" : {
+        "cluster_name" : "tdk",
+        "version" : "HDP-2.1"
+      }
+    }
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/components.json
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/components.json b/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/components.json
new file mode 100644
index 0000000..8814b09
--- /dev/null
+++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/components.json
@@ -0,0 +1,94 @@
+{
+  "items" : [
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "DATANODE",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "HDFS_CLIENT",
+        "state" : "INSTALLED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "JOURNALNODE",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "NAMENODE",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "SECONDARY_NAMENODE",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "ZKFC",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "HISTORYSERVER",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "MAPREDUCE2_CLIENT",
+        "state" : "INSTALLED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "TEZ_CLIENT",
+        "state" : "INSTALLED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "APP_TIMELINE_SERVER",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "NODEMANAGER",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "RESOURCEMANAGER",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "YARN_CLIENT",
+        "state" : "INSTALLED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "ZOOKEEPER_CLIENT",
+        "state" : "INSTALLED"
+      }
+    },
+    {
+      "ServiceComponentInfo" : {
+        "component_name" : "ZOOKEEPER_SERVER",
+        "state" : "STARTED"
+      }
+    }
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/components_hosts.json
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/components_hosts.json
b/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/components_hosts.json
new file mode 100644
index 0000000..a86fd10
--- /dev/null
+++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/components_hosts.json
@@ -0,0 +1,16 @@
+{
+  "items" : [
+    {
+      "Hosts" : {
+        "host_name" : "tdk-2.c.apache.org"
+      },
+      "host_components" : [
+        {
+          "HostRoles" : {
+            "component_name" : "APP_TIMELINE_SERVER"
+          }
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/services.json
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/services.json b/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/services.json
new file mode 100644
index 0000000..018ec24
--- /dev/null
+++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/assets/services.json
@@ -0,0 +1,39 @@
+{
+  "items" : [
+    {
+      "ServiceInfo" : {
+        "maintenance_state" : "OFF",
+        "service_name" : "HDFS",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "maintenance_state" : "OFF",
+        "service_name" : "MAPREDUCE2",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "maintenance_state" : "OFF",
+        "service_name" : "TEZ",
+        "state" : "INSTALLED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "maintenance_state" : "OFF",
+        "service_name" : "YARN",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "maintenance_state" : "OFF",
+        "service_name" : "ZOOKEEPER",
+        "state" : "STARTED"
+      }
+    }
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/scripts/controllers/jobs_controller.js
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/controllers/jobs_controller.js
b/contrib/views/jobs/src/main/resources/ui/app/scripts/controllers/jobs_controller.js
index c2b6560..d033a4c 100644
--- a/contrib/views/jobs/src/main/resources/ui/app/scripts/controllers/jobs_controller.js
+++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/controllers/jobs_controller.js
@@ -340,19 +340,6 @@ App.JobsController = Ember.ArrayController.extend(App.RunPeriodically,
{
     }
   }),
 
-  /*columnsName: Ember.ArrayController.create({
-    content: [
-      { name: Em.I18n.t('jobs.column.id'), index: 0 },
-      { name: Em.I18n.t('jobs.column.user'), index: 1 },
-      { name: Em.I18n.t('jobs.column.start.time'), index: 2 },
-      { name: Em.I18n.t('jobs.column.end.time'), index: 3 },
-      { name: Em.I18n.t('jobs.column.duration'), index: 4 }
-    ],
-    columnsCount: function () {
-      return this.get('content.length') + 1;
-    }.property('content.length')
-  }),*/
-
   lastIDSuccessCallback: function(data) {
     if(!data.entities[0]){
       return;
@@ -378,16 +365,23 @@ App.JobsController = Ember.ArrayController.extend(App.RunPeriodically,
{
   },
 
   checkDataLoadingError: function (jqXHR){
-    /*var atsComponent = App.HostComponent.find().findProperty('componentName','APP_TIMELINE_SERVER');
+    var atsComponent = App.HiveJob.store.getById('component', 'APP_TIMELINE_SERVER');
     if(atsComponent && atsComponent.get('workStatus') != "STARTED") {
       this.set('jobsMessage', Em.I18n.t('jobs.error.ats.down'));
-    }else if (jqXHR && jqXHR.status == 400) {
-      this.set('jobsMessage', Em.I18n.t('jobs.error.400'));
-    }else if ((!jqXHR && this.get('loaded') && !this.get('loading')) || (jqXHR
&& jqXHR.status == 500)) {
-      this.set('jobsMessage', Em.I18n.t('jobs.nothingToShow'));
-    }else{
-      this.set('jobsMessage', Em.I18n.t('jobs.loadingTasks'));
-    }*/
+    }
+    else {
+      if (jqXHR && jqXHR.status == 400) {
+        this.set('jobsMessage', Em.I18n.t('jobs.error.400'));
+      }
+      else {
+        if ((!jqXHR && this.get('loaded') && !this.get('loading')) || (jqXHR
&& jqXHR.status == 500)) {
+          this.set('jobsMessage', Em.I18n.t('jobs.nothingToShow'));
+        }
+        else {
+          this.set('jobsMessage', Em.I18n.t('jobs.loadingTasks'));
+        }
+      }
+    }
   },
 
   init: function() {
@@ -396,37 +390,35 @@ App.JobsController = Ember.ArrayController.extend(App.RunPeriodically,
{
   },
 
   loadJobs : function() {
-      //var yarnService = App.YARNService.find().objectAt(0),
-      //atsComponent = App.HostComponent.find().findProperty('componentName','APP_TIMELINE_SERVER'),
-      //atsInValidState = !!atsComponent && atsComponent.get('workStatus') === "STARTED",
-      //retryLoad = this.checkDataLoadingError();
-    //if (yarnService != null && atsInValidState) {
-    this.set('loading', true);
-    /*var historyServerHostName = yarnService.get('appTimelineServer.hostName'),
-      filtersLink = this.get('filterObject').createJobsFiltersLink(),
-      hiveQueriesUrl = App.get('testMode') ? "/scripts/assets/hive-queries.json" : "/proxy?url=http://"
+ historyServerHostName
-        + ":" + yarnService.get('ahsWebPort') + "/ws/v1/timeline/HIVE_QUERY_ID" + filtersLink;*/
-    /*App.ajax.send({
-      name: 'jobs.lastID',
-      sender: self,
-      data: {
-        historyServerHostName: '',//historyServerHostName,
-        ahsWebPort: ''//yarnService.get('ahsWebPort')
-      },
-      success: 'lastIDSuccessCallback',
-      error : 'lastIDErrorCallback'
-    });*/
-    App.ajax.send({
-      name: 'load_jobs',
-      sender: this,
-      data: {
-        historyServerHostName: '',
-        ahsWebPort: '',
-        filtersLink: this.get('filterObject').createJobsFiltersLink()
-      },
-      success: 'loadJobsSuccessCallback',
-      error : 'loadJobsErrorCallback'
-    });
+    var yarnService = App.HiveJob.store.getById('service', 'YARN'),
+      atsComponent = App.HiveJob.store.getById('component', 'APP_TIMELINE_SERVER'),
+      atsInValidState = !!atsComponent && atsComponent.get('workStatus') === "STARTED";
+    this.checkDataLoadingError();
+    if (!Em.isNone(yarnService) && atsInValidState) {
+      this.set('loading', true);
+      var historyServerHostName = atsComponent.get('hostName');
+      /*App.ajax.send({
+        name: 'jobs.lastID',
+        sender: self,
+        data: {
+          historyServerHostName: '',//historyServerHostName,
+          ahsWebPort: ''//yarnService.get('ahsWebPort')
+        },
+        success: 'lastIDSuccessCallback',
+        error : 'lastIDErrorCallback'
+      });*/
+      App.ajax.send({
+        name: 'load_jobs',
+        sender: this,
+        data: {
+          historyServerHostName: historyServerHostName,
+          ahsWebPort: '',
+          filtersLink: this.get('filterObject').createJobsFiltersLink()
+        },
+        success: 'loadJobsSuccessCallback',
+        error : 'loadJobsErrorCallback'
+      });
+    }
   },
 
   loadJobsSuccessCallback: function(data) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/ajax.js
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/ajax.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/ajax.js
index 2c301ad..7a61437 100644
--- a/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/ajax.js
+++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/helpers/ajax.js
@@ -40,6 +40,26 @@ var urls = {
     real: '/proxy?url=http://{historyServerHostName}:{ahsWebPort}/ws/v1/timeline/HIVE_QUERY_ID?limit=1&secondaryFilter=tez:true',
     mock: '/scripts/assets/hive-queries.json',
     apiPrefix: ''
+  },
+
+  'cluster_name': {
+    real: 'clusters',
+    mock: '/scripts/assets/clusters.json'
+  },
+
+  'services': {
+    real: 'clusters/{clusterName}/services?fields=ServiceInfo/state,ServiceInfo/maintenance_state&minimal_response=true',
+    mock: '/scripts/assets/services.json'
+  },
+
+  'components': {
+    real: 'clusters/{clusterName}/components/?fields=ServiceComponentInfo/state&minimal_response=true',
+    mock: '/scripts/assets/components.json'
+  },
+
+  'components_hosts': {
+    real: 'clusters/{clusterName}/hosts?host_components/HostRoles/component_name={componentName}&minimal_response=true',
+    mock: '/scripts/assets/components_hosts.json'
   }
 
 };
@@ -122,7 +142,7 @@ var ajax = Em.Object.extend({
     Ember.assert('Invalid config.name provided - ' + config.name, urls[config.name]);
 
     var opt = {},
-      params = {};
+      params = {clusterName: App.get('clusterName')};
 
     if (config.data) {
       jQuery.extend(params, config.data);

http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/scripts/mappers/application_status_mapper.js
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/mappers/application_status_mapper.js
b/contrib/views/jobs/src/main/resources/ui/app/scripts/mappers/application_status_mapper.js
new file mode 100644
index 0000000..426c6c8
--- /dev/null
+++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/mappers/application_status_mapper.js
@@ -0,0 +1,208 @@
+/**
+ * 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.
+ */
+
+/**
+ * Mapper for YARN and ATS
+ * Get their statuses and save it to proper models
+ * Should be called only from application initializer (and it's already done)
+ * @type {Ember.Object}
+ */
+App.ApplicationStatusMapper = Em.Object.createWithMixins(App.RunPeriodically, {
+
+  /**
+   * Map for Service-model
+   * @type {Object}
+   */
+  yarnMap: {
+    workStatus: {
+      key: 'ServiceInfo.state',
+      default: 'UNKNOWN'
+    },
+    maintenanceState: {
+      key: 'ServiceInfo.maintenance_state',
+      default: 'OFF'
+    },
+    id: {
+      default: 'YARN'
+    }
+  },
+
+  /**
+   * Map for Component-model
+   * @type {Object}
+   */
+  atsMap: {
+    workStatus: {
+      key: 'ServiceComponentInfo.state',
+      default: 'UNKNOWN'
+    },
+    componentName: {
+      default: 'APP_TIMELINE_SERVER'
+    },
+    id: {
+      default: 'APP_TIMELINE_SERVER'
+    }
+  },
+
+  /**
+   * Start mapping when <code>App.clusterName</code> is loaded
+   * @method mapInit
+   */
+  mapInit: function() {
+    var clusterName = App.get('clusterName');
+    if (Em.isNone(clusterName)) return;
+    this.loop('map');
+  }.observes('App.clusterName'),
+
+  /**
+   * Map service and component periodically
+   * Map host name for component only once
+   * @method map
+   */
+  map: function() {
+    var self = this;
+    this.getServices().then(function() {
+      self.getComponents().then(function() {
+        self.getHostsForComponents();
+      });
+    });
+  },
+
+  /**
+   * Get cluster name from server
+   * @returns {$.ajax}
+   * @method getClusterName
+   */
+  getClusterName: function() {
+    return App.ajax.send({
+      name: 'cluster_name',
+      sender: this,
+      success: 'getClusterNameSuccessCallback'
+    });
+  },
+
+  /**
+   * Success callback for clusterName-request
+   * @param {object} data
+   * @method getClusterNameSuccessCallback
+   */
+  getClusterNameSuccessCallback: function(data) {
+    App.set('clusterName', Em.get(data.items[0], 'Clusters.cluster_name'));
+  },
+
+  /**
+   * Get list of installed services (YARN is needed)
+   * @returns {$.ajax}
+   * @method getServices
+   */
+  getServices: function() {
+    return App.ajax.send({
+      name: 'services',
+      sender: this,
+      success: 'getServicesSuccessCallback',
+      error: 'getServicesErrorCallback'
+    });
+  },
+
+  /**
+   * Success callback for services-request
+   * Map YARN-service to model (if YARN not available - save empty object)
+   * @param {Object} data
+   * @method getServicesSuccessCallback
+   */
+  getServicesSuccessCallback: function(data) {
+    var map = this.get('yarnMap'),
+      yarn = data.items.findBy('ServiceInfo.service_name', 'YARN'),
+      yarnModel = Em.isNone(yarn) ? {id: 'YARN'} : Em.JsonMapper.map(yarn, map);
+    App.HiveJob.store.push('service', yarnModel);
+  },
+
+  /**
+   * Error callback for services-request
+   * Save empty object to model
+   * @method getServicesErrorCallback
+   */
+  getServicesErrorCallback: function() {
+    App.HiveJob.store.push('yarn', {id: 'YARN'});
+  },
+
+  /**
+   * Get list of components from server
+   * @returns {$.ajax}
+   * @method getComponents
+   */
+  getComponents: function() {
+    return App.ajax.send({
+      name: 'components',
+      sender: this,
+      success: 'getComponentsSuccessCallback',
+      error: 'getComponentsErrorCallback'
+    });
+  },
+
+  /**
+   * Success callback for components-request
+   * Save ATS to model (if ATS not available - save empty object)
+   * @param {object} data
+   * @method getComponentsSuccessCallback
+   */
+  getComponentsSuccessCallback: function(data) {
+    var map = this.get('atsMap'),
+      ats = data.items.findBy('ServiceComponentInfo.component_name', 'APP_TIMELINE_SERVER'),
+      atsModel = Em.isNone(ats) ? {id: 'APP_TIMELINE_SERVER'} : Em.JsonMapper.map(ats, map);
+    App.HiveJob.store.push('component', atsModel);
+  },
+
+  /**
+   * Error callback for components-request
+   * Save empty object to model
+   * @method getComponentsErrorCallback
+   */
+  getComponentsErrorCallback: function() {
+    App.HiveJob.store.push('component', {id: 'APP_TIMELINE_SERVER'});
+  },
+
+  /**
+   * Get host name for ATS
+   * @returns {$.ajax}
+   * @method getHostsForComponents
+   */
+  getHostsForComponents: function() {
+    if (!App.HiveJob.store.getById('component', 'APP_TIMELINE_SERVER').get('hostName')) {
+      return App.ajax.send({
+        name: 'components_hosts',
+        sender: this,
+        data: {
+          componentName: 'APP_TIMELINE_SERVER'
+        },
+        success: 'getHostsForComponentsSuccessCallback'
+      });
+    }
+  },
+
+  /**
+   * Success callback for hosts-request
+   * Save host name to ATS-model
+   * @param {Object} data
+   * @method getHostsForComponentsSuccessCallback
+   */
+  getHostsForComponentsSuccessCallback: function(data) {
+    App.HiveJob.store.getById('component', 'APP_TIMELINE_SERVER').set('hostName', Em.get(data.items[0],
'Hosts.host_name'));
+  }
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/scripts/models/component.js
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/models/component.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/component.js
new file mode 100644
index 0000000..9e5c646
--- /dev/null
+++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/component.js
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+
+App.Component = DS.Model.extend({
+
+  /**
+   * Component name
+   * @type {string}
+   */
+  componentName: DS.attr('string'),
+
+  /**
+   * Component state
+   * @type {string}
+   */
+  workStatus: DS.attr('string'),
+
+  /**
+   * Name of host where ATS installed
+   * @type {string}
+   */
+  hostName: ''
+
+});
+
+App.Component.FIXTURES = [];
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/scripts/models/service.js
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/models/service.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/service.js
new file mode 100644
index 0000000..ce0b131
--- /dev/null
+++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/models/service.js
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+
+App.Service = DS.Model.extend({
+
+  /**
+   * Service maintenance state
+   * @type {string}
+   */
+  maintenanceState: DS.attr('string'),
+
+  /**
+   * Service state
+   * @type {string}
+   */
+  workStatus: DS.attr('string'),
+
+  /**
+   *
+   * @type {string}
+   */
+  ahsWebPort: '8088'
+
+});
+
+App.Service.FIXTURES = [];
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/scripts/views/jobs_view.js
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/scripts/views/jobs_view.js b/contrib/views/jobs/src/main/resources/ui/app/scripts/views/jobs_view.js
index 26124b5..9d814d6 100644
--- a/contrib/views/jobs/src/main/resources/ui/app/scripts/views/jobs_view.js
+++ b/contrib/views/jobs/src/main/resources/ui/app/scripts/views/jobs_view.js
@@ -34,11 +34,7 @@ App.JobsView = App.TableView.extend({
    If no jobs to display set noDataToShow to true, else set emptyData to false.
    */
   noDataToShowObserver: function () {
-    if(this.get("controller.content.length") > 0){
-      this.set("noDataToShow",false);
-    }else{
-      this.set("noDataToShow",true);
-    }
+    this.set("noDataToShow", this.get("controller.content.length") === 0);
   }.observes("controller.content.length"),
 
   willInsertElement: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/f1a5d053/contrib/views/jobs/src/main/resources/ui/app/templates/jobs.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/jobs/src/main/resources/ui/app/templates/jobs.hbs b/contrib/views/jobs/src/main/resources/ui/app/templates/jobs.hbs
index d43f5f0..212c5d4 100644
--- a/contrib/views/jobs/src/main/resources/ui/app/templates/jobs.hbs
+++ b/contrib/views/jobs/src/main/resources/ui/app/templates/jobs.hbs
@@ -50,11 +50,11 @@
     </thead>
     <tbody>
       {{#if view.noDataToShow}}
-      <tr>
-        <td class="no-data" colspan="6">
-          {{controller.jobsMessage}}
-        </td>
-      </tr>
+        <tr>
+          <td class="no-data" colspan="6">
+            {{controller.jobsMessage}}
+          </td>
+        </tr>
       {{else}}
         {{#each job in controller.sortedContent}}
           <tr>


Mime
View raw message