浏览代码

AMBARI-10102 Create ember data model for widget. (atkach)

Andrii Tkach 10 年之前
父节点
当前提交
72bd502b05

+ 46 - 0
ambari-web/app/assets/data/widgets/service_widgets.json

@@ -0,0 +1,46 @@
+{
+  "href": "http://c6401.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/HDFS/artifacts/widget_layout",
+  "Artifacts": {
+    "artifact_name": "widget_order",
+    "service_name": "HDFS",
+    "stack_name": "HDP",
+    "stack_version": "2.2"
+  },
+  "artifact_data": {
+    "name": "HDFS",
+    "sections": [
+      {
+        "name": "HDFS_SUMMARY",
+        "widgets": [
+          {
+            "widget_name": "NAMENODE_HEAP",
+            "widget_type": "GAUGE",
+            "component_name": "NAMENODE",
+            "display_name": "NameNode Heap",
+            "time_created": 11111111,
+            "author": "me",
+            "expression": [{"template": "${jvmMemoryHeapUsed}/${jvmMemoryHeapMax}"}],
+            "properties": {
+              "warning_threshold": 0.5,
+              "error_threshold": 0.7
+            }
+          },
+          {
+            "widget_name": "HDFS_BYTES_READ",
+            "widget_type": "HEATMAP",
+            "display_name": "HDFS Bytes Read",
+            "time_created": 11111112,
+            "author": "me",
+            "description": "",
+            "component_name": "DATANODE",
+            "expression": [{"template": "${metrics.dfs.datanode.bytes_read}"}],
+            "properties": {
+              "display_unit": "MB",
+              "max_limit": "1024"
+            }
+          }
+        ]
+      }
+    ]
+  }
+}

+ 2 - 1
ambari-web/app/config.js

@@ -71,7 +71,8 @@ App.supports = {
   automatedKerberos: true,
   customizeAgentUserAccount: false,
   installGanglia: false,
-  opsDuringRollingUpgrade: false
+  opsDuringRollingUpgrade: false,
+  customizedWidgets: false
 };
 
 if (App.enableExperimental) {

+ 22 - 1
ambari-web/app/controllers/main/service/item.js

@@ -767,6 +767,27 @@ App.MainServiceItemController = Em.Controller.extend({
     console.warn('Error during executing custom command');
   },
 
-  isPending:true
+  isPending:true,
+
+  widgetsUrl: function () {
+    return App.get('apiPrefix') + App.get('stackVersionURL') + '/services/' + this.get('service.serviceName') + '/artifacts/widget_layout';
+  }.property('service.serviceName'),
+  widgetsMockUrl: '/data/widgets/service_widgets.json',
+
+  /**
+   * load service widgets
+   * @returns {$.Deferred}
+   */
+  loadWidgets: function () {
+    var dfd = $.Deferred();
+    var url = App.get('testMode') ? this.get('widgetsMockUrl') : this.get('widgetsUrl');
+
+    App.HttpClient.get(url, App.widgetMapper, {
+      complete: function () {
+        dfd.resolve();
+      }
+    });
+    return dfd.promise();
+  }
 
 });

+ 1 - 0
ambari-web/app/mappers.js

@@ -42,3 +42,4 @@ require('mappers/alert_instances_mapper');
 require('mappers/alert_groups_mapper');
 require('mappers/alert_notification_mapper');
 require('mappers/root_service_mapper');
+require('mappers/widget_mapper');

+ 56 - 0
ambari-web/app/mappers/widget_mapper.js

@@ -0,0 +1,56 @@
+/**
+ * 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.widgetMapper = App.QuickDataMapper.create({
+  model: App.Widget,
+  config: {
+    id: 'widget_name',
+    widget_name: 'widget_name',
+    default_order: 'default_order',
+    widget_type: 'widget_type',
+    display_name: 'display_name',
+    service_name: 'service_name',
+    component_name: 'component_name',
+    section_name: 'section_name',
+    time_created: 'time_created',
+    author: 'author',
+    properties: 'properties',
+    expression: 'expression'
+  },
+  map: function (json) {
+    if (!this.get('model')) return;
+
+    if (json.artifact_data) {
+      var result = [];
+      var serviceName = json.artifact_data.name;
+
+      json.artifact_data.sections.forEach(function (section) {
+        var sectionName = section.name;
+        section.widgets.forEach(function (item, index) {
+          item.service_name = serviceName;
+          item.section_name = sectionName;
+          item.default_order = (index + 1);
+          result.push(this.parseIt(item, this.config));
+        }, this);
+      }, this);
+
+      App.store.loadMany(this.get('model'), result);
+    }
+  }
+});

+ 2 - 1
ambari-web/app/models.js

@@ -67,4 +67,5 @@ require('models/configs/config_version');
 require('models/configs/config_property');
 require('models/configs/tab');
 require('models/configs/section');
-require('models/configs/sub_section');
+require('models/configs/sub_section');
+require('models/widget');

+ 36 - 0
ambari-web/app/models/widget.js

@@ -0,0 +1,36 @@
+/**
+ * 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');
+
+App.Widget = DS.Model.extend({
+  widgetName: DS.attr('string'),
+  defaultOrder: "", // This field is not derived from API but needs to be filled in the mapper on the client side
+  widgetType: DS.attr('string'),
+  displayName: DS.attr('string'),
+  serviceName: DS.attr('string'),
+  componentName: DS.attr('string'),
+  timeCreated: DS.attr('number'),
+  sectionName: DS.attr('string'),
+  author: DS.attr('string'),
+  properties: DS.attr('object'),
+  expression: DS.attr('array')
+});
+
+
+App.Widget.FIXTURES = [];

+ 3 - 0
ambari-web/app/views/main/service/item.js

@@ -234,6 +234,9 @@ App.MainServiceItemView = Em.View.extend({
 
   didInsertElement: function () {
     this.get('controller').setStartStopState();
+    if (App.get('supports.customizedWidgets')) {
+      this.get('controller').loadWidgets();
+    }
   },
 
   willInsertElement: function () {

+ 14 - 0
ambari-web/test/controllers/main/service/item_test.js

@@ -757,4 +757,18 @@ describe('App.MainServiceItemController', function () {
       expect(App.showConfirmationPopup.calledOnce).to.equal(true);
     });
   });
+
+  describe("#loadWidgets()", function () {
+    var mainServiceItemController = App.MainServiceItemController.create();
+    before(function () {
+      sinon.stub(App.HttpClient, 'get');
+    });
+    after(function () {
+      App.HttpClient.get.restore();
+    });
+    it("make GET call", function () {
+      mainServiceItemController.loadWidgets();
+      expect(App.HttpClient.get.calledOnce).to.be.true;
+    });
+  });
 });