You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2013/02/22 09:11:16 UTC
svn commit: r1448926 - in /incubator/ambari/trunk: CHANGES.txt
ambari-web/app/controllers/global/background_operations_controller.js
ambari-web/app/controllers/main/service/item.js
ambari-web/app/initialize.js ambari-web/app/utils/ajax.js
Author: yusaku
Date: Fri Feb 22 08:11:16 2013
New Revision: 1448926
URL: http://svn.apache.org/r1448926
Log:
AMBARI-1471. Refactor ajax calls. (yusaku)
Added:
incubator/ambari/trunk/ambari-web/app/utils/ajax.js
Modified:
incubator/ambari/trunk/CHANGES.txt
incubator/ambari/trunk/ambari-web/app/controllers/global/background_operations_controller.js
incubator/ambari/trunk/ambari-web/app/controllers/main/service/item.js
incubator/ambari/trunk/ambari-web/app/initialize.js
Modified: incubator/ambari/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1448926&r1=1448925&r2=1448926&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Fri Feb 22 08:11:16 2013
@@ -51,6 +51,8 @@ Trunk (unreleased changes):
IMPROVEMENTS
+ AMBARI-1471. Refactor ajax calls. (yusaku)
+
AMBARI-1461. Optimize query for getting service and host component status back
from the server. (yusaku)
Modified: incubator/ambari/trunk/ambari-web/app/controllers/global/background_operations_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/global/background_operations_controller.js?rev=1448926&r1=1448925&r2=1448926&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/global/background_operations_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/global/background_operations_controller.js Fri Feb 22 08:11:16 2013
@@ -41,15 +41,6 @@ App.BackgroundOperationsController = Em.
updateInterval: App.bgOperationsUpdateInterval,
url : '',
- generateUrl: function(){
- var url = App.testMode ?
- '/data/background_operations/list_on_start.json' :
- App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/requests/?fields=tasks/*';
-
- this.set('url', url);
- return url;
- },
-
timeoutId : null,
/**
@@ -100,39 +91,30 @@ App.BackgroundOperationsController = Em.
if(!this.get('isWorking')){
return;
}
- var self = this;
if(!App.router.getClusterName()){
this.loadOperationsDelayed(this.get('updateInterval')/2, 'error:clusterName');
return;
}
- var url = this.get('url');
- if(!url){
- url = this.generateUrl();
- }
-
- $.ajax({
- type: "GET",
- url: url,
- dataType: 'json',
- timeout: App.timeout,
- success: function (data) {
- //refresh model
- self.updateBackgroundOperations(data);
-
- self.loadOperationsDelayed();
- },
-
- error: function (request, ajaxOptions, error) {
- self.loadOperationsDelayed(null, 'error:response error');
- },
+ App.ajax.send({
+ 'name': 'background_operations',
+ 'sender': this,
+ 'success': 'ajaxSuccess', //todo provide interfaces for strings and functions
+ 'error': 'ajaxError'
+ })
- statusCode: require('data/statusCodes')
- });
}.observes('isWorking'),
+ ajaxSuccess: function(data) {
+ this.updateBackgroundOperations(data);
+ this.loadOperationsDelayed();
+ },
+ ajaxError: function(request, ajaxOptions, error) {
+ this.loadOperationsDelayed(null, 'error:response error');
+ },
+
/**
* Update info about background operations
* Put all tasks with command 'EXECUTE' into <code>executeTasks</code>, other tasks with it they are still running put into <code>runningTasks</code>
Modified: incubator/ambari/trunk/ambari-web/app/controllers/main/service/item.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/main/service/item.js?rev=1448926&r1=1448925&r2=1448926&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/main/service/item.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/main/service/item.js Fri Feb 22 08:11:16 2013
@@ -22,89 +22,106 @@ App.MainServiceItemController = Em.Contr
name: 'mainServiceItemController',
/**
- * Send specific command to server
- * @param url
- * @param data Object to send
- */
- sendCommandToServer : function(url, method, postData, callback){
- var url = (App.testMode) ?
- '/data/wizard/deploy/poll_1.json' : //content is the same as ours
- App.apiPrefix + '/clusters/' + App.router.getClusterName() + url;
-
- method = App.testMode ? 'GET' : method;
-
- $.ajax({
- type: method,
- url: url,
- data: (postData != null) ? JSON.stringify(postData) : null,
- dataType: 'json',
- timeout: App.timeout,
- success: function(data){
- if(data && data.Requests){
- callback(data.Requests.id);
- } else{
- callback(null);
- console.log('cannot get request id from ', data);
+ * Callback functions for start and stop service have few differences
+ *
+ * Used with currentCallBack property
+ */
+ callBackConfig: {
+ 'STARTED': {
+ 'c': 'STARTING',
+ 'f': 'starting',
+ 'c2': 'live',
+ 'hs': 'started',
+ 's': 'start'
+ },
+ 'INSTALLED': {
+ 'c': 'STOPPING',
+ 'f': 'stopping',
+ 'c2': 'dead',
+ 'hs': 'stopped',
+ 's': 'stop'
+ }
+ },
+ /**
+ * Success ajax response processing
+ * @param data
+ * @param ajaxOptions
+ */
+ ajaxSuccess: function(data, ajaxOptions) {
+ if(data && data.Requests) {
+ this.ajaxCallBack(data.Requests.id, (JSON.parse(ajaxOptions.data)).ServiceInfo.state);
+ }
+ else {
+ console.log('cannot get request id from ', data);
+ }
+ },
+ /**
+ * Common method for ajax (start/stop service) responses
+ * @param requestId
+ * @param serviceHealth
+ */
+ ajaxCallBack: function(requestId, serviceHealth) {
+ var config = this.get('callBackConfig')[serviceHealth];
+ var self = this;
+ console.log('Send request for ' + config.c + ' successfully');
+ if (App.testMode) {
+ self.set('content.workStatus', App.Service.Health[config.f]);
+ self.get('content.hostComponents').setEach('workStatus', App.HostComponentStatus[config.f]);
+ setTimeout(function () {
+ self.set('content.workStatus', App.Service.Health[config.c2]);
+ self.get('content.hostComponents').setEach('workStatus', App.HostComponentStatus[config.hs]);
+ }, App.testModeDelayForActions);
+ }
+ else {
+ App.router.get('clusterController').loadUpdatedStatusDelayed(500);// @todo check working without param 500
+ App.router.get('backgroundOperationsController.eventsArray').push({
+ "when": function (controller) {
+ var result = (controller.getOperationsForRequestId(requestId).length == 0);
+ console.log(config.s + 'Service.when = ', result)
+ return result;
+ },
+ "do": function () {
+ App.router.get('clusterController').loadUpdatedStatus();
}
- },
-
- error: function (request, ajaxOptions, error) {
- //do something
- callback(null);
- console.log('error on change component host status')
- },
-
- statusCode: require('data/statusCodes')
- });
+ });
+ }
+ App.router.get('backgroundOperationsController').showPopup();
},
-
/**
- * On click callback for <code>start service</code> button
+ * Confirmation popup for start/stop services
* @param event
+ * @param serviceHealth - 'STARTED' or 'INSTALLED'
*/
- startService: function (event) {
+ startStopPopup: function(event, serviceHealth) {
if ($(event.target).hasClass('disabled') || $(event.target.parentElement).hasClass('disabled')) {
return;
}
-
var self = this;
- App.showConfirmationPopup(function(){
- self.sendCommandToServer('/services/' + self.get('content.serviceName').toUpperCase(), "PUT", {
- ServiceInfo: {
- state: 'STARTED'
- }
- }, function (requestId) {
-
- if (!requestId) {
- return;
- }
- console.log('Send request for STARTING successfully');
+ App.showConfirmationPopup(function() {
+ self.startStopPopupPrimary(serviceHealth);
+ });
+ },
- if (App.testMode) {
- self.set('content.workStatus', App.Service.Health.starting);
- self.get('content.hostComponents').setEach('workStatus', App.HostComponentStatus.starting);
- setTimeout(function () {
- self.set('content.workStatus', App.Service.Health.live);
- self.get('content.hostComponents').setEach('workStatus', App.HostComponentStatus.started);
- }, App.testModeDelayForActions);
- } else {
- App.router.get('clusterController').loadUpdatedStatusDelayed(500);
- App.router.get('backgroundOperationsController.eventsArray').push({
- "when": function (controller) {
- var result = (controller.getOperationsForRequestId(requestId).length == 0);
- console.log('startService.when = ', result)
- return result;
- },
- "do": function () {
- App.router.get('clusterController').loadUpdatedStatus();
- }
- });
- }
- App.router.get('backgroundOperationsController').showPopup();
- });
- self.set('content.isStopDisabled',true);
- self.set('content.isStartDisabled',true);
+ startStopPopupPrimary: function(serviceHealth) {
+ App.ajax.send({
+ 'name': 'service.item.start_stop',
+ 'sender': this,
+ 'success': 'ajaxSuccess',
+ 'data': {
+ 'serviceName': this.get('content.serviceName').toUpperCase(),
+ 'state': serviceHealth
+ }
});
+ this.set('content.isStopDisabled',true);
+ this.set('content.isStartDisabled',true);
+ },
+
+ /**
+ * On click callback for <code>start service</code> button
+ * @param event
+ */
+ startService: function (event) {
+ this.startStopPopup(event, App.HostComponentStatus.started);
},
/**
@@ -112,46 +129,7 @@ App.MainServiceItemController = Em.Contr
* @param event
*/
stopService: function (event) {
- if ($(event.target).hasClass('disabled') || $(event.target.parentElement).hasClass('disabled')) {
- return;
- }
-
- var self = this;
- App.showConfirmationPopup(function(){
- self.sendCommandToServer('/services/' + self.get('content.serviceName').toUpperCase(), "PUT",{
- ServiceInfo:{
- state: 'INSTALLED'
- }
- }, function (requestId) {
- if (!requestId) {
- return
- }
- console.log('Send request for STOPPING successfully');
- if (App.testMode) {
- self.set('content.workStatus', App.Service.Health.stopping);
- self.get('content.hostComponents').setEach('workStatus', App.HostComponentStatus.stopping);
- setTimeout(function () {
- self.set('content.workStatus', App.Service.Health.dead);
- self.get('content.hostComponents').setEach('workStatus', App.HostComponentStatus.stopped);
- }, App.testModeDelayForActions);
- } else {
- App.router.get('clusterController').loadUpdatedStatusDelayed(500);
- App.router.get('backgroundOperationsController.eventsArray').push({
- "when": function (controller) {
- var result = (controller.getOperationsForRequestId(requestId).length == 0);
- console.log('stopService.when = ', result)
- return result;
- },
- "do": function () {
- App.router.get('clusterController').loadUpdatedStatus();
- }
- });
- }
- App.router.get('backgroundOperationsController').showPopup();
- });
- self.set('content.isStopDisabled',true);
- self.set('content.isStartDisabled',true);
- });
+ this.startStopPopup(event, App.HostComponentStatus.stopped);
},
/**
@@ -161,8 +139,8 @@ App.MainServiceItemController = Em.Contr
runRebalancer: function (event) {
var self = this;
App.showConfirmationPopup(function() {
- self.content.set('runRebalancer', true);
- App.router.get('backgroundOperationsController').showPopup();
+ self.content.set('runRebalancer', true);
+ App.router.get('backgroundOperationsController').showPopup();
});
},
@@ -173,8 +151,8 @@ App.MainServiceItemController = Em.Contr
runCompaction: function (event) {
var self = this;
App.showConfirmationPopup(function() {
- self.content.set('runCompaction', true);
- App.router.get('backgroundOperationsController').showPopup();
+ self.content.set('runCompaction', true);
+ App.router.get('backgroundOperationsController').showPopup();
});
},
@@ -184,23 +162,31 @@ App.MainServiceItemController = Em.Contr
*/
runSmokeTest: function (event) {
var self = this;
- App.showConfirmationPopup(function(){
- var serviceName = self.get('content.serviceName').toUpperCase();
- var smokeName = serviceName + "_SERVICE_CHECK";
- self.sendCommandToServer('/services/' + serviceName + '/actions/' + smokeName, "POST",
- null,
- function (requestId) {
-
- if (!requestId) {
- return;
- }
- self.content.set('runSmokeTest', true);
- App.router.get('backgroundOperationsController').showPopup();
- }
- );
+ App.showConfirmationPopup(function() {
+ self.runSmokeTestPrimary();
});
},
+ runSmokeTestPrimary: function() {
+ App.ajax.send({
+ 'name': 'service.item.smoke',
+ 'sender': this,
+ 'success':'runSmokeTestSuccessCallBack',
+ 'data': {
+ 'serviceName': this.get('content.serviceName').toUpperCase()
+ }
+ });
+ },
+
+ runSmokeTestSuccessCallBack: function(data) {
+ if (data.Requests.id) {
+ App.router.get('backgroundOperationsController').showPopup();
+ }
+ else {
+ console.warn('error during runSmokeTestSuccessCallBack');
+ }
+ },
+
/**
* On click callback for <code>Reassign <master component></code> button
* @param hostComponent
Modified: incubator/ambari/trunk/ambari-web/app/initialize.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/initialize.js?rev=1448926&r1=1448925&r2=1448926&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/initialize.js (original)
+++ incubator/ambari/trunk/ambari-web/app/initialize.js Fri Feb 22 08:11:16 2013
@@ -31,6 +31,8 @@ require('templates');
require('views');
require('router');
+require('utils/ajax');
+
require('mappers/server_data_mapper');
require('mappers/status_mapper');
require('mappers/hosts_mapper');
@@ -46,6 +48,11 @@ require('utils/http_client');
App.initialize();
+/**
+ * Test Mode values
+ */
+App.test_hostname = 'hostname';
+
console.log('after initialize');
console.log('TRACE: app.js-> localStorage:Ambari.authenticated=' + localStorage.getItem('Ambari' + 'authenticated'));
console.log('TRACE: app.js-> localStorage:currentStep=' + localStorage.getItem(App.get('router').getLoginName() + 'Installer' + 'currentStep'));
Added: incubator/ambari/trunk/ambari-web/app/utils/ajax.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/utils/ajax.js?rev=1448926&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/utils/ajax.js (added)
+++ incubator/ambari/trunk/ambari-web/app/utils/ajax.js Fri Feb 22 08:11:16 2013
@@ -0,0 +1,156 @@
+/**
+ * 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');
+
+/**
+ * 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. Return ajax-params object
+ * testInProduction - can this request be executed on production tests (used only in tests)
+ *
+ * @type {Object}
+ */
+var urls = {
+ 'background_operations': {
+ 'mock': '/data/background_operations/list_on_start.json',
+ 'real': '/clusters/{clusterName}/requests/?fields=tasks/*',
+ 'testInProduction': true
+ },
+ 'service.item.start_stop': {
+ 'mock': '/data/wizard/deploy/poll_1.json',
+ 'real': '/clusters/{clusterName}/services/{serviceName}',
+ 'format': function (data, opt) {
+ return {
+ type: 'PUT',
+ data: JSON.stringify({
+ ServiceInfo: {
+ state: data.state
+ }
+ })
+ };
+ }
+ },
+ 'service.item.smoke': {
+ 'mock': '/data/wizard/deploy/poll_1.json',
+ 'real': '/clusters/{clusterName}/services/{serviceName}/actions/{serviceName}_SERVICE_CHECK',
+ 'type': 'POST'
+ }
+};
+/**
+ * Replace data-placeholders to its values
+ *
+ * @param {String} url
+ * @param {Object} data
+ * @return {String}
+ */
+var formatUrl = function(url, data) {
+ var keys = url.match(/\{\w+\}/g);
+ keys.forEach(function(key){
+ var raw_key = key.substr(1, key.length - 2);
+ var replace;
+ if (!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',
+ timeout : App.timeout,
+ dataType: 'json',
+ statusCode: require('data/statusCodes')
+ };
+ if(App.testMode) {
+ opt.url = this.mock;
+ }
+ else {
+ opt.url = App.apiPrefix + formatUrl(this.real, data);
+ }
+
+ if(this.format) {
+ jQuery.extend(opt, this.format(data, opt));
+ }
+ return opt;
+};
+
+/**
+ * Wrapper for all ajax requests
+ *
+ * @type {Object}
+ */
+App.ajax = {
+ /**
+ * Send ajax request
+ *
+ * @param {Object} config
+ * @return {Boolean}
+ *
+ * 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
+ * success - method-name for ajax success response callback
+ * error - method-name for ajax error response callback
+ */
+ send: function(config) {
+ if (!config.sender) {
+ console.warn('Ajax sender should be defined!');
+ return false;
+ }
+
+ // default parameters
+ var params = {
+ clusterName: App.router.get('clusterController.clusterName')
+ };
+
+ // extend default parameters with provided
+ if (config.data) {
+ jQuery.extend(params, config.data);
+ }
+
+ var opt = {};
+ opt = formatRequest.call(urls[config.name], params);
+
+ // object sender should be provided for processing success and error responses
+ opt.success = function(data) {
+ if(config.success) {
+ config.sender[config.success](data, opt);
+ }
+ };
+ opt.error = function(request, ajaxOptions, error) {
+ if (config.error) {
+ config.sender[config.error](request, ajaxOptions, error, opt);
+ }
+ };
+ $.ajax(opt);
+ }
+}