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/02/18 12:52:53 UTC
git commit: AMBARI-4707. Refactor host components view.
(onechiporenko)
Repository: ambari
Updated Branches:
refs/heads/trunk 65249796f -> 746e68fc6
AMBARI-4707. Refactor host components view. (onechiporenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/746e68fc
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/746e68fc
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/746e68fc
Branch: refs/heads/trunk
Commit: 746e68fc6ff6d743f0a069901dcb9c90fe0cda48
Parents: 6524979
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Tue Feb 18 13:50:05 2014 +0200
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Tue Feb 18 13:50:05 2014 +0200
----------------------------------------------------------------------
ambari-web/app/assets/test/tests.js | 1 +
.../main/host/details/host_component.hbs | 99 +---
ambari-web/app/templates/main/host/summary.hbs | 2 +-
ambari-web/app/utils/ajax.js | 22 +-
ambari-web/app/views.js | 4 +
.../main/host/details/host_component_view.js | 472 +------------------
.../host_component_views/datanode_view.js | 127 +++++
.../host_component_views/decommissionable.js | 253 ++++++++++
.../host_component_views/nodemanager_view.js | 71 +++
.../host_component_views/regionserver_view.js | 52 ++
.../host_component_views/tasktracker_view.js | 74 +++
ambari-web/app/views/main/host/summary.js | 21 +
.../host/details/host_component_view_test.js | 138 +++++-
.../decommissionable_test.js | 201 ++++++++
14 files changed, 975 insertions(+), 562 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/assets/test/tests.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js
index fd7cb29..4bf8c78 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -100,6 +100,7 @@ require('test/views/main/dashboard/widgets/pie_chart_widget_test');
require('test/views/main/dashboard/widgets/namenode_cpu_test');
require('test/views/main/host/summary_test');
require('test/views/main/host/details/host_component_view_test');
+require('test/views/main/host/details/host_component_views/decommissionable_test');
require('test/views/common/configs/services_config_test');
require('test/views/wizard/step9_view_test');
require('test/models/host_test');
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/templates/main/host/details/host_component.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/host/details/host_component.hbs b/ambari-web/app/templates/main/host/details/host_component.hbs
index ee29b88..10c772a 100644
--- a/ambari-web/app/templates/main/host/details/host_component.hbs
+++ b/ambari-web/app/templates/main/host/details/host_component.hbs
@@ -32,7 +32,7 @@
{{component.displayName}}
{{/if}}
/
- <a href="#" {{action routeToService component.service target="controller" }}>{{component.service.displayName}}</a>
+ <a href="#" {{action routeToService component.service target="controller"}}>{{component.service.displayName}}</a>
{{#if component.staleConfigs}}
<i class="text-warning icon-refresh"></i>
@@ -46,69 +46,19 @@
<span class="caret pull-right"></span>
</a>
<ul class="dropdown-menu">
- {{#if view.isDataNode}}
- {{#if view.isDataNodeDecommissionAvailable}}
- <li {{bindAttr class="view.noActionAvailable"}}>
- <a href="javascript:void(null)" data-toggle="modal" {{action "decommission" view.content target="controller"}}>
- {{t common.decommission}}
- </a>
- </li>
- {{/if}}
- {{#if view.isDataNodeRecommissionAvailable}}
- <li {{bindAttr class="view.noActionAvailable"}}>
- <a href="javascript:void(null)" data-toggle="modal" {{action "recommission" view.content target="controller"}}>
- {{t common.recommission}}
- </a>
- </li>
- {{/if}}
- {{/if}}
- {{#if view.isNodeManager}}
- {{#if view.isNodeManagerDecommissionAvailable}}
- <li {{bindAttr class="view.noActionAvailable"}}>
- <a href="javascript:void(null)" data-toggle="modal" {{action "decommission" view.content target="controller"}}>
- {{t common.decommission}}
- </a>
- </li>
- {{/if}}
- {{#if view.isNodeManagerRecommissionAvailable}}
- <li {{bindAttr class="view.noActionAvailable"}}>
- <a href="javascript:void(null)" data-toggle="modal" {{action "recommission" view.content target="controller"}}>
- {{t common.recommission}}
- </a>
- </li>
- {{/if}}
- {{/if}}
- {{#if view.isTaskTracker}}
- {{#if view.isTaskTrackerDecommissionAvailable}}
- <li {{bindAttr class="view.noActionAvailable"}}>
- <a href="javascript:void(null)" data-toggle="modal" {{action "decommission" view.content target="controller"}}>
- {{t common.decommission}}
- </a>
- </li>
- {{/if}}
- {{#if view.isTaskTrackerRecommissionAvailable}}
- <li {{bindAttr class="view.noActionAvailable"}}>
- <a href="javascript:void(null)" data-toggle="modal" {{action "recommission" view.content target="controller"}}>
- {{t common.recommission}}
- </a>
- </li>
- {{/if}}
+ {{#if view.isComponentDecommissionAvailable}}
+ <li {{bindAttr class="view.noActionAvailable"}}>
+ <a href="javascript:void(null)" data-toggle="modal" {{action "decommission" view.content target="controller"}}>
+ {{t common.decommission}}
+ </a>
+ </li>
{{/if}}
- {{#if view.isRegionServer}}
- {{#if view.isRegionServerDecommissionAvailable}}
- <li {{bindAttr class="view.noActionAvailable"}}>
- <a href="javascript:void(null)" data-toggle="modal" {{action "decommission" view.content target="controller"}}>
- {{t common.decommission}}
- </a>
- </li>
- {{/if}}
- {{#if view.isRegionServerRecommissionAvailable}}
- <li {{bindAttr class="view.noActionAvailable"}}>
- <a href="javascript:void(null)" data-toggle="modal" {{action "recommission" view.content target="controller"}}>
- {{t common.recommission}}
- </a>
- </li>
- {{/if}}
+ {{#if view.isComponentRecommissionAvailable}}
+ <li {{bindAttr class="view.noActionAvailable"}}>
+ <a href="javascript:void(null)" data-toggle="modal" {{action "recommission" view.content target="controller"}}>
+ {{t common.recommission}}
+ </a>
+ </li>
{{/if}}
{{#if view.isDeletableComponent}}
<li {{bindAttr class="view.isDeleteComponentDisabled:disabled"}}>
@@ -126,56 +76,49 @@
{{/if}}
{{#unless view.isInstalling}}
{{#if view.isStart}}
- <li {{bindAttr class=" view.isDecommissioning:hidden view.noActionAvailable"}}>
- <a href="javascript:void(null)"
- data-toggle="modal" {{action "stopComponent" view.content target="controller"}}>
+ <li {{bindAttr class="view.isComponentDecommissioning:hidden view.noActionAvailable"}}>
+ <a href="javascript:void(null)" data-toggle="modal" {{action "stopComponent" view.content target="controller"}}>
{{t common.stop}}
</a>
</li>
{{/if}}
{{#unless view.isStart}}
<li {{bindAttr class="view.isUpgradeFailed:hidden view.isInstallFailed:hidden view.isDecommissioning:hidden view.noActionAvailable"}}>
- <a href="javascript:void(null)"
- data-toggle="modal" {{action "startComponent" view.content target="controller"}}>
+ <a href="javascript:void(null)" data-toggle="modal" {{action "startComponent" view.content target="controller"}}>
{{t common.start}}
</a>
</li>
{{/unless}}
{{#if view.isUpgradeFailed}}
<li {{bindAttr class="view.noActionAvailable"}}>
- <a href="javascript:void(null)"
- data-toggle="modal" {{action "upgradeComponent" view.content target="controller"}}>
+ <a href="javascript:void(null)" data-toggle="modal" {{action "upgradeComponent" view.content target="controller"}}>
{{t common.reUpgrade}}
</a>
</li>
{{/if}}
{{#if view.isInstallFailed}}
<li {{bindAttr class="view.noActionAvailable"}}>
- <a href="javascript:void(null)"
- data-toggle="modal" {{action "installComponent" view.content target="controller"}}>
+ <a href="javascript:void(null)" data-toggle="modal" {{action "installComponent" view.content target="controller"}}>
{{t common.reinstall}}
</a>
</li>
{{/if}}
{{#if view.isReassignable}}
<li {{bindAttr class="view.noActionAvailable"}}>
- <a href="javascript:void(null)"
- data-toggle="modal" {{action "moveComponent" view.content target="controller"}}>
+ <a href="javascript:void(null)" data-toggle="modal" {{action "moveComponent" view.content target="controller"}}>
{{t common.move}}
</a>
</li>
{{/if}}
{{#if view.isActive}}
<li rel='passiveTooltip' {{bindAttr class="view.noActionAvailable" title="view.passiveImpliedTextStatus"}}>
- <a href="javascript:void(null)" {{bindAttr class="view.isImplied:disabled"}}
- data-toggle="modal" {{action "turnOnOffPassiveConfirmation" view.content target="controller"}}>
+ <a href="javascript:void(null)" {{bindAttr class="view.isImplied:disabled"}} data-toggle="modal" {{action "turnOnOffPassiveConfirmation" view.content target="controller"}}>
{{t passiveState.turnOn}}
</a>
</li>
{{else}}
<li rel='passiveTooltip' {{bindAttr class="view.noActionAvailable" title="view.passiveImpliedTextStatus"}}>
- <a href="javascript:void(null)" {{bindAttr class="view.isImplied:disabled"}}
- data-toggle="modal" {{action "turnOnOffPassiveConfirmation" view.content target="controller"}}>
+ <a href="javascript:void(null)" {{bindAttr class="view.isImplied:disabled"}} data-toggle="modal" {{action "turnOnOffPassiveConfirmation" view.content target="controller"}}>
{{t passiveState.turnOff}}
</a>
</li>
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/templates/main/host/summary.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/host/summary.hbs b/ambari-web/app/templates/main/host/summary.hbs
index 83c0ade..2b04ea9 100644
--- a/ambari-web/app/templates/main/host/summary.hbs
+++ b/ambari-web/app/templates/main/host/summary.hbs
@@ -58,7 +58,7 @@
{{#each component in view.sortedComponents}}
<div class="row-fluid">
- {{view App.HostComponentView contentBinding="component"}}
+ {{view component.view contentBinding="component"}}
</div>
{{/each}}
{{/if}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/utils/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax.js b/ambari-web/app/utils/ajax.js
index 0823b9b..2ada34c 100644
--- a/ambari-web/app/utils/ajax.js
+++ b/ambari-web/app/utils/ajax.js
@@ -348,23 +348,11 @@ var urls = {
},
'host.host_component.slave_desired_admin_state': {
'real': '/clusters/{clusterName}/hosts/{hostName}/host_components/{componentName}/?fields=HostRoles/desired_admin_state',
- 'mock': '',
- 'type': 'GET'
- },
- 'host.host_component.datanodes_decommission_status': {
- 'real': '/clusters/{clusterName}/services/HDFS/components/NAMENODE/?fields=ServiceComponentInfo',
- 'mock': '',
- 'type': 'GET'
- },
- 'host.host_component.nodemanager_decommission_status': {
- 'real': '/clusters/{clusterName}/services/YARN/components/RESOURCEMANAGER/?fields=ServiceComponentInfo',
- 'mock': '',
- 'type': 'GET'
+ 'mock': ''
},
- 'host.host_component.tasktracker_decommission_status': {
- 'real': '/clusters/{clusterName}/services/MAPREDUCE/components/JOBTRACKER/?fields=ServiceComponentInfo',
- 'mock': '',
- 'type': 'GET'
+ 'host.host_component.decommission_status': {
+ 'real': '/clusters/{clusterName}/services/{serviceName}/components/{componentName}/?fields=ServiceComponentInfo',
+ 'mock': ''
},
'host.host_component.decommission_slave': {
'real' : '/clusters/{clusterName}/requests',
@@ -1683,7 +1671,7 @@ var ajax = Em.Object.extend({
* Send ajax request
*
* @param {Object} config
- * @return Object jquery ajax object
+ * @return {$.ajax} jquery ajax object
*
* config fields:
* name - url-key in the urls-object *required*
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 88cf9b1..6f88eca 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -43,6 +43,10 @@ require('views/main/host');
require('views/main/host/hosts_table_menu_view');
require('views/main/host/details');
require('views/main/host/details/host_component_view');
+require('views/main/host/details/host_component_views/datanode_view');
+require('views/main/host/details/host_component_views/nodemanager_view');
+require('views/main/host/details/host_component_views/regionserver_view');
+require('views/main/host/details/host_component_views/tasktracker_view');
require('views/main/host/menu');
require('views/main/host/summary');
require('views/main/host/configs');
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/views/main/host/details/host_component_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/details/host_component_view.js b/ambari-web/app/views/main/host/details/host_component_view.js
index 8b26434..31e9b99 100644
--- a/ambari-web/app/views/main/host/details/host_component_view.js
+++ b/ambari-web/app/views/main/host/details/host_component_view.js
@@ -57,44 +57,13 @@ App.HostComponentView = Em.View.extend({
* @type {String}
*/
componentTextStatus: function () {
- var workStatus = this.get("workStatus");
var componentTextStatus = this.get('content.componentTextStatus');
var hostComponent = this.get('hostComponent');
if (hostComponent) {
componentTextStatus = hostComponent.get('componentTextStatus');
- if(this.get("isDataNode") && this.get('isDataNodeRecommissionAvailable')){
- if(this.get('isDataNodeDecommissioning')){
- componentTextStatus = Em.I18n.t('hosts.host.decommissioning');
- } else {
- componentTextStatus = Em.I18n.t('hosts.host.decommissioned');
- }
- }
- if(this.get("isNodeManager") && this.get('isNodeManagerRecommissionAvailable')){
- if(this.get('isNodeManagerDecommissioning')){
- componentTextStatus = Em.I18n.t('hosts.host.decommissioning');
- } else {
- componentTextStatus = Em.I18n.t('hosts.host.decommissioned');
- }
- }
- if(this.get("isTaskTracker") && this.get('isTaskTrackerRecommissionAvailable')){
- if(this.get('isTaskTrackerDecommissioning')){
- componentTextStatus = Em.I18n.t('hosts.host.decommissioning');
- } else {
- componentTextStatus = Em.I18n.t('hosts.host.decommissioned');
- }
- }
- if(this.get("isRegionServer") && this.get('isRegionServerRecommissionAvailable')){
- if(this.get('isRegionServerDecommissioning')){
- componentTextStatus = Em.I18n.t('hosts.host.decommissioning');
- } else {
- componentTextStatus = Em.I18n.t('hosts.host.decommissioned');
- }
- }
}
return componentTextStatus;
- }.property('content.passiveState','workStatus','isDataNodeRecommissionAvailable', 'isDataNodeDecommissioning', 'isNodeManagerRecommissionAvailable', 'isNodeManagerDecommissioning',
- 'isTaskTrackerRecommissionAvailable', 'isTaskTrackerDecommissioning', 'isRegionServerRecommissionAvailable', 'isRegionServerDecommissioning'),
-
+ }.property('content.passiveState','workStatus'),
/**
* Returns message for health tooltip
@@ -143,38 +112,10 @@ App.HostComponentView = Em.View.extend({
return 'icon-medkit';
}
- //If the component is DataNode
- if (this.get('isDataNode')) {
- if (this.get('isDataNodeRecommissionAvailable') && (this.get('isStart') || this.get('workStatus') == 'INSTALLED')) {
- return 'health-status-DEAD-ORANGE';
- }
- }
-
- //If the component is NodeManager
- if (this.get('isNodeManager')) {
- if (this.get('isNodeManagerRecommissionAvailable') && (this.get('isStart') || this.get('workStatus') == 'INSTALLED')) {
- return 'health-status-DEAD-ORANGE';
- }
- }
-
- //If the component is TaskTracker
- if (this.get('isTaskTracker')) {
- if (this.get('isTaskTrackerRecommissionAvailable') && (this.get('isStart') || this.get('workStatus') == 'INSTALLED')) {
- return 'health-status-DEAD-ORANGE';
- }
- }
-
- //If the component is RegionServer
- if (this.get('isRegionServer')) {
- if (this.get('isRegionServerRecommissionAvailable') && (this.get('isStart') || this.get('workStatus') == 'INSTALLED')) {
- return 'health-status-DEAD-ORANGE';
- }
- }
-
//For all other cases
return 'health-status-' + App.HostComponentStatus.getKeyName(this.get('workStatus'));
- }.property('content.passiveState','workStatus', 'isDataNodeRecommissionAvailable', 'isNodeManagerRecommissionAvailable', 'isTaskTrackerRecommissionAvailable', 'isRegionServerRecommissionAvailable'),
+ }.property('content.passiveState','workStatus'),
/**
* CSS-class for disabling drop-down menu with list of host component actions
@@ -239,14 +180,13 @@ App.HostComponentView = Em.View.extend({
}.property('workStatus'),
/**
- * For Stopping or Starting states, also for decommissioning
+ * For Stopping or Starting states
* @type {bool}
*/
isInProgress: function () {
return (this.get('workStatus') === App.HostComponentStatus.stopping ||
- this.get('workStatus') === App.HostComponentStatus.starting) ||
- this.get('isDecommissioning');
- }.property('workStatus', 'isDecommissioning'),
+ this.get('workStatus') === App.HostComponentStatus.starting);
+ }.property('workStatus'),
/**
* For ACTIVE <code>passiveState</code> of host component
@@ -265,15 +205,6 @@ App.HostComponentView = Em.View.extend({
}.property('parentView.content.passiveState', 'content.service.passiveState'),
/**
- *
- * @type {bool}
- */
- isDecommissioning: function () {
- return ( (this.get('isDataNode') && this.get("isDataNodeDecommissioning")) || (this.get('isRegionServer') && this.get("isRegionServerDecommissioning"))
- || (this.get('isNodeManager') && this.get("isNodeManagerDecommissioning")) || (this.get('isTaskTracker') && this.get('isTaskTrackerDecommissioning')));
- }.property("workStatus", "isDataNodeDecommissioning", "isRegionServerDecommissioning", "isNodeManagerDecommissioning", "isTaskTrackerDecommissioning"),
-
- /**
* Shows whether we need to show Delete button
* @type {bool}
*/
@@ -319,18 +250,6 @@ App.HostComponentView = Em.View.extend({
if (this.get('isInProgress')) {
this.doBlinking();
}
- if (this.get('isDataNode')){
- this.loadDataNodeDecommissionStatus();
- }
- if (this.get('isNodeManager')){
- this.loadNodeManagerDecommissionStatus();
- }
- if (this.get('isTaskTracker')){
- this.loadTaskTrackerDecommissionStatus();
- }
- if (this.get('isRegionServer')){
- this.loadRegionServerDecommissionStatus();
- }
},
/**
@@ -340,12 +259,6 @@ App.HostComponentView = Em.View.extend({
var workStatus = this.get('workStatus');
var self = this;
var pulsate = [ App.HostComponentStatus.starting, App.HostComponentStatus.stopping, App.HostComponentStatus.installing].contains(workStatus);
- if (!pulsate && (this.get('isDataNode') || this.get('isRegionServer') || this.get('isNodeManager') || this.get('isTaskTracker'))) {
- var component = this.get('content');
- if (component && workStatus != "INSTALLED") {
- pulsate = this.get('isDecommissioning');
- }
- }
if (pulsate && !self.get('isBlinking')) {
self.set('isBlinking', true);
uiEffects.pulsate(self.$('.components-health'), 1000, function () {
@@ -354,383 +267,14 @@ App.HostComponentView = Em.View.extend({
});
}
},
+
/**
- * Start blinking when host component is starting/stopping/decommissioning
+ * Start blinking when host component is starting/stopping
*/
startBlinking: function () {
this.$('.components-health').stop(true, true);
this.$('.components-health').css({opacity: 1.0});
this.doBlinking();
- }.observes('workStatus','isDataNodeRecommissionAvailable', 'isDecommissioning', 'isRegionServerRecommissionAvailable',
- 'isNodeManagerRecommissionAvailable', 'isTaskTrackerRecommissionAvailable'),
-
- isDataNode: function () {
- return this.get('content.componentName') === 'DATANODE';
- }.property('content'),
-
- isNodeManager: function () {
- return this.get('content.componentName') === 'NODEMANAGER';
- }.property('content'),
-
- isTaskTracker: function () {
- return this.get('content.componentName') === 'TASKTRACKER';
- }.property('content'),
-
- isRegionServer: function () {
- return this.get('content.componentName') === 'HBASE_REGIONSERVER';
- }.property('content'),
-
- isDataNodeDecommissioning: null,
- isDataNodeDecommissionAvailable: null,
- isDataNodeRecommissionAvailable: null,
-
- updateDecommissionStatus: function() {
- if (this.get('isDataNode'))
- Em.run.once(this, 'loadDataNodeDecommissionStatus');
- if (this.get('isNodeManager'))
- Em.run.once(this, 'loadNodeManagerDecommissionStatus');
- if (this.get('isTaskTracker'))
- Em.run.once(this, 'loadTaskTrackerDecommissionStatus');
- if (this.get('isRegionServer'))
- Em.run.once(this, 'loadRegionServerDecommissionStatus');
- }.observes('content.workStatus', 'content.passiveState'),
-
- /**
- * load Recommission/Decommission status from adminState of each live node
- */
- loadDataNodeDecommissionStatus: function () {
- var clusterName = App.router.get('clusterController.clusterName');
- var hostName = App.router.get('mainHostDetailsController.content.hostName');
- var componentName = 'NAMENODE';
- var slaveType = 'DATANODE';
- var version = App.get('currentStackVersionNumber');
- var dfd = $.Deferred();
- var self = this;
- this.getDNDecommissionStatus(clusterName, hostName, componentName).done(function () {
- var curObj = self.get('decommissionedStatusObject');
- self.set('decommissionedStatusObject', null);
- // HDP-2 stack
- if (version.charAt(0) == 2) {
- if (curObj) {
- var liveNodesJson = App.parseJSON(curObj.LiveNodes);
- if (liveNodesJson && liveNodesJson[hostName] ) {
- switch(liveNodesJson[hostName].adminState) {
- case "In Service":
- self.set('isDataNodeRecommissionAvailable', false);
- self.set('isDataNodeDecommissioning', false);
- self.set('isDataNodeDecommissionAvailable', self.get('isStart'));
- break;
- case "Decommission In Progress":
- self.set('isDataNodeRecommissionAvailable', true);
- self.set('isDataNodeDecommissioning', true);
- self.set('isDataNodeDecommissionAvailable', false);
- break;
- case "Decommissioned":
- self.set('isDataNodeRecommissionAvailable', true);
- self.set('isDataNodeDecommissioning', false);
- self.set('isDataNodeDecommissionAvailable', false);
- break;
- }
- } else {
- // if namenode is down, get desired_admin_state to decide if the user had issued a decommission
- var deferred = $.Deferred();
- self.getDesiredAdminState(clusterName, hostName, slaveType).done( function () {
- var desired_admin_state = self.get('desiredAdminState');
- self.set('desiredAdminState', null);
- switch(desired_admin_state) {
- case "INSERVICE":
- self.set('isDataNodeRecommissionAvailable', false);
- self.set('isDataNodeDecommissioning', false);
- self.set('isDataNodeDecommissionAvailable', self.get('isStart'));
- break;
- case "DECOMMISSIONED":
- self.set('isDataNodeRecommissionAvailable', true);
- self.set('isDataNodeDecommissioning', false);
- self.set('isDataNodeDecommissionAvailable', false);
- break;
- }
- deferred.resolve(desired_admin_state);
- });
- }
- }
- }
- // HDP-1 stack
- if (version.charAt(0) == 1) {
- if (curObj) {
- var liveNodesJson = App.parseJSON(curObj.LiveNodes);
- var decomNodesJson = App.parseJSON(curObj.DecomNodes);
- var deadNodesJson = App.parseJSON(curObj.DeadNodes);
- if (decomNodesJson && decomNodesJson[hostName] ) {
- self.set('isDataNodeRecommissionAvailable', true);
- self.set('isDataNodeDecommissioning', true);
- self.set('isDataNodeDecommissionAvailable', false);
- } else if (deadNodesJson && deadNodesJson[hostName] ) {
- self.set('isDataNodeRecommissionAvailable', true);
- self.set('isDataNodeDecommissioning', false);
- self.set('isDataNodeDecommissionAvailable', false);
- } else if (liveNodesJson && liveNodesJson[hostName] ) {
- self.set('isDataNodeRecommissionAvailable', false);
- self.set('isDataNodeDecommissioning', false);
- self.set('isDataNodeDecommissionAvailable', self.get('isStart'));
- } else {
- // if namenode is down, get desired_admin_state to decide if the user had issued a decommission
- var deferred = $.Deferred();
- self.getDesiredAdminState(clusterName, hostName, slaveType).done( function () {
- var desired_admin_state = self.get('desiredAdminState');
- self.set('desiredAdminState', null);
- switch(desired_admin_state) {
- case "INSERVICE":
- self.set('isDataNodeRecommissionAvailable', false);
- self.set('isDataNodeDecommissioning', false);
- self.set('isDataNodeDecommissionAvailable', self.get('isStart'));
- break;
- case "DECOMMISSIONED":
- self.set('isDataNodeRecommissionAvailable', true);
- self.set('isDataNodeDecommissioning', false);
- self.set('isDataNodeDecommissionAvailable', false);
- break;
- }
- deferred.resolve(desired_admin_state);
- });
- }
- }
- }
- dfd.resolve(curObj);
- });
- return dfd.promise();
- },
-
- /**
- * get datanodes decommission status: from NAMENODE component, liveNodes property
- */
- getDNDecommissionStatus: function(clusterName, hostName, componentName){
- return App.ajax.send({
- name: 'host.host_component.datanodes_decommission_status',
- sender: this,
- data: {
- clusterName: clusterName,
- hostName: hostName,
- componentName: componentName
- },
- success: 'getDNDecommissionStatusSuccessCallback',
- error: 'getDNDecommissionStatusErrorCallback'
- });
- },
-
- decommissionedStatusObject: null,
- getDNDecommissionStatusSuccessCallback: function (response, request, data) {
- var statusObject = response.ServiceComponentInfo;
- if ( statusObject != null) {
- this.set('decommissionedStatusObject', statusObject);
- return statusObject;
- }
- },
- getDNDecommissionStatusErrorCallback: function (request, ajaxOptions, error) {
- console.log('ERROR: '+ error);
- this.set('decommissionedStatusObject', null);
- return null;
- },
-
- /**
- * get desired_admin_state status of DataNode, TaskTracker, NodeManager and RegionServer
- */
- getDesiredAdminState: function(clusterName, hostName, componentName){
- return App.ajax.send({
- name: 'host.host_component.slave_desired_admin_state',
- sender: this,
- data: {
- clusterName: clusterName,
- hostName: hostName,
- componentName: componentName
- },
- success: 'getDesiredAdminStateSuccessCallback',
- error: 'getDesiredAdminStateErrorCallback'
- });
- },
- desiredAdminState: null,
- getDesiredAdminStateSuccessCallback: function (response, request, data) {
- var status = response.HostRoles.desired_admin_state;
- if ( status != null) {
- this.set('desiredAdminState', status);
- return status;
- }
- },
- getDesiredAdminStateErrorCallback: function (request, ajaxOptions, error) {
- console.log('ERROR: '+ error);
- this.set('desiredAdminState', null);
- return null;
- },
-
- isNodeManagerDecommissionAvailable: null,
- isNodeManagerRecommissionAvailable: null,
- isNodeManagerDecommissioning: null,
- /**
- * load Recommission/Decommission status for nodeManager from nodeManagers list
- */
- loadNodeManagerDecommissionStatus: function () {
- var clusterName = App.router.get('clusterController.clusterName');
- var hostName = App.router.get('mainHostDetailsController.content.hostName');
- var componentName = 'RESOURCEMANAGER';
- var slaveType = 'NODEMANAGER';
- var dfd = $.Deferred();
- var self = this;
-
- this.getDesiredAdminState(clusterName, hostName, slaveType).done( function () {
- var desired_admin_state = self.get('desiredAdminState');
- self.set('desiredAdminState', null);
- switch(desired_admin_state) {
- case "INSERVICE":
- // can be decommissioned if already started
- self.set('isNodeManagerRecommissionAvailable', false);
- self.set('isNodeManagerDecommissioning', false);
- self.set('isNodeManagerDecommissionAvailable', self.get('isStart'));
- break;
- case "DECOMMISSIONED":
- var deferred = $.Deferred();
- self.getNMDecommissionStatus(clusterName, hostName, componentName).done( function() {
- var curObj = self.get('decommissionedStatusObject');
- self.set('decommissionedStatusObject', null);
- if (curObj && curObj.rm_metrics) {
- var nodeManagersArray = App.parseJSON(curObj.rm_metrics.cluster.nodeManagers);
- if (nodeManagersArray.findProperty('HostName', hostName)){
- // decommisioning ..
- self.set('isNodeManagerRecommissionAvailable', true);
- self.set('isNodeManagerDecommissioning', true);
- self.set('isNodeManagerDecommissionAvailable', false);
- } else {
- // decommissioned ..
- self.set('isNodeManagerRecommissionAvailable', true);
- self.set('isNodeManagerDecommissioning', false);
- self.set('isNodeManagerDecommissionAvailable', false);
- }
- }
- deferred.resolve(curObj);
- });
- break;
- }
- dfd.resolve(desired_admin_state);
- });
- return dfd.promise();
- },
-
- /**
- * get NodeManager decommission status: from RESOURCEMANAGER component, rm_metrics/nodeManagers property
- */
- getNMDecommissionStatus: function(clusterName, hostName, componentName){
- return App.ajax.send({
- name: 'host.host_component.nodemanager_decommission_status',
- sender: this,
- data: {
- clusterName: clusterName,
- hostName: hostName,
- componentName: componentName
- },
- success: 'getDNDecommissionStatusSuccessCallback',
- error: 'getDNDecommissionStatusErrorCallback'
- });
- },
-
- isTaskTrackerDecommissionAvailable: null,
- isTaskTrackerRecommissionAvailable: null,
- isTaskTrackerDecommissioning: null,
- /**
- * load Recommission/Decommission status for TaskTracker from JobTracker/AliveNodes list
- */
- loadTaskTrackerDecommissionStatus: function () {
- var clusterName = App.router.get('clusterController.clusterName');
- var hostName = App.router.get('mainHostDetailsController.content.hostName');
- var componentName = 'JOBTRACKER';
- var slaveType = 'TASKTRACKER';
- var dfd = $.Deferred();
- var self = this;
- this.getDesiredAdminState(clusterName, hostName, slaveType).done( function () {
- var desired_admin_state = self.get('desiredAdminState');
- self.set('desiredAdminState', null);
- switch(desired_admin_state) {
- case "INSERVICE":
- // can be decommissioned if already started
- self.set('isTaskTrackerRecommissionAvailable', false);
- self.set('isTaskTrackerDecommissioning', false);
- self.set('isTaskTrackerDecommissionAvailable', self.get('isStart'));
- break;
- case "DECOMMISSIONED":
- var deferred = $.Deferred();
- self.getTTDecommissionStatus(clusterName, hostName, componentName).done( function() {
- var curObj = self.get('decommissionedStatusObject');
- self.set('decommissionedStatusObject', null);
- if (curObj) {
- var aliveNodesArray = App.parseJSON(curObj.AliveNodes);
- if (aliveNodesArray != null) {
- if (aliveNodesArray.findProperty('hostname', hostName)){
- //decommissioning ..
- self.set('isTaskTrackerRecommissionAvailable', true);
- self.set('isTaskTrackerDecommissioning', true);
- self.set('isTaskTrackerDecommissionAvailable', false);
- } else {
- //decommissioned
- self.set('isTaskTrackerRecommissionAvailable', true);
- self.set('isTaskTrackerDecommissioning', false);
- self.set('isTaskTrackerDecommissionAvailable', false);
- }
- }
-
- }
- deferred.resolve(curObj);
- });
- break;
- }
- dfd.resolve(desired_admin_state);
- });
- return dfd.promise();
- },
-
- /**
- * get TaskTracker decommission status: from JobTracker component, AliveNodes property
- */
- getTTDecommissionStatus: function(clusterName, hostName, componentName){
- return App.ajax.send({
- name: 'host.host_component.tasktracker_decommission_status',
- sender: this,
- data: {
- clusterName: clusterName,
- hostName: hostName,
- componentName: componentName
- },
- success: 'getDNDecommissionStatusSuccessCallback',
- error: 'getDNDecommissionStatusErrorCallback'
- });
- },
-
- isRegionServerDecommissioning: null,
- isRegionServerDecommissionAvailable: null,
- isRegionServerRecommissionAvailable: null,
- /**
- * load Recommission/Decommission status of RegionServer
- */
- loadRegionServerDecommissionStatus: function () {
- var clusterName = App.router.get('clusterController.clusterName');
- var hostName = App.router.get('mainHostDetailsController.content.hostName');
- var slaveType = 'HBASE_REGIONSERVER';
- var self = this;
- var deferred = $.Deferred();
- self.getDesiredAdminState(clusterName, hostName, slaveType).done( function () {
- var desired_admin_state = self.get('desiredAdminState');
- self.set('desiredAdminState', null);
- switch(desired_admin_state) {
- case "INSERVICE":
- self.set('isRegionServerRecommissionAvailable', false);
- self.set('isRegionServerDecommissioning', false);
- self.set('isRegionServerDecommissionAvailable', self.get('isStart'));
- break;
- case "DECOMMISSIONED":
- self.set('isRegionServerRecommissionAvailable', true);
- self.set('isRegionServerDecommissioning', self.get('isStart'));
- self.set('isRegionServerDecommissionAvailable', false);
- break;
- }
- deferred.resolve(desired_admin_state);
- });
- return deferred.promise();
- }
+ }.observes('workStatus')
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/views/main/host/details/host_component_views/datanode_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/details/host_component_views/datanode_view.js b/ambari-web/app/views/main/host/details/host_component_views/datanode_view.js
new file mode 100644
index 0000000..a2b1c04
--- /dev/null
+++ b/ambari-web/app/views/main/host/details/host_component_views/datanode_view.js
@@ -0,0 +1,127 @@
+/**
+ * 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');
+require('views/main/host/details/host_component_views/decommissionable');
+
+App.DataNodeComponentView = App.HostComponentView.extend(App.Decommissionable, {
+
+ componentForCheckDecommission: 'NAMENODE',
+
+ /**
+ * load Recommission/Decommission status from adminState of each live node
+ */
+ loadComponentDecommissionStatus: function () {
+ var hostName = this.get('content.host.hostName');
+ var dfd = $.Deferred();
+ var self = this;
+ this.getDecommissionStatus().done(function () {
+ var curObj = self.get('decommissionedStatusObject');
+ self.set('decommissionedStatusObject', null);
+ // HDP-2 stack
+ if (App.get('isHadoop2Stack')) {
+ if (curObj) {
+ var liveNodesJson = App.parseJSON(curObj.LiveNodes);
+ if (liveNodesJson && liveNodesJson[hostName] ) {
+ switch(liveNodesJson[hostName].adminState) {
+ case "In Service":
+ self.set('isComponentRecommissionAvailable', false);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', self.get('isStart'));
+ break;
+ case "Decommission In Progress":
+ self.set('isComponentRecommissionAvailable', true);
+ self.set('isComponentDecommissioning', true);
+ self.set('isComponentDecommissionAvailable', false);
+ break;
+ case "Decommissioned":
+ self.set('isComponentRecommissionAvailable', true);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', false);
+ break;
+ }
+ } else {
+ // if namenode is down, get desired_admin_state to decide if the user had issued a decommission
+ var deferred = $.Deferred();
+ self.getDesiredAdminState().done(function () {
+ var desired_admin_state = self.get('desiredAdminState');
+ self.set('desiredAdminState', null);
+ switch(desired_admin_state) {
+ case "INSERVICE":
+ self.set('isComponentRecommissionAvailable', false);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', self.get('isStart'));
+ break;
+ case "DECOMMISSIONED":
+ self.set('isComponentRecommissionAvailable', true);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', false);
+ break;
+ }
+ deferred.resolve(desired_admin_state);
+ });
+ }
+ }
+ }
+ else {
+ if (curObj) {
+ var liveNodesJson = App.parseJSON(curObj.LiveNodes);
+ var decomNodesJson = App.parseJSON(curObj.DecomNodes);
+ var deadNodesJson = App.parseJSON(curObj.DeadNodes);
+ if (decomNodesJson && decomNodesJson[hostName] ) {
+ self.set('isComponentRecommissionAvailable', true);
+ self.set('isComponentDecommissioning', true);
+ self.set('isComponentDecommissionAvailable', false);
+ } else if (deadNodesJson && deadNodesJson[hostName] ) {
+ self.set('isComponentRecommissionAvailable', true);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', false);
+ } else if (liveNodesJson && liveNodesJson[hostName] ) {
+ self.set('isComponentRecommissionAvailable', false);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', self.get('isStart'));
+ } else {
+ // if namenode is down, get desired_admin_state to decide if the user had issued a decommission
+ var deferred = $.Deferred();
+ self.getDesiredAdminState().done( function () {
+ var desired_admin_state = self.get('desiredAdminState');
+ self.set('desiredAdminState', null);
+ switch(desired_admin_state) {
+ case "INSERVICE":
+ self.set('isComponentRecommissionAvailable', false);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', self.get('isStart'));
+ break;
+ case "DECOMMISSIONED":
+ self.set('isComponentRecommissionAvailable', true);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', false);
+ break;
+ }
+ deferred.resolve(desired_admin_state);
+ });
+ }
+ }
+ }
+ dfd.resolve(curObj);
+ });
+ return dfd.promise();
+ }
+
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/views/main/host/details/host_component_views/decommissionable.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/details/host_component_views/decommissionable.js b/ambari-web/app/views/main/host/details/host_component_views/decommissionable.js
new file mode 100644
index 0000000..b17f2c9
--- /dev/null
+++ b/ambari-web/app/views/main/host/details/host_component_views/decommissionable.js
@@ -0,0 +1,253 @@
+/**
+ * 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 uiEffects = require('utils/ui_effects');
+
+/**
+ * Mixin for <code>App.HostComponentView</code>
+ * Contains code for processing components with allowed decommission
+ * @type {Em.Mixin}
+ */
+App.Decommissionable = Em.Mixin.create({
+
+ /**
+ * Should be redeclared in views that use this mixin
+ * @type {String}
+ */
+ componentForCheckDecommission: '',
+
+ /**
+ * Received from server object with data about decommission
+ * @type {Object}
+ */
+ decommissionedStatusObject: null,
+
+ /**
+ * Received from server desired_admin_state value
+ * @type {String}
+ */
+ desiredAdminState: null,
+
+ /**
+ * Is component in decommission process right know
+ * @type {bool}
+ */
+ isComponentDecommissioning: null,
+
+ /**
+ * May conponent be decommissioned
+ * @type {bool}
+ */
+ isComponentDecommissionAvailable: null,
+
+ /**
+ * May component be recommissioned
+ * @type {bool}
+ */
+ isComponentRecommissionAvailable: null,
+
+ /**
+ * Recalculated component status based on decommission
+ * @type {string}
+ */
+ statusClass: function () {
+
+ //Class when install failed
+ if (this.get('workStatus') === App.HostComponentStatus.install_failed) {
+ return 'health-status-color-red icon-cog';
+ }
+
+ //Class when installing
+ if (this.get('workStatus') === App.HostComponentStatus.installing) {
+ return 'health-status-color-blue icon-cog';
+ }
+
+ //Class when maintenance
+ if (this.get('content.passiveState') != "ACTIVE") {
+ return 'icon-medkit';
+ }
+
+ if (this.get('isComponentRecommissionAvailable') && (this.get('isStart') || this.get('workStatus') == 'INSTALLED')) {
+ return 'health-status-DEAD-ORANGE';
+ }
+
+ //For all other cases
+ return 'health-status-' + App.HostComponentStatus.getKeyName(this.get('workStatus'));
+
+ }.property('content.passiveState','workStatus', 'isComponentRecommissionAvailable', 'isComponentDecommissioning'),
+
+ /**
+ * Return host component text status
+ * @type {String}
+ */
+ componentTextStatus: function () {
+ var componentTextStatus = this.get('content.componentTextStatus');
+ var hostComponent = this.get('hostComponent');
+ if (hostComponent) {
+ componentTextStatus = hostComponent.get('componentTextStatus');
+ if(this.get('isComponentRecommissionAvailable')){
+ if(this.get('isComponentDecommissioning')){
+ componentTextStatus = Em.I18n.t('hosts.host.decommissioning');
+ } else {
+ componentTextStatus = Em.I18n.t('hosts.host.decommissioned');
+ }
+ }
+ }
+ return componentTextStatus;
+ }.property('content.passiveState','workStatus','isComponentRecommissionAvailable','isComponentDecommissioning'),
+
+ /**
+ * For Stopping or Starting states, also for decommissioning
+ * @type {bool}
+ */
+ isInProgress: function () {
+ return (this.get('workStatus') === App.HostComponentStatus.stopping ||
+ this.get('workStatus') === App.HostComponentStatus.starting) ||
+ this.get('isDecommissioning');
+ }.property('workStatus', 'isDecommissioning'),
+
+ /**
+ * Get desired_admin_state status from server
+ */
+ getDesiredAdminState: function(){
+ return App.ajax.send({
+ name: 'host.host_component.slave_desired_admin_state',
+ sender: this,
+ data: {
+ hostName: this.get('content.host.hostName'),
+ componentName: this.get('content.componentName')
+ },
+ success: 'getDesiredAdminStateSuccessCallback',
+ error: 'getDesiredAdminStateErrorCallback'
+ });
+ },
+
+ /**
+ * Set received value or null to <code>desiredAdminState</code>
+ * @param {Object} response
+ * @returns {String|null}
+ */
+ getDesiredAdminStateSuccessCallback: function (response) {
+ var status = response.HostRoles.desired_admin_state;
+ if ( status != null) {
+ this.set('desiredAdminState', status);
+ return status;
+ }
+ return null;
+ },
+
+ /**
+ * Set null to <code>desiredAdminState</code> if server returns error
+ * @returns {null}
+ */
+ getDesiredAdminStateErrorCallback: function () {
+ this.set('desiredAdminState', null);
+ return null;
+ },
+
+ /**
+ * Get component decommission status from server
+ * @returns {$.ajax}
+ */
+ getDecommissionStatus: function() {
+ return App.ajax.send({
+ name: 'host.host_component.decommission_status',
+ sender: this,
+ data: {
+ hostName: this.get('content.host.hostName'),
+ componentName: this.get('componentForCheckDecommission'),
+ serviceName: this.get('content.service.serviceName')
+ },
+ success: 'getDecommissionStatusSuccessCallback',
+ error: 'getDecommissionStatusErrorCallback'
+ });
+ },
+
+ /**
+ * Set received value or null to <code>decommissionedStatusObject</code>
+ * @param {Object} response
+ * @returns {Object|null}
+ */
+ getDecommissionStatusSuccessCallback: function (response) {
+ var statusObject = response.ServiceComponentInfo;
+ if ( statusObject != null) {
+ this.set('decommissionedStatusObject', statusObject);
+ return statusObject;
+ }
+ return null;
+ },
+
+ /**
+ * Set null to <code>decommissionedStatusObject</code> if server returns error
+ * @returns {null}
+ */
+ getDecommissionStatusErrorCallback: function () {
+ this.set('decommissionedStatusObject', null);
+ return null;
+ },
+
+ /**
+ * Do blinking for 1 minute
+ */
+ doBlinking: function () {
+ var workStatus = this.get('workStatus');
+ var self = this;
+ var pulsate = [App.HostComponentStatus.starting, App.HostComponentStatus.stopping, App.HostComponentStatus.installing].contains(workStatus);
+ if (!pulsate) {
+ var component = this.get('content');
+ if (component && workStatus != "INSTALLED") {
+ pulsate = this.get('isDecommissioning');
+ }
+ }
+ if (pulsate && !self.get('isBlinking')) {
+ self.set('isBlinking', true);
+ uiEffects.pulsate(self.$('.components-health'), 1000, function () {
+ self.set('isBlinking', false);
+ self.doBlinking();
+ });
+ }
+ },
+
+ /**
+ * Start blinking when host component is starting/stopping/decommissioning
+ */
+ startBlinking: function () {
+ this.$('.components-health').stop(true, true);
+ this.$('.components-health').css({opacity: 1.0});
+ this.doBlinking();
+ }.observes('workStatus','isComponentRecommissionAvailable', 'isDecommissioning'),
+
+ /**
+ * Should be redeclared in views that use this mixin
+ */
+ loadComponentDecommissionStatus: function() {},
+
+ didInsertElement: function() {
+ this._super();
+ this.loadComponentDecommissionStatus();
+ },
+
+ /**
+ * Update Decommission status only one time when component was changed
+ */
+ updateDecommissionStatus: function() {
+ Em.run.once(this, 'loadComponentDecommissionStatus');
+ }.observes('content.workStatus', 'content.passiveState')
+
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/views/main/host/details/host_component_views/nodemanager_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/details/host_component_views/nodemanager_view.js b/ambari-web/app/views/main/host/details/host_component_views/nodemanager_view.js
new file mode 100644
index 0000000..16fadc9
--- /dev/null
+++ b/ambari-web/app/views/main/host/details/host_component_views/nodemanager_view.js
@@ -0,0 +1,71 @@
+/**
+ * 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');
+require('views/main/host/details/host_component_views/decommissionable');
+
+App.NodeManagerComponentView = App.HostComponentView.extend(App.Decommissionable, {
+
+ componentForCheckDecommission: 'RESOURCEMANAGER',
+
+ /**
+ * load Recommission/Decommission status for nodeManager from nodeManagers list
+ */
+ loadComponentDecommissionStatus: function () {
+ var hostName = this.get('content.host.hostName');
+ var dfd = $.Deferred();
+ var self = this;
+ this.getDesiredAdminState().done( function () {
+ var desired_admin_state = self.get('desiredAdminState');
+ self.set('desiredAdminState', null);
+ switch(desired_admin_state) {
+ case "INSERVICE":
+ // can be decommissioned if already started
+ self.set('isComponentRecommissionAvailable', false);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', self.get('isStart'));
+ break;
+ case "DECOMMISSIONED":
+ var deferred = $.Deferred();
+ self.getDecommissionStatus().done( function() {
+ var curObj = self.get('decommissionedStatusObject');
+ self.set('decommissionedStatusObject', null);
+ if (curObj && curObj.rm_metrics) {
+ var nodeManagersArray = App.parseJSON(curObj.rm_metrics.cluster.nodeManagers);
+ if (nodeManagersArray.findProperty('HostName', hostName)){
+ // decommisioning ..
+ self.set('isComponentRecommissionAvailable', true);
+ self.set('isComponentDecommissioning', true);
+ self.set('isComponentDecommissionAvailable', false);
+ } else {
+ // decommissioned ..
+ self.set('isComponentRecommissionAvailable', true);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', false);
+ }
+ }
+ deferred.resolve(curObj);
+ });
+ break;
+ }
+ dfd.resolve(desired_admin_state);
+ });
+ return dfd.promise();
+ }
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/views/main/host/details/host_component_views/regionserver_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/details/host_component_views/regionserver_view.js b/ambari-web/app/views/main/host/details/host_component_views/regionserver_view.js
new file mode 100644
index 0000000..0d166dd
--- /dev/null
+++ b/ambari-web/app/views/main/host/details/host_component_views/regionserver_view.js
@@ -0,0 +1,52 @@
+/**
+ * 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');
+require('views/main/host/details/host_component_views/decommissionable');
+
+App.RegionServerComponentView = App.HostComponentView.extend(App.Decommissionable, {
+
+ /**
+ * load Recommission/Decommission status of RegionServer
+ */
+ loadComponentDecommissionStatus: function () {
+ var hostName = this.get('content.host.hostName');
+ var slaveType = 'HBASE_REGIONSERVER';
+ var self = this;
+ var deferred = $.Deferred();
+ self.getDesiredAdminState().done( function () {
+ var desired_admin_state = self.get('desiredAdminState');
+ self.set('desiredAdminState', null);
+ switch(desired_admin_state) {
+ case "INSERVICE":
+ self.set('isComponentRecommissionAvailable', false);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', self.get('isStart'));
+ break;
+ case "DECOMMISSIONED":
+ self.set('isComponentRecommissionAvailable', true);
+ self.set('isComponentDecommissioning', self.get('isStart'));
+ self.set('isComponentDecommissionAvailable', false);
+ break;
+ }
+ deferred.resolve(desired_admin_state);
+ });
+ return deferred.promise();
+ }
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/views/main/host/details/host_component_views/tasktracker_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/details/host_component_views/tasktracker_view.js b/ambari-web/app/views/main/host/details/host_component_views/tasktracker_view.js
new file mode 100644
index 0000000..7948ef4
--- /dev/null
+++ b/ambari-web/app/views/main/host/details/host_component_views/tasktracker_view.js
@@ -0,0 +1,74 @@
+/**
+ * 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');
+require('views/main/host/details/host_component_views/decommissionable');
+
+App.TaskTrackerComponentView = App.HostComponentView.extend(App.Decommissionable, {
+
+ componentForCheckDecommission: 'JOBTRACKER',
+
+ /**
+ * load Recommission/Decommission status for TaskTracker from JobTracker/AliveNodes list
+ */
+ loadComponentDecommissionStatus: function () {
+ var hostName = this.get('content.host.hostName');
+ var dfd = $.Deferred();
+ var self = this;
+ this.getDesiredAdminState().done( function () {
+ var desired_admin_state = self.get('desiredAdminState');
+ self.set('desiredAdminState', null);
+ switch(desired_admin_state) {
+ case "INSERVICE":
+ // can be decommissioned if already started
+ self.set('isComponentRecommissionAvailable', false);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', self.get('isStart'));
+ break;
+ case "DECOMMISSIONED":
+ var deferred = $.Deferred();
+ self.getDecommissionStatus().done( function() {
+ var curObj = self.get('decommissionedStatusObject');
+ self.set('decommissionedStatusObject', null);
+ if (curObj) {
+ var aliveNodesArray = App.parseJSON(curObj.AliveNodes);
+ if (aliveNodesArray != null) {
+ if (aliveNodesArray.findProperty('hostname', hostName)){
+ //decommissioning ..
+ self.set('isComponentRecommissionAvailable', true);
+ self.set('isComponentDecommissioning', true);
+ self.set('isComponentDecommissionAvailable', false);
+ } else {
+ //decommissioned
+ self.set('isComponentRecommissionAvailable', true);
+ self.set('isComponentDecommissioning', false);
+ self.set('isComponentDecommissionAvailable', false);
+ }
+ }
+
+ }
+ deferred.resolve(curObj);
+ });
+ break;
+ }
+ dfd.resolve(desired_admin_state);
+ });
+ return dfd.promise();
+ }
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/app/views/main/host/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/summary.js b/ambari-web/app/views/main/host/summary.js
index cb95d79..d367e89 100644
--- a/ambari-web/app/views/main/host/summary.js
+++ b/ambari-web/app/views/main/host/summary.js
@@ -23,6 +23,25 @@ App.MainHostSummaryView = Em.View.extend({
templateName: require('templates/main/host/summary'),
/**
+ * List of custom view for some host components
+ * @type {Em.Object}
+ * Format:
+ * <code>
+ * {
+ * COMPONENT_NAME1: VIEW1,
+ * COMPONENT_NAME2: VIEW2
+ * ....
+ * }
+ * </code>
+ */
+ hostComponentViewMap: Em.Object.create({
+ 'DATANODE': App.DataNodeComponentView,
+ 'NODEMANAGER': App.NodeManagerComponentView,
+ 'HBASE_REGIONSERVER': App.RegionServerComponentView,
+ 'TASKTRACKER': App.TaskTrackerComponentView
+ }),
+
+ /**
* @type {bool}
*/
isStopCommand:true,
@@ -107,6 +126,7 @@ App.MainHostSummaryView = Em.View.extend({
sortedComponentsFormatter: function() {
var updatebleProperties = Em.A(['workStatus', 'passiveState', 'staleConfigs', 'haStatus']);
var self = this;
+ var hostComponentViewMap = this.get('hostComponentViewMap');
// Remove deleted components
this.get('sortedComponents').forEach(function(sortedComponent, index) {
if (!self.get('content.hostComponents').findProperty('id', sortedComponent.get('id'))) {
@@ -125,6 +145,7 @@ App.MainHostSummaryView = Em.View.extend({
}
else {
// Add new component
+ component.set('view', hostComponentViewMap[component.get('componentName')] ? hostComponentViewMap[component.get('componentName')] : App.HostComponentView);
if (component.get('isMaster')) {
// Masters should be before slaves
var lastMasterIndex = 0, atLeastOneMasterExists = false;
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/test/views/main/host/details/host_component_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/host/details/host_component_view_test.js b/ambari-web/test/views/main/host/details/host_component_view_test.js
index 226ba1f..394133e 100644
--- a/ambari-web/test/views/main/host/details/host_component_view_test.js
+++ b/ambari-web/test/views/main/host/details/host_component_view_test.js
@@ -36,14 +36,19 @@ describe('App.HostComponentView', function() {
var tests = Em.A([
{
- content: Em.Object.create({passiveState: 'PASSIVE'}),
+ content: Em.Object.create({componentTextStatus: 'status', passiveState: 'PASSIVE'}),
m: 'PASSIVE state',
e: Em.I18n.t('hosts.component.passive.short.mode')
},
{
- content: Em.Object.create({passiveState: 'IMPLIED'}),
+ content: Em.Object.create({componentTextStatus: 'status', passiveState: 'IMPLIED'}),
m: 'IMPLIED state',
e: Em.I18n.t('hosts.component.passive.short.mode')
+ },
+ {
+ content: Em.Object.create({componentTextStatus: 'status', passiveState: 'ACTIVE'}),
+ m: 'ACTIVE state',
+ e: 'status'
}
]);
@@ -313,4 +318,133 @@ describe('App.HostComponentView', function() {
});
+ describe('#componentTextStatus', function() {
+
+ var tests = Em.A([
+ {
+ content: Em.Object.create({componentTextStatus: 'status'}),
+ hostComponent: null,
+ e: 'status',
+ m: 'get content status'
+ },
+ {
+ content: Em.Object.create({componentTextStatus: 'status'}),
+ hostComponent: Em.Object.create({componentTextStatus: 'new_status'}),
+ e: 'new_status',
+ m: 'get hostComponent status'
+ }
+ ]);
+
+ tests.forEach(function(test) {
+ it(test.m, function() {
+ hostComponentView = App.HostComponentView.create({
+ startBlinking: function(){},
+ doBlinking: function(){},
+ getDesiredAdminState: function(){return $.ajax({});},
+ content: test.content,
+ hostComponent: test.hostComponent
+ });
+ expect(hostComponentView.get('componentTextStatus')).to.equal(test.e);
+ });
+ });
+
+ });
+
+ describe('#workStatus', function() {
+
+ var tests = Em.A([
+ {
+ content: Em.Object.create({workStatus: 'status'}),
+ hostComponent: null,
+ e: 'status',
+ m: 'get content workStatus'
+ },
+ {
+ content: Em.Object.create({workStatus: 'status'}),
+ hostComponent: Em.Object.create({workStatus: 'new_status'}),
+ e: 'new_status',
+ m: 'get hostComponent workStatus'
+ }
+ ]);
+
+ tests.forEach(function(test) {
+ it(test.m, function() {
+ hostComponentView = App.HostComponentView.create({
+ startBlinking: function(){},
+ doBlinking: function(){},
+ getDesiredAdminState: function(){return $.ajax({});},
+ content: test.content,
+ hostComponent: test.hostComponent
+ });
+ expect(hostComponentView.get('workStatus')).to.equal(test.e);
+ });
+ });
+
+ });
+
+ describe('#statusClass', function() {
+
+ var tests = Em.A([
+ {
+ content: Em.Object.create({workStatus: App.HostComponentStatus.install_failed,passiveState: 'ACTIVE'}),
+ e: 'health-status-color-red icon-cog'
+ },
+ {
+ content: Em.Object.create({workStatus: App.HostComponentStatus.installing, passiveState: 'ACTIVE'}),
+ e: 'health-status-color-blue icon-cog'
+ },
+ {
+ content: Em.Object.create({workStatus: 'STARTED', passiveState: 'PASSIVE'}),
+ e: 'icon-medkit'
+ },
+ {
+ content: Em.Object.create({workStatus: 'STARTED', passiveState: 'IMPLIED'}),
+ e: 'icon-medkit'
+ },
+ {
+ content: Em.Object.create({workStatus: 'STARTED', passiveState: 'ACTIVE'}),
+ e: 'health-status-started'
+ }
+ ]);
+
+ tests.forEach(function(test) {
+ it(test.content.get('workStatus') + ' ' + test.content.get('passiveState'), function() {
+ hostComponentView = App.HostComponentView.create({
+ startBlinking: function(){},
+ doBlinking: function(){},
+ getDesiredAdminState: function(){return $.ajax({});},
+ content: test.content
+ });
+ expect(hostComponentView.get('statusClass')).to.equal(test.e);
+ });
+ });
+
+ });
+
+ describe('#isInProgress', function() {
+
+ var tests = Em.A([
+ {
+ workStatus: App.HostComponentStatus.stopping,
+ e: true
+ },
+ {
+ workStatus: App.HostComponentStatus.starting,
+ e: true
+ },
+ {
+ workStatus: 'other_status',
+ e: false
+ }
+ ]);
+
+ tests.forEach(function(test) {
+ it(test.workStatus, function() {
+ hostComponentView.set('content', Em.Object.create({workStatus: test.workStatus}));
+ expect(hostComponentView.get('isInProgress')).to.equal(test.e);
+ });
+ });
+
+ });
+
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/746e68fc/ambari-web/test/views/main/host/details/host_component_views/decommissionable_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/host/details/host_component_views/decommissionable_test.js b/ambari-web/test/views/main/host/details/host_component_views/decommissionable_test.js
new file mode 100644
index 0000000..edbe8ca
--- /dev/null
+++ b/ambari-web/test/views/main/host/details/host_component_views/decommissionable_test.js
@@ -0,0 +1,201 @@
+/**
+ * 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');
+require('models/host_component');
+require('views/main/host/details/host_component_view');
+require('views/main/host/details/host_component_views/decommissionable');
+
+var hostComponentView;
+
+describe('App.Decommissionable', function() {
+
+ beforeEach(function() {
+ hostComponentView = App.HostComponentView.create(App.Decommissionable, {
+ startBlinking: function(){},
+ doBlinking: function(){},
+ getDesiredAdminState: function(){return $.ajax({});}
+ });
+ });
+
+ describe('#componentTextStatus', function() {
+
+ var tests = Em.A([
+ {
+ content: Em.Object.create({componentTextStatus: 'status'}),
+ hostComponent: null,
+ isComponentRecommissionAvailable: false,
+ isComponentDecommissioning: false,
+ e: 'status',
+ m: 'get content status'
+ },
+ {
+ content: Em.Object.create({componentTextStatus: 'status'}),
+ hostComponent: Em.Object.create({componentTextStatus: 'new_status'}),
+ isComponentRecommissionAvailable: false,
+ isComponentDecommissioning: false,
+ e: 'new_status',
+ m: 'get hostComponent status'
+ },
+ {
+ content: Em.Object.create({componentTextStatus: 'status'}),
+ hostComponent: Em.Object.create({componentTextStatus: 'new_status'}),
+ isComponentRecommissionAvailable: false,
+ isComponentDecommissioning: false,
+ e: 'new_status',
+ m: 'get hostComponent status'
+ },
+ {
+ content: Em.Object.create({componentTextStatus: 'status'}),
+ hostComponent: Em.Object.create({componentTextStatus: 'new_status'}),
+ isComponentRecommissionAvailable: true,
+ isComponentDecommissioning: true,
+ e: Em.I18n.t('hosts.host.decommissioning'),
+ m: 'get decommissioning status'
+ },
+ {
+ content: Em.Object.create({componentTextStatus: 'status'}),
+ hostComponent: Em.Object.create({componentTextStatus: 'new_status'}),
+ isComponentRecommissionAvailable: true,
+ isComponentDecommissioning: false,
+ e: Em.I18n.t('hosts.host.decommissioned'),
+ m: 'get decommissioned status'
+ }
+ ]);
+
+ tests.forEach(function(test) {
+ it(test.m, function() {
+ hostComponentView = App.HostComponentView.create(App.Decommissionable, {
+ startBlinking: function(){},
+ doBlinking: function(){},
+ getDesiredAdminState: function(){return $.ajax({});},
+ content: test.content,
+ hostComponent: test.hostComponent,
+ isComponentRecommissionAvailable: test.isComponentRecommissionAvailable,
+ isComponentDecommissioning: test.isComponentDecommissioning
+ });
+ expect(hostComponentView.get('componentTextStatus')).to.equal(test.e);
+ });
+ });
+
+ });
+
+ describe('#statusClass', function() {
+
+ var tests = Em.A([
+ {
+ content: Em.Object.create({workStatus: App.HostComponentStatus.install_failed,passiveState: 'ACTIVE'}),
+ isComponentRecommissionAvailable: false,
+ e: 'health-status-color-red icon-cog'
+ },
+ {
+ content: Em.Object.create({workStatus: App.HostComponentStatus.installing, passiveState: 'ACTIVE'}),
+ isComponentRecommissionAvailable: false,
+ e: 'health-status-color-blue icon-cog'
+ },
+ {
+ content: Em.Object.create({workStatus: 'STARTED', passiveState: 'PASSIVE'}),
+ isComponentRecommissionAvailable: false,
+ e: 'icon-medkit'
+ },
+ {
+ content: Em.Object.create({workStatus: 'STARTED', passiveState: 'IMPLIED'}),
+ isComponentRecommissionAvailable: false,
+ e: 'icon-medkit'
+ },
+ {
+ content: Em.Object.create({workStatus: 'STARTED', passiveState: 'ACTIVE'}),
+ isComponentRecommissionAvailable: false,
+ e: 'health-status-started'
+ },
+ {
+ content: Em.Object.create({workStatus: 'STARTED', passiveState: 'ACTIVE'}),
+ isComponentRecommissionAvailable: true,
+ e: 'health-status-DEAD-ORANGE'
+ },
+ {
+ content: Em.Object.create({workStatus: 'STARTING', passiveState: 'ACTIVE'}),
+ isComponentRecommissionAvailable: true,
+ e: 'health-status-DEAD-ORANGE'
+ },
+ {
+ content: Em.Object.create({workStatus: 'INSTALLED', passiveState: 'ACTIVE'}),
+ isComponentRecommissionAvailable: true,
+ e: 'health-status-DEAD-ORANGE'
+ }
+
+ ]);
+
+ tests.forEach(function(test) {
+ it(test.content.get('workStatus') + ' ' + test.content.get('passiveState') + ' ' + test.isComponentRecommissionAvailable?'true':'false', function() {
+ hostComponentView = App.HostComponentView.create(App.Decommissionable,{
+ startBlinking: function(){},
+ doBlinking: function(){},
+ getDesiredAdminState: function(){return $.ajax({});},
+ isComponentRecommissionAvailable: test.isComponentRecommissionAvailable,
+ content: test.content
+ });
+ expect(hostComponentView.get('statusClass')).to.equal(test.e);
+ });
+ });
+
+ });
+
+ describe('#isInProgress', function() {
+
+ var tests = Em.A([
+ {
+ workStatus: App.HostComponentStatus.stopping,
+ isDecommissioning: false,
+ e: true
+ },
+ {
+ workStatus: App.HostComponentStatus.starting,
+ isDecommissioning: false,
+ e: true
+ },
+ {
+ workStatus: 'other_status',
+ isDecommissioning: false,
+ e: false
+ },
+ {
+ workStatus: 'other_status',
+ isDecommissioning: true,
+ e: true
+ }
+ ]);
+
+ tests.forEach(function(test) {
+ it(test.workStatus + ' ' + test.isDecommissioning?'true':'false', function() {
+
+ hostComponentView = App.HostComponentView.create(App.Decommissionable,{
+ startBlinking: function(){},
+ doBlinking: function(){},
+ getDesiredAdminState: function(){return $.ajax({});},
+ isDecommissioning: test.isDecommissioning,
+ content: Em.Object.create({workStatus: test.workStatus})
+ });
+
+ expect(hostComponentView.get('isInProgress')).to.equal(test.e);
+ });
+ });
+
+ });
+
+});