You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2014/05/27 13:41:36 UTC

git commit: AMBARI-5898. Slider's new app wizard should make POST call to create app. (onechiporenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk 5c84352f5 -> f42404055


AMBARI-5898. Slider's new app wizard should make POST call to create app. (onechiporenko)


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

Branch: refs/heads/trunk
Commit: f42404055afee812b38c1bd339379346d319a840
Parents: 5c84352
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Tue May 27 14:37:47 2014 +0300
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Tue May 27 14:41:27 2014 +0300

----------------------------------------------------------------------
 .../createAppWizard/step1_controller.js         |  42 +++--
 .../createAppWizard/step2_controller.js         |  58 +++---
 .../createAppWizard/step3_controller.js         |  15 ++
 .../createAppWizard/step4_controller.js         |  93 ++++-----
 .../controllers/create_app_wizard_controller.js |  45 ++++-
 .../ui/app/controllers/slider_app_controller.js |  22 ++-
 .../src/main/resources/ui/app/helpers/ajax.js   | 188 +++++++++++++++++++
 .../ui/app/mappers/application_status.js        |  19 +-
 .../ui/app/mappers/application_type.js          |  23 +--
 .../src/main/resources/ui/app/mappers/mapper.js |   7 -
 .../ui/app/mappers/slider_apps_mapper.js        |  19 +-
 .../resources/ui/app/models/slider_app_type.js  |   7 +-
 .../ui/app/models/slider_app_type_component.js  |   7 +-
 13 files changed, 401 insertions(+), 144 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step1_controller.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step1_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step1_controller.js
index 5017aa1..9bfe68c 100644
--- a/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step1_controller.js
+++ b/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step1_controller.js
@@ -59,7 +59,26 @@ App.CreateAppWizardStep1Controller = Ember.Controller.extend({
   nameErrorMessage: '',
 
   /**
+   * Define description depending on selected App type
+   * @type {string}
+   */
+  typeDescription: function () {
+    var selectedType = this.get('selectedType');
+    return selectedType ? Em.I18n.t('wizard.step1.typeDescription').format(selectedType.get('displayName')) : '';
+  }.property('selectedType'),
+
+  /**
+   * Define if submit button is disabled
+   * <code>newAppName</code> should pass validation and be not empty
+   * @type {bool}
+   */
+  isSubmitDisabled: function () {
+    return !this.get('newAppName') || this.get('isNameError');
+  }.property('newAppName', 'isNameError'),
+
+  /**
    * Load all required data for step
+   * @method loadStep
    */
   loadStep: function () {
     this.initializeNewApp();
@@ -68,17 +87,20 @@ App.CreateAppWizardStep1Controller = Ember.Controller.extend({
 
   /**
    * Initialize new App and set it to <code>newApp</code>
+   * @method initializeNewApp
    */
   initializeNewApp: function () {
     var newApp = Ember.Object.create({
       name: '',
-      appType: null
+      appType: null,
+      configs: {}
     });
     this.set('newApp', newApp);
   },
 
   /**
    * Load all available types for App
+   * @method loadAvailableTypes
    */
   loadAvailableTypes: function () {
     this.set('availableTypes', this.store.all('sliderAppType'));
@@ -87,6 +109,7 @@ App.CreateAppWizardStep1Controller = Ember.Controller.extend({
   /**
    * Validate <code>newAppName</code>
    * It should consist only of letters, numbers, '-', '_' and first character should be a letter
+   * @method nameValidator
    * @return {Boolean}
    */
   nameValidator: function () {
@@ -110,25 +133,14 @@ App.CreateAppWizardStep1Controller = Ember.Controller.extend({
   }.observes('newAppName'),
 
   /**
-   * Define description depending on selected App type
+   * Save new application data to wizard controller
+   * @method saveApp
    */
-  typeDescription: function () {
-    var selectedType = this.get('selectedType');
-    return selectedType ? Em.I18n.t('wizard.step1.typeDescription').format(selectedType.get('displayName')) : '';
-  }.property('selectedType'),
-
-  /**
-   * Define if submit button is disabled
-   * <code>newAppName</code> should pass validation and be not empty
-   */
-  isSubmitDisabled: function () {
-    return !this.get('newAppName') || this.get('isNameError');
-  }.property('newAppName', 'isNameError'),
-
   saveApp: function () {
     var newApp = this.get('newApp');
     newApp.set('appType', this.get('selectedType'));
     newApp.set('name', this.get('newAppName'));
+    newApp.set('configs', this.get('selectedType.configs'));
     this.set('appWizardController.newApp', newApp);
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step2_controller.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step2_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step2_controller.js
index 201dafb..c9e57ff 100644
--- a/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step2_controller.js
+++ b/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step2_controller.js
@@ -22,6 +22,10 @@ App.CreateAppWizardStep2Controller = Ember.ArrayController.extend({
 
   appWizardController: Ember.computed.alias("controllers.createAppWizard"),
 
+  /**
+   * List of app type components
+   * @type {App.SliderAppTypeComponent}
+   */
   content: [],
 
   /**
@@ -31,7 +35,31 @@ App.CreateAppWizardStep2Controller = Ember.ArrayController.extend({
   newApp: null,
 
   /**
+   * Validate all input fields are integer
+   * @type {Boolean}
+   */
+  isError: function () {
+    var result = false;
+    this.get('content').forEach(function (component) {
+      if (!result && (this.isNotInteger(component.get('numInstances')) || this.isNotInteger(component.get('yarnMemory')) || this.isNotInteger(component.get('yarnCPU')))) {
+        result = true;
+      }
+    }, this);
+    return result;
+  }.property('content.@each.numInstances', 'content.@each.yarnMemory', 'content.@each.yarnCPU'),
+
+  /**
+   * Define if submit button is disabled
+   * <code>isError</code> should be true
+   * @type {bool}
+   */
+  isSubmitDisabled: function () {
+    return this.get('isError');
+  }.property('isError'),
+
+  /**
    * Load all required data for step
+   * @method loadStep
    */
   loadStep: function () {
     this.initializeNewApp();
@@ -39,6 +67,7 @@ App.CreateAppWizardStep2Controller = Ember.ArrayController.extend({
 
   /**
    * Initialize new App to use it scope of controller
+   * @method initializeNewApp
    */
   initializeNewApp: function () {
     var newApp = this.get('appWizardController.newApp');
@@ -47,6 +76,7 @@ App.CreateAppWizardStep2Controller = Ember.ArrayController.extend({
 
   /**
    * Fill <code>content</code> with objects created from <code>App.SliderAppTypeComponent</code>
+   * @method loadTypeComponents
    */
   loadTypeComponents: function () {
     var content = [];
@@ -56,6 +86,7 @@ App.CreateAppWizardStep2Controller = Ember.ArrayController.extend({
         content.push(Ember.Object.create({
           displayName: typeComponent.get('displayName'),
           name: typeComponent.get('name'),
+          priority: typeComponent.get('priority'),
           numInstances: typeComponent.get('defaultNumInstances').toString(),
           yarnMemory: typeComponent.get('defaultYARNMemory').toString(),
           yarnCPU: typeComponent.get('defaultYARNCPU').toString()
@@ -66,38 +97,18 @@ App.CreateAppWizardStep2Controller = Ember.ArrayController.extend({
   }.observes('newApp.appType.components.length'),
 
   /**
-   * Validate all input fields are integer
-   * @return {Boolean}
-   */
-  isError: function () {
-    var result = false;
-    this.get('content').forEach(function (component) {
-      if (!result && (this.isNotInteger(component.get('numInstances')) || this.isNotInteger(component.get('yarnMemory')) || this.isNotInteger(component.get('yarnCPU')))) {
-        result = true;
-      }
-    }, this);
-    return result;
-  }.property('content.@each.numInstances', 'content.@each.yarnMemory', 'content.@each.yarnCPU'),
-
-  /**
    * Check if param is integer
-   * @param value value to check
+   * @param {string} value value to check
    * @return {Boolean}
+   * @method isNotInteger
    */
   isNotInteger: function (value) {
     return !(value.trim().length && (value % 1 == 0));
   },
 
   /**
-   * Define if submit button is disabled
-   * <code>isError</code> should be true
-   */
-  isSubmitDisabled: function () {
-    return this.get('isError');
-  }.property('isError'),
-
-  /**
    * Save all data about components to <code>appWizardController.newApp.components</code>
+   * @method saveComponents
    */
   saveComponents: function () {
     this.set('appWizardController.newApp.components', this.get('content'));
@@ -106,6 +117,7 @@ App.CreateAppWizardStep2Controller = Ember.ArrayController.extend({
   actions: {
     /**
      * Save data and proceed to the next step
+     * @method submit
      */
     submit: function () {
       this.saveComponents();

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step3_controller.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step3_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step3_controller.js
index 8b6ed04..2c34592 100644
--- a/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step3_controller.js
+++ b/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step3_controller.js
@@ -42,13 +42,26 @@ App.CreateAppWizardStep3Controller = Ember.ObjectController.extend({
 
   /**
    * Load all data required for step
+   * @method loadStep
    */
   loadStep: function () {
     this.clearStep();
+    this.initConfigs();
+  },
+
+  /**
+   * Format init value for <code>configs</code> property
+   * @method initConfigs
+   */
+  initConfigs: function() {
+    var c = JSON.stringify(this.get('appWizardController.newApp.configs')).replace(/",/g, '",\n');
+    c = c.substr(1, c.length - 2);
+    this.set('configs', c);
   },
 
   /**
    * Clear all initial data
+   * @method clearStep
    */
   clearStep: function () {
     this.set('isError', false);
@@ -57,6 +70,7 @@ App.CreateAppWizardStep3Controller = Ember.ObjectController.extend({
   /**
    * Validate <code>configs</code> to be key-value formatted amd convert it to object
    * @return {Boolean}
+   * @method validateConfigs
    */
   validateConfigs: function () {
     var self = this;
@@ -74,6 +88,7 @@ App.CreateAppWizardStep3Controller = Ember.ObjectController.extend({
 
   /**
    * Save converted configs to new App configs
+   * @method saveConfigs
    */
   saveConfigs: function () {
     this.set('appWizardController.newApp.configs', this.get('configsObject'));

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step4_controller.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step4_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step4_controller.js
index 3fc5e7d..e703c27 100644
--- a/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step4_controller.js
+++ b/contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step4_controller.js
@@ -29,21 +29,6 @@ App.CreateAppWizardStep4Controller = Ember.ObjectController.extend({
   newApp: null,
 
   /**
-   * Load all required data for step
-   */
-  loadStep: function () {
-    this.initializeNewApp();
-  },
-
-  /**
-   * Initialize new App to use it scope of controller
-   */
-  initializeNewApp: function () {
-    var newApp = this.get('appWizardController.newApp');
-    this.set('newApp', newApp);
-  },
-
-  /**
    * Return formatted configs to show them on preview page
    * @return {String}
    */
@@ -53,58 +38,80 @@ App.CreateAppWizardStep4Controller = Ember.ObjectController.extend({
     if (configs) {
       result = JSON.stringify(configs);
       result = result.substring(1, result.length - 1);
-      result = result.replace(/,/g, ',\n');
+      result = result.replace(/",/g, '",\n');
     }
     return result;
   }.property('newApp.configs'),
 
   /**
    * Return formatted object to send it in request to server
-   * @type {Object}
+   * @type {Object[]}
    */
   componentsFormatted: function () {
-    var result = {};
-    this.get('newApp.components').forEach(function (component) {
-      result[component.get('name')] = {
-        'num_instances': component.get('numInstances'),
-        'yarn_memory': component.get('yarnMemory'),
-        'yarn_cpu': component.get('yarnCPU')
+    return this.get('newApp.components').map(function (component) {
+      return {
+        'id': component.get('name'),
+        'instanceCount': component.get('numInstances'),
+        'yarnMemory': component.get('yarnMemory'),
+        'yarnCpuCores': component.get('yarnCPU'),
+        'priority': component.get('priority')
       };
     });
-    return result;
   }.property('newApp.components.@each'),
 
   /**
+   * Load all required data for step
+   * @method loadStep
+   */
+  loadStep: function () {
+    this.initializeNewApp();
+  },
+
+  /**
+   * Initialize new App to use it scope of controller
+   * @method initializeNewApp
+   */
+  initializeNewApp: function () {
+    var newApp = this.get('appWizardController.newApp');
+    this.set('newApp', newApp);
+  },
+
+  /**
    * Send request to server to deploy new App
    * @return {$.ajax}
+   * @method sendAppDataToServer
    */
   sendAppDataToServer: function () {
-    if (!App.get('testMode')) {
-      var self = this;
-      var app = this.get('newApp');
-      var componentsFormatted = this.get('componentsFormatted');
-      return $.ajax({
-        url: App.get('urlPrefix') + 'apps/',
-        method: 'POST',
-        data: JSON.stringify({
-          type: app.get('appType.index'),
+    var app = this.get('newApp');
+    return App.ajax.send({
+      name: 'createNewApp',
+      sender: this,
+      data: {
+        data: {
+          typeName: app.get('appType.index'),
+          typeVersion: app.get('appType.version'),
           name: app.get('name'),
-          components: componentsFormatted,
-          configs: app.get('configs')
-        }),
-        complete: function () {
-          self.get('appWizardController').hidePopup();
+          typeComponents: this.get('componentsFormatted'),
+          typeConfigs: app.get('configs')
         }
-      });
-    } else {
-      this.get('appWizardController').hidePopup();
-      return true;
-    }
+      },
+      complete: 'sendAppDataToServerCompleteCallback'
+    });
+  },
+
+  /**
+   * Complete-callback for "create new app"-request
+   * @method sendAppDataToServerCompleteCallback
+   */
+  sendAppDataToServerCompleteCallback: function() {
+    this.get('appWizardController').hidePopup();
   },
 
   actions: {
+
     /**
      * Onclick handler for finish button
+     * @method finish
      */
     finish: function () {
       this.sendAppDataToServer();

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/contrib/views/slider/src/main/resources/ui/app/controllers/create_app_wizard_controller.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/create_app_wizard_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/create_app_wizard_controller.js
index fbe0e17..432027c 100644
--- a/contrib/views/slider/src/main/resources/ui/app/controllers/create_app_wizard_controller.js
+++ b/contrib/views/slider/src/main/resources/ui/app/controllers/create_app_wizard_controller.js
@@ -18,41 +18,84 @@
 
 App.CreateAppWizardController = Ember.ObjectController.extend({
 
+  /**
+   * New app created via current wizard
+   * Populated with data step by step
+   * @type {object|null}
+   */
   newApp: null,
 
+  /**
+   * Current step number
+   * @type {number}
+   */
   currentStep: 1,
 
+  /**
+   * Overall steps count
+   * @type {number}
+   */
   TOTAL_STEPS_NUMBER: 4,
 
+  /**
+   * Init controller's data
+   * @method loadStep
+   */
   loadStep: function () {
     this.set('currentStep', 1);
     this.gotoStep(this.get('currentStep'));
   },
 
+  /**
+   * Proceed user to selected step
+   * @param {number} step step's number
+   * @param {bool} fromNextButon is user came from "Next"-button click
+   * @method gotoStep
+   */
   gotoStep: function (step, fromNextButon) {
     if (step > this.get('TOTAL_STEPS_NUMBER') || step < 1 || (!fromNextButon && step > this.get('currentStep'))) {
-      return false;
+      return;
     }
     this.set('currentStep', step);
     this.transitionToRoute('createAppWizard.step' + step);
   },
 
+  /**
+   * Proceed user no next step
+   * @method nextStep
+   */
   nextStep: function () {
     this.gotoStep(this.get('currentStep') + 1, true);
   },
 
+  /**
+   * Proceed user to prev step
+   * @method prevStep
+   */
   prevStep: function () {
     this.gotoStep(this.get('currentStep') - 1);
   },
 
+  /**
+   * Hide wizard-popup
+   * @method hidePopup
+   */
   hidePopup: function () {
     $('#createAppWizard').hide();
+    this.set('newApp', null);
     this.transitionToRoute('slider_apps');
   },
 
   actions: {
+
+    /**
+     * Proceed user to selected step
+     * @param {number} step step's number
+     * @method gotoStep
+     */
     gotoStep: function (step) {
       this.gotoStep(step);
     }
   }
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/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 0652dea..6a383c5 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
@@ -93,16 +93,24 @@ App.SliderAppController = Ember.ObjectController.extend({
    * @method destroy
    */
   destroy: function() {
-    var self = this;
-    return $.ajax({
-      url: App.get('urlPrefix') + 'apps/' + this.get('model.index'),
-      method: 'DELETE',
-      complete: function() {
-        self.transitionToRoute('slider_apps');
-      }
+    return App.ajax.send({
+      name: 'destroyApp',
+      sender: this,
+      data: {
+        id: this.get('model.id')
+      },
+      complete: 'destroyCompleteCallback'
     });
   },
 
+  /**
+   * Complate-callback for "destroy app"-request
+   * @method destroyCompleteCallback
+   */
+  destroyCompleteCallback: function() {
+    this.transitionToRoute('slider_apps');
+  },
+
   actions: {
 
     /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/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
new file mode 100644
index 0000000..d8b3d3b
--- /dev/null
+++ b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
@@ -0,0 +1,188 @@
+/**
+ * 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.
+ */
+
+/**
+ * Config for each ajax-request
+ *
+ * Fields example:
+ *  mock - testMode url
+ *  real - real url (without API prefix)
+ *  type - request type (also may be defined in the format method)
+ *  format - function for processing ajax params after default formatRequest. May be called with one or two parameters (data, opt). Return ajax-params object
+ *  testInProduction - can this request be executed on production tests (used only in tests)
+ *
+ * @type {Object}
+ */
+var urls = {
+
+  'mapper.applicationTypes': {
+    real: 'apptypes?fields=*',
+    mock: '/data/apptypes/all_fields.json'
+  },
+
+  'mapper.applicationApps': {
+    real: 'apps/?fields=*',
+    mock: '/data/apps/apps.json'
+  },
+
+  'mapper.applicationStatus': {
+    real: 'resources/status',
+    mock: '/data/resource/status_true.json'
+  },
+
+  'createNewApp': {
+    real: 'apps',
+    mock: '',
+    format: function(data) {
+      return {
+        type: 'POST',
+        data: JSON.stringify(data.data)
+      }
+    }
+  },
+
+  'destroyApp': {
+    real: 'apps/{id}',
+    mock: '',
+    format: function() {
+      return {
+        method: 'DELETE'
+      }
+    }
+  }
+};
+/**
+ * Replace data-placeholders to its values
+ *
+ * @param {String} url
+ * @param {Object} data
+ * @return {String}
+ */
+var formatUrl = function (url, data) {
+  if (!url) return null;
+  var keys = url.match(/\{\w+\}/g);
+  keys = (keys === null) ? [] : keys;
+  if (keys) {
+    keys.forEach(function (key) {
+      var raw_key = key.substr(1, key.length - 2);
+      var replace;
+      if (!data || !data[raw_key]) {
+        replace = '';
+      }
+      else {
+        replace = data[raw_key];
+      }
+      url = url.replace(new RegExp(key, 'g'), replace);
+    });
+  }
+  return url;
+};
+
+/**
+ * this = object from config
+ * @return {Object}
+ */
+var formatRequest = function (data) {
+  var opt = {
+    type: this.type || 'GET',
+    dataType: 'json',
+    async: true
+  };
+  if (App.get('testMode')) {
+    opt.url = formatUrl(this.mock ? this.mock : '', data);
+    opt.type = 'GET';
+  }
+  else {
+    var prefix = App.get('urlPrefix');
+    opt.url = prefix + formatUrl(this.real, data);
+  }
+
+  if (this.format) {
+    jQuery.extend(opt, this.format(data, opt));
+  }
+  return opt;
+};
+
+/**
+ * Wrapper for all ajax requests
+ *
+ * @type {Object}
+ */
+var ajax = Em.Object.extend({
+  /**
+   * Send ajax request
+   *
+   * @param {Object} config
+   * @return {$.ajax} jquery ajax object
+   *
+   * config fields:
+   *  name - url-key in the urls-object *required*
+   *  sender - object that send request (need for proper callback initialization) *required*
+   *  data - object with data for url-format
+   *  beforeSend - method-name for ajax beforeSend response callback
+   *  success - method-name for ajax success response callback
+   *  error - method-name for ajax error response callback
+   *  callback - callback from <code>App.updater.run</code> library
+   */
+  send: function (config) {
+
+    Ember.assert('Ajax sender should be defined!', config.sender);
+    Ember.assert('Invalid config.name provided - ' + config.name, urls[config.name]);
+
+    var opt = {},
+      params = {};
+
+    if (config.data) {
+      jQuery.extend(params, config.data);
+    }
+
+    opt = formatRequest.call(urls[config.name], params);
+    opt.context = this;
+
+    // object sender should be provided for processing beforeSend, success, error and complete responses
+    opt.beforeSend = function (xhr) {
+      if (config.beforeSend) {
+        config.sender[config.beforeSend](opt, xhr, params);
+      }
+    };
+
+    opt.success = function (data) {
+      console.log("TRACE: The url is: " + opt.url);
+      if (config.success) {
+        config.sender[config.success](data, opt, params);
+      }
+    };
+
+    opt.error = function (request, ajaxOptions, error) {
+      if (config.error) {
+        config.sender[config.error](request, ajaxOptions, error, opt, params);
+      }
+    };
+
+    opt.complete = function (xhr, status) {
+      if (config.complete) {
+        config.sender[config.complete](xhr, status);
+      }
+    };
+
+    return $.ajax(opt);
+  }
+
+});
+
+App.ajax = ajax.create({});

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/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 675b8c7..40a6edf 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,13 +24,6 @@
 App.ApplicationStatusMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
 
   /**
-   * Url suffix
-   * Used with <code>App.urlPrefix</code>
-   * @type {string}
-   */
-  urlSuffix: 'resources/status',
-
-  /**
    * Map for parsing JSON received from server
    * Format:
    *  <code>
@@ -57,14 +50,10 @@ App.ApplicationStatusMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
    */
   load: function() {
     console.log('App.ApplicationStatusMapper loading data');
-    var self = this,
-      url = App.get('testMode') ? '/data/resource/status_true.json' : App.get('urlPrefix') + this.get('urlSuffix');
-
-    return $.ajax({
-      url: url,
-      dataType: 'json',
-      async: true,
-      success: function(data) {self.parse(data);}
+    return App.ajax.send({
+      name: 'mapper.applicationStatus',
+      sender: this,
+      success: 'parse'
     });
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/contrib/views/slider/src/main/resources/ui/app/mappers/application_type.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/mappers/application_type.js b/contrib/views/slider/src/main/resources/ui/app/mappers/application_type.js
index b737d9b..938412e 100644
--- a/contrib/views/slider/src/main/resources/ui/app/mappers/application_type.js
+++ b/contrib/views/slider/src/main/resources/ui/app/mappers/application_type.js
@@ -37,13 +37,6 @@
 App.ApplicationTypeMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
 
   /**
-   * Url suffix
-   * Used with <code>App.urlPrefix</code>
-   * @type {string}
-   */
-  urlSuffix: 'apptypes?fields=*',
-
-  /**
    * Map for parsing JSON received from server
    * Format:
    *  <code>
@@ -63,6 +56,7 @@ App.ApplicationTypeMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
     displayName: 'typeName',
     index: 'id',
     description: 'typeDescription',
+    version: 'typeVersion',
     /**
      * Map array to nested models
      * Use <code>('$components').replace('$', '') + 'Map'</code> property as map
@@ -81,7 +75,8 @@ App.ApplicationTypeMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
     displayName: 'displayName',
     defaultNumInstances: 'instanceCount',
     defaultYARNMemory: 'yarnMemory',
-    defaultYARNCPU: 'yarnCpuCores'
+    defaultYARNCPU: 'yarnCpuCores',
+    priority: 'priority'
   },
 
   /**
@@ -103,14 +98,10 @@ App.ApplicationTypeMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
    */
   load: function() {
     console.log('App.ApplicationTypeMapper loading data');
-    var self = this,
-      url = App.get('testMode') ? '/data/apptypes/all_fields.json' : App.get('urlPrefix') + this.get('urlSuffix');
-
-    return $.ajax({
-      url: url,
-      dataType: 'json',
-      async: true,
-      success: function(data) {self.parse(data);}
+    return App.ajax.send({
+      name: 'mapper.applicationTypes',
+      sender: this,
+      success: 'parse'
     });
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/contrib/views/slider/src/main/resources/ui/app/mappers/mapper.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/mappers/mapper.js b/contrib/views/slider/src/main/resources/ui/app/mappers/mapper.js
index d5c79a4..2f985eb 100644
--- a/contrib/views/slider/src/main/resources/ui/app/mappers/mapper.js
+++ b/contrib/views/slider/src/main/resources/ui/app/mappers/mapper.js
@@ -24,13 +24,6 @@
 App.Mapper = Ember.Object.extend({
 
   /**
-   * Url suffix
-   * Used with <code>App.urlPrefix</code>
-   * @type {string}
-   */
-  urlSuffix: '',
-
-  /**
    * Map for parsing JSON received from server
    * Format:
    *  <code>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/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 4127e20..c791a23 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
@@ -23,26 +23,15 @@
 App.SliderAppsMapper = App.Mapper.createWithMixins(App.RunPeriodically, {
 
   /**
-   * Url suffix
-   * Used with <code>App.urlPrefix</code>
-   * @type {string}
-   */
-  urlSuffix: 'apps/?fields=*',
-
-  /**
    * Load data from <code>App.urlPrefix + this.urlSuffix</code> one time
    * @method load
    * @return {$.ajax}
    */
   load: function() {
-    var self = this,
-      url = App.get('testMode') ? '/data/apps/apps.json' : App.get('urlPrefix') + this.get('urlSuffix');
-
-    return $.ajax({
-      url: url,
-      dataType: 'json',
-      async: true,
-      success: function(data) {self.parse(data);}
+    return App.ajax.send({
+      name: 'mapper.applicationApps',
+      sender: this,
+      success: 'parse'
     });
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/contrib/views/slider/src/main/resources/ui/app/models/slider_app_type.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/models/slider_app_type.js b/contrib/views/slider/src/main/resources/ui/app/models/slider_app_type.js
index 9415429..fd58384 100644
--- a/contrib/views/slider/src/main/resources/ui/app/models/slider_app_type.js
+++ b/contrib/views/slider/src/main/resources/ui/app/models/slider_app_type.js
@@ -39,9 +39,14 @@ App.SliderAppType = DS.Model.extend({
   description: DS.attr('string'),
 
   /**
+   * @type {string}
+   */
+  version: DS.attr('string'),
+
+  /**
    * @type {object}
    */
-  configs: {}
+  configs: DS.attr('object')
 
 });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4240405/contrib/views/slider/src/main/resources/ui/app/models/slider_app_type_component.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/models/slider_app_type_component.js b/contrib/views/slider/src/main/resources/ui/app/models/slider_app_type_component.js
index 50edd18..1576b04 100644
--- a/contrib/views/slider/src/main/resources/ui/app/models/slider_app_type_component.js
+++ b/contrib/views/slider/src/main/resources/ui/app/models/slider_app_type_component.js
@@ -51,7 +51,12 @@ App.SliderAppTypeComponent = DS.Model.extend({
   /**
    * @type {App.SliderAppType}
    */
-  appType: DS.belongsTo('sliderAppType')
+  appType: DS.belongsTo('sliderAppType'),
+
+  /**
+   * @type {number}
+   */
+  priority: DS.attr('string')
 
 });