blob: 9cc35f3cac10dcad24df4b9f172dae955b25a54b [file] [log] [blame]
/**
* 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');
var filters = require('views/common/filter_view');
App.MainDashboardView = Em.View.extend({
templateName:require('templates/main/dashboard'),
didInsertElement:function () {
this.services();
this.setWidgetsDataModel();
this.setInitPrefObject();
this.setOnLoadVisibleWidgets();
this.set('isDataLoaded',true);
Ember.run.next(this, 'makeSortable');
},
content:[],
isDataLoaded: false,
isClassicDashboard: false,
makeSortable: function () {
var self = this;
$( "#sortable" ).sortable({
items: "> div",
//placeholder: "sortable-placeholder",
cursor: "move",
update: function (event, ui) {
if (!App.testMode) {
// update persist then translate to real
var widgetsArray = $('div[viewid]'); // get all in DOM
self.getUserPref(self.get('persistKey'));
var oldValue = self.get('currentPrefObject');
var newValue = Em.Object.create({
dashboardVersion: oldValue.dashboardVersion,
visible: [],
hidden: oldValue.hidden,
threshold: oldValue.threshold
});
var size = oldValue.visible.length;
for(var j = 0; j <= size -1; j++){
var viewID = widgetsArray.get(j).getAttribute('viewid');
var id = viewID.split("-").get(1);
newValue.visible.push(id);
}
self.postUserPref(self.get('persistKey'), newValue);
//self.translateToReal(newValue);
}
}
});
$( "#sortable" ).disableSelection();
},
setWidgetsDataModel: function () {
var services = App.Service.find();
var self = this;
services.forEach(function (item) {
switch (item.get('serviceName')) {
case "HDFS":
self.set('hdfs_model', App.HDFSService.find(item.get('id')) || item);
break;
case "YARN":
self.set('yarn_model', App.YARNService.find(item.get('id')) || item);
break;
case "MAPREDUCE":
self.set('mapreduce_model', App.MapReduceService.find(item.get('id')) || item);
break;
case "HBASE":
self.set('hbase_model', App.HBaseService.find(item.get('id')) || item);
break;
}
}, this);
},
setInitPrefObject: function() {
//in case of some service not installed
var visibleFull = [
'2', '4', '8', '10',
'17', '11', '12', '13', '14',
'18', '1', '6', '5', '9',
'3', '7', '15', '16', '20',
'19', '21', '23',
'24', '25', '26', '27'// all yarn
]; // all in order
var hiddenFull = [['22','Region In Transition']];
if (this.get('hdfs_model') == null) {
var hdfs= ['1', '2', '3', '4', '5', '15', '17'];
hdfs.forEach ( function (item) {
visibleFull = visibleFull.without(item);
}, this);
}
if (this.get('mapreduce_model') == null) {
var map = ['6', '7', '8', '9', '10', '16', '18'];
map.forEach ( function (item) {
visibleFull = visibleFull.without(item);
}, this);
}
if (this.get('hbase_model') == null) {
var hbase = ['19', '20', '21', '23'];
hbase.forEach ( function (item) {
visibleFull = visibleFull.without(item);
}, this);
hiddenFull = [];
}if (this.get('yarn_model') == null) {
var yarn = ['24', '25', '26', '27'];
yarn.forEach ( function (item) {
visibleFull = visibleFull.without(item);
}, this);
}
var obj = this.get('initPrefObject');
obj.set('visible', visibleFull);
obj.set('hidden', hiddenFull);
},
hdfs_model: null,
mapreduce_model: null,
mapreduce2_model: null,
yarn_model: null,
hbase_model: null,
visibleWidgets: [],
hiddenWidgets: [], // widget child view will push object in this array if deleted
plusButtonFilterView: filters.createComponentView({
/**
* Base methods was implemented in <code>filters.componentFieldView</code>
*/
hiddenWidgetsBinding: 'parentView.hiddenWidgets',
visibleWidgetsBinding: 'parentView.visibleWidgets',
layout: null,
filterView: filters.componentFieldView.extend({
templateName:require('templates/main/dashboard/plus_button_filter'),
hiddenWidgetsBinding: 'parentView.hiddenWidgets',
visibleWidgetsBinding: 'parentView.visibleWidgets',
valueBinding: '',
applyFilter:function() {
this._super();
var parent = this.get('parentView').get('parentView');
var hiddenWidgets = this.get('hiddenWidgets');
var checkedWidgets = hiddenWidgets.filterProperty('checked', true);
if (App.testMode) {
var visibleWidgets = this.get('visibleWidgets');
checkedWidgets.forEach(function(item){
var newObj = parent.widgetsMapper(item.id);
visibleWidgets.pushObject(newObj);
hiddenWidgets.removeObject(item);
}, this);
} else {
//save in persist
parent.getUserPref(parent.get('persistKey'));
var oldValue = parent.get('currentPrefObject');
var newValue = Em.Object.create({
dashboardVersion: oldValue.dashboardVersion,
visible: oldValue.visible,
hidden: [],
threshold: oldValue.threshold
});
checkedWidgets.forEach(function(item){
newValue.visible.push(item.id);
hiddenWidgets.removeObject(item);
}, this);
hiddenWidgets.forEach(function(item){
newValue.hidden.push([item.id, item.displayName]);
}, this);
parent.postUserPref(parent.get('persistKey'), newValue);
parent.translateToReal(newValue);
}
}
})
}),
/**
* translate from Json value got from persist to real widgets view
*/
translateToReal: function (value) {
var version = value.dashboardVersion;
var visible = value.visible;
var hidden = value.hidden;
var threshold = value.threshold;
if (version == 'classic') {
this.set('isClassicDashboard', true);
} else if (version == 'new') {
this.set('isClassicDashboard', false);
var visibleWidgets = [];
var hiddenWidgets = [];
// re-construct visibleWidgets and hiddenWidgets
for (var j = 0; j <= visible.length -1; j++) {
var id = visible[j];
var widgetClass = this.widgetsMapper(id);
//override with new threshold
if (threshold[id].length > 0) {
widgetClass.reopen({
thresh1: threshold[id][0],
thresh2: threshold[id][1]
});
}
visibleWidgets.pushObject(widgetClass);
}
for (var j = 0; j <= hidden.length -1; j++) {
var id = hidden[j][0];
var title = hidden[j][1];
hiddenWidgets.pushObject(Em.Object.create({displayName:title , id: id, checked: false}));
}
this.set('visibleWidgets', visibleWidgets);
this.set('hiddenWidgets', hiddenWidgets);
}
},
setOnLoadVisibleWidgets: function () {
if (App.testMode) {
this.translateToReal(this.get('initPrefObject'));
} else {
// called when first load/refresh/jump back page
this.getUserPref(this.get('persistKey'));
var currentPrefObject = this.get('currentPrefObject');
if (currentPrefObject) { // fit for no dashboard version
if (!currentPrefObject.dashboardVersion) {
currentPrefObject.dashboardVersion = 'new';
this.postUserPref(this.get('persistKey'), currentPrefObject);
}
this.set('currentPrefObject', this.checkServicesChange(currentPrefObject));
this.translateToReal(this.get('currentPrefObject'));
} else {
// post persist then translate init object
if(App.get('isAdmin')) {
this.postUserPref(this.get('persistKey'), this.get('initPrefObject'));
}
this.translateToReal(this.get('initPrefObject'));
}
}
},
removeWidget: function (value, itemToRemove) {
value.visible = value.visible.without(itemToRemove);
for (var j = 0; j <= value.hidden.length -1; j++) {
if (value.hidden[j][0] == itemToRemove) {
value.hidden.splice(j, 1);
}
}
return value;
},
containsWidget: function (value, item) {
var flag = value.visible.contains (item);
for (var j = 0; j <= value.hidden.length -1; j++) {
if ( !flag && value.hidden[j][0] == item) {
flag = true;
break;
}
}
return flag;
},
/**
* check if stack has upgraded from HDP 1.0 to 2.0 OR add/delete services.
* Update the value on server if true.
*/
checkServicesChange: function (currentPrefObject) {
var toDelete = $.extend(true, {}, currentPrefObject);
var toAdd = [];
var self = this;
// check each service, find out the newly added service and already deleted service
if (this.get('hdfs_model') != null) {
var hdfsAndMetrics= ['1', '2', '3', '4', '5', '15', '17', '11', '12', '13', '14'];
hdfsAndMetrics.forEach ( function (item) {
toDelete = self.removeWidget(toDelete, item);
}, this);
}
if (this.get('mapreduce_model') != null) {
var map = ['6', '7', '8', '9', '10', '16', '18'];
var flag = self.containsWidget(toDelete, map[0]);
if (flag) {
map.forEach ( function (item) {
toDelete = self.removeWidget(toDelete, item);
}, this);
} else {
toAdd = toAdd.concat(map);
}
}
if (this.get('hbase_model') != null) {
var hbase = ['19', '20', '21', '22', '23'];
var flag = self.containsWidget(toDelete, hbase[0]);
if (flag) {
hbase.forEach ( function (item) {
toDelete = self.removeWidget(toDelete, item);
}, this);
} else {
toAdd = toAdd.concat(hbase);
}
}
if (this.get('yarn_model') != null) {
var yarn = ['24', '25', '26', '27'];
var flag = self.containsWidget(toDelete, yarn[0]);
if (flag) {
yarn.forEach ( function (item) {
toDelete = self.removeWidget(toDelete, item);
}, this);
} else {
toAdd = toAdd.concat(yarn);
}
}
var value = currentPrefObject;
if (toDelete.visible.length || toDelete.hidden.length) {
toDelete.visible.forEach ( function (item) {
value = self.removeWidget(value, item);
}, this);
toDelete.hidden.forEach ( function (item) {
value = self.removeWidget(value, item[0]);
}, this);
}
if (toAdd.length) {
value.visible = value.visible.concat(toAdd);
var allThreshold = this.get('initPrefObject').threshold;
// add new threshold OR override with default value
toAdd.forEach ( function (item) {
value.threshold[item] = allThreshold[item];
}, this);
}
return value;
},
widgetsMapper: function (id) {
switch(id){
case '1': return App.NameNodeHeapPieChartView;
case '2': return App.NameNodeCapacityPieChartView;
case '3': return App.NameNodeCpuPieChartView;
case '4': return App.DataNodeUpView;
case '5': return App.NameNodeRpcView;
case '6': return App.JobTrackerHeapPieChartView;
case '7': return App.JobTrackerCpuPieChartView;
case '8': return App.TaskTrackerUpView;
case '9': return App.JobTrackerRpcView;
case '10': return App.MapReduceSlotsView;
case '11': return App.ChartClusterMetricsMemoryWidgetView;
case '12': return App.ChartClusterMetricsNetworkWidgetView;
case '13': return App.ChartClusterMetricsCPUWidgetView;
case '14': return App.ChartClusterMetricsLoadWidgetView;
case '15': return App.NameNodeUptimeView;
case '16': return App.JobTrackerUptimeView;
case '17': return App.HDFSLinksView;
case '18': return App.MapReduceLinksView;
case '19': return App.HBaseLinksView;
case '20': return App.HBaseMasterHeapPieChartView;
case '21': return App.HBaseAverageLoadView;
case '22': return App.HBaseRegionsInTransitionView;
case '23': return App.HBaseMasterUptimeView;
case '24': return App.ResourceManagerHeapPieChartView;
case '25': return App.ResourceManagerUptimeView;
case '26': return App.NodeManagersLiveView;
case '27': return App.YARNMemoryPieChartView;
}
},
currentPrefObject: null,
initPrefObject: Em.Object.create({
dashboardVersion: 'new',
visible: [],
hidden: [],
threshold: {1: [80, 90], 2: [85, 95], 3: [90, 95], 4: [80, 90], 5: [1000, 3000], 6: [70, 90], 7: [90, 95], 8: [50, 75], 9: [30000, 120000],
10: [], 11: [], 12: [], 13: [], 14: [], 15: [], 16: [], 17: [], 18: [], 19: [], 20: [70, 90], 21: [10, 19.2], 22: [3, 10], 23: [],
24: [70, 90], 25: [], 26: [50, 75], 27: [50, 75]} // id:[thresh1, thresh2]
}),
persistKey: function () {
var loginName = App.router.get('loginName');
return 'user-pref-' + loginName + '-dashboard';
}.property(''),
/**
* get persist value from server with persistKey
*/
getUserPref: function(key){
App.ajax.send({
name: 'dashboard.get.user_pref',
sender: this,
data: {
key: key
},
success: 'getUserPrefSuccessCallback',
error: 'getUserPrefErrorCallback'
});
},
getUserPrefSuccessCallback: function (response, request, data) {
if (response) {
console.log('Got persist value from server with key ' + data.key + '. Value is: ' + response);
this.set('currentPrefObject', response);
}
},
getUserPrefErrorCallback: function (request, ajaxOptions, error) {
// this user is first time login
if (request.status == 404) {
console.log('Persist did NOT find the key');
return null;
}
},
/**
* post persist key/value to server, value is object
*/
postUserPref: function (key, value) {
var url = App.apiPrefix + '/persist/';
var keyValuePair = {};
keyValuePair[key] = JSON.stringify(value);
App.ajax.send({
'name': 'dashboard.post.user_pref',
'sender': this,
'beforeSend': 'postUserPrefBeforeSend',
'data': {
'keyValuePair': keyValuePair
}
});
},
postUserPrefBeforeSend: function(request, ajaxOptions, data){
console.log('BeforeSend to persist: persistKeyValues', data.keyValuePair);
},
resetAllWidgets: function(){
var self = this;
App.showConfirmationPopup(function() {
if(!App.testMode){
self.postUserPref(self.get('persistKey'), self.get('initPrefObject'));
}
self.translateToReal(self.get('initPrefObject'));
});
},
switchToClassic: function () {
if(!App.testMode){
this.getUserPref(this.get('persistKey'));
var oldValue = this.get('currentPrefObject');
oldValue.dashboardVersion = 'classic';
this.postUserPref(this.get('persistKey'), oldValue);
}else{
var oldValue = this.get('initPrefObject');
oldValue.dashboardVersion = 'classic';
}
this.translateToReal(oldValue);
},
switchToNew: function () {
if(!App.testMode){
this.getUserPref(this.get('persistKey'));
var oldValue = this.get('currentPrefObject');
oldValue.dashboardVersion = 'new';
this.postUserPref(this.get('persistKey'), oldValue);
this.didInsertElement();
}else{
var oldValue = this.get('initPrefObject');
oldValue.dashboardVersion = 'new';
this.translateToReal(oldValue);
}
},
updateServices: function(){
var services = App.Service.find();
services.forEach(function (item) {
var view;
switch (item.get('serviceName')) {
case "HDFS":
view = this.get('content').filterProperty('viewName', App.MainDashboardServiceHdfsView);
view.objectAt(0).set('model', App.HDFSService.find(item.get('id')));
break;
case "MAPREDUCE":
view = this.get('content').filterProperty('viewName', App.MainDashboardServiceMapreduceView);
view.objectAt(0).set('model', App.MapReduceService.find(item.get('id')));
break;
case "HBASE":
view = this.get('content').filterProperty('viewName', App.MainDashboardServiceHbaseView);
view.objectAt(0).set('model', App.HBaseService.find(item.get('id')));
}
}, this);
}.observes('App.router.updateController.isUpdate'),
services: function () {
var services = App.Service.find();
if (this.get('content').length > 0) {
return false
}
services.forEach(function (item) {
var vName;
var item2;
switch (item.get('serviceName')) {
case "HDFS":
vName = App.MainDashboardServiceHdfsView;
item2 = App.HDFSService.find(item.get('id'));
break;
case "YARN":
vName = App.MainDashboardServiceYARNView;
item2 = App.YARNService.find(item.get('id'));
break;
case "MAPREDUCE":
vName = App.MainDashboardServiceMapreduceView;
item2 = App.MapReduceService.find(item.get('id'));
break;
case "MAPREDUCE2":
vName = App.MainDashboardServiceMapreduce2View;
break;
case "HBASE":
vName = App.MainDashboardServiceHbaseView;
item2 = App.HBaseService.find(item.get('id'));
break;
case "HIVE":
vName = App.MainDashboardServiceHiveView;
break;
case "ZOOKEEPER":
vName = App.MainDashboardServiceZookeperView;
break;
case "OOZIE":
vName = App.MainDashboardServiceOozieView;
break;
default:
vName = Em.View;
}
this.get('content').pushObject(Em.Object.create({
viewName: vName,
model: item2 || item
}))
}, this);
},
gangliaUrl: function () {
return App.router.get('clusterController.gangliaUrl') + "/?r=hour&cs=&ce=&m=&s=by+name&c=HDPSlaves&tab=m&vn=";
}.property('App.router.clusterController.gangliaUrl'),
showAlertsPopup: function (event) {
App.ModalPopup.show({
header: this.t('services.alerts.headingOfList'),
bodyClass: Ember.View.extend({
service: event.context,
warnAlerts: function () {
var allAlerts = App.router.get('clusterController.alerts');
var serviceId = this.get('service.serviceName');
if (serviceId) {
return allAlerts.filterProperty('serviceType', serviceId).filterProperty('isOk', false).filterProperty('ignoredForServices', false);
}
return 0;
}.property('App.router.clusterController.alerts'),
warnAlertsCount: function () {
return this.get('warnAlerts').length;
}.property('warnAlerts'),
warnAlertsMessage: function() {
return Em.I18n.t('services.alerts.head').format(this.get('warnAlertsCount'));
}.property('warnAlertsCount'),
nagiosUrl: function () {
return App.router.get('clusterController.nagiosUrl');
}.property('App.router.clusterController.nagiosUrl'),
closePopup: function () {
this.get('parentView').hide();
},
viewNagiosUrl: function () {
window.open(this.get('nagiosUrl'), "_blank");
this.closePopup();
},
selectService: function () {
App.router.transitionTo('services.service.summary', event.context)
this.closePopup();
},
templateName: require('templates/main/dashboard/alert_notification_popup')
}),
primary: Em.I18n.t('common.close'),
secondary : null,
didInsertElement: function () {
this.$().find('.modal-footer').addClass('align-center');
this.$().children('.modal').css({'margin-top': '-350px'});
}
});
event.stopPropagation();
}
});