You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2014/09/10 01:16:17 UTC

git commit: AMBARI-7231. Slider View: View UI should load data from Ambari API (alexantonenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk 4f624444a -> 00be663b5


AMBARI-7231. Slider View: View UI should load data from Ambari API (alexantonenko)


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

Branch: refs/heads/trunk
Commit: 00be663b5835c3cc4e56b19f3e7521ff187a1926
Parents: 4f62444
Author: Alex Antonenko <hi...@gmail.com>
Authored: Wed Sep 10 02:11:02 2014 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Wed Sep 10 02:14:18 2014 +0300

----------------------------------------------------------------------
 .../assets/data/resource/service_status.json    | 107 +++++++++++++++
 .../app/controllers/slider_apps_controller.js   | 136 ++++++++++++++++++-
 .../src/main/resources/ui/app/helpers/ajax.js   |  40 +++++-
 .../src/main/resources/ui/app/initialize.js     |   4 +-
 .../ui/app/mappers/application_status.js        |  79 +++++------
 .../src/main/resources/ui/app/translations.js   |   7 +
 6 files changed, 325 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/00be663b/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/service_status.json
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/service_status.json b/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/service_status.json
new file mode 100644
index 0000000..59dd8db
--- /dev/null
+++ b/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/service_status.json
@@ -0,0 +1,107 @@
+
+{
+  "items" : [
+    {
+      "ServiceInfo" : {
+        "service_name" : "FALCON",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "FLUME",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "GANGLIA",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "HBASE",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "HCATALOG",
+        "state" : "INSTALLED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "HDFS",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "HIVE",
+        "state" : "INSTALLED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "MAPREDUCE2",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "NAGIOS",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "OOZIE",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "PIG",
+        "state" : "INSTALLED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "SQOOP",
+        "state" : "INSTALLED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "STORM",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "TEZ",
+        "state" : "INSTALLED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "WEBHCAT",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "YARN",
+        "state" : "STARTED"
+      }
+    },
+    {
+      "ServiceInfo" : {
+        "service_name" : "ZOOKEEPER",
+        "state" : "STARTED"
+      }
+    }
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/00be663b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_apps_controller.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_apps_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_apps_controller.js
index df06c2c..7199777 100644
--- a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_apps_controller.js
+++ b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_apps_controller.js
@@ -23,9 +23,141 @@ App.SliderAppsController = Ember.ArrayController.extend({
    * @method initResources
    */
   initResources:function () {
+    this.getClusterName();
+  },
+
+  initialValuesToLoad: Em.Object.create({
+    ambariAddress: null,
+    clusterName: null,
+    hdfsAddress: null,
+    yarnRMAddress: null,
+    yarnRMSchedulerAddress: null,
+    zookeeperQuorum: null
+  }),
+
+  zookeeperHosts: [],
+
+  /**
+   * Get cluster name from server
+   * @returns {$.ajax}
+   * @method getClusterName
+   */
+  getClusterName: function() {
+    return App.ajax.send({
+      name: 'cluster_name',
+      sender: this,
+      data: {
+        urlPrefix: '/api/v1/'
+      },
+      success: 'getClusterNameSuccessCallback'
+    });
+  },
+
+  /**
+   * Success callback for clusterName-request
+   * @param {object} data
+   * @method getClusterNameSuccessCallback
+   */
+  getClusterNameSuccessCallback: function(data) {
+    var clusterName = Em.get(data.items[0], 'Clusters.cluster_name');
+    App.set('clusterName', clusterName);
+    App.ApplicationStatusMapper.loop('load');
+    this.loadConfigsTags();
     this.loadComponentHost({componentName:"GANGLIA_SERVER",callback:"loadGangliaHostSuccessCallback"});
     this.loadComponentHost({componentName:"NAGIOS_SERVER",callback:"loadNagiosHostSuccessCallback"});
-  }.on('init'),
+    this.loadComponentHost({componentName:"ZOOKEEPER_SERVER",callback:"setZookeeperQuorum"});
+  },
+
+  loadConfigsTags: function () {
+    App.ajax.send({
+      name: 'config.tags',
+      sender: this,
+      data: {
+        urlPrefix: '/api/v1/'
+      },
+      success: 'onLoadConfigsTags'
+    });
+  },
+
+  onLoadConfigsTags: function (data) {
+    var urlParams = [];
+    if(data.Clusters.desired_configs['yarn-site'] && data.Clusters.desired_configs['zookeeper-env']){
+      var coreSiteTag = data.Clusters.desired_configs['core-site'].tag;
+      var yarnSiteTag = data.Clusters.desired_configs['yarn-site'].tag;
+      var zookeeperTag = data.Clusters.desired_configs['zookeeper-env'].tag;
+      urlParams.push('(type=core-site&tag=' + coreSiteTag + ')');
+      urlParams.push('(type=yarn-site&tag=' + yarnSiteTag + ')');
+      urlParams.push('(type=zookeeper-env&tag=' + zookeeperTag + ')');
+
+      App.ajax.send({
+        name: 'get_all_configurations',
+        sender: this,
+        data: {
+          urlParams: urlParams.join('|'),
+          urlPrefix: '/api/v1/'
+        },
+        success: 'onLoadConfigs'
+      });
+    }
+  },
+
+  onLoadConfigs: function (data) {
+    var hdfs = data.items.findProperty('type', 'core-site'),
+    yarn = data.items.findProperty('type', 'yarn-site'),
+    zookeeper = data.items.findProperty('type', 'zookeeper-env'),
+    initialValuesToLoad = this.get('initialValuesToLoad');
+    initialValuesToLoad.set('ambariAddress', location.protocol+"//"+document.location.host);
+    initialValuesToLoad.set('clusterName', App.get('clusterName'));
+    initialValuesToLoad.set('hdfsAddress', hdfs.properties['fs.defaultFS']);
+    initialValuesToLoad.set('yarnRMAddress', yarn.properties['yarn.resourcemanager.address']);
+    initialValuesToLoad.set('yarnRMSchedulerAddress', yarn.properties['yarn.resourcemanager.scheduler.address']);
+    initialValuesToLoad.set('zookeeperQuorum', zookeeper.properties.clientPort);
+    this.setZookeeperQuorum();
+  },
+
+  setZookeeperQuorum: function (data){
+    var zookeeperHosts = this.get('zookeeperHosts'),
+    hosts = [],
+    initialValuesToLoad = this.get('initialValuesToLoad');
+
+    //done
+    if(initialValuesToLoad.zookeeperQuorum !== null){
+      if(data){
+        hosts = data.items.map(function(item) {
+          return item.Hosts.host_name + ":" + initialValuesToLoad.zookeeperQuorum;
+        });
+        initialValuesToLoad.set('zookeeperQuorum', hosts.join(','));
+        this.sendInitialValues();
+      }else if(zookeeperHosts.length > 0){
+        hosts = zookeeperHosts.map(function(host) {
+          return host + ":" + initialValuesToLoad.zookeeperQuorum;
+        });
+        initialValuesToLoad.set('zookeeperQuorum', hosts.join(','));
+        this.sendInitialValues();
+      }
+    }else{
+      this.set('zookeeperHosts', data.items.mapProperty('Hosts.host_name'));
+    }
+  },
+
+  /**
+   * Send request to server to save initialValues
+   * @return {$.ajax}
+   * @method sendInitialValues
+   */
+  sendInitialValues: function () {
+    return App.ajax.send({
+      name: 'saveInitialValues',
+      sender: this,
+      data: {
+        data:  {
+          ViewInstanceInfo: {
+            properties: this.get('initialValuesToLoad')
+          }
+        }
+      }
+    });
+  },
 
   /**
    * Load ganglia server host
@@ -66,5 +198,5 @@ App.SliderAppsController = Ember.ArrayController.extend({
     if(data.items[0]){
       App.set('nagiosHost', Em.get(data.items[0], 'Hosts.host_name'));
     }
-  },
+  }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/00be663b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
index c3d6967..f19f4eb 100644
--- a/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
+++ b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
@@ -53,6 +53,19 @@ var urls = {
     mock: '/data/resource/status_true.json'
   },
 
+  'saveInitialValues': {
+    real: '',
+    headers: {
+      "Content-Type": "text/plain; charset=utf-8"
+    },
+    format: function(data) {
+      return {
+        type: 'PUT',
+        data: JSON.stringify(data.data)
+      }
+    }
+  },
+
   'createNewApp': {
     real: 'apps',
     mock: '',
@@ -104,6 +117,15 @@ var urls = {
     }
   },
 
+  'service_status': {
+    real: 'clusters/{clusterName}/services?fields=ServiceInfo/state&minimal_response=true',
+    mock:'/data/resource/service_status.json',
+    headers: {
+      Accept : "text/plain; charset=utf-8",
+      "Content-Type": "text/plain; charset=utf-8"
+    }
+  },
+
   'components_hosts': {
     real: 'clusters/{clusterName}/hosts?host_components/HostRoles/component_name={componentName}&minimal_response=true',
     mock:'/data/resource/components_hosts.json',
@@ -113,6 +135,22 @@ var urls = {
     }
   },
 
+  'config.tags': {
+    'real': 'clusters/{clusterName}?fields=Clusters/desired_configs',
+    headers: {
+      Accept : "text/plain; charset=utf-8",
+      "Content-Type": "text/plain; charset=utf-8"
+    }
+  },
+
+  'get_all_configurations': {
+    'real': 'clusters/{clusterName}/configurations?{urlParams}',
+    headers: {
+      Accept : "text/plain; charset=utf-8",
+      "Content-Type": "text/plain; charset=utf-8"
+    }
+  },
+
   'cluster_name': {
     real: 'clusters',
     mock:'/data/resource/cluster_name.json',
@@ -190,7 +228,7 @@ var formatRequest = function (data) {
     if(Em.get(data, 'urlPrefix')){
       var prefix = Em.get(data, 'urlPrefix');
     }
-    opt.url = prefix + formatUrl(this.real, data);
+    opt.url = prefix + (formatUrl(this.real, data) ? formatUrl(this.real, data) : "");
   }
 
   if (this.format) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00be663b/contrib/views/slider/src/main/resources/ui/app/initialize.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/initialize.js b/contrib/views/slider/src/main/resources/ui/app/initialize.js
index e93550f..a9df6ad 100755
--- a/contrib/views/slider/src/main/resources/ui/app/initialize.js
+++ b/contrib/views/slider/src/main/resources/ui/app/initialize.js
@@ -82,9 +82,7 @@ App.initializer({
       viewErrors: []
 
     });
-
-    application.ApplicationStatusMapper.getClusterName();
-    application.ApplicationStatusMapper.loop('load');
+    application.SliderAppsController.proto().initResources();
     application.ApplicationTypeMapper.loop('load');
     application.SliderAppsMapper.loop('load');
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/00be663b/contrib/views/slider/src/main/resources/ui/app/mappers/application_status.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/mappers/application_status.js b/contrib/views/slider/src/main/resources/ui/app/mappers/application_status.js
index 93a3789..f3d3968 100644
--- a/contrib/views/slider/src/main/resources/ui/app/mappers/application_status.js
+++ b/contrib/views/slider/src/main/resources/ui/app/mappers/application_status.js
@@ -24,24 +24,14 @@
 App.ApplicationStatusMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
 
   /**
-   * Map for parsing JSON received from server
-   * Format:
-   *  <code>
-   *    {
-   *      key1: 'path1',
-   *      key2: 'path2',
-   *      key3: 'path3'
-   *    }
-   *  </code>
-   *  Keys - names for properties in App
-   *  Values - pathes in JSON
-   * @type {object}
+   * List of services, we need to get status of them
+   * @type {Array}
    */
-  map: {
-    viewEnabled: 'viewEnabled',
-    viewErrors: 'viewErrors',
-    resourcesVersion: 'version'
-  },
+  servicesWeNeed: [
+    'HDFS',
+    'YARN',
+    'ZOOKEEPER'
+  ],
 
   /**
    * Load data from <code>App.urlPrefix + this.urlSuffix</code> one time
@@ -49,50 +39,55 @@ App.ApplicationStatusMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
    * @return {$.ajax}
    */
   load: function() {
-    console.log('App.ApplicationStatusMapper loading data');
     return App.ajax.send({
       name: 'mapper.applicationStatus',
       sender: this,
-      success: 'parse'
+      success: 'setResourcesVersion'
     });
   },
 
   /**
-   * Parse loaded data according to <code>map</code>
    * Set <code>App</code> properties
    * @param {object} data received from server data
-   * @method parse
+   * @method setResourcesVersion
    */
-  parse: function(data) {
-    var map = this.get('map');
-    Ember.keys(map).forEach(function(key) {
-      App.set(key, Ember.getWithDefault(data, map[key], ''));
-    });
+  setResourcesVersion: function(data) {
+    App.set('resourcesVersion', Em.get(data, "version") ? Em.get(data, "version") : "version" );
+    if(App.get('clusterName')){
+      this.loadServicesStatus();
+    }
   },
 
-  /**
-   * Get cluster name from server
-   * @returns {$.ajax}
-   * @method getClusterName
-   */
-  getClusterName: function() {
+  loadServicesStatus: function () {
     return App.ajax.send({
-      name: 'cluster_name',
-      sender: this,
+      name: 'service_status',
       data: {
         urlPrefix: '/api/v1/'
       },
-      success: 'getClusterNameSuccessCallback'
+      sender: this,
+      success: 'setErrors'
     });
   },
 
-  /**
-   * Success callback for clusterName-request
-   * @param {object} data
-   * @method getClusterNameSuccessCallback
-   */
-  getClusterNameSuccessCallback: function(data) {
-    App.set('clusterName', Em.get(data.items[0], 'Clusters.cluster_name'));
+  setErrors: function (data) {
+    var self = this,
+    errors = [];
+    this.get('servicesWeNeed').forEach( function (serviceName) {
+      self.findError(data.items.findProperty("ServiceInfo.service_name", serviceName), errors);
+    });
+
+    App.set('viewEnabled', (errors.length > 0 ? false : true));
+    App.set('viewErrors', errors);
+  },
+
+  findError: function (data, errors){
+    var name = Em.get(data, "ServiceInfo.service_name")
+    if(data){
+      if(Em.get(data, "ServiceInfo.state") != "STARTED")
+        errors.push(Em.I18n.t('error.start'+name));
+    }else{
+      errors.push(Em.I18n.t('error.no'+name));
+    }
   }
 
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/00be663b/contrib/views/slider/src/main/resources/ui/app/translations.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/translations.js b/contrib/views/slider/src/main/resources/ui/app/translations.js
index 108d1c7..4af412a 100644
--- a/contrib/views/slider/src/main/resources/ui/app/translations.js
+++ b/contrib/views/slider/src/main/resources/ui/app/translations.js
@@ -49,6 +49,13 @@ Em.I18n.translations = {
     'description': 'Description'
   },
 
+  'error.noHDFS': 'Slider applications view requires HDFS service.',
+  'error.startHDFS': 'Slider applications view requires HDFS service to be started.',
+  'error.noYARN': 'Slider applications view requires YARN service.',
+  'error.startYARN': 'Slider applications view requires YARN service to be started.',
+  'error.noZooKeeper': 'Slider applications view requires ZooKeeper service.',
+  'error.startZOOKEEPER': 'Slider applications view requires ZooKeeper service to be started.',
+
   'popup.confirmation.commonHeader': 'Confirmation',
   'question.sure':'Are you sure?',