You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2014/09/11 21:02:42 UTC

[22/26] git commit: AMBARI-7262. Slider View: Flex action for running app not showing user input dialog (regression). (onechiporenko)

AMBARI-7262. Slider View: Flex action for running app not showing user input dialog (regression). (onechiporenko)


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

Branch: refs/heads/branch-alerts-dev
Commit: b0fee6d4c6546f650d2e255dd646a52b6dc6d46f
Parents: a2f0bcd
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Thu Sep 11 18:39:56 2014 +0300
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Thu Sep 11 18:39:56 2014 +0300

----------------------------------------------------------------------
 .../resources/ui/app/assets/data/apps/apps.json |  16 ++-
 .../ui/app/controllers/slider_app_controller.js | 127 ++++++++++++++++---
 .../ui/app/mappers/slider_apps_mapper.js        |   4 +-
 .../resources/ui/app/styles/application.less    |  15 ++-
 .../ui/app/templates/slider_app/flex_popup.hbs  |  39 ++++++
 .../src/main/resources/ui/app/translations.js   |   5 +-
 6 files changed, 182 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/b0fee6d4/contrib/views/slider/src/main/resources/ui/app/assets/data/apps/apps.json
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/assets/data/apps/apps.json b/contrib/views/slider/src/main/resources/ui/app/assets/data/apps/apps.json
index d774387..63aa0be 100644
--- a/contrib/views/slider/src/main/resources/ui/app/assets/data/apps/apps.json
+++ b/contrib/views/slider/src/main/resources/ui/app/assets/data/apps/apps.json
@@ -83,7 +83,7 @@
       "components" : {
         "HBASE_MASTER" : {
           "componentName" : "HBASE_MASTER",
-          "instanceCount" : 1,
+          "instanceCount" : 2,
           "activeContainers" : {
             "container_1409333994422_0005_01_000002" : {
               "released" : "false",
@@ -98,6 +98,20 @@
               "exitCode" : "0",
               "diagnostics" : "",
               "roleId" : "1"
+            },
+            "container_1409333994422_0005_01_000003" : {
+              "released" : "false",
+              "startTime" : "1409348511279",
+              "createTime" : "1409348510529",
+              "environment" : "[AGENT_WORK_ROOT=\"$PWD\", HADOOP_USER_NAME=\"yarn\", AGENT_LOG_ROOT=\"$LOG_DIRS\", PYTHONPATH=\"./infra/agent/slider-agent/\", SLIDER_PASSPHRASE=\"DEV\"]",
+              "host" : "с6402.ambari.apache.org",
+              "name" : "container_1409333994422_0005_01_000002",
+              "command" : "python ./infra/agent/slider-agent/agent/main.py --label container_1409333994422_0005_01_000002___HBASE_MASTER --zk-quorum с6401.ambari.apache.org:2181 --zk-reg-path /registry/org-apache-slider/h4 ; ",
+              "state" : "3",
+              "role" : "HBASE_MASTER",
+              "exitCode" : "0",
+              "diagnostics" : "",
+              "roleId" : "1"
             }
           },
           "completedContainers" : { }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b0fee6d4/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
index f160383..e78a1b3 100644
--- a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
+++ b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
@@ -126,24 +126,82 @@ App.SliderAppController = Ember.ObjectController.extend({
   },
 
   /**
+   * Buttons for Flex modal popup
+   * @type {Em.Object[]}
+   */
+  flexModalButtons: [
+    Ember.Object.create({title: Em.I18n.t('common.cancel'), clicked:"closeFlex", dismiss: 'modal'}),
+    Ember.Object.create({title: Em.I18n.t('common.send'), clicked:"submitFlex", type:'success'})
+  ],
+
+  /**
+   * Grouped components by name
+   * @type {{name: string, count: number}[]}
+   */
+  groupedComponents: [],
+
+  /**
+   * Group components by <code>componentName</code> and save them to <code>groupedComponents</code>
+   * @method groupComponents
+   */
+  groupComponents: function() {
+    var groupedComponents = this.get('appType.components').map(function(c) {
+      return {
+        name: c.get('name'),
+        count: 0
+      };
+    });
+
+    this.get('components').forEach(function(component) {
+      var name = component.get('componentName'),
+        group = groupedComponents.findBy('name', name);
+      if (group) {
+        group.count++;
+      }
+    });
+    this.set('groupedComponents', groupedComponents);
+  },
+
+  /**
+   * Does new instance counts are invalid
+   * @type {bool}
+   */
+  groupedComponentsHaveErrors: false,
+
+  /**
+   * Validate new instance counts for components (should be integer and >= 0)
+   * @method validateGroupedComponents
+   * @returns {boolean}
+   */
+  validateGroupedComponents: function() {
+    var hasErrors = false;
+    this.get('groupedComponents').forEach(function(c) {
+      if (!/^\d+$/.test(c.count)) {
+        hasErrors = true;
+        return;
+      }
+      var count = parseInt(c.count + 0);
+      if (count < 0) {
+        hasErrors = true;
+      }
+    });
+    this.set('groupedComponentsHaveErrors', hasErrors);
+    return hasErrors;
+  },
+
+  /**
    * Do request to <strong>flex</strong> current slider's app
-   * @returns {$.ajax}
    * @method flex
    */
   flex: function() {
-    var model = this.get('model');
-    return App.ajax.send({
-      name: 'flexApp',
-      sender: this,
-      data: {
-        id: model.get('id'),
-        data: {
-          id: model.get('id'),
-          name: model.get('name'),
-          components: this.mapComponentsForFlexRequest()
-        }
-      }
-    });
+    this.groupComponents();
+    Bootstrap.ModalManager.open(
+      'flex-popup',
+      'Flex',
+      'slider_app/flex_popup',
+      this.get('flexModalButtons'),
+      this
+    );
   },
 
   /**
@@ -165,9 +223,9 @@ App.SliderAppController = Ember.ObjectController.extend({
    */
   mapComponentsForFlexRequest: function() {
     var components = {};
-    this.get('model.components').forEach(function(component) {
-      components[component.get('name')] = {
-        instanceCount: component.get('defaultNumInstances')
+    this.get('groupedComponents').forEach(function(component) {
+      components[Em.get(component, 'name')] = {
+        instanceCount: Em.get(component, 'count')
       }
     });
     return components;
@@ -200,6 +258,41 @@ App.SliderAppController = Ember.ObjectController.extend({
   actions: {
 
     /**
+     * Submit new instance counts for app components
+     * @method submitFlex
+     * @returns {*}
+     */
+    submitFlex: function() {
+      if (this.validateGroupedComponents()) return;
+      var model = this.get('model'),
+        components = this.mapComponentsForFlexRequest();
+      this.get('groupedComponents').clear();
+      this.set('groupedComponentsHaveErrors', false);
+      Bootstrap.ModalManager.close('flex-popup');
+      return App.ajax.send({
+        name: 'flexApp',
+        sender: this,
+        data: {
+          id: model.get('id'),
+          data: {
+            id: model.get('id'),
+            name: model.get('name'),
+            components: components
+          }
+        }
+      });
+    },
+
+    /**
+     * Close flex-popup
+     * @method closeFlex
+     */
+    closeFlex: function() {
+      this.get('groupedComponents').clear();
+      this.set('groupedComponentsHaveErrors', false);
+    },
+
+    /**
      * Handler for "Yes" click in modal popup
      * @returns {*}
      * @method modalConfirmed

http://git-wip-us.apache.org/repos/asf/ambari/blob/b0fee6d4/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js b/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js
index 6b83eea..013c65c 100644
--- a/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js
+++ b/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js
@@ -75,8 +75,8 @@ App.SliderAppsMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
       appId = data.id;
 
     Object.keys(data.components).forEach(function (key) {
-      var component = data.components[key];
-      activeContainers = Object.keys(component.activeContainers);
+      var component = data.components[key],
+        activeContainers = Object.keys(component.activeContainers);
       for (var i = 0; i < component.instanceCount; i++) {
         components.pushObject(
           Ember.Object.create({

http://git-wip-us.apache.org/repos/asf/ambari/blob/b0fee6d4/contrib/views/slider/src/main/resources/ui/app/styles/application.less
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/styles/application.less b/contrib/views/slider/src/main/resources/ui/app/styles/application.less
index c0988f2..f3c4df9 100644
--- a/contrib/views/slider/src/main/resources/ui/app/styles/application.less
+++ b/contrib/views/slider/src/main/resources/ui/app/styles/application.less
@@ -16,6 +16,10 @@
  * limitations under the License.
  */
 
+.table-row() {
+  margin: 10px 0;
+}
+
 html {
   overflow-y: scroll;
 }
@@ -380,6 +384,7 @@ a {
     }
   }
 }
+
 .app-page {
   .wrap-tabs {
     margin-top: 30px;
@@ -539,7 +544,6 @@ a {
   }
 }
 
-
 .chart-container {
   cursor: default;
 
@@ -620,13 +624,12 @@ a {
   }
 }
 
-
 .app_configs {
   a.accordion-toggle {
     display: block;
   }
   .row {
-    margin: 10px 0;
+    .table-row();
     textarea {
       height: 200px;
       padding-left: 5px;
@@ -695,3 +698,9 @@ a {
     color: #999;
   }
 }
+
+.flex-popup {
+  .row {
+    .table-row();
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/b0fee6d4/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/flex_popup.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/flex_popup.hbs b/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/flex_popup.hbs
new file mode 100644
index 0000000..70dfce8
--- /dev/null
+++ b/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/flex_popup.hbs
@@ -0,0 +1,39 @@
+{{!
+* 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.
+}}
+
+<div class="container flex-popup">
+  <form class="form-horizontal" role="form">
+    <div class="form-group">
+      <div class="col-sm-2"><strong>{{t common.components}}</strong></div>
+      <div class="col-sm-4"><strong>{{t wizard.step2.table.instances}}</strong></div>
+    </div>
+    {{#each component in groupedComponents}}
+      <div class="form-group">
+        <div class="col-sm-2">{{component.name}}</div>
+        <div class="col-sm-4">{{input value=component.count}}</div>
+      </div>
+    {{/each}}
+    <div class="form-group">
+      {{#if groupedComponentsHaveErrors}}
+        <div class="col-sm-5 alert alert-danger">
+          {{t sliderApp.flex.invalid_counts}}
+        </div>
+      {{/if}}
+    </div>
+  </form>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b0fee6d4/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 056b21f..51c9352 100644
--- a/contrib/views/slider/src/main/resources/ui/app/translations.js
+++ b/contrib/views/slider/src/main/resources/ui/app/translations.js
@@ -49,7 +49,8 @@ Em.I18n.translations = {
     'description': 'Description',
     'alerts': 'Alerts',
     'key': 'Key',
-    'remove': 'Remove'
+    'remove': 'Remove',
+    'send': 'Send'
   },
 
   'error.noHDFS': 'Slider applications view requires HDFS service.',
@@ -80,6 +81,8 @@ Em.I18n.translations = {
   'slider.apps.create': 'Create App',
   'sliderApps.filters.info': '{0} of {1} sliders showing',
 
+  'sliderApp.flex.invalid_counts': 'Instance counts should be integer and >= 0',
+
   'sliderApp.summary.go_to_nagios': 'Go to Nagios',
   'sliderApp.summary.go_to_ganglia': 'Go to Ganglia',